diff options
author | frsfnrrg <frsfnrrg@users.noreply.github.com> | 2018-05-27 12:37:18 -0400 |
---|---|---|
committer | frsfnrrg <frsfnrrg@users.noreply.github.com> | 2018-05-27 13:28:02 -0400 |
commit | a78a5684ea8a19e54d797ab6cddd2f81f88360a5 (patch) | |
tree | 8870a8acc8d92d10d64e9d3d9bfdd28dedb6eea7 | |
parent | Merge pull request #2052 from emersion/output-destroy-empty-workspace (diff) | |
download | sway-a78a5684ea8a19e54d797ab6cddd2f81f88360a5.tar.gz sway-a78a5684ea8a19e54d797ab6cddd2f81f88360a5.tar.zst sway-a78a5684ea8a19e54d797ab6cddd2f81f88360a5.zip |
Implement bindsym/bindcode --locked
Adds the --locked flag to bindsym and bindcode commands.
When a keyboard's associated seat has an exclusive client
(i.e, a screenlocker), then bindings are only executed if
they have the locked flag. When there is no such client,
this restriction is lifted.
-rw-r--r-- | include/sway/config.h | 1 | ||||
-rw-r--r-- | sway/commands/bind.c | 48 | ||||
-rw-r--r-- | sway/input/keyboard.c | 25 | ||||
-rw-r--r-- | sway/sway.5.scd | 9 |
4 files changed, 52 insertions, 31 deletions
diff --git a/include/sway/config.h b/include/sway/config.h index 33f52156..118981e3 100644 --- a/include/sway/config.h +++ b/include/sway/config.h | |||
@@ -28,6 +28,7 @@ struct sway_variable { | |||
28 | struct sway_binding { | 28 | struct sway_binding { |
29 | int order; | 29 | int order; |
30 | bool release; | 30 | bool release; |
31 | bool locked; | ||
31 | bool bindcode; | 32 | bool bindcode; |
32 | list_t *keys; | 33 | list_t *keys; |
33 | uint32_t modifiers; | 34 | uint32_t modifiers; |
diff --git a/sway/commands/bind.c b/sway/commands/bind.c index cbabb07b..c6b3368a 100644 --- a/sway/commands/bind.c +++ b/sway/commands/bind.c | |||
@@ -83,20 +83,26 @@ struct cmd_results *cmd_bindsym(int argc, char **argv) { | |||
83 | binding->keys = create_list(); | 83 | binding->keys = create_list(); |
84 | binding->modifiers = 0; | 84 | binding->modifiers = 0; |
85 | binding->release = false; | 85 | binding->release = false; |
86 | binding->locked = false; | ||
86 | binding->bindcode = false; | 87 | binding->bindcode = false; |
87 | 88 | ||
88 | // Handle --release | 89 | // Handle --release and --locked |
89 | if (strcmp("--release", argv[0]) == 0) { | 90 | while (argc > 0) { |
90 | if (argc >= 3) { | 91 | if (strcmp("--release", argv[0]) == 0) { |
91 | binding->release = true; | 92 | binding->release = true; |
92 | argv++; | 93 | } else if (strcmp("--locked", argv[0]) == 0) { |
93 | argc--; | 94 | binding->locked = true; |
94 | } else { | 95 | } else { |
95 | free_sway_binding(binding); | 96 | break; |
96 | return cmd_results_new(CMD_FAILURE, "bindsym", | ||
97 | "Invalid bindsym command " | ||
98 | "(expected more than 2 arguments, got %d)", argc); | ||
99 | } | 97 | } |
98 | argv++; | ||
99 | argc--; | ||
100 | } | ||
101 | if (argc < 2) { | ||
102 | free_sway_binding(binding); | ||
103 | return cmd_results_new(CMD_FAILURE, "bindsym", | ||
104 | "Invalid bindsym command " | ||
105 | "(expected at least 2 non-option arguments, got %d)", argc); | ||
100 | } | 106 | } |
101 | 107 | ||
102 | binding->command = join_args(argv + 1, argc - 1); | 108 | binding->command = join_args(argv + 1, argc - 1); |
@@ -176,20 +182,26 @@ struct cmd_results *cmd_bindcode(int argc, char **argv) { | |||
176 | binding->keys = create_list(); | 182 | binding->keys = create_list(); |
177 | binding->modifiers = 0; | 183 | binding->modifiers = 0; |
178 | binding->release = false; | 184 | binding->release = false; |
185 | binding->locked = false; | ||
179 | binding->bindcode = true; | 186 | binding->bindcode = true; |
180 | 187 | ||
181 | // Handle --release | 188 | // Handle --release and --locked |
182 | if (strcmp("--release", argv[0]) == 0) { | 189 | while (argc > 0) { |
183 | if (argc >= 3) { | 190 | if (strcmp("--release", argv[0]) == 0) { |
184 | binding->release = true; | 191 | binding->release = true; |
185 | argv++; | 192 | } else if (strcmp("--locked", argv[0]) == 0) { |
186 | argc--; | 193 | binding->locked = true; |
187 | } else { | 194 | } else { |
188 | free_sway_binding(binding); | 195 | break; |
189 | return cmd_results_new(CMD_FAILURE, "bindcode", | ||
190 | "Invalid bindcode command " | ||
191 | "(expected more than 2 arguments, got %d)", argc); | ||
192 | } | 196 | } |
197 | argv++; | ||
198 | argc--; | ||
199 | } | ||
200 | if (argc < 2) { | ||
201 | free_sway_binding(binding); | ||
202 | return cmd_results_new(CMD_FAILURE, "bindcode", | ||
203 | "Invalid bindcode command " | ||
204 | "(expected at least 2 non-option arguments, got %d)", argc); | ||
193 | } | 205 | } |
194 | 206 | ||
195 | binding->command = join_args(argv + 1, argc - 1); | 207 | binding->command = join_args(argv + 1, argc - 1); |
diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c index c07557db..e873eea3 100644 --- a/sway/input/keyboard.c +++ b/sway/input/keyboard.c | |||
@@ -141,7 +141,7 @@ static bool keyboard_execute_compositor_binding(struct sway_keyboard *keyboard, | |||
141 | */ | 141 | */ |
142 | static bool keyboard_execute_bindsym(struct sway_keyboard *keyboard, | 142 | static bool keyboard_execute_bindsym(struct sway_keyboard *keyboard, |
143 | xkb_keysym_t *pressed_keysyms, uint32_t modifiers, | 143 | xkb_keysym_t *pressed_keysyms, uint32_t modifiers, |
144 | enum wlr_key_state key_state) { | 144 | enum wlr_key_state key_state, bool locked) { |
145 | // configured bindings | 145 | // configured bindings |
146 | int n = pressed_keysyms_length(pressed_keysyms); | 146 | int n = pressed_keysyms_length(pressed_keysyms); |
147 | list_t *keysym_bindings = config->current_mode->keysym_bindings; | 147 | list_t *keysym_bindings = config->current_mode->keysym_bindings; |
@@ -149,7 +149,7 @@ static bool keyboard_execute_bindsym(struct sway_keyboard *keyboard, | |||
149 | struct sway_binding *binding = keysym_bindings->items[i]; | 149 | struct sway_binding *binding = keysym_bindings->items[i]; |
150 | if (!binding_matches_key_state(binding, key_state) || | 150 | if (!binding_matches_key_state(binding, key_state) || |
151 | modifiers ^ binding->modifiers || | 151 | modifiers ^ binding->modifiers || |
152 | n != binding->keys->length) { | 152 | n != binding->keys->length || locked > binding->locked) { |
153 | continue; | 153 | continue; |
154 | } | 154 | } |
155 | 155 | ||
@@ -174,7 +174,7 @@ static bool keyboard_execute_bindsym(struct sway_keyboard *keyboard, | |||
174 | } | 174 | } |
175 | 175 | ||
176 | static bool binding_matches_keycodes(struct wlr_keyboard *keyboard, | 176 | static bool binding_matches_keycodes(struct wlr_keyboard *keyboard, |
177 | struct sway_binding *binding, struct wlr_event_keyboard_key *event) { | 177 | struct sway_binding *binding, struct wlr_event_keyboard_key *event, bool locked) { |
178 | assert(binding->bindcode); | 178 | assert(binding->bindcode); |
179 | 179 | ||
180 | uint32_t keycode = event->keycode + 8; | 180 | uint32_t keycode = event->keycode + 8; |
@@ -183,6 +183,10 @@ static bool binding_matches_keycodes(struct wlr_keyboard *keyboard, | |||
183 | return false; | 183 | return false; |
184 | } | 184 | } |
185 | 185 | ||
186 | if (locked > binding->locked) { | ||
187 | return false; | ||
188 | } | ||
189 | |||
186 | uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard); | 190 | uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard); |
187 | if (modifiers ^ binding->modifiers) { | 191 | if (modifiers ^ binding->modifiers) { |
188 | return false; | 192 | return false; |
@@ -265,13 +269,13 @@ static bool binding_matches_keycodes(struct wlr_keyboard *keyboard, | |||
265 | * should be propagated to clients. | 269 | * should be propagated to clients. |
266 | */ | 270 | */ |
267 | static bool keyboard_execute_bindcode(struct sway_keyboard *keyboard, | 271 | static bool keyboard_execute_bindcode(struct sway_keyboard *keyboard, |
268 | struct wlr_event_keyboard_key *event) { | 272 | struct wlr_event_keyboard_key *event, bool locked) { |
269 | struct wlr_keyboard *wlr_keyboard = | 273 | struct wlr_keyboard *wlr_keyboard = |
270 | keyboard->seat_device->input_device->wlr_device->keyboard; | 274 | keyboard->seat_device->input_device->wlr_device->keyboard; |
271 | list_t *keycode_bindings = config->current_mode->keycode_bindings; | 275 | list_t *keycode_bindings = config->current_mode->keycode_bindings; |
272 | for (int i = 0; i < keycode_bindings->length; ++i) { | 276 | for (int i = 0; i < keycode_bindings->length; ++i) { |
273 | struct sway_binding *binding = keycode_bindings->items[i]; | 277 | struct sway_binding *binding = keycode_bindings->items[i]; |
274 | if (binding_matches_keycodes(wlr_keyboard, binding, event)) { | 278 | if (binding_matches_keycodes(wlr_keyboard, binding, event, locked)) { |
275 | keyboard_execute_command(keyboard, binding); | 279 | keyboard_execute_command(keyboard, binding); |
276 | return true; | 280 | return true; |
277 | } | 281 | } |
@@ -333,19 +337,20 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) { | |||
333 | keyboard->seat_device->input_device->wlr_device; | 337 | keyboard->seat_device->input_device->wlr_device; |
334 | wlr_idle_notify_activity(keyboard->seat_device->sway_seat->input->server->idle, wlr_seat); | 338 | wlr_idle_notify_activity(keyboard->seat_device->sway_seat->input->server->idle, wlr_seat); |
335 | struct wlr_event_keyboard_key *event = data; | 339 | struct wlr_event_keyboard_key *event = data; |
340 | bool input_inhibited = keyboard->seat_device->sway_seat->exclusive_client != NULL; | ||
336 | 341 | ||
337 | xkb_keycode_t keycode = event->keycode + 8; | 342 | xkb_keycode_t keycode = event->keycode + 8; |
338 | bool handled = false; | 343 | bool handled = false; |
339 | 344 | ||
340 | // handle keycodes | 345 | // handle keycodes |
341 | handled = keyboard_execute_bindcode(keyboard, event); | 346 | handled = keyboard_execute_bindcode(keyboard, event, input_inhibited); |
342 | 347 | ||
343 | // handle translated keysyms | 348 | // handle translated keysyms |
344 | if (!handled && event->state == WLR_KEY_RELEASED) { | 349 | if (!handled && event->state == WLR_KEY_RELEASED) { |
345 | handled = keyboard_execute_bindsym(keyboard, | 350 | handled = keyboard_execute_bindsym(keyboard, |
346 | keyboard->pressed_keysyms_translated, | 351 | keyboard->pressed_keysyms_translated, |
347 | keyboard->modifiers_translated, | 352 | keyboard->modifiers_translated, |
348 | event->state); | 353 | event->state, input_inhibited); |
349 | } | 354 | } |
350 | const xkb_keysym_t *translated_keysyms; | 355 | const xkb_keysym_t *translated_keysyms; |
351 | size_t translated_keysyms_len = | 356 | size_t translated_keysyms_len = |
@@ -357,14 +362,14 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) { | |||
357 | handled = keyboard_execute_bindsym(keyboard, | 362 | handled = keyboard_execute_bindsym(keyboard, |
358 | keyboard->pressed_keysyms_translated, | 363 | keyboard->pressed_keysyms_translated, |
359 | keyboard->modifiers_translated, | 364 | keyboard->modifiers_translated, |
360 | event->state); | 365 | event->state, input_inhibited); |
361 | } | 366 | } |
362 | 367 | ||
363 | // Handle raw keysyms | 368 | // Handle raw keysyms |
364 | if (!handled && event->state == WLR_KEY_RELEASED) { | 369 | if (!handled && event->state == WLR_KEY_RELEASED) { |
365 | handled = keyboard_execute_bindsym(keyboard, | 370 | handled = keyboard_execute_bindsym(keyboard, |
366 | keyboard->pressed_keysyms_raw, keyboard->modifiers_raw, | 371 | keyboard->pressed_keysyms_raw, keyboard->modifiers_raw, |
367 | event->state); | 372 | event->state, input_inhibited); |
368 | } | 373 | } |
369 | const xkb_keysym_t *raw_keysyms; | 374 | const xkb_keysym_t *raw_keysyms; |
370 | size_t raw_keysyms_len = | 375 | size_t raw_keysyms_len = |
@@ -374,7 +379,7 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) { | |||
374 | if (!handled && event->state == WLR_KEY_PRESSED) { | 379 | if (!handled && event->state == WLR_KEY_PRESSED) { |
375 | handled = keyboard_execute_bindsym(keyboard, | 380 | handled = keyboard_execute_bindsym(keyboard, |
376 | keyboard->pressed_keysyms_raw, keyboard->modifiers_raw, | 381 | keyboard->pressed_keysyms_raw, keyboard->modifiers_raw, |
377 | event->state); | 382 | event->state, input_inhibited); |
378 | } | 383 | } |
379 | 384 | ||
380 | // Compositor bindings | 385 | // Compositor bindings |
diff --git a/sway/sway.5.scd b/sway/sway.5.scd index e6bc5a1e..5d99c9d6 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd | |||
@@ -186,17 +186,20 @@ runtime. | |||
186 | 186 | ||
187 | for\_window <criteria> move container to workspace <workspace> | 187 | for\_window <criteria> move container to workspace <workspace> |
188 | 188 | ||
189 | *bindsym* <key combo> <command> | 189 | *bindsym* [--release|--locked] <key combo> <command> |
190 | Binds _key combo_ to execute the sway command _command_ when pressed. You | 190 | Binds _key combo_ to execute the sway command _command_ when pressed. You |
191 | may use XKB key names here (*xev*(1) is a good tool for discovering these). | 191 | may use XKB key names here (*xev*(1) is a good tool for discovering these). |
192 | With the flag _--release_, the command is executed when the key combo is | ||
193 | released. Unless the flag _--locked_ is set, the command will not be run | ||
194 | when a screen locking program is active. | ||
192 | 195 | ||
193 | Example: | 196 | Example: |
194 | 197 | ||
195 | # Execute firefox when alt, shift, and f are pressed together | 198 | # Execute firefox when alt, shift, and f are pressed together |
196 | bindsym Mod1+Shift+f exec firefox | 199 | bindsym Mod1+Shift+f exec firefox |
197 | 200 | ||
198 | *bindcode* <code> <command> is also available for binding with key codes | 201 | *bindcode* [--release|--locked] <code> <command> is also available for |
199 | instead of key names. | 202 | binding with key codes instead of key names. |
200 | 203 | ||
201 | *client.<class>* <border> <background> <text> <indicator> <child\_border> | 204 | *client.<class>* <border> <background> <text> <indicator> <child\_border> |
202 | Configures the color of window borders and title bars. All 5 colors are | 205 | Configures the color of window borders and title bars. All 5 colors are |