[gtk+] wayland: synchronize key repeat with server
- From: Ray Strode <halfline src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] wayland: synchronize key repeat with server
- Date: Wed, 2 Mar 2016 18:07:37 +0000 (UTC)
commit b5281837d676783987c24b4e429e0242a856bcbb
Author: Ray Strode <rstrode redhat com>
Date: Thu Feb 25 13:58:42 2016 -0500
wayland: synchronize key repeat with server
key repeat is handled client side, which means stalls in the compositor
dispatching key release events can lead to fictious repeat events.
This commit ties key repeat to a server roundtrip to ensure the client
and server are in sync.
https://bugzilla.gnome.org/show_bug.cgi?id=757942
gdk/wayland/gdkdevice-wayland.c | 37 ++++++++++++++++++++++++++++++++++++-
1 files changed, 36 insertions(+), 1 deletions(-)
---
diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c
index a5735d0..dae132b 100644
--- a/gdk/wayland/gdkdevice-wayland.c
+++ b/gdk/wayland/gdkdevice-wayland.c
@@ -105,6 +105,8 @@ struct _GdkWaylandSeat
gboolean have_server_repeat;
uint32_t server_repeat_rate;
uint32_t server_repeat_delay;
+
+ struct wl_callback *repeat_callback;
guint32 repeat_timer;
guint32 repeat_key;
guint32 repeat_count;
@@ -175,6 +177,10 @@ struct _GdkWaylandDeviceManagerClass
GdkDeviceManagerClass parent_class;
};
+static void deliver_key_event (GdkWaylandDeviceData *device,
+ uint32_t time_,
+ uint32_t key,
+ uint32_t state);
GType gdk_wayland_device_manager_get_type (void);
G_DEFINE_TYPE (GdkWaylandDeviceManager,
@@ -1692,6 +1698,8 @@ stop_key_repeat (GdkWaylandDeviceData *device)
g_source_remove (device->repeat_timer);
device->repeat_timer = 0;
}
+
+ g_clear_pointer (&device->repeat_callback, wl_callback_destroy);
}
static void
@@ -1762,12 +1770,39 @@ deliver_key_event (GdkWaylandDeviceData *device,
g_source_set_name_by_id (device->repeat_timer, "[gtk+] keyboard_repeat");
}
+static void
+sync_after_repeat_callback (void *data,
+ struct wl_callback *callback,
+ uint32_t time)
+{
+ GdkWaylandDeviceData *device = data;
+
+ g_clear_pointer (&device->repeat_callback, wl_callback_destroy);
+
+ deliver_key_event (device, device->time, device->repeat_key, 1);
+}
+
+static const struct wl_callback_listener sync_after_repeat_callback_listener = {
+ sync_after_repeat_callback
+};
+
static gboolean
keyboard_repeat (gpointer data)
{
GdkWaylandDeviceData *device = data;
+ GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display);
- deliver_key_event (device, device->time, device->repeat_key, 1);
+ /* Ping the server and wait for the timeout. We won't process
+ * key repeat until it responds, since a hung server could lead
+ * to a delayed key release event. We don't want to generate
+ * repeat events long after the user released the key, just because
+ * the server is tardy in telling us the user released the key.
+ */
+ device->repeat_callback = wl_display_sync (display->wl_display);
+
+ wl_callback_add_listener (device->repeat_callback,
+ &sync_after_repeat_callback_listener,
+ device);
return G_SOURCE_REMOVE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]