diff options
author | Victor Makarov <vitja.makarov@gmail.com> | 2022-04-28 14:20:44 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-28 13:20:44 +0200 |
commit | 70d30ac72b93c19813f6574025fb4723845ed6a4 (patch) | |
tree | 891abe247eb507bf8b2fc59da7dad9755573b69a /sway/commands/input/xkb_switch_layout.c | |
parent | Update grimshot.1.scd (diff) | |
download | sway-70d30ac72b93c19813f6574025fb4723845ed6a4.tar.gz sway-70d30ac72b93c19813f6574025fb4723845ed6a4.tar.zst sway-70d30ac72b93c19813f6574025fb4723845ed6a4.zip |
xkb_switch_layout: fix relative layout switches
Fixes #6011
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 3be37daf..dabc6697 100644 --- a/sway/commands/input/xkb_switch_layout.c +++ b/sway/commands/input/xkb_switch_layout.c | |||
@@ -6,6 +6,11 @@ | |||
6 | #include "sway/input/input-manager.h" | 6 | #include "sway/input/input-manager.h" |
7 | #include "log.h" | 7 | #include "log.h" |
8 | 8 | ||
9 | struct xkb_switch_layout_action { | ||
10 | struct wlr_keyboard *keyboard; | ||
11 | xkb_layout_index_t layout; | ||
12 | }; | ||
13 | |||
9 | 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) { |
10 | 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); |
11 | if (idx >= num_layouts) { | 16 | if (idx >= num_layouts) { |
@@ -29,10 +34,10 @@ static xkb_layout_index_t get_current_layout_index(struct wlr_keyboard *kbd) { | |||
29 | return layout_idx; | 34 | return layout_idx; |
30 | } | 35 | } |
31 | 36 | ||
32 | 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) { |
33 | 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); |
34 | xkb_layout_index_t idx = get_current_layout_index(kbd); | 39 | xkb_layout_index_t idx = get_current_layout_index(kbd); |
35 | switch_layout(kbd, (idx + num_layouts + dir) % num_layouts); | 40 | return (idx + num_layouts + dir) % num_layouts; |
36 | } | 41 | } |
37 | 42 | ||
38 | 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) { |
@@ -67,6 +72,18 @@ struct cmd_results *input_cmd_xkb_switch_layout(int argc, char **argv) { | |||
67 | relative = 0; | 72 | relative = 0; |
68 | } | 73 | } |
69 | 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. */ | ||
70 | struct sway_input_device *dev; | 87 | struct sway_input_device *dev; |
71 | wl_list_for_each(dev, &server.input->devices, link) { | 88 | wl_list_for_each(dev, &server.input->devices, link) { |
72 | if (strcmp(ic->identifier, "*") != 0 && | 89 | if (strcmp(ic->identifier, "*") != 0 && |
@@ -77,12 +94,23 @@ struct cmd_results *input_cmd_xkb_switch_layout(int argc, char **argv) { | |||
77 | if (dev->wlr_device->type != WLR_INPUT_DEVICE_KEYBOARD) { | 94 | if (dev->wlr_device->type != WLR_INPUT_DEVICE_KEYBOARD) { |
78 | continue; | 95 | continue; |
79 | } | 96 | } |
97 | |||
98 | struct xkb_switch_layout_action *action = | ||
99 | &actions[actions_len++]; | ||
100 | |||
101 | action->keyboard = dev->wlr_device->keyboard; | ||
80 | if (relative) { | 102 | if (relative) { |
81 | switch_layout_relative(dev->wlr_device->keyboard, relative); | 103 | action->layout = get_layout_relative( |
104 | dev->wlr_device->keyboard, relative); | ||
82 | } else { | 105 | } else { |
83 | switch_layout(dev->wlr_device->keyboard, layout); | 106 | action->layout = layout; |
84 | } | 107 | } |
85 | } | 108 | } |
86 | 109 | ||
110 | for (size_t i = 0; i < actions_len; i++) { | ||
111 | switch_layout(actions[i].keyboard, actions[i].layout); | ||
112 | } | ||
113 | free(actions); | ||
114 | |||
87 | return cmd_results_new(CMD_SUCCESS, NULL); | 115 | return cmd_results_new(CMD_SUCCESS, NULL); |
88 | } | 116 | } |