summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Mikkel Oscar Lyderik <mikkeloscar@gmail.com>2016-03-19 13:42:32 +0100
committerLibravatar Mikkel Oscar Lyderik <mikkeloscar@gmail.com>2016-03-19 14:06:46 +0100
commitbb32cba795c7ab11e3b4844d21f0b2ae2f1fdc2d (patch)
treea9075a0c6834aed4eb5c18d62f817d4fcf1ab172
parentAllow legal non-x11 keycodes (diff)
downloadsway-bb32cba795c7ab11e3b4844d21f0b2ae2f1fdc2d.tar.gz
sway-bb32cba795c7ab11e3b4844d21f0b2ae2f1fdc2d.tar.zst
sway-bb32cba795c7ab11e3b4844d21f0b2ae2f1fdc2d.zip
Make key handling less strict
Sway has been very strict when it comes to key handling. Only on an exact match would a bindsym be triggered. This patch makes it less strict by for instance allowing the key combo `$mod+1+2` to act as `$mod+2` if 2 was the last pressed key and `$mod+1` if 1 was the last pressed key. The new key handling uses the following algorithm: 1. List of bindings sorted by number of keys in binding (already the default) 2. Find all bindings covered by the current keyboard state and list them by same order as in 1. 3. Select the first binding from the list where the last pressed key is part of the binding. Addresses #452
-rw-r--r--sway/handlers.c48
1 files changed, 38 insertions, 10 deletions
diff --git a/sway/handlers.c b/sway/handlers.c
index d992a7b6..cec63192 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -405,7 +405,28 @@ static void handle_binding_command(struct sway_binding *binding) {
405 free_cmd_results(res); 405 free_cmd_results(res);
406} 406}
407 407
408static bool handle_bindsym(struct sway_binding *binding) { 408static bool handle_bindsym(struct sway_binding *binding, uint32_t keysym, uint32_t keycode) {
409 int i;
410 for (i = 0; i < binding->keys->length; ++i) {
411 if (binding->bindcode) {
412 xkb_keycode_t *key = binding->keys->items[i];
413 if (keycode == *key) {
414 handle_binding_command(binding);
415 return true;
416 }
417 } else {
418 xkb_keysym_t *key = binding->keys->items[i];
419 if (keysym == *key) {
420 handle_binding_command(binding);
421 return true;
422 }
423 }
424 }
425
426 return false;
427}
428
429static bool valid_bindsym(struct sway_binding *binding) {
409 bool match = false; 430 bool match = false;
410 int i; 431 int i;
411 for (i = 0; i < binding->keys->length; ++i) { 432 for (i = 0; i < binding->keys->length; ++i) {
@@ -422,12 +443,7 @@ static bool handle_bindsym(struct sway_binding *binding) {
422 } 443 }
423 } 444 }
424 445
425 if (match) { 446 return match;
426 handle_binding_command(binding);
427 return true;
428 }
429
430 return false;
431} 447}
432 448
433static bool handle_bindsym_release(struct sway_binding *binding) { 449static bool handle_bindsym_release(struct sway_binding *binding) {
@@ -489,18 +505,19 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier
489 modifiers_state_update(modifiers->mods); 505 modifiers_state_update(modifiers->mods);
490 506
491 // handle bindings 507 // handle bindings
508 list_t *candidates = create_list();
492 for (i = 0; i < mode->bindings->length; ++i) { 509 for (i = 0; i < mode->bindings->length; ++i) {
493 struct sway_binding *binding = mode->bindings->items[i]; 510 struct sway_binding *binding = mode->bindings->items[i];
494 if ((modifiers->mods ^ binding->modifiers) == 0) { 511 if ((modifiers->mods ^ binding->modifiers) == 0) {
495 switch (state) { 512 switch (state) {
496 case WLC_KEY_STATE_PRESSED: { 513 case WLC_KEY_STATE_PRESSED: {
497 if (!binding->release && handle_bindsym(binding)) { 514 if (!binding->release && valid_bindsym(binding)) {
498 return EVENT_HANDLED; 515 list_add(candidates, binding);
499 } 516 }
500 break;
501 } 517 }
502 case WLC_KEY_STATE_RELEASED: 518 case WLC_KEY_STATE_RELEASED:
503 if (binding->release && handle_bindsym_release(binding)) { 519 if (binding->release && handle_bindsym_release(binding)) {
520 list_free(candidates);
504 return EVENT_HANDLED; 521 return EVENT_HANDLED;
505 } 522 }
506 break; 523 break;
@@ -508,6 +525,17 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier
508 } 525 }
509 } 526 }
510 527
528 for (i = 0; i < candidates->length; ++i) {
529 struct sway_binding *binding = candidates->items[i];
530 if (state == WLC_KEY_STATE_PRESSED) {
531 if (!binding->release && handle_bindsym(binding, sym, key)) {
532 list_free(candidates);
533 return EVENT_HANDLED;
534 }
535 }
536 }
537
538 list_free(candidates);
511 return EVENT_PASSTHROUGH; 539 return EVENT_PASSTHROUGH;
512} 540}
513 541