2012-05-16 22:26:44 +00:00
|
|
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
|
|
|
|
2023-07-10 09:53:00 +00:00
|
|
|
import GLib from 'gi://GLib';
|
|
|
|
import * as Signals from '../misc/signals.js';
|
2012-05-16 22:26:44 +00:00
|
|
|
|
2023-07-10 09:53:00 +00:00
|
|
|
import * as FileUtils from '../misc/fileUtils.js';
|
|
|
|
import * as Params from '../misc/params.js';
|
|
|
|
|
|
|
|
import {LoginDialog} from '../gdm/loginDialog.js';
|
|
|
|
import {UnlockDialog} from '../ui/unlockDialog.js';
|
2012-05-16 22:26:44 +00:00
|
|
|
|
2023-08-07 15:30:22 +00:00
|
|
|
import * as Config from '../misc/config.js';
|
2014-02-11 22:20:15 +00:00
|
|
|
|
2012-09-04 01:26:37 +00:00
|
|
|
const DEFAULT_MODE = 'restrictive';
|
2012-05-16 22:26:44 +00:00
|
|
|
|
2020-03-27 13:18:34 +00:00
|
|
|
const USER_SESSION_COMPONENTS = [
|
|
|
|
'polkitAgent', 'telepathyClient', 'keyring',
|
|
|
|
'autorunManager', 'automountManager',
|
|
|
|
];
|
|
|
|
|
|
|
|
if (Config.HAVE_NETWORKMANAGER)
|
|
|
|
USER_SESSION_COMPONENTS.push('networkAgent');
|
|
|
|
|
2012-05-16 22:26:44 +00:00
|
|
|
const _modes = {
|
2012-09-04 01:26:37 +00:00
|
|
|
'restrictive': {
|
2012-11-29 19:42:38 +00:00
|
|
|
parentMode: null,
|
2022-06-03 15:21:08 +00:00
|
|
|
stylesheetName: 'gnome-shell.css',
|
|
|
|
colorScheme: 'prefer-dark',
|
2020-03-03 09:05:54 +00:00
|
|
|
themeResourceName: 'gnome-shell-theme.gresource',
|
2012-09-04 01:23:22 +00:00
|
|
|
hasOverview: false,
|
|
|
|
showCalendarEvents: false,
|
2021-04-05 17:36:29 +00:00
|
|
|
showWelcomeDialog: false,
|
2012-09-04 01:23:22 +00:00
|
|
|
allowSettings: false,
|
2013-07-18 01:22:54 +00:00
|
|
|
allowScreencast: false,
|
2012-11-29 15:09:21 +00:00
|
|
|
enabledExtensions: [],
|
2012-09-04 01:23:22 +00:00
|
|
|
hasRunDialog: false,
|
|
|
|
hasWorkspaces: false,
|
|
|
|
hasWindows: false,
|
2012-08-26 14:53:08 +00:00
|
|
|
hasNotifications: false,
|
2017-06-03 22:37:36 +00:00
|
|
|
hasWmMenus: false,
|
2012-09-04 01:26:37 +00:00
|
|
|
isLocked: false,
|
2012-09-04 17:28:19 +00:00
|
|
|
isGreeter: false,
|
2012-09-06 11:21:12 +00:00
|
|
|
isPrimary: false,
|
2012-09-04 17:28:19 +00:00
|
|
|
unlockDialog: null,
|
2012-09-04 01:23:22 +00:00
|
|
|
components: [],
|
2012-09-04 01:26:37 +00:00
|
|
|
panel: {
|
|
|
|
left: [],
|
|
|
|
center: [],
|
2019-08-20 21:43:54 +00:00
|
|
|
right: [],
|
2012-09-04 01:26:37 +00:00
|
|
|
},
|
2019-08-20 21:43:54 +00:00
|
|
|
panelStyle: null,
|
2012-09-04 01:26:37 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
'gdm': {
|
2012-08-26 14:53:08 +00:00
|
|
|
hasNotifications: true,
|
2012-09-04 17:28:19 +00:00
|
|
|
isGreeter: true,
|
2012-09-06 11:21:12 +00:00
|
|
|
isPrimary: true,
|
2023-07-10 09:53:00 +00:00
|
|
|
unlockDialog: LoginDialog,
|
2021-06-10 21:12:27 +00:00
|
|
|
components: Config.HAVE_NETWORKMANAGER
|
|
|
|
? ['networkAgent', 'polkitAgent']
|
|
|
|
: ['polkitAgent'],
|
2012-09-04 01:23:22 +00:00
|
|
|
panel: {
|
2013-03-23 00:29:23 +00:00
|
|
|
left: [],
|
2012-09-04 01:23:22 +00:00
|
|
|
center: ['dateMenu'],
|
2022-08-03 04:11:33 +00:00
|
|
|
right: ['dwellClick', 'a11y', 'keyboard', 'quickSettings'],
|
2012-09-21 20:19:27 +00:00
|
|
|
},
|
2019-08-20 21:43:54 +00:00
|
|
|
panelStyle: 'login-screen',
|
2012-09-04 01:23:22 +00:00
|
|
|
},
|
2012-05-16 22:26:44 +00:00
|
|
|
|
2012-08-26 14:53:08 +00:00
|
|
|
'unlock-dialog': {
|
|
|
|
isLocked: true,
|
|
|
|
unlockDialog: undefined,
|
2012-09-20 06:53:20 +00:00
|
|
|
components: ['polkitAgent', 'telepathyClient'],
|
2012-08-26 14:53:08 +00:00
|
|
|
panel: {
|
2013-05-22 18:46:47 +00:00
|
|
|
left: [],
|
2012-08-26 14:53:08 +00:00
|
|
|
center: [],
|
2022-08-03 04:11:33 +00:00
|
|
|
right: ['dwellClick', 'a11y', 'keyboard', 'quickSettings'],
|
2012-08-26 14:53:08 +00:00
|
|
|
},
|
2019-08-20 21:43:54 +00:00
|
|
|
panelStyle: 'unlock-screen',
|
2012-08-26 14:53:08 +00:00
|
|
|
},
|
|
|
|
|
2012-09-04 01:23:22 +00:00
|
|
|
'user': {
|
|
|
|
hasOverview: true,
|
2021-12-03 19:04:05 +00:00
|
|
|
showCalendarEvents: false,
|
2021-04-05 17:36:29 +00:00
|
|
|
showWelcomeDialog: true,
|
2012-09-04 01:23:22 +00:00
|
|
|
allowSettings: true,
|
2013-07-18 01:22:54 +00:00
|
|
|
allowScreencast: true,
|
2012-09-04 01:23:22 +00:00
|
|
|
hasRunDialog: true,
|
|
|
|
hasWorkspaces: true,
|
|
|
|
hasWindows: true,
|
2017-06-03 22:37:36 +00:00
|
|
|
hasWmMenus: true,
|
2012-08-26 14:53:08 +00:00
|
|
|
hasNotifications: true,
|
2012-09-04 17:28:19 +00:00
|
|
|
isLocked: false,
|
2012-09-06 11:21:12 +00:00
|
|
|
isPrimary: true,
|
2023-07-10 09:53:00 +00:00
|
|
|
unlockDialog: UnlockDialog,
|
2020-03-27 13:18:34 +00:00
|
|
|
components: USER_SESSION_COMPONENTS,
|
2012-09-04 01:23:22 +00:00
|
|
|
panel: {
|
2023-01-23 15:22:03 +00:00
|
|
|
left: ['activities'],
|
2012-09-04 01:23:22 +00:00
|
|
|
center: ['dateMenu'],
|
2022-08-03 04:11:33 +00:00
|
|
|
right: ['screenRecording', 'screenSharing', 'dwellClick', 'a11y', 'keyboard', 'quickSettings'],
|
2019-08-20 21:43:54 +00:00
|
|
|
},
|
|
|
|
},
|
2012-05-16 22:26:44 +00:00
|
|
|
};
|
|
|
|
|
2013-11-04 15:07:44 +00:00
|
|
|
function _loadMode(file, info) {
|
2012-11-29 17:20:43 +00:00
|
|
|
let name = info.get_name();
|
|
|
|
let suffix = name.indexOf('.json');
|
2023-08-07 00:51:19 +00:00
|
|
|
let modeName = suffix === -1 ? name : name.slice(name, suffix);
|
2012-11-29 17:20:43 +00:00
|
|
|
|
2019-06-29 23:05:27 +00:00
|
|
|
if (Object.prototype.hasOwnProperty.call(_modes, modeName))
|
2012-11-29 17:20:43 +00:00
|
|
|
return;
|
|
|
|
|
2019-01-31 14:08:00 +00:00
|
|
|
let fileContent, success_, newMode;
|
2012-11-28 20:14:21 +00:00
|
|
|
try {
|
2019-01-31 14:08:00 +00:00
|
|
|
[success_, fileContent] = file.load_contents(null);
|
2021-08-12 14:38:57 +00:00
|
|
|
const decoder = new TextDecoder();
|
|
|
|
newMode = JSON.parse(decoder.decode(fileContent));
|
2019-01-29 01:26:39 +00:00
|
|
|
} catch (e) {
|
2012-11-28 20:14:21 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-11-04 15:07:44 +00:00
|
|
|
_modes[modeName] = {};
|
2020-08-04 08:39:29 +00:00
|
|
|
const excludedProps = ['unlockDialog'];
|
2013-12-06 20:25:15 +00:00
|
|
|
for (let prop in _modes[DEFAULT_MODE]) {
|
2012-11-29 17:20:43 +00:00
|
|
|
if (newMode[prop] !== undefined &&
|
2020-08-04 08:39:29 +00:00
|
|
|
!excludedProps.includes(prop))
|
2013-12-06 20:25:15 +00:00
|
|
|
_modes[modeName][prop] = newMode[prop];
|
2012-11-28 20:14:21 +00:00
|
|
|
}
|
2013-11-04 15:07:44 +00:00
|
|
|
_modes[modeName]['isPrimary'] = true;
|
|
|
|
}
|
|
|
|
|
2022-11-30 02:17:20 +00:00
|
|
|
/**
|
|
|
|
* Loads external session modes from the system data directories.
|
|
|
|
*/
|
2013-12-06 20:28:23 +00:00
|
|
|
function _loadModes() {
|
2022-11-30 02:17:20 +00:00
|
|
|
for (const {dir, info} of FileUtils.collectFromDatadirs('modes', false))
|
|
|
|
_loadMode(dir, info);
|
2012-11-28 20:14:21 +00:00
|
|
|
}
|
|
|
|
|
2023-07-10 09:53:00 +00:00
|
|
|
export function listModes() {
|
2013-12-06 20:28:23 +00:00
|
|
|
_loadModes();
|
2019-08-19 18:50:33 +00:00
|
|
|
let loop = new GLib.MainLoop(null, false);
|
|
|
|
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
|
2013-12-06 20:28:23 +00:00
|
|
|
let names = Object.getOwnPropertyNames(_modes);
|
2019-08-20 00:51:42 +00:00
|
|
|
for (let i = 0; i < names.length; i++) {
|
2012-11-29 17:20:43 +00:00
|
|
|
if (_modes[names[i]].isPrimary)
|
|
|
|
print(names[i]);
|
2019-08-20 00:51:42 +00:00
|
|
|
}
|
2019-08-19 18:50:33 +00:00
|
|
|
loop.quit();
|
2012-11-29 17:20:43 +00:00
|
|
|
});
|
2014-04-10 17:26:52 +00:00
|
|
|
GLib.Source.set_name_by_id(id, '[gnome-shell] listModes');
|
2019-08-19 18:50:33 +00:00
|
|
|
loop.run();
|
2012-05-18 01:52:57 +00:00
|
|
|
}
|
|
|
|
|
2023-07-10 09:53:00 +00:00
|
|
|
export class SessionMode extends Signals.EventEmitter {
|
2017-10-31 01:19:44 +00:00
|
|
|
constructor() {
|
2022-07-04 22:30:44 +00:00
|
|
|
super();
|
|
|
|
|
2013-12-06 20:31:46 +00:00
|
|
|
_loadModes();
|
2019-08-19 19:38:51 +00:00
|
|
|
let isPrimary = _modes[global.session_mode] &&
|
|
|
|
_modes[global.session_mode].isPrimary;
|
2013-11-04 15:07:44 +00:00
|
|
|
let mode = isPrimary ? global.session_mode : 'user';
|
|
|
|
this._modeStack = [mode];
|
|
|
|
this._sync();
|
2017-10-31 01:19:44 +00:00
|
|
|
}
|
2012-09-01 12:42:53 +00:00
|
|
|
|
2017-10-31 00:03:21 +00:00
|
|
|
pushMode(mode) {
|
2022-08-09 10:52:58 +00:00
|
|
|
console.debug(`sessionMode: Pushing mode ${mode}`);
|
2012-09-01 12:42:53 +00:00
|
|
|
this._modeStack.push(mode);
|
|
|
|
this._sync();
|
2017-10-31 01:19:44 +00:00
|
|
|
}
|
2012-09-01 12:42:53 +00:00
|
|
|
|
2017-10-31 00:03:21 +00:00
|
|
|
popMode(mode) {
|
2023-08-07 00:51:19 +00:00
|
|
|
if (this.currentMode !== mode || this._modeStack.length === 1)
|
2023-08-06 22:34:20 +00:00
|
|
|
throw new Error('Invalid SessionMode.popMode');
|
2022-08-09 10:52:58 +00:00
|
|
|
|
|
|
|
console.debug(`sessionMode: Popping mode ${mode}`);
|
2012-09-01 12:42:53 +00:00
|
|
|
this._modeStack.pop();
|
|
|
|
this._sync();
|
2017-10-31 01:19:44 +00:00
|
|
|
}
|
2012-09-01 12:42:53 +00:00
|
|
|
|
2017-10-31 00:03:21 +00:00
|
|
|
switchMode(to) {
|
2023-08-07 00:51:19 +00:00
|
|
|
if (this.currentMode === to)
|
2012-08-26 14:53:08 +00:00
|
|
|
return;
|
|
|
|
this._modeStack[this._modeStack.length - 1] = to;
|
|
|
|
this._sync();
|
2017-10-31 01:19:44 +00:00
|
|
|
}
|
2012-08-26 14:53:08 +00:00
|
|
|
|
2012-09-01 12:42:53 +00:00
|
|
|
get currentMode() {
|
|
|
|
return this._modeStack[this._modeStack.length - 1];
|
2017-10-31 01:19:44 +00:00
|
|
|
}
|
2012-05-16 22:26:44 +00:00
|
|
|
|
2017-10-31 00:03:21 +00:00
|
|
|
_sync() {
|
2013-11-04 15:07:44 +00:00
|
|
|
let params = _modes[this.currentMode];
|
2012-11-29 19:42:38 +00:00
|
|
|
let defaults;
|
2019-08-20 00:51:42 +00:00
|
|
|
if (params.parentMode) {
|
2023-08-06 23:45:22 +00:00
|
|
|
defaults = Params.parse(
|
|
|
|
_modes[params.parentMode],
|
|
|
|
_modes[DEFAULT_MODE]);
|
2019-08-20 00:51:42 +00:00
|
|
|
} else {
|
2013-11-04 15:07:44 +00:00
|
|
|
defaults = _modes[DEFAULT_MODE];
|
2019-08-20 00:51:42 +00:00
|
|
|
}
|
2012-11-29 19:42:38 +00:00
|
|
|
params = Params.parse(params, defaults);
|
2012-05-17 13:50:51 +00:00
|
|
|
|
2012-09-04 17:28:19 +00:00
|
|
|
// 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];
|
|
|
|
}
|
2012-05-17 13:50:51 +00:00
|
|
|
|
2012-09-01 12:42:53 +00:00
|
|
|
this.emit('updated');
|
2012-09-04 17:28:19 +00:00
|
|
|
}
|
2023-07-10 09:53:00 +00:00
|
|
|
}
|