Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <campbell@blender.org>2022-11-01 06:23:02 +0300
committerCampbell Barton <campbell@blender.org>2022-11-01 06:28:54 +0300
commitfe863b59db40315866d70b78662fc059cc04c59e (patch)
tree75e58232a8d654d06fbb85d3ee2a6bae26343ab9
parent4d139601baec7b1195394fc03bfde98d93060c2c (diff)
Fix T102194: unhandled number keys on AZERTY layout under Wayland
Support layouts such as AZERTY where the shift key is held for number keys. Text entry remains unchanged but these keys now activate shortcuts as expected. This matches a fix in X11 for the same problem: T47228.
-rw-r--r--intern/ghost/intern/GHOST_SystemWayland.cpp112
1 files changed, 100 insertions, 12 deletions
diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp
index 5af9f5a0231..5afbf5b0b5f 100644
--- a/intern/ghost/intern/GHOST_SystemWayland.cpp
+++ b/intern/ghost/intern/GHOST_SystemWayland.cpp
@@ -101,9 +101,7 @@ static const struct GWL_RegistryHandler *gwl_registry_handler_from_interface_slo
int interface_slot);
/* -------------------------------------------------------------------- */
-/** \name Local Defines
- *
- * Control local functionality, compositors specific workarounds.
+/** \name Workaround Compositor Sprsific Bugs
* \{ */
/**
@@ -156,6 +154,18 @@ static bool use_gnome_confine_hack = false;
# define USE_GNOME_NEEDS_LIBDECOR_HACK
#endif
+/* -------------------------------------------------------------------- */
+/** \name Local Defines
+ *
+ * Control local functionality, compositors specific workarounds.
+ * \{ */
+
+/**
+ * Fix short-cut part of keyboard reading code not properly handling some keys, see: T102194.
+ * \note This is similar to X11 workaround by the same name, see: T47228.
+ */
+#define USE_NON_LATIN_KB_WORKAROUND
+
#define WL_NAME_UNSET uint32_t(-1)
/** \} */
@@ -198,6 +208,19 @@ static bool use_gnome_confine_hack = false;
*/
#define KEY_GRAVE 41
+#ifdef USE_NON_LATIN_KB_WORKAROUND
+# define KEY_1 2
+# define KEY_2 3
+# define KEY_3 4
+# define KEY_4 5
+# define KEY_5 6
+# define KEY_6 7
+# define KEY_7 8
+# define KEY_8 9
+# define KEY_9 10
+# define KEY_0 11
+#endif
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -665,12 +688,22 @@ struct GWL_Seat {
* Keep a state with no modifiers active, use for symbol lookups.
*/
struct xkb_state *xkb_state_empty = nullptr;
+
+ /**
+ * Keep a state with shift enabled, use to access predictable number access for AZERTY keymaps.
+ * If shift is not supported by the key-map, this is set to NULL.
+ */
+ struct xkb_state *xkb_state_empty_with_shift = nullptr;
/**
* Keep a state with number-lock enabled, use to access predictable key-pad symbols.
* If number-lock is not supported by the key-map, this is set to NULL.
*/
struct xkb_state *xkb_state_empty_with_numlock = nullptr;
+#ifdef USE_NON_LATIN_KB_WORKAROUND
+ bool xkb_use_non_latin_workaround = false;
+#endif
+
/** Keys held matching `xkb_state`. */
struct GWL_KeyboardDepressedState key_depressed;
@@ -3294,9 +3327,23 @@ static void keyboard_handle_keymap(void *data,
xkb_state_unref(seat->xkb_state_empty);
seat->xkb_state_empty = xkb_state_new(keymap);
+ for (int i = 0; i < MOD_INDEX_NUM; i++) {
+ const GWL_ModifierInfo &mod_info = g_modifier_info_table[i];
+ seat->xkb_keymap_mod_index[i] = xkb_keymap_mod_get_index(keymap, mod_info.xkb_id);
+ }
+
+ xkb_state_unref(seat->xkb_state_empty_with_shift);
+ seat->xkb_state_empty_with_shift = nullptr;
+ {
+ const xkb_mod_index_t mod_shift = seat->xkb_keymap_mod_index[MOD_INDEX_SHIFT];
+ if (mod_shift != XKB_MOD_INVALID) {
+ seat->xkb_state_empty_with_shift = xkb_state_new(keymap);
+ xkb_state_update_mask(seat->xkb_state_empty_with_shift, (1 << mod_shift), 0, 0, 0, 0, 0);
+ }
+ }
+
xkb_state_unref(seat->xkb_state_empty_with_numlock);
seat->xkb_state_empty_with_numlock = nullptr;
-
{
const xkb_mod_index_t mod2 = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_NUM);
const xkb_mod_index_t num = xkb_keymap_mod_get_index(keymap, "NumLock");
@@ -3307,10 +3354,21 @@ static void keyboard_handle_keymap(void *data,
}
}
- for (int i = 0; i < MOD_INDEX_NUM; i++) {
- const GWL_ModifierInfo &mod_info = g_modifier_info_table[i];
- seat->xkb_keymap_mod_index[i] = xkb_keymap_mod_get_index(keymap, mod_info.xkb_id);
+#ifdef USE_NON_LATIN_KB_WORKAROUND
+ seat->xkb_use_non_latin_workaround = false;
+ if (seat->xkb_state_empty_with_shift) {
+ seat->xkb_use_non_latin_workaround = true;
+ for (xkb_keycode_t key_code = KEY_1 + EVDEV_OFFSET; key_code <= KEY_0 + EVDEV_OFFSET;
+ key_code++) {
+ const xkb_keysym_t sym_test = xkb_state_key_get_one_sym(seat->xkb_state_empty_with_shift,
+ key_code);
+ if (!(sym_test >= XKB_KEY_0 && sym_test <= XKB_KEY_9)) {
+ seat->xkb_use_non_latin_workaround = false;
+ break;
+ }
+ }
}
+#endif
keyboard_depressed_state_reset(seat);
@@ -3401,6 +3459,8 @@ static void keyboard_handle_leave(void *data,
static xkb_keysym_t xkb_state_key_get_one_sym_without_modifiers(
struct xkb_state *xkb_state_empty,
struct xkb_state *xkb_state_empty_with_numlock,
+ struct xkb_state *xkb_state_empty_with_shift,
+ const bool xkb_use_non_latin_workaround,
const xkb_keycode_t key)
{
/* Use an empty keyboard state to access key symbol without modifiers. */
@@ -3414,12 +3474,31 @@ static xkb_keysym_t xkb_state_key_get_one_sym_without_modifiers(
/* Accounts for key-pad keys typically swapped for numbers when number-lock is enabled:
* `Home Left Up Right Down Prior Page_Up Next Page_Dow End Begin Insert Delete`. */
- if (xkb_state_empty_with_numlock && (sym >= XKB_KEY_KP_Home && sym <= XKB_KEY_KP_Delete)) {
- const xkb_keysym_t sym_test = xkb_state_key_get_one_sym(xkb_state_empty_with_numlock, key);
- if (sym_test != XKB_KEY_NoSymbol) {
- sym = sym_test;
+ if (sym >= XKB_KEY_KP_Home && sym <= XKB_KEY_KP_Delete) {
+ if (xkb_state_empty_with_numlock) {
+ const xkb_keysym_t sym_test = xkb_state_key_get_one_sym(xkb_state_empty_with_numlock, key);
+ if (sym_test != XKB_KEY_NoSymbol) {
+ sym = sym_test;
+ }
}
}
+ else {
+#ifdef USE_NON_LATIN_KB_WORKAROUND
+ if (key >= (KEY_1 + EVDEV_OFFSET) && key <= (KEY_0 + EVDEV_OFFSET)) {
+ if (xkb_state_empty_with_shift && xkb_use_non_latin_workaround) {
+ const xkb_keysym_t sym_test = xkb_state_key_get_one_sym(xkb_state_empty_with_shift, key);
+ if (sym_test != XKB_KEY_NoSymbol) {
+ /* Should never happen as enabling `xkb_use_non_latin_workaround` checks this. */
+ GHOST_ASSERT(sym_test >= XKB_KEY_0 && sym_test <= XKB_KEY_9, "Unexpected key");
+ sym = sym_test;
+ }
+ }
+ }
+#else
+ (void)xkb_state_empty_with_shift;
+ (void)xkb_use_non_latin_workaround;
+#endif
+ }
return sym;
}
@@ -3461,7 +3540,15 @@ static void keyboard_handle_key(void *data,
const xkb_keycode_t key_code = key + EVDEV_OFFSET;
const xkb_keysym_t sym = xkb_state_key_get_one_sym_without_modifiers(
- seat->xkb_state_empty, seat->xkb_state_empty_with_numlock, key_code);
+ seat->xkb_state_empty,
+ seat->xkb_state_empty_with_numlock,
+ seat->xkb_state_empty_with_shift,
+#ifdef USE_NON_LATIN_KB_WORKAROUND
+ seat->xkb_use_non_latin_workaround,
+#else
+ false,
+#endif
+ key_code);
if (sym == XKB_KEY_NoSymbol) {
CLOG_INFO(LOG, 2, "key (code=%d, state=%u, no symbol, skipped)", int(key_code), state);
return;
@@ -4512,6 +4599,7 @@ static void gwl_registry_wl_seat_remove(GWL_Display *display, void *user_data, c
/* Un-referencing checks for NULL case. */
xkb_state_unref(seat->xkb_state);
xkb_state_unref(seat->xkb_state_empty);
+ xkb_state_unref(seat->xkb_state_empty_with_shift);
xkb_state_unref(seat->xkb_state_empty_with_numlock);
xkb_context_unref(seat->xkb_context);