[gnome-shell] Add tooltip delay to the preview pop-ups.



commit dcc0f368bd4589e14e00fdc7b0fea65ae367b15b
Author: Marina Zhurakhinskaya <marinaz redhat com>
Date:   Sat Mar 21 10:37:15 2009 -0400

    Add tooltip delay to the preview pop-ups.
    
    Showing previews after a delay allows the user to move the mouse around
    the screen without triggering constant pop-ups.
    
    Make sure we remove the pop-up when the user hits Escape and redisplay
    the pop-up if we are updating the section results due to a change in space
    allocated for it.
    
    Rename protected variable _hasPreview to _showPreview in order to not have
    the naming conflict with a new private variable _havePointer, which we
    name in first person.
---
 js/ui/appDisplay.js     |    2 +-
 js/ui/docDisplay.js     |    2 +-
 js/ui/genericDisplay.js |   86 ++++++++++++++++++++++++++++++++--------------
 js/ui/overlay.js        |    5 +++
 4 files changed, 67 insertions(+), 28 deletions(-)

diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index 79ba939..45bd9bf 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -106,7 +106,7 @@ AppDisplayItem.prototype = {
 
     // Ensures the preview icon is created.
     _ensurePreviewIconCreated : function() {
-        if (!this._hasPreview || this._previewIcon)
+        if (!this._showPreview || this._previewIcon)
             return; 
 
         let previewIconPath = null;
diff --git a/js/ui/docDisplay.js b/js/ui/docDisplay.js
index 1fd4700..68bfa57 100644
--- a/js/ui/docDisplay.js
+++ b/js/ui/docDisplay.js
@@ -88,7 +88,7 @@ DocDisplayItem.prototype = {
 
     // Ensures the preview icon is created.
     _ensurePreviewIconCreated : function() {
-        if (!this._hasPreview || this._previewIcon)
+        if (!this._showPreview || this._previewIcon)
             return; 
 
         this._previewIcon = new Clutter.Texture();
diff --git a/js/ui/genericDisplay.js b/js/ui/genericDisplay.js
index c328403..d96a934 100644
--- a/js/ui/genericDisplay.js
+++ b/js/ui/genericDisplay.js
@@ -6,6 +6,7 @@ const Gio = imports.gi.Gio;
 const Gdk = imports.gi.Gdk;
 const Gtk = imports.gi.Gtk;
 const Lang = imports.lang;
+const Mainloop = imports.mainloop;
 const Pango = imports.gi.Pango;
 const Signals = imports.signals;
 const Shell = imports.gi.Shell;
@@ -54,7 +55,9 @@ function GenericDisplayItem(availableWidth) {
 GenericDisplayItem.prototype = {
     _init: function(availableWidth) {
         this._availableWidth = availableWidth;
-        this._hasPreview = false;
+        this._showPreview = false;
+        this._havePointer = false; 
+        this._previewEventSourceId = null;
 
         this.actor = new Clutter.Group({ reactive: true,
                                          width: availableWidth,
@@ -117,18 +120,18 @@ GenericDisplayItem.prototype = {
     //// Public methods ////
 
     // Sets a boolean value that indicates whether the item should display a pop-up preview on mouse over.
-    setHasPreview: function(hasPreview) {
-        this._hasPreview = hasPreview;
+    setShowPreview: function(showPreview) {
+        this._showPreview = showPreview;
     },
 
     // Returns a boolean value that indicates whether the item displays a pop-up preview on mouse over.
-    getHasPreview: function() {
-        return this._hasPreview;
+    getShowPreview: function() {
+        return this._showPreview;
     },
 
     // Displays the preview for the item.
     showPreview: function() {
-        if(!this._hasPreview)
+        if(!this._showPreview)
             return;
 
         this._ensurePreviewCreated();
@@ -142,12 +145,24 @@ GenericDisplayItem.prototype = {
         this._preview.show();
     },
 
-    // Hides the preview for the item.
+    // Hides the preview for the item and removes the preview event source so that 
+    // there is no preview scheduled to show up.
     hidePreview: function() {
-        if(!this._hasPreview)
-            return;
+        if (this._previewEventSourceId) {
+            Mainloop.source_remove(this._previewEventSourceId);
+            this._previewEventSourceId = null;
+        }
 
-        this._preview.hide();
+        if (this._preview)
+            this._preview.hide();
+    },
+
+    // Shows a preview when the item was drawn under the mouse pointer.
+    onDrawnUnderPointer: function() {
+        this._havePointer = true;
+        // This code is usually triggered when we just had a different preview showing on the same spot
+        // and having a delay before showing a new preview looks bad. So we just show it right away.
+        this.showPreview();  
     },
 
     // Highlights the item by setting a different background color than the default 
@@ -250,7 +265,7 @@ GenericDisplayItem.prototype = {
 
     // Ensures the preview actor is created.
     _ensurePreviewCreated: function() {
-        if (!this._hasPreview || this._preview)
+        if (!this._showPreview || this._preview)
             return;
 
         this._preview = new Big.Box({ background_color: PREVIEW_BOX_BACKGROUND_COLOR,
@@ -295,11 +310,22 @@ GenericDisplayItem.prototype = {
 
     // Performs actions on mouse enter event for the item. Currently, shows the preview for the item.
     _onEnter: function(actor, event) {
-        this.showPreview();
+        this._havePointer = true;
+        let tooltipTimeout = Gtk.Settings.get_default().gtk_tooltip_timeout;
+        this._previewEventSourceId = Mainloop.timeout_add(tooltipTimeout, 
+                                                          Lang.bind(this,
+                                                                    function() {
+                                                                        if (this._havePointer) {
+                                                                            this.showPreview();
+                                                                        }
+                                                                        this._previewEventSourceId = null;
+                                                                        return false;
+                                                                    }));
     },
 
     // Performs actions on mouse leave event for the item. Currently, hides the preview for the item.
     _onLeave: function(actor, event) {
+        this._havePointer = false;
         this.hidePreview();
     },
 
@@ -307,9 +333,10 @@ GenericDisplayItem.prototype = {
     _onDragBegin : function (draggable, time) {
         // For some reason, we are not getting leave-event signal when we are dragging an item,
         // so the preview box stays behind if we didn't have the call here. It makes sense to hide  
-        // the preview as soon as the item starts being dragged anyway. 
+        // the preview as soon as the item starts being dragged anyway.
+        this._havePointer = false;  
         this.hidePreview();
-    }
+    } 
 };
 
 Signals.addSignalMethods(GenericDisplayItem.prototype);
@@ -512,6 +539,24 @@ GenericDisplay.prototype = {
         }
 
         this._updateDisplayControl(resetDisplayControl);
+
+        // We currently redisplay matching items and raise the sideshow as part of two different callbacks.
+        // Checking what is under the pointer after a timeout allows us to not merge these callbacks into one, at least for now.  
+        Mainloop.timeout_add(5, 
+                             Lang.bind(this,
+                                       function() {
+                                           // Check if the pointer is over one of the items and display the preview pop-up if it is.
+                                           let [child, x, y, mask] = Gdk.Screen.get_default().get_root_window().get_pointer();
+                                           let global = Shell.Global.get();
+                                           let actor = global.stage.get_actor_at_pos(x, y);
+                                           if (actor != null) {
+                                               let item = this._findDisplayedByActor(actor.get_parent());
+                                               if (item != null) {
+                                                   item.onDrawnUnderPointer();
+                                               }
+                                           }
+                                           return false;
+                                       }));
     },
 
     // Creates a display item based on the information associated with itemId 
@@ -526,7 +571,7 @@ GenericDisplay.prototype = {
 
         let itemInfo = this._allItems[itemId];
         let displayItem = this._createDisplayItem(itemInfo);
-        displayItem.setHasPreview(true);
+        displayItem.setShowPreview(true);
 
         displayItem.connect('activate', function() {
             me._activatedItem = displayItem;
@@ -608,17 +653,6 @@ GenericDisplay.prototype = {
 
         this._displayMatchedItems(true);
 
-        // Check if the pointer is over one of the items and display the preview pop-up if it is.
-        let [child, x, y, mask] = Gdk.Screen.get_default().get_root_window().get_pointer();
-        let global = Shell.Global.get();
-        let actor = global.stage.get_actor_at_pos(x, y);
-        if (actor != null) {
-            let item = this._findDisplayedByActor(actor.get_parent());
-            if (item != null) {
-                item.showPreview();
-            }
-        }
-
         this.emit('redisplayed');
     },
 
diff --git a/js/ui/overlay.js b/js/ui/overlay.js
index 5ad47ed..dbc66cd 100644
--- a/js/ui/overlay.js
+++ b/js/ui/overlay.js
@@ -146,6 +146,11 @@ Sideshow.prototype = {
         this._searchEntry.connect('key-press-event', function (se, e) {
             let symbol = Shell.get_event_key_symbol(e);
             if (symbol == Clutter.Escape) {
+                // We always want to hide the previews when the user hits Escape.
+                // If something that should have a preview gets displayed under 
+                // the mouse pointer afterwards the preview will get redisplayed.
+                me._appDisplay.hidePreview(); 
+                me._docDisplay.hidePreview(); 
                 // Escape will keep clearing things back to the desktop.  First, if
                 // we have active text, we remove it.
                 if (me._searchEntry.text != '')



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