From 452a615bb8f546fbeaddd7bacc71b5c597ab5629 Mon Sep 17 00:00:00 2001 From: Brian Ashworth Date: Sun, 15 Dec 2019 01:33:33 -0500 Subject: [PATCH] seat_cmd_keyboard_grouping: change keymap to smart This removes `seat keyboard_grouping keymap` and replaces it with `seat keyboard_grouping smart`. The smart keyboard grouping will group based on both the keymap and repeat info. The reasoning for this is that deciding what the repeat info should be for a group is either arbitrary or non-deterministic when multiple keyboards in the group have repeat info configured (unless somehow exposed to the user in a reproducible uniquely identifiable fashion). --- include/sway/config.h | 4 +-- include/sway/input/keyboard.h | 3 ++ sway/commands/seat/keyboard_grouping.c | 6 ++-- sway/input/keyboard.c | 46 +++++++++++++++++--------- sway/sway-input.5.scd | 14 ++++---- 5 files changed, 45 insertions(+), 28 deletions(-) diff --git a/include/sway/config.h b/include/sway/config.h index 3e3d2725..aef6694d 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -177,9 +177,9 @@ enum seat_config_allow_constrain { }; enum seat_keyboard_grouping { - KEYBOARD_GROUP_DEFAULT, // the default is currently keymap + KEYBOARD_GROUP_DEFAULT, // the default is currently smart KEYBOARD_GROUP_NONE, - KEYBOARD_GROUP_KEYMAP + KEYBOARD_GROUP_SMART // keymap and repeat info }; enum sway_input_idle_source { diff --git a/include/sway/input/keyboard.h b/include/sway/input/keyboard.h index 72a29ba6..13fcafcc 100644 --- a/include/sway/input/keyboard.h +++ b/include/sway/input/keyboard.h @@ -54,6 +54,9 @@ struct sway_keyboard { struct xkb_keymap *keymap; xkb_layout_index_t effective_layout; + int32_t repeat_rate; + int32_t repeat_delay; + struct wl_listener keyboard_key; struct wl_listener keyboard_modifiers; diff --git a/sway/commands/seat/keyboard_grouping.c b/sway/commands/seat/keyboard_grouping.c index 959c6f94..5ad0f408 100644 --- a/sway/commands/seat/keyboard_grouping.c +++ b/sway/commands/seat/keyboard_grouping.c @@ -15,11 +15,11 @@ struct cmd_results *seat_cmd_keyboard_grouping(int argc, char **argv) { struct seat_config *seat_config = config->handler_context.seat_config; if (strcmp(argv[0], "none") == 0) { seat_config->keyboard_grouping = KEYBOARD_GROUP_NONE; - } else if (strcmp(argv[0], "keymap") == 0) { - seat_config->keyboard_grouping = KEYBOARD_GROUP_KEYMAP; + } else if (strcmp(argv[0], "smart") == 0) { + seat_config->keyboard_grouping = KEYBOARD_GROUP_SMART; } else { return cmd_results_new(CMD_INVALID, - "Expected syntax `keyboard_grouping none|keymap`"); + "Expected syntax `keyboard_grouping none|smart`"); } return cmd_results_new(CMD_SUCCESS, NULL); diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c index f71a7909..2cfcd126 100644 --- a/sway/input/keyboard.c +++ b/sway/input/keyboard.c @@ -659,6 +659,11 @@ static bool keymaps_match(struct xkb_keymap *km1, struct xkb_keymap *km2) { return result; } +static bool repeat_info_match(struct sway_keyboard *a, struct wlr_keyboard *b) { + return a->repeat_rate == b->repeat_info.rate && + a->repeat_delay == b->repeat_info.delay; +} + static void destroy_empty_wlr_keyboard_group(void *data) { wlr_keyboard_group_destroy(data); } @@ -711,9 +716,10 @@ static void sway_keyboard_group_remove_invalid(struct sway_keyboard *keyboard) { sway_keyboard_group_remove(keyboard); break; case KEYBOARD_GROUP_DEFAULT: /* fallthrough */ - case KEYBOARD_GROUP_KEYMAP:; + case KEYBOARD_GROUP_SMART:; struct wlr_keyboard_group *group = wlr_keyboard->group; - if (!keymaps_match(keyboard->keymap, group->keyboard.keymap)) { + if (!keymaps_match(keyboard->keymap, group->keyboard.keymap) || + !repeat_info_match(keyboard, &group->keyboard)) { sway_keyboard_group_remove(keyboard); } break; @@ -741,9 +747,10 @@ static void sway_keyboard_group_add(struct sway_keyboard *keyboard) { // Nothing to do. This shouldn't even be reached return; case KEYBOARD_GROUP_DEFAULT: /* fallthrough */ - case KEYBOARD_GROUP_KEYMAP:; + case KEYBOARD_GROUP_SMART:; struct wlr_keyboard_group *wlr_group = group->wlr_group; - if (keymaps_match(keyboard->keymap, wlr_group->keyboard.keymap)) { + if (keymaps_match(keyboard->keymap, wlr_group->keyboard.keymap) && + repeat_info_match(keyboard, &wlr_group->keyboard)) { sway_log(SWAY_DEBUG, "Adding keyboard %s to group %p", device->identifier, wlr_group); wlr_keyboard_group_add_keyboard(wlr_group, wlr_keyboard); @@ -767,6 +774,8 @@ static void sway_keyboard_group_add(struct sway_keyboard *keyboard) { } sway_group->wlr_group->data = sway_group; wlr_keyboard_set_keymap(&sway_group->wlr_group->keyboard, keyboard->keymap); + wlr_keyboard_set_repeat_info(&sway_group->wlr_group->keyboard, + keyboard->repeat_rate, keyboard->repeat_delay); sway_log(SWAY_DEBUG, "Created keyboard group %p", sway_group->wlr_group); sway_group->seat_device = calloc(1, sizeof(struct sway_seat_device)); @@ -836,14 +845,30 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) { keyboard->keymap ? !keymaps_match(keyboard->keymap, keymap) : true; bool effective_layout_changed = keyboard->effective_layout != 0; - if (keymap_changed || config->reloading) { + int repeat_rate = 25; + if (input_config && input_config->repeat_rate != INT_MIN) { + repeat_rate = input_config->repeat_rate; + } + int repeat_delay = 600; + if (input_config && input_config->repeat_delay != INT_MIN) { + repeat_delay = input_config->repeat_delay; + } + + bool repeat_info_changed = keyboard->repeat_rate != repeat_rate || + keyboard->repeat_delay != repeat_delay; + + if (keymap_changed || repeat_info_changed || config->reloading) { xkb_keymap_unref(keyboard->keymap); keyboard->keymap = keymap; keyboard->effective_layout = 0; + keyboard->repeat_rate = repeat_rate; + keyboard->repeat_delay = repeat_delay; sway_keyboard_group_remove_invalid(keyboard); wlr_keyboard_set_keymap(wlr_device->keyboard, keyboard->keymap); + wlr_keyboard_set_repeat_info(wlr_device->keyboard, + keyboard->repeat_rate, keyboard->repeat_delay); if (!wlr_device->keyboard->group) { sway_keyboard_group_add(keyboard); @@ -890,17 +915,6 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) { } } - int repeat_rate = 25; - if (input_config && input_config->repeat_rate != INT_MIN) { - repeat_rate = input_config->repeat_rate; - } - int repeat_delay = 600; - if (input_config && input_config->repeat_delay != INT_MIN) { - repeat_delay = input_config->repeat_delay; - } - wlr_keyboard_set_repeat_info(wlr_device->keyboard, repeat_rate, - repeat_delay); - struct wlr_seat *seat = keyboard->seat_device->sway_seat->wlr_seat; wlr_seat_set_keyboard(seat, wlr_device); diff --git a/sway/sway-input.5.scd b/sway/sway-input.5.scd index e1ae6781..a0f155fe 100644 --- a/sway/sway-input.5.scd +++ b/sway/sway-input.5.scd @@ -230,15 +230,15 @@ correct seat. "keyboard", "pointer", "touchpad", "touch", "tablet pad", "tablet tool", and "switch". The default behavior is to wake from idle on any event. -*seat* keyboard_grouping none|keymap +*seat* keyboard_grouping none|smart Set how the keyboards in the seat are grouped together. Currently, there are two options. _none_ will disable all keyboard grouping. This will make - it so each keyboard device has its own isolated state. _keymap_ will - group the keyboards in the seat by their keymap. This is useful for when - the keyboard appears as multiple separate input devices. In this mode, - the effective layout and repeat info are also synced between the keyboards - in the group. The default is _keymap_. To restore the behavior of older - versions of sway, use _none_. + it so each keyboard device has its own isolated state. _smart_ will + group the keyboards in the seat by their keymap and repeat info. This is + useful for when the keyboard appears as multiple separate input devices. + In this mode, the effective layout is synced between the keyboards in the + group. The default is _smart_. To restore the behavior of older versions + of sway, use _none_. *seat* pointer_constraint enable|disable|escape Enables or disables the ability for clients to capture the cursor (enabled