diff options
-rw-r--r-- | include/key_state.h | 18 | ||||
-rw-r--r-- | sway/commands.c | 17 | ||||
-rw-r--r-- | sway/handlers.c | 39 | ||||
-rw-r--r-- | sway/key_state.c | 52 |
4 files changed, 94 insertions, 32 deletions
diff --git a/include/key_state.h b/include/key_state.h new file mode 100644 index 00000000..a8fa8d5e --- /dev/null +++ b/include/key_state.h | |||
@@ -0,0 +1,18 @@ | |||
1 | #ifndef _SWAY_KEY_STATE_H | ||
2 | #define _SWAY_KEY_STATE_H | ||
3 | #include <stdbool.h> | ||
4 | #include <stdint.h> | ||
5 | |||
6 | typedef uint32_t keycode; | ||
7 | |||
8 | // returns true if key has been pressed, otherwise false | ||
9 | bool check_key(keycode key); | ||
10 | |||
11 | // sets a key as pressed | ||
12 | void press_key(keycode key); | ||
13 | |||
14 | // unsets a key as pressed | ||
15 | void release_key(keycode key); | ||
16 | |||
17 | #endif | ||
18 | |||
diff --git a/sway/commands.c b/sway/commands.c index f3553b03..66c05a0c 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -76,6 +76,18 @@ static bool checkarg(int argc, char *name, enum expected_args type, int val) { | |||
76 | return false; | 76 | return false; |
77 | } | 77 | } |
78 | 78 | ||
79 | static int bindsym_sort(const void *_lbind, const void *_rbind) { | ||
80 | const struct sway_binding *lbind = *(void **)_lbind; | ||
81 | const struct sway_binding *rbind = *(void **)_rbind; | ||
82 | unsigned int lmod = 0, rmod = 0, i; | ||
83 | |||
84 | //Count how any modifiers are pressed | ||
85 | for (i = 0; i < 8 * sizeof(lbind->modifiers); ++i) { | ||
86 | lmod += lbind->modifiers & 1 << i; | ||
87 | rmod += rbind->modifiers & 1 << i; | ||
88 | } | ||
89 | return (rbind->keys->length + rmod) - (lbind->keys->length + lmod); | ||
90 | } | ||
79 | 91 | ||
80 | static bool cmd_bindsym(struct sway_config *config, int argc, char **argv) { | 92 | static bool cmd_bindsym(struct sway_config *config, int argc, char **argv) { |
81 | if (!checkarg(argc, "bindsym", EXPECTED_MORE_THAN, 1)) { | 93 | if (!checkarg(argc, "bindsym", EXPECTED_MORE_THAN, 1)) { |
@@ -118,7 +130,10 @@ static bool cmd_bindsym(struct sway_config *config, int argc, char **argv) { | |||
118 | list_free(split); | 130 | list_free(split); |
119 | 131 | ||
120 | // TODO: Check if there are other commands with this key binding | 132 | // TODO: Check if there are other commands with this key binding |
121 | list_add(config->current_mode->bindings, binding); | 133 | struct sway_mode *mode = config->current_mode; |
134 | list_add(mode->bindings, binding); | ||
135 | qsort(mode->bindings->items, mode->bindings->length, | ||
136 | sizeof(mode->bindings->items[0]), bindsym_sort); | ||
122 | 137 | ||
123 | sway_log(L_DEBUG, "bindsym - Bound %s to command %s", argv[0], binding->command); | 138 | sway_log(L_DEBUG, "bindsym - Bound %s to command %s", argv[0], binding->command); |
124 | return true; | 139 | return true; |
diff --git a/sway/handlers.c b/sway/handlers.c index 63db972e..c9d7c7ac 100644 --- a/sway/handlers.c +++ b/sway/handlers.c | |||
@@ -13,9 +13,7 @@ | |||
13 | #include "workspace.h" | 13 | #include "workspace.h" |
14 | #include "container.h" | 14 | #include "container.h" |
15 | #include "focus.h" | 15 | #include "focus.h" |
16 | 16 | #include "key_state.h" | |
17 | #define KEY_CACHE_SIZE 32 | ||
18 | uint32_t keys_pressed[KEY_CACHE_SIZE]; | ||
19 | 17 | ||
20 | static struct wlc_origin mouse_origin; | 18 | static struct wlc_origin mouse_origin; |
21 | 19 | ||
@@ -327,7 +325,6 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier | |||
327 | if (locked_view_focus && state == WLC_KEY_STATE_PRESSED) { | 325 | if (locked_view_focus && state == WLC_KEY_STATE_PRESSED) { |
328 | return false; | 326 | return false; |
329 | } | 327 | } |
330 | bool cmd_success = false; | ||
331 | 328 | ||
332 | // Revert floating container back to original position on keypress | 329 | // Revert floating container back to original position on keypress |
333 | if (state == WLC_KEY_STATE_PRESSED && (dragging || resizing)) { | 330 | if (state == WLC_KEY_STATE_PRESSED && (dragging || resizing)) { |
@@ -356,16 +353,10 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier | |||
356 | } | 353 | } |
357 | } | 354 | } |
358 | 355 | ||
359 | int total = 0; | 356 | if (state == WLC_KEY_STATE_PRESSED) { |
360 | for (i = 0; i < KEY_CACHE_SIZE && !mod; ++i) { | 357 | press_key(sym); |
361 | total += keys_pressed[i] != 0; | 358 | } else { // WLC_KEY_STATE_RELEASED |
362 | if (state == WLC_KEY_STATE_PRESSED && keys_pressed[i] == 0) { | 359 | release_key(sym); |
363 | keys_pressed[i] = sym; | ||
364 | break; | ||
365 | } else if (state == WLC_KEY_STATE_RELEASED && keys_pressed[i] == sym) { | ||
366 | keys_pressed[i] = 0; | ||
367 | break; | ||
368 | } | ||
369 | } | 360 | } |
370 | 361 | ||
371 | // TODO: reminder to check conflicts with mod+q+a versus mod+q | 362 | // TODO: reminder to check conflicts with mod+q+a versus mod+q |
@@ -376,32 +367,22 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier | |||
376 | bool match; | 367 | bool match; |
377 | int j; | 368 | int j; |
378 | for (j = 0; j < binding->keys->length; ++j) { | 369 | for (j = 0; j < binding->keys->length; ++j) { |
379 | match = false; | ||
380 | xkb_keysym_t *key = binding->keys->items[j]; | 370 | xkb_keysym_t *key = binding->keys->items[j]; |
381 | int k; | 371 | if ((match = check_key(*key)) == false) { |
382 | for (k = 0; k < KEY_CACHE_SIZE; ++k) { | ||
383 | if (keys_pressed[k] == *key) { | ||
384 | match = true; | ||
385 | break; | ||
386 | } | ||
387 | } | ||
388 | if (match == false) { | ||
389 | break; | 372 | break; |
390 | } | 373 | } |
391 | } | 374 | } |
392 | |||
393 | if (match) { | 375 | if (match) { |
394 | // Remove matched keys from keys_pressed | ||
395 | if (state == WLC_KEY_STATE_PRESSED) { | 376 | if (state == WLC_KEY_STATE_PRESSED) { |
396 | handle_command(config, binding->command); | 377 | handle_command(config, binding->command); |
397 | cmd_success = true; | 378 | return true; |
398 | } else if (state == WLC_KEY_STATE_RELEASED) { | 379 | } else if (state == WLC_KEY_STATE_RELEASED) { |
399 | // TODO: --released | 380 | // TODO: --released |
400 | } | 381 | } |
401 | } | 382 | } |
402 | } | 383 | } |
403 | } | 384 | } |
404 | return cmd_success; | 385 | return false; |
405 | } | 386 | } |
406 | 387 | ||
407 | static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct wlc_origin *origin) { | 388 | static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct wlc_origin *origin) { |
@@ -590,10 +571,6 @@ static void handle_wlc_ready(void) { | |||
590 | } | 571 | } |
591 | free_flat_list(config->cmd_queue); | 572 | free_flat_list(config->cmd_queue); |
592 | config->active = true; | 573 | config->active = true; |
593 | |||
594 | for (i = 0; i < KEY_CACHE_SIZE; ++i) { | ||
595 | keys_pressed[i] = 0; | ||
596 | } | ||
597 | } | 574 | } |
598 | 575 | ||
599 | 576 | ||
diff --git a/sway/key_state.c b/sway/key_state.c new file mode 100644 index 00000000..76561dbc --- /dev/null +++ b/sway/key_state.c | |||
@@ -0,0 +1,52 @@ | |||
1 | #include <string.h> | ||
2 | #include <stdbool.h> | ||
3 | #include <ctype.h> | ||
4 | |||
5 | #include "key_state.h" | ||
6 | |||
7 | enum { KEY_STATE_MAX_LENGTH = 64 }; | ||
8 | |||
9 | static keycode key_state_array[KEY_STATE_MAX_LENGTH]; | ||
10 | static uint8_t key_state_length = 0; | ||
11 | |||
12 | static uint8_t find_key(keycode key) | ||
13 | { | ||
14 | int i; | ||
15 | for (i = 0; i < key_state_length; ++i) | ||
16 | { | ||
17 | if (key_state_array[i] == key) | ||
18 | { | ||
19 | break; | ||
20 | } | ||
21 | } | ||
22 | return i; | ||
23 | } | ||
24 | |||
25 | bool check_key(keycode key) | ||
26 | { | ||
27 | return find_key(key) < key_state_length; | ||
28 | } | ||
29 | |||
30 | void press_key(keycode key) | ||
31 | { | ||
32 | // Check if key exists | ||
33 | if (!check_key(key)) | ||
34 | { | ||
35 | // Check that we dont exceed buffer length | ||
36 | if (key_state_length < KEY_STATE_MAX_LENGTH) { | ||
37 | key_state_array[key_state_length++] = key; | ||
38 | } | ||
39 | } | ||
40 | } | ||
41 | |||
42 | void release_key(keycode key) | ||
43 | { | ||
44 | uint8_t index = find_key(key); | ||
45 | if (index < key_state_length) | ||
46 | { | ||
47 | //shift it over and remove key | ||
48 | memmove(&key_state_array[index], | ||
49 | &key_state_array[index + 1], | ||
50 | sizeof(*key_state_array) * (--key_state_length - index)); | ||
51 | } | ||
52 | } | ||