]> git.mdlowis.com Git - proto/labwc.git/commitdiff
keyboard: absolve release event if press was bound
authorJohan Malm <jgm323@gmail.com>
Tue, 21 Dec 2021 22:25:59 +0000 (22:25 +0000)
committerARDiDo <90479315+ARDiDo@users.noreply.github.com>
Wed, 22 Dec 2021 15:37:25 +0000 (10:37 -0500)
When key press events are handled by compositor keybindings, do not
forward the corresponding release events to clients.

include/key-state.h [new file with mode: 0644]
src/key-state.c [new file with mode: 0644]
src/keyboard.c
src/meson.build

diff --git a/include/key-state.h b/include/key-state.h
new file mode 100644 (file)
index 0000000..1e7e541
--- /dev/null
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __LABWC_KEY_STATE_H
+#define __LABWC_KEY_STATE_H
+
+void key_state_set_pressed(uint32_t keycode, bool ispressed);
+void key_state_store_pressed_keys_as_bound(void);
+bool key_state_corresponding_press_event_was_bound(uint32_t keycode);
+void key_state_bound_key_remove(uint32_t keycode);
+
+#endif /* __LABWC_KEY_STATE_H */
diff --git a/src/key-state.c b/src/key-state.c
new file mode 100644 (file)
index 0000000..9b50f33
--- /dev/null
@@ -0,0 +1,69 @@
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+
+#define MAX_PRESSED_KEYS (16)
+
+struct key_array {
+       uint32_t keys[MAX_PRESSED_KEYS];
+       int nr_keys;
+};
+
+static struct key_array pressed, bound;
+
+static void
+remove_key(struct key_array *array, uint32_t keycode)
+{
+       bool shifting = false;
+
+       for (int i = 0; i < MAX_PRESSED_KEYS; ++i) {
+               if (array->keys[i] == keycode) {
+                       --array->nr_keys;
+                       shifting = true;
+               }
+               if (shifting) {
+                       array->keys[i] = i < MAX_PRESSED_KEYS - 1
+                               ? array->keys[i + 1] : 0;
+               }
+       }
+}
+
+static void
+add_key(struct key_array *array, uint32_t keycode)
+{
+       array->keys[array->nr_keys++] = keycode;
+}
+
+void
+key_state_set_pressed(uint32_t keycode, bool ispressed)
+{
+       if (ispressed) {
+               add_key(&pressed, keycode);
+       } else {
+               remove_key(&pressed, keycode);
+       }
+}
+
+void
+key_state_store_pressed_keys_as_bound(void)
+{
+       memcpy(bound.keys, pressed.keys, MAX_PRESSED_KEYS * sizeof(uint32_t));
+       bound.nr_keys = pressed.nr_keys;
+}
+
+bool
+key_state_corresponding_press_event_was_bound(uint32_t keycode)
+{
+       for (int i = 0; i < bound.nr_keys; ++i) {
+               if (bound.keys[i] == keycode) {
+                       return true;
+               }
+       }
+       return false;
+}
+
+void
+key_state_bound_key_remove(uint32_t keycode)
+{
+       remove_key(&bound, keycode);
+}
index 2e6873bc94ddf54ff43a9fa47996a7f8e9b50ea6..5508f8728c54f9ac551989a8673f4097c1446cc8 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 #include <wlr/backend/multi.h>
 #include <wlr/backend/session.h>
+#include "key-state.h"
 #include "labwc.h"
 
 static void
@@ -101,6 +102,19 @@ handle_compositor_keybindings(struct wl_listener *listener,
 
        bool handled = false;
 
+       key_state_set_pressed(keycode,
+               event->state == WL_KEYBOARD_KEY_STATE_PRESSED);
+
+       /*
+        * If a press event was handled by a compositor binding, then do not
+        * forward the corresponding release event to clients
+        */
+       if (key_state_corresponding_press_event_was_bound(keycode)
+                       && event->state == WL_KEYBOARD_KEY_STATE_RELEASED) {
+               key_state_bound_key_remove(keycode);
+               return true;
+       }
+
        uint32_t modifiers =
                wlr_keyboard_get_modifiers(device->keyboard);
 
@@ -152,6 +166,11 @@ handle_compositor_keybindings(struct wl_listener *listener,
                        handled |= handle_keybinding(server, modifiers, syms[i]);
                }
        }
+
+       if (handled) {
+               key_state_store_pressed_keys_as_bound();
+       }
+
        return handled;
 }
 
index 947f80e08729eaf8a3091e965aaff5f263329445..cb761362555caa7fe02c34f7679fe9e1608430fd 100644 (file)
@@ -6,6 +6,7 @@ labwc_sources = files(
   'foreign.c',
   'interactive.c',
   'keyboard.c',
+  'key-state.c',
   'layers.c',
   'main.c',
   'osd.c',