diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h index 3d220f70c..707467654 100644 --- a/src/backends/meta-backend-private.h +++ b/src/backends/meta-backend-private.h @@ -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); diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c index 965f8e810..0afdf3344 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c @@ -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) { diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c index a8eee50ba..3b44920f6 100644 --- a/src/backends/x11/meta-backend-x11.c +++ b/src/backends/x11/meta-backend-x11.c @@ -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; diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 9852266aa..3b6f728bb 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -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; diff --git a/src/meta/display.h b/src/meta/display.h index 18b435652..e815191b6 100644 --- a/src/meta/display.h +++ b/src/meta/display.h @@ -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); diff --git a/src/meta/meta-backend.h b/src/meta/meta-backend.h index 611f2d05f..b6836a99f 100644 --- a/src/meta/meta-backend.h +++ b/src/meta/meta-backend.h @@ -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);