[gtk/event-recorder] Fix event history
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/event-recorder] Fix event history
- Date: Wed, 15 Dec 2021 05:31:04 +0000 (UTC)
commit 6012276093ea10dc0913c38d9123c37b08a20264
Author: Matthias Clasen <mclasen redhat com>
Date: Wed Dec 15 00:24:05 2021 -0500
Fix event history
Collecting of history wasn't working correctly
for either motion or scroll events.
gdk/gdkevents.c | 112 ++++++++++++++++++++++++++++++++++++++------------------
1 file changed, 76 insertions(+), 36 deletions(-)
---
diff --git a/gdk/gdkevents.c b/gdk/gdkevents.c
index 3ee8905ef3..5ce7724eb4 100644
--- a/gdk/gdkevents.c
+++ b/gdk/gdkevents.c
@@ -19,7 +19,7 @@
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
- * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
@@ -522,7 +522,8 @@ _gdk_event_queue_find_first (GdkDisplay *display)
if (pending_motion)
return pending_motion;
- if (event->event_type == GDK_MOTION_NOTIFY && (event->flags & GDK_EVENT_FLUSHED) == 0)
+ if ((event->event_type == GDK_MOTION_NOTIFY || event->event_type == GDK_SCROLL) &&
+ (event->flags & GDK_EVENT_FLUSHED) == 0)
pending_motion = tmp_list;
else
return tmp_list;
@@ -596,6 +597,9 @@ _gdk_event_unqueue (GdkDisplay *display)
/*
* If the last N events in the event queue are smooth scroll events
* for the same surface and device, combine them into one.
+ *
+ * We give the remaining event a history with N items, and deltas
+ * that are the sum over the history entries.
*/
void
gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
@@ -605,7 +609,6 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
GdkDevice *device = NULL;
GdkEvent *last_event = NULL;
GList *scrolls = NULL;
- double delta_x, delta_y;
GArray *history = NULL;
GdkTimeCoord hist;
@@ -640,35 +643,42 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
l = l->prev;
}
- delta_x = delta_y = 0;
-
while (scrolls && scrolls->next != NULL)
{
GdkEvent *event = scrolls->data;
GList *next = scrolls->next;
double dx, dy;
+ gboolean inherited = FALSE;
+
+ if (!history && ((GdkScrollEvent *)event)->history)
+ {
+ history = ((GdkScrollEvent *)event)->history;
+ ((GdkScrollEvent *)event)->history = NULL;
+ inherited = TRUE;
+ }
if (!history)
history = g_array_new (FALSE, TRUE, sizeof (GdkTimeCoord));
- gdk_scroll_event_get_deltas (event, &dx, &dy);
- delta_x += dx;
- delta_y += dy;
+ if (!inherited)
+ {
+ gdk_scroll_event_get_deltas (event, &dx, &dy);
- memset (&hist, 0, sizeof (GdkTimeCoord));
- hist.time = gdk_event_get_time (event);
- hist.flags = GDK_AXIS_FLAG_DELTA_X | GDK_AXIS_FLAG_DELTA_Y;
- hist.axes[GDK_AXIS_DELTA_X] = dx;
- hist.axes[GDK_AXIS_DELTA_Y] = dy;
+ memset (&hist, 0, sizeof (GdkTimeCoord));
+ hist.time = gdk_event_get_time (event);
+ hist.flags = GDK_AXIS_FLAG_DELTA_X | GDK_AXIS_FLAG_DELTA_Y;
+ hist.axes[GDK_AXIS_DELTA_X] = dx;
+ hist.axes[GDK_AXIS_DELTA_Y] = dy;
- g_array_append_val (history, hist);
+ g_array_append_val (history, hist);
+ }
gdk_event_unref (event);
g_queue_delete_link (&display->queued_events, scrolls);
scrolls = next;
}
- if (scrolls)
+ if (scrolls && history)
{
GdkEvent *old_event, *event;
double dx, dy;
@@ -676,13 +686,29 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
old_event = scrolls->data;
gdk_scroll_event_get_deltas (old_event, &dx, &dy);
+
+ memset (&hist, 0, sizeof (GdkTimeCoord));
+ hist.time = gdk_event_get_time (old_event);
+ hist.flags = GDK_AXIS_FLAG_DELTA_X | GDK_AXIS_FLAG_DELTA_Y;
+ hist.axes[GDK_AXIS_DELTA_X] = dx;
+ hist.axes[GDK_AXIS_DELTA_Y] = dy;
+ g_array_append_val (history, hist);
+
+ dx = dy = 0;
+ for (int i = 0; i < history->len; i++)
+ {
+ GdkTimeCoord *val = &g_array_index (history, GdkTimeCoord, i);
+ dx += val->axes[GDK_AXIS_DELTA_X];
+ dy += val->axes[GDK_AXIS_DELTA_Y];
+ }
+
event = gdk_scroll_event_new (surface,
device,
gdk_event_get_device_tool (old_event),
gdk_event_get_time (old_event),
gdk_event_get_modifier_state (old_event),
- delta_x + dx,
- delta_y + dy,
+ dx,
+ dy,
gdk_scroll_event_is_stop (old_event));
((GdkScrollEvent *)event)->history = history;
@@ -714,24 +740,41 @@ gdk_motion_event_push_history (GdkEvent *event,
g_assert (GDK_IS_EVENT_TYPE (event, GDK_MOTION_NOTIFY));
g_assert (GDK_IS_EVENT_TYPE (history_event, GDK_MOTION_NOTIFY));
- if (!self->tool)
- return;
+ if (G_UNLIKELY (!self->history))
+ self->history = g_array_new (FALSE, TRUE, sizeof (GdkTimeCoord));
+
+ if (((GdkMotionEvent *)history_event)->history)
+ {
+ GArray *history = ((GdkMotionEvent *)history_event)->history;
+ g_array_append_vals (self->history, history->data, history->len);
+ }
tool = gdk_event_get_device_tool (history_event);
memset (&hist, 0, sizeof (GdkTimeCoord));
hist.time = gdk_event_get_time (history_event);
- hist.flags = gdk_device_tool_get_axes (tool);
-
- for (i = GDK_AXIS_X; i < GDK_AXIS_LAST; i++)
- gdk_event_get_axis (history_event, i, &hist.axes[i]);
-
- if (G_UNLIKELY (!self->history))
- self->history = g_array_new (FALSE, TRUE, sizeof (GdkTimeCoord));
+ if (tool)
+ {
+ hist.flags = gdk_device_tool_get_axes (tool);
+ for (i = GDK_AXIS_X; i < GDK_AXIS_LAST; i++)
+ gdk_event_get_axis (history_event, i, &hist.axes[i]);
+ }
+ else
+ {
+ hist.flags = GDK_AXIS_FLAG_X | GDK_AXIS_FLAG_Y;
+ gdk_event_get_position (history_event, &hist.axes[GDK_AXIS_X], &hist.axes[GDK_AXIS_Y]);
+ }
g_array_append_val (self->history, hist);
}
+/* If the last N events in the event queue are motion notify
+ * events for the same surface, drop all but the last.
+ *
+ * If a button is held down or the device has a tool, then
+ * we give the remaining events a history containing the N-1
+ * dropped events.
+ */
void
_gdk_event_queue_handle_motion_compression (GdkDisplay *display)
{
@@ -741,9 +784,6 @@ _gdk_event_queue_handle_motion_compression (GdkDisplay *display)
GdkDevice *pending_motion_device = NULL;
GdkEvent *last_motion = NULL;
- /* If the last N events in the event queue are motion notify
- * events for the same surface, drop all but the last */
-
tmp_list = g_queue_peek_tail_link (&display->queued_events);
while (tmp_list)
@@ -780,12 +820,11 @@ _gdk_event_queue_handle_motion_compression (GdkDisplay *display)
if (last_motion != NULL)
{
- GdkModifierType state = gdk_event_get_modifier_state (last_motion);
-
- if (state &
- (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK |
- GDK_BUTTON4_MASK | GDK_BUTTON5_MASK))
- gdk_motion_event_push_history (last_motion, pending_motions->data);
+ if ((gdk_event_get_modifier_state (last_motion) &
+ (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK |
+ GDK_BUTTON4_MASK | GDK_BUTTON5_MASK)) ||
+ gdk_event_get_device_tool (last_motion) != NULL)
+ gdk_motion_event_push_history (last_motion, pending_motions->data);
}
gdk_event_unref (pending_motions->data);
@@ -2907,7 +2946,8 @@ gdk_motion_event_new (GdkSurface *surface,
* to the application because they occurred in the same frame as @event.
*
* Note that only motion and scroll events record history, and motion
- * events do it only if one of the mouse buttons is down.
+ * events do it only if one of the mouse buttons is down, or the device
+ * has a tool.
*
* Returns: (transfer container) (array length=out_n_coords) (nullable): an
* array of time and coordinates
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]