aboutsummaryrefslogtreecommitdiffstats
path: root/sway/commands
diff options
context:
space:
mode:
authorLibravatar Bor Grošelj Simić <bor.groseljsimic@telemach.net>2020-02-27 21:50:21 +0100
committerLibravatar Simon Ser <contact@emersion.fr>2020-03-11 12:12:23 +0100
commit27d5cf131608594788b3755059391d4b78c072b7 (patch)
treeba84de92919d5b32e1e476d0b726f282f4f14502 /sway/commands
parentipc: add missing required properties (diff)
downloadsway-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.c45
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
17static 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
31static 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
16struct cmd_results *input_cmd_xkb_switch_layout(int argc, char **argv) { 37struct 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);