diff --git a/extension.js b/extension.js index e8a2abf..bba49e3 100644 --- a/extension.js +++ b/extension.js @@ -178,6 +178,55 @@ export default class HibernateButtonExtension extends Extension { } } + _loginManagerCanRebootToFirmwareSetup(asyncCallback) { + if (this._loginManager._proxy) { + // systemd path + this._loginManager._proxy.call( + 'CanRebootToFirmwareSetup', + null, + Gio.DBusCallFlags.NONE, + -1, + null, + function (proxy, asyncResult) { + let result, error; + + try { + result = proxy.call_finish(asyncResult).deep_unpack(); + } catch (e) { + error = e; + } + + if (error) asyncCallback(false); + else asyncCallback(!['no', 'na'].includes(result[0])); + } + ); + } else { + this.can_suspend_then_hibernate_sourceID = GLib.idle_add(() => { + asyncCallback(false); + return false; + }); + } + } + + _loginManagerUEFI() { + this._loginManager._proxy.call( + 'SetRebootToFirmwareSetup', + GLib.Variant.new('(b)', [true]), + Gio.DBusCallFlags.NONE, + -1, + null, + null + ); + this._loginManager._proxy.call( + 'Reboot', + GLib.Variant.new('(b)', [true]), + Gio.DBusCallFlags.NONE, + -1, + null, + null + ); + } + _updateHaveHibernate() { this._loginManagerCanHibernate(result => { log(`Able to hibernate: ${result}`); @@ -217,6 +266,19 @@ export default class HibernateButtonExtension extends Extension { this._haveSuspendThenHibernate && !Main.sessionMode.isLocked && this._setting.get_boolean('show-suspend-then-hibernate'); } + _updateHaveRebootToFirmwareSetup() { + this._loginManagerCanRebootToFirmwareSetup(result => { + log(`Able to reboot to firmware setup: ${result}`); + this._haveRebootToFirmwareSetup = result; + this._updateUEFI(); + }); + } + + _updateUEFI() { + this._uefiMenuItem.visible = + this._haveRebootToFirmwareSetup && !Main.sessionMode.isLocked && this._setting.get_boolean('show-uefi'); + } + _updateDefaults() { console.log("Update defaults"); let menuItems = this.systemMenu._systemItem.menu._getMenuItems() @@ -336,6 +398,39 @@ export default class HibernateButtonExtension extends Extension { } } + _onUEFIClicked() { + this.systemMenu._systemItem.menu.itemActivated(); + + if (this._setting.get_boolean('show-uefi-dialog')) { + let DialogContent = { + subject: C_('title', __('UEFI')), + description: __('Do you really want to boot to UEFI?'), + confirmButtons: [ + { + signal: 'Cancel', + label: C_('button', __('Cancel')), + key: Clutter.Escape, + }, + { + signal: 'Confirmed', + label: C_('button', __('UEFI')), + default: true, + }, + ], + }; + + this._dialog = new ConfirmDialog( + DialogContent + ); + this._dialog.connect('Confirmed', () => + this._loginManagerUEFI() + ); + this._dialog.open(); + } else { + this._loginManagerUEFI() + } + } + _disableExtension() { Main.extensionManager.disableExtension('hibernate-status@dromi') console.log('Disabled') @@ -460,9 +555,21 @@ export default class HibernateButtonExtension extends Extension { () => this._onSuspendThenHibernateClicked() ); + this._uefiMenuItem = new PopupMenu.PopupMenuItem( + __('UEFI') + ); + this._uefiMenuItemId = this._uefiMenuItem.connect( + 'activate', + () => this._onUEFIClicked() + ); + let afterSuspendPosition = this.systemMenu._systemItem.menu.numMenuItems - 5; + this.systemMenu._systemItem.menu.addMenuItem( + this._uefiMenuItem, + afterSuspendPosition + ); this.systemMenu._systemItem.menu.addMenuItem( this._hybridSleepMenuItem, afterSuspendPosition @@ -474,7 +581,7 @@ export default class HibernateButtonExtension extends Extension { this.systemMenu._systemItem.menu.addMenuItem( this._suspendThenHibernateMenuItem, afterSuspendPosition - ); + ); this._menuOpenStateChangedId = this.systemMenu._systemItem.menu.connect( 'open-state-changed', @@ -484,6 +591,7 @@ export default class HibernateButtonExtension extends Extension { this._updateHaveHibernate(); this._updateHaveHybridSleep(); this._updateHaveSuspendThenHibernate(); + this._updateHaveRebootToFirmwareSetup(); } ); } @@ -514,6 +622,11 @@ export default class HibernateButtonExtension extends Extension { ); this._menuOpenStateChangedId = 0; } + + if (this._uefiMenuItemId) { + this._uefiMenuItem.disconnect(this._uefiMenuItemId); + this._uefiMenuItemId = 0; + } if (this._suspendThenHibernateMenuItemId) { this._suspendThenHibernateMenuItem.disconnect(this._suspendThenHibernateMenuItemId); @@ -530,6 +643,11 @@ export default class HibernateButtonExtension extends Extension { this._hibernateMenuItemId = 0; } + if (this._uefiMenuItem) { + this._uefiMenuItem.destroy(); + this._uefiMenuItem = 0; + } + if (this._suspendThenHibernateMenuItem) { this._suspendThenHibernateMenuItem.destroy(); this._suspendThenHibernateMenuItem = 0; diff --git a/prefs.js b/prefs.js index f5f73b0..6e765d8 100644 --- a/prefs.js +++ b/prefs.js @@ -114,6 +114,10 @@ export default class Prefs extends ExtensionPreferences { const suspend_then_hibernate_row = new Adw.SwitchRow({ title: __('Suspend then hibernate'), }); + const uefi_row = new Adw.SwitchRow({ + title: __('UEFI'), + }); + modes_group.add(uefi_row); modes_group.add(suspend_then_hibernate_row); const restart_row = new Adw.SwitchRow({ title: __('Restart...'), @@ -146,6 +150,10 @@ export default class Prefs extends ExtensionPreferences { title: __('Suspend then Hibernate'), }); dialog_group.add(suspend_then_hibernate_dialog_row); + const uefi_dialog_row = new Adw.SwitchRow({ + title: __('UEFI'), + }); + dialog_group.add(uefi_dialog_row); window._settings = this.getSettings(); window._settings.bind('show-suspend', suspend_row, 'active', @@ -160,6 +168,8 @@ export default class Prefs extends ExtensionPreferences { Gio.SettingsBindFlags.DEFAULT); window._settings.bind('show-custom-reboot', restart_to_row, 'active', Gio.SettingsBindFlags.DEFAULT); + window._settings.bind('show-uefi', uefi_row, 'active', + Gio.SettingsBindFlags.DEFAULT); window._settings.bind('show-shutdown', shutdown_row, 'active', Gio.SettingsBindFlags.DEFAULT); window._settings.bind('show-hibernate-dialog', hibernate_dialog_row, 'active', @@ -168,5 +178,7 @@ export default class Prefs extends ExtensionPreferences { Gio.SettingsBindFlags.DEFAULT); window._settings.bind('show-suspend-then-hibernate-dialog', suspend_then_hibernate_dialog_row, 'active', Gio.SettingsBindFlags.DEFAULT); + window._settings.bind('show-uefi-dialog', uefi_dialog_row, 'active', + Gio.SettingsBindFlags.DEFAULT); } } diff --git a/schemas/org.gnome.shell.extensions.hibernate-status-button.gschema.xml b/schemas/org.gnome.shell.extensions.hibernate-status-button.gschema.xml index ffb81fd..705f8ff 100644 --- a/schemas/org.gnome.shell.extensions.hibernate-status-button.gschema.xml +++ b/schemas/org.gnome.shell.extensions.hibernate-status-button.gschema.xml @@ -25,6 +25,9 @@ true + + false + true @@ -34,5 +37,8 @@ false + + true +