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
This commit is contained in:
Ingo Bürk 2015-12-12 15:45:59 -05:00
parent 8e081d7fff
commit 6f12f029f4
2 changed files with 19 additions and 0 deletions

View File

@ -164,6 +164,10 @@ void regrab_all_buttons(xcb_connection_t *conn) {
xcb_grab_buttons(conn, con->window->id, grab_scrollwheel); 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); xcb_ungrab_server(conn);
} }

View File

@ -363,6 +363,21 @@ int handle_button_press(xcb_button_press_event_t *event) {
return route_click(con, event, mod_pressed, CLICK_INSIDE); return route_click(con, event, mod_pressed, CLICK_INSIDE);
if (!(con = con_by_frame_id(event->event))) { 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 /* If the root window is clicked, find the relevant output from the
* click coordinates and focus the output's active workspace. */ * click coordinates and focus the output's active workspace. */
if (event->event == root && event->response_type == XCB_BUTTON_PRESS) { if (event->event == root && event->response_type == XCB_BUTTON_PRESS) {