diff options
Diffstat (limited to 'sway/commands/input/xkb_switch_layout.c')
-rw-r--r-- | sway/commands/input/xkb_switch_layout.c | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/sway/commands/input/xkb_switch_layout.c b/sway/commands/input/xkb_switch_layout.c index d6548a68..ecac8e6c 100644 --- a/sway/commands/input/xkb_switch_layout.c +++ b/sway/commands/input/xkb_switch_layout.c | |||
@@ -1,10 +1,15 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <assert.h> | 1 | #include <assert.h> |
2 | #include <wlr/interfaces/wlr_keyboard.h> | ||
3 | #include "sway/config.h" | 3 | #include "sway/config.h" |
4 | #include "sway/commands.h" | 4 | #include "sway/commands.h" |
5 | #include "sway/input/input-manager.h" | 5 | #include "sway/input/input-manager.h" |
6 | #include "log.h" | 6 | #include "log.h" |
7 | 7 | ||
8 | struct xkb_switch_layout_action { | ||
9 | struct wlr_keyboard *keyboard; | ||
10 | xkb_layout_index_t layout; | ||
11 | }; | ||
12 | |||
8 | static void switch_layout(struct wlr_keyboard *kbd, xkb_layout_index_t idx) { | 13 | static void switch_layout(struct wlr_keyboard *kbd, xkb_layout_index_t idx) { |
9 | xkb_layout_index_t num_layouts = xkb_keymap_num_layouts(kbd->keymap); | 14 | xkb_layout_index_t num_layouts = xkb_keymap_num_layouts(kbd->keymap); |
10 | if (idx >= num_layouts) { | 15 | if (idx >= num_layouts) { |
@@ -28,10 +33,10 @@ static xkb_layout_index_t get_current_layout_index(struct wlr_keyboard *kbd) { | |||
28 | return layout_idx; | 33 | return layout_idx; |
29 | } | 34 | } |
30 | 35 | ||
31 | static void switch_layout_relative(struct wlr_keyboard *kbd, int dir) { | 36 | static xkb_layout_index_t get_layout_relative(struct wlr_keyboard *kbd, int dir) { |
32 | xkb_layout_index_t num_layouts = xkb_keymap_num_layouts(kbd->keymap); | 37 | xkb_layout_index_t num_layouts = xkb_keymap_num_layouts(kbd->keymap); |
33 | xkb_layout_index_t idx = get_current_layout_index(kbd); | 38 | xkb_layout_index_t idx = get_current_layout_index(kbd); |
34 | switch_layout(kbd, (idx + num_layouts + dir) % num_layouts); | 39 | return (idx + num_layouts + dir) % num_layouts; |
35 | } | 40 | } |
36 | 41 | ||
37 | struct cmd_results *input_cmd_xkb_switch_layout(int argc, char **argv) { | 42 | struct cmd_results *input_cmd_xkb_switch_layout(int argc, char **argv) { |
@@ -66,6 +71,18 @@ struct cmd_results *input_cmd_xkb_switch_layout(int argc, char **argv) { | |||
66 | relative = 0; | 71 | relative = 0; |
67 | } | 72 | } |
68 | 73 | ||
74 | struct xkb_switch_layout_action *actions = calloc( | ||
75 | wl_list_length(&server.input->devices), | ||
76 | sizeof(struct xkb_switch_layout_action)); | ||
77 | size_t actions_len = 0; | ||
78 | |||
79 | if (!actions) { | ||
80 | return cmd_results_new(CMD_FAILURE, "Unable to allocate actions"); | ||
81 | } | ||
82 | |||
83 | /* Calculate new indexes first because switching a layout in one | ||
84 | keyboard may result in a change on other keyboards as well because | ||
85 | of keyboard groups. */ | ||
69 | struct sway_input_device *dev; | 86 | struct sway_input_device *dev; |
70 | wl_list_for_each(dev, &server.input->devices, link) { | 87 | wl_list_for_each(dev, &server.input->devices, link) { |
71 | if (strcmp(ic->identifier, "*") != 0 && | 88 | if (strcmp(ic->identifier, "*") != 0 && |
@@ -76,12 +93,22 @@ struct cmd_results *input_cmd_xkb_switch_layout(int argc, char **argv) { | |||
76 | if (dev->wlr_device->type != WLR_INPUT_DEVICE_KEYBOARD) { | 93 | if (dev->wlr_device->type != WLR_INPUT_DEVICE_KEYBOARD) { |
77 | continue; | 94 | continue; |
78 | } | 95 | } |
96 | |||
97 | struct xkb_switch_layout_action *action = | ||
98 | &actions[actions_len++]; | ||
99 | |||
100 | action->keyboard = wlr_keyboard_from_input_device(dev->wlr_device); | ||
79 | if (relative) { | 101 | if (relative) { |
80 | switch_layout_relative(dev->wlr_device->keyboard, relative); | 102 | action->layout = get_layout_relative(action->keyboard, relative); |
81 | } else { | 103 | } else { |
82 | switch_layout(dev->wlr_device->keyboard, layout); | 104 | action->layout = layout; |
83 | } | 105 | } |
84 | } | 106 | } |
85 | 107 | ||
108 | for (size_t i = 0; i < actions_len; i++) { | ||
109 | switch_layout(actions[i].keyboard, actions[i].layout); | ||
110 | } | ||
111 | free(actions); | ||
112 | |||
86 | return cmd_results_new(CMD_SUCCESS, NULL); | 113 | return cmd_results_new(CMD_SUCCESS, NULL); |
87 | } | 114 | } |