From: Michael Stapelberg Date: Sun, 9 Feb 2014 13:00:43 +0000 (+0100) Subject: handle ButtonPress events with child != XCB_NONE (Thanks xeen) X-Git-Tag: 4.8~118 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=491274d8b3f0f683fb554d696f5c2bd205a0cfc9;p=i3%2Fi3 handle ButtonPress events with child != XCB_NONE (Thanks xeen) 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 --- diff --git a/src/click.c b/src/click.c index 33d5a4d7..22e70b9f 100644 --- a/src/click.c +++ b/src/click.c @@ -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) {