[gnome-shell] main: Move workspace tracking code to WindowManager
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] main: Move workspace tracking code to WindowManager
- Date: Mon, 20 May 2013 17:20:34 +0000 (UTC)
commit b2aa29e2219929ce3773caef12bca42c6e4da3f7
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Sat Dec 22 22:10:27 2012 -0500
main: Move workspace tracking code to WindowManager
https://bugzilla.gnome.org/show_bug.cgi?id=691746
js/ui/main.js | 198 +---------------------------------------------
js/ui/windowManager.js | 206 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 207 insertions(+), 197 deletions(-)
---
diff --git a/js/ui/main.js b/js/ui/main.js
index b4e4687..bcd840e 100644
--- a/js/ui/main.js
+++ b/js/ui/main.js
@@ -38,7 +38,6 @@ const Magnifier = imports.ui.magnifier;
const XdndHandler = imports.ui.xdndHandler;
const Util = imports.misc.util;
-const OVERRIDES_SCHEMA = 'org.gnome.shell.overrides';
const DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2e3436ff);
const A11Y_SCHEMA = 'org.gnome.desktop.a11y.keyboard';
@@ -71,7 +70,6 @@ let layoutManager = null;
let _startDate;
let _defaultCssStylesheet = null;
let _cssStylesheet = null;
-let _overridesSettings = null;
let _a11ySettings = null;
function _sessionUpdated() {
@@ -127,11 +125,9 @@ function _initializeUI() {
// and recalculate application associations, so to avoid
// races for now we initialize it here. It's better to
// be predictable anyways.
- let tracker = Shell.WindowTracker.get_default();
+ Shell.WindowTracker.get_default();
Shell.AppUsage.get_default();
- tracker.connect('startup-sequence-changed', _queueCheckWorkspaces);
-
_loadDefaultStylesheet();
// Setup the stage hierarchy early
@@ -188,17 +184,6 @@ function _initializeUI() {
Scripting.runPerfScript(module, perfOutput);
}
- _overridesSettings = new Gio.Settings({ schema: OVERRIDES_SCHEMA });
- _overridesSettings.connect('changed::dynamic-workspaces', _queueCheckWorkspaces);
-
- global.screen.connect('notify::n-workspaces', _nWorkspacesChanged);
-
- global.screen.connect('window-entered-monitor', _windowEnteredMonitor);
- global.screen.connect('window-left-monitor', _windowLeftMonitor);
- global.screen.connect('restacked', _windowsRestacked);
-
- _nWorkspacesChanged();
-
ExtensionDownloader.init();
ExtensionSystem.init();
@@ -215,187 +200,6 @@ function _initializeUI() {
});
}
-let _workspaces = [];
-let _checkWorkspacesId = 0;
-
-/*
- * When the last window closed on a workspace is a dialog or splash
- * screen, we assume that it might be an initial window shown before
- * the main window of an application, and give the app a grace period
- * where it can map another window before we remove the workspace.
- */
-const LAST_WINDOW_GRACE_TIME = 1000;
-
-function _checkWorkspaces() {
- let i;
- let emptyWorkspaces = [];
-
- if (!Meta.prefs_get_dynamic_workspaces()) {
- _checkWorkspacesId = 0;
- return false;
- }
-
- for (i = 0; i < _workspaces.length; i++) {
- let lastRemoved = _workspaces[i]._lastRemovedWindow;
- if ((lastRemoved &&
- (lastRemoved.get_window_type() == Meta.WindowType.SPLASHSCREEN ||
- lastRemoved.get_window_type() == Meta.WindowType.DIALOG ||
- lastRemoved.get_window_type() == Meta.WindowType.MODAL_DIALOG)) ||
- _workspaces[i]._keepAliveId)
- emptyWorkspaces[i] = false;
- else
- emptyWorkspaces[i] = true;
- }
-
- let sequences = Shell.WindowTracker.get_default().get_startup_sequences();
- for (i = 0; i < sequences.length; i++) {
- let index = sequences[i].get_workspace();
- if (index >= 0 && index <= global.screen.n_workspaces)
- emptyWorkspaces[index] = false;
- }
-
- 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);
- }
-
- let activeWorkspaceIndex = global.screen.get_active_workspace_index();
- let removingCurrentWorkspace = (emptyWorkspaces[activeWorkspaceIndex] &&
- activeWorkspaceIndex < emptyWorkspaces.length - 1);
- // Don't enter the overview when removing multiple empty workspaces at startup
- let showOverview = (removingCurrentWorkspace &&
- !emptyWorkspaces.every(function(x) { return x; }));
-
- if (removingCurrentWorkspace) {
- // "Merge" the empty workspace we are removing with the one at the end
- wm.blockAnimations();
- }
-
- // 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());
- }
-
- if (removingCurrentWorkspace) {
- global.screen.get_workspace_by_index(global.screen.n_workspaces -
1).activate(global.get_current_time());
- wm.unblockAnimations();
-
- if (!overview.visible && showOverview)
- overview.show();
- }
-
- _checkWorkspacesId = 0;
- return false;
-}
-
-function keepWorkspaceAlive(workspace, duration) {
- if (workspace._keepAliveId)
- Mainloop.source_remove(workspace._keepAliveId);
-
- workspace._keepAliveId = Mainloop.timeout_add(duration, function() {
- workspace._keepAliveId = 0;
- _queueCheckWorkspaces();
- return false;
- });
-}
-
-function _windowRemoved(workspace, window) {
- workspace._lastRemovedWindow = window;
- _queueCheckWorkspaces();
- Mainloop.timeout_add(LAST_WINDOW_GRACE_TIME, function() {
- if (workspace._lastRemovedWindow == window) {
- workspace._lastRemovedWindow = null;
- _queueCheckWorkspaces();
- }
- return false;
- });
-}
-
-function _windowLeftMonitor(metaScreen, monitorIndex, metaWin) {
- // If the window left the primary monitor, that
- // might make that workspace empty
- if (monitorIndex == layoutManager.primaryIndex)
- _queueCheckWorkspaces();
-}
-
-function _windowEnteredMonitor(metaScreen, monitorIndex, metaWin) {
- // If the window entered the primary monitor, that
- // might make that workspace non-empty
- if (monitorIndex == layoutManager.primaryIndex)
- _queueCheckWorkspaces();
-}
-
-function _windowsRestacked() {
- // Figure out where the pointer is in case we lost track of
- // it during a grab. (In particular, if a trayicon popup menu
- // is dismissed, see if we need to close the message tray.)
- global.sync_pointer();
-}
-
-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', _windowRemoved);
- }
-
- } 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;
-}
-
function _loadDefaultStylesheet() {
if (!sessionMode.isPrimary)
return;
diff --git a/js/ui/windowManager.js b/js/ui/windowManager.js
index 9877fb1..d6433a5 100644
--- a/js/ui/windowManager.js
+++ b/js/ui/windowManager.js
@@ -4,6 +4,7 @@ const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
+const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
const St = imports.gi.St;
const Shell = imports.gi.Shell;
@@ -66,6 +67,209 @@ function getWindowDimmer(actor) {
}
}
+/*
+ * When the last window closed on a workspace is a dialog or splash
+ * screen, we assume that it might be an initial window shown before
+ * the main window of an application, and give the app a grace period
+ * where it can map another window before we remove the workspace.
+ */
+const LAST_WINDOW_GRACE_TIME = 1000;
+
+const WorkspaceTracker = new Lang.Class({
+ Name: 'WorkspaceTracker',
+
+ _init: function(wm) {
+ this._wm = wm;
+
+ this._workspaces = [];
+ this._checkWorkspacesId = 0;
+
+ let tracker = Shell.WindowTracker.get_default();
+ tracker.connect('startup-sequence-changed', Lang.bind(this, this._queueCheckWorkspaces));
+
+ global.screen.connect('notify::n-workspaces', Lang.bind(this, this._nWorkspacesChanged));
+
+ global.screen.connect('window-entered-monitor', Lang.bind(this, this._windowEnteredMonitor));
+ global.screen.connect('window-left-monitor', Lang.bind(this, this._windowLeftMonitor));
+ global.screen.connect('restacked', Lang.bind(this, this._windowsRestacked));
+
+ this._overrideSettings = new Gio.Settings({ schema: 'org.gnome.shell.overrides' });
+ this._overrideSettings.connect('changed::dynamic-workspaces', Lang.bind(this,
this._queueCheckWorkspaces));
+
+ this._nWorkspacesChanged();
+ },
+
+ _checkWorkspaces: function() {
+ let i;
+ let emptyWorkspaces = [];
+
+ if (!Meta.prefs_get_dynamic_workspaces()) {
+ this._checkWorkspacesId = 0;
+ return false;
+ }
+
+ for (i = 0; i < this._workspaces.length; i++) {
+ let lastRemoved = this._workspaces[i]._lastRemovedWindow;
+ if ((lastRemoved &&
+ (lastRemoved.get_window_type() == Meta.WindowType.SPLASHSCREEN ||
+ lastRemoved.get_window_type() == Meta.WindowType.DIALOG ||
+ lastRemoved.get_window_type() == Meta.WindowType.MODAL_DIALOG)) ||
+ this._workspaces[i]._keepAliveId)
+ emptyWorkspaces[i] = false;
+ else
+ emptyWorkspaces[i] = true;
+ }
+
+ let sequences = Shell.WindowTracker.get_default().get_startup_sequences();
+ for (i = 0; i < sequences.length; i++) {
+ let index = sequences[i].get_workspace();
+ if (index >= 0 && index <= global.screen.n_workspaces)
+ emptyWorkspaces[index] = false;
+ }
+
+ 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);
+ }
+
+ let activeWorkspaceIndex = global.screen.get_active_workspace_index();
+ let removingCurrentWorkspace = (emptyWorkspaces[activeWorkspaceIndex] &&
+ activeWorkspaceIndex < emptyWorkspaces.length - 1);
+ // Don't enter the overview when removing multiple empty workspaces at startup
+ let showOverview = (removingCurrentWorkspace &&
+ !emptyWorkspaces.every(function(x) { return x; }));
+
+ if (removingCurrentWorkspace) {
+ // "Merge" the empty workspace we are removing with the one at the end
+ this._wm.blockAnimations();
+ }
+
+ // 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(this._workspaces[i], global.get_current_time());
+ }
+
+ if (removingCurrentWorkspace) {
+ global.screen.get_workspace_by_index(global.screen.n_workspaces -
1).activate(global.get_current_time());
+ this._wm.unblockAnimations();
+
+ if (!Main.overview.visible && showOverview)
+ Main.overview.show();
+ }
+
+ this._checkWorkspacesId = 0;
+ return false;
+ },
+
+ keepWorkspaceAlive: function(workspace, duration) {
+ if (workspace._keepAliveId)
+ Mainloop.source_remove(workspace._keepAliveId);
+
+ workspace._keepAliveId = Mainloop.timeout_add(duration, Lang.bind(this, function() {
+ workspace._keepAliveId = 0;
+ this._queueCheckWorkspaces();
+ return false;
+ }));
+ },
+
+ _windowRemoved: function(workspace, window) {
+ workspace._lastRemovedWindow = window;
+ this._queueCheckWorkspaces();
+ Mainloop.timeout_add(LAST_WINDOW_GRACE_TIME, Lang.bind(this, function() {
+ if (workspace._lastRemovedWindow == window) {
+ workspace._lastRemovedWindow = null;
+ this._queueCheckWorkspaces();
+ }
+ return false;
+ }));
+ },
+
+ _windowLeftMonitor: function(metaScreen, monitorIndex, metaWin) {
+ // If the window left the primary monitor, that
+ // might make that workspace empty
+ if (monitorIndex == Main.layoutManager.primaryIndex)
+ this._queueCheckWorkspaces();
+ },
+
+ _windowEnteredMonitor: function(metaScreen, monitorIndex, metaWin) {
+ // If the window entered the primary monitor, that
+ // might make that workspace non-empty
+ if (monitorIndex == Main.layoutManager.primaryIndex)
+ this._queueCheckWorkspaces();
+ },
+
+ _windowsRestacked: function() {
+ // Figure out where the pointer is in case we lost track of
+ // it during a grab. (In particular, if a trayicon popup menu
+ // is dismissed, see if we need to close the message tray.)
+ global.sync_pointer();
+ },
+
+ _queueCheckWorkspaces: function() {
+ if (this._checkWorkspacesId == 0)
+ this._checkWorkspacesId = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this,
this._checkWorkspaces));
+ },
+
+ _nWorkspacesChanged: function() {
+ let oldNumWorkspaces = this._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++)
+ this._workspaces[w] = global.screen.get_workspace_by_index(w);
+
+ for (w = oldNumWorkspaces; w < newNumWorkspaces; w++) {
+ let workspace = this._workspaces[w];
+ workspace._windowAddedId = workspace.connect('window-added', Lang.bind(this,
this._queueCheckWorkspaces));
+ workspace._windowRemovedId = workspace.connect('window-removed', Lang.bind(this,
this._windowRemoved));
+ }
+
+ } 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 (this._workspaces[w] != workspace) {
+ removedIndex = w;
+ break;
+ }
+ }
+
+ let lostWorkspaces = this._workspaces.splice(removedIndex, removedNum);
+ lostWorkspaces.forEach(function(workspace) {
+ workspace.disconnect(workspace._windowAddedId);
+ workspace.disconnect(workspace._windowRemovedId);
+ });
+ }
+
+ this._queueCheckWorkspaces();
+
+ return false;
+ }
+});
+
const WindowManager = new Lang.Class({
Name: 'WindowManager',
@@ -268,6 +472,8 @@ const WindowManager = new Lang.Class({
for (let i = 0; i < this._dimmedWindows.length; i++)
this._dimWindow(this._dimmedWindows[i]);
}));
+
+ this._workspaceTracker = new WorkspaceTracker(this);
},
setCustomKeybindingHandler: function(name, modes, handler) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]