From 491274d8b3f0f683fb554d696f5c2bd205a0cfc9 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sun, 9 Feb 2014 14:00:43 +0100 Subject: [PATCH] handle ButtonPress events with child != XCB_NONE (Thanks xeen) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) 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) {