[gimp] app: compress tool motion evnets more conservatively
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: compress tool motion evnets more conservatively
- Date: Sun, 11 Jun 2017 19:13:07 +0000 (UTC)
commit 5543a9da4f168c2c30ff06d358f8f48f3a250b88
Author: Ell <ell_se yahoo com>
Date: Sun Jun 11 14:45:36 2017 -0400
app: compress tool motion evnets more conservatively
When compressing tool motion events, only compress motion events
at the front of the event queue, targeted at the same widget as,
and having similar characteristics to, the initial motion event;
stop compressing upon the first mismatched event.
Previously, all pending motion events targeted at the canvas were
compressed, stopping only at a button-release event targeted at the
canvas. As a result, when adding a guide by dragging from a ruler,
there could be a situation where a pending button-release event
targeted at the ruler would be followed by motion events targeted at
the canvas, with a cleared state mask. These motion events would
get compressed to the initial motion event targeted at the ruler,
resulting in a motion event with a cleared state mask being processed
before the said button-release event. This, in turn, would cause the
guide tool's cursor_update function to be called, while the tool is
still active, emitting a CRITICAL. Sheesh.
The moral of the story is: let's play it safe.
app/display/gimpdisplayshell-tool-events.c | 59 +++++++++------------------
1 files changed, 20 insertions(+), 39 deletions(-)
---
diff --git a/app/display/gimpdisplayshell-tool-events.c b/app/display/gimpdisplayshell-tool-events.c
index 3c59e25..d08ed13 100644
--- a/app/display/gimpdisplayshell-tool-events.c
+++ b/app/display/gimpdisplayshell-tool-events.c
@@ -126,7 +126,7 @@ static void gimp_display_shell_untransform_event_coords (GimpDisplayShell
GimpCoords *image_coords,
gboolean *update_software_cursor);
-static GdkEvent * gimp_display_shell_compress_motion (GimpDisplayShell *shell);
+static GdkEvent * gimp_display_shell_compress_motion (GdkEvent *initial_event);
/* public functions */
@@ -851,7 +851,7 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
if (shell->scrolling ||
motion_mode == GIMP_MOTION_MODE_COMPRESS)
{
- compressed_motion = gimp_display_shell_compress_motion (shell);
+ compressed_motion = gimp_display_shell_compress_motion (event);
if (compressed_motion && ! shell->scrolling)
{
@@ -1946,8 +1946,9 @@ gimp_display_shell_untransform_event_coords (GimpDisplayShell *shell,
/* gimp_display_shell_compress_motion:
*
- * This function walks the whole GDK event queue seeking motion events
- * corresponding to the widget 'widget'. If it finds any it will
+ * This function walks the GDK event queue, seeking motion events at the
+ * front of the queue corresponding to the same widget as, and having
+ * similar characteristics to, `initial_event`. If it finds any it will
* remove them from the queue, and return the most recent motion event.
* Otherwise it will return NULL.
*
@@ -1955,15 +1956,16 @@ gimp_display_shell_untransform_event_coords (GimpDisplayShell *shell,
* the XFree86-style license. <adam gimp org>
*/
static GdkEvent *
-gimp_display_shell_compress_motion (GimpDisplayShell *shell)
+gimp_display_shell_compress_motion (GdkEvent *initial_event)
{
- GList *requeued_events = NULL;
- const GList *list;
- GdkEvent *last_motion = NULL;
+ GdkEvent *last_motion = NULL;
+ GtkWidget *widget;
+
+ if (initial_event->any.type != GDK_MOTION_NOTIFY)
+ return NULL;
+
+ widget = gtk_get_event_widget (initial_event);
- /* Move the entire GDK event queue to a private list, filtering
- * out any motion events for the desired widget.
- */
while (gdk_events_pending ())
{
GdkEvent *event = gdk_event_get ();
@@ -1972,45 +1974,24 @@ gimp_display_shell_compress_motion (GimpDisplayShell *shell)
{
/* Do nothing */
}
- else if ((gtk_get_event_widget (event) == shell->canvas) &&
- (event->any.type == GDK_MOTION_NOTIFY))
+ else if ((gtk_get_event_widget (event) == widget) &&
+ (event->any.type == GDK_MOTION_NOTIFY) &&
+ (event->motion.state == initial_event->motion.state) &&
+ (event->motion.device == initial_event->motion.device))
{
if (last_motion)
gdk_event_free (last_motion);
last_motion = event;
}
- else if ((gtk_get_event_widget (event) == shell->canvas) &&
- (event->any.type == GDK_BUTTON_RELEASE))
+ else
{
- requeued_events = g_list_prepend (requeued_events, event);
-
- while (gdk_events_pending ())
- if ((event = gdk_event_get ()))
- requeued_events = g_list_prepend (requeued_events, event);
+ gdk_event_put (event);
+ gdk_event_free (event);
break;
}
- else
- {
- requeued_events = g_list_prepend (requeued_events, event);
- }
}
- /* Replay the remains of our private event list back into the
- * event queue in order.
- */
- requeued_events = g_list_reverse (requeued_events);
-
- for (list = requeued_events; list; list = g_list_next (list))
- {
- GdkEvent *event = list->data;
-
- gdk_event_put (event);
- gdk_event_free (event);
- }
-
- g_list_free (requeued_events);
-
return last_motion;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]