diff options
author | Bor Grošelj Simić <bor.groseljsimic@telemach.net> | 2020-02-27 21:50:21 +0100 |
---|---|---|
committer | Simon Ser <contact@emersion.fr> | 2020-03-11 12:12:23 +0100 |
commit | 27d5cf131608594788b3755059391d4b78c072b7 (patch) | |
tree | ba84de92919d5b32e1e476d0b726f282f4f14502 /sway/commands | |
parent | ipc: add missing required properties (diff) | |
download | sway-27d5cf131608594788b3755059391d4b78c072b7.tar.gz sway-27d5cf131608594788b3755059391d4b78c072b7.tar.zst sway-27d5cf131608594788b3755059391d4b78c072b7.zip |
input: implement cycling through keyboard layout list
Diffstat (limited to 'sway/commands')
-rw-r--r-- | sway/commands/input/xkb_switch_layout.c | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/sway/commands/input/xkb_switch_layout.c b/sway/commands/input/xkb_switch_layout.c index 286c040d..d6548a68 100644 --- a/sway/commands/input/xkb_switch_layout.c +++ b/sway/commands/input/xkb_switch_layout.c | |||
@@ -1,4 +1,5 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | 1 | #define _POSIX_C_SOURCE 200809L |
2 | #include <assert.h> | ||
2 | #include "sway/config.h" | 3 | #include "sway/config.h" |
3 | #include "sway/commands.h" | 4 | #include "sway/commands.h" |
4 | #include "sway/input/input-manager.h" | 5 | #include "sway/input/input-manager.h" |
@@ -13,6 +14,26 @@ static void switch_layout(struct wlr_keyboard *kbd, xkb_layout_index_t idx) { | |||
13 | kbd->modifiers.latched, kbd->modifiers.locked, idx); | 14 | kbd->modifiers.latched, kbd->modifiers.locked, idx); |
14 | } | 15 | } |
15 | 16 | ||
17 | static xkb_layout_index_t get_current_layout_index(struct wlr_keyboard *kbd) { | ||
18 | xkb_layout_index_t num_layouts = xkb_keymap_num_layouts(kbd->keymap); | ||
19 | assert(num_layouts > 0); | ||
20 | |||
21 | xkb_layout_index_t layout_idx; | ||
22 | for (layout_idx = 0; layout_idx < num_layouts; layout_idx++) { | ||
23 | if (xkb_state_layout_index_is_active(kbd->xkb_state, | ||
24 | layout_idx, XKB_STATE_LAYOUT_EFFECTIVE)) { | ||
25 | break; | ||
26 | } | ||
27 | } | ||
28 | return layout_idx; | ||
29 | } | ||
30 | |||
31 | static void switch_layout_relative(struct wlr_keyboard *kbd, int dir) { | ||
32 | xkb_layout_index_t num_layouts = xkb_keymap_num_layouts(kbd->keymap); | ||
33 | xkb_layout_index_t idx = get_current_layout_index(kbd); | ||
34 | switch_layout(kbd, (idx + num_layouts + dir) % num_layouts); | ||
35 | } | ||
36 | |||
16 | struct cmd_results *input_cmd_xkb_switch_layout(int argc, char **argv) { | 37 | struct cmd_results *input_cmd_xkb_switch_layout(int argc, char **argv) { |
17 | struct cmd_results *error = NULL; | 38 | struct cmd_results *error = NULL; |
18 | if ((error = checkarg(argc, "xkb_switch_layout", EXPECTED_EQUAL_TO, 1))) { | 39 | if ((error = checkarg(argc, "xkb_switch_layout", EXPECTED_EQUAL_TO, 1))) { |
@@ -28,11 +49,21 @@ struct cmd_results *input_cmd_xkb_switch_layout(int argc, char **argv) { | |||
28 | } | 49 | } |
29 | 50 | ||
30 | const char *layout_str = argv[0]; | 51 | const char *layout_str = argv[0]; |
52 | int relative, layout; | ||
31 | 53 | ||
32 | char *end; | 54 | if (strcmp(layout_str, "next") == 0) { |
33 | int layout = strtol(layout_str, &end, 10); | 55 | relative = 1; |
34 | if (layout_str[0] == '\0' || end[0] != '\0' || layout < 0) { | 56 | } else if (strcmp(layout_str, "prev") == 0) { |
35 | return cmd_results_new(CMD_FAILURE, "Invalid layout index."); | 57 | relative = -1; |
58 | } else { | ||
59 | char *end; | ||
60 | layout = strtol(layout_str, &end, 10); | ||
61 | if (layout_str[0] == '\0' || end[0] != '\0') { | ||
62 | return cmd_results_new(CMD_FAILURE, "Invalid argument."); | ||
63 | } else if (layout < 0) { | ||
64 | return cmd_results_new(CMD_FAILURE, "Invalid layout index."); | ||
65 | } | ||
66 | relative = 0; | ||
36 | } | 67 | } |
37 | 68 | ||
38 | struct sway_input_device *dev; | 69 | struct sway_input_device *dev; |
@@ -45,7 +76,11 @@ struct cmd_results *input_cmd_xkb_switch_layout(int argc, char **argv) { | |||
45 | if (dev->wlr_device->type != WLR_INPUT_DEVICE_KEYBOARD) { | 76 | if (dev->wlr_device->type != WLR_INPUT_DEVICE_KEYBOARD) { |
46 | continue; | 77 | continue; |
47 | } | 78 | } |
48 | switch_layout(dev->wlr_device->keyboard, layout); | 79 | if (relative) { |
80 | switch_layout_relative(dev->wlr_device->keyboard, relative); | ||
81 | } else { | ||
82 | switch_layout(dev->wlr_device->keyboard, layout); | ||
83 | } | ||
49 | } | 84 | } |
50 | 85 | ||
51 | return cmd_results_new(CMD_SUCCESS, NULL); | 86 | return cmd_results_new(CMD_SUCCESS, NULL); |