diff options
| author | AlexanderCurl <alexc@alexc.hu> | 2026-04-18 17:46:06 +0100 |
|---|---|---|
| committer | AlexanderCurl <alexc@alexc.hu> | 2026-04-18 17:46:06 +0100 |
| commit | 70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69 (patch) | |
| tree | ab1123d4067c1b086dd6faa7ee4ea643236b565a /raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545 | |
| parent | 5d94c0a7d44a2255b81815a52a7056a94a39842d (diff) | |
| download | RaveOS-PKGBUILD-70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69.tar.gz RaveOS-PKGBUILD-70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69.zip | |
Replaced file structures for themes in the correct format
Diffstat (limited to 'raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545')
11 files changed, 866 insertions, 0 deletions
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/42_custom_reboot b/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/42_custom_reboot new file mode 100644 index 0000000..638d768 --- /dev/null +++ b/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/42_custom_reboot @@ -0,0 +1,11 @@ +#! /bin/sh +# This script allows the extension to skip grub's timeout when rebooting + +set -e + +cat << EOF +if [ ! -z "\${boot_once}" ] ; then + set timeout_style=hidden + set timeout=0 +fi +EOF
\ No newline at end of file diff --git a/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/bootloader.js b/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/bootloader.js new file mode 100644 index 0000000..5913d9c --- /dev/null +++ b/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/bootloader.js @@ -0,0 +1,36 @@ +import { EFIBootManager } from "./efibootmgr.js"; +import { SystemdBoot } from './systemdBoot.js'; +import { Grub } from './grub.js'; + +export const BootLoaders = { + EFI: "EFI Boot Manager", + GRUB: "Grub", + SYSD: "Systemd Boot", + UNKNOWN: "Unknown Boot Loader" +} + +export class Bootloader { + /** + * Gets the first available boot loader type on the current system + * @returns BootLoaders type. Can be "EFI", "SYSD", "GRUB", or "UNKNOWN" + */ + static async GetUseableType(extension) { + const settings = extension.getSettings('org.gnome.shell.extensions.customreboot'); + + if (await EFIBootManager.IsUseable() && settings.get_boolean('use-efibootmgr')) return BootLoaders.EFI; + if (await Grub.IsUseable() && settings.get_boolean('use-grub')) return BootLoaders.GRUB; + if (await SystemdBoot.IsUseable() && settings.get_boolean('use-systemd-boot')) return BootLoaders.SYSD; + return BootLoaders.UNKNOWN; + } + + /** + * Gets a instance of the provided boot loader + * @returns A boot loader if one is found otherwise undefined + */ + static async GetUseable(type) { + if (type === BootLoaders.EFI) return EFIBootManager; + if (type === BootLoaders.SYSD) return SystemdBoot; + if (type === BootLoaders.GRUB) return Grub; + return undefined; + } +}
\ No newline at end of file diff --git a/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/efibootmgr.js b/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/efibootmgr.js new file mode 100644 index 0000000..f34cec0 --- /dev/null +++ b/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/efibootmgr.js @@ -0,0 +1,101 @@ +import Gio from "gi://Gio"; +import { ExecCommand, Log, LogWarning } from './utils.js'; + +/** + * Represents efibootmgr + */ +export class EFIBootManager { + /** + * Get's all available boot options + * @returns {[Map, string]} Map(title, id), defaultOption + */ + static async GetBootOptions() { + const [status, stdout, stderr] = await ExecCommand(['efibootmgr'],); + const lines = stdout.split("\n"); + + let boot_first = "0000"; + + const boot_options = new Map(); + + for (let l = 0; l < lines.length; l++) { + const line = lines[l]; + if (line.startsWith("BootOrder:")) { + boot_first = line.split(" ")[1].split(",")[0]; + continue; + } + + const regex = /(Boot[0-9]{4})/; + const vLine = regex.exec(line) + if (vLine && vLine.length) { + const option = line.replace("Boot", "").split("*"); + const title = option[1]; + if (title.includes("HD") || title.includes("RC")) { + const trimed_title = title.replace(/(?<=[\S\s]*)(HD|RC)([\s\S()]*|$)/, "").trim(); + boot_options.set(trimed_title, option[0].trim()); + } + else { + boot_options.set(option[1].trim(), option[0].trim()); + } + } + } + + return [boot_options, boot_first]; + } + + /** + * Set's the next boot option + * @param {string} id + * @returns True if the boot option was set, otherwise false + */ + static async SetBootOption(id) { + if (!this.IsUseable()) return false; + const [status, stdout, stderr] = await ExecCommand(['/usr/bin/pkexec', 'efibootmgr', '-n', id],); + if (status === 0) { + Log(`Set boot option to ${id}`); + return true; + } + LogWarning("Unable to set boot option using efibootmgr"); + return false; + } + + /** + * Can we use this bootloader? + * @returns True if useable otherwise false + */ + static async IsUseable() { + return await this.GetBinary() !== ""; + } + + /** + * Get's efibootmgr binary path + * @returns A string containing the location of the binary, if none is found returns a blank string + */ + static async GetBinary() { + let paths = ["/usr/bin/efibootmgr", "/usr/sbin/efibootmgr"]; + + let file; + + for (let i = 0; i < paths.length; i++) { + file = Gio.file_new_for_path(paths[i]); + if (file.query_exists(null)) { + return paths[i]; + } + } + + return ""; + } + + /** + * This boot loader cannot be quick rebooted + */ + static async CanQuickReboot() { + return false; + } + + /** + * This boot loader cannot be quick rebooted + */ + static async QuickRebootEnabled() { + return false; + } +}
\ No newline at end of file diff --git a/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/extension.js b/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/extension.js new file mode 100644 index 0000000..035e019 --- /dev/null +++ b/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/extension.js @@ -0,0 +1,170 @@ +import * as Main from 'resource:///org/gnome/shell/ui/main.js'; +import * as PopupMenu from 'resource:///org/gnome/shell/ui/popupMenu.js'; +import * as QuickSettings from 'resource:///org/gnome/shell/ui/quickSettings.js'; + + +import { Extension } from "resource:///org/gnome/shell/extensions/extension.js"; +import { getDefault } from "resource:///org/gnome/shell/misc/systemActions.js"; +import GObject from "gi://GObject"; + +//import +import { LogWarning, Log } from './utils.js'; +import { BootLoaders, Bootloader } from "./bootloader.js"; + + +const RebootQuickMenu = GObject.registerClass( +class RebootQuickMenu extends QuickSettings.QuickMenuToggle { + + _init(extension) { + const init_params = { iconName: 'system-reboot-symbolic', toggleMode: false }; + init_params.title = "Reboot Into"; + super._init(init_params); + + // Set toggle to be unchecked + this.checked = false; + + // Open menu and set toggle check to true + this.clickedID = this.connect("clicked", () => { + this.menu.open(); + this.checked = true; + }); + + // Connect 'menu-closed' to update checked state + this.menuClosedID = this.menu.connect("menu-closed", () => { + this.checked = false; + }); + + // Add boot options to menu + try { + this.createBootMenu(extension); + } + catch (e) { + LogWarning(e); + } + } + + cleanConns() { + // Disconnect all connections + this.disconnect(this.openStateID); + this.disconnect(this.clickedID); + } + + async createBootMenu(extension) { + // Get boot options + const type = await Bootloader.GetUseableType(extension); + + + const header_title = `Boot Options - ${type}`; + + // Set Menu Header + this.menu.setHeader('system-reboot-symbolic', header_title, 'Reboot into the selected entry'); + + const loader = await Bootloader.GetUseable(type); + + if (loader === undefined) { + // Set Menu Header + this.menu.setHeader('system-reboot-symbolic', 'Error', 'The selected boot loader cannot be found...'); + + // Add reload option, to refresh extension menu without reloading GNOME or the extension + this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); + this.menu.addAction('Reload', () => { + this.menu.removeAll(); + this.createBootMenu(); + }); + + // Add button to open settings + this.menu.addAction('Settings', () => { + extension.openPreferences(); + }); + + return; + } + + loader.GetBootOptions().then(([bootOps, defaultOpt]) => { + if (bootOps !== undefined) { + this._itemsSection = new PopupMenu.PopupMenuSection(); + + for (let [title, id] of bootOps) { + Log(`${title} - ${id}`); + this._itemsSection.addAction(String(title), () => { + // Set boot option + loader.SetBootOption(String(id)).then(result => { + if (result) { + // On success trigger restart dialog + new getDefault().activateRestart(); + } + }); + }, (title === defaultOpt || id === defaultOpt)? "pan-end-symbolic" : undefined); + } + + this.menu.addMenuItem(this._itemsSection); + } + + // Add reload option, to refresh extension menu without reloading GNOME or the extension + this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); + this.menu.addAction('Reload', () => { + this.menu.removeAll(); + this.createBootMenu(); + }); + + // Add button to open settings + this.menu.addAction('Settings', () => { + extension.openPreferences(); + }); + + loader.CanQuickReboot().then(async result => { + if (!result) return; + if (!await loader.QuickRebootEnabled()) { + this.menu.addAction('Enable Quick Reboot', async () => { + await loader.EnableQuickReboot(extension); + this.menu.removeAll(); + this.createBootMenu(); + }); + } + else { + this.menu.addAction('Disable Quick Reboot', async () => { + await loader.DisableQuickReboot(); + this.menu.removeAll(); + this.createBootMenu(); + }); + } + }); + + }).catch((error) => { + LogWarning(error); + // Only do this if the current bootloader is grub + if (type === BootLoaders.GRUB) + { + // Only add this if all fails, giving user option to make the config readable + this.menu.addMenuItem(new PopupSeparatorMenuItem()); + this.menu.addAction('Fix Grub.conf Perms', async () => { + await loader.SetReadable(); + this.menu.removeAll(); + this.createBootMenu(extension); + }); + } + }) + } +}); + +export default class CustomReboot extends Extension { + + enable() { + // Add items to QuickSettingsMenu + this._indicator = new QuickSettings.SystemIndicator(); + this.menu = new RebootQuickMenu(this); + this._indicator.quickSettingsItems.push(this.menu); + Main.panel.statusArea.quickSettings.addExternalIndicator(this._indicator, 1); + } + + disable() { + this.menu.cleanConns(); + this.menu = null; + + this._indicator.quickSettingsItems.forEach(item => { + item.destroy(); + }); + this._indicator.destroy(); + this._indicator = null; + } +} diff --git a/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/grub.js b/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/grub.js new file mode 100644 index 0000000..6d67ff0 --- /dev/null +++ b/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/grub.js @@ -0,0 +1,205 @@ +import Gio from "gi://Gio"; +import { ExecCommand, Log, LogWarning } from './utils.js'; + +/** + * Represents grub + */ +export class Grub { + /** + * Get's all available boot options + * @returns {[Map, string]} Map(title, id), defaultOption + */ + static async GetBootOptions() { + try { + let cfgpath = await this.GetConfig(); + if (cfgpath == "") { + throw new String("Failed to find grub config"); + } + + let bootOptions = new Map(); + + let defualtEn = ""; + + let file = Gio.file_new_for_path(cfgpath); + let [suc, content] = file.load_contents(null); + if (!suc) { + throw new String("Failed to load grub config"); + } + + let lines; + if (content instanceof Uint8Array) { + lines = new TextDecoder().decode(content); + } + else { + lines = content.toString(); + } + + let entryRx = /^menuentry ['"]([^'"]+)/; + let defaultRx = /(?<=set default=\")([A-Za-z- ()/0-9]*)(?=\")/ + lines.split('\n').forEach(l => { + let res = entryRx.exec(l); + if (res && res.length) { + bootOptions.set(res[1], res[1]); + } + let def = defaultRx.exec(l); + if (def && def.length) { + defualtEn = def[0]; + } + }); + + bootOptions.forEach((v, k) => { + Log(`${k} = ${v}`); + }); + + if (defualtEn == "") defualtEn = bootOptions.keys().next().value; + + return [bootOptions, defualtEn]; + + } catch (e) { + LogWarning(e); + return undefined; + } + } + + /** + * Set's the next boot option + * @param {string} id + * @returns True if the boot option was set, otherwise false + */ + static async SetBootOption(id) { + try { + let [status, stdout, stderr] = await ExecCommand( + ['/usr/bin/pkexec', '/usr/sbin/grub-reboot', id], + ); + Log(`Set boot option to ${id}: ${status}\n${stdout}\n${stderr}`); + return true; + } catch (e) { + LogWarning(e); + return false; + } + } + + /** + * Can we use this bootloader? + * @returns True if useable otherwise false + */ + static async IsUseable() { + return await this.GetConfig() !== ""; + } + + /** + * Get's grub config file + * @returns A string containing the location of the config file, if none is found returns a blank string + */ + static async GetConfig() { + let paths = ["/boot/grub/grub.cfg", "/boot/grub2/grub.cfg"]; + + let file; + + for (let i = 0; i < paths.length; i++) { + file = Gio.file_new_for_path(paths[i]); + if (file.query_exists(null)) { + return paths[i]; + } + } + + return ""; + } + + /** + * Copies a custom grub script to allow the extension to quickly reboot into another OS + * If anyone reads this: Idk how to combine these into one pkexec call, if you do please leave a commit fixing it + */ + static async EnableQuickReboot(ext) { + try { + let [status, stdout, stderr] = await ExecCommand([ + 'pkexec', + 'sh', + '-c', + `/usr/bin/cp ${ext.lookupByUUID('customreboot@nova1545').path()}/42_custom_reboot /etc/grub.d/42_custom_reboot && /usr/bin/chmod 755 /etc/grub.d/42_custom_reboot && /usr/sbin/update-grub` + ]); + + if (status !== 0) { + return false; + } + + return true; + } + catch (e) { + LogWarning(e); + return false; + } + } + + + /** + * Removes the script used to allow the extension to quickly reboot into another OS without waiting for grub's timeout + * If anyone reads this: Idk how to combine these into one pkexec call, if you do please leave a commit fixing it + */ + static async DisableQuickReboot() { + try { + + let [status, stdout, stderr] = await ExecCommand([ + 'pkexec', + 'sh', + '-c', + '/usr/bin/rm /etc/grub.d/42_custom_reboot && /usr/sbin/update-grub' + ]); + + if (status !== 0) { + return false; + } + + return true; + } + catch (e) { + LogWarning(e); + return false; + } + } + + + /** + * This boot loader can be quick rebooted + */ + static async CanQuickReboot() { + return true; + } + + /** + * Checks if /etc/grub.d/42_custom_reboot exists + */ + static async QuickRebootEnabled() { + try { + let [status, stdout, stderr] = await ExecCommand(['/usr/bin/cat', '/etc/grub.d/42_custom_reboot'],); + if (status !== 0) { + LogWarning(`/etc/grub.d/42_custom_reboot not found`); + return false; + } + Log(`/etc/grub.d/42_custom_reboot found`); + + return true; + } + catch (e) { + LogWarning(e); + return false; + } + } + + static async SetReadable() { + try { + const config = GetConfig(); + let [status, stdout, stderr] = await ExecCommand(['/usr/bin/pkexec', '/usr/bin/chmod', '644', config],); + if (status !== 0) { + Log(`Failed to make ${config} readable`); + return false; + } + Log(`Made ${config} readable`); + return true; + } + catch (e) { + Log(e); + return false; + } + } +}
\ No newline at end of file diff --git a/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/metadata.json b/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/metadata.json new file mode 100644 index 0000000..8cea11c --- /dev/null +++ b/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/metadata.json @@ -0,0 +1,17 @@ +{ + "_generated": "Generated by SweetTooth, do not edit", + "description": "Reboot into another OS directly from GNOME.\nA expansion of https://github.com/docquantum/gnome-shell-extension-customreboot", + "name": "Custom Reboot", + "original-author": "Nova1545", + "shell-version": [ + "45", + "46", + "47", + "48", + "49", + "50" + ], + "url": "https://github.com/Nova1545/gnome-shell-extension-customreboot", + "uuid": "customreboot@nova1545", + "version": 11 +} diff --git a/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/prefs.js b/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/prefs.js new file mode 100644 index 0000000..f93539a --- /dev/null +++ b/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/prefs.js @@ -0,0 +1,101 @@ +'use strict'; + +import {ExtensionPreferences, gettext as _} from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js'; + + +import Gio from "gi://Gio"; +import Adw from "gi://Adw"; +import Gtk from "gi://Gtk"; +import { EFIBootManager } from './efibootmgr.js'; +import { Grub } from './grub.js'; +import { SystemdBoot } from './systemdBoot.js'; + +export default class MyExtensionPreferences extends ExtensionPreferences { + fillPreferencesWindow(window) { + const settings = this.getSettings('org.gnome.shell.extensions.customreboot'); + + // Create a preferences page and group + const page = new Adw.PreferencesPage(); + const group = new Adw.PreferencesGroup(); + page.add(group); + + // Create row for efibootmgr + const efi = new Adw.ActionRow({ title: 'Use EFI Boot Manager (efibootmgr)' }); + + // Create row for grub + const grub = new Adw.ActionRow({ title: 'Use Grub'}); + + // Create row for systemd-boot + const sysd = new Adw.ActionRow({ title: 'Use Systemd Boot'}); + + // Add rows + group.add(efi); + group.add(grub); + group.add(sysd); + + // Create switch for efibootmgr + const efi_switch = new Gtk.Switch({ + active: settings.get_boolean('use-efibootmgr'), + valign: Gtk.Align.CENTER, + }); + + // Create switch for grub + const grub_switch = new Gtk.Switch({ + active: settings.get_boolean('use-grub'), + valign: Gtk.Align.CENTER, + }); + + // Create switch for systemd-boot + const sysd_switch = new Gtk.Switch({ + active: settings.get_boolean('use-systemd-boot'), + valign: Gtk.Align.CENTER, + }); + + // Bind settings for efibootmgr + settings.bind( + 'use-efibootmgr', + efi_switch, + 'active', + Gio.SettingsBindFlags.DEFAULT + ); + + // Bind settings for grub + settings.bind( + 'use-grub', + grub_switch, + 'active', + Gio.SettingsBindFlags.DEFAULT + ); + + // Bind settings for systemd-boot + settings.bind( + 'use-systemd-boot', + sysd_switch, + 'active', + Gio.SettingsBindFlags.DEFAULT + ); + + // Add the switch for efibootmgr + efi.add_suffix(efi_switch); + efi.activatable_widget = efi_switch; + + // Add the switch for grub + grub.add_suffix(grub_switch); + grub.activatable_widget = grub_switch; + + // Add the switch for systemd-boot + sysd.add_suffix(sysd_switch); + sysd.activatable_widget = sysd_switch; + + // Add our page to the window + window.add(page); + + (async () => { + // Disable/enable switches in accordance to them being usable + + efi_switch.set_sensitive(await EFIBootManager.IsUseable()); + grub_switch.set_sensitive(await Grub.IsUseable()); + sysd_switch.set_sensitive(await SystemdBoot.IsUseable()); + })(); + } +}
\ No newline at end of file diff --git a/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/schemas/gschemas.compiled b/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/schemas/gschemas.compiled Binary files differnew file mode 100644 index 0000000..cdce7f0 --- /dev/null +++ b/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/schemas/gschemas.compiled diff --git a/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/schemas/org.gnome.extensions.customreboot.gschema.xml b/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/schemas/org.gnome.extensions.customreboot.gschema.xml new file mode 100644 index 0000000..f56ca42 --- /dev/null +++ b/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/schemas/org.gnome.extensions.customreboot.gschema.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<schemalist> + <schema id="org.gnome.shell.extensions.customreboot" path="/org/gnome/shell/extensions/customreboot/"> + <!-- See also: https://docs.gtk.org/glib/gvariant-format-strings.html --> + <key name="use-efibootmgr" type="b"> + <default>true</default> + </key> + <key name="use-grub" type="b"> + <default>false</default> + </key> + <key name="use-systemd-boot" type="b"> + <default>false</default> + </key> + </schema> +</schemalist>
\ No newline at end of file diff --git a/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/systemdBoot.js b/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/systemdBoot.js new file mode 100644 index 0000000..51d4e6e --- /dev/null +++ b/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/systemdBoot.js @@ -0,0 +1,121 @@ +import Gio from "gi://Gio"; +import { ExecCommand, Log, LogWarning } from './utils.js'; + +/** + * Represents Systemdboot + */ +export class SystemdBoot { + /** + * Get's all available boot options + * @returns {[Map, string]} Map(title, id), defaultOption + */ + static async GetBootOptions() { + let bootctl = await this.GetBinary(); + if (bootctl == "") { + Log(`Failed to find bootctl binary`); + return undefined; + } + + try { + let [status, stdout, stderr] = await ExecCommand([bootctl, "list"]); + if (status !== 0) + throw new Error(`Failed to get list from bootctl: ${status}\n${stdout}\n${stderr}`); + Log(`bootctl list: ${status}\n${stdout}\n${stderr}`); + let lines = String(stdout).split('\n'); + let titleRx = /(?<=title:\s+).+/; + let idRx = /(?<=id:\s+).+/; + let defaultRx = /\(default\)/; + let titles = []; + let ids = [] + let defaultOpt; + lines.forEach(l => { + let title = titleRx.exec(l); + let id = idRx.exec(l); + if (title && title.length) { + titles.push(String(title)); + } else if (id && id.length) { + ids.push(String(id)); + } + }); + if (titles.length !== ids.length) + throw new Error("Number of titles and ids do not match!"); + let bootOptions = new Map(); + for (let i = 0; i < titles.length; i++) { + bootOptions.set(titles[i], ids[i]) + } + + bootOptions.forEach((id, title) => { + Log(`${id} = ${title}`); + + let defaultRes = defaultRx.exec(title); + + if (defaultRes) { + defaultOpt = title; + } + }) + + return [bootOptions, bootOptions.get(defaultOpt)]; + } catch (e) { + LogWarning(e); + return undefined; + } + } + + /** + * Set's the next boot option + * @param {string} id + * @returns True if the boot option was set, otherwise false + */ + static async SetBootOption(id) { + if (!this.IsUseable()) return false; + const [status, stdout, stderr] = await ExecCommand(['/usr/bin/pkexec', '/usr/bin/bootctl', 'set-oneshot', id],); + if (status === 0) { + Log(`Set boot option to ${id}`); + return true; + } + LogWarning("Unable to set boot option using bootctl"); + return false; + } + + + /** + * Can we use this bootloader? + * @returns True if useable otherwise false + */ + static async IsUseable() { + return await this.GetBinary() !== ""; + } + + /** + * Get's bootctl binary path + * @returns A string containing the location of the binary, if none is found returns a blank string + */ + static async GetBinary() { + let paths = ["/usr/sbin/bootctl", "/usr/bin/bootctl"]; + + let file; + + for (let i = 0; i < paths.length; i++) { + file = Gio.file_new_for_path(paths[i]); + if (file.query_exists(null)) { + return paths[i]; + } + } + + return ""; + } + + /** + * This boot loader cannot be quick rebooted + */ + static async CanQuickReboot() { + return false; + } + + /** + * This boot loader cannot be quick rebooted + */ + static async QuickRebootEnabled() { + return false; + } +} diff --git a/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/utils.js b/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/utils.js new file mode 100644 index 0000000..1c7514a --- /dev/null +++ b/raveos-gnome-theme/theme-data/extensions/installed/customreboot@nova1545/utils.js @@ -0,0 +1,89 @@ +/* utils.js + * + * Copyright (C) 2020 + * Daniel Shchur (DocQuantum) <shchurgood@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * SPDX-License-Identifier: GPL-3.0-or-later +*/ + +import Gio from "gi://Gio"; + + +var DEBUG = false; + +/** + * @param {String[]} argv + * @param {String} input + * @param {Gio.Cancellable} cancellable + * @returns {Promise} Function execution + * => @returns {[int, String, String]} [StatusCode, STDOUT, STDERR] + * + * Executes a command asynchronously. + */ +export async function ExecCommand(argv, input = null, cancellable = null) { + let flags = Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDERR_PIPE; + + if (input !== null) + flags |= Gio.SubprocessFlags.STDIN_PIPE; + + let proc = new Gio.Subprocess({ + argv: argv, + flags: flags + }); + proc.init(cancellable); + return new Promise((resolve,reject) => { + proc.communicate_utf8_async(input, cancellable, (proc, res) => { + try { + resolve([(function() { + if(!proc.get_if_exited()) + throw new Error("Subprocess failed to exit in time!"); + return proc.get_exit_status() + })()].concat(proc.communicate_utf8_finish(res).slice(1))); + } catch (e) { + reject(e); + } + }); + }); +} + +/** + * @param {bool} value + * + * Set's whether to debug or to not. + */ +export function SetDebug(value){ + DEBUG = value; +} + +/** + * @param {string} msg + * + * Logs general messages if debug is set to true. + */ +export function Log(msg) { + if(DEBUG) + console.log(`CustomReboot NOTE: ${msg}`); +} + +/** + * @param {string} msg + * + * Logs warning messages if debug is set to true. + */ +export function LogWarning(msg) { + if(DEBUG) + console.warn(`CustomReboot WARN: ${msg}`); +}
\ No newline at end of file |