From f0e03b5e828d7b9f7f2786741c7d74277ec7ef06 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Wed, 27 Jun 2012 21:13:32 +0200 Subject: [PATCH] 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 ae08ea255..dafe131ed 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 1202d5f22..6bd124d5d 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);