[gtk/scroll-compression] Keep scroll history
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/scroll-compression] Keep scroll history
- Date: Tue, 9 Jun 2020 01:27:56 +0000 (UTC)
commit 2321c785003642d79c922b1d1f5269a2ce225ff5
Author: Matthias Clasen <mclasen redhat com>
Date: Mon Jun 8 20:29:38 2020 -0400
Keep scroll history
Similar to how we keep motion history for compressed
events, keep scroll history for compressed scroll
events.
gdk/gdkevents.c | 75 +++++++++++++++++++++++++++++++++++++++++++-------
gdk/gdkevents.h | 11 ++++++++
gdk/gdkeventsprivate.h | 4 +++
3 files changed, 80 insertions(+), 10 deletions(-)
---
diff --git a/gdk/gdkevents.c b/gdk/gdkevents.c
index 1b20a57dac..7c621f7e5b 100644
--- a/gdk/gdkevents.c
+++ b/gdk/gdkevents.c
@@ -632,9 +632,7 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
GdkEvent *last_event = NULL;
GList *scrolls = NULL;
double delta_x, delta_y;
- double dx, dy;
-
- delta_x = delta_y = 0;
+ GArray *history = NULL;
l = g_queue_peek_tail_link (&display->queued_events);
@@ -664,18 +662,31 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
device = event->device;
scrolls = l;
- gdk_scroll_event_get_deltas (event, &dx, &dy);
- delta_x += dx;
- delta_y += dy;
-
l = l->prev;
}
+ delta_x = delta_y = 0;
+
while (scrolls && scrolls->next != NULL)
{
+ GdkEvent *event = scrolls->data;
GList *next = scrolls->next;
+ GdkScrollHistory h;
+ double dx, dy;
+
+ if (!history)
+ history = g_array_new (FALSE, TRUE, sizeof (GdkScrollHistory));
+
+ gdk_scroll_event_get_deltas (event, &dx, &dy);
+ delta_x += dx;
+ delta_y += dy;
- gdk_event_unref (scrolls->data);
+ h.time = gdk_event_get_time (event);
+ h.delta_x = dx;
+ h.delta_y = dy;
+ g_array_append_val (history, h);
+
+ gdk_event_unref (event);
g_queue_delete_link (&display->queued_events, scrolls);
scrolls = next;
}
@@ -683,19 +694,23 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
if (scrolls)
{
GdkEvent *old_event, *event;
+ double dx, dy;
old_event = scrolls->data;
+ gdk_scroll_event_get_deltas (old_event, &dx, &dy);
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,
+ delta_x + dx,
+ delta_y + dy,
gdk_scroll_event_is_stop (old_event));
+ ((GdkScrollEvent *)event)->history = history;
+
g_queue_delete_link (&display->queued_events, scrolls);
g_queue_push_tail (&display->queued_events, event);
}
@@ -2247,6 +2262,8 @@ gdk_scroll_event_finalize (GdkEvent *event)
GdkScrollEvent *self = (GdkScrollEvent *) event;
g_clear_object (&self->tool);
+ if (self->history)
+ g_array_free (self->history, TRUE);
GDK_EVENT_SUPER (self)->finalize (event);
}
@@ -2394,6 +2411,44 @@ gdk_scroll_event_is_stop (GdkEvent *event)
return self->is_stop;
}
+/**
+ * gdk_scroll_event_get_history:
+ * @event: (type GdkScrollEvent): a scroll #GdkEvent
+ * @out_n: (out): Return location for the length of the returned array
+ *
+ * Retrieves the history of the @event, as a list of times and deltas.
+ *
+ * Returns: (transfer container) (array length=out_n) (nullable): an
+ * array of #GdkScrollHistory
+ */
+GdkScrollHistory *
+gdk_scroll_event_get_history (GdkEvent *event,
+ guint *out_n)
+{
+ GdkScrollEvent *self = (GdkScrollEvent *) event;
+
+ g_return_val_if_fail (GDK_IS_EVENT (event), NULL);
+ g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_SCROLL), NULL);
+ g_return_val_if_fail (out_n != NULL, NULL);
+
+ if (self->history &&
+ self->history->len > 0)
+ {
+ GdkScrollHistory *result;
+
+ *out_n = self->history->len;
+
+ result = g_new (GdkScrollHistory, self->history->len);
+ memcpy (result, self->history->data, sizeof (GdkScrollHistory) * self->history->len);
+
+ return result;
+ }
+
+ *out_n = 0;
+
+ return NULL;
+}
+
/* }}} */
/* {{{ GdkTouchpadEvent */
diff --git a/gdk/gdkevents.h b/gdk/gdkevents.h
index e702717541..17f76ce0d8 100644
--- a/gdk/gdkevents.h
+++ b/gdk/gdkevents.h
@@ -392,6 +392,17 @@ GDK_AVAILABLE_IN_ALL
void gdk_scroll_event_get_deltas (GdkEvent *event,
double *delta_x,
double *delta_y);
+
+typedef struct {
+ guint32 time;
+ double delta_x;
+ double delta_y;
+} GdkScrollHistory;
+
+GDK_AVAILABLE_IN_ALL
+GdkScrollHistory * gdk_scroll_event_get_history (GdkEvent *event,
+ guint *out_n);
+
GDK_AVAILABLE_IN_ALL
gboolean gdk_scroll_event_is_stop (GdkEvent *event);
GDK_AVAILABLE_IN_ALL
diff --git a/gdk/gdkeventsprivate.h b/gdk/gdkeventsprivate.h
index 0fd0b3e908..a21e458746 100644
--- a/gdk/gdkeventsprivate.h
+++ b/gdk/gdkeventsprivate.h
@@ -211,6 +211,9 @@ struct _GdkTouchEvent
* @pointer_emulated: whether the scroll event was the result of
* a pointer emulation
* @tool: a #GdkDeviceTool
+ * @history: (element-type GdkScrollHistory): array of times and deltas
+ * for other scroll events that were compressed before delivering the
+ * current event
*
* Generated from button presses for the buttons 4 to 7. Wheel mice are
* usually configured to generate button press events for buttons 4 and 5
@@ -232,6 +235,7 @@ struct _GdkScrollEvent
gboolean pointer_emulated;
gboolean is_stop;
GdkDeviceTool *tool;
+ GArray *history; /* <GdkScrollHistory> */
};
/*
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]