commit a9233e9
Michael Forney
·
2014-08-01 02:58:01 +0000 UTC
parent ec4e188
Reset keyboard state on session deactivation This prevents an inconsistent state of the keyboard when the VT is switched away with keys held down.
5 files changed,
+47,
-0
+29,
-0
1@@ -31,6 +31,7 @@
2 #include "keyboard.h"
3 #include "util.h"
4
5+#include <assert.h>
6 #include <stdio.h>
7 #include <string.h>
8
9@@ -149,6 +150,34 @@ void keyboard_finalize(struct keyboard * keyboard)
10 xkb_finalize(&keyboard->xkb);
11 }
12
13+void keyboard_reset(struct keyboard * keyboard)
14+{
15+ struct key * key;
16+ uint32_t time = swc_time();
17+
18+ /* Send simulated key release events for all current key handlers. */
19+ wl_array_for_each(key, &keyboard->keys)
20+ {
21+ if (key->handler)
22+ {
23+ key->press.serial = wl_display_next_serial(swc.display);
24+ key->handler->key(keyboard, time, &key->press,
25+ WL_KEYBOARD_KEY_STATE_RELEASED);
26+ /* Don't bother updating the XKB state because we will be resetting
27+ * it later on and it is unlikely that a key handler cares about the
28+ * keyboard state for release events. */
29+ }
30+ }
31+
32+ /* We should have removed all the client keys by calling the client key
33+ * handler. */
34+ assert(keyboard->client_keys.size == 0);
35+ keyboard->keys.size = 0;
36+ keyboard->modifier_state = (struct keyboard_modifier_state) { };
37+ keyboard->modifiers = 0;
38+ xkb_reset_state(&keyboard->xkb);
39+}
40+
41 /**
42 * Sets the focus of the keyboard to the specified surface.
43 */
+1,
-0
1@@ -74,6 +74,7 @@ struct keyboard
2
3 bool keyboard_initialize(struct keyboard * keyboard);
4 void keyboard_finalize(struct keyboard * keyboard);
5+void keyboard_reset(struct keyboard * keyboard);
6 void keyboard_set_focus(struct keyboard * keyboard,
7 struct compositor_view * view);
8 struct wl_resource * keyboard_bind(struct keyboard * keyboard,
+1,
-0
1@@ -146,6 +146,7 @@ static void handle_launch_event(struct wl_listener * listener, void * data)
2 #ifdef ENABLE_LIBINPUT
3 libinput_suspend(seat.libinput);
4 #endif
5+ keyboard_reset(&seat.keyboard);
6 break;
7 case SWC_LAUNCH_EVENT_ACTIVATED:
8 {
+15,
-0
1@@ -89,6 +89,21 @@ void xkb_finalize(struct xkb * xkb)
2 xkb_context_unref(xkb->context);
3 }
4
5+bool xkb_reset_state(struct xkb * xkb)
6+{
7+ struct xkb_state * state;
8+
9+ if (!(state = xkb_state_new(xkb->keymap.map)))
10+ {
11+ ERROR("Failed to allocate new XKB state\n");
12+ return false;
13+ }
14+
15+ xkb_state_unref(xkb->state);
16+ xkb->state = state;
17+ return true;
18+}
19+
20 bool xkb_update_keymap(struct xkb * xkb)
21 {
22 const char * keymap_directory = getenv("XDG_RUNTIME_DIR") ?: "/tmp";
+1,
-0
1@@ -51,6 +51,7 @@ struct xkb
2
3 bool xkb_initialize(struct xkb * xkb);
4 void xkb_finalize(struct xkb * xkb);
5+bool xkb_reset_state(struct xkb * xkb);
6
7 bool xkb_update_keymap(struct xkb * xkb);
8