From 6f12f029f4fcfac384bb58d4f426f8dab3840f72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ingo=20B=C3=BCrk?= Date: Sat, 12 Dec 2015 15:45:59 -0500 Subject: [PATCH] Allow mouse bindings to run on the root window. Previously, mouse bindings could only be run when a window was present, by using --whole-window. Such bindings would not work on empty workspaces. However, this is a valid usecase for bindings like bindsym $mod+button4 workspace prev bindsym $mod+button5 workspace next Hence, we need to grab the root window as well and run bindings on it. fixes #2097 --- src/bindings.c | 4 ++++ src/click.c | 15 +++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/bindings.c b/src/bindings.c index b9d994ea..16235a1e 100644 --- a/src/bindings.c +++ b/src/bindings.c @@ -164,6 +164,10 @@ void regrab_all_buttons(xcb_connection_t *conn) { xcb_grab_buttons(conn, con->window->id, grab_scrollwheel); } + /* Also grab the root window to allow bindings to work on there as well. */ + xcb_ungrab_button(conn, XCB_BUTTON_INDEX_ANY, root, XCB_BUTTON_MASK_ANY); + xcb_grab_buttons(conn, root, grab_scrollwheel); + xcb_ungrab_server(conn); } diff --git a/src/click.c b/src/click.c index c895666d..66a271c2 100644 --- a/src/click.c +++ b/src/click.c @@ -363,6 +363,21 @@ int handle_button_press(xcb_button_press_event_t *event) { return route_click(con, event, mod_pressed, CLICK_INSIDE); if (!(con = con_by_frame_id(event->event))) { + /* Run bindings on the root window as well, see #2097. We only run it + * if --whole-window was set as that's the equivalent for a normal + * window. */ + if (event->event == root) { + Binding *bind = get_binding_from_xcb_event((xcb_generic_event_t *)event); + if (bind != NULL && bind->whole_window) { + CommandResult *result = run_binding(bind, NULL); + if (result->needs_tree_render) { + tree_render(); + } + + command_result_free(result); + } + } + /* If the root window is clicked, find the relevant output from the * click coordinates and focus the output's active workspace. */ if (event->event == root && event->response_type == XCB_BUTTON_PRESS) {