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 in the unlock-dialog
mode (when the screen is locked).
{
"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"
}
Be aware that when the session mode changes between user
and unlock-dialog
, GNOME Shell may call disable()
and enable()
on extensions. Extensions should be prepared to handle disable()
being called at any time.
Extensions that continue running on the lock screen may want to disable UI elements when the session is locked, while continuing to operate in the background. Note that GNOME Shell may use custom user modes other than user
, so the parent mode must be checked as well.
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();
}
enable() {
// Ensure we take the correct action for the current session mode
this._onSessionModeChanged(Main.sessionMode);
// 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;
});
}
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();
}
}