Translate bindsym bindings upon ISO_Next_Group
With commit c738b2e454
we changed i3 so
that the default keybindings can be used when ISO_Next_Group is enabled,
but bindings which explicitly use Mode_switch have precedence. This
behavior required the use of bindcode instead of bindsym.
With this commit, when switching from group 1 to group 2 using
ISO_Next_Group, i3 will re-translate all keybindings (looking at column
2/3, regardless of whether the keybinding itself specifies Mode_switch)
and re-grab them.
That way, the keybinding “bindsym $mod+x nop foo” will work when
pressing $mod+x without Mode_switch and when pressing the corresponding
$mod+x (different key) with Mode_switch. A binding such as “bindsym
Mode_switch+$mod+x nop bar” will still have precedence.
The intention here is to make bindsym keybindings work well with dual
keyboard layouts (such as {dvorak, us} or {us, ru}), so that users can
switch between groups and still have their (logical) keybindings behave
the same way.
fixes #1775
This commit is contained in:
parent
fed05ef876
commit
0fb784f5cb
@ -111,9 +111,7 @@ static void grab_keycode_for_binding(xcb_connection_t *conn, Binding *bind, uint
|
|||||||
void grab_all_keys(xcb_connection_t *conn, bool bind_mode_switch) {
|
void grab_all_keys(xcb_connection_t *conn, bool bind_mode_switch) {
|
||||||
Binding *bind;
|
Binding *bind;
|
||||||
TAILQ_FOREACH(bind, bindings, bindings) {
|
TAILQ_FOREACH(bind, bindings, bindings) {
|
||||||
if (bind->input_type != B_KEYBOARD ||
|
if (bind->input_type != B_KEYBOARD)
|
||||||
(bind_mode_switch && (bind->mods & BIND_MODE_SWITCH) == 0) ||
|
|
||||||
(!bind_mode_switch && (bind->mods & BIND_MODE_SWITCH) != 0))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* The easy case: the user specified a keycode directly. */
|
/* The easy case: the user specified a keycode directly. */
|
||||||
@ -225,7 +223,7 @@ Binding *get_binding_from_xcb_event(xcb_generic_event_t *event) {
|
|||||||
/* No match? Then the user has Mode_switch enabled but does not have a
|
/* No match? Then the user has Mode_switch enabled but does not have a
|
||||||
* specific keybinding. Fall back to the default keybindings (without
|
* specific keybinding. Fall back to the default keybindings (without
|
||||||
* Mode_switch). Makes it much more convenient for users of a hybrid
|
* Mode_switch). Makes it much more convenient for users of a hybrid
|
||||||
* layout (like ru). */
|
* layout (like {us, ru} or {dvorak, us}, see e.g. ticket #1775). */
|
||||||
if (bind == NULL) {
|
if (bind == NULL) {
|
||||||
state_filtered &= ~(BIND_MODE_SWITCH);
|
state_filtered &= ~(BIND_MODE_SWITCH);
|
||||||
DLOG("no match, new state_filtered = %d\n", state_filtered);
|
DLOG("no match, new state_filtered = %d\n", state_filtered);
|
||||||
@ -252,6 +250,8 @@ void translate_keysyms(void) {
|
|||||||
int col;
|
int col;
|
||||||
xcb_keycode_t i, min_keycode, max_keycode;
|
xcb_keycode_t i, min_keycode, max_keycode;
|
||||||
|
|
||||||
|
const bool mode_switch = (xkb_current_group == XCB_XKB_GROUP_2);
|
||||||
|
|
||||||
min_keycode = xcb_get_setup(conn)->min_keycode;
|
min_keycode = xcb_get_setup(conn)->min_keycode;
|
||||||
max_keycode = xcb_get_setup(conn)->max_keycode;
|
max_keycode = xcb_get_setup(conn)->max_keycode;
|
||||||
|
|
||||||
@ -282,7 +282,7 @@ void translate_keysyms(void) {
|
|||||||
* the base column and the corresponding shift column, so without
|
* the base column and the corresponding shift column, so without
|
||||||
* mode_switch, we look in 0 and 1, with mode_switch we look in 2 and
|
* mode_switch, we look in 0 and 1, with mode_switch we look in 2 and
|
||||||
* 3. */
|
* 3. */
|
||||||
col = (bind->mods & BIND_MODE_SWITCH ? 2 : 0);
|
col = (bind->mods & BIND_MODE_SWITCH || mode_switch ? 2 : 0);
|
||||||
|
|
||||||
FREE(bind->translated_to);
|
FREE(bind->translated_to);
|
||||||
bind->number_keycodes = 0;
|
bind->number_keycodes = 0;
|
||||||
|
@ -1361,14 +1361,10 @@ void handle_event(int type, xcb_generic_event_t *event) {
|
|||||||
if (xkb_current_group == state->group)
|
if (xkb_current_group == state->group)
|
||||||
return;
|
return;
|
||||||
xkb_current_group = state->group;
|
xkb_current_group = state->group;
|
||||||
if (state->group == XCB_XKB_GROUP_1) {
|
DLOG("Mode_switch %s\n", (xkb_current_group == XCB_XKB_GROUP_1 ? "disabled" : "enabled"));
|
||||||
DLOG("Mode_switch disabled\n");
|
|
||||||
ungrab_all_keys(conn);
|
ungrab_all_keys(conn);
|
||||||
grab_all_keys(conn, false);
|
translate_keysyms();
|
||||||
} else {
|
grab_all_keys(conn, (xkb_current_group == XCB_XKB_GROUP_2));
|
||||||
DLOG("Mode_switch enabled\n");
|
|
||||||
grab_all_keys(conn, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user