DND: don't cancel a drag if the actor is destroyed inside acceptDrop
This happens in the case of Workspace/WorkspaceThumbnail: they call meta_window_change_workspace_by_index(), which fires window-removed on the old workspace, thus destroying the window clone. https://bugzilla.gnome.org/show_bug.cgi?id=685285
This commit is contained in:
parent
ceae032112
commit
57f27572ae
12
js/ui/dnd.js
12
js/ui/dnd.js
@ -85,11 +85,13 @@ const _Draggable = new Lang.Class({
|
|||||||
|
|
||||||
this.actor.connect('destroy', Lang.bind(this, function() {
|
this.actor.connect('destroy', Lang.bind(this, function() {
|
||||||
this._actorDestroyed = true;
|
this._actorDestroyed = true;
|
||||||
|
|
||||||
// If the drag actor is destroyed and we were going to fix
|
// If the drag actor is destroyed and we were going to fix
|
||||||
// up its hover state, fix up the parent hover state instead
|
// up its hover state, fix up the parent hover state instead
|
||||||
if (this.actor == this._firstLeaveActor)
|
if (this.actor == this._firstLeaveActor)
|
||||||
this._firstLeaveActor = this._dragOrigParent;
|
this._firstLeaveActor = this._dragOrigParent;
|
||||||
if (this._dragInProgress)
|
|
||||||
|
if (this._dragInProgress && this._dragCancellable)
|
||||||
this._cancelDrag(global.get_current_time());
|
this._cancelDrag(global.get_current_time());
|
||||||
this.disconnectAll();
|
this.disconnectAll();
|
||||||
}));
|
}));
|
||||||
@ -102,6 +104,7 @@ const _Draggable = new Lang.Class({
|
|||||||
this._buttonDown = false; // The mouse button has been pressed and has not yet been released.
|
this._buttonDown = false; // The mouse button has been pressed and has not yet been released.
|
||||||
this._dragInProgress = false; // The drag has been started, and has not been dropped or cancelled yet.
|
this._dragInProgress = false; // The drag has been started, and has not been dropped or cancelled yet.
|
||||||
this._animationInProgress = false; // The drag is over and the item is in the process of animating to its original position (snapping back or reverting).
|
this._animationInProgress = false; // The drag is over and the item is in the process of animating to its original position (snapping back or reverting).
|
||||||
|
this._dragCancellable = true;
|
||||||
|
|
||||||
// During the drag, we eat enter/leave events so that actors don't prelight.
|
// During the drag, we eat enter/leave events so that actors don't prelight.
|
||||||
// But we remember the actors that we first left/last entered so we can
|
// But we remember the actors that we first left/last entered so we can
|
||||||
@ -439,6 +442,11 @@ const _Draggable = new Lang.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// At this point it is too late to cancel a drag by destroying
|
||||||
|
// the actor, the fate of which is decided by acceptDrop and its
|
||||||
|
// side-effects
|
||||||
|
this._dragCancellable = false;
|
||||||
|
|
||||||
while (target) {
|
while (target) {
|
||||||
if (target._delegate && target._delegate.acceptDrop) {
|
if (target._delegate && target._delegate.acceptDrop) {
|
||||||
let [r, targX, targY] = target.transform_stage_point(dropX, dropY);
|
let [r, targX, targY] = target.transform_stage_point(dropX, dropY);
|
||||||
@ -447,8 +455,6 @@ const _Draggable = new Lang.Class({
|
|||||||
targX,
|
targX,
|
||||||
targY,
|
targY,
|
||||||
event.get_time())) {
|
event.get_time())) {
|
||||||
if (this._actorDestroyed)
|
|
||||||
return true;
|
|
||||||
// If it accepted the drop without taking the actor,
|
// If it accepted the drop without taking the actor,
|
||||||
// handle it ourselves.
|
// handle it ourselves.
|
||||||
if (this._dragActor.get_parent() == Main.uiGroup) {
|
if (this._dragActor.get_parent() == Main.uiGroup) {
|
||||||
|
Loading…
Reference in New Issue
Block a user