[clutter] actions/drag: Be more reliable when destroying the drag handle



commit d847d43f70d29be78b529b19046b453a05135fa3
Author: Emmanuele Bassi <ebassi linux intel com>
Date:   Tue Aug 30 10:47:12 2011 +0100

    actions/drag: Be more reliable when destroying the drag handle
    
    Whenever the drag handle gets destroyed mid-drag we need to cancel any
    current drag operation and reset the state of the DragAction.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=657681

 clutter/clutter-drag-action.c |   44 +++++++++++++++++++++++++++++++---------
 1 files changed, 34 insertions(+), 10 deletions(-)
---
diff --git a/clutter/clutter-drag-action.c b/clutter/clutter-drag-action.c
index c8302be..cf37600 100644
--- a/clutter/clutter-drag-action.c
+++ b/clutter/clutter-drag-action.c
@@ -88,6 +88,8 @@ struct _ClutterDragActionPrivate
 
   gfloat last_motion_x;
   gfloat last_motion_y;
+  ClutterModifierType last_motion_state;
+  ClutterInputDevice *last_motion_device;
 
   gfloat transformed_press_x;
   gfloat transformed_press_y;
@@ -191,6 +193,8 @@ emit_drag_motion (ClutterDragAction *action,
   gfloat motion_x, motion_y;
 
   clutter_event_get_coords (event, &priv->last_motion_x, &priv->last_motion_y);
+  priv->last_motion_state = clutter_event_get_state (event);
+  priv->last_motion_device = clutter_event_get_device (event);
 
   if (priv->drag_handle != NULL && !priv->emit_delayed_press)
     drag_handle = priv->drag_handle;
@@ -254,14 +258,23 @@ emit_drag_end (ClutterDragAction *action,
 {
   ClutterDragActionPrivate *priv = action->priv;
 
-  clutter_event_get_coords (event, &priv->last_motion_x, &priv->last_motion_y);
+  /* if we have an event, update our own state, otherwise we'll
+   * just use the currently stored state when emitting the ::drag-end
+   * signal
+   */
+  if (event != NULL)
+    {
+      clutter_event_get_coords (event, &priv->last_motion_x, &priv->last_motion_y);
+      priv->last_motion_state = clutter_event_get_state (event);
+      priv->last_motion_device = clutter_event_get_device (event);
+    }
 
   /* we might not have emitted ::drag-begin yet */
   if (!priv->emit_delayed_press)
     g_signal_emit (action, drag_signals[DRAG_END], 0,
                    actor,
                    priv->last_motion_x, priv->last_motion_y,
-                   clutter_event_get_state (event));
+                   priv->last_motion_state);
 
   /* disconnect the capture */
   if (priv->capture_id != 0)
@@ -272,8 +285,9 @@ emit_drag_end (ClutterDragAction *action,
 
   clutter_stage_set_motion_events_enabled (priv->stage,
                                            priv->motion_events_enabled);
-  _clutter_stage_remove_drag_actor (priv->stage,
-                                    clutter_event_get_device (event));
+
+  if (priv->last_motion_device != NULL)
+    _clutter_stage_remove_drag_actor (priv->stage, priv->last_motion_device);
 
   priv->in_drag = FALSE;
 }
@@ -388,16 +402,20 @@ clutter_drag_action_set_actor (ClutterActorMeta *meta,
       old_actor = clutter_actor_meta_get_actor (meta);
 
       g_signal_handler_disconnect (old_actor, priv->button_press_id);
-
-      if (priv->capture_id != 0)
-        g_signal_handler_disconnect (old_actor, priv->capture_id);
-
       priv->button_press_id = 0;
-      priv->capture_id = 0;
+    }
 
+  if (priv->capture_id != 0 && priv->stage != NULL)
+    {
+      g_signal_handler_disconnect (priv->stage, priv->capture_id);
+      priv->capture_id = 0;
       priv->stage = NULL;
     }
 
+  clutter_drag_action_set_drag_handle (CLUTTER_DRAG_ACTION (meta), NULL);
+
+  priv->in_drag = FALSE;
+
   if (actor != NULL)
     priv->button_press_id = g_signal_connect (actor, "button-press-event",
                                               G_CALLBACK (on_button_press),
@@ -849,7 +867,13 @@ static void
 on_drag_handle_destroy (ClutterActor      *actor,
                         ClutterDragAction *action)
 {
-  action->priv->drag_handle = NULL;
+  ClutterDragActionPrivate *priv = action->priv;
+
+  /* make sure we reset the state */
+  if (priv->in_drag)
+    emit_drag_end (action, actor, NULL);
+
+  priv->drag_handle = NULL;
 }
 
 /**



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