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