Fix T99202: AccentGrave key doesn't work with Wayland

Implement scan-code fallback when the scan-code used for AccentGrave
on US keyboards doesn't map to a key known to GHOST.

Without this, shortcuts that use AccentGrave are inaccessible and the
key does nothing.

This matches functionality from X11, see [0].

[0]: f3427cbc98
This commit is contained in:
Campbell Barton 2022-06-28 11:31:12 +10:00
parent b910114384
commit b8cc181808
Notes: blender-bot 2023-02-14 07:45:38 +01:00
Referenced by issue #99202, AccentGrave (`) key doesn't work on Wayland build
Referenced by issue #76428, GHOST/Wayland Support
1 changed files with 42 additions and 3 deletions

View File

@ -94,6 +94,11 @@ static bool use_gnome_confine_hack = false;
/* NOTE(@campbellbarton): Map to an additional button (not sure which hardware uses this). */
#define BTN_STYLUS3 0x149
/**
* Keyboard scan-codes, also from `linux/input-event-codes.h`.
*/
#define KEY_GRAVE 41
struct buffer_t {
void *data = nullptr;
size_t size = 0;
@ -567,8 +572,7 @@ static GHOST_TKey xkb_map_gkey(const xkb_keysym_t &sym)
GXMAP(gkey, XKB_KEY_XF86AudioPrev, GHOST_kKeyMediaFirst);
GXMAP(gkey, XKB_KEY_XF86AudioNext, GHOST_kKeyMediaLast);
default:
GHOST_PRINT("unhandled key: " << std::hex << std::showbase << sym << std::dec << " ("
<< sym << ")" << std::endl);
/* Rely on #xkb_map_gkey_or_scan_code to report when no key can be found. */
gkey = GHOST_kKeyUnknown;
}
#undef GXMAP
@ -577,6 +581,41 @@ static GHOST_TKey xkb_map_gkey(const xkb_keysym_t &sym)
return gkey;
}
/**
* Map the keys using the users keyboard layout, if that fails fall back to physical locations.
* This is needed so users with keyboard layouts that don't expose #GHOST_kKeyAccentGrave
* (typically the key under escape) in the layout can still use this key in keyboard shortcuts.
*
* \param key: The key's scan-code, compatible with values in `linux/input-event-codes.h`.
*/
static GHOST_TKey xkb_map_gkey_or_scan_code(const xkb_keysym_t &sym, const uint32_t key)
{
GHOST_TKey gkey = xkb_map_gkey(sym);
if (gkey == GHOST_kKeyUnknown) {
/* Fall back to physical location for keys that would otherwise do nothing. */
switch (key) {
case KEY_GRAVE: {
gkey = GHOST_kKeyAccentGrave;
break;
}
default: {
GHOST_PRINT(
/* Key-code. */
"unhandled key: " << std::hex << std::showbase << sym << /* Hex. */
std::dec << " (" << sym << "), " << /* Decimal. */
/* Scan-code. */
"scan-code: " << std::hex << std::showbase << key << /* Hex. */
std::dec << " (" << key << ")" << /* Decimal. */
std::endl);
break;
}
}
}
return gkey;
}
static GHOST_TTabletMode tablet_tool_map_type(enum zwp_tablet_tool_v2_type wl_tablet_tool_type)
{
switch (wl_tablet_tool_type) {
@ -1934,7 +1973,7 @@ static void keyboard_handle_key(void *data,
}
}
const GHOST_TKey gkey = xkb_map_gkey(sym);
const GHOST_TKey gkey = xkb_map_gkey_or_scan_code(sym, key);
char utf8_buf[sizeof(GHOST_TEventKeyData::utf8_buf)] = {'\0'};
if (etype == GHOST_kEventKeyDown) {
xkb_state_key_get_utf8(input->xkb_state, key_code, utf8_buf, sizeof(utf8_buf));