gnome-shell/js/ui/sessionMode.js
Florian Müllner 111e982eb7 sessionMode: Log mode changes
Now that console.debug() makes it easy to log message with DEBUG
priority, we can be a lot more generous with logging without
spamming logs (by default).

Those turned out useful in figuring out the issue in the next
commit, so let's keep them.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2413>
2022-08-10 16:31:42 +00:00

207 lines
5.8 KiB
JavaScript

// -*- 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', 'aggregateMenu'],
},
panelStyle: 'login-screen',
},
'unlock-dialog': {
isLocked: true,
unlockDialog: undefined,
components: ['polkitAgent', 'telepathyClient'],
panel: {
left: [],
center: [],
right: ['dwellClick', 'a11y', 'keyboard', 'quickSettings', 'aggregateMenu'],
},
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', 'aggregateMenu'],
},
},
};
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');
}
};