[gnome-shell] dnd: Cancel the animation on drag actor destruction



commit 1883df2927b9d088bf31f6d02ddbffac2de319f0
Author: Marek Chalupa <mchqwerty gmail com>
Date:   Thu Mar 31 14:26:06 2016 +0200

    dnd: Cancel the animation on drag actor destruction
    
    If the drag actor is destroyed before the animation
    callback is called, the callback is never called and
    we're sticked with dnd grabing the events after we
    dropped the target.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=757676

 js/ui/dnd.js |   70 +++++++++++++++++++++++++++++++++++----------------------
 1 files changed, 43 insertions(+), 27 deletions(-)
---
diff --git a/js/ui/dnd.js b/js/ui/dnd.js
index c7140a1..e749dd9 100644
--- a/js/ui/dnd.js
+++ b/js/ui/dnd.js
@@ -571,20 +571,13 @@ const _Draggable = new Lang.Class({
             return;
         }
 
-        this._animationInProgress = true;
-        // No target, so snap back
-        Tweener.addTween(this._dragActor,
-                         { x: snapBackX,
-                           y: snapBackY,
-                           scale_x: snapBackScale,
-                           scale_y: snapBackScale,
-                           opacity: this._dragOrigOpacity,
-                           time: SNAP_BACK_ANIMATION_TIME,
-                           transition: 'easeOutQuad',
-                           onComplete: this._onAnimationComplete,
-                           onCompleteScope: this,
-                           onCompleteParams: [this._dragActor, eventTime]
-                         });
+        this._animateDragEnd(eventTime,
+                             { x: snapBackX,
+                               y: snapBackY,
+                               scale_x: snapBackScale,
+                               scale_y: snapBackScale,
+                               time: SNAP_BACK_ANIMATION_TIME,
+                             });
     },
 
     _restoreDragActor: function(eventTime) {
@@ -596,18 +589,44 @@ const _Draggable = new Lang.Class({
         this._dragActor.set_scale(restoreScale, restoreScale);
         this._dragActor.opacity = 0;
 
+        this._animateDragEnd(eventTime,
+                             { time: REVERT_ANIMATION_TIME });
+    },
+
+    _animateDragEnd: function (eventTime, params) {
         this._animationInProgress = true;
-        Tweener.addTween(this._dragActor,
-                         { opacity: this._dragOrigOpacity,
-                           time: REVERT_ANIMATION_TIME,
-                           transition: 'easeOutQuad',
-                           onComplete: this._onAnimationComplete,
-                           onCompleteScope: this,
-                           onCompleteParams: [this._dragActor, eventTime]
-                         });
+
+        // finish animation if the actor gets destroyed
+        // during it
+        this._dragActorDestroyId =
+            this._dragActor.connect('destroy',
+                                    Lang.bind(this, this._finishAnimation));
+
+        params['opacity']          = this._dragOrigOpacity;
+        params['transition']       = 'easeOutQuad';
+        params['onComplete']       = this._onAnimationComplete;
+        params['onCompleteScope']  = this;
+        params['onCompleteParams'] = [this._dragActor, eventTime];
+
+        // start the animation
+        Tweener.addTween(this._dragActor, params)
+    },
+
+    _finishAnimation : function () {
+        if (!this._animationInProgress)
+            return
+
+        this._animationInProgress = false;
+        if (!this._buttonDown)
+            this._dragComplete();
+
+        global.screen.set_cursor(Meta.Cursor.DEFAULT);
     },
 
     _onAnimationComplete : function (dragActor, eventTime) {
+        dragActor.disconnect(this._dragActorDestroyId);
+        this._dragActorDestroyId = 0;
+
         if (this._dragOrigParent) {
             Main.uiGroup.remove_child(this._dragActor);
             this._dragOrigParent.add_actor(this._dragActor);
@@ -616,12 +635,9 @@ const _Draggable = new Lang.Class({
         } else {
             dragActor.destroy();
         }
-        global.screen.set_cursor(Meta.Cursor.DEFAULT);
-        this.emit('drag-end', eventTime, false);
 
-        this._animationInProgress = false;
-        if (!this._buttonDown)
-            this._dragComplete();
+        this.emit('drag-end', eventTime, false);
+        this._finishAnimation();
     },
 
     _dragComplete: function() {


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