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_x;
|
||||||
gfloat last_motion_y;
|
gfloat last_motion_y;
|
||||||
|
ClutterModifierType last_motion_state;
|
||||||
|
ClutterInputDevice *last_motion_device;
|
||||||
|
|
||||||
gfloat transformed_press_x;
|
gfloat transformed_press_x;
|
||||||
gfloat transformed_press_y;
|
gfloat transformed_press_y;
|
||||||
@ -191,6 +193,8 @@ emit_drag_motion (ClutterDragAction *action,
|
|||||||
gfloat motion_x, motion_y;
|
gfloat motion_x, motion_y;
|
||||||
|
|
||||||
clutter_event_get_coords (event, &priv->last_motion_x, &priv->last_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)
|
if (priv->drag_handle != NULL && !priv->emit_delayed_press)
|
||||||
drag_handle = priv->drag_handle;
|
drag_handle = priv->drag_handle;
|
||||||
@ -254,14 +258,23 @@ emit_drag_end (ClutterDragAction *action,
|
|||||||
{
|
{
|
||||||
ClutterDragActionPrivate *priv = action->priv;
|
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 */
|
/* we might not have emitted ::drag-begin yet */
|
||||||
if (!priv->emit_delayed_press)
|
if (!priv->emit_delayed_press)
|
||||||
g_signal_emit (action, drag_signals[DRAG_END], 0,
|
g_signal_emit (action, drag_signals[DRAG_END], 0,
|
||||||
actor,
|
actor,
|
||||||
priv->last_motion_x, priv->last_motion_y,
|
priv->last_motion_x, priv->last_motion_y,
|
||||||
clutter_event_get_state (event));
|
priv->last_motion_state);
|
||||||
|
|
||||||
/* disconnect the capture */
|
/* disconnect the capture */
|
||||||
if (priv->capture_id != 0)
|
if (priv->capture_id != 0)
|
||||||
@ -272,8 +285,9 @@ emit_drag_end (ClutterDragAction *action,
|
|||||||
|
|
||||||
clutter_stage_set_motion_events_enabled (priv->stage,
|
clutter_stage_set_motion_events_enabled (priv->stage,
|
||||||
priv->motion_events_enabled);
|
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;
|
priv->in_drag = FALSE;
|
||||||
}
|
}
|
||||||
@ -388,16 +402,20 @@ clutter_drag_action_set_actor (ClutterActorMeta *meta,
|
|||||||
old_actor = clutter_actor_meta_get_actor (meta);
|
old_actor = clutter_actor_meta_get_actor (meta);
|
||||||
|
|
||||||
g_signal_handler_disconnect (old_actor, priv->button_press_id);
|
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->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;
|
priv->stage = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clutter_drag_action_set_drag_handle (CLUTTER_DRAG_ACTION (meta), NULL);
|
||||||
|
|
||||||
|
priv->in_drag = FALSE;
|
||||||
|
|
||||||
if (actor != NULL)
|
if (actor != NULL)
|
||||||
priv->button_press_id = g_signal_connect (actor, "button-press-event",
|
priv->button_press_id = g_signal_connect (actor, "button-press-event",
|
||||||
G_CALLBACK (on_button_press),
|
G_CALLBACK (on_button_press),
|
||||||
@ -849,7 +867,13 @@ static void
|
|||||||
on_drag_handle_destroy (ClutterActor *actor,
|
on_drag_handle_destroy (ClutterActor *actor,
|
||||||
ClutterDragAction *action)
|
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