summaryrefslogtreecommitdiffstats
path: root/js/ui/sessionMode.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/ui/sessionMode.js')
-rw-r--r--js/ui/sessionMode.js206
1 files changed, 206 insertions, 0 deletions
diff --git a/js/ui/sessionMode.js b/js/ui/sessionMode.js
new file mode 100644
index 0000000..b38bcdf
--- /dev/null
+++ b/js/ui/sessionMode.js
@@ -0,0 +1,206 @@
+// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
+/* exported SessionMode, listModes */
+
+const GLib = imports.gi.GLib;
+const Signals = imports.misc.signals;
+
+const FileUtils = imports.misc.fileUtils;
+const Params = imports.misc.params;
+
+const Config = imports.misc.config;
+
+const DEFAULT_MODE = 'restrictive';
+
+const USER_SESSION_COMPONENTS = [
+ 'polkitAgent', 'telepathyClient', 'keyring',
+ 'autorunManager', 'automountManager',
+];
+
+if (Config.HAVE_NETWORKMANAGER)
+ USER_SESSION_COMPONENTS.push('networkAgent');
+
+const _modes = {
+ 'restrictive': {
+ parentMode: null,
+ stylesheetName: 'gnome-shell.css',
+ themeResourceName: 'gnome-shell-theme.gresource',
+ hasOverview: false,
+ showCalendarEvents: false,
+ showWelcomeDialog: false,
+ allowSettings: false,
+ allowScreencast: false,
+ enabledExtensions: [],
+ hasRunDialog: false,
+ hasWorkspaces: false,
+ hasWindows: false,
+ hasNotifications: false,
+ hasWmMenus: false,
+ isLocked: false,
+ isGreeter: false,
+ isPrimary: false,
+ unlockDialog: null,
+ components: [],
+ panel: {
+ left: [],
+ center: [],
+ right: [],
+ },
+ panelStyle: null,
+ },
+
+ 'gdm': {
+ hasNotifications: true,
+ isGreeter: true,
+ isPrimary: true,
+ unlockDialog: imports.gdm.loginDialog.LoginDialog,
+ components: Config.HAVE_NETWORKMANAGER
+ ? ['networkAgent', 'polkitAgent']
+ : ['polkitAgent'],
+ panel: {
+ left: [],
+ center: ['dateMenu'],
+ right: ['dwellClick', 'a11y', 'keyboard', 'quickSettings'],
+ },
+ panelStyle: 'login-screen',
+ },
+
+ 'unlock-dialog': {
+ isLocked: true,
+ unlockDialog: undefined,
+ components: ['polkitAgent', 'telepathyClient'],
+ panel: {
+ left: [],
+ center: [],
+ right: ['dwellClick', 'a11y', 'keyboard', 'quickSettings'],
+ },
+ panelStyle: 'unlock-screen',
+ },
+
+ 'user': {
+ hasOverview: true,
+ showCalendarEvents: true,
+ showWelcomeDialog: true,
+ allowSettings: true,
+ allowScreencast: true,
+ hasRunDialog: true,
+ hasWorkspaces: true,
+ hasWindows: true,
+ hasWmMenus: true,
+ hasNotifications: true,
+ isLocked: false,
+ isPrimary: true,
+ unlockDialog: imports.ui.unlockDialog.UnlockDialog,
+ components: USER_SESSION_COMPONENTS,
+ panel: {
+ left: ['activities', 'appMenu'],
+ center: ['dateMenu'],
+ right: ['screenRecording', 'screenSharing', 'dwellClick', 'a11y', 'keyboard', 'quickSettings'],
+ },
+ },
+};
+
+function _loadMode(file, info) {
+ let name = info.get_name();
+ let suffix = name.indexOf('.json');
+ let modeName = suffix == -1 ? name : name.slice(name, suffix);
+
+ if (Object.prototype.hasOwnProperty.call(_modes, modeName))
+ return;
+
+ let fileContent, success_, newMode;
+ try {
+ [success_, fileContent] = file.load_contents(null);
+ const decoder = new TextDecoder();
+ newMode = JSON.parse(decoder.decode(fileContent));
+ } catch (e) {
+ return;
+ }
+
+ _modes[modeName] = {};
+ const excludedProps = ['unlockDialog'];
+ for (let prop in _modes[DEFAULT_MODE]) {
+ if (newMode[prop] !== undefined &&
+ !excludedProps.includes(prop))
+ _modes[modeName][prop] = newMode[prop];
+ }
+ _modes[modeName]['isPrimary'] = true;
+}
+
+function _loadModes() {
+ FileUtils.collectFromDatadirs('modes', false, _loadMode);
+}
+
+function listModes() {
+ _loadModes();
+ let loop = new GLib.MainLoop(null, false);
+ let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
+ let names = Object.getOwnPropertyNames(_modes);
+ for (let i = 0; i < names.length; i++) {
+ if (_modes[names[i]].isPrimary)
+ print(names[i]);
+ }
+ loop.quit();
+ });
+ GLib.Source.set_name_by_id(id, '[gnome-shell] listModes');
+ loop.run();
+}
+
+var SessionMode = class extends Signals.EventEmitter {
+ constructor() {
+ super();
+
+ _loadModes();
+ let isPrimary = _modes[global.session_mode] &&
+ _modes[global.session_mode].isPrimary;
+ let mode = isPrimary ? global.session_mode : 'user';
+ this._modeStack = [mode];
+ this._sync();
+ }
+
+ pushMode(mode) {
+ console.debug(`sessionMode: Pushing mode ${mode}`);
+ this._modeStack.push(mode);
+ this._sync();
+ }
+
+ popMode(mode) {
+ if (this.currentMode != mode || this._modeStack.length === 1)
+ throw new Error("Invalid SessionMode.popMode");
+
+ console.debug(`sessionMode: Popping mode ${mode}`);
+ this._modeStack.pop();
+ this._sync();
+ }
+
+ switchMode(to) {
+ if (this.currentMode == to)
+ return;
+ this._modeStack[this._modeStack.length - 1] = to;
+ this._sync();
+ }
+
+ get currentMode() {
+ return this._modeStack[this._modeStack.length - 1];
+ }
+
+ _sync() {
+ let params = _modes[this.currentMode];
+ let defaults;
+ if (params.parentMode) {
+ defaults = Params.parse(_modes[params.parentMode],
+ _modes[DEFAULT_MODE]);
+ } else {
+ defaults = _modes[DEFAULT_MODE];
+ }
+ params = Params.parse(params, defaults);
+
+ // A simplified version of Lang.copyProperties, handles
+ // undefined as a special case for "no change / inherit from previous mode"
+ for (let prop in params) {
+ if (params[prop] !== undefined)
+ this[prop] = params[prop];
+ }
+
+ this.emit('updated');
+ }
+};