aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <RyanDwyer@users.noreply.github.com>2018-07-24 19:48:27 +1000
committerLibravatar GitHub <noreply@github.com>2018-07-24 19:48:27 +1000
commit1a9179dbab91490c4a8dc45f8630ac139c96efe6 (patch)
tree429de47906f0ba1f114689c48cbabc5be8bb6e71
parentMerge pull request #2284 from frsfnrrg/resolve-workspace-name-todo (diff)
parentMerge branch 'master' into mouse-bindings (diff)
downloadsway-1a9179dbab91490c4a8dc45f8630ac139c96efe6.tar.gz
sway-1a9179dbab91490c4a8dc45f8630ac139c96efe6.tar.zst
sway-1a9179dbab91490c4a8dc45f8630ac139c96efe6.zip
Merge pull request #2303 from frsfnrrg/mouse-bindings
Implement mouse bindings
-rw-r--r--include/sway/config.h23
-rw-r--r--include/sway/input/cursor.h6
-rw-r--r--sway/commands/bind.c168
-rw-r--r--sway/config.c7
-rw-r--r--sway/input/cursor.c102
-rw-r--r--sway/input/keyboard.c42
6 files changed, 271 insertions, 77 deletions
diff --git a/include/sway/config.h b/include/sway/config.h
index b8da29c5..bcd503a4 100644
--- a/include/sway/config.h
+++ b/include/sway/config.h
@@ -22,14 +22,28 @@ struct sway_variable {
22 char *value; 22 char *value;
23}; 23};
24 24
25
26enum binding_input_type {
27 BINDING_KEYCODE,
28 BINDING_KEYSYM,
29 BINDING_MOUSE,
30};
31
32enum binding_flags {
33 BINDING_RELEASE=1,
34 BINDING_LOCKED=2, // keyboard only
35 BINDING_BORDER=4, // mouse only; trigger on container border
36 BINDING_CONTENTS=8, // mouse only; trigger on container contents
37 BINDING_TITLEBAR=16 // mouse only; trigger on container titlebar
38};
39
25/** 40/**
26 * A key binding and an associated command. 41 * A key binding and an associated command.
27 */ 42 */
28struct sway_binding { 43struct sway_binding {
44 enum binding_input_type type;
29 int order; 45 int order;
30 bool release; 46 uint32_t flags;
31 bool locked;
32 bool bindcode;
33 list_t *keys; // sorted in ascending order 47 list_t *keys; // sorted in ascending order
34 uint32_t modifiers; 48 uint32_t modifiers;
35 char *command; 49 char *command;
@@ -50,6 +64,7 @@ struct sway_mode {
50 char *name; 64 char *name;
51 list_t *keysym_bindings; 65 list_t *keysym_bindings;
52 list_t *keycode_bindings; 66 list_t *keycode_bindings;
67 list_t *mouse_bindings;
53 bool pango; 68 bool pango;
54}; 69};
55 70
@@ -482,6 +497,8 @@ void free_sway_binding(struct sway_binding *sb);
482 497
483struct sway_binding *sway_binding_dup(struct sway_binding *sb); 498struct sway_binding *sway_binding_dup(struct sway_binding *sb);
484 499
500void seat_execute_command(struct sway_seat *seat, struct sway_binding *binding);
501
485void load_swaybars(); 502void load_swaybars();
486 503
487void invoke_swaybar(struct bar_config *bar); 504void invoke_swaybar(struct bar_config *bar);
diff --git a/include/sway/input/cursor.h b/include/sway/input/cursor.h
index b0a3a7c5..7ec45120 100644
--- a/include/sway/input/cursor.h
+++ b/include/sway/input/cursor.h
@@ -3,6 +3,8 @@
3#include <stdint.h> 3#include <stdint.h>
4#include "sway/input/seat.h" 4#include "sway/input/seat.h"
5 5
6#define SWAY_CURSOR_PRESSED_BUTTONS_CAP 32
7
6struct sway_cursor { 8struct sway_cursor {
7 struct sway_seat *seat; 9 struct sway_seat *seat;
8 struct wlr_cursor *cursor; 10 struct wlr_cursor *cursor;
@@ -29,6 +31,10 @@ struct sway_cursor {
29 uint32_t tool_buttons; 31 uint32_t tool_buttons;
30 32
31 struct wl_listener request_set_cursor; 33 struct wl_listener request_set_cursor;
34
35 // Mouse binding state
36 uint32_t pressed_buttons[SWAY_CURSOR_PRESSED_BUTTONS_CAP];
37 size_t pressed_button_count;
32}; 38};
33 39
34void sway_cursor_destroy(struct sway_cursor *cursor); 40void sway_cursor_destroy(struct sway_cursor *cursor);
diff --git a/sway/commands/bind.c b/sway/commands/bind.c
index 83e9e432..133fd089 100644
--- a/sway/commands/bind.c
+++ b/sway/commands/bind.c
@@ -34,11 +34,14 @@ void free_sway_binding(struct sway_binding *binding) {
34 */ 34 */
35static bool binding_key_compare(struct sway_binding *binding_a, 35static bool binding_key_compare(struct sway_binding *binding_a,
36 struct sway_binding *binding_b) { 36 struct sway_binding *binding_b) {
37 if (binding_a->release != binding_b->release) { 37 if (binding_a->type != binding_b->type) {
38 return false; 38 return false;
39 } 39 }
40 40
41 if (binding_a->bindcode != binding_b->bindcode) { 41 uint32_t conflict_generating_flags = BINDING_RELEASE | BINDING_BORDER
42 | BINDING_CONTENTS | BINDING_TITLEBAR;
43 if ((binding_a->flags & conflict_generating_flags) !=
44 (binding_b->flags & conflict_generating_flags)) {
42 return false; 45 return false;
43 } 46 }
44 47
@@ -69,6 +72,66 @@ static int key_qsort_cmp(const void *keyp_a, const void *keyp_b) {
69 return (key_a < key_b) ? -1 : ((key_a > key_b) ? 1 : 0); 72 return (key_a < key_b) ? -1 : ((key_a > key_b) ? 1 : 0);
70} 73}
71 74
75
76/**
77 * From a keycode, bindcode, or bindsym name and the most likely binding type,
78 * identify the appropriate numeric value corresponding to the key. Return NULL
79 * and set *key_val if successful, otherwise return a specific error. Change
80 * the value of *type if the initial type guess was incorrect and if this
81 * was the first identified key.
82 */
83static struct cmd_results *identify_key(const char* name, bool first_key,
84 uint32_t* key_val, enum binding_input_type* type) {
85 if (*type == BINDING_KEYCODE) {
86 // check for keycode
87 xkb_keycode_t keycode = strtol(name, NULL, 10);
88 if (!xkb_keycode_is_legal_ext(keycode)) {
89 return cmd_results_new(CMD_INVALID, "bindcode",
90 "Invalid keycode '%s'", name);
91 }
92 *key_val = keycode;
93 } else {
94 // check for keysym
95 xkb_keysym_t keysym = xkb_keysym_from_name(name,
96 XKB_KEYSYM_CASE_INSENSITIVE);
97
98 // Check for mouse binding
99 uint32_t button = 0;
100 if (strncasecmp(name, "button", strlen("button")) == 0 &&
101 strlen(name) == strlen("button0")) {
102 button = name[strlen("button")] - '1' + BTN_LEFT;
103 }
104
105 if (*type == BINDING_KEYSYM) {
106 if (button) {
107 if (first_key) {
108 *type = BINDING_MOUSE;
109 *key_val = button;
110 } else {
111 return cmd_results_new(CMD_INVALID, "bindsym",
112 "Mixed button '%s' into key sequence", name);
113 }
114 } else if (keysym) {
115 *key_val = keysym;
116 } else {
117 return cmd_results_new(CMD_INVALID, "bindsym",
118 "Unknown key '%s'", name);
119 }
120 } else {
121 if (button) {
122 *key_val = button;
123 } else if (keysym) {
124 return cmd_results_new(CMD_INVALID, "bindsym",
125 "Mixed keysym '%s' into button sequence", name);
126 } else {
127 return cmd_results_new(CMD_INVALID, "bindsym",
128 "Unknown button '%s'", name);
129 }
130 }
131 }
132 return NULL;
133}
134
72static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv, 135static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
73 bool bindcode) { 136 bool bindcode) {
74 const char *bindtype = bindcode ? "bindcode" : "bindsym"; 137 const char *bindtype = bindcode ? "bindcode" : "bindsym";
@@ -85,22 +148,34 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
85 } 148 }
86 binding->keys = create_list(); 149 binding->keys = create_list();
87 binding->modifiers = 0; 150 binding->modifiers = 0;
88 binding->release = false; 151 binding->flags = 0;
89 binding->locked = false; 152 binding->type = bindcode ? BINDING_KEYCODE : BINDING_KEYSYM;
90 binding->bindcode = bindcode; 153
154 bool exclude_titlebar = false;
91 155
92 // Handle --release and --locked 156 // Handle --release and --locked
93 while (argc > 0) { 157 while (argc > 0) {
94 if (strcmp("--release", argv[0]) == 0) { 158 if (strcmp("--release", argv[0]) == 0) {
95 binding->release = true; 159 binding->flags |= BINDING_RELEASE;
96 } else if (strcmp("--locked", argv[0]) == 0) { 160 } else if (strcmp("--locked", argv[0]) == 0) {
97 binding->locked = true; 161 binding->flags |= BINDING_LOCKED;
162 } else if (strcmp("--whole-window", argv[0]) == 0) {
163 binding->flags |= BINDING_BORDER | BINDING_CONTENTS | BINDING_TITLEBAR;
164 } else if (strcmp("--border", argv[0]) == 0) {
165 binding->flags |= BINDING_BORDER;
166 } else if (strcmp("--exclude-titlebar", argv[0]) == 0) {
167 exclude_titlebar = true;
98 } else { 168 } else {
99 break; 169 break;
100 } 170 }
101 argv++; 171 argv++;
102 argc--; 172 argc--;
103 } 173 }
174 if (binding->flags & (BINDING_BORDER | BINDING_CONTENTS | BINDING_TITLEBAR)
175 || exclude_titlebar) {
176 binding->type = BINDING_MOUSE;
177 }
178
104 if (argc < 2) { 179 if (argc < 2) {
105 free_sway_binding(binding); 180 free_sway_binding(binding);
106 return cmd_results_new(CMD_FAILURE, bindtype, 181 return cmd_results_new(CMD_FAILURE, bindtype,
@@ -119,64 +194,47 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
119 continue; 194 continue;
120 } 195 }
121 196
122 xkb_keycode_t keycode; 197 // Identify the key and possibly change binding->type
123 xkb_keysym_t keysym; 198 uint32_t key_val = 0;
124 if (bindcode) { 199 error = identify_key(split->items[i], binding->keys->length == 0,
125 // parse keycode 200 &key_val, &binding->type);
126 keycode = (int)strtol(split->items[i], NULL, 10); 201 if (error) {
127 if (!xkb_keycode_is_legal_ext(keycode)) { 202 free_sway_binding(binding);
128 error = 203 list_free(split);
129 cmd_results_new(CMD_INVALID, "bindcode", 204 return error;
130 "Invalid keycode '%s'", (char *)split->items[i]);
131 free_sway_binding(binding);
132 list_free(split);
133 return error;
134 }
135 } else {
136 // Check for xkb key
137 keysym = xkb_keysym_from_name(split->items[i],
138 XKB_KEYSYM_CASE_INSENSITIVE);
139
140 // Check for mouse binding
141 if (strncasecmp(split->items[i], "button", strlen("button")) == 0 &&
142 strlen(split->items[i]) == strlen("button0")) {
143 keysym = ((char *)split->items[i])[strlen("button")] - '1' + BTN_LEFT;
144 }
145 if (!keysym) {
146 struct cmd_results *ret = cmd_results_new(CMD_INVALID, "bindsym",
147 "Unknown key '%s'", (char *)split->items[i]);
148 free_sway_binding(binding);
149 free_flat_list(split);
150 return ret;
151 }
152 } 205 }
206
153 uint32_t *key = calloc(1, sizeof(uint32_t)); 207 uint32_t *key = calloc(1, sizeof(uint32_t));
154 if (!key) { 208 if (!key) {
155 free_sway_binding(binding); 209 free_sway_binding(binding);
156 free_flat_list(split); 210 free_flat_list(split);
157 return cmd_results_new(CMD_FAILURE, bindtype, 211 return cmd_results_new(CMD_FAILURE, bindtype,
158 "Unable to allocate binding"); 212 "Unable to allocate binding key");
159 } 213 }
160 214 *key = key_val;
161 if (bindcode) {
162 *key = (uint32_t)keycode;
163 } else {
164 *key = (uint32_t)keysym;
165 }
166
167 list_add(binding->keys, key); 215 list_add(binding->keys, key);
168 } 216 }
169 free_flat_list(split); 217 free_flat_list(split);
170 binding->order = binding_order++; 218 binding->order = binding_order++;
171 219
220 // refine region of interest for mouse binding once we are certain
221 // that this is one
222 if (exclude_titlebar) {
223 binding->flags &= ~BINDING_TITLEBAR;
224 } else if (binding->type == BINDING_MOUSE) {
225 binding->flags |= BINDING_TITLEBAR;
226 }
227
172 // sort ascending 228 // sort ascending
173 list_qsort(binding->keys, key_qsort_cmp); 229 list_qsort(binding->keys, key_qsort_cmp);
174 230
175 list_t *mode_bindings; 231 list_t *mode_bindings;
176 if (bindcode) { 232 if (binding->type == BINDING_KEYCODE) {
177 mode_bindings = config->current_mode->keycode_bindings; 233 mode_bindings = config->current_mode->keycode_bindings;
178 } else { 234 } else if (binding->type == BINDING_KEYSYM) {
179 mode_bindings = config->current_mode->keysym_bindings; 235 mode_bindings = config->current_mode->keysym_bindings;
236 } else {
237 mode_bindings = config->current_mode->mouse_bindings;
180 } 238 }
181 239
182 // overwrite the binding if it already exists 240 // overwrite the binding if it already exists
@@ -209,3 +267,19 @@ struct cmd_results *cmd_bindsym(int argc, char **argv) {
209struct cmd_results *cmd_bindcode(int argc, char **argv) { 267struct cmd_results *cmd_bindcode(int argc, char **argv) {
210 return cmd_bindsym_or_bindcode(argc, argv, true); 268 return cmd_bindsym_or_bindcode(argc, argv, true);
211} 269}
270
271
272/**
273 * Execute the command associated to a binding
274 */
275void seat_execute_command(struct sway_seat *seat, struct sway_binding *binding) {
276 wlr_log(WLR_DEBUG, "running command for binding: %s",
277 binding->command);
278 config->handler_context.seat = seat;
279 struct cmd_results *results = execute_command(binding->command, NULL);
280 if (results->status != CMD_SUCCESS) {
281 wlr_log(WLR_DEBUG, "could not run command for binding: %s (%s)",
282 binding->command, results->error);
283 }
284 free_cmd_results(results);
285}
diff --git a/sway/config.c b/sway/config.c
index ed624bfa..c2310ff7 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -56,6 +56,12 @@ static void free_mode(struct sway_mode *mode) {
56 } 56 }
57 list_free(mode->keycode_bindings); 57 list_free(mode->keycode_bindings);
58 } 58 }
59 if (mode->mouse_bindings) {
60 for (i = 0; i < mode->mouse_bindings->length; i++) {
61 free_sway_binding(mode->mouse_bindings->items[i]);
62 }
63 list_free(mode->mouse_bindings);
64 }
59 free(mode); 65 free(mode);
60} 66}
61 67
@@ -172,6 +178,7 @@ static void config_defaults(struct sway_config *config) {
172 strcpy(config->current_mode->name, "default"); 178 strcpy(config->current_mode->name, "default");
173 if (!(config->current_mode->keysym_bindings = create_list())) goto cleanup; 179 if (!(config->current_mode->keysym_bindings = create_list())) goto cleanup;
174 if (!(config->current_mode->keycode_bindings = create_list())) goto cleanup; 180 if (!(config->current_mode->keycode_bindings = create_list())) goto cleanup;
181 if (!(config->current_mode->mouse_bindings = create_list())) goto cleanup;
175 list_add(config->modes, config->current_mode); 182 list_add(config->modes, config->current_mode);
176 183
177 config->floating_mod = 0; 184 config->floating_mod = 0;
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index 65d04cac..f1481936 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -469,6 +469,83 @@ static void dispatch_cursor_button_floating(struct sway_cursor *cursor,
469 seat_pointer_notify_button(seat, time_msec, button, state); 469 seat_pointer_notify_button(seat, time_msec, button, state);
470} 470}
471 471
472/**
473 * Remove a button (and duplicates) to the sorted list of currently pressed buttons
474 */
475static void state_erase_button(struct sway_cursor *cursor, uint32_t button) {
476 size_t j = 0;
477 for (size_t i = 0; i < cursor->pressed_button_count; ++i) {
478 if (i > j) {
479 cursor->pressed_buttons[j] = cursor->pressed_buttons[i];
480 }
481 if (cursor->pressed_buttons[i] != button) {
482 ++j;
483 }
484 }
485 while (cursor->pressed_button_count > j) {
486 --cursor->pressed_button_count;
487 cursor->pressed_buttons[cursor->pressed_button_count] = 0;
488 }
489}
490
491/**
492 * Add a button to the sorted list of currently pressed buttons, if there
493 * is space.
494 */
495static void state_add_button(struct sway_cursor *cursor, uint32_t button) {
496 if (cursor->pressed_button_count >= SWAY_CURSOR_PRESSED_BUTTONS_CAP) {
497 return;
498 }
499 size_t i = 0;
500 while (i < cursor->pressed_button_count && cursor->pressed_buttons[i] < button) {
501 ++i;
502 }
503 size_t j = cursor->pressed_button_count;
504 while (j > i) {
505 cursor->pressed_buttons[j] = cursor->pressed_buttons[j - 1];
506 --j;
507 }
508 cursor->pressed_buttons[i] = button;
509 cursor->pressed_button_count++;
510}
511
512/**
513 * Return the mouse binding which matches modifier, click location, release,
514 * and pressed button state, otherwise return null.
515 */
516static struct sway_binding* get_active_mouse_binding(const struct sway_cursor *cursor,
517 list_t *bindings, uint32_t modifiers, bool release, bool on_titlebar,
518 bool on_border, bool on_content) {
519 uint32_t click_region = (on_titlebar ? BINDING_TITLEBAR : 0) |
520 (on_border ? BINDING_BORDER : 0) |
521 (on_content ? BINDING_CONTENTS : 0);
522
523 for (int i = 0; i < bindings->length; ++i) {
524 struct sway_binding *binding = bindings->items[i];
525 if (modifiers ^ binding->modifiers ||
526 cursor->pressed_button_count != (size_t)binding->keys->length ||
527 release != (binding->flags & BINDING_RELEASE) ||
528 !(click_region & binding->flags)) {
529 continue;
530 }
531
532 bool match = true;
533 for (size_t j = 0; j < cursor->pressed_button_count; j++) {
534 uint32_t key = *(uint32_t *)binding->keys->items[j];
535 if (key != cursor->pressed_buttons[j]) {
536 match = false;
537 break;
538 }
539 }
540 if (!match) {
541 continue;
542 }
543
544 return binding;
545 }
546 return NULL;
547}
548
472void dispatch_cursor_button(struct sway_cursor *cursor, 549void dispatch_cursor_button(struct sway_cursor *cursor,
473 uint32_t time_msec, uint32_t button, enum wlr_button_state state) { 550 uint32_t time_msec, uint32_t button, enum wlr_button_state state) {
474 if (cursor->seat->operation != OP_NONE && 551 if (cursor->seat->operation != OP_NONE &&
@@ -485,6 +562,31 @@ void dispatch_cursor_button(struct sway_cursor *cursor,
485 double sx, sy; 562 double sx, sy;
486 struct sway_container *cont = container_at_coords(cursor->seat, 563 struct sway_container *cont = container_at_coords(cursor->seat,
487 cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy); 564 cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
565
566 // Handle mouse bindings
567 bool on_border = find_resize_edge(cont, cursor) != WLR_EDGE_NONE;
568 bool on_contents = !on_border && surface;
569 bool on_titlebar = !on_border && !surface;
570 struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(cursor->seat->wlr_seat);
571 uint32_t modifiers = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0;
572
573 struct sway_binding *binding = NULL;
574 if (state == WLR_BUTTON_PRESSED) {
575 state_add_button(cursor, button);
576 binding = get_active_mouse_binding(cursor,
577 config->current_mode->mouse_bindings, modifiers, false,
578 on_titlebar, on_border, on_contents);
579 } else {
580 binding = get_active_mouse_binding(cursor,
581 config->current_mode->mouse_bindings, modifiers, true,
582 on_titlebar, on_border, on_contents);
583 state_erase_button(cursor, button);
584 }
585 if (binding) {
586 seat_execute_command(cursor->seat, binding);
587 // TODO: do we want to pass on the event?
588 }
589
488 if (surface && wlr_surface_is_layer_surface(surface)) { 590 if (surface && wlr_surface_is_layer_surface(surface)) {
489 struct wlr_layer_surface *layer = 591 struct wlr_layer_surface *layer =
490 wlr_layer_surface_from_wlr_surface(surface); 592 wlr_layer_surface_from_wlr_surface(surface);
diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c
index ede38519..49241db8 100644
--- a/sway/input/keyboard.c
+++ b/sway/input/keyboard.c
@@ -3,11 +3,11 @@
3#include <wlr/backend/multi.h> 3#include <wlr/backend/multi.h>
4#include <wlr/backend/session.h> 4#include <wlr/backend/session.h>
5#include <wlr/types/wlr_idle.h> 5#include <wlr/types/wlr_idle.h>
6#include "sway/commands.h"
6#include "sway/desktop/transaction.h" 7#include "sway/desktop/transaction.h"
7#include "sway/input/seat.h"
8#include "sway/input/keyboard.h"
9#include "sway/input/input-manager.h" 8#include "sway/input/input-manager.h"
10#include "sway/commands.h" 9#include "sway/input/keyboard.h"
10#include "sway/input/seat.h"
11#include "log.h" 11#include "log.h"
12 12
13/** 13/**
@@ -88,11 +88,13 @@ static void get_active_binding(const struct sway_shortcut_state *state,
88 uint32_t modifiers, bool release, bool locked) { 88 uint32_t modifiers, bool release, bool locked) {
89 for (int i = 0; i < bindings->length; ++i) { 89 for (int i = 0; i < bindings->length; ++i) {
90 struct sway_binding *binding = bindings->items[i]; 90 struct sway_binding *binding = bindings->items[i];
91 bool binding_locked = binding->flags & BINDING_LOCKED;
92 bool binding_release = binding->flags & BINDING_RELEASE;
91 93
92 if (modifiers ^ binding->modifiers || 94 if (modifiers ^ binding->modifiers ||
93 state->npressed != (size_t)binding->keys->length || 95 state->npressed != (size_t)binding->keys->length ||
94 locked > binding->locked || 96 release != binding_release ||
95 release != binding->release) { 97 locked > binding_locked) {
96 continue; 98 continue;
97 } 99 }
98 100
@@ -119,23 +121,6 @@ static void get_active_binding(const struct sway_shortcut_state *state,
119} 121}
120 122
121/** 123/**
122 * Execute the command associated to a binding
123 */
124static void keyboard_execute_command(struct sway_keyboard *keyboard,
125 struct sway_binding *binding) {
126 wlr_log(WLR_DEBUG, "running command for binding: %s",
127 binding->command);
128 config->handler_context.seat = keyboard->seat_device->sway_seat;
129 struct cmd_results *results = execute_command(binding->command, NULL);
130 transaction_commit_dirty();
131 if (results->status != CMD_SUCCESS) {
132 wlr_log(WLR_DEBUG, "could not run command for binding: %s (%s)",
133 binding->command, results->error);
134 }
135 free_cmd_results(results);
136}
137
138/**
139 * Execute a built-in, hardcoded compositor binding. These are triggered from a 124 * Execute a built-in, hardcoded compositor binding. These are triggered from a
140 * single keysym. 125 * single keysym.
141 * 126 *
@@ -211,12 +196,13 @@ static size_t keyboard_keysyms_raw(struct sway_keyboard *keyboard,
211static void handle_keyboard_key(struct wl_listener *listener, void *data) { 196static void handle_keyboard_key(struct wl_listener *listener, void *data) {
212 struct sway_keyboard *keyboard = 197 struct sway_keyboard *keyboard =
213 wl_container_of(listener, keyboard, keyboard_key); 198 wl_container_of(listener, keyboard, keyboard_key);
214 struct wlr_seat *wlr_seat = keyboard->seat_device->sway_seat->wlr_seat; 199 struct sway_seat* seat = keyboard->seat_device->sway_seat;
200 struct wlr_seat *wlr_seat = seat->wlr_seat;
215 struct wlr_input_device *wlr_device = 201 struct wlr_input_device *wlr_device =
216 keyboard->seat_device->input_device->wlr_device; 202 keyboard->seat_device->input_device->wlr_device;
217 wlr_idle_notify_activity(keyboard->seat_device->sway_seat->input->server->idle, wlr_seat); 203 wlr_idle_notify_activity(seat->input->server->idle, wlr_seat);
218 struct wlr_event_keyboard_key *event = data; 204 struct wlr_event_keyboard_key *event = data;
219 bool input_inhibited = keyboard->seat_device->sway_seat->exclusive_client != NULL; 205 bool input_inhibited = seat->exclusive_client != NULL;
220 206
221 // Identify new keycode, raw keysym(s), and translated keysym(s) 207 // Identify new keycode, raw keysym(s), and translated keysym(s)
222 xkb_keycode_t keycode = event->keycode + 8; 208 xkb_keycode_t keycode = event->keycode + 8;
@@ -266,7 +252,7 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) {
266 // Execute stored release binding once no longer active 252 // Execute stored release binding once no longer active
267 if (keyboard->held_binding && binding_released != keyboard->held_binding && 253 if (keyboard->held_binding && binding_released != keyboard->held_binding &&
268 event->state == WLR_KEY_RELEASED) { 254 event->state == WLR_KEY_RELEASED) {
269 keyboard_execute_command(keyboard, keyboard->held_binding); 255 seat_execute_command(seat, keyboard->held_binding);
270 handled = true; 256 handled = true;
271 } 257 }
272 if (binding_released != keyboard->held_binding) { 258 if (binding_released != keyboard->held_binding) {
@@ -290,7 +276,7 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) {
290 raw_modifiers, false, input_inhibited); 276 raw_modifiers, false, input_inhibited);
291 277
292 if (binding_pressed) { 278 if (binding_pressed) {
293 keyboard_execute_command(keyboard, binding_pressed); 279 seat_execute_command(seat, binding_pressed);
294 handled = true; 280 handled = true;
295 } 281 }
296 } 282 }
@@ -312,6 +298,8 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) {
312 wlr_seat_keyboard_notify_key(wlr_seat, event->time_msec, 298 wlr_seat_keyboard_notify_key(wlr_seat, event->time_msec,
313 event->keycode, event->state); 299 event->keycode, event->state);
314 } 300 }
301
302 transaction_commit_dirty();
315} 303}
316 304
317static void handle_keyboard_modifiers(struct wl_listener *listener, 305static void handle_keyboard_modifiers(struct wl_listener *listener,