From 06ea2cf7b1d0a22985e3753e855b731cc52724a8 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Mon, 20 Aug 2012 18:56:20 +0100 Subject: [PATCH] drag-action: Ensure that we can destroy the drag handle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the DragAction has a drag handle that gets destroyed inside the ::drag-end signal handler, the destruction sequence will trigger a callback we have in place to check if the handle is being destroyed mid-drag, e.g. from a ::drag-motion event. The callback on the drag handle destruction will check if we are still in the middle of a drag and emit the ::drag-end signal to allow cleaning up; the callback erroneously uses the drag handle as the argument for the emit_drag_end() function — instead of the actor to which the drag action has been attached. Also, by the time we emit the ::drag-end, we are not dragging the actor any more, so we shouldn't be emitted the ::drag-end signal twice. The fix is, thus, made of two parts: - reset the in_drag boolean before emitting the ::drag-end signal so that destroying the drag handle will not result in a double signal emission; - use the correct actor when calling emit_drag_end(). https://bugzilla.gnome.org/show_bug.cgi?id=681814 --- clutter/clutter-drag-action.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/clutter/clutter-drag-action.c b/clutter/clutter-drag-action.c index d686ef995..a58ec4d37 100644 --- a/clutter/clutter-drag-action.c +++ b/clutter/clutter-drag-action.c @@ -306,6 +306,8 @@ emit_drag_end (ClutterDragAction *action, priv->last_motion_device = clutter_event_get_device (event); } + priv->in_drag = FALSE; + /* we might not have emitted ::drag-begin yet */ if (!priv->emit_delayed_press) g_signal_emit (action, drag_signals[DRAG_END], 0, @@ -334,8 +336,6 @@ emit_drag_end (ClutterDragAction *action, } priv->sequence = NULL; - - priv->in_drag = FALSE; } static gboolean @@ -1062,12 +1062,14 @@ clutter_drag_action_get_drag_threshold (ClutterDragAction *action, } static void -on_drag_handle_destroy (ClutterActor *actor, +on_drag_handle_destroy (ClutterActor *handle, ClutterDragAction *action) { ClutterDragActionPrivate *priv = action->priv; + ClutterActor *actor; /* make sure we reset the state */ + actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action)); if (priv->in_drag) emit_drag_end (action, actor, NULL);