diff options
author | Drew DeVault <sir@cmpwn.com> | 2015-08-08 19:24:18 -0400 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2015-08-08 19:24:18 -0400 |
commit | a78b9218039de3d6f567990619b4fd255743a67f (patch) | |
tree | 67486c0e4953d4145729670e539f30b5685acb68 | |
parent | Handle focus changes (diff) | |
download | sway-a78b9218039de3d6f567990619b4fd255743a67f.tar.gz sway-a78b9218039de3d6f567990619b4fd255743a67f.tar.zst sway-a78b9218039de3d6f567990619b4fd255743a67f.zip |
Implement key bindings
-rw-r--r-- | sway/commands.c | 49 | ||||
-rw-r--r-- | sway/config.c | 3 | ||||
-rw-r--r-- | sway/config.h | 2 | ||||
-rw-r--r-- | sway/handlers.c | 42 | ||||
-rw-r--r-- | sway/handlers.h | 3 | ||||
-rw-r--r-- | sway/main.c | 5 |
6 files changed, 97 insertions, 7 deletions
diff --git a/sway/commands.c b/sway/commands.c index 89dd0936..6e2a79f6 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -1,5 +1,6 @@ | |||
1 | #include <xkbcommon/xkbcommon.h> | 1 | #include <xkbcommon/xkbcommon.h> |
2 | #include <xkbcommon/xkbcommon-names.h> | 2 | #include <xkbcommon/xkbcommon-names.h> |
3 | #include <wlc/wlc.h> | ||
3 | #include <stdio.h> | 4 | #include <stdio.h> |
4 | #include <stdlib.h> | 5 | #include <stdlib.h> |
5 | #include <string.h> | 6 | #include <string.h> |
@@ -22,6 +23,32 @@ int cmd_set(struct sway_config *config, int argc, char **argv) { | |||
22 | return 0; | 23 | return 0; |
23 | } | 24 | } |
24 | 25 | ||
26 | int cmd_exit(struct sway_config *config, int argc, char **argv) { | ||
27 | if (argc != 0) { | ||
28 | sway_log(L_ERROR, "Invalid exit command (expected 1 arguments, got %d)", argc); | ||
29 | return 1; | ||
30 | } | ||
31 | // TODO: Some kind of clean up is probably in order | ||
32 | exit(0); | ||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | struct modifier_key { | ||
37 | char *name; | ||
38 | uint32_t mod; | ||
39 | }; | ||
40 | |||
41 | struct modifier_key modifiers[] = { | ||
42 | { XKB_MOD_NAME_SHIFT, WLC_BIT_MOD_SHIFT }, | ||
43 | { XKB_MOD_NAME_CAPS, WLC_BIT_MOD_CAPS }, | ||
44 | { XKB_MOD_NAME_CTRL, WLC_BIT_MOD_CTRL }, | ||
45 | { XKB_MOD_NAME_ALT, WLC_BIT_MOD_ALT }, | ||
46 | { XKB_MOD_NAME_NUM, WLC_BIT_MOD_MOD2 }, | ||
47 | { "Mod3", WLC_BIT_MOD_MOD3 }, | ||
48 | { XKB_MOD_NAME_LOGO, WLC_BIT_MOD_LOGO }, | ||
49 | { "Mod5", WLC_BIT_MOD_MOD5 }, | ||
50 | }; | ||
51 | |||
25 | int cmd_bindsym(struct sway_config *config, int argc, char **argv) { | 52 | int cmd_bindsym(struct sway_config *config, int argc, char **argv) { |
26 | if (argc < 2) { | 53 | if (argc < 2) { |
27 | sway_log(L_ERROR, "Invalid set command (expected 2 arguments, got %d)", argc); | 54 | sway_log(L_ERROR, "Invalid set command (expected 2 arguments, got %d)", argc); |
@@ -37,12 +64,22 @@ int cmd_bindsym(struct sway_config *config, int argc, char **argv) { | |||
37 | list_t *split = split_string(argv[0], "+"); | 64 | list_t *split = split_string(argv[0], "+"); |
38 | int i; | 65 | int i; |
39 | for (i = 0; i < split->length; ++i) { | 66 | for (i = 0; i < split->length; ++i) { |
40 | // TODO: Parse modifier keys | 67 | // Check for a modifier key |
68 | int j; | ||
69 | bool is_mod = false; | ||
70 | for (j = 0; j < sizeof(modifiers) / sizeof(struct modifier_key); ++j) { | ||
71 | if (strcasecmp(modifiers[j].name, split->items[i]) == 0) { | ||
72 | binding->modifiers |= modifiers[j].mod; | ||
73 | is_mod = true; | ||
74 | break; | ||
75 | } | ||
76 | } | ||
77 | if (is_mod) continue; | ||
78 | // Check for xkb key | ||
41 | xkb_keysym_t sym = xkb_keysym_from_name(split->items[i], XKB_KEYSYM_CASE_INSENSITIVE); | 79 | xkb_keysym_t sym = xkb_keysym_from_name(split->items[i], XKB_KEYSYM_CASE_INSENSITIVE); |
42 | if (!sym) { | 80 | if (!sym) { |
43 | sway_log(L_ERROR, "bindsym - unknown key %s", (char *)split->items[i]); | 81 | sway_log(L_ERROR, "bindsym - unknown key %s", (char *)split->items[i]); |
44 | // Ignore for now, we need to deal with modifier keys | 82 | return 1; |
45 | // return 1; | ||
46 | } | 83 | } |
47 | xkb_keysym_t *key = malloc(sizeof(xkb_keysym_t)); | 84 | xkb_keysym_t *key = malloc(sizeof(xkb_keysym_t)); |
48 | *key = sym; | 85 | *key = sym; |
@@ -60,7 +97,8 @@ int cmd_bindsym(struct sway_config *config, int argc, char **argv) { | |||
60 | /* Keep alphabetized */ | 97 | /* Keep alphabetized */ |
61 | struct cmd_handler handlers[] = { | 98 | struct cmd_handler handlers[] = { |
62 | { "bindsym", cmd_bindsym }, | 99 | { "bindsym", cmd_bindsym }, |
63 | { "set", cmd_set } | 100 | { "exit", cmd_exit }, |
101 | { "set", cmd_set }, | ||
64 | }; | 102 | }; |
65 | 103 | ||
66 | char **split_directive(char *line, int *argc) { | 104 | char **split_directive(char *line, int *argc) { |
@@ -128,10 +166,11 @@ struct cmd_handler *find_handler(struct cmd_handler handlers[], int l, char *lin | |||
128 | } | 166 | } |
129 | 167 | ||
130 | int handle_command(struct sway_config *config, char *exec) { | 168 | int handle_command(struct sway_config *config, char *exec) { |
169 | sway_log(L_INFO, "Handling command '%s'", exec); | ||
131 | char *ptr, *cmd; | 170 | char *ptr, *cmd; |
132 | if ((ptr = strchr(exec, ' ')) == NULL) { | 171 | if ((ptr = strchr(exec, ' ')) == NULL) { |
133 | cmd = malloc(strlen(exec) + 1); | 172 | cmd = malloc(strlen(exec) + 1); |
134 | strcpy(exec, cmd); | 173 | strcpy(cmd, exec); |
135 | } else { | 174 | } else { |
136 | int index = ptr - exec; | 175 | int index = ptr - exec; |
137 | cmd = malloc(index + 1); | 176 | cmd = malloc(index + 1); |
diff --git a/sway/config.c b/sway/config.c index b93d3f8c..7c610755 100644 --- a/sway/config.c +++ b/sway/config.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include "readline.h" | 4 | #include "readline.h" |
5 | #include "stringop.h" | 5 | #include "stringop.h" |
6 | #include "list.h" | 6 | #include "list.h" |
7 | #include "log.h" | ||
7 | #include "commands.h" | 8 | #include "commands.h" |
8 | #include "config.h" | 9 | #include "config.h" |
9 | 10 | ||
@@ -33,7 +34,7 @@ struct sway_config *read_config(FILE *file) { | |||
33 | goto _continue; | 34 | goto _continue; |
34 | } | 35 | } |
35 | 36 | ||
36 | if (handle_command(config, line) != 0) { | 37 | if (!temp_depth && handle_command(config, line) != 0) { |
37 | success = false; | 38 | success = false; |
38 | } | 39 | } |
39 | 40 | ||
diff --git a/sway/config.h b/sway/config.h index bcf65ec8..88225800 100644 --- a/sway/config.h +++ b/sway/config.h | |||
@@ -30,4 +30,6 @@ struct sway_config { | |||
30 | struct sway_config *read_config(FILE *file); | 30 | struct sway_config *read_config(FILE *file); |
31 | char *do_var_replacement(struct sway_config *config, char *str); | 31 | char *do_var_replacement(struct sway_config *config, char *str); |
32 | 32 | ||
33 | extern struct sway_config *config; | ||
34 | |||
33 | #endif | 35 | #endif |
diff --git a/sway/handlers.c b/sway/handlers.c index 84fd8544..59e67f59 100644 --- a/sway/handlers.c +++ b/sway/handlers.c | |||
@@ -1,8 +1,12 @@ | |||
1 | #include <xkbcommon/xkbcommon.h> | ||
1 | #include <stdlib.h> | 2 | #include <stdlib.h> |
2 | #include <stdbool.h> | 3 | #include <stdbool.h> |
3 | #include <wlc/wlc.h> | 4 | #include <wlc/wlc.h> |
5 | #include <ctype.h> | ||
4 | #include "layout.h" | 6 | #include "layout.h" |
5 | #include "log.h" | 7 | #include "log.h" |
8 | #include "config.h" | ||
9 | #include "commands.h" | ||
6 | #include "handlers.h" | 10 | #include "handlers.h" |
7 | 11 | ||
8 | bool handle_output_created(wlc_handle output) { | 12 | bool handle_output_created(wlc_handle output) { |
@@ -41,3 +45,41 @@ void handle_view_focus(wlc_handle view, bool focus) { | |||
41 | void handle_view_geometry_request(wlc_handle view, const struct wlc_geometry* geometry) { | 45 | void handle_view_geometry_request(wlc_handle view, const struct wlc_geometry* geometry) { |
42 | // deny that shit | 46 | // deny that shit |
43 | } | 47 | } |
48 | |||
49 | bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifiers | ||
50 | *modifiers, uint32_t key, uint32_t sym, enum wlc_key_state state) { | ||
51 | // TODO: handle keybindings with more than 1 non-modifier key involved | ||
52 | // Note: reminder to check conflicts with mod+q+a versus mod+q | ||
53 | |||
54 | bool ret = true; | ||
55 | struct sway_mode *mode = config->current_mode; | ||
56 | sway_log(L_DEBUG, "key pressed: %d %d", sym, modifiers->mods); | ||
57 | |||
58 | // Lowercase if necessary | ||
59 | sym = tolower(sym); | ||
60 | |||
61 | if (state == WLC_KEY_STATE_PRESSED) { | ||
62 | int i; | ||
63 | for (i = 0; i < mode->bindings->length; ++i) { | ||
64 | struct sway_binding *binding = mode->bindings->items[i]; | ||
65 | |||
66 | if ((modifiers->mods & binding->modifiers) == binding->modifiers) { | ||
67 | bool match = true; | ||
68 | int j; | ||
69 | for (j = 0; j < binding->keys->length; ++j) { | ||
70 | xkb_keysym_t *k = binding->keys->items[j]; | ||
71 | if (sym != *k) { | ||
72 | match = false; | ||
73 | break; | ||
74 | } | ||
75 | } | ||
76 | |||
77 | if (match) { | ||
78 | ret = false; | ||
79 | handle_command(config, binding->command); | ||
80 | } | ||
81 | } | ||
82 | } | ||
83 | } | ||
84 | return ret; | ||
85 | } | ||
diff --git a/sway/handlers.h b/sway/handlers.h index 4feebe05..d0cc67c8 100644 --- a/sway/handlers.h +++ b/sway/handlers.h | |||
@@ -13,4 +13,7 @@ void handle_view_destroyed(wlc_handle view); | |||
13 | void handle_view_focus(wlc_handle view, bool focus); | 13 | void handle_view_focus(wlc_handle view, bool focus); |
14 | void handle_view_geometry_request(wlc_handle view, const struct wlc_geometry* geometry); | 14 | void handle_view_geometry_request(wlc_handle view, const struct wlc_geometry* geometry); |
15 | 15 | ||
16 | bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifiers | ||
17 | *modifiers, uint32_t key, uint32_t sym, enum wlc_key_state state); | ||
18 | |||
16 | #endif | 19 | #endif |
diff --git a/sway/main.c b/sway/main.c index 65aa0faa..e547ef4a 100644 --- a/sway/main.c +++ b/sway/main.c | |||
@@ -11,7 +11,7 @@ struct sway_config *config; | |||
11 | 11 | ||
12 | void load_config() { | 12 | void load_config() { |
13 | // TODO: Allow use of more config file locations | 13 | // TODO: Allow use of more config file locations |
14 | const char *name = "/.i3/config"; | 14 | const char *name = "/.sway/config"; |
15 | const char *home = getenv("HOME"); | 15 | const char *home = getenv("HOME"); |
16 | char *temp = malloc(strlen(home) + strlen(name) + 1); | 16 | char *temp = malloc(strlen(home) + strlen(name) + 1); |
17 | strcpy(temp, home); | 17 | strcpy(temp, home); |
@@ -45,6 +45,9 @@ int main(int argc, char **argv) { | |||
45 | .request = { | 45 | .request = { |
46 | .geometry = handle_view_geometry_request | 46 | .geometry = handle_view_geometry_request |
47 | } | 47 | } |
48 | }, | ||
49 | .keyboard = { | ||
50 | .key = handle_key | ||
48 | } | 51 | } |
49 | }; | 52 | }; |
50 | 53 | ||