keybindings: Move X11 bits to a separate header
Reduces the noise in terms of ifdef and makes it much easier to spot which X11 bits are still mixed in the generic keybindings file Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3776>
This commit is contained in:
@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#ifdef HAVE_X11_CLIENT
|
#ifdef HAVE_X11_CLIENT
|
||||||
#include "x11/meta-x11-frame.h"
|
#include "x11/meta-x11-frame.h"
|
||||||
|
#include "x11/meta-x11-keybindings-private.h"
|
||||||
#include "x11/window-x11.h"
|
#include "x11/window-x11.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -39,6 +39,9 @@
|
|||||||
#include "meta/common.h"
|
#include "meta/common.h"
|
||||||
#include "meta/meta-selection.h"
|
#include "meta/meta-selection.h"
|
||||||
#include "meta/prefs.h"
|
#include "meta/prefs.h"
|
||||||
|
#ifdef HAVE_X11_CLIENT
|
||||||
|
#include "meta/meta-x11-types.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct _MetaBell MetaBell;
|
typedef struct _MetaBell MetaBell;
|
||||||
typedef struct _MetaStack MetaStack;
|
typedef struct _MetaStack MetaStack;
|
||||||
@ -229,17 +232,6 @@ void meta_display_notify_window_created (MetaDisplay *display,
|
|||||||
META_EXPORT_TEST
|
META_EXPORT_TEST
|
||||||
GSList* meta_display_list_windows (MetaDisplay *display,
|
GSList* meta_display_list_windows (MetaDisplay *display,
|
||||||
MetaListWindowsFlags flags);
|
MetaListWindowsFlags flags);
|
||||||
#ifdef HAVE_X11
|
|
||||||
void meta_display_grab_window_buttons (MetaDisplay *display,
|
|
||||||
MetaWindow *window);
|
|
||||||
void meta_display_ungrab_window_buttons (MetaDisplay *display,
|
|
||||||
MetaWindow *window);
|
|
||||||
|
|
||||||
void meta_display_grab_focus_window_button (MetaDisplay *display,
|
|
||||||
MetaWindow *window);
|
|
||||||
void meta_display_ungrab_focus_window_button (MetaDisplay *display,
|
|
||||||
MetaWindow *window);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void meta_display_ping_window (MetaWindow *window,
|
void meta_display_ping_window (MetaWindow *window,
|
||||||
guint32 serial);
|
guint32 serial);
|
||||||
|
@ -31,9 +31,6 @@
|
|||||||
|
|
||||||
#include "core/meta-accel-parse.h"
|
#include "core/meta-accel-parse.h"
|
||||||
#include "meta/keybindings.h"
|
#include "meta/keybindings.h"
|
||||||
#ifdef HAVE_X11
|
|
||||||
#include "meta/meta-x11-types.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct _MetaKeyHandler MetaKeyHandler;
|
typedef struct _MetaKeyHandler MetaKeyHandler;
|
||||||
struct _MetaKeyHandler
|
struct _MetaKeyHandler
|
||||||
@ -138,10 +135,6 @@ typedef struct
|
|||||||
|
|
||||||
void meta_display_init_keys (MetaDisplay *display);
|
void meta_display_init_keys (MetaDisplay *display);
|
||||||
void meta_display_shutdown_keys (MetaDisplay *display);
|
void meta_display_shutdown_keys (MetaDisplay *display);
|
||||||
#ifdef HAVE_X11
|
|
||||||
void meta_window_grab_keys (MetaWindow *window);
|
|
||||||
void meta_window_ungrab_keys (MetaWindow *window);
|
|
||||||
#endif
|
|
||||||
gboolean meta_keybindings_process_event (MetaDisplay *display,
|
gboolean meta_keybindings_process_event (MetaDisplay *display,
|
||||||
MetaWindow *window,
|
MetaWindow *window,
|
||||||
const ClutterEvent *event);
|
const ClutterEvent *event);
|
||||||
@ -159,11 +152,6 @@ void meta_prefs_get_locate_pointer_binding (MetaKeyCombo *combo);
|
|||||||
const char *meta_prefs_get_iso_next_group_option (void);
|
const char *meta_prefs_get_iso_next_group_option (void);
|
||||||
gboolean meta_prefs_is_locate_pointer_enabled (void);
|
gboolean meta_prefs_is_locate_pointer_enabled (void);
|
||||||
|
|
||||||
#ifdef HAVE_X11
|
|
||||||
void meta_x11_display_grab_keys (MetaX11Display *x11_display);
|
|
||||||
void meta_x11_display_ungrab_keys (MetaX11Display *x11_display);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gboolean meta_display_process_keybinding_event (MetaDisplay *display,
|
gboolean meta_display_process_keybinding_event (MetaDisplay *display,
|
||||||
const char *name,
|
const char *name,
|
||||||
const ClutterEvent *event);
|
const ClutterEvent *event);
|
||||||
|
@ -43,12 +43,9 @@
|
|||||||
|
|
||||||
#ifdef HAVE_X11
|
#ifdef HAVE_X11
|
||||||
#include "backends/x11/meta-backend-x11.h"
|
#include "backends/x11/meta-backend-x11.h"
|
||||||
#include "backends/x11/meta-clutter-backend-x11.h"
|
|
||||||
#include "backends/x11/meta-input-device-x11.h"
|
#include "backends/x11/meta-input-device-x11.h"
|
||||||
#include "mtk/mtk-x11.h"
|
|
||||||
#include "x11/meta-x11-display-private.h"
|
#include "x11/meta-x11-display-private.h"
|
||||||
#include "x11/meta-x11-frame.h"
|
#include "x11/meta-x11-keybindings-private.h"
|
||||||
#include "x11/window-x11-private.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_NATIVE_BACKEND
|
#ifdef HAVE_NATIVE_BACKEND
|
||||||
@ -183,11 +180,6 @@ meta_key_binding_is_builtin (MetaKeyBinding *binding)
|
|||||||
* handler functions and have some kind of flag to say they're unbindable.
|
* handler functions and have some kind of flag to say they're unbindable.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_X11
|
|
||||||
static void maybe_update_locate_pointer_keygrab (MetaDisplay *display,
|
|
||||||
gboolean grab);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static GHashTable *key_handlers;
|
static GHashTable *key_handlers;
|
||||||
static GHashTable *external_grabs;
|
static GHashTable *external_grabs;
|
||||||
|
|
||||||
@ -901,44 +893,6 @@ rebuild_special_bindings (MetaKeyBindingManager *keys)
|
|||||||
keys->locate_pointer_key_combo = combo;
|
keys->locate_pointer_key_combo = combo;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_X11
|
|
||||||
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 *
|
static MetaKeyBinding *
|
||||||
get_keybinding (MetaKeyBindingManager *keys,
|
get_keybinding (MetaKeyBindingManager *keys,
|
||||||
MetaResolvedKeyCombo *resolved_combo)
|
MetaResolvedKeyCombo *resolved_combo)
|
||||||
@ -1167,7 +1121,7 @@ reload_keybindings (MetaDisplay *display)
|
|||||||
MetaKeyBindingManager *keys = &display->key_binding_manager;
|
MetaKeyBindingManager *keys = &display->key_binding_manager;
|
||||||
|
|
||||||
#ifdef HAVE_X11
|
#ifdef HAVE_X11
|
||||||
ungrab_key_bindings (display);
|
meta_x11_keybindings_ungrab_key_bindings (display);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Deciphering the modmap depends on the loaded keysyms to find out
|
/* Deciphering the modmap depends on the loaded keysyms to find out
|
||||||
@ -1178,104 +1132,10 @@ reload_keybindings (MetaDisplay *display)
|
|||||||
reload_combos (keys);
|
reload_combos (keys);
|
||||||
|
|
||||||
#ifdef HAVE_X11
|
#ifdef HAVE_X11
|
||||||
grab_key_bindings (display);
|
meta_x11_keybindings_grab_key_bindings (display);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_X11
|
|
||||||
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,
|
|
||||||
MetaWindow *window,
|
|
||||||
gboolean grab,
|
|
||||||
gboolean sync,
|
|
||||||
int button,
|
|
||||||
int modmask)
|
|
||||||
{
|
|
||||||
MetaBackendX11 *backend;
|
|
||||||
Display *xdisplay;
|
|
||||||
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
|
|
||||||
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
|
|
||||||
Window xwindow;
|
|
||||||
GArray *mods;
|
|
||||||
MetaFrame *frame;
|
|
||||||
|
|
||||||
if (meta_is_wayland_compositor ())
|
|
||||||
return;
|
|
||||||
if (window->client_type != META_WINDOW_CLIENT_TYPE_X11)
|
|
||||||
return;
|
|
||||||
|
|
||||||
backend = META_BACKEND_X11 (keys->backend);
|
|
||||||
xdisplay = meta_backend_x11_get_xdisplay (backend);
|
|
||||||
|
|
||||||
XISetMask (mask.mask, XI_ButtonPress);
|
|
||||||
XISetMask (mask.mask, XI_ButtonRelease);
|
|
||||||
XISetMask (mask.mask, XI_Motion);
|
|
||||||
|
|
||||||
mods = calc_grab_modifiers (keys, modmask);
|
|
||||||
|
|
||||||
mtk_x11_error_trap_push (xdisplay);
|
|
||||||
frame = meta_window_x11_get_frame (window);
|
|
||||||
if (frame)
|
|
||||||
xwindow = frame->xwindow;
|
|
||||||
else
|
|
||||||
xwindow = meta_window_x11_get_xwindow (window);
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
|
|
||||||
XSync (xdisplay, False);
|
|
||||||
|
|
||||||
mtk_x11_error_trap_pop (xdisplay);
|
|
||||||
|
|
||||||
g_array_free (mods, TRUE);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ClutterModifierType
|
ClutterModifierType
|
||||||
meta_display_get_compositor_modifiers (MetaDisplay *display)
|
meta_display_get_compositor_modifiers (MetaDisplay *display)
|
||||||
{
|
{
|
||||||
@ -1283,71 +1143,6 @@ meta_display_get_compositor_modifiers (MetaDisplay *display)
|
|||||||
return keys->window_grab_modifiers;
|
return keys->window_grab_modifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_X11
|
|
||||||
static void
|
|
||||||
meta_change_buttons_grab (MetaKeyBindingManager *keys,
|
|
||||||
MetaWindow *window,
|
|
||||||
gboolean grab,
|
|
||||||
gboolean sync,
|
|
||||||
int modmask)
|
|
||||||
{
|
|
||||||
#define MAX_BUTTON 3
|
|
||||||
|
|
||||||
int i;
|
|
||||||
for (i = 1; i <= MAX_BUTTON; i++)
|
|
||||||
meta_change_button_grab (keys, window, grab, sync, i, modmask);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_display_grab_window_buttons (MetaDisplay *display,
|
|
||||||
MetaWindow *window)
|
|
||||||
{
|
|
||||||
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 %s", window->desc);
|
|
||||||
|
|
||||||
/* 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, window, 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, window,
|
|
||||||
TRUE,
|
|
||||||
FALSE,
|
|
||||||
1, keys->window_grab_modifiers | CLUTTER_SHIFT_MASK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_display_ungrab_window_buttons (MetaDisplay *display,
|
|
||||||
MetaWindow *window)
|
|
||||||
{
|
|
||||||
MetaKeyBindingManager *keys = &display->key_binding_manager;
|
|
||||||
|
|
||||||
if (keys->window_grab_modifiers == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
meta_change_buttons_grab (keys, window, FALSE, FALSE,
|
|
||||||
keys->window_grab_modifiers);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_window_grab_modifiers (MetaDisplay *display)
|
update_window_grab_modifiers (MetaDisplay *display)
|
||||||
{
|
{
|
||||||
@ -1365,47 +1160,6 @@ update_window_grab_modifiers (MetaDisplay *display)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_X11
|
|
||||||
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, 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, FALSE, FALSE, XIAnyModifier);
|
|
||||||
window->have_focus_click_grab = FALSE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
prefs_changed_callback (MetaPreference pref,
|
prefs_changed_callback (MetaPreference pref,
|
||||||
void *data)
|
void *data)
|
||||||
@ -1417,19 +1171,19 @@ prefs_changed_callback (MetaPreference pref,
|
|||||||
{
|
{
|
||||||
case META_PREF_LOCATE_POINTER:
|
case META_PREF_LOCATE_POINTER:
|
||||||
#ifdef HAVE_X11
|
#ifdef HAVE_X11
|
||||||
maybe_update_locate_pointer_keygrab (display,
|
meta_x11_keybindings_maybe_update_locate_pointer_keygrab (display,
|
||||||
meta_prefs_is_locate_pointer_enabled());
|
meta_prefs_is_locate_pointer_enabled ());
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case META_PREF_KEYBINDINGS:
|
case META_PREF_KEYBINDINGS:
|
||||||
#ifdef HAVE_X11
|
#ifdef HAVE_X11
|
||||||
ungrab_key_bindings (display);
|
meta_x11_keybindings_ungrab_key_bindings (display);
|
||||||
#endif
|
#endif
|
||||||
rebuild_key_binding_table (keys);
|
rebuild_key_binding_table (keys);
|
||||||
rebuild_special_bindings (keys);
|
rebuild_special_bindings (keys);
|
||||||
reload_combos (keys);
|
reload_combos (keys);
|
||||||
#ifdef HAVE_X11
|
#ifdef HAVE_X11
|
||||||
grab_key_bindings (display);
|
meta_x11_keybindings_grab_key_bindings (display);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case META_PREF_MOUSE_BUTTON_MODS:
|
case META_PREF_MOUSE_BUTTON_MODS:
|
||||||
@ -1441,7 +1195,7 @@ prefs_changed_callback (MetaPreference pref,
|
|||||||
for (l = windows; l; l = l->next)
|
for (l = windows; l; l = l->next)
|
||||||
{
|
{
|
||||||
MetaWindow *w = l->data;
|
MetaWindow *w = l->data;
|
||||||
meta_display_ungrab_window_buttons (display, w);
|
meta_x11_keybindings_ungrab_window_buttons (&display->key_binding_manager, w);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1452,7 +1206,7 @@ prefs_changed_callback (MetaPreference pref,
|
|||||||
{
|
{
|
||||||
MetaWindow *w = l->data;
|
MetaWindow *w = l->data;
|
||||||
if (w->type != META_WINDOW_DOCK)
|
if (w->type != META_WINDOW_DOCK)
|
||||||
meta_display_grab_window_buttons (display, w);
|
meta_x11_keybindings_grab_window_buttons (&display->key_binding_manager, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_slist_free (windows);
|
g_slist_free (windows);
|
||||||
@ -1463,7 +1217,6 @@ prefs_changed_callback (MetaPreference pref,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_display_shutdown_keys (MetaDisplay *display)
|
meta_display_shutdown_keys (MetaDisplay *display)
|
||||||
{
|
{
|
||||||
@ -1477,247 +1230,6 @@ meta_display_shutdown_keys (MetaDisplay *display)
|
|||||||
clear_active_keyboard_layouts (keys);
|
clear_active_keyboard_layouts (keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Grab/ungrab, ignoring all annoying modifiers like NumLock etc. */
|
|
||||||
#ifdef HAVE_X11
|
|
||||||
static void
|
|
||||||
meta_change_keygrab (MetaKeyBindingManager *keys,
|
|
||||||
Window xwindow,
|
|
||||||
gboolean grab,
|
|
||||||
MetaResolvedKeyCombo *resolved_combo)
|
|
||||||
{
|
|
||||||
MetaBackendX11 *backend_x11;
|
|
||||||
Display *xdisplay;
|
|
||||||
GArray *mods;
|
|
||||||
int i;
|
|
||||||
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);
|
|
||||||
|
|
||||||
if (meta_is_wayland_compositor ())
|
|
||||||
return;
|
|
||||||
|
|
||||||
backend_x11 = META_BACKEND_X11 (keys->backend);
|
|
||||||
xdisplay = meta_backend_x11_get_xdisplay (backend_x11);
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
|
|
||||||
mtk_x11_error_trap_push (xdisplay);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
XSync (xdisplay, False);
|
|
||||||
|
|
||||||
mtk_x11_error_trap_pop (xdisplay);
|
|
||||||
|
|
||||||
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;
|
|
||||||
MetaWindowX11Private *priv;
|
|
||||||
|
|
||||||
if (meta_is_wayland_compositor ())
|
|
||||||
return;
|
|
||||||
|
|
||||||
priv = meta_window_x11_get_private (META_WINDOW_X11 (window));
|
|
||||||
if (window->type == META_WINDOW_DOCK
|
|
||||||
|| window->override_redirect)
|
|
||||||
{
|
|
||||||
if (priv->keys_grabbed)
|
|
||||||
change_window_keygrabs (keys, meta_window_x11_get_xwindow (window), FALSE);
|
|
||||||
priv->keys_grabbed = FALSE;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priv->keys_grabbed)
|
|
||||||
{
|
|
||||||
if (priv->frame && !priv->grab_on_frame)
|
|
||||||
change_window_keygrabs (keys, meta_window_x11_get_xwindow (window), FALSE);
|
|
||||||
else if (priv->frame == NULL &&
|
|
||||||
priv->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);
|
|
||||||
|
|
||||||
priv->keys_grabbed = TRUE;
|
|
||||||
priv->grab_on_frame = priv->frame != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_window_ungrab_keys (MetaWindow *window)
|
|
||||||
{
|
|
||||||
MetaWindowX11Private *priv;
|
|
||||||
|
|
||||||
if (meta_is_wayland_compositor ())
|
|
||||||
return;
|
|
||||||
|
|
||||||
priv = meta_window_x11_get_private (META_WINDOW_X11 (window));
|
|
||||||
|
|
||||||
if (priv->keys_grabbed)
|
|
||||||
{
|
|
||||||
MetaDisplay *display = window->display;
|
|
||||||
MetaKeyBindingManager *keys = &display->key_binding_manager;
|
|
||||||
MetaFrame *frame = meta_window_x11_get_frame (window);
|
|
||||||
|
|
||||||
if (priv->grab_on_frame && frame != NULL)
|
|
||||||
change_window_keygrabs (keys, frame->xwindow, FALSE);
|
|
||||||
else if (!priv->grab_on_frame)
|
|
||||||
change_window_keygrabs (keys, meta_window_x11_get_xwindow (window), FALSE);
|
|
||||||
|
|
||||||
priv->keys_grabbed = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
handle_external_grab (MetaDisplay *display,
|
handle_external_grab (MetaDisplay *display,
|
||||||
MetaWindow *window,
|
MetaWindow *window,
|
||||||
@ -1768,8 +1280,8 @@ meta_display_grab_accelerator (MetaDisplay *display,
|
|||||||
#ifdef HAVE_X11
|
#ifdef HAVE_X11
|
||||||
if (!meta_is_wayland_compositor ())
|
if (!meta_is_wayland_compositor ())
|
||||||
{
|
{
|
||||||
meta_change_keygrab (keys, display->x11_display->xroot,
|
meta_x11_keybindings_change_keygrab (keys, display->x11_display->xroot,
|
||||||
TRUE, &resolved_combo);
|
TRUE, &resolved_combo);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1820,8 +1332,8 @@ meta_display_ungrab_accelerator (MetaDisplay *display,
|
|||||||
#ifdef HAVE_X11
|
#ifdef HAVE_X11
|
||||||
if (!meta_is_wayland_compositor ())
|
if (!meta_is_wayland_compositor ())
|
||||||
{
|
{
|
||||||
meta_change_keygrab (keys, display->x11_display->xroot,
|
meta_x11_keybindings_change_keygrab (keys, display->x11_display->xroot,
|
||||||
FALSE, &binding->resolved_combo);
|
FALSE, &binding->resolved_combo);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -87,6 +87,7 @@
|
|||||||
#include "x11/meta-x11-display-private.h"
|
#include "x11/meta-x11-display-private.h"
|
||||||
#include "x11/meta-x11-frame.h"
|
#include "x11/meta-x11-frame.h"
|
||||||
#include "x11/meta-x11-group-private.h"
|
#include "x11/meta-x11-group-private.h"
|
||||||
|
#include "x11/meta-x11-keybindings-private.h"
|
||||||
#include "x11/window-props.h"
|
#include "x11/window-props.h"
|
||||||
#include "x11/window-x11-private.h"
|
#include "x11/window-x11-private.h"
|
||||||
#include "x11/window-x11.h"
|
#include "x11/window-x11.h"
|
||||||
@ -5274,10 +5275,12 @@ meta_window_set_focused_internal (MetaWindow *window,
|
|||||||
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK ||
|
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK ||
|
||||||
!meta_prefs_get_raise_on_click())
|
!meta_prefs_get_raise_on_click())
|
||||||
{
|
{
|
||||||
meta_display_ungrab_focus_window_button (window->display, window);
|
meta_x11_keybindings_ungrab_focus_window_button (&window->display->key_binding_manager,
|
||||||
|
window);
|
||||||
/* Since we ungrab with XIAnyModifier above, all button
|
/* Since we ungrab with XIAnyModifier above, all button
|
||||||
grabs go way so we need to re-grab the window buttons. */
|
grabs go way so we need to re-grab the window buttons. */
|
||||||
meta_display_grab_window_buttons (window->display, window);
|
meta_x11_keybindings_grab_window_buttons (&window->display->key_binding_manager,
|
||||||
|
window);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -5303,7 +5306,7 @@ meta_window_set_focused_internal (MetaWindow *window,
|
|||||||
#ifdef HAVE_X11
|
#ifdef HAVE_X11
|
||||||
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK ||
|
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK ||
|
||||||
!meta_prefs_get_raise_on_click ())
|
!meta_prefs_get_raise_on_click ())
|
||||||
meta_display_grab_focus_window_button (window->display, window);
|
meta_x11_keybindings_grab_focus_window_button (&window->display->key_binding_manager, window);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -482,6 +482,8 @@ if have_x11_client
|
|||||||
'x11/meta-x11-frame.h',
|
'x11/meta-x11-frame.h',
|
||||||
'x11/meta-x11-group.c',
|
'x11/meta-x11-group.c',
|
||||||
'x11/meta-x11-group-private.h',
|
'x11/meta-x11-group-private.h',
|
||||||
|
'x11/meta-x11-keybindings-private.h',
|
||||||
|
'x11/meta-x11-keybindings.c',
|
||||||
'x11/meta-x11-selection.c',
|
'x11/meta-x11-selection.c',
|
||||||
'x11/meta-x11-selection-private.h',
|
'x11/meta-x11-selection-private.h',
|
||||||
'x11/meta-x11-selection-input-stream.c',
|
'x11/meta-x11-selection-input-stream.c',
|
||||||
|
@ -61,6 +61,7 @@
|
|||||||
#include "x11/events.h"
|
#include "x11/events.h"
|
||||||
#include "x11/group-props.h"
|
#include "x11/group-props.h"
|
||||||
#include "x11/meta-x11-frame.h"
|
#include "x11/meta-x11-frame.h"
|
||||||
|
#include "x11/meta-x11-keybindings-private.h"
|
||||||
#include "x11/meta-x11-selection-private.h"
|
#include "x11/meta-x11-selection-private.h"
|
||||||
#include "x11/window-props.h"
|
#include "x11/window-props.h"
|
||||||
#include "x11/window-x11.h"
|
#include "x11/window-x11.h"
|
||||||
|
@ -26,10 +26,10 @@
|
|||||||
#include "backends/x11/meta-backend-x11.h"
|
#include "backends/x11/meta-backend-x11.h"
|
||||||
#include "compositor/compositor-private.h"
|
#include "compositor/compositor-private.h"
|
||||||
#include "core/bell.h"
|
#include "core/bell.h"
|
||||||
#include "core/keybindings-private.h"
|
|
||||||
#include "mtk/mtk-x11.h"
|
#include "mtk/mtk-x11.h"
|
||||||
#include "x11/meta-x11-display-private.h"
|
#include "x11/meta-x11-display-private.h"
|
||||||
#include "x11/meta-x11-frame.h"
|
#include "x11/meta-x11-frame.h"
|
||||||
|
#include "x11/meta-x11-keybindings-private.h"
|
||||||
#include "x11/window-props.h"
|
#include "x11/window-props.h"
|
||||||
#include "x11/window-x11-private.h"
|
#include "x11/window-x11-private.h"
|
||||||
|
|
||||||
|
58
src/x11/meta-x11-keybindings-private.h
Normal file
58
src/x11/meta-x11-keybindings-private.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Bilal Elmoussaoui
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "backends/x11/meta-backend-x11.h"
|
||||||
|
#include "core/keybindings-private.h"
|
||||||
|
#include "core/window-private.h"
|
||||||
|
#include "mtk/mtk-x11-errors.h"
|
||||||
|
#include "x11/meta-x11-display-private.h"
|
||||||
|
#include "x11/meta-x11-frame.h"
|
||||||
|
#include "x11/window-x11-private.h"
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
void meta_x11_keybindings_grab_window_buttons (MetaKeyBindingManager *keys,
|
||||||
|
MetaWindow *window);
|
||||||
|
|
||||||
|
void meta_x11_keybindings_ungrab_window_buttons (MetaKeyBindingManager *keys,
|
||||||
|
MetaWindow *window);
|
||||||
|
|
||||||
|
void meta_x11_keybindings_grab_focus_window_button (MetaKeyBindingManager *keys,
|
||||||
|
MetaWindow *window);
|
||||||
|
|
||||||
|
void meta_x11_keybindings_ungrab_focus_window_button (MetaKeyBindingManager *keys,
|
||||||
|
MetaWindow *window);
|
||||||
|
|
||||||
|
void meta_x11_display_grab_keys (MetaX11Display *x11_display);
|
||||||
|
|
||||||
|
void meta_x11_display_ungrab_keys (MetaX11Display *x11_display);
|
||||||
|
|
||||||
|
void meta_x11_keybindings_change_keygrab (MetaKeyBindingManager *keys,
|
||||||
|
Window xwindow,
|
||||||
|
gboolean grab,
|
||||||
|
MetaResolvedKeyCombo *resolved_combo);
|
||||||
|
|
||||||
|
void meta_x11_keybindings_grab_key_bindings (MetaDisplay *display);
|
||||||
|
|
||||||
|
void meta_x11_keybindings_ungrab_key_bindings (MetaDisplay *display);
|
||||||
|
|
||||||
|
void meta_x11_keybindings_maybe_update_locate_pointer_keygrab (MetaDisplay *display,
|
||||||
|
gboolean grab);
|
||||||
|
|
||||||
|
void meta_window_grab_keys (MetaWindow *window);
|
||||||
|
|
||||||
|
void meta_window_ungrab_keys (MetaWindow *window);
|
483
src/x11/meta-x11-keybindings.c
Normal file
483
src/x11/meta-x11-keybindings.c
Normal file
@ -0,0 +1,483 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2024 Bilal Elmoussaoui
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Grab/ungrab, ignoring all annoying modifiers like NumLock etc. */
|
||||||
|
|
||||||
|
#include "meta-x11-keybindings-private.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,
|
||||||
|
MetaWindow *window,
|
||||||
|
gboolean grab,
|
||||||
|
gboolean sync,
|
||||||
|
int button,
|
||||||
|
int modmask)
|
||||||
|
{
|
||||||
|
MetaBackendX11 *backend;
|
||||||
|
Display *xdisplay;
|
||||||
|
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
|
||||||
|
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
|
||||||
|
Window xwindow;
|
||||||
|
GArray *mods;
|
||||||
|
MetaFrame *frame;
|
||||||
|
|
||||||
|
if (meta_is_wayland_compositor ())
|
||||||
|
return;
|
||||||
|
if (window->client_type != META_WINDOW_CLIENT_TYPE_X11)
|
||||||
|
return;
|
||||||
|
|
||||||
|
backend = META_BACKEND_X11 (keys->backend);
|
||||||
|
xdisplay = meta_backend_x11_get_xdisplay (backend);
|
||||||
|
|
||||||
|
XISetMask (mask.mask, XI_ButtonPress);
|
||||||
|
XISetMask (mask.mask, XI_ButtonRelease);
|
||||||
|
XISetMask (mask.mask, XI_Motion);
|
||||||
|
|
||||||
|
mods = calc_grab_modifiers (keys, modmask);
|
||||||
|
|
||||||
|
mtk_x11_error_trap_push (xdisplay);
|
||||||
|
frame = meta_window_x11_get_frame (window);
|
||||||
|
if (frame)
|
||||||
|
xwindow = frame->xwindow;
|
||||||
|
else
|
||||||
|
xwindow = meta_window_x11_get_xwindow (window);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
XSync (xdisplay, False);
|
||||||
|
|
||||||
|
mtk_x11_error_trap_pop (xdisplay);
|
||||||
|
|
||||||
|
g_array_free (mods, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_change_buttons_grab (MetaKeyBindingManager *keys,
|
||||||
|
MetaWindow *window,
|
||||||
|
gboolean grab,
|
||||||
|
gboolean sync,
|
||||||
|
int modmask)
|
||||||
|
{
|
||||||
|
#define MAX_BUTTON 3
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 1; i <= MAX_BUTTON; i++)
|
||||||
|
meta_change_button_grab (keys, window, grab, sync, i, modmask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_x11_keybindings_change_keygrab (MetaKeyBindingManager *keys,
|
||||||
|
Window xwindow,
|
||||||
|
gboolean grab,
|
||||||
|
MetaResolvedKeyCombo *resolved_combo)
|
||||||
|
{
|
||||||
|
MetaBackendX11 *backend_x11;
|
||||||
|
Display *xdisplay;
|
||||||
|
GArray *mods;
|
||||||
|
int i;
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (meta_is_wayland_compositor ())
|
||||||
|
return;
|
||||||
|
|
||||||
|
backend_x11 = META_BACKEND_X11 (keys->backend);
|
||||||
|
xdisplay = meta_backend_x11_get_xdisplay (backend_x11);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
mtk_x11_error_trap_push (xdisplay);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
XSync (xdisplay, False);
|
||||||
|
|
||||||
|
mtk_x11_error_trap_pop (xdisplay);
|
||||||
|
|
||||||
|
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_x11_keybindings_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
|
||||||
|
meta_x11_keybindings_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_x11_keybindings_change_keygrab (keys, display->x11_display->xroot,
|
||||||
|
(!!grab & !!meta_prefs_is_locate_pointer_enabled ()),
|
||||||
|
&keys->locate_pointer_resolved_key_combo);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
MetaWindowX11Private *priv;
|
||||||
|
|
||||||
|
if (meta_is_wayland_compositor ())
|
||||||
|
return;
|
||||||
|
|
||||||
|
priv = meta_window_x11_get_private (META_WINDOW_X11 (window));
|
||||||
|
if (window->type == META_WINDOW_DOCK
|
||||||
|
|| window->override_redirect)
|
||||||
|
{
|
||||||
|
if (priv->keys_grabbed)
|
||||||
|
change_window_keygrabs (keys, meta_window_x11_get_xwindow (window), FALSE);
|
||||||
|
priv->keys_grabbed = FALSE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->keys_grabbed)
|
||||||
|
{
|
||||||
|
if (priv->frame && !priv->grab_on_frame)
|
||||||
|
change_window_keygrabs (keys, meta_window_x11_get_xwindow (window), FALSE);
|
||||||
|
else if (priv->frame == NULL &&
|
||||||
|
priv->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);
|
||||||
|
|
||||||
|
priv->keys_grabbed = TRUE;
|
||||||
|
priv->grab_on_frame = priv->frame != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_window_ungrab_keys (MetaWindow *window)
|
||||||
|
{
|
||||||
|
MetaWindowX11Private *priv;
|
||||||
|
|
||||||
|
if (meta_is_wayland_compositor ())
|
||||||
|
return;
|
||||||
|
|
||||||
|
priv = meta_window_x11_get_private (META_WINDOW_X11 (window));
|
||||||
|
|
||||||
|
if (priv->keys_grabbed)
|
||||||
|
{
|
||||||
|
MetaDisplay *display = window->display;
|
||||||
|
MetaKeyBindingManager *keys = &display->key_binding_manager;
|
||||||
|
MetaFrame *frame = meta_window_x11_get_frame (window);
|
||||||
|
|
||||||
|
if (priv->grab_on_frame && frame != NULL)
|
||||||
|
change_window_keygrabs (keys, frame->xwindow, FALSE);
|
||||||
|
else if (!priv->grab_on_frame)
|
||||||
|
change_window_keygrabs (keys, meta_window_x11_get_xwindow (window), FALSE);
|
||||||
|
|
||||||
|
priv->keys_grabbed = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_x11_keybindings_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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_x11_keybindings_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_keybindings_grab_window_buttons (MetaKeyBindingManager *keys,
|
||||||
|
MetaWindow *window)
|
||||||
|
{
|
||||||
|
/* 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 %s", window->desc);
|
||||||
|
|
||||||
|
/* 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, window, 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, window,
|
||||||
|
TRUE,
|
||||||
|
FALSE,
|
||||||
|
1, keys->window_grab_modifiers | CLUTTER_SHIFT_MASK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_x11_keybindings_ungrab_window_buttons (MetaKeyBindingManager *keys,
|
||||||
|
MetaWindow *window)
|
||||||
|
{
|
||||||
|
if (keys->window_grab_modifiers == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
meta_change_buttons_grab (keys, window, FALSE, FALSE,
|
||||||
|
keys->window_grab_modifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_x11_keybindings_grab_focus_window_button (MetaKeyBindingManager *keys,
|
||||||
|
MetaWindow *window)
|
||||||
|
{
|
||||||
|
/* 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, TRUE, TRUE, XIAnyModifier);
|
||||||
|
window->have_focus_click_grab = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_x11_keybindings_ungrab_focus_window_button (MetaKeyBindingManager *keys,
|
||||||
|
MetaWindow *window)
|
||||||
|
{
|
||||||
|
meta_verbose ("Ungrabbing unfocused window buttons for %s", window->desc);
|
||||||
|
|
||||||
|
if (!window->have_focus_click_grab)
|
||||||
|
return;
|
||||||
|
|
||||||
|
meta_change_buttons_grab (keys, window, FALSE, FALSE, XIAnyModifier);
|
||||||
|
window->have_focus_click_grab = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
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_x11_keybindings_change_keygrab (keys, x11_display->xroot,
|
||||||
|
grab, &keys->overlay_resolved_key_combo);
|
||||||
|
|
||||||
|
meta_x11_keybindings_maybe_update_locate_pointer_keygrab (x11_display->display,
|
||||||
|
grab);
|
||||||
|
|
||||||
|
for (i = 0; i < keys->n_iso_next_group_combos; i++)
|
||||||
|
meta_x11_keybindings_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;
|
||||||
|
}
|
@ -55,6 +55,7 @@
|
|||||||
#include "x11/meta-x11-display-private.h"
|
#include "x11/meta-x11-display-private.h"
|
||||||
#include "x11/meta-x11-frame.h"
|
#include "x11/meta-x11-frame.h"
|
||||||
#include "x11/meta-x11-group-private.h"
|
#include "x11/meta-x11-group-private.h"
|
||||||
|
#include "x11/meta-x11-keybindings-private.h"
|
||||||
#include "x11/session.h"
|
#include "x11/session.h"
|
||||||
#include "x11/window-props.h"
|
#include "x11/window-props.h"
|
||||||
#include "x11/xprops.h"
|
#include "x11/xprops.h"
|
||||||
@ -714,8 +715,10 @@ meta_window_x11_unmanage (MetaWindow *window)
|
|||||||
XShapeSelectInput (x11_display->xdisplay, priv->xwindow, NoEventMask);
|
XShapeSelectInput (x11_display->xdisplay, priv->xwindow, NoEventMask);
|
||||||
|
|
||||||
meta_window_ungrab_keys (window);
|
meta_window_ungrab_keys (window);
|
||||||
meta_display_ungrab_window_buttons (window->display, window);
|
meta_x11_keybindings_ungrab_window_buttons (&window->display->key_binding_manager,
|
||||||
meta_display_ungrab_focus_window_button (window->display, window);
|
window);
|
||||||
|
meta_x11_keybindings_ungrab_focus_window_button (&window->display->key_binding_manager,
|
||||||
|
window);
|
||||||
|
|
||||||
mtk_x11_error_trap_pop (x11_display->xdisplay);
|
mtk_x11_error_trap_pop (x11_display->xdisplay);
|
||||||
|
|
||||||
@ -4075,8 +4078,8 @@ meta_window_x11_new (MetaDisplay *display,
|
|||||||
meta_window_grab_keys (window);
|
meta_window_grab_keys (window);
|
||||||
if (window->type != META_WINDOW_DOCK && !window->override_redirect)
|
if (window->type != META_WINDOW_DOCK && !window->override_redirect)
|
||||||
{
|
{
|
||||||
meta_display_grab_window_buttons (window->display, window);
|
meta_x11_keybindings_grab_window_buttons (&window->display->key_binding_manager, window);
|
||||||
meta_display_grab_focus_window_button (window->display, window);
|
meta_x11_keybindings_grab_focus_window_button (&window->display->key_binding_manager, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
mtk_x11_error_trap_pop (x11_display->xdisplay); /* pop the XSync()-reducing trap */
|
mtk_x11_error_trap_pop (x11_display->xdisplay); /* pop the XSync()-reducing trap */
|
||||||
|
Reference in New Issue
Block a user