summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRui Matos <tiagomatos@gmail.com>2016-11-25 12:44:56 +0100
committerRui Matos <tiagomatos@gmail.com>2017-01-25 13:10:15 +0100
commit18a4b9fb2cf708941144c9a9bba8598df70af0f4 (patch)
tree4f1407a1d1ed4808ac324fe80e6cdcde8210a379
parent2166a496fec3bc19a6b3cc34e7271041637d1d42 (diff)
downloadmutter-18a4b9fb2cf708941144c9a9bba8598df70af0f4.tar.gz
clutter/evdev: Dispatch libinput before generating key repeat events
Since both the libinput event source and the key repeat timer have the same priority, the order in which both handlers are called is arbitrary if both sources are ready on the same poll return. This means that sometimes we generate key repeats when there's already a real key event queued on libinput that would cancel the repeat timer if only it was processed before. One solution would be lowering the repeat timer source priority a notch lower than the libinput source but that would mean that a steady stream of events from libinput (e.g. pointer device motion) would prevent any key repeats to happen. Instead, we can fix this problem by trying to dispatch libinput from the key repeat timer and checking if the timer source has been destroyed before generating more key repeats. https://bugzilla.gnome.org/show_bug.cgi?id=774989
-rw-r--r--clutter/clutter/evdev/clutter-device-manager-evdev.c6
-rw-r--r--clutter/clutter/evdev/clutter-device-manager-evdev.h2
-rw-r--r--clutter/clutter/evdev/clutter-seat-evdev.c6
3 files changed, 14 insertions, 0 deletions
diff --git a/clutter/clutter/evdev/clutter-device-manager-evdev.c b/clutter/clutter/evdev/clutter-device-manager-evdev.c
index c03c68cec..04dcb2eb7 100644
--- a/clutter/clutter/evdev/clutter-device-manager-evdev.c
+++ b/clutter/clutter/evdev/clutter-device-manager-evdev.c
@@ -2261,6 +2261,12 @@ _clutter_device_manager_evdev_acquire_device_id (ClutterDeviceManagerEvdev *mana
return next_id;
}
+void
+_clutter_device_manager_evdev_dispatch (ClutterDeviceManagerEvdev *manager_evdev)
+{
+ dispatch_libinput (manager_evdev);
+}
+
static int
compare_ids (gconstpointer a,
gconstpointer b)
diff --git a/clutter/clutter/evdev/clutter-device-manager-evdev.h b/clutter/clutter/evdev/clutter-device-manager-evdev.h
index 1b01b8d06..c2dbe3198 100644
--- a/clutter/clutter/evdev/clutter-device-manager-evdev.h
+++ b/clutter/clutter/evdev/clutter-device-manager-evdev.h
@@ -76,6 +76,8 @@ void _clutter_device_manager_evdev_constrain_pointer (ClutterDeviceManagerEvdev
float *new_x,
float *new_y);
+void _clutter_device_manager_evdev_dispatch (ClutterDeviceManagerEvdev *manager_evdev);
+
static inline guint64
us (guint64 us)
{
diff --git a/clutter/clutter/evdev/clutter-seat-evdev.c b/clutter/clutter/evdev/clutter-seat-evdev.c
index 2fc040bb6..17464cf75 100644
--- a/clutter/clutter/evdev/clutter-seat-evdev.c
+++ b/clutter/clutter/evdev/clutter-seat-evdev.c
@@ -186,6 +186,12 @@ keyboard_repeat (gpointer data)
ClutterSeatEvdev *seat = data;
GSource *source;
+ /* There might be events queued in libinput that could cancel the
+ repeat timer. */
+ _clutter_device_manager_evdev_dispatch (seat->manager_evdev);
+ if (!seat->repeat_timer)
+ return G_SOURCE_REMOVE;
+
g_return_val_if_fail (seat->repeat_device != NULL, G_SOURCE_REMOVE);
source = g_main_context_find_source_by_id (NULL, seat->repeat_timer);