diff options
Diffstat (limited to 'sway/commands/input/xkb_switch_layout.c')
-rw-r--r-- | sway/commands/input/xkb_switch_layout.c | 36 |
1 files changed, 32 insertions, 4 deletions
diff --git a/sway/commands/input/xkb_switch_layout.c b/sway/commands/input/xkb_switch_layout.c index d6548a68..3cce4ec8 100644 --- a/sway/commands/input/xkb_switch_layout.c +++ b/sway/commands/input/xkb_switch_layout.c @@ -1,10 +1,16 @@ #define _POSIX_C_SOURCE 200809L #include <assert.h> +#include <wlr/interfaces/wlr_keyboard.h> #include "sway/config.h" #include "sway/commands.h" #include "sway/input/input-manager.h" #include "log.h" +struct xkb_switch_layout_action { + struct wlr_keyboard *keyboard; + xkb_layout_index_t layout; +}; + static void switch_layout(struct wlr_keyboard *kbd, xkb_layout_index_t idx) { xkb_layout_index_t num_layouts = xkb_keymap_num_layouts(kbd->keymap); if (idx >= num_layouts) { @@ -28,10 +34,10 @@ static xkb_layout_index_t get_current_layout_index(struct wlr_keyboard *kbd) { return layout_idx; } -static void switch_layout_relative(struct wlr_keyboard *kbd, int dir) { +static xkb_layout_index_t get_layout_relative(struct wlr_keyboard *kbd, int dir) { xkb_layout_index_t num_layouts = xkb_keymap_num_layouts(kbd->keymap); xkb_layout_index_t idx = get_current_layout_index(kbd); - switch_layout(kbd, (idx + num_layouts + dir) % num_layouts); + return (idx + num_layouts + dir) % num_layouts; } struct cmd_results *input_cmd_xkb_switch_layout(int argc, char **argv) { @@ -66,6 +72,18 @@ struct cmd_results *input_cmd_xkb_switch_layout(int argc, char **argv) { relative = 0; } + struct xkb_switch_layout_action *actions = calloc( + wl_list_length(&server.input->devices), + sizeof(struct xkb_switch_layout_action)); + size_t actions_len = 0; + + if (!actions) { + return cmd_results_new(CMD_FAILURE, "Unable to allocate actions"); + } + + /* Calculate new indexes first because switching a layout in one + keyboard may result in a change on other keyboards as well because + of keyboard groups. */ struct sway_input_device *dev; wl_list_for_each(dev, &server.input->devices, link) { if (strcmp(ic->identifier, "*") != 0 && @@ -76,12 +94,22 @@ struct cmd_results *input_cmd_xkb_switch_layout(int argc, char **argv) { if (dev->wlr_device->type != WLR_INPUT_DEVICE_KEYBOARD) { continue; } + + struct xkb_switch_layout_action *action = + &actions[actions_len++]; + + action->keyboard = wlr_keyboard_from_input_device(dev->wlr_device); if (relative) { - switch_layout_relative(dev->wlr_device->keyboard, relative); + action->layout = get_layout_relative(action->keyboard, relative); } else { - switch_layout(dev->wlr_device->keyboard, layout); + action->layout = layout; } } + for (size_t i = 0; i < actions_len; i++) { + switch_layout(actions[i].keyboard, actions[i].layout); + } + free(actions); + return cmd_results_new(CMD_SUCCESS, NULL); } |