bool load_keymap(void);
/**
- * Returns true if the current config has any binding to a scroll wheel button
- * (4 or 5) which is a whole-window binding.
- * We need this to figure out whether we should grab all buttons or just 1-3
- * when managing a window. See #2049.
- *
+ * Returns a list of buttons that should be grabbed on a window.
+ * This list will always contain 1–3, all higher buttons will only be returned
+ * if there is a whole-window binding for it on some window in the current
+ * config.
+ * The list is terminated by a 0.
*/
-bool bindings_should_grab_scrollwheel_buttons(void);
+int *bindings_get_buttons_to_grab(void);
* Grab the specified buttons on a window when managing it.
*
*/
-void xcb_grab_buttons(xcb_connection_t *conn, xcb_window_t window, bool bind_scrollwheel);
+void xcb_grab_buttons(xcb_connection_t *conn, xcb_window_t window, int *buttons);
*
*/
void regrab_all_buttons(xcb_connection_t *conn) {
- bool grab_scrollwheel = bindings_should_grab_scrollwheel_buttons();
+ int *buttons = bindings_get_buttons_to_grab();
xcb_grab_server(conn);
Con *con;
continue;
xcb_ungrab_button(conn, XCB_BUTTON_INDEX_ANY, con->window->id, XCB_BUTTON_MASK_ANY);
- xcb_grab_buttons(conn, con->window->id, grab_scrollwheel);
+ xcb_grab_buttons(conn, con->window->id, buttons);
}
+ FREE(buttons);
xcb_ungrab_server(conn);
}
}
/*
- * Returns true if the current config has any binding to a scroll wheel button
- * (4 or 5) which is a whole-window binding.
- * We need this to figure out whether we should grab all buttons or just 1-3
- * when managing a window. See #2049.
- *
+ * Returns a list of buttons that should be grabbed on a window.
+ * This list will always contain 1–3, all higher buttons will only be returned
+ * if there is a whole-window binding for it on some window in the current
+ * config.
+ * The list is terminated by a 0.
*/
-bool bindings_should_grab_scrollwheel_buttons(void) {
+int *bindings_get_buttons_to_grab(void) {
+ /* Let's make the reasonable assumption that there's no more than 25
+ * buttons. */
+ int num_max = 25;
+
+ int buffer[num_max];
+ int num = 0;
+
+ /* We always return buttons 1 through 3. */
+ buffer[num++] = 1;
+ buffer[num++] = 2;
+ buffer[num++] = 3;
+
Binding *bind;
TAILQ_FOREACH(bind, bindings, bindings) {
+ if (num + 1 == num_max)
+ break;
+
/* We are only interested in whole window mouse bindings. */
if (bind->input_type != B_MOUSE || !bind->whole_window)
continue;
continue;
}
- /* If the binding is for either scrollwheel button, we need to grab everything. */
- if (button == 4 || button == 5) {
- return true;
+ /* Avoid duplicates. */
+ for (int i = 0; i < num_max; i++) {
+ if (buffer[i] == button)
+ continue;
}
+
+ buffer[num++] = button;
}
+ buffer[num++] = 0;
+
+ int *buttons = scalloc(num, sizeof(int));
+ memcpy(buttons, buffer, num * sizeof(int));
- return false;
+ return buttons;
}
cwindow->id = window;
cwindow->depth = get_visual_depth(attr->visual);
- xcb_grab_buttons(conn, window, bindings_should_grab_scrollwheel_buttons());
+ int *buttons = bindings_get_buttons_to_grab();
+ xcb_grab_buttons(conn, window, buttons);
+ FREE(buttons);
/* update as much information as possible so far (some replies may be NULL) */
window_update_class(cwindow, xcb_get_property_reply(conn, class_cookie, NULL), true);
* Grab the specified buttons on a window when managing it.
*
*/
-void xcb_grab_buttons(xcb_connection_t *conn, xcb_window_t window, bool bind_scrollwheel) {
- uint8_t buttons[3];
- int num = 0;
-
- if (bind_scrollwheel) {
- buttons[num++] = XCB_BUTTON_INDEX_ANY;
- } else {
- buttons[num++] = XCB_BUTTON_INDEX_1;
- buttons[num++] = XCB_BUTTON_INDEX_2;
- buttons[num++] = XCB_BUTTON_INDEX_3;
- }
-
- for (int i = 0; i < num; i++) {
+void xcb_grab_buttons(xcb_connection_t *conn, xcb_window_t window, int *buttons) {
+ int i = 0;
+ while (buttons[i] > 0) {
xcb_grab_button(conn, false, window, XCB_EVENT_MASK_BUTTON_PRESS, XCB_GRAB_MODE_SYNC,
XCB_GRAB_MODE_ASYNC, root, XCB_NONE, buttons[i], XCB_BUTTON_MASK_ANY);
+
+ i++;
}
}