[gtk/scroll-compression] gdk: Compress scroll events
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/scroll-compression] gdk: Compress scroll events
- Date: Mon, 8 Jun 2020 22:57:12 +0000 (UTC)
commit 535df4d6dcfc7397039f5757ace221d51d6d71eb
Author: Matthias Clasen <mclasen redhat com>
Date: Mon Jun 8 18:07:40 2020 -0400
gdk: Compress scroll events
Only return one accumulated scroll event per frame.
Compress them by adding up the deltas.
Still missing: a way to capture history, like
we do for motion events.
Fixes: #2800
gdk/gdkevents.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
gdk/gdkinternals.h | 1 +
gdk/gdksurface.c | 1 +
3 files changed, 85 insertions(+), 1 deletion(-)
---
diff --git a/gdk/gdkevents.c b/gdk/gdkevents.c
index e1a58006cb..e51ab82721 100644
--- a/gdk/gdkevents.c
+++ b/gdk/gdkevents.c
@@ -644,6 +644,88 @@ gdk_motion_event_push_history (GdkEvent *event,
}
+/*
+ * If the last N events in the event queue are smooth scroll events
+ * for the same surface and device, combine them into one.
+ */
+void
+gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
+{
+ GList *l;
+ GdkSurface *surface = NULL;
+ GdkDevice *device = NULL;
+ GdkEvent *last_event = NULL;
+ GList *scrolls = NULL;
+ double delta_x, delta_y;
+ double dx, dy;
+
+ delta_x = delta_y = 0;
+
+ l = g_queue_peek_tail_link (&display->queued_events);
+
+ while (l)
+ {
+ GdkEvent *event = l->data;
+
+ if (event->flags & GDK_EVENT_PENDING)
+ break;
+
+ if (event->event_type != GDK_SCROLL ||
+ gdk_scroll_event_get_direction (event) != GDK_SCROLL_SMOOTH)
+ break;
+
+ if (surface != NULL &&
+ surface != event->surface)
+ break;
+
+ if (device != NULL &&
+ device != event->device)
+ break;
+
+ if (!last_event)
+ last_event = event;
+
+ surface = event->surface;
+ device = event->device;
+ scrolls = l;
+
+ gdk_scroll_event_get_deltas (event, &dx, &dy);
+ delta_x += dx;
+ delta_y += dy;
+
+ l = l->prev;
+ }
+
+ while (scrolls && scrolls->next != NULL)
+ {
+ GList *next = scrolls->next;
+
+ gdk_event_unref (scrolls->data);
+ g_queue_delete_link (&display->queued_events, scrolls);
+ scrolls = next;
+ }
+
+ if (scrolls)
+ {
+ GdkEvent *old_event, *event;
+
+ old_event = scrolls->data;
+
+ event = gdk_scroll_event_new (surface,
+ device,
+ gdk_event_get_source_device (old_event),
+ gdk_event_get_device_tool (old_event),
+ gdk_event_get_time (old_event),
+ gdk_event_get_modifier_state (old_event),
+ delta_x,
+ delta_y,
+ gdk_scroll_event_is_stop (old_event));
+
+ g_queue_delete_link (&display->queued_events, scrolls);
+ g_queue_push_tail (&display->queued_events, event);
+ }
+}
+
void
_gdk_event_queue_handle_motion_compression (GdkDisplay *display)
{
@@ -710,7 +792,7 @@ _gdk_event_queue_handle_motion_compression (GdkDisplay *display)
{
GdkFrameClock *clock = gdk_surface_get_frame_clock (pending_motion_surface);
if (clock) /* might be NULL if surface was destroyed */
- gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS);
+ gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS);
}
}
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index e30872edc6..b26aac73eb 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -123,6 +123,7 @@ GList* _gdk_event_queue_append (GdkDisplay *display,
GdkEvent *event);
void _gdk_event_queue_handle_motion_compression (GdkDisplay *display);
+void gdk_event_queue_handle_scroll_compression (GdkDisplay *display);
void _gdk_event_queue_flush (GdkDisplay *display);
gboolean _gdk_cairo_surface_extents (cairo_surface_t *surface,
diff --git a/gdk/gdksurface.c b/gdk/gdksurface.c
index 1c5aeb180a..9e5946794d 100644
--- a/gdk/gdksurface.c
+++ b/gdk/gdksurface.c
@@ -2366,6 +2366,7 @@ _gdk_windowing_got_event (GdkDisplay *display,
* candidate it queues up flushing the event queue.
*/
_gdk_event_queue_handle_motion_compression (display);
+ gdk_event_queue_handle_scroll_compression (display);
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]