[gnome-shell] Bug 589316 - Add application/window icon to overlay windows



commit 4d52c1095816bfba51715b5e836f29483960ea13
Author: Colin Walters <walters verbum org>
Date:   Thu Jul 23 17:36:41 2009 -0400

    Bug 589316 - Add application/window icon to overlay windows
    
    To better distinguish between vast fields of white of which many
    windows are composed, add the application icon to the bottom
    right of the window.
    
    We fade them in to avoid an abrupt feel.  The icons are in the
    workspaces group, not individual workspace groups to avoid
    having to adjust them when we scale the workspaces.
    
    Replace Workspace._lookupIndexAndClone with Workspace.lookupIndex,
    and make the caller go from index to clone, or clone and index.

 js/ui/workspaces.js |  146 +++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 112 insertions(+), 34 deletions(-)
---
diff --git a/js/ui/workspaces.js b/js/ui/workspaces.js
index 2325b5a..6babf82 100644
--- a/js/ui/workspaces.js
+++ b/js/ui/workspaces.js
@@ -121,9 +121,10 @@ WindowClone.prototype = {
     _onDragBegin : function (draggable, time) {
         this._inDrag = true;
         this._updateTitle();
+        this.emit('drag-begin');
     },
 
-    _onDragEnd : function (draggable, time) {
+    _onDragEnd : function (draggable, time, snapback) {
         this._inDrag = false;
 
         // Most likely, the clone is going to move away from the
@@ -133,6 +134,8 @@ WindowClone.prototype = {
         // better to have the label mysteriously missing than
         // mysteriously present
         this._havePointer = false;
+
+        this.emit('drag-end');
     },
 
     // Called by Tweener
@@ -155,16 +158,7 @@ WindowClone.prototype = {
                                 padding: 4,
                                 spacing: 4,
                                 orientation: Big.BoxOrientation.HORIZONTAL });
-        
-        let icon = this.metaWindow.mini_icon;
-        let iconTexture = new Clutter.Texture({ x: this.actor.x,
-                                                y: this.actor.y + this.actor.height - 16,
-                                                width: 16,
-                                                height: 16,
-                                                keep_aspect_ratio: true });
-        Shell.clutter_texture_set_from_pixbuf(iconTexture, icon);
-        box.append(iconTexture, Big.BoxPackFlags.NONE);
-        
+
         let title = new Clutter.Text({ color: WINDOWCLONE_TITLE_COLOR,
                                        font_name: "Sans 12",
                                        text: this.metaWindow.title,
@@ -258,18 +252,26 @@ DesktopClone.prototype = {
 Signals.addSignalMethods(DesktopClone.prototype);
 
 
-function Workspace(workspaceNum) {
-    this._init(workspaceNum);
+/**
+ * @workspaceNum: Workspace index
+ * @parentActor: The actor which will be the parent of this workspace;
+ *               we need this in order to add chrome such as the icons
+ *               on top of the windows without having them be scaled.
+ */
+function Workspace(workspaceNum, parentActor) {
+    this._init(workspaceNum, parentActor);
 }
 
 Workspace.prototype = {
-    _init : function(workspaceNum) {
+    _init : function(workspaceNum, parentActor) {
         let me = this;
         let global = Shell.Global.get();
 
         this.workspaceNum = workspaceNum;
         this._metaWorkspace = global.screen.get_workspace_by_index(workspaceNum);
 
+        this.parentActor = parentActor;
+
         this.actor = new Clutter.Group();
         this.actor._delegate = this;
         this.scale = 1.0;
@@ -298,6 +300,7 @@ Workspace.prototype = {
         // Create clones for remaining windows that should be
         // visible in the overlay
         this._windows = [this._desktop];
+        this._windowIcons = [ null ];
         for (let i = 0; i < windows.length; i++) {
             if (this._isOverlayWindow(windows[i])) {
                 this._addWindowClone(windows[i]);
@@ -364,21 +367,19 @@ Workspace.prototype = {
         }
     },
 
-    _lookupIndexAndClone: function (metaWindow) {
+    _lookupIndex: function (metaWindow) {
         let index, clone;
         for (let i = 0; i < this._windows.length; i++) {
             if (this._windows[i].metaWindow == metaWindow) {
-                index = i;
-                clone = this._windows[index];
-                return [index, clone];
+                return i;
             }
         }
-        return [-1, null];
+        return -1;
     },
 
     lookupCloneForMetaWindow: function (metaWindow) {
-        let [index, clone] = this._lookupIndexAndClone (metaWindow);
-        return clone;
+        let index = this._lookupIndex (metaWindow);
+        return index < 0 ? null : this._windows[index];
     },
 
     _adjustRemoveButton : function() {
@@ -440,6 +441,7 @@ Workspace.prototype = {
 
         for (let i = 1; i < this._windows.length; i++) {
             let clone = this._windows[i];
+            let icon = this._windowIcons[i];
             clone.stackAbove = this._windows[i - 1].actor;
 
             let [xCenter, yCenter, fraction] = this._computeWindowPosition(i);
@@ -450,6 +452,7 @@ Workspace.prototype = {
             let desiredSize = global.screen_width * fraction;
             let scale = Math.min(desiredSize / size, 1.0 / this.scale);
 
+            icon.hide();
             Tweener.addTween(clone.actor, 
                              { x: xCenter - 0.5 * scale * clone.actor.width,
                                y: yCenter - 0.5 * scale * clone.actor.height,
@@ -457,22 +460,63 @@ Workspace.prototype = {
                                scale_y: scale,
                                workspace_relative: workspaceZooming ? this : null,
                                time: Overlay.ANIMATION_TIME,
-                               transition: "easeOutQuad"
+                               transition: "easeOutQuad",
+                               onComplete: Lang.bind(this, function() {
+                                  this._fadeInWindowIcon(clone, icon);
+                               })
                              });
         }
     },
 
+    _fadeInWindowIcon: function (clone, icon) {
+        icon.opacity = 0;
+        icon.show();
+        let [parentX, parentY] = icon.get_parent().get_transformed_position();
+        let [cloneX, cloneY] = clone.actor.get_transformed_position();
+        let [cloneWidth, cloneHeight] = clone.actor.get_transformed_size();
+        // Note we only round the first part, because we're still going to be
+        // positioned relative to the parent.  By subtracting a possibly
+        // non-integral parent X/Y we cancel it out.
+        let x = Math.round(cloneX + cloneWidth - icon.width) - parentX;
+        let y = Math.round(cloneY + cloneHeight - icon.height) - parentY;
+        icon.set_position(x, y);
+        icon.raise(this.actor);
+        Tweener.addTween(icon,
+                         { opacity: 255,
+                           time: Overlay.ANIMATION_TIME,
+                           transition: "easeOutQuad" });
+    },
+
+    _fadeInAllIcons: function () {
+        for (let i = 1; i < this._windows.length; i++) {
+            let clone = this._windows[i];
+            let icon = this._windowIcons[i];
+            this._fadeInWindowIcon(clone, icon);
+        }
+    },
+
+    _hideAllIcons: function () {
+        for (let i = 1; i < this._windows.length; i++) {
+            let icon = this._windowIcons[i];
+            icon.hide();
+        }
+    },
+
     _windowRemoved : function(metaWorkspace, metaWin) {
         let global = Shell.Global.get();
         let win = metaWin.get_compositor_private();
 
         // find the position of the window in our list
-        let [index, clone] = this._lookupIndexAndClone (metaWin);
+        let index = this._lookupIndex (metaWin);
 
         if (index == -1)
             return;
 
+        let clone = this._windows[index];
+        let icon = this._windowIcons[index];
+
         this._windows.splice(index, 1);
+        this._windowIcons.splice(index, 1);
 
         // If metaWin.get_compositor_private() returned non-NULL, that
         // means the window still exists (and is just being moved to
@@ -490,6 +534,7 @@ Workspace.prototype = {
             };
         }
         clone.destroy();
+        icon.destroy();
 
         this._positionWindows(false);
         this.updateRemovable();
@@ -559,8 +604,10 @@ Workspace.prototype = {
 
     // Animates the return from overlay mode
     zoomFromOverlay : function() {
-        this.leavingOverlay = true; 
- 
+        this.leavingOverlay = true;
+
+        this._hideAllIcons();
+
         Tweener.addTween(this.actor,
                          { x: this.fullSizeX,
                            y: this.fullSizeY,
@@ -592,16 +639,18 @@ Workspace.prototype = {
     // Animates grid shrinking/expanding when a row or column
     // of workspaces is added or removed
     resizeToGrid : function (oldScale) {
+        this._hideAllIcons();
         Tweener.addTween(this.actor,
                          { x: this.gridX,
                            y: this.gridY,
                            scale_x: this.scale,
                            scale_y: this.scale,
                            time: Overlay.ANIMATION_TIME,
-                           transition: "easeOutQuad"
+                           transition: "easeOutQuad",
+                           onComplete: Lang.bind(this, this._fadeInAllIcons)
                          });
     },
-    
+
     // Animates the addition of a new (empty) workspace
     slideIn : function(oldScale) {
         let global = Shell.Global.get();
@@ -630,6 +679,8 @@ Workspace.prototype = {
         let global = Shell.Global.get();
         let destX = this.actor.x, destY = this.actor.y;
 
+        this._hideAllIcons();
+
         if (this.gridCol > this.gridRow)
             destX = global.screen_width;
         else
@@ -682,16 +733,47 @@ Workspace.prototype = {
         return !win.is_override_redirect();
     },
 
+    _createWindowIcon: function(window) {
+        let appSys = Shell.AppSystem.get_default();
+        let appMon = Shell.AppMonitor.get_default()
+        let appInfo = appMon.get_window_app(window.metaWindow);
+        let iconTexture = null;
+        // The design is application based, so prefer the application
+        // icon here if we have it.  FIXME - should move this fallback code
+        // into ShellAppMonitor.
+        if (appInfo) {
+            iconTexture = appInfo.create_icon_texture(48);
+        } else {
+            let icon = window.metaWindow.icon;
+            iconTexture = new Clutter.Texture({ width: 48,
+                                                height: 48,
+                                                keep_aspect_ratio: true });
+            Shell.clutter_texture_set_from_pixbuf(iconTexture, icon);
+        }
+        return iconTexture;
+    },
+
     // Create a clone of a (non-desktop) window and add it to the window list
     _addWindowClone : function(win) {
+        let icon = this._createWindowIcon(win);
+        this.parentActor.add_actor(icon);
+
         let clone = new WindowClone(win);
         clone.connect('selected',
                       Lang.bind(this, this._onCloneSelected));
-        clone.connect('dragged',
-                      Lang.bind(this, this._onCloneDragged));
+        clone.connect('drag-begin',
+                      Lang.bind(this, function() {
+                          icon.hide();
+                      }));
+        clone.connect('drag-end',
+                      Lang.bind(this, function() {
+                          icon.show();
+                      }));
 
         this.actor.add_actor(clone.actor);
+
         this._windows.push(clone);
+        this._windowIcons.push(icon);
 
         return clone;
     },
@@ -717,10 +799,6 @@ Workspace.prototype = {
         return [xCenter, yCenter, fraction];
     },
 
-    _onCloneDragged : function (clone, stageX, stageY, time) {
-        this.emit('window-dragged', clone, stageX, stageY, time);
-    },
-
     _onCloneSelected : function (clone, time) {
         Main.overlay.activateWindow(clone.metaWindow, time);
     },
@@ -1052,7 +1130,7 @@ Workspaces.prototype = {
     },
 
     _addWorkspaceActor : function(workspaceNum) {
-        let workspace  = new Workspace(workspaceNum);
+        let workspace  = new Workspace(workspaceNum, this.actor);
         this._workspaces[workspaceNum] = workspace;
         this.actor.add_actor(workspace.actor);
     },



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