libevdev: flushing state forcefully
David Herrmann
dh.herrmann at gmail.com
Wed Aug 27 04:38:31 PDT 2014
Hi
I'm hacking on some xkb stuff again and stumbled across some
inconsistencies in libevdev state handling. In particular, there is
currently no easy way to parse initial evdev state when opening a
device. Imagine the following setup:
1) ctrl+alt+F2 is pressed, a session switch to session #2 occurs. The
session is activated the first time, therefore, it opens evdev devices
(either directly or via TakeDevice on logind) and initializes its
libevdev state.
2) F2 button is released.
3) F3 button is pressed. No session switch occurs, as the libevdev has
not generated any event for the ctrl and alt buttons, thus, the xkb
state does not know of them.
If the session has already been loaded and you switch to it, we
usually force a libevdev resync via LIBEVDEV_READ_FLAG_FORCE_SYNC.
Therefore, the new modifiers are updated in xkb. However, during
device setup, there is no way to get events for the initial state.
Two solutions:
1) Iterate over all the available types+codes and generate events manually.
2) Don't sync initial state during setup. To keep backwards-compat,
libevdev_set_fd_no_sync() would be needed (name subject
to change, obviously).
Now, solution 1) obviously sounds easier as there is no need to
introduce a new API. However, there's one more issue: Imagine you
change the xkb-keymap of an in-flight session. We have to destroy the
xkb_state object and recreate it for the new keymap. However, this
looses all state and we need to resync it. This is impossible to
achieve with libevdev, as it assumes we already parsed the state.
Again, two solutions:
1) Iterate over all the available types+codes and generate
events for them.
2) Destroy the libevdev object and recreate it via
libevdev_set_fd_no_sync() and sync yourself.
Merging both problems, I see the following proper solutions:
1) Let applications deal with it.
2) Add LIBEVDEV_FOREACH_CODE() which is a convenience
for-loop that iterates all available type+code combinations
of the libevdev device. This can be easily used to generate
required events in the application itself.
3) Add libevdev_reset_state(). This flushes all internal event
state of an libevdev object. A following forced SYNC will
then properly resync the device.
This probably also implies a libevdev_set_fd_no_sync() so
we avoid the initial state sync.
Comments?
Thanks
David
More information about the Input-tools
mailing list