Blame SOURCES/0001-backends-x11-Fix-key-repeat-of-on-screen-keyboard-fo.patch

2cfc33
From a1f33bdac95ba4fd0599f164ef893c05d8be123b Mon Sep 17 00:00:00 2001
2cfc33
From: Ray Strode <rstrode@redhat.com>
2cfc33
Date: Wed, 6 Oct 2021 15:31:30 -0400
2cfc33
Subject: [PATCH] backends/x11: Fix key repeat of on-screen keyboard for second
2cfc33
 level keysyms
2cfc33
2cfc33
Certains keys (such as ~ and |) are in the keyboard map behind the
2cfc33
second shift level. This means in order for them to be input, the
2cfc33
shift key needs to be held down by the user.
2cfc33
2cfc33
The GNOME Shell on-screen keyboard presents these keys separately on
2cfc33
a page of keys that has no shift key. Instead, it relies on mutter
2cfc33
to set a shift latch before the key event is emitted. A shift latch
2cfc33
is a virtual press of the shift key that automatically gets released
2cfc33
after the next key press (in our case the ~ or | key).
2cfc33
2cfc33
The problem is using a shift latch doesn't work very well in the face
2cfc33
of key repeat. The latch is automatically released after the first
2cfc33
press, and subsequent repeats of that press no longer have shift
2cfc33
latched to them.
2cfc33
2cfc33
This commit fixes the problem by using a shift lock instead of a shift
2cfc33
latch. A shift lock is never implicitly released, so it remains
2cfc33
in place for the duration of key repeat.
2cfc33
---
2cfc33
 src/backends/x11/meta-keymap-x11.c               | 12 ++++++------
2cfc33
 src/backends/x11/meta-keymap-x11.h               |  6 +++---
2cfc33
 src/backends/x11/meta-virtual-input-device-x11.c |  4 ++--
2cfc33
 3 files changed, 11 insertions(+), 11 deletions(-)
2cfc33
2cfc33
diff --git a/src/backends/x11/meta-keymap-x11.c b/src/backends/x11/meta-keymap-x11.c
2cfc33
index da5d064e7..1192cc387 100644
2cfc33
--- a/src/backends/x11/meta-keymap-x11.c
2cfc33
+++ b/src/backends/x11/meta-keymap-x11.c
2cfc33
@@ -829,85 +829,85 @@ meta_keymap_x11_reserve_keycode (MetaKeymapX11 *keymap_x11,
2cfc33
       g_warning ("Cannot reserve a keycode for keyval %d: no available keycode", keyval);
2cfc33
       return FALSE;
2cfc33
     }
2cfc33
 
2cfc33
   if (!meta_keymap_x11_replace_keycode (keymap_x11, *keycode_out, keyval))
2cfc33
     {
2cfc33
       g_warning ("Failed to remap keycode %d to keyval %d", *keycode_out, keyval);
2cfc33
       return FALSE;
2cfc33
     }
2cfc33
 
2cfc33
   g_hash_table_insert (keymap_x11->reserved_keycodes, GUINT_TO_POINTER (*keycode_out), GUINT_TO_POINTER (keyval));
2cfc33
   g_queue_remove (keymap_x11->available_keycodes, GUINT_TO_POINTER (*keycode_out));
2cfc33
 
2cfc33
   return TRUE;
2cfc33
 }
2cfc33
 
2cfc33
 void
2cfc33
 meta_keymap_x11_release_keycode_if_needed (MetaKeymapX11 *keymap_x11,
2cfc33
                                            uint32_t       keycode)
2cfc33
 {
2cfc33
   g_return_if_fail (META_IS_KEYMAP_X11 (keymap_x11));
2cfc33
 
2cfc33
   if (!g_hash_table_contains (keymap_x11->reserved_keycodes, GUINT_TO_POINTER (keycode)) ||
2cfc33
       g_queue_index (keymap_x11->available_keycodes, GUINT_TO_POINTER (keycode)) != -1)
2cfc33
     return;
2cfc33
 
2cfc33
   g_queue_push_tail (keymap_x11->available_keycodes, GUINT_TO_POINTER (keycode));
2cfc33
 }
2cfc33
 
2cfc33
 void
2cfc33
-meta_keymap_x11_latch_modifiers (MetaKeymapX11 *keymap_x11,
2cfc33
-                                 uint32_t       level,
2cfc33
-                                 gboolean       enable)
2cfc33
+meta_keymap_x11_lock_modifiers (MetaKeymapX11 *keymap_x11,
2cfc33
+                                uint32_t       level,
2cfc33
+                                gboolean       enable)
2cfc33
 {
2cfc33
   uint32_t modifiers[] = {
2cfc33
     0,
2cfc33
     ShiftMask,
2cfc33
     keymap_x11->level3_shift_mask,
2cfc33
     keymap_x11->level3_shift_mask | ShiftMask,
2cfc33
   };
2cfc33
   uint32_t value = 0;
2cfc33
 
2cfc33
   if (!keymap_x11->use_xkb)
2cfc33
     return;
2cfc33
 
2cfc33
   level = CLAMP (level, 0, G_N_ELEMENTS (modifiers) - 1);
2cfc33
 
2cfc33
   if (enable)
2cfc33
     value = modifiers[level];
2cfc33
   else
2cfc33
     value = 0;
2cfc33
 
2cfc33
-  XkbLatchModifiers (clutter_x11_get_default_display (),
2cfc33
-                     XkbUseCoreKbd, modifiers[level],
2cfc33
-                     value);
2cfc33
+  XkbLockModifiers (clutter_x11_get_default_display (),
2cfc33
+                    XkbUseCoreKbd, modifiers[level],
2cfc33
+                    value);
2cfc33
 }
2cfc33
 
2cfc33
 static uint32_t
2cfc33
 meta_keymap_x11_get_current_group (MetaKeymapX11 *keymap_x11)
2cfc33
 {
2cfc33
   XkbStateRec state_rec;
2cfc33
 
2cfc33
   if (keymap_x11->current_group >= 0)
2cfc33
     return keymap_x11->current_group;
2cfc33
 
2cfc33
   XkbGetState (clutter_x11_get_default_display (),
2cfc33
                XkbUseCoreKbd, &state_rec);
2cfc33
   return XkbStateGroup (&state_rec);
2cfc33
 }
2cfc33
 
2cfc33
 gboolean
2cfc33
 meta_keymap_x11_keycode_for_keyval (MetaKeymapX11 *keymap_x11,
2cfc33
                                     uint32_t       keyval,
2cfc33
                                     uint32_t      *keycode_out,
2cfc33
                                     uint32_t      *level_out)
2cfc33
 {
2cfc33
   ClutterKeymapKey *keys;
2cfc33
   int i, n_keys, group;
2cfc33
   gboolean found = FALSE;
2cfc33
 
2cfc33
   g_return_val_if_fail (keycode_out != NULL, FALSE);
2cfc33
   g_return_val_if_fail (level_out != NULL, FALSE);
2cfc33
 
2cfc33
   group = meta_keymap_x11_get_current_group (keymap_x11);
2cfc33
 
2cfc33
diff --git a/src/backends/x11/meta-keymap-x11.h b/src/backends/x11/meta-keymap-x11.h
2cfc33
index 67a5f8eb9..2f93acdbc 100644
2cfc33
--- a/src/backends/x11/meta-keymap-x11.h
2cfc33
+++ b/src/backends/x11/meta-keymap-x11.h
2cfc33
@@ -17,45 +17,45 @@
2cfc33
  * Author: Emmanuele Bassi <ebassi@linux.intel.com>
2cfc33
  */
2cfc33
 
2cfc33
 #ifndef META_KEYMAP_X11_H
2cfc33
 #define META_KEYMAP_X11_H
2cfc33
 
2cfc33
 #include <glib-object.h>
2cfc33
 #include <pango/pango.h>
2cfc33
 
2cfc33
 #include "clutter/clutter.h"
2cfc33
 
2cfc33
 G_BEGIN_DECLS
2cfc33
 
2cfc33
 #define META_TYPE_KEYMAP_X11 (meta_keymap_x11_get_type ())
2cfc33
 G_DECLARE_FINAL_TYPE (MetaKeymapX11, meta_keymap_x11,
2cfc33
                       META, KEYMAP_X11, ClutterKeymap)
2cfc33
 
2cfc33
 int      meta_keymap_x11_get_key_group       (MetaKeymapX11       *keymap,
2cfc33
                                               ClutterModifierType  state);
2cfc33
 int      meta_keymap_x11_translate_key_state (MetaKeymapX11       *keymap,
2cfc33
                                               guint                hardware_keycode,
2cfc33
                                               ClutterModifierType *modifier_state_p,
2cfc33
                                               ClutterModifierType *mods_p);
2cfc33
 gboolean meta_keymap_x11_get_is_modifier     (MetaKeymapX11       *keymap,
2cfc33
                                               int                  keycode);
2cfc33
 
2cfc33
 gboolean meta_keymap_x11_keycode_for_keyval       (MetaKeymapX11    *keymap_x11,
2cfc33
                                                    guint             keyval,
2cfc33
                                                    guint            *keycode_out,
2cfc33
                                                    guint            *level_out);
2cfc33
-void     meta_keymap_x11_latch_modifiers          (MetaKeymapX11 *keymap_x11,
2cfc33
-                                                   uint32_t          level,
2cfc33
-                                                   gboolean          enable);
2cfc33
+void     meta_keymap_x11_lock_modifiers           (MetaKeymapX11 *keymap_x11,
2cfc33
+                                                   uint32_t       level,
2cfc33
+                                                   gboolean       enable);
2cfc33
 gboolean meta_keymap_x11_reserve_keycode           (MetaKeymapX11 *keymap_x11,
2cfc33
                                                     guint             keyval,
2cfc33
                                                     guint            *keycode_out);
2cfc33
 void     meta_keymap_x11_release_keycode_if_needed (MetaKeymapX11 *keymap_x11,
2cfc33
                                                     guint             keycode);
2cfc33
 
2cfc33
 gboolean meta_keymap_x11_handle_event        (MetaKeymapX11 *keymap_x11,
2cfc33
                                               XEvent        *xevent);
2cfc33
 
2cfc33
 G_END_DECLS
2cfc33
 
2cfc33
 #endif /* META_KEYMAP_X11_H */
2cfc33
diff --git a/src/backends/x11/meta-virtual-input-device-x11.c b/src/backends/x11/meta-virtual-input-device-x11.c
2cfc33
index fe6040859..1a5cdfc2e 100644
2cfc33
--- a/src/backends/x11/meta-virtual-input-device-x11.c
2cfc33
+++ b/src/backends/x11/meta-virtual-input-device-x11.c
2cfc33
@@ -159,71 +159,71 @@ meta_virtual_input_device_x11_notify_key (ClutterVirtualInputDevice *virtual_dev
2cfc33
                                           ClutterKeyState            key_state)
2cfc33
 {
2cfc33
   XTestFakeKeyEvent (clutter_x11_get_default_display (),
2cfc33
                      key + 8, key_state == CLUTTER_KEY_STATE_PRESSED, 0);
2cfc33
 }
2cfc33
 
2cfc33
 static void
2cfc33
 meta_virtual_input_device_x11_notify_keyval (ClutterVirtualInputDevice *virtual_device,
2cfc33
                                              uint64_t                   time_us,
2cfc33
                                              uint32_t                   keyval,
2cfc33
                                              ClutterKeyState            key_state)
2cfc33
 {
2cfc33
   ClutterBackend *backend = clutter_get_default_backend ();
2cfc33
   ClutterSeat *seat = clutter_backend_get_default_seat (backend);
2cfc33
   MetaKeymapX11 *keymap = META_KEYMAP_X11 (clutter_seat_get_keymap (seat));
2cfc33
   uint32_t keycode, level;
2cfc33
 
2cfc33
   if (!meta_keymap_x11_keycode_for_keyval (keymap, keyval, &keycode, &level))
2cfc33
     {
2cfc33
       level = 0;
2cfc33
 
2cfc33
       if (!meta_keymap_x11_reserve_keycode (keymap, keyval, &keycode))
2cfc33
         {
2cfc33
           g_warning ("No keycode found for keyval %x in current group", keyval);
2cfc33
           return;
2cfc33
         }
2cfc33
     }
2cfc33
 
2cfc33
   if (!meta_keymap_x11_get_is_modifier (keymap, keycode) &&
2cfc33
       key_state == CLUTTER_KEY_STATE_PRESSED)
2cfc33
-    meta_keymap_x11_latch_modifiers (keymap, level, TRUE);
2cfc33
+    meta_keymap_x11_lock_modifiers (keymap, level, TRUE);
2cfc33
 
2cfc33
   XTestFakeKeyEvent (clutter_x11_get_default_display (),
2cfc33
                      (KeyCode) keycode,
2cfc33
                      key_state == CLUTTER_KEY_STATE_PRESSED, 0);
2cfc33
 
2cfc33
 
2cfc33
   if (key_state == CLUTTER_KEY_STATE_RELEASED)
2cfc33
     {
2cfc33
       if (!meta_keymap_x11_get_is_modifier (keymap, keycode))
2cfc33
-        meta_keymap_x11_latch_modifiers (keymap, level, FALSE);
2cfc33
+        meta_keymap_x11_lock_modifiers (keymap, level, FALSE);
2cfc33
       meta_keymap_x11_release_keycode_if_needed (keymap, keycode);
2cfc33
     }
2cfc33
 }
2cfc33
 
2cfc33
 static void
2cfc33
 meta_virtual_input_device_x11_notify_touch_down (ClutterVirtualInputDevice *virtual_device,
2cfc33
                                                  uint64_t                   time_us,
2cfc33
                                                  int                        device_slot,
2cfc33
                                                  double                     x,
2cfc33
                                                  double                     y)
2cfc33
 {
2cfc33
   g_warning ("Virtual touch motion not implemented under X11");
2cfc33
 }
2cfc33
 
2cfc33
 static void
2cfc33
 meta_virtual_input_device_x11_notify_touch_motion (ClutterVirtualInputDevice *virtual_device,
2cfc33
                                                    uint64_t                   time_us,
2cfc33
                                                    int                        device_slot,
2cfc33
                                                    double                     x,
2cfc33
                                                    double                     y)
2cfc33
 {
2cfc33
   g_warning ("Virtual touch motion not implemented under X11");
2cfc33
 }
2cfc33
 
2cfc33
 static void
2cfc33
 meta_virtual_input_device_x11_notify_touch_up (ClutterVirtualInputDevice *virtual_device,
2cfc33
                                                uint64_t                   time_us,
2cfc33
                                                int                        device_slot)
2cfc33
 {
2cfc33
   g_warning ("Virtual touch motion not implemented under X11");
2cfc33
-- 
2cfc33
2.33.1
2cfc33