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.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 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
9struct xkb_switch_layout_action {
10 struct wlr_keyboard *keyboard;
11 xkb_layout_index_t layout;
12};
13
8static 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) {
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
31static void switch_layout_relative(struct wlr_keyboard *kbd, int dir) { 37static 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
37struct cmd_results *input_cmd_xkb_switch_layout(int argc, char **argv) { 43struct 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}