[gnome-shell] AppSwitcher: Delay activating appIcons when the thumbnail list is open



commit 75d1230dd16cf576bdfd00093b7ee3e9f95765cd
Author: Adel Gadllah <adel gadllah gmail com>
Date:   Thu Jan 6 20:21:27 2011 +0100

    AppSwitcher: Delay activating appIcons when the thumbnail list is open
    
    When aiming for the thumbnails with the mouse one might cross an
    icon by accident which causes the thumbnail list to be closed, which is
    frustrating.
    
    Fix this by delaying the icon activation when the thumbnail list is
    open.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=636650

 js/ui/altTab.js |   62 +++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 49 insertions(+), 13 deletions(-)
---
diff --git a/js/ui/altTab.js b/js/ui/altTab.js
index aa0e7e2..a8d3e79 100644
--- a/js/ui/altTab.js
+++ b/js/ui/altTab.js
@@ -15,6 +15,8 @@ const POPUP_APPICON_SIZE = 96;
 const POPUP_SCROLL_TIME = 0.10; // seconds
 const POPUP_FADE_TIME = 0.1; // seconds
 
+const APP_ICON_HOVER_TIMEOUT = 750; // milliseconds
+
 const DISABLE_HOVER_TIMEOUT = 500; // milliseconds
 
 const THUMBNAIL_DEFAULT_SIZE = 256;
@@ -50,6 +52,8 @@ AltTabPopup.prototype = {
         this._thumbnailTimeoutId = 0;
         this._motionTimeoutId = 0;
 
+        this.thumbnailsVisible = false;
+
         // Initially disable hover so we ignore the enter-event if
         // the switcher appears underneath the current pointer location
         this._disableHover();
@@ -133,7 +137,7 @@ AltTabPopup.prototype = {
         this.actor.connect('button-press-event', Lang.bind(this, this._clickedOutside));
         this.actor.connect('scroll-event', Lang.bind(this, this._onScroll));
 
-        this._appSwitcher = new AppSwitcher(apps);
+        this._appSwitcher = new AppSwitcher(apps, this);
         this.actor.add_actor(this._appSwitcher.actor);
         this._appSwitcher.connect('item-activated', Lang.bind(this, this._appActivated));
         this._appSwitcher.connect('item-entered', Lang.bind(this, this._appEntered));
@@ -457,11 +461,15 @@ AltTabPopup.prototype = {
     },
 
     _destroyThumbnails : function() {
-        Tweener.addTween(this._thumbnails.actor,
+        let thumbnailsActor = this._thumbnails.actor;
+        Tweener.addTween(thumbnailsActor,
                          { opacity: 0,
                            time: THUMBNAIL_FADE_TIME,
                            transition: 'easeOutQuad',
-                           onComplete: function() { this.destroy(); }
+                           onComplete: Lang.bind(this, function() {
+                                                            thumbnailsActor.destroy();
+                                                            this.thumbnailsVisible = false;
+                                                        })
                          });
         this._thumbnails = null;
     },
@@ -477,7 +485,8 @@ AltTabPopup.prototype = {
         Tweener.addTween(this._thumbnails.actor,
                          { opacity: 255,
                            time: THUMBNAIL_FADE_TIME,
-                           transition: 'easeOutQuad'
+                           transition: 'easeOutQuad',
+                           onComplete: Lang.bind(this, function () { this.thumbnailsVisible = true; })
                          });
     }
 };
@@ -591,16 +600,20 @@ SwitcherList.prototype = {
         this._list.add_actor(bbox);
 
         let n = this._items.length;
-        bbox.connect('clicked', Lang.bind(this, function () {
-                                               this._itemActivated(n);
-                                          }));
-        bbox.connect('enter-event', Lang.bind(this, function () {
-                                                  this._itemEntered(n);
-                                              }));
+        bbox.connect('clicked', Lang.bind(this, function() { this._onItemClicked(n); }));
+        bbox.connect('enter-event', Lang.bind(this, function() { this._onItemEnter(n); }));
 
         this._items.push(bbox);
     },
 
+    _onItemClicked: function (index) {
+        this._itemActivated(index);
+    },
+
+    _onItemEnter: function (index) {
+        this._itemEntered(index);
+    },
+
     addSeparator: function () {
         let box = new St.Bin({ style_class: 'separator' });
         this._separator = box;
@@ -819,14 +832,14 @@ AppIcon.prototype = {
     }
 };
 
-function AppSwitcher(apps) {
-    this._init(apps);
+function AppSwitcher(apps, altTabPopup) {
+    this._init(apps, altTabPopup);
 }
 
 AppSwitcher.prototype = {
     __proto__ : SwitcherList.prototype,
 
-    _init : function(apps) {
+    _init : function(apps, altTabPopup) {
         SwitcherList.prototype._init.call(this, true);
 
         // Construct the AppIcons, sort by time, add to the popup
@@ -858,6 +871,8 @@ AppSwitcher.prototype = {
 
         this._curApp = -1;
         this._iconSize = 0;
+        this._altTabPopup = altTabPopup;
+        this._mouseTimeOutId = 0;
     },
 
     _getPreferredHeight: function (actor, forWidth, alloc) {
@@ -922,6 +937,27 @@ AppSwitcher.prototype = {
         }
     },
 
+    // We override SwitcherList's _onItemEnter method to delay
+    // activation when the thumbnail list is open
+    _onItemEnter: function (index) {
+        if (this._mouseTimeOutId != 0)
+            Mainloop.source_remove(this._mouseTimeOutId);
+        if (this._altTabPopup.thumbnailsVisible) {
+            this._mouseTimeOutId = Mainloop.timeout_add(APP_ICON_HOVER_TIMEOUT,
+                                                        Lang.bind(this, function () {
+                                                                            this._enterItem(index);
+                                                        }));
+        } else
+           this._itemEntered(index);
+    },
+
+    _enterItem: function(index) {
+        let [x, y, mask] = global.get_pointer();
+        let pickedActor = global.stage.get_actor_at_pos(Clutter.PickMode.ALL, x, y);
+        if (this._items[index].contains(pickedActor))
+            this._itemEntered(index);
+    },
+
     // We override SwitcherList's highlight() method to also deal with
     // the AppSwitcher->ThumbnailList arrows. Apps with only 1 window
     // will hide their arrows by default, but show them when their



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