summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sway/config.h1
-rw-r--r--sway/commands/bind.c48
-rw-r--r--sway/input/keyboard.c25
-rw-r--r--sway/sway.5.scd9
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 {
28struct sway_binding { 28struct 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 */
142static bool keyboard_execute_bindsym(struct sway_keyboard *keyboard, 142static 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
176static bool binding_matches_keycodes(struct wlr_keyboard *keyboard, 176static 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 */
267static bool keyboard_execute_bindcode(struct sway_keyboard *keyboard, 271static 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