swc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/swc
Log | Files | Refs | README | LICENSE

commit a9233e93623694396ee63d1959c83afb470406b1
parent ec4e18824393d3270f552c88d4f03ff7c29d090f
Author: Michael Forney <mforney@mforney.org>
Date:   Thu, 31 Jul 2014 19:58:01 -0700

Reset keyboard state on session deactivation

This prevents an inconsistent state of the keyboard when the VT is
switched away with keys held down.

Diffstat:
Mlibswc/keyboard.c | 29+++++++++++++++++++++++++++++
Mlibswc/keyboard.h | 1+
Mlibswc/seat.c | 1+
Mlibswc/xkb.c | 15+++++++++++++++
Mlibswc/xkb.h | 1+
5 files changed, 47 insertions(+), 0 deletions(-)

diff --git a/libswc/keyboard.c b/libswc/keyboard.c @@ -31,6 +31,7 @@ #include "keyboard.h" #include "util.h" +#include <assert.h> #include <stdio.h> #include <string.h> @@ -149,6 +150,34 @@ void keyboard_finalize(struct keyboard * keyboard) xkb_finalize(&keyboard->xkb); } +void keyboard_reset(struct keyboard * keyboard) +{ + struct key * key; + uint32_t time = swc_time(); + + /* Send simulated key release events for all current key handlers. */ + wl_array_for_each(key, &keyboard->keys) + { + if (key->handler) + { + key->press.serial = wl_display_next_serial(swc.display); + key->handler->key(keyboard, time, &key->press, + WL_KEYBOARD_KEY_STATE_RELEASED); + /* Don't bother updating the XKB state because we will be resetting + * it later on and it is unlikely that a key handler cares about the + * keyboard state for release events. */ + } + } + + /* We should have removed all the client keys by calling the client key + * handler. */ + assert(keyboard->client_keys.size == 0); + keyboard->keys.size = 0; + keyboard->modifier_state = (struct keyboard_modifier_state) { }; + keyboard->modifiers = 0; + xkb_reset_state(&keyboard->xkb); +} + /** * Sets the focus of the keyboard to the specified surface. */ diff --git a/libswc/keyboard.h b/libswc/keyboard.h @@ -74,6 +74,7 @@ struct keyboard bool keyboard_initialize(struct keyboard * keyboard); void keyboard_finalize(struct keyboard * keyboard); +void keyboard_reset(struct keyboard * keyboard); void keyboard_set_focus(struct keyboard * keyboard, struct compositor_view * view); struct wl_resource * keyboard_bind(struct keyboard * keyboard, diff --git a/libswc/seat.c b/libswc/seat.c @@ -146,6 +146,7 @@ static void handle_launch_event(struct wl_listener * listener, void * data) #ifdef ENABLE_LIBINPUT libinput_suspend(seat.libinput); #endif + keyboard_reset(&seat.keyboard); break; case SWC_LAUNCH_EVENT_ACTIVATED: { diff --git a/libswc/xkb.c b/libswc/xkb.c @@ -89,6 +89,21 @@ void xkb_finalize(struct xkb * xkb) xkb_context_unref(xkb->context); } +bool xkb_reset_state(struct xkb * xkb) +{ + struct xkb_state * state; + + if (!(state = xkb_state_new(xkb->keymap.map))) + { + ERROR("Failed to allocate new XKB state\n"); + return false; + } + + xkb_state_unref(xkb->state); + xkb->state = state; + return true; +} + bool xkb_update_keymap(struct xkb * xkb) { const char * keymap_directory = getenv("XDG_RUNTIME_DIR") ?: "/tmp"; diff --git a/libswc/xkb.h b/libswc/xkb.h @@ -51,6 +51,7 @@ struct xkb bool xkb_initialize(struct xkb * xkb); void xkb_finalize(struct xkb * xkb); +bool xkb_reset_state(struct xkb * xkb); bool xkb_update_keymap(struct xkb * xkb);