summaryrefslogtreecommitdiff
path: root/raveos-gnome-theme/theme-data/extensions/installed/ShutdownTimer@deminder/prefs.js
diff options
context:
space:
mode:
Diffstat (limited to 'raveos-gnome-theme/theme-data/extensions/installed/ShutdownTimer@deminder/prefs.js')
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/ShutdownTimer@deminder/prefs.js240
1 files changed, 240 insertions, 0 deletions
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/ShutdownTimer@deminder/prefs.js b/raveos-gnome-theme/theme-data/extensions/installed/ShutdownTimer@deminder/prefs.js
new file mode 100644
index 0000000..9914fd2
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/ShutdownTimer@deminder/prefs.js
@@ -0,0 +1,240 @@
+// SPDX-FileCopyrightText: 2023 Deminder <tremminder@gmail.com>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+import Gtk from 'gi://Gtk';
+import Gio from 'gi://Gio';
+
+import { ExtensionPreferences } from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js';
+
+import { Install } from './modules/install.js';
+import {
+ actionLabel,
+ ACTIONS,
+ mapLegacyAction,
+ supportedActions,
+} from './dbus-service/action.js';
+import { logDebug, Idle } from './modules/util.js';
+
+const templateComponents = {
+ shutdown: {
+ 'shutdown-mode': 'combo',
+ 'root-mode': 'switch',
+ 'show-end-session-dialog': 'switch',
+ 'shutdown-max-timer': 'adjustment',
+ 'shutdown-ref-timer': 'buffer',
+ 'shutdown-slider': 'adjustment',
+ 'nonlinear-shutdown-slider': 'adjustment',
+ },
+ wake: {
+ 'auto-wake': 'switch',
+ 'wake-max-timer': 'adjustment',
+ 'wake-ref-timer': 'buffer',
+ 'wake-slider': 'adjustment',
+ 'nonlinear-wake-slider': 'adjustment',
+ },
+ display: {
+ 'show-settings': 'switch',
+ 'show-shutdown-mode': 'buffer',
+ 'show-shutdown-slider': 'switch',
+ 'show-shutdown-indicator': 'switch',
+ 'show-shutdown-absolute-timer': 'switch',
+ 'show-textboxes': 'switch',
+ 'show-wake-slider': 'switch',
+ 'show-wake-items': 'switch',
+ 'show-wake-absolute-timer': 'switch',
+ },
+};
+
+export default class ShutdownTimerPreferences extends ExtensionPreferences {
+ /**
+ * Fill the preferences window with preferences.
+ *
+ * The default implementation adds the widget
+ * returned by getPreferencesWidget().
+ *
+ * @param {Adw.PreferencesWindow} window - the preferences window
+ */
+ fillPreferencesWindow(window) {
+ const builder = Gtk.Builder.new();
+ builder.add_from_file(
+ this.dir.get_child('ui').get_child('prefs.ui').get_path()
+ );
+
+ const settings = this.getSettings();
+ const handlers = [];
+ const pageNames = ['install', 'shutdown', 'wake', 'display'].map(
+ n => `shutdowntimer-prefs-${n}`
+ );
+ for (const name of pageNames) {
+ const pageId = name.replaceAll('-', '_');
+ const page = builder.get_object(pageId);
+ const pageName = pageId.split('_').at(-1);
+ if (!page) {
+ throw new Error(`${pageId} not found!`);
+ }
+ if (pageName === 'install') {
+ const idle = new Idle();
+ const install = new Install();
+ this.initInstallPage(
+ builder,
+ this.dir.get_child('tool').get_child('installer.sh').get_path(),
+ install,
+ idle
+ );
+ window.connect('destroy', () => {
+ idle.destroy();
+ install.destroy();
+ });
+ }
+ this.initPage(pageName, builder, settings);
+ window.add(page);
+ }
+ const selPageName =
+ pageNames[settings.get_int('preferences-selected-page-value')];
+ if (selPageName) {
+ window.set_visible_page_name(selPageName);
+ }
+ const pageVisHandlerId = window.connect('notify::visible-page-name', () => {
+ logDebug(window.get_visible_page_name());
+ settings.set_int(
+ 'preferences-selected-page-value',
+ pageNames.indexOf(window.get_visible_page_name())
+ );
+ });
+ handlers.push([window, pageVisHandlerId]);
+
+ window.connect('destroy', () => {
+ handlers.forEach(([comp, handlerId]) => {
+ comp.disconnect(handlerId);
+ });
+ });
+ }
+
+ async initShutdownModeCombo(settings, comp) {
+ const model = new Gtk.StringList();
+ const actionIds = [];
+ try {
+ for await (const action of supportedActions()) {
+ model.append(actionLabel(action));
+ actionIds.push(ACTIONS[action]);
+ }
+ } catch (err) {
+ console.error(err);
+ }
+ comp.model = model;
+ const updateComboRow = () => {
+ const actionId =
+ ACTIONS[mapLegacyAction(settings.get_string('shutdown-mode-value'))];
+ const index = actionIds.indexOf(actionId);
+ if (index >= 0) comp.selected = index;
+ };
+ comp.connect('notify::selected', () => {
+ const actionId = actionIds[comp.selected];
+ const action = Object.entries(ACTIONS).find(
+ ([_, id]) => id === actionId
+ )[0];
+ if (action) settings.set_string('shutdown-mode-value', action);
+ });
+ const comboHandlerId = settings.connect(
+ 'changed::shutdown-mode-value',
+ () => updateComboRow()
+ );
+ comp.connect('destroy', () => settings.disconnect(comboHandlerId));
+ updateComboRow();
+ }
+
+ initPage(pageName, builder, settings) {
+ if (pageName in templateComponents) {
+ for (const [baseName, component] of Object.entries(
+ templateComponents[pageName]
+ )) {
+ const baseId = baseName.replaceAll('-', '_');
+ const settingsName = `${baseName}-value`;
+ const compId = `${baseId}_${component}`;
+ const comp = builder.get_object(compId);
+ if (!comp) {
+ throw new Error(`Component not found in template: ${compId}`);
+ }
+ if (compId === 'shutdown_mode_combo') {
+ this.initShutdownModeCombo(settings, comp);
+ } else {
+ settings.bind(
+ settingsName,
+ comp,
+ {
+ adjustment: 'value',
+ switch: 'active',
+ textbuffer: 'text',
+ buffer: 'text',
+ }[component],
+ Gio.SettingsBindFlags.DEFAULT
+ );
+ }
+
+ if (
+ [
+ 'show_wake_slider_switch',
+ 'show_wake_absolute_timer_switch',
+ ].includes(compId)
+ )
+ this.switchDependsOnSetting(comp, settings, 'show-wake-items-value');
+ }
+ }
+ }
+
+ switchDependsOnSetting(comp, settings, settingsName) {
+ const update = () => {
+ const active = settings.get_boolean(settingsName);
+ comp.sensitive = active;
+ const row = comp.get_parent().get_parent();
+ row.sensitive = active;
+ };
+ const handlerId = settings.connect(`changed::${settingsName}`, () =>
+ update()
+ );
+ comp.connect('destroy', () => settings.disconnect(handlerId));
+ update();
+ }
+
+ initInstallPage(builder, installerScriptPath, install, idle) {
+ // install log textbuffer updates
+ const logTextBuffer = builder.get_object('install_log_textbuffer');
+ const scrollAdj = builder.get_object('installer_scrollbar_adjustment');
+ const errorTag = new Gtk.TextTag({ foreground: 'red' });
+ const successTag = new Gtk.TextTag({ foreground: 'green' });
+ const table = logTextBuffer.get_tag_table();
+ table.add(errorTag);
+ table.add(successTag);
+
+ const installSwitch = builder.get_object('install_policy_switch');
+ installSwitch.set_active(install.checkInstalled());
+ installSwitch.connect('notify::active', () =>
+ install.installAction(
+ installerScriptPath,
+ installSwitch.get_active() ? 'install' : 'uninstall',
+ async message => {
+ await idle.guiIdle();
+ // Format log lines
+ message.split('\n').forEach(line => {
+ line = ['[', '#'].includes(line[0]) ? line : ` ${line}`;
+ const b = logTextBuffer;
+ b.insert(b.get_end_iter(), `${line}\n`, -1);
+ const end = b.get_end_iter();
+ const start = end.copy();
+ if (start.backward_line()) {
+ if (line.startsWith('# ')) {
+ b.apply_tag(errorTag, start, end);
+ } else if (line.endsWith('🟢')) {
+ b.apply_tag(successTag, start, end);
+ }
+ }
+ });
+ await idle.guiIdle();
+ scrollAdj.set_value(1000000);
+ }
+ )
+ );
+ // Clear install log
+ logTextBuffer.set_text('', -1);
+ }
+}