summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiovanni Campagna <gcampagn@redhat.com>2013-08-09 17:07:52 +0200
committerGiovanni Campagna <gcampagn@redhat.com>2013-08-13 18:11:12 +0200
commit7b780b0c38ea95fa6a79b2cad1b070c245746255 (patch)
tree9f7a088cee66811cd97a2099685460b2c55c1353
parent8c358f18b1be3a10430be6abb164494cf1591ed0 (diff)
downloadclutter-7b780b0c38ea95fa6a79b2cad1b070c245746255.tar.gz
evdev: don't update xkb state for autorepeated keys
xkb_state_update_key() needs to be called only on state transitions, otherwise the state tracking gets confused and locks certain modifiers forever. https://bugzilla.gnome.org/show_bug.cgi?id=705710
-rw-r--r--clutter/evdev/clutter-device-manager-evdev.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/clutter/evdev/clutter-device-manager-evdev.c b/clutter/evdev/clutter-device-manager-evdev.c
index 0e7f7c24e..5a92e8ea6 100644
--- a/clutter/evdev/clutter-device-manager-evdev.c
+++ b/clutter/evdev/clutter-device-manager-evdev.c
@@ -58,6 +58,8 @@
#define FIRST_SLAVE_ID 4
#define INVALID_SLAVE_ID 255
+#define AUTOREPEAT_VALUE 2
+
struct _ClutterDeviceManagerEvdevPrivate
{
GUdevClient *udev_client;
@@ -210,12 +212,18 @@ notify_key (ClutterEventSource *source,
manager_evdev->priv->xkb,
manager_evdev->priv->button_state,
time_, key, state);
- xkb_state_update_key (manager_evdev->priv->xkb, event->key.hardware_keycode, state ? XKB_KEY_DOWN : XKB_KEY_UP);
- if (state)
- add_key (manager_evdev->priv->keys, event->key.hardware_keycode);
- else
- remove_key (manager_evdev->priv->keys, event->key.hardware_keycode);
+ /* We must be careful and not pass multiple releases to xkb, otherwise it gets
+ confused and locks the modifiers */
+ if (state != AUTOREPEAT_VALUE)
+ {
+ xkb_state_update_key (manager_evdev->priv->xkb, event->key.hardware_keycode, state ? XKB_KEY_DOWN : XKB_KEY_UP);
+
+ if (state)
+ add_key (manager_evdev->priv->keys, event->key.hardware_keycode);
+ else
+ remove_key (manager_evdev->priv->keys, event->key.hardware_keycode);
+ }
queue_event (event);
}
@@ -410,7 +418,7 @@ clutter_event_dispatch (GSource *g_source,
/* don't repeat mouse buttons */
if (e->code >= BTN_MOUSE && e->code < KEY_OK)
- if (e->value == 2)
+ if (e->value == AUTOREPEAT_VALUE)
continue;
switch (e->code)