From 70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69 Mon Sep 17 00:00:00 2001 From: AlexanderCurl Date: Sat, 18 Apr 2026 17:46:06 +0100 Subject: Replaced file structures for themes in the correct format --- .../installed/ShutdownTimer@deminder/prefs.js | 240 +++++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 raveos-gnome-theme/theme-data/extensions/installed/ShutdownTimer@deminder/prefs.js (limited to 'raveos-gnome-theme/theme-data/extensions/installed/ShutdownTimer@deminder/prefs.js') 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 +// 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); + } +} -- cgit v1.3