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) {