diff options
author | Bilal Elmoussaoui <belmouss@redhat.com> | 2022-06-20 13:00:08 +0200 |
---|---|---|
committer | Bilal Elmoussaoui <belmouss@redhat.com> | 2022-08-02 09:51:54 +0200 |
commit | 90b2cd0158be5f82c4c8f05227a3970c349e412f (patch) | |
tree | 62606f2f873635f3ffafaa41caf4bb7af8c847e5 | |
parent | 444b81f1897bb64177186a815e752b241b1cafb6 (diff) | |
download | mutter-bilelmoussaoui/keybindings.tar.gz |
x11: Move X11 specific functions to x11/keybindingsbilelmoussaoui/keybindings
-rw-r--r-- | src/core/display-private.h | 11 | ||||
-rw-r--r-- | src/core/frame.c | 2 | ||||
-rw-r--r-- | src/core/keybindings-private.h | 7 | ||||
-rw-r--r-- | src/core/keybindings.c | 461 | ||||
-rw-r--r-- | src/core/window.c | 2 | ||||
-rw-r--r-- | src/meson.build | 2 | ||||
-rw-r--r-- | src/x11/keybindings-x11-private.h | 20 | ||||
-rw-r--r-- | src/x11/keybindings-x11.c | 440 | ||||
-rw-r--r-- | src/x11/meta-x11-display-private.h | 10 | ||||
-rw-r--r-- | src/x11/meta-x11-display.c | 1 | ||||
-rw-r--r-- | src/x11/window-x11.c | 1 |
11 files changed, 481 insertions, 476 deletions
diff --git a/src/core/display-private.h b/src/core/display-private.h index e33fd61de..1449b4dd9 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -316,17 +316,6 @@ void meta_display_update_cursor (MetaDisplay *display); void meta_display_check_threshold_reached (MetaDisplay *display, int x, int y); -#ifdef HAVE_X11_CLIENT -void meta_display_grab_window_buttons (MetaDisplay *display, - Window xwindow); -void meta_display_ungrab_window_buttons (MetaDisplay *display, - Window xwindow); - -void meta_display_grab_focus_window_button (MetaDisplay *display, - MetaWindow *window); -void meta_display_ungrab_focus_window_button (MetaDisplay *display, - MetaWindow *window); -#endif /* Next function is defined in edge-resistance.c */ void meta_display_cleanup_edges (MetaDisplay *display); diff --git a/src/core/frame.c b/src/core/frame.c index 9c8cbb946..785ccedf7 100644 --- a/src/core/frame.c +++ b/src/core/frame.c @@ -27,8 +27,8 @@ #include "backends/x11/meta-backend-x11.h" #include "core/bell.h" -#include "core/keybindings-private.h" #include "meta/meta-x11-errors.h" +#include "x11/keybindings-x11-private.h" #include "x11/meta-x11-display-private.h" #define EVENT_MASK (SubstructureRedirectMask | \ diff --git a/src/core/keybindings-private.h b/src/core/keybindings-private.h index 449247e0e..6100ecc65 100644 --- a/src/core/keybindings-private.h +++ b/src/core/keybindings-private.h @@ -131,8 +131,6 @@ typedef struct void meta_display_init_keys (MetaDisplay *display); void meta_display_shutdown_keys (MetaDisplay *display); -void meta_window_grab_keys (MetaWindow *window); -void meta_window_ungrab_keys (MetaWindow *window); gboolean meta_window_grab_all_keys (MetaWindow *window, guint32 timestamp); void meta_window_ungrab_all_keys (MetaWindow *window, @@ -154,9 +152,4 @@ void meta_prefs_get_locate_pointer_binding (MetaKeyCombo *combo); const char *meta_prefs_get_iso_next_group_option (void); gboolean meta_prefs_is_locate_pointer_enabled (void); -#ifdef HAVE_X11_CLIENT -void meta_x11_display_grab_keys (MetaX11Display *x11_display); -void meta_x11_display_ungrab_keys (MetaX11Display *x11_display); -#endif - #endif diff --git a/src/core/keybindings.c b/src/core/keybindings.c index c3a7f28c6..d64980de6 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -35,7 +35,6 @@ #include "backends/meta-monitor-manager-private.h" #include "compositor/compositor-private.h" #include "core/edge-resistance.h" -#include "core/frame.h" #include "core/keybindings-private.h" #include "core/meta-accel-parse.h" #include "core/meta-workspace-manager-private.h" @@ -46,9 +45,8 @@ #ifdef HAVE_X11_CLIENT #include "backends/x11/meta-backend-x11.h" #include "backends/x11/meta-input-device-x11.h" -#include "meta/meta-x11-errors.h" +#include "x11/keybindings-x11-private.h" #include "x11/meta-x11-display-private.h" -#include "x11/window-x11.h" #endif #ifdef HAVE_NATIVE_BACKEND @@ -196,11 +194,6 @@ static gboolean process_keyboard_resize_grab (MetaDisplay *display, MetaWindow *window, ClutterKeyEvent *event); -#ifdef HAVE_X11_CLIENT -static void maybe_update_locate_pointer_keygrab (MetaDisplay *display, - gboolean grab); -#endif - static GHashTable *key_handlers; static GHashTable *external_grabs; @@ -897,44 +890,6 @@ rebuild_special_bindings (MetaKeyBindingManager *keys) keys->locate_pointer_key_combo = combo; } -#ifdef HAVE_X11_CLIENT -static void -ungrab_key_bindings (MetaDisplay *display) -{ - GSList *windows, *l; - - if (display->x11_display) - meta_x11_display_ungrab_keys (display->x11_display); - - windows = meta_display_list_windows (display, META_LIST_DEFAULT); - for (l = windows; l; l = l->next) - { - MetaWindow *w = l->data; - meta_window_ungrab_keys (w); - } - - g_slist_free (windows); -} - -static void -grab_key_bindings (MetaDisplay *display) -{ - GSList *windows, *l; - - if (display->x11_display) - meta_x11_display_grab_keys (display->x11_display); - - windows = meta_display_list_windows (display, META_LIST_DEFAULT); - for (l = windows; l; l = l->next) - { - MetaWindow *w = l->data; - meta_window_grab_keys (w); - } - - g_slist_free (windows); -} -#endif - static MetaKeyBinding * get_keybinding (MetaKeyBindingManager *keys, MetaResolvedKeyCombo *resolved_combo) @@ -1147,7 +1102,7 @@ reload_keybindings (MetaDisplay *display) MetaKeyBindingManager *keys = &display->key_binding_manager; #ifdef HAVE_X11_CLIENT - ungrab_key_bindings (display); + meta_x11_display_ungrab_key_bindings (display); #endif /* Deciphering the modmap depends on the loaded keysyms to find out @@ -1157,87 +1112,10 @@ reload_keybindings (MetaDisplay *display) reload_combos (keys); #ifdef HAVE_X11_CLIENT - grab_key_bindings (display); + meta_x11_display_grab_key_bindings (display); #endif } -#ifdef HAVE_X11_CLIENT -static GArray * -calc_grab_modifiers (MetaKeyBindingManager *keys, - unsigned int modmask) -{ - unsigned int ignored_mask; - XIGrabModifiers mods; - GArray *mods_array = g_array_new (FALSE, TRUE, sizeof (XIGrabModifiers)); - - /* The X server crashes if XIAnyModifier gets passed in with any - other bits. It doesn't make sense to ask for a grab of - XIAnyModifier plus other bits anyway so we avoid that. */ - if (modmask & XIAnyModifier) - { - mods = (XIGrabModifiers) { XIAnyModifier, 0 }; - g_array_append_val (mods_array, mods); - return mods_array; - } - - mods = (XIGrabModifiers) { modmask, 0 }; - g_array_append_val (mods_array, mods); - - for (ignored_mask = 1; - ignored_mask <= keys->ignored_modifier_mask; - ++ignored_mask) - { - if (ignored_mask & keys->ignored_modifier_mask) - { - mods = (XIGrabModifiers) { modmask | ignored_mask, 0 }; - g_array_append_val (mods_array, mods); - } - } - - return mods_array; -} - -static void -meta_change_button_grab (MetaKeyBindingManager *keys, - Window xwindow, - gboolean grab, - gboolean sync, - int button, - int modmask) -{ - if (meta_is_wayland_compositor ()) - return; - - MetaBackendX11 *backend = META_BACKEND_X11 (keys->backend); - Display *xdisplay = meta_backend_x11_get_xdisplay (backend); - - unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; - XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; - GArray *mods; - - XISetMask (mask.mask, XI_ButtonPress); - XISetMask (mask.mask, XI_ButtonRelease); - XISetMask (mask.mask, XI_Motion); - - mods = calc_grab_modifiers (keys, modmask); - - /* GrabModeSync means freeze until XAllowEvents */ - if (grab) - XIGrabButton (xdisplay, - META_VIRTUAL_CORE_POINTER_ID, - button, xwindow, None, - sync ? XIGrabModeSync : XIGrabModeAsync, - XIGrabModeAsync, False, - &mask, mods->len, (XIGrabModifiers *)mods->data); - else - XIUngrabButton (xdisplay, - META_VIRTUAL_CORE_POINTER_ID, - button, xwindow, mods->len, (XIGrabModifiers *)mods->data); - - g_array_free (mods, TRUE); -} -#endif - ClutterModifierType meta_display_get_compositor_modifiers (MetaDisplay *display) { @@ -1245,71 +1123,6 @@ meta_display_get_compositor_modifiers (MetaDisplay *display) return keys->window_grab_modifiers; } -#ifdef HAVE_X11_CLIENT -static void -meta_change_buttons_grab (MetaKeyBindingManager *keys, - Window xwindow, - gboolean grab, - gboolean sync, - int modmask) -{ -#define MAX_BUTTON 3 - - int i; - for (i = 1; i <= MAX_BUTTON; i++) - meta_change_button_grab (keys, xwindow, grab, sync, i, modmask); -} - -void -meta_display_grab_window_buttons (MetaDisplay *display, - Window xwindow) -{ - MetaKeyBindingManager *keys = &display->key_binding_manager; - - /* Grab Alt + button1 for moving window. - * Grab Alt + button2 for resizing window. - * Grab Alt + button3 for popping up window menu. - * Grab Alt + Shift + button1 for snap-moving window. - */ - meta_verbose ("Grabbing window buttons for 0x%lx", xwindow); - - /* FIXME If we ignored errors here instead of spewing, we could - * put one big error trap around the loop and avoid a bunch of - * XSync() - */ - - if (keys->window_grab_modifiers != 0) - { - meta_change_buttons_grab (keys, xwindow, TRUE, FALSE, - keys->window_grab_modifiers); - - /* In addition to grabbing Alt+Button1 for moving the window, - * grab Alt+Shift+Button1 for snap-moving the window. See bug - * 112478. Unfortunately, this doesn't work with - * Shift+Alt+Button1 for some reason; so at least part of the - * order still matters, which sucks (please FIXME). - */ - meta_change_button_grab (keys, xwindow, - TRUE, - FALSE, - 1, keys->window_grab_modifiers | ShiftMask); - } -} - -void -meta_display_ungrab_window_buttons (MetaDisplay *display, - Window xwindow) -{ - MetaKeyBindingManager *keys = &display->key_binding_manager; - - if (keys->window_grab_modifiers == 0) - return; - - meta_change_buttons_grab (keys, xwindow, FALSE, FALSE, - keys->window_grab_modifiers); -} -#endif /* HAVE_X11_CLIENT */ - static void update_window_grab_modifiers (MetaDisplay *display) { @@ -1327,47 +1140,6 @@ update_window_grab_modifiers (MetaDisplay *display) } } -#ifdef HAVE_X11_CLIENT -void -meta_display_grab_focus_window_button (MetaDisplay *display, - MetaWindow *window) -{ - MetaKeyBindingManager *keys = &display->key_binding_manager; - - /* Grab button 1 for activating unfocused windows */ - meta_verbose ("Grabbing unfocused window buttons for %s", window->desc); - - if (window->have_focus_click_grab) - { - meta_verbose (" (well, not grabbing since we already have the grab)"); - return; - } - - /* FIXME If we ignored errors here instead of spewing, we could - * put one big error trap around the loop and avoid a bunch of - * XSync() - */ - - meta_change_buttons_grab (keys, window->xwindow, TRUE, TRUE, XIAnyModifier); - window->have_focus_click_grab = TRUE; -} - -void -meta_display_ungrab_focus_window_button (MetaDisplay *display, - MetaWindow *window) -{ - MetaKeyBindingManager *keys = &display->key_binding_manager; - - meta_verbose ("Ungrabbing unfocused window buttons for %s", window->desc); - - if (!window->have_focus_click_grab) - return; - - meta_change_buttons_grab (keys, window->xwindow, FALSE, FALSE, XIAnyModifier); - window->have_focus_click_grab = FALSE; -} -#endif - static void prefs_changed_callback (MetaPreference pref, void *data) @@ -1385,13 +1157,13 @@ prefs_changed_callback (MetaPreference pref, break; case META_PREF_KEYBINDINGS: #ifdef HAVE_X11_CLIENT - ungrab_key_bindings (display); + meta_x11_display_ungrab_key_bindings (display); #endif rebuild_key_binding_table (keys); rebuild_special_bindings (keys); reload_combos (keys); #ifdef HAVE_X11_CLIENT - grab_key_bindings (display); + meta_x11_display_grab_key_bindings (display); #endif break; case META_PREF_MOUSE_BUTTON_MODS: @@ -1438,229 +1210,6 @@ meta_display_shutdown_keys (MetaDisplay *display) clear_active_keyboard_layouts (keys); } -/* Grab/ungrab, ignoring all annoying modifiers like NumLock etc. */ -#ifdef HAVE_X11_CLIENT -static void -meta_change_keygrab (MetaKeyBindingManager *keys, - Window xwindow, - gboolean grab, - MetaResolvedKeyCombo *resolved_combo) -{ - unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; - XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; - - XISetMask (mask.mask, XI_KeyPress); - XISetMask (mask.mask, XI_KeyRelease); - - MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ()); - Display *xdisplay = meta_backend_x11_get_xdisplay (backend); - GArray *mods; - int i; - - /* Grab keycode/modmask, together with - * all combinations of ignored modifiers. - * X provides no better way to do this. - */ - - mods = calc_grab_modifiers (keys, resolved_combo->mask); - - for (i = 0; i < resolved_combo->len; i++) - { - xkb_keycode_t keycode = resolved_combo->keycodes[i]; - - meta_topic (META_DEBUG_KEYBINDINGS, - "%s keybinding keycode %d mask 0x%x on 0x%lx", - grab ? "Grabbing" : "Ungrabbing", - keycode, resolved_combo->mask, xwindow); - - if (grab) - XIGrabKeycode (xdisplay, - META_VIRTUAL_CORE_KEYBOARD_ID, - keycode, xwindow, - XIGrabModeSync, XIGrabModeAsync, - False, &mask, mods->len, (XIGrabModifiers *)mods->data); - else - XIUngrabKeycode (xdisplay, - META_VIRTUAL_CORE_KEYBOARD_ID, - keycode, xwindow, - mods->len, (XIGrabModifiers *)mods->data); - } - - g_array_free (mods, TRUE); -} - -typedef struct -{ - MetaKeyBindingManager *keys; - Window xwindow; - gboolean only_per_window; - gboolean grab; -} ChangeKeygrabData; - -static void -change_keygrab_foreach (gpointer key, - gpointer value, - gpointer user_data) -{ - ChangeKeygrabData *data = user_data; - MetaKeyBinding *binding = value; - gboolean binding_is_per_window = (binding->flags & META_KEY_BINDING_PER_WINDOW) != 0; - - if (data->only_per_window != binding_is_per_window) - return; - - /* Ignore the key bindings marked as META_KEY_BINDING_NO_AUTO_GRAB, - * those are handled separately - */ - if (binding->flags & META_KEY_BINDING_NO_AUTO_GRAB) - return; - - if (binding->resolved_combo.len == 0) - return; - - meta_change_keygrab (data->keys, data->xwindow, data->grab, &binding->resolved_combo); -} - -static void -change_binding_keygrabs (MetaKeyBindingManager *keys, - Window xwindow, - gboolean only_per_window, - gboolean grab) -{ - ChangeKeygrabData data; - - data.keys = keys; - data.xwindow = xwindow; - data.only_per_window = only_per_window; - data.grab = grab; - - g_hash_table_foreach (keys->key_bindings, change_keygrab_foreach, &data); -} - -static void -maybe_update_locate_pointer_keygrab (MetaDisplay *display, - gboolean grab) -{ - MetaKeyBindingManager *keys = &display->key_binding_manager; - - if (!display->x11_display) - return; - - if (keys->locate_pointer_resolved_key_combo.len != 0) - meta_change_keygrab (keys, display->x11_display->xroot, - (!!grab & !!meta_prefs_is_locate_pointer_enabled()), - &keys->locate_pointer_resolved_key_combo); -} - -static void -meta_x11_display_change_keygrabs (MetaX11Display *x11_display, - gboolean grab) -{ - MetaKeyBindingManager *keys = &x11_display->display->key_binding_manager; - int i; - - if (keys->overlay_resolved_key_combo.len != 0) - meta_change_keygrab (keys, x11_display->xroot, - grab, &keys->overlay_resolved_key_combo); - - maybe_update_locate_pointer_keygrab (x11_display->display, grab); - - for (i = 0; i < keys->n_iso_next_group_combos; i++) - meta_change_keygrab (keys, x11_display->xroot, - grab, &keys->iso_next_group_combo[i]); - - change_binding_keygrabs (keys, x11_display->xroot, - FALSE, grab); -} - -void -meta_x11_display_grab_keys (MetaX11Display *x11_display) -{ - if (x11_display->keys_grabbed) - return; - - meta_x11_display_change_keygrabs (x11_display, TRUE); - - x11_display->keys_grabbed = TRUE; -} - -void -meta_x11_display_ungrab_keys (MetaX11Display *x11_display) -{ - if (!x11_display->keys_grabbed) - return; - - meta_x11_display_change_keygrabs (x11_display, FALSE); - - x11_display->keys_grabbed = FALSE; -} - -static void -change_window_keygrabs (MetaKeyBindingManager *keys, - Window xwindow, - gboolean grab) -{ - change_binding_keygrabs (keys, xwindow, TRUE, grab); -} - -void -meta_window_grab_keys (MetaWindow *window) -{ - MetaDisplay *display = window->display; - MetaKeyBindingManager *keys = &display->key_binding_manager; - - if (meta_is_wayland_compositor ()) - return; - if (window->all_keys_grabbed) - return; - - if (window->type == META_WINDOW_DOCK - || window->override_redirect) - { - if (window->keys_grabbed) - change_window_keygrabs (keys, window->xwindow, FALSE); - window->keys_grabbed = FALSE; - return; - } - - if (window->keys_grabbed) - { - if (window->frame && !window->grab_on_frame) - change_window_keygrabs (keys, window->xwindow, FALSE); - else if (window->frame == NULL && - window->grab_on_frame) - ; /* continue to regrab on client window */ - else - return; /* already all good */ - } - - change_window_keygrabs (keys, - meta_window_x11_get_toplevel_xwindow (window), - TRUE); - - window->keys_grabbed = TRUE; - window->grab_on_frame = window->frame != NULL; -} - -void -meta_window_ungrab_keys (MetaWindow *window) -{ - if (!meta_is_wayland_compositor () && window->keys_grabbed) - { - MetaDisplay *display = window->display; - MetaKeyBindingManager *keys = &display->key_binding_manager; - - if (window->grab_on_frame && - window->frame != NULL) - change_window_keygrabs (keys, window->frame->xwindow, FALSE); - else if (!window->grab_on_frame) - change_window_keygrabs (keys, window->xwindow, FALSE); - - window->keys_grabbed = FALSE; - } -} -#endif /* HAVE_X11_CLIENT */ - static void handle_external_grab (MetaDisplay *display, MetaWindow *window, diff --git a/src/core/window.c b/src/core/window.c index 0eef063b0..2a093a685 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -74,7 +74,6 @@ #include "core/constraints.h" #include "core/edge-resistance.h" #include "core/frame.h" -#include "core/keybindings-private.h" #include "core/meta-workspace-manager-private.h" #include "core/place.h" #include "core/stack.h" @@ -89,6 +88,7 @@ #include "meta/group.h" #include "ui/ui.h" #include "meta/meta-x11-errors.h" +#include "x11/keybindings-x11-private.h" #include "x11/meta-x11-display-private.h" #include "x11/window-props.h" #include "x11/window-x11.h" diff --git a/src/meson.build b/src/meson.build index fbe9fb835..f0a7d82ce 100644 --- a/src/meson.build +++ b/src/meson.build @@ -444,6 +444,8 @@ if have_x11_client 'x11/group-props.h', 'x11/iconcache.c', 'x11/iconcache.h', + 'x11/keybindings-x11.c', + 'x11/keybindings-x11-private.h', 'x11/meta-selection-source-x11.c', 'x11/meta-selection-source-x11-private.h', 'x11/meta-startup-notification-x11.c', diff --git a/src/x11/keybindings-x11-private.h b/src/x11/keybindings-x11-private.h new file mode 100644 index 000000000..bec3d85c5 --- /dev/null +++ b/src/x11/keybindings-x11-private.h @@ -0,0 +1,20 @@ +#ifndef META_KEYBINDINGS_X11_PRIVATE_H +#define META_KEYBINDINGS_X11_PRIVATE_H + +void meta_window_grab_keys (MetaWindow *window); +void meta_window_ungrab_keys (MetaWindow *window); + +void meta_x11_display_grab_keys (MetaX11Display *x11_display); +void meta_x11_display_ungrab_keys (MetaX11Display *x11_display); +void meta_x11_display_ungrab_key_bindings (MetaDisplay *display); +void meta_x11_display_grab_key_bindings (MetaDisplay *display); + +void maybe_update_locate_pointer_keygrab (MetaDisplay *display, + gboolean grab); + +void meta_change_keygrab (MetaKeyBindingManager *keys, + Window xwindow, + gboolean grab, + MetaResolvedKeyCombo *resolved_combo); + +#endif diff --git a/src/x11/keybindings-x11.c b/src/x11/keybindings-x11.c new file mode 100644 index 000000000..240d262e5 --- /dev/null +++ b/src/x11/keybindings-x11.c @@ -0,0 +1,440 @@ +#include "backends/x11/meta-backend-x11.h" +#include "backends/x11/meta-input-device-x11.h" +#include "core/frame.h" +#include "x11/keybindings-x11-private.h" +#include "x11/meta-x11-display-private.h" +#include "x11/window-x11.h" + +static GArray * +calc_grab_modifiers (MetaKeyBindingManager *keys, + unsigned int modmask) +{ + unsigned int ignored_mask; + XIGrabModifiers mods; + GArray *mods_array = g_array_new (FALSE, TRUE, sizeof (XIGrabModifiers)); + + /* The X server crashes if XIAnyModifier gets passed in with any + other bits. It doesn't make sense to ask for a grab of + XIAnyModifier plus other bits anyway so we avoid that. */ + if (modmask & XIAnyModifier) + { + mods = (XIGrabModifiers) { XIAnyModifier, 0 }; + g_array_append_val (mods_array, mods); + return mods_array; + } + + mods = (XIGrabModifiers) { modmask, 0 }; + g_array_append_val (mods_array, mods); + + for (ignored_mask = 1; + ignored_mask <= keys->ignored_modifier_mask; + ++ignored_mask) + { + if (ignored_mask & keys->ignored_modifier_mask) + { + mods = (XIGrabModifiers) { modmask | ignored_mask, 0 }; + g_array_append_val (mods_array, mods); + } + } + + return mods_array; +} + +static void +meta_change_button_grab (MetaKeyBindingManager *keys, + Window xwindow, + gboolean grab, + gboolean sync, + int button, + int modmask) +{ + if (meta_is_wayland_compositor ()) + return; + + MetaBackendX11 *backend = META_BACKEND_X11 (keys->backend); + Display *xdisplay = meta_backend_x11_get_xdisplay (backend); + + unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; + XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; + GArray *mods; + + XISetMask (mask.mask, XI_ButtonPress); + XISetMask (mask.mask, XI_ButtonRelease); + XISetMask (mask.mask, XI_Motion); + + mods = calc_grab_modifiers (keys, modmask); + + /* GrabModeSync means freeze until XAllowEvents */ + if (grab) + XIGrabButton (xdisplay, + META_VIRTUAL_CORE_POINTER_ID, + button, xwindow, None, + sync ? XIGrabModeSync : XIGrabModeAsync, + XIGrabModeAsync, False, + &mask, mods->len, (XIGrabModifiers *)mods->data); + else + XIUngrabButton (xdisplay, + META_VIRTUAL_CORE_POINTER_ID, + button, xwindow, mods->len, (XIGrabModifiers *)mods->data); + + g_array_free (mods, TRUE); +} + +static void +meta_change_buttons_grab (MetaKeyBindingManager *keys, + Window xwindow, + gboolean grab, + gboolean sync, + int modmask) +{ +#define MAX_BUTTON 3 + + int i; + for (i = 1; i <= MAX_BUTTON; i++) + meta_change_button_grab (keys, xwindow, grab, sync, i, modmask); +} + +void +meta_display_grab_window_buttons (MetaDisplay *display, + Window xwindow) +{ + MetaKeyBindingManager *keys = &display->key_binding_manager; + + /* Grab Alt + button1 for moving window. + * Grab Alt + button2 for resizing window. + * Grab Alt + button3 for popping up window menu. + * Grab Alt + Shift + button1 for snap-moving window. + */ + meta_verbose ("Grabbing window buttons for 0x%lx", xwindow); + + /* FIXME If we ignored errors here instead of spewing, we could + * put one big error trap around the loop and avoid a bunch of + * XSync() + */ + + if (keys->window_grab_modifiers != 0) + { + meta_change_buttons_grab (keys, xwindow, TRUE, FALSE, + keys->window_grab_modifiers); + + /* In addition to grabbing Alt+Button1 for moving the window, + * grab Alt+Shift+Button1 for snap-moving the window. See bug + * 112478. Unfortunately, this doesn't work with + * Shift+Alt+Button1 for some reason; so at least part of the + * order still matters, which sucks (please FIXME). + */ + meta_change_button_grab (keys, xwindow, + TRUE, + FALSE, + 1, keys->window_grab_modifiers | ShiftMask); + } +} + +void +meta_display_ungrab_window_buttons (MetaDisplay *display, + Window xwindow) +{ + MetaKeyBindingManager *keys = &display->key_binding_manager; + + if (keys->window_grab_modifiers == 0) + return; + + meta_change_buttons_grab (keys, xwindow, FALSE, FALSE, + keys->window_grab_modifiers); +} + +void +meta_display_grab_focus_window_button (MetaDisplay *display, + MetaWindow *window) +{ + MetaKeyBindingManager *keys = &display->key_binding_manager; + + /* Grab button 1 for activating unfocused windows */ + meta_verbose ("Grabbing unfocused window buttons for %s", window->desc); + + if (window->have_focus_click_grab) + { + meta_verbose (" (well, not grabbing since we already have the grab)"); + return; + } + + /* FIXME If we ignored errors here instead of spewing, we could + * put one big error trap around the loop and avoid a bunch of + * XSync() + */ + + meta_change_buttons_grab (keys, window->xwindow, TRUE, TRUE, XIAnyModifier); + window->have_focus_click_grab = TRUE; +} + +void +meta_display_ungrab_focus_window_button (MetaDisplay *display, + MetaWindow *window) +{ + MetaKeyBindingManager *keys = &display->key_binding_manager; + + meta_verbose ("Ungrabbing unfocused window buttons for %s", window->desc); + + if (!window->have_focus_click_grab) + return; + + meta_change_buttons_grab (keys, window->xwindow, FALSE, FALSE, XIAnyModifier); + window->have_focus_click_grab = FALSE; +} + +/* Grab/ungrab, ignoring all annoying modifiers like NumLock etc. */ +void +meta_change_keygrab (MetaKeyBindingManager *keys, + Window xwindow, + gboolean grab, + MetaResolvedKeyCombo *resolved_combo) +{ + unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; + XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; + + XISetMask (mask.mask, XI_KeyPress); + XISetMask (mask.mask, XI_KeyRelease); + + MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ()); + Display *xdisplay = meta_backend_x11_get_xdisplay (backend); + GArray *mods; + int i; + + /* Grab keycode/modmask, together with + * all combinations of ignored modifiers. + * X provides no better way to do this. + */ + + mods = calc_grab_modifiers (keys, resolved_combo->mask); + + for (i = 0; i < resolved_combo->len; i++) + { + xkb_keycode_t keycode = resolved_combo->keycodes[i]; + + meta_topic (META_DEBUG_KEYBINDINGS, + "%s keybinding keycode %d mask 0x%x on 0x%lx", + grab ? "Grabbing" : "Ungrabbing", + keycode, resolved_combo->mask, xwindow); + + if (grab) + XIGrabKeycode (xdisplay, + META_VIRTUAL_CORE_KEYBOARD_ID, + keycode, xwindow, + XIGrabModeSync, XIGrabModeAsync, + False, &mask, mods->len, (XIGrabModifiers *)mods->data); + else + XIUngrabKeycode (xdisplay, + META_VIRTUAL_CORE_KEYBOARD_ID, + keycode, xwindow, + mods->len, (XIGrabModifiers *)mods->data); + } + + g_array_free (mods, TRUE); +} + +typedef struct +{ + MetaKeyBindingManager *keys; + Window xwindow; + gboolean only_per_window; + gboolean grab; +} ChangeKeygrabData; + +static void +change_keygrab_foreach (gpointer key, + gpointer value, + gpointer user_data) +{ + ChangeKeygrabData *data = user_data; + MetaKeyBinding *binding = value; + gboolean binding_is_per_window = (binding->flags & META_KEY_BINDING_PER_WINDOW) != 0; + + if (data->only_per_window != binding_is_per_window) + return; + + /* Ignore the key bindings marked as META_KEY_BINDING_NO_AUTO_GRAB, + * those are handled separately + */ + if (binding->flags & META_KEY_BINDING_NO_AUTO_GRAB) + return; + + if (binding->resolved_combo.len == 0) + return; + + meta_change_keygrab (data->keys, data->xwindow, data->grab, &binding->resolved_combo); +} + +static void +change_binding_keygrabs (MetaKeyBindingManager *keys, + Window xwindow, + gboolean only_per_window, + gboolean grab) +{ + ChangeKeygrabData data; + + data.keys = keys; + data.xwindow = xwindow; + data.only_per_window = only_per_window; + data.grab = grab; + + g_hash_table_foreach (keys->key_bindings, change_keygrab_foreach, &data); +} + +void +maybe_update_locate_pointer_keygrab (MetaDisplay *display, + gboolean grab) +{ + MetaKeyBindingManager *keys = &display->key_binding_manager; + + if (!display->x11_display) + return; + + if (keys->locate_pointer_resolved_key_combo.len != 0) + meta_change_keygrab (keys, display->x11_display->xroot, + (!!grab & !!meta_prefs_is_locate_pointer_enabled()), + &keys->locate_pointer_resolved_key_combo); +} + +static void +meta_x11_display_change_keygrabs (MetaX11Display *x11_display, + gboolean grab) +{ + MetaKeyBindingManager *keys = &x11_display->display->key_binding_manager; + int i; + + if (keys->overlay_resolved_key_combo.len != 0) + meta_change_keygrab (keys, x11_display->xroot, + grab, &keys->overlay_resolved_key_combo); + + maybe_update_locate_pointer_keygrab (x11_display->display, grab); + + for (i = 0; i < keys->n_iso_next_group_combos; i++) + meta_change_keygrab (keys, x11_display->xroot, + grab, &keys->iso_next_group_combo[i]); + + change_binding_keygrabs (keys, x11_display->xroot, + FALSE, grab); +} + +static void +change_window_keygrabs (MetaKeyBindingManager *keys, + Window xwindow, + gboolean grab) +{ + change_binding_keygrabs (keys, xwindow, TRUE, grab); +} + +void +meta_window_grab_keys (MetaWindow *window) +{ + MetaDisplay *display = window->display; + MetaKeyBindingManager *keys = &display->key_binding_manager; + + if (meta_is_wayland_compositor ()) + return; + if (window->all_keys_grabbed) + return; + + if (window->type == META_WINDOW_DOCK + || window->override_redirect) + { + if (window->keys_grabbed) + change_window_keygrabs (keys, window->xwindow, FALSE); + window->keys_grabbed = FALSE; + return; + } + + if (window->keys_grabbed) + { + if (window->frame && !window->grab_on_frame) + change_window_keygrabs (keys, window->xwindow, FALSE); + else if (window->frame == NULL && + window->grab_on_frame) + ; /* continue to regrab on client window */ + else + return; /* already all good */ + } + + change_window_keygrabs (keys, + meta_window_x11_get_toplevel_xwindow (window), + TRUE); + + window->keys_grabbed = TRUE; + window->grab_on_frame = window->frame != NULL; +} + +void +meta_window_ungrab_keys (MetaWindow *window) +{ + if (!meta_is_wayland_compositor () && window->keys_grabbed) + { + MetaDisplay *display = window->display; + MetaKeyBindingManager *keys = &display->key_binding_manager; + + if (window->grab_on_frame && + window->frame != NULL) + change_window_keygrabs (keys, window->frame->xwindow, FALSE); + else if (!window->grab_on_frame) + change_window_keygrabs (keys, window->xwindow, FALSE); + + window->keys_grabbed = FALSE; + } +} + +void +meta_x11_display_grab_keys (MetaX11Display *x11_display) +{ + if (x11_display->keys_grabbed) + return; + + meta_x11_display_change_keygrabs (x11_display, TRUE); + + x11_display->keys_grabbed = TRUE; +} + +void +meta_x11_display_ungrab_keys (MetaX11Display *x11_display) +{ + if (!x11_display->keys_grabbed) + return; + + meta_x11_display_change_keygrabs (x11_display, FALSE); + + x11_display->keys_grabbed = FALSE; +} + +void +meta_x11_display_grab_key_bindings (MetaDisplay *display) +{ + GSList *windows, *l; + + if (display->x11_display) + meta_x11_display_grab_keys (display->x11_display); + + windows = meta_display_list_windows (display, META_LIST_DEFAULT); + for (l = windows; l; l = l->next) + { + MetaWindow *w = l->data; + meta_window_grab_keys (w); + } + + g_slist_free (windows); +} + +void +meta_x11_display_ungrab_key_bindings (MetaDisplay *display) +{ + GSList *windows, *l; + + if (display->x11_display) + meta_x11_display_ungrab_keys (display->x11_display); + + windows = meta_display_list_windows (display, META_LIST_DEFAULT); + for (l = windows; l; l = l->next) + { + MetaWindow *w = l->data; + meta_window_ungrab_keys (w); + } + + g_slist_free (windows); +} diff --git a/src/x11/meta-x11-display-private.h b/src/x11/meta-x11-display-private.h index 9158387d6..ff5277489 100644 --- a/src/x11/meta-x11-display-private.h +++ b/src/x11/meta-x11-display-private.h @@ -253,4 +253,14 @@ MetaDisplay * meta_x11_display_get_display (MetaX11Display *x11_display); const gchar * meta_x11_get_display_name (void); + +void meta_display_grab_window_buttons (MetaDisplay *display, + Window xwindow); +void meta_display_ungrab_window_buttons (MetaDisplay *display, + Window xwindow); +void meta_display_grab_focus_window_button (MetaDisplay *display, + MetaWindow *window); +void meta_display_ungrab_focus_window_button (MetaDisplay *display, + MetaWindow *window); + #endif /* META_X11_DISPLAY_PRIVATE_H */ diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c index fdd4b8010..80c7e63ce 100644 --- a/src/x11/meta-x11-display.c +++ b/src/x11/meta-x11-display.c @@ -63,6 +63,7 @@ #include "x11/events.h" #include "x11/group-props.h" +#include "x11/keybindings-x11-private.h" #include "x11/meta-x11-selection-private.h" #include "x11/window-props.h" #include "x11/xprops.h" diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index 617a1dfaa..afb6ca3c2 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -47,6 +47,7 @@ #include "meta/meta-later.h" #include "meta/meta-x11-errors.h" #include "meta/prefs.h" +#include "x11/keybindings-x11-private.h" #include "x11/meta-x11-display-private.h" #include "x11/session.h" #include "x11/window-props.h" |