[gnome-shell/workspace-thumbnails] Add automatic workspace management
- From: Owen Taylor <otaylor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/workspace-thumbnails] Add automatic workspace management
- Date: Tue, 25 Jan 2011 21:49:27 +0000 (UTC)
commit 0fd666c419a5fe0074a0ffc49f64b9be7a3f6f55
Author: Owen W. Taylor <otaylor fishsoup net>
Date: Tue Jan 25 16:29:45 2011 -0500
Add automatic workspace management
Automatically add and remove workspaces so that the last workspace is
always empty and no workspaces are empty other than that workspace.
js/ui/main.js | 121 +++++++++++++++++++++++++++++++++++------------
js/ui/workspacesView.js | 6 ++
2 files changed, 97 insertions(+), 30 deletions(-)
---
diff --git a/js/ui/main.js b/js/ui/main.js
index c8e87e1..14a8b76 100644
--- a/js/ui/main.js
+++ b/js/ui/main.js
@@ -196,14 +196,103 @@ function start() {
_log('info', 'loaded at ' + _startDate);
log('GNOME Shell started at ' + _startDate);
- Mainloop.idle_add(_removeUnusedWorkspaces);
-
let perfModuleName = GLib.getenv("SHELL_PERF_MODULE");
if (perfModuleName) {
let perfOutput = GLib.getenv("SHELL_PERF_OUTPUT");
let module = eval('imports.perf.' + perfModuleName + ';');
Scripting.runPerfScript(module, perfOutput);
}
+
+ global.screen.connect('notify::n-workspaces', _nWorkspacesChanged);
+ Mainloop.idle_add(_nWorkspacesChanged);
+}
+
+let _workspaces = [];
+let _checkWorkspacesId = 0;
+
+function _checkWorkspaces() {
+ let i;
+ let emptyWorkspaces = [];
+
+ for (i = 0; i < _workspaces.length; i++)
+ emptyWorkspaces[i] = true;
+
+ let windows = global.get_window_actors();
+ for (i = 0; i < windows.length; i++) {
+ let win = windows[i];
+
+ if (win.get_meta_window().is_on_all_workspaces())
+ continue;
+
+ let workspaceIndex = win.get_workspace();
+ emptyWorkspaces[workspaceIndex] = false;
+ }
+
+ // If we don't have an empty workspace at the end, add one
+ if (!emptyWorkspaces[emptyWorkspaces.length -1]) {
+ global.screen.append_new_workspace(false, global.get_current_time());
+ emptyWorkspaces.push(false);
+ }
+
+ // Delete other empty workspaces; do it from the end to avoid index changes
+ for (i = emptyWorkspaces.length - 2; i >= 0; i--) {
+ if (emptyWorkspaces[i])
+ global.screen.remove_workspace(_workspaces[i], global.get_current_time());
+ }
+
+ _checkWorkspacesId = 0;
+ return false;
+}
+
+function _queueCheckWorkspaces() {
+ if (_checkWorkspacesId == 0)
+ _checkWorkspacesId = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, _checkWorkspaces);
+}
+
+function _nWorkspacesChanged() {
+ let oldNumWorkspaces = _workspaces.length;
+ let newNumWorkspaces = global.screen.n_workspaces;
+
+ if (oldNumWorkspaces == newNumWorkspaces)
+ return false;
+
+ let lostWorkspaces = [];
+ if (newNumWorkspaces > oldNumWorkspaces) {
+ let w;
+
+ // Assume workspaces are only added at the end
+ for (w = oldNumWorkspaces; w < newNumWorkspaces; w++)
+ _workspaces[w] = global.screen.get_workspace_by_index(w);
+
+ for (w = oldNumWorkspaces; w < newNumWorkspaces; w++) {
+ let workspace = _workspaces[w];
+ workspace._windowAddedId = workspace.connect('window-added', _queueCheckWorkspaces);
+ workspace._windowRemovedId = workspace.connect('window-removed', _queueCheckWorkspaces);
+ }
+
+ } else {
+ // Assume workspaces are only removed sequentially
+ // (e.g. 2,3,4 - not 2,4,7)
+ let removedIndex;
+ let removedNum = oldNumWorkspaces - newNumWorkspaces;
+ for (let w = 0; w < oldNumWorkspaces; w++) {
+ let workspace = global.screen.get_workspace_by_index(w);
+ if (_workspaces[w] != workspace) {
+ removedIndex = w;
+ break;
+ }
+ }
+
+ let lostWorkspaces = _workspaces.splice(removedIndex, removedNum);
+ lostWorkspaces.forEach(function(workspace) {
+ workspace.disconnect(workspace._windowAddedId);
+ workspace.disconnect(workspace._windowRemovedId);
+ });
+ }
+
+ _queueCheckWorkspaces();
+
+ return false;
}
/**
@@ -273,34 +362,6 @@ function _relayout() {
panel.hideCalendar();
}
-// metacity-clutter currently uses the same prefs as plain metacity,
-// which probably means we'll be starting out with multiple workspaces;
-// remove any unused ones. (We do this from an idle handler, because
-// global.get_window_actors() still returns NULL at the point when start()
-// is called.)
-function _removeUnusedWorkspaces() {
-
- let windows = global.get_window_actors();
- let maxWorkspace = 0;
- for (let i = 0; i < windows.length; i++) {
- let win = windows[i];
-
- if (!win.get_meta_window().is_on_all_workspaces() &&
- win.get_workspace() > maxWorkspace) {
- maxWorkspace = win.get_workspace();
- }
- }
- let screen = global.screen;
- if (screen.n_workspaces > maxWorkspace) {
- for (let w = screen.n_workspaces - 1; w > maxWorkspace; w--) {
- let workspace = screen.get_workspace_by_index(w);
- screen.remove_workspace(workspace, 0);
- }
- }
-
- return false;
-}
-
// This function encapsulates hacks to make certain global keybindings
// work even when we are in one of our modes where global keybindings
// are disabled with a global grab. (When there is a global grab, then
diff --git a/js/ui/workspacesView.js b/js/ui/workspacesView.js
index 9a51139..669ca05 100644
--- a/js/ui/workspacesView.js
+++ b/js/ui/workspacesView.js
@@ -1075,6 +1075,12 @@ WorkspacesDisplay.prototype = {
this._workspaceThumbnails.splice(removedIndex, removedNum);
}
+ // If we removed the current workspace then we'll be animating workspace indicator
+ // to an adjacent workspace, but that is wrong, since now that adjacent workspace
+ // is in the current slot, so remove the animation
+ Tweener.removeTweens(this._thumbnailIndicator);
+ this._constrainThumbnailIndicator();
+
this.workspacesView.updateWorkspaces(oldNumWorkspaces,
newNumWorkspaces,
lostWorkspaces);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]