|
|
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 |
|