[gnome-shell] main: Move workspace tracking code to WindowManager



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]