summaryrefslogtreecommitdiff
path: root/raveos-theme/gnome/theme-data/extensions/installed/ShutdownTimer@deminder/dbus-service/action.js
diff options
context:
space:
mode:
authornippy <you@example.com>2026-04-18 13:49:56 +0200
committernippy <you@example.com>2026-04-18 13:49:56 +0200
commit5d94c0a7d44a2255b81815a52a7056a94a39842d (patch)
tree759bdea9645c6a62f9e1e4c001f7d81cccd120d2 /raveos-theme/gnome/theme-data/extensions/installed/ShutdownTimer@deminder/dbus-service/action.js
parente79cdf210b267f21a186255ce1a4d50029439d54 (diff)
downloadRaveOS-PKGBUILD-5d94c0a7d44a2255b81815a52a7056a94a39842d.tar.gz
RaveOS-PKGBUILD-5d94c0a7d44a2255b81815a52a7056a94a39842d.zip
update Raveos themes
Diffstat (limited to 'raveos-theme/gnome/theme-data/extensions/installed/ShutdownTimer@deminder/dbus-service/action.js')
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/ShutdownTimer@deminder/dbus-service/action.js217
1 files changed, 217 insertions, 0 deletions
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/ShutdownTimer@deminder/dbus-service/action.js b/raveos-theme/gnome/theme-data/extensions/installed/ShutdownTimer@deminder/dbus-service/action.js
new file mode 100644
index 0000000..4b5bf9f
--- /dev/null
+++ b/raveos-theme/gnome/theme-data/extensions/installed/ShutdownTimer@deminder/dbus-service/action.js
@@ -0,0 +1,217 @@
+// SPDX-FileCopyrightText: 2023 Deminder <tremminder@gmail.com>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+import Gio from 'gi://Gio';
+import * as Control from './control.js';
+import { proxyPromise } from '../modules/util.js';
+import { pgettext as C_, gettext as _ } from '../modules/translation.js';
+import { logDebug } from '../modules/util.js';
+
+export const ACTIONS = {
+ PowerOff: 0,
+ Reboot: 1,
+ Suspend: 2,
+ SuspendThenHibernate: 3,
+ Hibernate: 4,
+ HybridSleep: 5,
+ Halt: 6,
+};
+
+export const WAKE_ACTIONS = { wake: 100, 'no-wake': 101 };
+
+/**
+ * Get supported actions.
+ * In order to show an error when shutdown or reboot are not supported
+ * they are always included here. */
+export async function* supportedActions() {
+ const actionDbus = new Action();
+ for await (const action of Object.keys(ACTIONS).map(async a =>
+ ['PowerOff', 'Reboot'].includes(a) ||
+ (await actionDbus.canShutdownAction(a))
+ ? a
+ : null
+ )) {
+ if (action) {
+ yield action;
+ }
+ }
+}
+
+export class UnsupportedActionError extends Error {}
+
+export class Action {
+ #cancellable = new Gio.Cancellable();
+ #cookie = null;
+
+ #loginProxy = proxyPromise(
+ 'org.freedesktop.login1.Manager',
+ Gio.DBus.system,
+ 'org.freedesktop.login1',
+ '/org/freedesktop/login1',
+ this.#cancellable
+ );
+
+ #screenSaverProxy = proxyPromise(
+ 'org.gnome.ScreenSaver',
+ Gio.DBus.session,
+ 'org.gnome.ScreenSaver',
+ '/org/gnome/ScreenSaver',
+ this.#cancellable
+ );
+
+ #sessionProxy = proxyPromise(
+ 'org.gnome.SessionManager',
+ Gio.DBus.session,
+ 'org.gnome.SessionManager',
+ '/org/gnome/SessionManager',
+ this.#cancellable
+ );
+
+ destroy() {
+ if (this.#cancellable !== null) {
+ this.#cancellable.cancel();
+ this.#cancellable = null;
+ }
+ }
+
+ #poweroffOrReboot(action) {
+ return [ACTIONS.PowerOff, ACTIONS.Reboot].includes(ACTIONS[action]);
+ }
+
+ /**
+ * Perform the shutdown action.
+ *
+ * @param {string} action the shutdown action
+ * @param {boolean} showEndSessionDialog show the end session dialog or directly shutdown
+ *
+ * @returns {Promise} resolves on action completion
+ */
+ async shutdownAction(action, showEndSessionDialog) {
+ if (!(action in ACTIONS))
+ throw new Error(`Unknown shutdown action: ${action}`);
+ logDebug('[shutdownAction]', action);
+
+ await this.uninhibitSuspend();
+
+ const screenSaverProxy = await this.#screenSaverProxy;
+ const [screenSaverActive] = await screenSaverProxy.GetActiveAsync();
+ if (
+ showEndSessionDialog &&
+ !screenSaverActive &&
+ this.#poweroffOrReboot(action)
+ ) {
+ const sessionProxy = await this.#sessionProxy;
+ if (action === 'PowerOff') {
+ await sessionProxy.ShutdownAsync();
+ } else {
+ await sessionProxy.RebootAsync();
+ }
+ } else {
+ const loginProxy = await this.#loginProxy;
+ if (await this.canShutdownAction(action)) {
+ await loginProxy[`${action}Async`](true);
+ } else if (this.#poweroffOrReboot(action)) {
+ await Control.shutdown('now', ACTIONS[action] === ACTIONS.Reboot);
+ } else {
+ throw new UnsupportedActionError();
+ }
+ }
+ }
+
+ /**
+ * Check if a shutdown action can be performed (without authentication).
+ *
+ * @returns {Promise} resolves to `true` if action can be performed, otherwise `false`.
+ */
+ async canShutdownAction(action) {
+ const loginProxy = await this.#loginProxy;
+ if (!(action in ACTIONS))
+ throw new Error(`Unknown shutdown action: ${action}`);
+ const [result] = await loginProxy[`Can${action}Async`]();
+ return result === 'yes';
+ }
+
+ /**
+ * Schedule a wake after some minutes or cancel
+ *
+ * @param {boolean} wake
+ * @param {number} minutes
+ */
+ async wakeAction(wake, minutes) {
+ if (wake) {
+ await Control.wake(minutes);
+ } else {
+ await Control.wakeCancel();
+ }
+ }
+
+ async inhibitSuspend() {
+ if (this.#cookie === null) {
+ const sessionProxy = await this.#sessionProxy;
+ const [cookie] = await sessionProxy.InhibitAsync(
+ 'user',
+ 0,
+ 'Inhibit by Shutdown Timer (GNOME-Shell extension)',
+ /* Suspend flag */ 4
+ );
+ this.#cookie = cookie;
+ }
+ }
+
+ async uninhibitSuspend() {
+ if (this.#cookie !== null) {
+ const sessionProxy = await this.#sessionProxy;
+ await sessionProxy.UninhibitAsync(this.#cookie);
+ this.#cookie = null;
+ }
+ }
+}
+
+/**
+ * Get the translated action label
+ *
+ * @param action
+ */
+export function actionLabel(action) {
+ return {
+ SuspendThenHibernate: _('Suspend then Hibernate'),
+ HybridSleep: _('Hybrid Sleep'),
+ Hibernate: _('Hibernate'),
+ Halt: _('Halt'),
+ Suspend: _('Suspend'),
+ PowerOff: _('Power Off'),
+ Reboot: _('Restart'),
+ wake: _('Wake'),
+ 'no-wake': _('No Wake'),
+ }[action];
+}
+
+export function untilText(action) {
+ return {
+ SuspendThenHibernate: C_('untiltext', 'suspend and hibernate'),
+ HybridSleep: C_('untiltext', 'hybrid sleep'),
+ Hibernate: C_('untiltext', 'hibernate'),
+ Halt: C_('untiltext', 'halt'),
+ Suspend: C_('untiltext', 'suspend'),
+ PowerOff: C_('untiltext', 'shutdown'),
+ Reboot: C_('untiltext', 'reboot'),
+ wake: C_('untiltext', 'wakeup'),
+ }[action];
+}
+
+export function mapLegacyAction(action) {
+ return action in ACTIONS || ['wake', ''].includes(action)
+ ? action
+ : {
+ poweroff: 'PowerOff',
+ shutdown: 'PowerOff',
+ reboot: 'Reboot',
+ suspend: 'Suspend',
+ }[action] ??
+ {
+ p: 'PowerOff',
+ r: 'Reboot',
+ s: 'Suspend',
+ h: 'SuspendThenHibernate',
+ }[action[0].toLowerCase()];
+}