Linux: When using layouts that map the keys to non-ascii characters, map shortcuts using the ascii equivalents, from the default layout.

Fixes #606
This commit is contained in:
Kovid Goyal 2018-06-11 12:21:35 +05:30
parent 7a7262923b
commit 4711746f8f
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 40 additions and 2 deletions

View File

@ -70,6 +70,10 @@ Changelog
- Add support for the CSI t escape code to query window and cell sizes
(:iss:`581`)
- Linux: When using layouts that map the keys to non-ascii characters,
map shortcuts using the ascii equivalents, from the default layout.
(:iss:`606`)
- Linux: Fix fonts not being correctly read from TrueType Collection
(.ttc) files (:iss:`577`)

36
glfw/xkb_glfw.c vendored
View File

@ -181,6 +181,10 @@ glfw_xkb_release(_GLFWXKBData *xkb) {
xkb_keymap_unref(xkb->keymap);
xkb->keymap = NULL;
}
if (xkb->default_keymap) {
xkb_keymap_unref(xkb->default_keymap);
xkb->default_keymap = NULL;
}
if (xkb->state) {
xkb_state_unref(xkb->state);
xkb->state = NULL;
@ -189,6 +193,10 @@ glfw_xkb_release(_GLFWXKBData *xkb) {
xkb_state_unref(xkb->clean_state);
xkb->clean_state = NULL;
}
if (xkb->default_state) {
xkb_state_unref(xkb->default_state);
xkb->default_state = NULL;
}
if (xkb->context) {
xkb_context_unref(xkb->context);
xkb->context = NULL;
@ -272,6 +280,21 @@ glfw_xkb_compile_keymap(_GLFWXKBData *xkb, const char *map_str) {
xkb->modifiers = 0;
xkb->activeUnknownModifiers = 0;
}
if (!xkb->default_keymap && xkb->context) {
// The system default keymap, can be overridden by the XKB_DEFAULT_RULES
// env var, see
// https://xkbcommon.org/doc/current/structxkb__rule__names.html
static struct xkb_rule_names default_rule_names = {0};
xkb->default_keymap = xkb_keymap_new_from_names(xkb->context, &default_rule_names, XKB_KEYMAP_COMPILE_NO_FLAGS);
if (xkb->default_keymap) {
xkb->default_state = xkb_state_new(keymap);
if (!xkb->default_state) {
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to create default XKB state, fallback key processing is unavailable");
}
} else {
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to create default XKB keymap, fallback key processing is unavailable");
}
}
return ok;
}
@ -379,7 +402,7 @@ format_xkb_mods(_GLFWXKBData *xkb, const char* name, xkb_mod_mask_t mods) {
void
glfw_xkb_handle_key_event(_GLFWwindow *window, _GLFWXKBData *xkb, xkb_keycode_t scancode, int action) {
const xkb_keysym_t *syms, *clean_syms;
const xkb_keysym_t *syms, *clean_syms, *default_syms;
xkb_keysym_t glfw_sym;
xkb_keycode_t code_for_sym = scancode;
#ifdef _GLFW_WAYLAND
@ -422,6 +445,15 @@ glfw_xkb_handle_key_event(_GLFWwindow *window, _GLFWXKBData *xkb, xkb_keycode_t
if (text[0]) { debug("%s: %s ", text_type, text); }
}
int glfw_keycode = glfw_key_for_sym(glfw_sym);
debug("%sglfw_key: %s\n", format_mods(xkb->modifiers), _glfwGetKeyName(glfw_keycode));
if (glfw_keycode == GLFW_KEY_UNKNOWN) {
int num_default_syms = xkb_state_key_get_syms(xkb->default_state, code_for_sym, &default_syms);
if (num_default_syms > 0) {
glfw_sym = default_syms[0];
glfw_keycode = glfw_key_for_sym(glfw_sym);
}
debug("%sglfw_fallback_key: %s\n", format_mods(xkb->modifiers), _glfwGetKeyName(glfw_keycode));
} else {
debug("%sglfw_key: %s\n", format_mods(xkb->modifiers), _glfwGetKeyName(glfw_keycode));
}
_glfwInputKeyboard(window, glfw_keycode, glfw_sym, action, xkb->modifiers, text, 0);
}

2
glfw/xkb_glfw.h vendored
View File

@ -35,8 +35,10 @@
typedef struct {
struct xkb_context* context;
struct xkb_keymap* keymap;
struct xkb_keymap* default_keymap;
struct xkb_state* state;
struct xkb_state* clean_state;
struct xkb_state* default_state;
struct xkb_compose_state* composeState;
xkb_mod_index_t controlIdx;