]> git.sur5r.net Git - i3/i3/commitdiff
handle ButtonPress events with child != XCB_NONE (Thanks xeen)
authorMichael Stapelberg <michael@stapelberg.de>
Sun, 9 Feb 2014 13:00:43 +0000 (14:00 +0100)
committerMichael Stapelberg <michael@stapelberg.de>
Sun, 9 Feb 2014 13:00:43 +0000 (14:00 +0100)
The X11 protocol description states:

  The window the event is reported with respect to is called the event
  window. The event window is found by starting with the source window
  and looking up the hierarchy for the first window on which any client
  has selected interest in the event.

For the case of urxvt with URxvt.internalBorder > 0, urxvt sets up a
subwindow for its actual contents that is placed “in the middle” of the
urxvt window. In terms of the X11 protocol, the source window is urxvt’s
window, but urxvt does not select ButtonPress events for that.
Therefore, X11 will go up in the hierarchy and deliver the event to i3
for i3’s window decoration, even though this was not actually a click on
the decoration, but into the managed window.

Therefore, we check whether child != XCB_NONE for clicks on window
decorations and then handle them as a click inside the window.

fixes #1176

src/click.c

index 33d5a4d7c88bed2a38ba2dbc85b30c8b2a778eaf..22e70b9f7954c1445dcbb46faef3259c7522acf8 100644 (file)
@@ -311,7 +311,9 @@ done:
  */
 int handle_button_press(xcb_button_press_event_t *event) {
     Con *con;
-    DLOG("Button %d pressed on window 0x%08x\n", event->state, event->event);
+    DLOG("Button %d pressed on window 0x%08x (child 0x%08x) at (%d, %d) (root %d, %d)\n",
+         event->state, event->event, event->child, event->event_x, event->event_y,
+         event->root_x, event->root_y);
 
     last_timestamp = event->time;
 
@@ -347,6 +349,11 @@ int handle_button_press(xcb_button_press_event_t *event) {
         return 0;
     }
 
+    if (event->child != XCB_NONE) {
+        DLOG("event->child not XCB_NONE, so this is an event which originated from a click into the application, but the application did not handle it.\n");
+        return route_click(con, event, mod_pressed, CLICK_INSIDE);
+    }
+
     /* Check if the click was on the decoration of a child */
     Con *child;
     TAILQ_FOREACH(child, &(con->nodes_head), nodes) {