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