[mutter/gnome-3-8] keybindings: Add API to freeze/unfreeze the keyboard



commit 056cc16b8299e771ed36d024ffa84caaa7f79977
Author: Rui Matos <tiagomatos gmail com>
Date:   Fri Mar 29 02:38:43 2013 +0100

    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

 src/core/keybindings.c |   44 ++++++++++++++++++++++++++++++++++++++++----
 src/meta/display.h     |    7 +++++++
 2 files changed, 47 insertions(+), 4 deletions(-)
---
diff --git a/src/core/keybindings.c b/src/core/keybindings.c
index b1681c7..94f86dc 100644
--- a/src/core/keybindings.c
+++ b/src/core/keybindings.c
@@ -1264,7 +1264,8 @@ grab_status_to_string (int status)
 static gboolean
 grab_keyboard (MetaDisplay *display,
                Window       xwindow,
-               guint32      timestamp)
+               guint32      timestamp,
+               int          grab_mode)
 {
   int result;
   int grab_status;
@@ -1280,12 +1281,21 @@ grab_keyboard (MetaDisplay *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,
                               META_VIRTUAL_CORE_KEYBOARD_ID,
                               xwindow,
                               timestamp,
                               None,
-                              XIGrabModeAsync, XIGrabModeAsync,
+                              grab_mode, grab_mode,
                               True, /* owner_events */
                               &mask);
 
@@ -1339,7 +1349,7 @@ meta_screen_grab_all_keys (MetaScreen *screen, guint32 timestamp)
 
   meta_topic (META_DEBUG_KEYBINDINGS,
               "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)
     {
       screen->all_keys_grabbed = TRUE;
@@ -1392,7 +1402,7 @@ meta_window_grab_all_keys (MetaWindow  *window,
 
   meta_topic (META_DEBUG_KEYBINDINGS,
               "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)
     {
       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
 is_modifier (MetaDisplay *display,
              unsigned int keycode)
diff --git a/src/meta/display.h b/src/meta/display.h
index d4c3aae..65d5797 100644
--- a/src/meta/display.h
+++ b/src/meta/display.h
@@ -187,4 +187,11 @@ void meta_display_unmanage_screen (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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]