summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBilal Elmoussaoui <belmouss@redhat.com>2022-06-20 13:00:08 +0200
committerBilal Elmoussaoui <belmouss@redhat.com>2022-08-02 09:51:54 +0200
commit90b2cd0158be5f82c4c8f05227a3970c349e412f (patch)
tree62606f2f873635f3ffafaa41caf4bb7af8c847e5
parent444b81f1897bb64177186a815e752b241b1cafb6 (diff)
downloadmutter-bilelmoussaoui/keybindings.tar.gz
x11: Move X11 specific functions to x11/keybindingsbilelmoussaoui/keybindings
-rw-r--r--src/core/display-private.h11
-rw-r--r--src/core/frame.c2
-rw-r--r--src/core/keybindings-private.h7
-rw-r--r--src/core/keybindings.c461
-rw-r--r--src/core/window.c2
-rw-r--r--src/meson.build2
-rw-r--r--src/x11/keybindings-x11-private.h20
-rw-r--r--src/x11/keybindings-x11.c440
-rw-r--r--src/x11/meta-x11-display-private.h10
-rw-r--r--src/x11/meta-x11-display.c1
-rw-r--r--src/x11/window-x11.c1
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"