aboutsummaryrefslogtreecommitdiffstats
path: root/sway/commands/input/xkb_switch_layout.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/commands/input/xkb_switch_layout.c')
-rw-r--r--sway/commands/input/xkb_switch_layout.c37
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
8struct xkb_switch_layout_action {
9 struct wlr_keyboard *keyboard;
10 xkb_layout_index_t layout;
11};
12
8static void switch_layout(struct wlr_keyboard *kbd, xkb_layout_index_t idx) { 13static 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
31static void switch_layout_relative(struct wlr_keyboard *kbd, int dir) { 36static 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
37struct cmd_results *input_cmd_xkb_switch_layout(int argc, char **argv) { 42struct 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}