170 lines
5.9 KiB
JavaScript
170 lines
5.9 KiB
JavaScript
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;
|
|
}
|
|
}
|