[gimp] Issue #1824 - Crash on 2.10.4 using tablet



commit 9b25611857c75e922dd10f3d933807b0c7cd44ed
Author: Ell <ell_se yahoo com>
Date:   Wed Jan 9 13:33:06 2019 -0500

    Issue #1824 - Crash on 2.10.4 using tablet
    
    In GimpTool, track the last-seen pointer coordinates, modifier
    state, and event time, during button_press() and motion() events
    and use those to synthesize a button_release() event when
    comitting/halting the tool, if the tool is still active, and a
    matching button_release() event has not been received.
    
    The paint tools (as well as other tools) require each
    button_press() event to be matched by a button_release() event in
    order to properly finish their operation, but one isn't organically
    generated when switching tools due to a device change.

 app/tools/gimptool.c | 34 ++++++++++++++++++++++++++++++++++
 app/tools/gimptool.h |  6 ++++++
 2 files changed, 40 insertions(+)
---
diff --git a/app/tools/gimptool.c b/app/tools/gimptool.c
index 52370cdfd3..53981c1aaa 100644
--- a/app/tools/gimptool.c
+++ b/app/tools/gimptool.c
@@ -138,6 +138,7 @@ static void            gimp_tool_options_notify      (GimpToolOptions  *options,
                                                       const GParamSpec *pspec,
                                                       GimpTool         *tool);
 static void            gimp_tool_clear_status        (GimpTool         *tool);
+static void            gimp_tool_release             (GimpTool         *tool);
 
 
 G_DEFINE_TYPE_WITH_CODE (GimpTool, gimp_tool, GIMP_TYPE_OBJECT,
@@ -649,6 +650,8 @@ gimp_tool_control (GimpTool       *tool,
 {
   g_return_if_fail (GIMP_IS_TOOL (tool));
 
+  g_object_ref (tool);
+
   switch (action)
     {
     case GIMP_TOOL_ACTION_PAUSE:
@@ -674,6 +677,8 @@ gimp_tool_control (GimpTool       *tool,
       break;
 
     case GIMP_TOOL_ACTION_COMMIT:
+      gimp_tool_release (tool);
+
       GIMP_TOOL_GET_CLASS (tool)->control (tool, action, display);
 
       /*  always HALT after COMMIT here and not in each tool individually;
@@ -685,6 +690,8 @@ gimp_tool_control (GimpTool       *tool,
 
       /* pass through */
     case GIMP_TOOL_ACTION_HALT:
+      gimp_tool_release (tool);
+
       GIMP_TOOL_GET_CLASS (tool)->control (tool, action, display);
 
       if (gimp_tool_control_is_active (tool->control))
@@ -693,6 +700,8 @@ gimp_tool_control (GimpTool       *tool,
       gimp_tool_clear_status (tool);
       break;
     }
+
+  g_object_unref (tool);
 }
 
 void
@@ -716,6 +725,10 @@ gimp_tool_button_press (GimpTool            *tool,
       tool->button_press_state    = state;
       tool->active_modifier_state = state;
 
+      tool->last_pointer_coords = *coords;
+      tool->last_pointer_time   = time - g_get_monotonic_time () / 1000;
+      tool->last_pointer_state  = state;
+
       if (gimp_tool_control_get_wants_click (tool->control))
         {
           tool->in_click_distance   = TRUE;
@@ -789,6 +802,8 @@ gimp_tool_button_release (GimpTool         *tool,
 
   g_object_ref (tool);
 
+  tool->last_pointer_state = 0;
+
   my_coords = *coords;
 
   if (state & GDK_BUTTON3_MASK)
@@ -855,6 +870,10 @@ gimp_tool_motion (GimpTool         *tool,
 
   tool->got_motion_event = TRUE;
 
+  tool->last_pointer_coords = *coords;
+  tool->last_pointer_time   = time - g_get_monotonic_time () / 1000;
+  tool->last_pointer_state  = state;
+
   GIMP_TOOL_GET_CLASS (tool)->motion (tool, coords, time, state, display);
 }
 
@@ -1476,3 +1495,18 @@ gimp_tool_clear_status (GimpTool *tool)
   while (tool->status_displays)
     gimp_tool_pop_status (tool, tool->status_displays->data);
 }
+
+static void
+gimp_tool_release (GimpTool *tool)
+{
+  if (tool->last_pointer_state &&
+      gimp_tool_control_is_active (tool->control))
+    {
+      gimp_tool_button_release (
+        tool,
+        &tool->last_pointer_coords,
+        tool->last_pointer_time + g_get_monotonic_time () / 1000,
+        tool->last_pointer_state,
+        tool->display);
+    }
+}
diff --git a/app/tools/gimptool.h b/app/tools/gimptool.h
index f869e7babd..171636338d 100644
--- a/app/tools/gimptool.h
+++ b/app/tools/gimptool.h
@@ -60,6 +60,12 @@ struct _GimpTool
   GdkModifierType  button_press_state;
   GdkModifierType  active_modifier_state;
 
+  /*  private state for synthesizing button_release() events
+   */
+  GimpCoords       last_pointer_coords;
+  guint32          last_pointer_time;
+  GdkModifierType  last_pointer_state;
+
   /*  private state for click detection
    */
   gboolean         in_click_distance;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]