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
This commit is contained in:
parent
f1a7cd7c0f
commit
d847d43f70
@ -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;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user