aboutsummaryrefslogtreecommitdiff
path: root/sway
diff options
context:
space:
mode:
authorMikkel Oscar Lyderik <mikkeloscar@gmail.com>2016-03-19 13:42:32 +0100
committerMikkel Oscar Lyderik <mikkeloscar@gmail.com>2016-03-19 14:06:46 +0100
commitbb32cba795c7ab11e3b4844d21f0b2ae2f1fdc2d (patch)
treea9075a0c6834aed4eb5c18d62f817d4fcf1ab172 /sway
parent8c7bdfc0047004245000b060f8187af3f2898feb (diff)
downloadsway-bb32cba795c7ab11e3b4844d21f0b2ae2f1fdc2d.tar.xz
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
Diffstat (limited to 'sway')
-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) {
free_cmd_results(res);
}
-static bool handle_bindsym(struct sway_binding *binding) {
+static bool handle_bindsym(struct sway_binding *binding, uint32_t keysym, uint32_t keycode) {
+ int i;
+ for (i = 0; i < binding->keys->length; ++i) {
+ if (binding->bindcode) {
+ xkb_keycode_t *key = binding->keys->items[i];
+ if (keycode == *key) {
+ handle_binding_command(binding);
+ return true;
+ }
+ } else {
+ xkb_keysym_t *key = binding->keys->items[i];
+ if (keysym == *key) {
+ handle_binding_command(binding);
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+static bool valid_bindsym(struct sway_binding *binding) {
bool match = false;
int i;
for (i = 0; i < binding->keys->length; ++i) {
@@ -422,12 +443,7 @@ static bool handle_bindsym(struct sway_binding *binding) {
}
}
- if (match) {
- handle_binding_command(binding);
- return true;
- }
-
- return false;
+ return match;
}
static 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
modifiers_state_update(modifiers->mods);
// handle bindings
+ list_t *candidates = create_list();
for (i = 0; i < mode->bindings->length; ++i) {
struct sway_binding *binding = mode->bindings->items[i];
if ((modifiers->mods ^ binding->modifiers) == 0) {
switch (state) {
case WLC_KEY_STATE_PRESSED: {
- if (!binding->release && handle_bindsym(binding)) {
- return EVENT_HANDLED;
+ if (!binding->release && valid_bindsym(binding)) {
+ list_add(candidates, binding);
}
- break;
}
case WLC_KEY_STATE_RELEASED:
if (binding->release && handle_bindsym_release(binding)) {
+ list_free(candidates);
return EVENT_HANDLED;
}
break;
@@ -508,6 +525,17 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier
}
}
+ for (i = 0; i < candidates->length; ++i) {
+ struct sway_binding *binding = candidates->items[i];
+ if (state == WLC_KEY_STATE_PRESSED) {
+ if (!binding->release && handle_bindsym(binding, sym, key)) {
+ list_free(candidates);
+ return EVENT_HANDLED;
+ }
+ }
+ }
+
+ list_free(candidates);
return EVENT_PASSTHROUGH;
}