keybindings: Move grab/freeze functions per backend

By making those functions virtual functions of MetaBackend
and have the BackendNative implementation no op

Helps https://gitlab.gnome.org/GNOME/mutter/-/issues/2272

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3583>
This commit is contained in:
Bilal Elmoussaoui 2022-06-20 10:24:49 +02:00 committed by Marge Bot
parent 868fbe622b
commit bd1ca76168
6 changed files with 123 additions and 118 deletions

View File

@ -81,6 +81,15 @@ struct _MetaBackendClass
int device_id,
uint32_t timestamp);
void (* freeze_keyboard) (MetaBackend *backend,
uint32_t timestamp);
void (* unfreeze_keyboard) (MetaBackend *backend,
uint32_t timestamp);
void (* ungrab_keyboard) (MetaBackend *backend,
uint32_t timestamp);
void (* finish_touch_sequence) (MetaBackend *backend,
ClutterEventSequence *sequence,
MetaSequenceState state);

View File

@ -647,6 +647,36 @@ meta_backend_real_is_headless (MetaBackend *backend)
return FALSE;
}
void
meta_backend_freeze_keyboard (MetaBackend *backend,
uint32_t timestamp)
{
g_return_if_fail (META_IS_BACKEND (backend));
if (META_BACKEND_GET_CLASS (backend)->freeze_keyboard)
META_BACKEND_GET_CLASS (backend)->freeze_keyboard (backend, timestamp);
}
void
meta_backend_unfreeze_keyboard (MetaBackend *backend,
uint32_t timestamp)
{
g_return_if_fail (META_IS_BACKEND (backend));
if (META_BACKEND_GET_CLASS (backend)->unfreeze_keyboard)
META_BACKEND_GET_CLASS (backend)->unfreeze_keyboard (backend, timestamp);
}
void
meta_backend_ungrab_keyboard (MetaBackend *backend,
uint32_t timestamp)
{
g_return_if_fail (META_IS_BACKEND (backend));
if (META_BACKEND_GET_CLASS (backend)->ungrab_keyboard)
META_BACKEND_GET_CLASS (backend)->ungrab_keyboard (backend, timestamp);
}
gboolean
meta_backend_is_lid_closed (MetaBackend *backend)
{

View File

@ -58,6 +58,7 @@
#include "meta/meta-cursor-tracker.h"
#include "meta/util.h"
#include "mtk/mtk-x11.h"
#include "x11/window-x11.h"
struct _MetaBackendX11Private
{
@ -703,6 +704,71 @@ meta_backend_x11_ungrab_device (MetaBackend *backend,
return (ret == Success);
}
static void
meta_backend_x11_freeze_keyboard (MetaBackend *backend,
uint32_t timestamp)
{
MetaBackendX11 *backend_x11;
Window xwindow;
Display *xdisplay;
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);
/* Grab the keyboard, so we get key releases and all key
* presses
*/
backend_x11 = META_BACKEND_X11 (backend);
xwindow = meta_backend_x11_get_xwindow (backend_x11);
xdisplay = meta_backend_x11_get_xdisplay (backend_x11);
/* Strictly, we only need to set grab_mode on the keyboard device
* while the pointer should always be XIGrabModeAsync. Unfortunately
* there is a bug in the X server, only fixed (link below) in 1.15,
* which swaps these arguments for keyboard devices. As such, we set
* both the device and the paired device mode which works around
* that bug and also works on fixed X servers.
*
* http://cgit.freedesktop.org/xorg/xserver/commit/?id=9003399708936481083424b4ff8f18a16b88b7b3
*/
XIGrabDevice (xdisplay,
META_VIRTUAL_CORE_KEYBOARD_ID,
xwindow,
timestamp,
None,
XIGrabModeSync, XIGrabModeSync,
False, /* owner_events */
&mask);
}
static void
meta_backend_x11_unfreeze_keyboard (MetaBackend *backend,
uint32_t timestamp)
{
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
XIAllowEvents (xdisplay, META_VIRTUAL_CORE_KEYBOARD_ID,
XIAsyncDevice, timestamp);
/* We shouldn't need to unfreeze the pointer device here, however we
* have to, due to the workaround we do in grab_keyboard().
*/
XIAllowEvents (xdisplay, META_VIRTUAL_CORE_POINTER_ID,
XIAsyncDevice, timestamp);
}
static void
meta_backend_x11_ungrab_keyboard (MetaBackend *backend,
uint32_t timestamp)
{
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
XIUngrabDevice (xdisplay, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp);
}
static void
meta_backend_x11_finish_touch_sequence (MetaBackend *backend,
ClutterEventSequence *sequence,
@ -993,6 +1059,9 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
backend_class->post_init = meta_backend_x11_post_init;
backend_class->grab_device = meta_backend_x11_grab_device;
backend_class->ungrab_device = meta_backend_x11_ungrab_device;
backend_class->freeze_keyboard = meta_backend_x11_freeze_keyboard;
backend_class->unfreeze_keyboard = meta_backend_x11_unfreeze_keyboard;
backend_class->ungrab_keyboard = meta_backend_x11_ungrab_keyboard;
backend_class->finish_touch_sequence = meta_backend_x11_finish_touch_sequence;
backend_class->get_current_logical_monitor = meta_backend_x11_get_current_logical_monitor;
backend_class->get_keymap = meta_backend_x11_get_keymap;

View File

@ -1762,111 +1762,6 @@ meta_display_ungrab_accelerator (MetaDisplay *display,
return TRUE;
}
static gboolean
grab_keyboard (MetaBackend *backend,
Window xwindow,
uint32_t timestamp,
int grab_mode)
{
MetaBackendX11 *backend_x11;
Display *xdisplay;
int grab_status;
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 TRUE;
/* Grab the keyboard, so we get key releases and all key
* presses
*/
backend_x11 = META_BACKEND_X11 (backend);
xdisplay = meta_backend_x11_get_xdisplay (backend_x11);
/* Strictly, we only need to set grab_mode on the keyboard device
* while the pointer should always be XIGrabModeAsync. Unfortunately
* there is a bug in the X server, only fixed (link below) in 1.15,
* which swaps these arguments for keyboard devices. As such, we set
* both the device and the paired device mode which works around
* that bug and also works on fixed X servers.
*
* http://cgit.freedesktop.org/xorg/xserver/commit/?id=9003399708936481083424b4ff8f18a16b88b7b3
*/
grab_status = XIGrabDevice (xdisplay,
META_VIRTUAL_CORE_KEYBOARD_ID,
xwindow,
timestamp,
None,
grab_mode, grab_mode,
False, /* owner_events */
&mask);
return (grab_status == Success);
}
static void
ungrab_keyboard (MetaBackend *backend,
uint32_t timestamp)
{
MetaBackendX11 *backend_x11;
Display *xdisplay;
if (meta_is_wayland_compositor ())
return;
backend_x11 = META_BACKEND_X11 (backend);
xdisplay = meta_backend_x11_get_xdisplay (backend_x11);
XIUngrabDevice (xdisplay, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp);
}
void
meta_display_freeze_keyboard (MetaDisplay *display, guint32 timestamp)
{
MetaContext *context = meta_display_get_context (display);
MetaBackend *backend = meta_context_get_backend (context);
if (!META_IS_BACKEND_X11 (backend))
return;
Window window = meta_backend_x11_get_xwindow (META_BACKEND_X11 (backend));
grab_keyboard (backend, window, timestamp, XIGrabModeSync);
}
void
meta_display_ungrab_keyboard (MetaDisplay *display, guint32 timestamp)
{
MetaContext *context = meta_display_get_context (display);
MetaBackend *backend = meta_context_get_backend (context);
ungrab_keyboard (backend, timestamp);
}
void
meta_display_unfreeze_keyboard (MetaDisplay *display, guint32 timestamp)
{
MetaContext *context = meta_display_get_context (display);
MetaBackend *backend = meta_context_get_backend (context);
if (!META_IS_BACKEND_X11 (backend))
return;
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
XIAllowEvents (xdisplay, META_VIRTUAL_CORE_KEYBOARD_ID,
XIAsyncDevice, timestamp);
/* We shouldn't need to unfreeze the pointer device here, however we
* have to, due to the workaround we do in grab_keyboard().
*/
XIAllowEvents (xdisplay, META_VIRTUAL_CORE_POINTER_ID,
XIAsyncDevice, timestamp);
}
static void
invoke_handler (MetaDisplay *display,
MetaKeyHandler *handler,
@ -2173,6 +2068,8 @@ static gboolean
process_iso_next_group (MetaDisplay *display,
ClutterKeyEvent *event)
{
MetaContext *context = meta_display_get_context (display);
MetaBackend *backend = meta_context_get_backend (context);
MetaKeyBindingManager *keys = &display->key_binding_manager;
gboolean activate;
xkb_keycode_t keycode =
@ -2199,7 +2096,7 @@ process_iso_next_group (MetaDisplay *display,
remain frozen. It's the signal handler's responsibility
to unfreeze it. */
if (!meta_display_modifiers_accelerator_activate (display))
meta_display_unfreeze_keyboard (display,
meta_backend_unfreeze_keyboard (backend,
clutter_event_get_time ((ClutterEvent *) event));
activate = TRUE;
break;

View File

@ -173,18 +173,6 @@ GSList *meta_display_sort_windows_by_stacking (MetaDisplay *display,
META_EXPORT
void meta_display_clear_mouse_mode (MetaDisplay *display);
META_EXPORT
void meta_display_freeze_keyboard (MetaDisplay *display,
guint32 timestamp);
META_EXPORT
void meta_display_ungrab_keyboard (MetaDisplay *display,
guint32 timestamp);
META_EXPORT
void meta_display_unfreeze_keyboard (MetaDisplay *display,
guint32 timestamp);
META_EXPORT
gboolean meta_display_is_pointer_emulating_sequence (MetaDisplay *display,
ClutterEventSequence *sequence);

View File

@ -78,5 +78,17 @@ gboolean meta_backend_is_rendering_hardware_accelerated (MetaBackend *backend);
META_EXPORT
gboolean meta_backend_is_headless (MetaBackend *backend);
META_EXPORT
void meta_backend_freeze_keyboard (MetaBackend *backend,
uint32_t timestamp);
META_EXPORT
void meta_backend_ungrab_keyboard (MetaBackend *backend,
uint32_t timestamp);
META_EXPORT
void meta_backend_unfreeze_keyboard (MetaBackend *backend,
uint32_t timestamp);
META_EXPORT
MetaBackendCapabilities meta_backend_get_capabilities (MetaBackend *backend);