mirror of
https://github.com/brl/mutter.git
synced 2024-12-01 04:10:43 -05:00
keybindings: Add API to freeze/unfreeze the keyboard
We'll use this in gnome-shell to freeze the keyboard right before switching input source and unfreeze it after that's finished so that we don't lose any key events to the wrong input source. https://bugzilla.gnome.org/show_bug.cgi?id=697001
This commit is contained in:
parent
6c4bcecc00
commit
056cc16b82
@ -1264,7 +1264,8 @@ grab_status_to_string (int status)
|
|||||||
static gboolean
|
static gboolean
|
||||||
grab_keyboard (MetaDisplay *display,
|
grab_keyboard (MetaDisplay *display,
|
||||||
Window xwindow,
|
Window xwindow,
|
||||||
guint32 timestamp)
|
guint32 timestamp,
|
||||||
|
int grab_mode)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
int grab_status;
|
int grab_status;
|
||||||
@ -1280,12 +1281,21 @@ grab_keyboard (MetaDisplay *display,
|
|||||||
*/
|
*/
|
||||||
meta_error_trap_push_with_return (display);
|
meta_error_trap_push_with_return (display);
|
||||||
|
|
||||||
|
/* 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 (display->xdisplay,
|
grab_status = XIGrabDevice (display->xdisplay,
|
||||||
META_VIRTUAL_CORE_KEYBOARD_ID,
|
META_VIRTUAL_CORE_KEYBOARD_ID,
|
||||||
xwindow,
|
xwindow,
|
||||||
timestamp,
|
timestamp,
|
||||||
None,
|
None,
|
||||||
XIGrabModeAsync, XIGrabModeAsync,
|
grab_mode, grab_mode,
|
||||||
True, /* owner_events */
|
True, /* owner_events */
|
||||||
&mask);
|
&mask);
|
||||||
|
|
||||||
@ -1339,7 +1349,7 @@ meta_screen_grab_all_keys (MetaScreen *screen, guint32 timestamp)
|
|||||||
|
|
||||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||||
"Grabbing all keys on RootWindow\n");
|
"Grabbing all keys on RootWindow\n");
|
||||||
retval = grab_keyboard (screen->display, screen->xroot, timestamp);
|
retval = grab_keyboard (screen->display, screen->xroot, timestamp, XIGrabModeAsync);
|
||||||
if (retval)
|
if (retval)
|
||||||
{
|
{
|
||||||
screen->all_keys_grabbed = TRUE;
|
screen->all_keys_grabbed = TRUE;
|
||||||
@ -1392,7 +1402,7 @@ meta_window_grab_all_keys (MetaWindow *window,
|
|||||||
|
|
||||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||||
"Grabbing all keys on window %s\n", window->desc);
|
"Grabbing all keys on window %s\n", window->desc);
|
||||||
retval = grab_keyboard (window->display, grabwindow, timestamp);
|
retval = grab_keyboard (window->display, grabwindow, timestamp, XIGrabModeAsync);
|
||||||
if (retval)
|
if (retval)
|
||||||
{
|
{
|
||||||
window->keys_grabbed = FALSE;
|
window->keys_grabbed = FALSE;
|
||||||
@ -1419,6 +1429,32 @@ meta_window_ungrab_all_keys (MetaWindow *window, guint32 timestamp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_display_freeze_keyboard (MetaDisplay *display, Window window, guint32 timestamp)
|
||||||
|
{
|
||||||
|
grab_keyboard (display, window, timestamp, XIGrabModeSync);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_display_ungrab_keyboard (MetaDisplay *display, guint32 timestamp)
|
||||||
|
{
|
||||||
|
ungrab_keyboard (display, timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_display_unfreeze_keyboard (MetaDisplay *display, guint32 timestamp)
|
||||||
|
{
|
||||||
|
meta_error_trap_push (display);
|
||||||
|
XIAllowEvents (display->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 (display->xdisplay, META_VIRTUAL_CORE_POINTER_ID,
|
||||||
|
XIAsyncDevice, timestamp);
|
||||||
|
meta_error_trap_pop (display);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
is_modifier (MetaDisplay *display,
|
is_modifier (MetaDisplay *display,
|
||||||
unsigned int keycode)
|
unsigned int keycode)
|
||||||
|
@ -187,4 +187,11 @@ void meta_display_unmanage_screen (MetaDisplay *display,
|
|||||||
|
|
||||||
void meta_display_clear_mouse_mode (MetaDisplay *display);
|
void meta_display_clear_mouse_mode (MetaDisplay *display);
|
||||||
|
|
||||||
|
void meta_display_freeze_keyboard (MetaDisplay *display,
|
||||||
|
Window window,
|
||||||
|
guint32 timestamp);
|
||||||
|
void meta_display_ungrab_keyboard (MetaDisplay *display,
|
||||||
|
guint32 timestamp);
|
||||||
|
void meta_display_unfreeze_keyboard (MetaDisplay *display,
|
||||||
|
guint32 timestamp);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user