aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Victor Makarov <vitja.makarov@gmail.com>2022-04-28 14:20:44 +0300
committerLibravatar GitHub <noreply@github.com>2022-04-28 13:20:44 +0200
commit70d30ac72b93c19813f6574025fb4723845ed6a4 (patch)
tree891abe247eb507bf8b2fc59da7dad9755573b69a
parentUpdate grimshot.1.scd (diff)
downloadsway-70d30ac72b93c19813f6574025fb4723845ed6a4.tar.gz
sway-70d30ac72b93c19813f6574025fb4723845ed6a4.tar.zst
sway-70d30ac72b93c19813f6574025fb4723845ed6a4.zip
xkb_switch_layout: fix relative layout switches
Fixes #6011
-rw-r--r--sway/commands/input/xkb_switch_layout.c36
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
9struct xkb_switch_layout_action {
10 struct wlr_keyboard *keyboard;
11 xkb_layout_index_t layout;
12};
13
9static void switch_layout(struct wlr_keyboard *kbd, xkb_layout_index_t idx) { 14static 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
32static void switch_layout_relative(struct wlr_keyboard *kbd, int dir) { 37static 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
38struct cmd_results *input_cmd_xkb_switch_layout(int argc, char **argv) { 43struct 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}