keybindings: Resolve on us layout too if primary is not latin based
If a non-latin based keyboard layout is active, for example Cyrillic, keybindings won't work unless we resolve the bound keysyms on a secondary latin based layout. So, to make keybindings work on non-latin based layouts, detect if a keymap doesn't have all of the basic latin letters (a-z) and resolve from an additional US layout as well. https://bugzilla.gnome.org/show_bug.cgi?id=787016
This commit is contained in:
parent
8b060342bd
commit
487b8a0430
@ -116,8 +116,8 @@ typedef struct
|
|||||||
int n_iso_next_group_combos;
|
int n_iso_next_group_combos;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A primary layout, and an optional secondary layout that is
|
* A primary layout, and an optional secondary layout for when the
|
||||||
* not yet used.
|
* primary layout does not use the latin alphabet.
|
||||||
*/
|
*/
|
||||||
MetaKeyBindingKeyboardLayout active_layouts[2];
|
MetaKeyBindingKeyboardLayout active_layouts[2];
|
||||||
|
|
||||||
|
@ -622,6 +622,86 @@ binding_reload_combos_foreach (gpointer key,
|
|||||||
index_binding (keys, binding);
|
index_binding (keys, binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct _FindLatinKeysymsState
|
||||||
|
{
|
||||||
|
MetaKeyBindingKeyboardLayout *layout;
|
||||||
|
gboolean *required_keysyms_found;
|
||||||
|
int n_required_keysyms;
|
||||||
|
} FindLatinKeysymsState;
|
||||||
|
|
||||||
|
static void
|
||||||
|
find_latin_keysym (struct xkb_keymap *keymap,
|
||||||
|
xkb_keycode_t key,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
FindLatinKeysymsState *state = data;
|
||||||
|
int n_keysyms, i;
|
||||||
|
const xkb_keysym_t *keysyms;
|
||||||
|
|
||||||
|
n_keysyms = xkb_keymap_key_get_syms_by_level (state->layout->keymap,
|
||||||
|
key,
|
||||||
|
state->layout->index,
|
||||||
|
0,
|
||||||
|
&keysyms);
|
||||||
|
for (i = 0; i < n_keysyms; i++)
|
||||||
|
{
|
||||||
|
xkb_keysym_t keysym = keysyms[i];
|
||||||
|
|
||||||
|
if (keysym >= XKB_KEY_a && keysym <= XKB_KEY_z)
|
||||||
|
{
|
||||||
|
unsigned int keysym_index = keysym - XKB_KEY_a;
|
||||||
|
|
||||||
|
if (!state->required_keysyms_found[keysym_index])
|
||||||
|
{
|
||||||
|
state->required_keysyms_found[keysym_index] = TRUE;
|
||||||
|
state->n_required_keysyms--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
needs_secondary_layout (MetaKeyBindingKeyboardLayout *layout)
|
||||||
|
{
|
||||||
|
gboolean required_keysyms_found[] = {
|
||||||
|
FALSE, /* XKB_KEY_a */
|
||||||
|
FALSE, /* XKB_KEY_b */
|
||||||
|
FALSE, /* XKB_KEY_c */
|
||||||
|
FALSE, /* XKB_KEY_d */
|
||||||
|
FALSE, /* XKB_KEY_e */
|
||||||
|
FALSE, /* XKB_KEY_f */
|
||||||
|
FALSE, /* XKB_KEY_g */
|
||||||
|
FALSE, /* XKB_KEY_h */
|
||||||
|
FALSE, /* XKB_KEY_i */
|
||||||
|
FALSE, /* XKB_KEY_j */
|
||||||
|
FALSE, /* XKB_KEY_k */
|
||||||
|
FALSE, /* XKB_KEY_l */
|
||||||
|
FALSE, /* XKB_KEY_m */
|
||||||
|
FALSE, /* XKB_KEY_n */
|
||||||
|
FALSE, /* XKB_KEY_o */
|
||||||
|
FALSE, /* XKB_KEY_p */
|
||||||
|
FALSE, /* XKB_KEY_q */
|
||||||
|
FALSE, /* XKB_KEY_r */
|
||||||
|
FALSE, /* XKB_KEY_s */
|
||||||
|
FALSE, /* XKB_KEY_t */
|
||||||
|
FALSE, /* XKB_KEY_u */
|
||||||
|
FALSE, /* XKB_KEY_v */
|
||||||
|
FALSE, /* XKB_KEY_w */
|
||||||
|
FALSE, /* XKB_KEY_x */
|
||||||
|
FALSE, /* XKB_KEY_y */
|
||||||
|
FALSE, /* XKB_KEY_z */
|
||||||
|
};
|
||||||
|
FindLatinKeysymsState state = {
|
||||||
|
.layout = layout,
|
||||||
|
.required_keysyms_found = required_keysyms_found,
|
||||||
|
.n_required_keysyms = G_N_ELEMENTS (required_keysyms_found),
|
||||||
|
};
|
||||||
|
|
||||||
|
xkb_keymap_key_for_each (layout->keymap, find_latin_keysym, &state);
|
||||||
|
|
||||||
|
return state.n_required_keysyms != 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clear_active_keyboard_layouts (MetaKeyBindingManager *keys)
|
clear_active_keyboard_layouts (MetaKeyBindingManager *keys)
|
||||||
{
|
{
|
||||||
@ -636,22 +716,55 @@ clear_active_keyboard_layouts (MetaKeyBindingManager *keys)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MetaKeyBindingKeyboardLayout
|
||||||
|
create_us_layout (void)
|
||||||
|
{
|
||||||
|
struct xkb_rule_names names;
|
||||||
|
struct xkb_keymap *keymap;
|
||||||
|
struct xkb_context *context;
|
||||||
|
|
||||||
|
names.rules = DEFAULT_XKB_RULES_FILE;
|
||||||
|
names.model = DEFAULT_XKB_MODEL;
|
||||||
|
names.layout = "us";
|
||||||
|
names.variant = "";
|
||||||
|
names.options = "";
|
||||||
|
|
||||||
|
context = xkb_context_new (XKB_CONTEXT_NO_FLAGS);
|
||||||
|
keymap = xkb_keymap_new_from_names (context, &names, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||||
|
xkb_context_unref (context);
|
||||||
|
|
||||||
|
return (MetaKeyBindingKeyboardLayout) {
|
||||||
|
.keymap = keymap,
|
||||||
|
.n_levels = calculate_n_layout_levels (keymap, 0),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
reload_active_keyboard_layouts (MetaKeyBindingManager *keys)
|
reload_active_keyboard_layouts (MetaKeyBindingManager *keys)
|
||||||
{
|
{
|
||||||
struct xkb_keymap *keymap;
|
struct xkb_keymap *keymap;
|
||||||
xkb_layout_index_t layout_index;
|
xkb_layout_index_t layout_index;
|
||||||
|
MetaKeyBindingKeyboardLayout primary_layout;
|
||||||
|
|
||||||
clear_active_keyboard_layouts (keys);
|
clear_active_keyboard_layouts (keys);
|
||||||
|
|
||||||
keymap = meta_backend_get_keymap (keys->backend);
|
keymap = meta_backend_get_keymap (keys->backend);
|
||||||
layout_index = meta_backend_get_keymap_layout_group (keys->backend);
|
layout_index = meta_backend_get_keymap_layout_group (keys->backend);
|
||||||
|
primary_layout = (MetaKeyBindingKeyboardLayout) {
|
||||||
keys->active_layouts[META_KEY_BINDING_PRIMARY_LAYOUT] = (MetaKeyBindingKeyboardLayout) {
|
|
||||||
.keymap = xkb_keymap_ref (keymap),
|
.keymap = xkb_keymap_ref (keymap),
|
||||||
.index = layout_index,
|
.index = layout_index,
|
||||||
.n_levels = calculate_n_layout_levels (keymap, layout_index),
|
.n_levels = calculate_n_layout_levels (keymap, layout_index),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
keys->active_layouts[META_KEY_BINDING_PRIMARY_LAYOUT] = primary_layout;
|
||||||
|
|
||||||
|
if (needs_secondary_layout (&primary_layout))
|
||||||
|
{
|
||||||
|
MetaKeyBindingKeyboardLayout us_layout;
|
||||||
|
|
||||||
|
us_layout = create_us_layout ();
|
||||||
|
keys->active_layouts[META_KEY_BINDING_SECONDARY_LAYOUT] = us_layout;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Loading…
Reference in New Issue
Block a user