aboutsummaryrefslogtreecommitdiffstats
path: root/sway/input
diff options
context:
space:
mode:
Diffstat (limited to 'sway/input')
-rw-r--r--sway/input/input-manager.c47
-rw-r--r--sway/input/keyboard.c41
-rw-r--r--sway/input/seat.c16
3 files changed, 95 insertions, 9 deletions
diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c
index 4cc07fe6..af0f5afa 100644
--- a/sway/input/input-manager.c
+++ b/sway/input/input-manager.c
@@ -296,6 +296,46 @@ static void handle_inhibit_deactivate(struct wl_listener *listener, void *data)
296 } 296 }
297} 297}
298 298
299static void handle_keyboard_shortcuts_inhibitor_destroy(
300 struct wl_listener *listener, void *data) {
301 struct sway_keyboard_shortcuts_inhibitor *sway_inhibitor =
302 wl_container_of(listener, sway_inhibitor, destroy);
303
304 sway_log(SWAY_DEBUG, "Removing keyboard shortcuts inhibitor");
305
306 // sway_seat::keyboard_shortcuts_inhibitors
307 wl_list_remove(&sway_inhibitor->link);
308 wl_list_remove(&sway_inhibitor->destroy.link);
309 free(sway_inhibitor);
310}
311
312static void handle_keyboard_shortcuts_inhibit_new_inhibitor(
313 struct wl_listener *listener, void *data) {
314 struct sway_input_manager *input_manager =
315 wl_container_of(listener, input_manager,
316 keyboard_shortcuts_inhibit_new_inhibitor);
317 struct wlr_keyboard_shortcuts_inhibitor_v1 *inhibitor = data;
318
319 sway_log(SWAY_DEBUG, "Adding keyboard shortcuts inhibitor");
320
321 struct sway_keyboard_shortcuts_inhibitor *sway_inhibitor =
322 calloc(1, sizeof(struct sway_keyboard_shortcuts_inhibitor));
323 if (!sway_assert(sway_inhibitor, "could not allocate keyboard "
324 "shortcuts inhibitor")) {
325 return;
326 }
327 sway_inhibitor->inhibitor = inhibitor;
328
329 sway_inhibitor->destroy.notify = handle_keyboard_shortcuts_inhibitor_destroy;
330 wl_signal_add(&inhibitor->events.destroy, &sway_inhibitor->destroy);
331
332 // attach inhibitor to the seat it applies to
333 struct sway_seat *seat = inhibitor->seat->data;
334 wl_list_insert(&seat->keyboard_shortcuts_inhibitors, &sway_inhibitor->link);
335
336 wlr_keyboard_shortcuts_inhibitor_v1_activate(inhibitor);
337}
338
299void handle_virtual_keyboard(struct wl_listener *listener, void *data) { 339void handle_virtual_keyboard(struct wl_listener *listener, void *data) {
300 struct sway_input_manager *input_manager = 340 struct sway_input_manager *input_manager =
301 wl_container_of(listener, input_manager, virtual_keyboard_new); 341 wl_container_of(listener, input_manager, virtual_keyboard_new);
@@ -397,6 +437,13 @@ struct sway_input_manager *input_manager_create(struct sway_server *server) {
397 wl_signal_add(&input->inhibit->events.deactivate, 437 wl_signal_add(&input->inhibit->events.deactivate,
398 &input->inhibit_deactivate); 438 &input->inhibit_deactivate);
399 439
440 input->keyboard_shortcuts_inhibit =
441 wlr_keyboard_shortcuts_inhibit_v1_create(server->wl_display);
442 input->keyboard_shortcuts_inhibit_new_inhibitor.notify =
443 handle_keyboard_shortcuts_inhibit_new_inhibitor;
444 wl_signal_add(&input->keyboard_shortcuts_inhibit->events.new_inhibitor,
445 &input->keyboard_shortcuts_inhibit_new_inhibitor);
446
400 return input; 447 return input;
401} 448}
402 449
diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c
index 2cfcd126..9c5f190e 100644
--- a/sway/input/keyboard.c
+++ b/sway/input/keyboard.c
@@ -150,16 +150,18 @@ static bool update_shortcut_state(struct sway_shortcut_state *state,
150 */ 150 */
151static void get_active_binding(const struct sway_shortcut_state *state, 151static void get_active_binding(const struct sway_shortcut_state *state,
152 list_t *bindings, struct sway_binding **current_binding, 152 list_t *bindings, struct sway_binding **current_binding,
153 uint32_t modifiers, bool release, bool locked, const char *input, 153 uint32_t modifiers, bool release, bool locked, bool inhibited,
154 bool exact_input, xkb_layout_index_t group) { 154 const char *input, bool exact_input, xkb_layout_index_t group) {
155 for (int i = 0; i < bindings->length; ++i) { 155 for (int i = 0; i < bindings->length; ++i) {
156 struct sway_binding *binding = bindings->items[i]; 156 struct sway_binding *binding = bindings->items[i];
157 bool binding_locked = (binding->flags & BINDING_LOCKED) != 0; 157 bool binding_locked = (binding->flags & BINDING_LOCKED) != 0;
158 bool binding_inhibited = (binding->flags & BINDING_INHIBITED) != 0;
158 bool binding_release = binding->flags & BINDING_RELEASE; 159 bool binding_release = binding->flags & BINDING_RELEASE;
159 160
160 if (modifiers ^ binding->modifiers || 161 if (modifiers ^ binding->modifiers ||
161 release != binding_release || 162 release != binding_release ||
162 locked > binding_locked || 163 locked > binding_locked ||
164 inhibited > binding_inhibited ||
163 (binding->group != XKB_LAYOUT_INVALID && 165 (binding->group != XKB_LAYOUT_INVALID &&
164 binding->group != group) || 166 binding->group != group) ||
165 (strcmp(binding->input, input) != 0 && 167 (strcmp(binding->input, input) != 0 &&
@@ -195,6 +197,8 @@ static void get_active_binding(const struct sway_shortcut_state *state,
195 197
196 bool current_locked = 198 bool current_locked =
197 ((*current_binding)->flags & BINDING_LOCKED) != 0; 199 ((*current_binding)->flags & BINDING_LOCKED) != 0;
200 bool current_inhibited =
201 ((*current_binding)->flags & BINDING_INHIBITED) != 0;
198 bool current_input = strcmp((*current_binding)->input, input) == 0; 202 bool current_input = strcmp((*current_binding)->input, input) == 0;
199 bool current_group_set = 203 bool current_group_set =
200 (*current_binding)->group != XKB_LAYOUT_INVALID; 204 (*current_binding)->group != XKB_LAYOUT_INVALID;
@@ -203,6 +207,7 @@ static void get_active_binding(const struct sway_shortcut_state *state,
203 207
204 if (current_input == binding_input 208 if (current_input == binding_input
205 && current_locked == binding_locked 209 && current_locked == binding_locked
210 && current_inhibited == binding_inhibited
206 && current_group_set == binding_group_set) { 211 && current_group_set == binding_group_set) {
207 sway_log(SWAY_DEBUG, 212 sway_log(SWAY_DEBUG,
208 "Encountered conflicting bindings %d and %d", 213 "Encountered conflicting bindings %d and %d",
@@ -224,11 +229,21 @@ static void get_active_binding(const struct sway_shortcut_state *state,
224 current_locked == locked) { 229 current_locked == locked) {
225 continue; // Prefer correct lock state for matching input+group 230 continue; // Prefer correct lock state for matching input+group
226 } 231 }
232
233 if (current_input == binding_input &&
234 current_group_set == binding_group_set &&
235 current_locked == binding_locked &&
236 current_inhibited == inhibited) {
237 // Prefer correct inhibition state for matching
238 // input+group+locked
239 continue;
240 }
227 } 241 }
228 242
229 *current_binding = binding; 243 *current_binding = binding;
230 if (strcmp((*current_binding)->input, input) == 0 && 244 if (strcmp((*current_binding)->input, input) == 0 &&
231 (((*current_binding)->flags & BINDING_LOCKED) == locked) && 245 (((*current_binding)->flags & BINDING_LOCKED) == locked) &&
246 (((*current_binding)->flags & BINDING_INHIBITED) == inhibited) &&
232 (*current_binding)->group == group) { 247 (*current_binding)->group == group) {
233 return; // If a perfect match is found, quit searching 248 return; // If a perfect match is found, quit searching
234 } 249 }
@@ -328,6 +343,9 @@ static void handle_key_event(struct sway_keyboard *keyboard,
328 bool exact_identifier = wlr_device->keyboard->group != NULL; 343 bool exact_identifier = wlr_device->keyboard->group != NULL;
329 seat_idle_notify_activity(seat, IDLE_SOURCE_KEYBOARD); 344 seat_idle_notify_activity(seat, IDLE_SOURCE_KEYBOARD);
330 bool input_inhibited = seat->exclusive_client != NULL; 345 bool input_inhibited = seat->exclusive_client != NULL;
346 struct sway_keyboard_shortcuts_inhibitor *sway_inhibitor =
347 keyboard_shortcuts_inhibitor_get_for_focused_surface(seat);
348 bool shortcuts_inhibited = sway_inhibitor && sway_inhibitor->inhibitor->active;
331 349
332 // Identify new keycode, raw keysym(s), and translated keysym(s) 350 // Identify new keycode, raw keysym(s), and translated keysym(s)
333 xkb_keycode_t keycode = event->keycode + 8; 351 xkb_keycode_t keycode = event->keycode + 8;
@@ -364,15 +382,18 @@ static void handle_key_event(struct sway_keyboard *keyboard,
364 struct sway_binding *binding_released = NULL; 382 struct sway_binding *binding_released = NULL;
365 get_active_binding(&keyboard->state_keycodes, 383 get_active_binding(&keyboard->state_keycodes,
366 config->current_mode->keycode_bindings, &binding_released, 384 config->current_mode->keycode_bindings, &binding_released,
367 code_modifiers, true, input_inhibited, device_identifier, 385 code_modifiers, true, input_inhibited,
386 shortcuts_inhibited, device_identifier,
368 exact_identifier, keyboard->effective_layout); 387 exact_identifier, keyboard->effective_layout);
369 get_active_binding(&keyboard->state_keysyms_raw, 388 get_active_binding(&keyboard->state_keysyms_raw,
370 config->current_mode->keysym_bindings, &binding_released, 389 config->current_mode->keysym_bindings, &binding_released,
371 raw_modifiers, true, input_inhibited, device_identifier, 390 raw_modifiers, true, input_inhibited,
391 shortcuts_inhibited, device_identifier,
372 exact_identifier, keyboard->effective_layout); 392 exact_identifier, keyboard->effective_layout);
373 get_active_binding(&keyboard->state_keysyms_translated, 393 get_active_binding(&keyboard->state_keysyms_translated,
374 config->current_mode->keysym_bindings, &binding_released, 394 config->current_mode->keysym_bindings, &binding_released,
375 translated_modifiers, true, input_inhibited, device_identifier, 395 translated_modifiers, true, input_inhibited,
396 shortcuts_inhibited, device_identifier,
376 exact_identifier, keyboard->effective_layout); 397 exact_identifier, keyboard->effective_layout);
377 398
378 // Execute stored release binding once no longer active 399 // Execute stored release binding once no longer active
@@ -393,17 +414,19 @@ static void handle_key_event(struct sway_keyboard *keyboard,
393 if (event->state == WLR_KEY_PRESSED) { 414 if (event->state == WLR_KEY_PRESSED) {
394 get_active_binding(&keyboard->state_keycodes, 415 get_active_binding(&keyboard->state_keycodes,
395 config->current_mode->keycode_bindings, &binding, 416 config->current_mode->keycode_bindings, &binding,
396 code_modifiers, false, input_inhibited, device_identifier, 417 code_modifiers, false, input_inhibited,
418 shortcuts_inhibited, device_identifier,
397 exact_identifier, keyboard->effective_layout); 419 exact_identifier, keyboard->effective_layout);
398 get_active_binding(&keyboard->state_keysyms_raw, 420 get_active_binding(&keyboard->state_keysyms_raw,
399 config->current_mode->keysym_bindings, &binding, 421 config->current_mode->keysym_bindings, &binding,
400 raw_modifiers, false, input_inhibited, device_identifier, 422 raw_modifiers, false, input_inhibited,
423 shortcuts_inhibited, device_identifier,
401 exact_identifier, keyboard->effective_layout); 424 exact_identifier, keyboard->effective_layout);
402 get_active_binding(&keyboard->state_keysyms_translated, 425 get_active_binding(&keyboard->state_keysyms_translated,
403 config->current_mode->keysym_bindings, &binding, 426 config->current_mode->keysym_bindings, &binding,
404 translated_modifiers, false, input_inhibited, 427 translated_modifiers, false, input_inhibited,
405 device_identifier, exact_identifier, 428 shortcuts_inhibited, device_identifier,
406 keyboard->effective_layout); 429 exact_identifier, keyboard->effective_layout);
407 } 430 }
408 431
409 // Set up (or clear) keyboard repeat for a pressed binding. Since the 432 // Set up (or clear) keyboard repeat for a pressed binding. Since the
diff --git a/sway/input/seat.c b/sway/input/seat.c
index 371de56e..6739c163 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -557,6 +557,7 @@ struct sway_seat *seat_create(const char *seat_name) {
557 handle_request_set_primary_selection; 557 handle_request_set_primary_selection;
558 558
559 wl_list_init(&seat->keyboard_groups); 559 wl_list_init(&seat->keyboard_groups);
560 wl_list_init(&seat->keyboard_shortcuts_inhibitors);
560 561
561 wl_list_insert(&server.input->seats, &seat->link); 562 wl_list_insert(&server.input->seats, &seat->link);
562 563
@@ -1473,3 +1474,18 @@ void seatop_render(struct sway_seat *seat, struct sway_output *output,
1473bool seatop_allows_set_cursor(struct sway_seat *seat) { 1474bool seatop_allows_set_cursor(struct sway_seat *seat) {
1474 return seat->seatop_impl->allow_set_cursor; 1475 return seat->seatop_impl->allow_set_cursor;
1475} 1476}
1477
1478struct sway_keyboard_shortcuts_inhibitor *
1479keyboard_shortcuts_inhibitor_get_for_focused_surface(
1480 const struct sway_seat *seat) {
1481 struct wlr_surface *focused_surface =
1482 seat->wlr_seat->keyboard_state.focused_surface;
1483 struct sway_keyboard_shortcuts_inhibitor *sway_inhibitor = NULL;
1484 wl_list_for_each(sway_inhibitor, &seat->keyboard_shortcuts_inhibitors, link) {
1485 if (sway_inhibitor->inhibitor->surface == focused_surface) {
1486 return sway_inhibitor;
1487 }
1488 }
1489
1490 return NULL;
1491}