From 394ff06589676c26561f19264de1097edaaecdc7 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 14 May 2016 16:16:24 +0200 Subject: [PATCH] Fix mouse clicks on titlebars (#901) Commit 7dad0b3b876af3c7 made awesome only ask for mouse events on the actual client window. Obviously, this means that we no longer get reports for clicks on the titlebar. Whoops. Fix this by asking for mouse events on *both* the actual client window and the frame window. The passive grab on the actual client window is actually unneeded, but we keep it so that the fix that was done by the above commit is still present (xev will no longer report leave/enter events just for a mouse click). Since we now get mouse events inside of a client reported twice, the event handling code in event.c has to be fixed to handle both cases. E.g. x/y are relative to the top-left corner of the window and thus needs to be fixed for titlebar size; the second click has to be ignored. Signed-off-by: Uli Schlachter --- event.c | 52 ++++++++++++++++++++++++++++++++---------------- objects/window.c | 1 + 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/event.c b/event.c index ed36c5e06..e4ca8fe55 100644 --- a/event.c +++ b/event.c @@ -223,26 +223,44 @@ event_handle_button(xcb_button_press_event_t *ev) XCB_ALLOW_ASYNC_POINTER, XCB_CURRENT_TIME); } - else if((c = client_getbywin(ev->event))) + else if((c = client_getbyframewin(ev->event)) || (c = client_getbywin(ev->event))) { - luaA_object_push(L, c); - /* And handle the button raw button event */ - event_emit_button(L, ev); - /* then check if a titlebar was "hit" */ - int x = ev->event_x, y = ev->event_y; - drawable_t *d = client_get_drawable_offset(c, &x, &y); - if (d) + /* For clicks inside of c->window, we get two events. Once because of a + * passive grab on c->window and then again for c->frame_window. + * Ignore the second event (identifiable by ev->child != XCB_NONE). + */ + if (ev->event != c->frame_window || ev->child == XCB_NONE) { - /* Copy the event so that we can fake x/y */ - xcb_button_press_event_t event = *ev; - event.event_x = x; - event.event_y = y; - luaA_object_push_item(L, -1, d); - event_emit_button(L, &event); - lua_pop(L, 1); + luaA_object_push(L, c); + if (c->window == ev->event) + { + /* Button event into the client itself (not titlebar), translate + * into the frame window. + */ + ev->event_x += c->titlebar[CLIENT_TITLEBAR_LEFT].size; + ev->event_y += c->titlebar[CLIENT_TITLEBAR_TOP].size; + } + /* And handle the button raw button event */ + event_emit_button(L, ev); + /* then check if a titlebar was "hit" */ + if (c->frame_window == ev->event) + { + int x = ev->event_x, y = ev->event_y; + drawable_t *d = client_get_drawable_offset(c, &x, &y); + if (d) + { + /* Copy the event so that we can fake x/y */ + xcb_button_press_event_t event = *ev; + event.event_x = x; + event.event_y = y; + luaA_object_push_item(L, -1, d); + event_emit_button(L, &event); + lua_pop(L, 1); + } + } + /* then check if any button objects match */ + event_button_callback(ev, &c->buttons, L, -1, 1, NULL); } - /* then check if any button objects match */ - event_button_callback(ev, &c->buttons, L, -1, 1, NULL); xcb_allow_events(globalconf.connection, XCB_ALLOW_REPLAY_POINTER, XCB_CURRENT_TIME); diff --git a/objects/window.c b/objects/window.c index 2529b04fc..2c02ac0fe 100644 --- a/objects/window.c +++ b/objects/window.c @@ -64,6 +64,7 @@ luaA_window_buttons(lua_State *L) { luaA_button_array_set(L, 1, 2, &window->buttons); luaA_object_emit_signal(L, 1, "property::buttons", 0); + xwindow_buttons_grab(window_get(window), &window->buttons); xwindow_buttons_grab(window->window, &window->buttons); }