[gnome-shell] WorkspaceSwitcherPopup: fix for dynamic workspace changes



commit f0e03b5e828d7b9f7f2786741c7d74277ec7ef06
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Wed Jun 27 21:13:32 2012 +0200

    WorkspaceSwitcherPopup: fix for dynamic workspace changes
    
    Changing the number of workspaces while the popup was visible (which
    happens when moving windows on the last non empty workspace) resulted
    in a wrong layout. Fix that, by listening to workspace-added and
    workspace-removed signals, and by always requesting an updated size
    from the actor.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=679005

 js/ui/windowManager.js          |   28 +++++++++++++++--------
 js/ui/workspaceSwitcherPopup.js |   45 +++++++++++++++++++++++++++-----------
 2 files changed, 50 insertions(+), 23 deletions(-)
---
diff --git a/js/ui/windowManager.js b/js/ui/windowManager.js
index ae08ea2..dafe131 100644
--- a/js/ui/windowManager.js
+++ b/js/ui/windowManager.js
@@ -521,7 +521,7 @@ const WindowManager = new Lang.Class({
     _startAppSwitcher : function(display, screen, window, binding) {
         /* prevent a corner case where both popups show up at once */
         if (this._workspaceSwitcherPopup != null)
-            this._workspaceSwitcherPopup.actor.hide();
+            this._workspaceSwitcherPopup.destroy();
 
         let tabPopup = new AltTab.AltTabPopup();
 
@@ -545,20 +545,29 @@ const WindowManager = new Lang.Class({
         if (screen.n_workspaces == 1)
             return;
 
-        if (this._workspaceSwitcherPopup == null)
-            this._workspaceSwitcherPopup = new WorkspaceSwitcherPopup.WorkspaceSwitcherPopup();
-
         let [action,,,direction] = binding.get_name().split('-');
         let direction = Meta.MotionDirection[direction.toUpperCase()];
+        let newWs;
+
 
         if (direction != Meta.MotionDirection.UP &&
             direction != Meta.MotionDirection.DOWN)
             return;
 
         if (action == 'switch')
-            this.actionMoveWorkspace(direction);
+            newWs = this.actionMoveWorkspace(direction);
         else
-            this.actionMoveWindow(window, direction);
+            newWs = this.actionMoveWindow(window, direction);
+
+        if (!Main.overview.visible) {
+            if (this._workspaceSwitcherPopup == null) {
+                this._workspaceSwitcherPopup = new WorkspaceSwitcherPopup.WorkspaceSwitcherPopup();
+                this._workspaceSwitcherPopup.connect('destroy', Lang.bind(this, function() {
+                    this._workspaceSwitcherPopup = null;
+                }));
+            }
+            this._workspaceSwitcherPopup.display(direction, newWs.index());
+        }
     },
 
     actionMoveWorkspace: function(direction) {
@@ -567,8 +576,8 @@ const WindowManager = new Lang.Class({
 
         if (activeWorkspace != toActivate)
             toActivate.activate(global.get_current_time());
-        if (!Main.overview.visible)
-            this._workspaceSwitcherPopup.display(direction, toActivate.index());
+
+        return toActivate;
     },
 
     actionMoveWindow: function(window, direction) {
@@ -586,7 +595,6 @@ const WindowManager = new Lang.Class({
             toActivate.activate_with_focus (window, global.get_current_time());
         }
 
-        if (!Main.overview.visible)
-            this._workspaceSwitcherPopup.display(direction, toActivate.index());
+        return toActivate;
     },
 });
diff --git a/js/ui/workspaceSwitcherPopup.js b/js/ui/workspaceSwitcherPopup.js
index 1202d5f..6bd124d 100644
--- a/js/ui/workspaceSwitcherPopup.js
+++ b/js/ui/workspaceSwitcherPopup.js
@@ -5,6 +5,7 @@ const Lang = imports.lang;
 const Mainloop = imports.mainloop;
 const Meta  = imports.gi.Meta;
 const Shell = imports.gi.Shell;
+const Signals = imports.signals;
 const St = imports.gi.St;
 
 const Main = imports.ui.main;
@@ -41,12 +42,14 @@ const WorkspaceSwitcherPopup = new Lang.Class({
 
         this.actor.add_actor(this._container);
 
-        this._redraw();
-
-        this._position();
+        this._redisplay();
 
         this.actor.hide();
 
+        this._globalSignals = [];
+        this._globalSignals.push(global.screen.connect('workspace-added', Lang.bind(this, this._redisplay)));
+        this._globalSignals.push(global.screen.connect('workspace-removed', Lang.bind(this, this._redisplay)));
+
         this._timeoutId = Mainloop.timeout_add(DISPLAY_TIMEOUT, Lang.bind(this, this._onTimeout));
     },
 
@@ -102,15 +105,15 @@ const WorkspaceSwitcherPopup = new Lang.Class({
         }
     },
 
-    _redraw : function(direction, activeWorkspaceIndex) {
+    _redisplay: function() {
         this._list.destroy_all_children();
 
         for (let i = 0; i < global.screen.n_workspaces; i++) {
             let indicator = null;
 
-           if (i == activeWorkspaceIndex && direction == Meta.MotionDirection.UP)
+           if (i == this._activeWorkspaceIndex && this._direction == Meta.MotionDirection.UP)
                indicator = new St.Bin({ style_class: 'ws-switcher-active-up' });
-           else if(i == activeWorkspaceIndex && direction == Meta.MotionDirection.DOWN)
+           else if(i == this._activeWorkspaceIndex && this._direction == Meta.MotionDirection.DOWN)
                indicator = new St.Bin({ style_class: 'ws-switcher-active-down' });
            else
                indicator = new St.Bin({ style_class: 'ws-switcher-box' });
@@ -118,13 +121,13 @@ const WorkspaceSwitcherPopup = new Lang.Class({
            this._list.add_actor(indicator);
 
         }
-    },
 
-    _position: function() {
         let primary = Main.layoutManager.primaryMonitor;
-        this._container.x = primary.x + Math.floor((primary.width - this._container.width) / 2);
+        let [containerMinHeight, containerNatHeight] = this._container.get_preferred_height(global.screen_width);
+        let [containerMinWidth, containerNatWidth] = this._container.get_preferred_width(containerNatHeight);
+        this._container.x = primary.x + Math.floor((primary.width - containerNatWidth) / 2);
         this._container.y = primary.y + Main.panel.actor.height +
-                            Math.floor(((primary.height - Main.panel.actor.height) - this._container.height) / 2);
+                            Math.floor(((primary.height - Main.panel.actor.height) - containerNatHeight) / 2);
     },
 
     _show : function() {
@@ -132,12 +135,14 @@ const WorkspaceSwitcherPopup = new Lang.Class({
                                             time: ANIMATION_TIME,
                                             transition: 'easeOutQuad'
                                            });
-        this._position();
         this.actor.show();
     },
 
     display : function(direction, activeWorkspaceIndex) {
-        this._redraw(direction, activeWorkspaceIndex);
+        this._direction = direction;
+        this._activeWorkspaceIndex = activeWorkspaceIndex;
+
+        this._redisplay();
         if (this._timeoutId != 0)
             Mainloop.source_remove(this._timeoutId);
         this._timeoutId = Mainloop.timeout_add(DISPLAY_TIMEOUT, Lang.bind(this, this._onTimeout));
@@ -150,8 +155,22 @@ const WorkspaceSwitcherPopup = new Lang.Class({
         Tweener.addTween(this._container, { opacity: 0.0,
                                             time: ANIMATION_TIME,
                                             transition: 'easeOutQuad',
-                                            onComplete: function() { this.actor.hide(); },
+                                            onComplete: function() { this.destroy(); },
                                             onCompleteScope: this
                                            });
+    },
+
+    destroy: function() {
+        if (this._timeoutId)
+            Mainloop.source_remove(this._timeoutId);
+        this._timeoutId = 0;
+
+        for (let i = 0; i < this._globalSignals.length; i++)
+            global.screen.disconnect(this._globalSignals[i]);
+
+        this.actor.destroy();
+
+        this.emit('destroy');
     }
 });
+Signals.addSignalMethods(WorkspaceSwitcherPopup.prototype);



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