Keep scroll history

Similar to how we keep motion history for compressed
events, keep scroll history for compressed scroll
events.
This commit is contained in:
Matthias Clasen 2020-06-08 20:29:38 -04:00
parent 86eece78b1
commit b9cde6f8ea
3 changed files with 82 additions and 12 deletions

View File

@ -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;
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;
l = l->prev;
}
h.time = gdk_event_get_time (event);
h.delta_x = dx;
h.delta_y = dy;
g_array_append_val (history, h);
while (scrolls && scrolls->next != NULL)
{
GList *next = scrolls->next;
gdk_event_unref (scrolls->data);
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 */

View File

@ -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

View File

@ -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> */
};
/*