]> git.sur5r.net Git - i3/i3/commitdiff
Bugfix: don’t apply shift+numlock fallback for keypad keys
authorMichael Stapelberg <michael@stapelberg.de>
Mon, 12 Sep 2016 20:24:23 +0000 (22:24 +0200)
committerMichael Stapelberg <michael@stapelberg.de>
Mon, 12 Sep 2016 20:24:23 +0000 (22:24 +0200)
fixes #2418

src/bindings.c
testcases/t/264-keypress-numlock.t

index 7a056adf397250c3a6e647afa642ece70d9a9c80..eec821b6a732d1bf245756c0d60ce9310f04196f 100644 (file)
@@ -368,6 +368,7 @@ struct resolve {
  */
 static void add_keycode_if_matches(struct xkb_keymap *keymap, xkb_keycode_t key, void *data) {
     const struct resolve *resolving = data;
+    struct xkb_state *numlock_state = resolving->xkb_state_numlock;
     xkb_keysym_t sym = xkb_state_key_get_one_sym(resolving->xkb_state, key);
     if (sym != resolving->keysym) {
         /* Check if Shift was specified, and try resolving the symbol without
@@ -377,6 +378,11 @@ static void add_keycode_if_matches(struct xkb_keymap *keymap, xkb_keycode_t key,
             return;
         if (xkb_state_key_get_level(resolving->xkb_state, key, layout) > 1)
             return;
+        /* Skip the Shift fallback for keypad keys, otherwise one cannot bind
+         * KP_1 independent of KP_End. */
+        if (sym >= XKB_KEY_KP_Space && sym <= XKB_KEY_KP_Equal)
+            return;
+        numlock_state = resolving->xkb_state_numlock_no_shift;
         sym = xkb_state_key_get_one_sym(resolving->xkb_state_no_shift, key);
         if (sym != resolving->keysym)
             return;
@@ -403,9 +409,8 @@ static void add_keycode_if_matches(struct xkb_keymap *keymap, xkb_keycode_t key,
          * active. If so, grab the key with NumLock as well, so that users don’t
          * need to duplicate every key binding with an additional Mod2 specified.
          */
-        xkb_keysym_t sym_numlock = xkb_state_key_get_one_sym(resolving->xkb_state_numlock, key);
-        xkb_keysym_t sym_numlock_no_shift = xkb_state_key_get_one_sym(resolving->xkb_state_numlock_no_shift, key);
-        if (sym_numlock == resolving->keysym || sym_numlock_no_shift == resolving->keysym) {
+        xkb_keysym_t sym_numlock = xkb_state_key_get_one_sym(numlock_state, key);
+        if (sym_numlock == resolving->keysym) {
             /* Also bind the key with active NumLock */
             ADD_TRANSLATED_KEY(bind->event_state_mask | xcb_numlock_mask);
 
index fa9caa61c1fcd6892e93331cb011322b707f27f8..45ec7e8897163e00a727f11fe21143ab6234a2d6 100644 (file)
@@ -41,6 +41,9 @@ bindsym Escape nop Escape
 
 # Binding which should work with numlock and without, see issue #2418.
 bindsym Shift+Escape nop Shift+Escape
+
+# Binding which should work with numlock and without, see issue #2418.
+bindsym Mod1+Shift+q nop Mod1+Shift+q
 EOT
 
 my $pid = launch_with_config($config);
@@ -143,8 +146,39 @@ is(listen_for_binding(
    'Shift+Escape',
    'triggered the "Escape" keybinding');
 
+is(listen_for_binding(
+    sub {
+        xtest_key_press(50); # Shift_L
+        xtest_key_press(64); # Alt_L
+        xtest_key_press(24); # q
+        xtest_key_release(24); # q
+        xtest_key_release(64); # Alt_L
+        xtest_key_release(50); # Shift_L
+    },
+    ),
+   'Mod1+Shift+q',
+   'triggered the "Mod1+Shift+q" keybinding');
+
+
+is(listen_for_binding(
+    sub {
+        xtest_key_press(77); # enable Num_Lock
+        xtest_key_release(77); # enable Num_Lock
+        xtest_key_press(50); # Shift_L
+        xtest_key_press(64); # Alt_L
+        xtest_key_press(24); # q
+        xtest_key_release(24); # q
+        xtest_key_release(64); # Alt_L
+        xtest_key_release(50); # Shift_L
+        xtest_key_press(77); # disable Num_Lock
+        xtest_key_release(77); # disable Num_Lock
+    },
+    ),
+   'Mod1+Shift+q',
+   'triggered the "Mod1+Shift+q" keybinding');
+
 sync_with_i3;
-is(scalar @i3test::XTEST::binding_events, 8, 'Received exactly 8 binding events');
+is(scalar @i3test::XTEST::binding_events, 10, 'Received exactly 10 binding events');
 
 exit_gracefully($pid);
 
@@ -188,7 +222,7 @@ is(listen_for_binding(
 # TODO: This test does not verify that i3 does _NOT_ grab keycode 87 with Mod2.
 
 sync_with_i3;
-is(scalar @i3test::XTEST::binding_events, 9, 'Received exactly 9 binding events');
+is(scalar @i3test::XTEST::binding_events, 11, 'Received exactly 11 binding events');
 
 exit_gracefully($pid);