seat_cmd_keyboard_grouping: change keymap to smart

This removes `seat <seat> keyboard_grouping keymap` and replaces it with
`seat <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).
master
Brian Ashworth 5 years ago committed by Drew DeVault
parent 2b51c5b294
commit 452a615bb8

@ -177,9 +177,9 @@ enum seat_config_allow_constrain {
}; };
enum seat_keyboard_grouping { 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_NONE,
KEYBOARD_GROUP_KEYMAP KEYBOARD_GROUP_SMART // keymap and repeat info
}; };
enum sway_input_idle_source { enum sway_input_idle_source {

@ -54,6 +54,9 @@ struct sway_keyboard {
struct xkb_keymap *keymap; struct xkb_keymap *keymap;
xkb_layout_index_t effective_layout; xkb_layout_index_t effective_layout;
int32_t repeat_rate;
int32_t repeat_delay;
struct wl_listener keyboard_key; struct wl_listener keyboard_key;
struct wl_listener keyboard_modifiers; struct wl_listener keyboard_modifiers;

@ -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; struct seat_config *seat_config = config->handler_context.seat_config;
if (strcmp(argv[0], "none") == 0) { if (strcmp(argv[0], "none") == 0) {
seat_config->keyboard_grouping = KEYBOARD_GROUP_NONE; seat_config->keyboard_grouping = KEYBOARD_GROUP_NONE;
} else if (strcmp(argv[0], "keymap") == 0) { } else if (strcmp(argv[0], "smart") == 0) {
seat_config->keyboard_grouping = KEYBOARD_GROUP_KEYMAP; seat_config->keyboard_grouping = KEYBOARD_GROUP_SMART;
} else { } else {
return cmd_results_new(CMD_INVALID, 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); return cmd_results_new(CMD_SUCCESS, NULL);

@ -659,6 +659,11 @@ static bool keymaps_match(struct xkb_keymap *km1, struct xkb_keymap *km2) {
return result; 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) { static void destroy_empty_wlr_keyboard_group(void *data) {
wlr_keyboard_group_destroy(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); sway_keyboard_group_remove(keyboard);
break; break;
case KEYBOARD_GROUP_DEFAULT: /* fallthrough */ case KEYBOARD_GROUP_DEFAULT: /* fallthrough */
case KEYBOARD_GROUP_KEYMAP:; case KEYBOARD_GROUP_SMART:;
struct wlr_keyboard_group *group = wlr_keyboard->group; 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); sway_keyboard_group_remove(keyboard);
} }
break; break;
@ -741,9 +747,10 @@ static void sway_keyboard_group_add(struct sway_keyboard *keyboard) {
// Nothing to do. This shouldn't even be reached // Nothing to do. This shouldn't even be reached
return; return;
case KEYBOARD_GROUP_DEFAULT: /* fallthrough */ case KEYBOARD_GROUP_DEFAULT: /* fallthrough */
case KEYBOARD_GROUP_KEYMAP:; case KEYBOARD_GROUP_SMART:;
struct wlr_keyboard_group *wlr_group = group->wlr_group; 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", sway_log(SWAY_DEBUG, "Adding keyboard %s to group %p",
device->identifier, wlr_group); device->identifier, wlr_group);
wlr_keyboard_group_add_keyboard(wlr_group, wlr_keyboard); 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; sway_group->wlr_group->data = sway_group;
wlr_keyboard_set_keymap(&sway_group->wlr_group->keyboard, keyboard->keymap); 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_log(SWAY_DEBUG, "Created keyboard group %p", sway_group->wlr_group);
sway_group->seat_device = calloc(1, sizeof(struct sway_seat_device)); 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; keyboard->keymap ? !keymaps_match(keyboard->keymap, keymap) : true;
bool effective_layout_changed = keyboard->effective_layout != 0; 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); xkb_keymap_unref(keyboard->keymap);
keyboard->keymap = keymap; keyboard->keymap = keymap;
keyboard->effective_layout = 0; keyboard->effective_layout = 0;
keyboard->repeat_rate = repeat_rate;
keyboard->repeat_delay = repeat_delay;
sway_keyboard_group_remove_invalid(keyboard); sway_keyboard_group_remove_invalid(keyboard);
wlr_keyboard_set_keymap(wlr_device->keyboard, keyboard->keymap); 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) { if (!wlr_device->keyboard->group) {
sway_keyboard_group_add(keyboard); 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; struct wlr_seat *seat = keyboard->seat_device->sway_seat->wlr_seat;
wlr_seat_set_keyboard(seat, wlr_device); wlr_seat_set_keyboard(seat, wlr_device);

@ -230,15 +230,15 @@ correct seat.
"keyboard", "pointer", "touchpad", "touch", "tablet pad", "tablet tool", "keyboard", "pointer", "touchpad", "touch", "tablet pad", "tablet tool",
and "switch". The default behavior is to wake from idle on any event. and "switch". The default behavior is to wake from idle on any event.
*seat* <name> keyboard_grouping none|keymap *seat* <name> keyboard_grouping none|smart
Set how the keyboards in the seat are grouped together. Currently, there Set how the keyboards in the seat are grouped together. Currently, there
are two options. _none_ will disable all keyboard grouping. This will make are two options. _none_ will disable all keyboard grouping. This will make
it so each keyboard device has its own isolated state. _keymap_ will it so each keyboard device has its own isolated state. _smart_ will
group the keyboards in the seat by their keymap. This is useful for when group the keyboards in the seat by their keymap and repeat info. This is
the keyboard appears as multiple separate input devices. In this mode, useful for when the keyboard appears as multiple separate input devices.
the effective layout and repeat info are also synced between the keyboards In this mode, the effective layout is synced between the keyboards in the
in the group. The default is _keymap_. To restore the behavior of older group. The default is _smart_. To restore the behavior of older versions
versions of sway, use _none_. of sway, use _none_.
*seat* <name> pointer_constraint enable|disable|escape *seat* <name> pointer_constraint enable|disable|escape
Enables or disables the ability for clients to capture the cursor (enabled Enables or disables the ability for clients to capture the cursor (enabled

Loading…
Cancel
Save