diff options
Diffstat (limited to 'sway/input/keyboard.c')
-rw-r--r-- | sway/input/keyboard.c | 41 |
1 files changed, 32 insertions, 9 deletions
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 | */ |
151 | static void get_active_binding(const struct sway_shortcut_state *state, | 151 | static 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 |