Session Modes
WARNING
This documentation is for GNOME 45 and later. Please see the Legacy Documentation for previous versions.
Session modes are environment states of GNOME Shell. For example, when a user is logged in and using their desktop the Shell is in the user
mode.
Since GNOME 42, extensions have the option of operating in other session modes, such as the unlock-dialog
mode when the screen is locked. For more details, see the session-modes
documentation.
Example Usage
Here is an example of a metadata.json
for an extension that can run in the regular user
mode and continue running in the unlock-dialog
mode, when the screen is locked. Pay attention that the shell may use custom user modes that are not named user
, so we need to ensure this by also checking the parent mode.
{
"uuid": "session-modes@gjs.guide",
"name": "Session Modes Example",
"description": "This is an example of using session modes in an extension.",
"shell-version": [ "45" ],
"session-modes": ["user", "unlock-dialog"],
"url": "https://gjs.guide/extensions/topics/session-modes"
}
2
3
4
5
6
7
8
Like standard extensions, the extension will be enabled when the user logs in and logs out, but won't be disabled when the screen locks.
Extensions that continue running on the lock screen will usually want to disable UI elements when the session is locked, while continuing to operate in the background.
import GLib from 'gi://GLib';
import St from 'gi://St';
import {Extension} from 'resource:///org/gnome/shell/extensions/extension.js';
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
import * as PanelMenu from 'resource:///org/gnome/shell/ui/panelMenu.js';
export default class ExampleExtension extends Extension {
constructor(metadata) {
super(metadata);
this._indicator = null;
this._timeoutId = null;
this._sessionId = null;
}
_addIndicator() {
if (this._indicator === null) {
this._indicator = new PanelMenu.Button(0.0, 'Remindicator', false);
const icon = new St.Icon({
icon_name: 'preferences-system-time-symbolic',
style_class: 'system-status-icon',
});
this._indicator.add_child(icon);
Main.panel.addToStatusArea('Remindicator', this._indicator);
}
}
_removeIndicator() {
if (this._indicator) {
this._indicator.destroy();
this._indicator = null;
}
}
// When the session mode changes, we will either add or remove our indicator
// so it is not visible on the lock screen.
_onSessionModeChanged(session) {
if (session.currentMode === 'user' || session.parentMode === 'user')
this._addIndicator();
else if (session.currentMode === 'unlock-dialog')
this._removeIndicator();
}
// Our extension will be enabled when the user logs in
enable() {
// Watch for changes to the session mode
this._sessionId = Main.sessionMode.connect('updated',
this._onSessionModeChanged.bind(this));
// Show a notification every hour
this._timeoutId = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT,
60 * 60, () => {
Main.notify('Reminder', 'An hour has passed!');
return GLib.SOURCE_CONTINUE;
});
this._addIndicator();
}
// Our extension will only be disabled when the user logs out
disable() {
if (this._timeoutId) {
GLib.Source.remove(this._timeoutId);
this._timeoutId = null;
}
if (this._sessionId) {
Main.sessionMode.disconnect(this._sessionId);
this._sessionId = null;
}
this._removeIndicator();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79