[gnome-shell/overview-relayout: 3/22] overview: Do not zoom the desktop background



commit 6432de95ccd1cd2b6576b4a75eb53e4df9abf098
Author: Florian Müllner <fmuellner gnome org>
Date:   Thu Jul 15 16:21:32 2010 +0200

    overview: Do not zoom the desktop background
    
    While scaling the desktop background with the window previews represents
    workspaces quite intuitively, the approach is not without problems.
    As window previews in the overview behave quite differently to "real"
    windows, the representation of workspaces as miniature versions of
    "real" workspaces is flawed. The scaling also makes the transitions
    to and from the overview much more visually expensive, without adding
    much benefit.
    Leaving the background in place provides more visual stability to the
    transitions and emphasizes the distinctive behavior of elements in the
    overview.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=634948

 data/theme/gnome-shell.css |    4 -
 js/ui/overview.js          |   62 ++++++++++++++---
 js/ui/workspace.js         |  166 ++++++++++----------------------------------
 js/ui/workspacesView.js    |   10 +++-
 4 files changed, 97 insertions(+), 145 deletions(-)
---
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index 0a62039..8c5c0d2 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -257,10 +257,6 @@ StTooltip StLabel {
 
 /* Overview */
 
-.overview {
-    background-color: #111;
-}
-
 .new-workspace-area {
     border: 2px solid rgba(255, 255, 255, 0.8);
     border-radius: 10px;
diff --git a/js/ui/overview.js b/js/ui/overview.js
index bec99c7..3c398d0 100644
--- a/js/ui/overview.js
+++ b/js/ui/overview.js
@@ -1,6 +1,7 @@
 /* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
 
 const Clutter = imports.gi.Clutter;
+const Meta = imports.gi.Meta;
 const Mainloop = imports.mainloop;
 const Signals = imports.signals;
 const Lang = imports.lang;
@@ -172,7 +173,16 @@ function Overview() {
 
 Overview.prototype = {
     _init : function() {
-        this._group = new St.Group({ style_class: 'overview' });
+        this._desktopFade = new St.Bin();
+        global.overlay_group.add_actor(this._desktopFade);
+
+        // The actual global.background_actor is inside global.window_group,
+        // which is hidden when displaying the overview, so we display a clone.
+        this._background = new Clutter.Clone({ source: global.background_actor });
+        this._background.hide();
+        global.overlay_group.add_actor(this._background);
+
+        this._group = new St.Group({ name: 'overview' });
         this._group._delegate = this;
         this._group.connect('destroy', Lang.bind(this,
             function() {
@@ -209,10 +219,6 @@ Overview.prototype = {
                                                               reactive: true });
         this._group.add_actor(this._transparentBackground);
 
-        // Background color for the Overview
-        this._backOver = new St.Label();
-        this._group.add_actor(this._backOver);
-
         this._group.hide();
         global.overlay_group.add_actor(this._group);
 
@@ -238,6 +244,20 @@ Overview.prototype = {
         this.workspaces = null;
     },
 
+    _getDesktopClone: function() {
+        let windows = global.get_window_actors().filter(function(w) {
+            return w.meta_window.get_window_type() == Meta.WindowType.DESKTOP;
+        });
+        if (windows.length == 0)
+            return null;
+
+        let clone = new Clutter.Clone({ source: windows[0].get_texture() });
+        clone.source.connect('destroy', Lang.bind(this, function() {
+            clone.destroy();
+        }));
+        return clone;
+    },
+
     _onViewChanged: function() {
         if (!this.visible)
             return;
@@ -314,11 +334,6 @@ Overview.prototype = {
         this._workspacesBarWidth = this._workspacesWidth;
         this._workspacesBarY = primary.height - displayGridRowHeight;
 
-        // The parent (this._group) is positioned at the top left of the primary monitor
-        // while this._backOver occupies the entire screen.
-        this._backOver.set_position(- primary.x, - primary.y);
-        this._backOver.set_size(global.screen_width, global.screen_height);
-
         this._paneContainer.set_position(this._dash.actor.x + this._dash.actor.width + DEFAULT_PADDING,
                                          this._workspacesY);
         // Dynamic width
@@ -456,6 +471,19 @@ Overview.prototype = {
         this._group.add_actor(this._workspacesBar);
         this._workspacesBar.raise(this.workspaces.actor);
 
+        if (!this._desktopFade.child)
+            this._desktopFade.child = this._getDesktopClone();
+
+        if (!this.workspaces.getActiveWorkspace().hasMaximizedWindows()) {
+            this._desktopFade.opacity = 255;
+            this._desktopFade.show();
+            Tweener.addTween(this._desktopFade,
+                             { opacity: 0,
+                               time: ANIMATION_TIME,
+                               transition: 'easeOutQuad'
+                             });
+        }
+
         // All the the actors in the window group are completely obscured,
         // hiding the group holding them while the Overview is displayed greatly
         // increases performance of the Overview especially when there are many
@@ -465,6 +493,7 @@ Overview.prototype = {
         // clones of them, this would obviously no longer be necessary.
         global.window_group.hide();
         this._group.show();
+        this._background.show();
 
         // Create a zoom out effect. First scale the Overview group up and
         // position it so that the active workspace fills up the whole screen,
@@ -502,6 +531,16 @@ Overview.prototype = {
 
         this.animationInProgress = true;
         this._hideInProgress = true;
+
+        if (!this.workspaces.getActiveWorkspace().hasMaximizedWindows()) {
+            this._desktopFade.opacity = 0;
+            this._desktopFade.show();
+            Tweener.addTween(this._desktopFade,
+                             { opacity: 255,
+                               time: ANIMATION_TIME,
+                               transition: 'easeOutQuad' });
+        }
+
         if (this._activeDisplayPane != null)
             this._activeDisplayPane.close();
         this.workspaces.hide();
@@ -559,6 +598,7 @@ Overview.prototype = {
             return;
 
         this.animationInProgress = false;
+        this._desktopFade.hide();
         this._coverPane.lower_bottom();
 
         this.emit('shown');
@@ -576,6 +616,8 @@ Overview.prototype = {
         this._workspacesManager = null;
 
         this._dash.hide();
+        this._desktopFade.hide();
+        this._background.hide();
         this._group.hide();
 
         this.visible = false;
diff --git a/js/ui/workspace.js b/js/ui/workspace.js
index 349c87b..2002175 100644
--- a/js/ui/workspace.js
+++ b/js/ui/workspace.js
@@ -289,76 +289,9 @@ WindowClone.prototype = {
         this.emit('drag-end');
     }
 };
-
 Signals.addSignalMethods(WindowClone.prototype);
 
 
-function DesktopClone(window) {
-    this._init(window);
-}
-
-DesktopClone.prototype = {
-    _init : function(window) {
-        this.actor = new Clutter.Group({ reactive: true });
-
-        let background = new Clutter.Clone({ source: global.background_actor });
-        this.actor.add_actor(background);
-
-        if (window) {
-            this._desktop = new Clutter.Clone({ source: window.get_texture() });
-            this.actor.add_actor(this._desktop);
-            this._desktop.hide();
-        } else {
-            this._desktop = null;
-        }
-
-        this.actor.connect('button-release-event',
-                           Lang.bind(this, this._onButtonRelease));
-    },
-
-    zoomFromOverview: function(fadeInIcons) {
-        if (this._desktop == null)
-            return;
-
-        if (fadeInIcons) {
-            this._desktop.opacity = 0;
-            this._desktop.show();
-            Tweener.addTween(this._desktop,
-                             { opacity: 255,
-                               time: Overview.ANIMATION_TIME,
-                               transition: 'easeOutQuad' });
-        }
-    },
-
-    zoomToOverview: function(fadeOutIcons) {
-        if (this._desktop == null)
-            return;
-
-        if (fadeOutIcons) {
-            this._desktop.opacity = 255;
-            this._desktop.show();
-            Tweener.addTween(this._desktop,
-                             { opacity: 0,
-                               time: Overview.ANIMATION_TIME,
-                               transition: 'easeOutQuad',
-                               onComplete: Lang.bind(this,
-                                   function() {
-                                       this._desktop.hide();
-                                   })
-                             });
-        } else {
-            this._desktop.hide();
-        }
-    },
-
-    _onButtonRelease : function (actor, event) {
-        this.emit('selected', event.get_time());
-    }
-};
-
-Signals.addSignalMethods(DesktopClone.prototype);
-
-
 /**
  * @windowClone: Corresponding window clone
  * @parentActor: The actor which will be the parent of all overlay items
@@ -561,7 +494,6 @@ WindowOverlay.prototype = {
         this._parentActor.queue_relayout();
     }
 };
-
 Signals.addSignalMethods(WindowOverlay.prototype);
 
 const WindowPositionFlags = {
@@ -585,10 +517,20 @@ Workspace.prototype = {
         // Without this the drop area will be overlapped.
         this._windowOverlaysGroup.set_size(0, 0);
 
-        this.actor = new Clutter.Group();
+        this.actor = new Clutter.Group({ reactive: true });
         this.actor._delegate = this;
 
         this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
+        this.actor.connect('button-release-event', Lang.bind(this,
+            function(actor, event) {
+                // Only switch to the workspace when there's no application
+                // windows open. The problem is that it's too easy to miss
+                // an app window and get the wrong one focused.
+                if (this._windows.length == 0) {
+                    this.metaWorkspace.activate(event.get_time());
+                    Main.overview.hide();
+                }
+            }));
 
         // Items in _windowOverlaysGroup should not be scaled, so we don't
         // add them to this.actor, but to its parent whenever it changes
@@ -604,35 +546,10 @@ Workspace.prototype = {
 
         let windows = global.get_window_actors().filter(this._isMyWindow, this);
 
-        // Find the desktop window
-        for (let i = 0; i < windows.length; i++) {
-            if (windows[i].meta_window.get_window_type() == Meta.WindowType.DESKTOP) {
-                this._desktop = new DesktopClone(windows[i]);
-                break;
-            }
-        }
-        // If there wasn't one, fake it
-        if (!this._desktop)
-            this._desktop = new DesktopClone();
-
-        this._desktop.connect('selected',
-                              Lang.bind(this,
-                                        function(clone, time) {
-                                            // Only switch to the workspace when there's no application windows
-                                            // open (we always have one window for the desktop).  The problem
-                                            // is that it's too easy to miss an app window and get the wrong
-                                            // one focused.
-                                            if (this._windows.length == 1) {
-                                                this.metaWorkspace.activate(time);
-                                                Main.overview.hide();
-                                            }
-                                        }));
-        this.actor.add_actor(this._desktop.actor);
-
         // Create clones for remaining windows that should be
         // visible in the Overview
-        this._windows = [this._desktop];
-        this._windowOverlays = [ null ];
+        this._windows = [];
+        this._windowOverlays = [];
         for (let i = 0; i < windows.length; i++) {
             if (this._isOverviewWindow(windows[i])) {
                 this._addWindowClone(windows[i]);
@@ -747,10 +664,10 @@ Workspace.prototype = {
             // FIXME: do something cooler-looking using clutter-cairo
             this._frame = new Clutter.Rectangle({ color: FRAME_COLOR });
             this.actor.add_actor(this._frame);
-            this._frame.set_position(this._desktop.actor.x - FRAME_SIZE / this.actor.scale_x,
-                                     this._desktop.actor.y - FRAME_SIZE / this.actor.scale_y);
-            this._frame.set_size(this._desktop.actor.width + 2 * FRAME_SIZE / this.actor.scale_x,
-                                 this._desktop.actor.height + 2 * FRAME_SIZE / this.actor.scale_y);
+            this._frame.set_position(- FRAME_SIZE / this.actor.scale_x,
+                                     - FRAME_SIZE / this.actor.scale_y);
+            this._frame.set_size(this.actor.width + 2 * FRAME_SIZE / this.actor.scale_x,
+                                 this.actor.height + 2 * FRAME_SIZE / this.actor.scale_y);
             this._frame.lower_bottom();
 
             this._framePosHandler = this.actor.connect('notify::scale-x', Lang.bind(this, this._updateFramePosition));
@@ -770,14 +687,14 @@ Workspace.prototype = {
      * Set the workspace (desktop) reactive
      **/
     setReactive: function(reactive) {
-        this._desktop.actor.reactive = reactive;
+        this.actor.reactive = reactive;
     },
 
     _updateFramePosition : function() {
-        this._frame.set_position(this._desktop.actor.x - FRAME_SIZE / this.actor.scale_x,
-                                 this._desktop.actor.y - FRAME_SIZE / this.actor.scale_y);
-        this._frame.set_size(this._desktop.actor.width + 2 * FRAME_SIZE / this.actor.scale_x,
-                             this._desktop.actor.height + 2 * FRAME_SIZE / this.actor.scale_y);
+        this._frame.set_position(- FRAME_SIZE / this.actor.scale_x,
+                                 - FRAME_SIZE / this.actor.scale_y);
+        this._frame.set_size(this.actor.width + 2 * FRAME_SIZE / this.actor.scale_x,
+                             this.actor.height + 2 * FRAME_SIZE / this.actor.scale_y);
     },
 
     _isCloneVisible: function(clone) {
@@ -788,7 +705,7 @@ Workspace.prototype = {
      * _getVisibleClones:
      *
      * Returns a list WindowClone objects where the clone isn't filtered
-     * out by any application filter.  The clone for the desktop is excluded.
+     * out by any application filter.
      * The returned array will always be newly allocated; it is not in any
      * defined order, and thus it's convenient to call .sort() with your
      * choice of sorting function.
@@ -796,7 +713,7 @@ Workspace.prototype = {
     _getVisibleClones: function() {
         let visible = [];
 
-        for (let i = 1; i < this._windows.length; i++) {
+        for (let i = 0; i < this._windows.length; i++) {
             let clone = this._windows[i];
 
             if (!this._isCloneVisible(clone))
@@ -808,7 +725,7 @@ Workspace.prototype = {
     },
 
     _resetCloneVisibility: function () {
-        for (let i = 1; i < this._windows.length; i++) {
+        for (let i = 0; i < this._windows.length; i++) {
             let clone = this._windows[i];
             let overlay = this._windowOverlays[i];
 
@@ -1007,9 +924,9 @@ Workspace.prototype = {
         let buttonOuterHeight, captionHeight;
         let buttonOuterWidth = 0;
 
-        if (this._windowOverlays[1]) {
-            [buttonOuterHeight, captionHeight] = this._windowOverlays[1].chromeHeights();
-            buttonOuterWidth = this._windowOverlays[1].chromeWidth() / this.scale;
+        if (this._windowOverlays[0]) {
+            [buttonOuterHeight, captionHeight] = this._windowOverlays[0].chromeHeights();
+            buttonOuterWidth = this._windowOverlays[0].chromeWidth() / this.scale;
         } else
             [buttonOuterHeight, captionHeight] = [0, 0];
         buttonOuterHeight /= this.scale;
@@ -1172,7 +1089,7 @@ Workspace.prototype = {
     },
 
     _fadeInAllOverlays: function() {
-        for (let i = 1; i < this._windows.length; i++) {
+        for (let i = 0; i < this._windows.length; i++) {
             let clone = this._windows[i];
             let overlay = this._windowOverlays[i];
             if (this._showOnlyWindows != null && !(clone.metaWindow in this._showOnlyWindows))
@@ -1182,7 +1099,7 @@ Workspace.prototype = {
     },
 
     _hideAllOverlays: function() {
-        for (let i = 1; i< this._windows.length; i++) {
+        for (let i = 0; i < this._windows.length; i++) {
             let overlay = this._windowOverlays[i];
             overlay.hide();
         }
@@ -1309,8 +1226,8 @@ Workspace.prototype = {
     },
 
     // check for maximized windows on the workspace
-    _haveMaximizedWindows: function() {
-        for (let i = 1; i < this._windows.length; i++) {
+    hasMaximizedWindows: function() {
+        for (let i = 0; i < this._windows.length; i++) {
             let metaWindow = this._windows[i].metaWindow;
             if (metaWindow.showing_on_its_workspace() &&
                 metaWindow.maximized_horizontally &&
@@ -1331,12 +1248,6 @@ Workspace.prototype = {
         else
             this.positionWindows(WindowPositionFlags.ZOOM);
 
-        let active = global.screen.get_active_workspace();
-        let fadeInIcons = (Main.overview.animationInProgress &&
-                           active == this.metaWorkspace &&
-                           !this._haveMaximizedWindows());
-        this._desktop.zoomToOverview(fadeInIcons);
-
         this._visible = true;
     },
 
@@ -1354,7 +1265,7 @@ Workspace.prototype = {
                                                                            this._doneLeavingOverview));
 
         // Position and scale the windows.
-        for (let i = 1; i < this._windows.length; i++) {
+        for (let i = 0; i < this._windows.length; i++) {
             let clone = this._windows[i];
 
             clone.zoomFromOverview();
@@ -1383,11 +1294,6 @@ Workspace.prototype = {
             }
         }
 
-        let active = global.screen.get_active_workspace();
-        let fadeOutIcons = (active == this.metaWorkspace &&
-                            !this._haveMaximizedWindows());
-        this._desktop.zoomFromOverview(fadeOutIcons);
-
         this._visible = false;
     },
 
@@ -1451,7 +1357,7 @@ Workspace.prototype = {
 
         // Don't let the user try to select this workspace as it's
         // making its exit.
-        this._desktop.reactive = false;
+        this.actor.reactive = false;
     },
 
     destroy : function() {
@@ -1475,7 +1381,7 @@ Workspace.prototype = {
         // their parent (this.actor), but we might have a zoomed window
         // which has been reparented to the stage - _windows[0] holds
         // the desktop window, which is never reparented
-        for (let w = 1; w < this._windows.length; w++)
+        for (let w = 0; w < this._windows.length; w++)
             this._windows[w].destroy();
         this._windows = [];
     },
@@ -1534,7 +1440,7 @@ Workspace.prototype = {
     },
 
     _onShowOverlayClose: function (windowOverlay) {
-        for (let i = 1; i < this._windowOverlays.length; i++) {
+        for (let i = 0; i < this._windowOverlays.length; i++) {
             let overlay = this._windowOverlays[i];
             if (overlay == windowOverlay)
                 continue;
diff --git a/js/ui/workspacesView.js b/js/ui/workspacesView.js
index 34945d7..4a7edc9 100644
--- a/js/ui/workspacesView.js
+++ b/js/ui/workspacesView.js
@@ -117,6 +117,11 @@ GenericWorkspacesView.prototype = {
         }
     },
 
+    getActiveWorkspace: function() {
+        let active = global.screen.get_active_workspace_index();
+        return this._workspaces[active];
+    },
+
     _clearApplicationWindowSelection: function(reposition) {
         if (this._windowSelectionAppId == null)
             return;
@@ -826,7 +831,7 @@ SingleView.prototype = {
         if (index < 0 || index >= global.n_workspaces)
             return;
 
-        let dragActor = this._workspaces[index]._desktop.actor;
+        let dragActor = this._workspaces[index].actor;
 
         if (draggable) {
             this._workspaces[index].actor.reactive = true;
@@ -856,6 +861,9 @@ SingleView.prototype = {
 
     // start dragging the active workspace
     _onButtonPress: function(actor, event) {
+        if (actor != event.get_source())
+            return;
+
         if (this._dragIndex == -1)
             return;
 



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