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

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