Skip to content

Commit e1a86fc

Browse files
committed
Bug fixes + settings improvements + suspend then hibernate
Fix detection of canHibernate, canHybridSleep Allow for individual suspend modes to be hidden Add suspend then hibernate functionality
1 parent 328e38c commit e1a86fc

File tree

4 files changed

+133
-76
lines changed

4 files changed

+133
-76
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Basic Makefile
22

33
UUID = hibernate-status@dromi
4-
BASE_MODULES = extension.js metadata.json confirmDialog.js LICENSE README.md
4+
BASE_MODULES = extension.js metadata.json LICENSE README.md
55
EXTRA_MODULES = prefs.js
66
TOLOCALIZE = confirmDialog.js prefs.js
77
PO_FILES := $(wildcard ./locale/*/*/*.po)

extension.js

Lines changed: 102 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ import * as StatusSystem from 'resource:///org/gnome/shell/ui/status/system.js';
1111
import * as PopupMenu from 'resource:///org/gnome/shell/ui/popupMenu.js';
1212
import * as ExtensionSystem from 'resource:///org/gnome/shell/ui/extensionSystem.js';
1313
import * as ModalDialog from 'resource:///org/gnome/shell/ui/modalDialog.js';
14+
import * as Dialog from 'resource:///org/gnome/shell/ui/dialog.js';
1415
import * as CheckBoxImport from 'resource:///org/gnome/shell/ui/checkBox.js';
16+
import {loadInterfaceXML} from 'resource:///org/gnome/shell/misc/fileUtils.js';
1517

1618
const CheckBox = CheckBoxImport.CheckBox;
1719

@@ -45,7 +47,7 @@ export default class MyExtension extends Extension {
4547
}
4648

4749
if (error) asyncCallback(false);
48-
else asyncCallback(result[0] != 'no');
50+
else asyncCallback(!['no', 'na'].includes(result[0]));
4951
}
5052
);
5153
} else {
@@ -101,7 +103,7 @@ export default class MyExtension extends Extension {
101103
}
102104

103105
if (error) asyncCallback(false);
104-
else asyncCallback(result[0] != 'no');
106+
else asyncCallback(!['no', 'na'].includes(result[0]));
105107
}
106108
);
107109
} else {
@@ -129,29 +131,92 @@ export default class MyExtension extends Extension {
129131
this._loginManager.emit('prepare-for-sleep', false);
130132
}
131133
}
134+
135+
_loginManagerCanSuspendThenHibernate(asyncCallback) {
136+
if (this._loginManager._proxy) {
137+
// systemd path
138+
this._loginManager._proxy.call(
139+
'CanSuspendThenHibernate',
140+
null,
141+
Gio.DBusCallFlags.NONE,
142+
-1,
143+
null,
144+
function (proxy, asyncResult) {
145+
let result, error;
146+
147+
try {
148+
result = proxy.call_finish(asyncResult).deep_unpack();
149+
} catch (e) {
150+
error = e;
151+
}
152+
153+
if (error) asyncCallback(false);
154+
else asyncCallback(!['no', 'na'].includes(result[0]));
155+
}
156+
);
157+
} else {
158+
Mainloop.idle_add(() => {
159+
asyncCallback(false);
160+
return false;
161+
});
162+
}
163+
}
164+
165+
_loginManagerSuspendThenHibernate() {
166+
if (this._loginManager._proxy) {
167+
// systemd path
168+
this._loginManager._proxy.call(
169+
'SuspendThenHibernate',
170+
GLib.Variant.new('(b)', [true]),
171+
Gio.DBusCallFlags.NONE,
172+
-1,
173+
null,
174+
null
175+
);
176+
} else {
177+
// Can't do in ConsoleKit
178+
this._loginManager.emit('prepare-for-sleep', true);
179+
this._loginManager.emit('prepare-for-sleep', false);
180+
}
181+
}
182+
132183
_updateHaveHibernate() {
133184
this._loginManagerCanHibernate(result => {
134-
log(`have hibernate ${result}`);
185+
log(`Able to hibernate: ${result}`);
135186
this._haveHibernate = result;
136187
this._updateHibernate();
137188
});
138189
}
139190

140191
_updateHibernate() {
141192
this._hibernateMenuItem.visible =
142-
this._haveHibernate && !Main.sessionMode.isLocked;
193+
this._haveHibernate && !Main.sessionMode.isLocked && this._setting.get_boolean('show-hibernate');
143194
}
144195

145196
_updateHaveHybridSleep() {
146197
this._loginManagerCanHybridSleep(result => {
198+
log(`Able to hybrid-sleep: ${result}`);
147199
this._haveHybridSleep = result;
148200
this._updateHybridSleep();
149201
});
150202
}
151203

152204
_updateHybridSleep() {
153205
this._hybridSleepMenuItem.visible =
154-
this._haveHybridSleep && !Main.sessionMode.isLocked;
206+
this._haveHybridSleep && !Main.sessionMode.isLocked && this._setting.get_boolean('show-hybrid-sleep');
207+
}
208+
209+
_updateHaveSuspendThenHibernate() {
210+
this._loginManagerCanSuspendThenHibernate(result => {
211+
log(`Able to suspend then hibernate: ${result}`);
212+
this._haveSuspendThenHibernate = result;
213+
this._updateSuspendThenHibernate();
214+
});
215+
}
216+
217+
_updateSuspendThenHibernate() {
218+
this._suspendThenHibernateMenuItem.visible =
219+
this._haveSuspendThenHibernate && !Main.sessionMode.isLocked && this._setting.get_boolean('show-suspend-then-hibernate');
155220
}
156221

157222
_onHibernateClicked() {
@@ -172,8 +237,8 @@ export default class MyExtension extends Extension {
172237
default: true,
173238
},
174239
],
175-
//iconName: 'document-save-symbolic',
176-
//iconStyleClass: 'end-session-dialog-shutdown-icon',
240+
iconName: 'document-save-symbolic',
241+
iconStyleClass: 'end-session-dialog-shutdown-icon',
177242
};
178243

179244
this._dialog = new ConfirmDialog(
@@ -190,15 +255,14 @@ export default class MyExtension extends Extension {
190255
this._loginManagerHybridSleep();
191256
}
192257

258+
_onSuspendThenHibernateClicked() {
259+
this.systemMenu._systemItem.menu.itemActivated();
260+
this._loginManagerSuspendThenHibernate();
261+
}
262+
193263
_disableExtension() {
194-
let enabledExtensions = global.settings.get_strv(
195-
ExtensionSystem.ENABLED_EXTENSIONS_KEY
196-
);
197-
enabledExtensions.splice(enabledExtensions.indexOf(Me.uuid), 1);
198-
global.settings.set_strv(
199-
ExtensionSystem.ENABLED_EXTENSIONS_KEY,
200-
enabledExtensions
201-
);
264+
Main.extensionManager.disableExtension('hibernate-status@dromi')
265+
console.log('Disabled')
202266
}
203267

204268
_cancelDisableExtension(notAgain) {
@@ -251,10 +315,9 @@ export default class MyExtension extends Extension {
251315
let HibernateFailedDialogContent = {
252316
subject: C_('title', __('Hibernate button: Hibernate failed')),
253317
description: __(
254-
'Looks like hibernation failed.\n' +
255-
'On some linux distributions hibernation is disabled\n' +
256-
'because not all hardware supports it well;\n' +
257-
'please check your distribution documentation\n' +
318+
'Looks like hibernation failed. On some linux distributions hibernation is disabled ' +
319+
'because not all hardware supports it well; ' +
320+
'please check your distribution documentation ' +
258321
'on how to enable it.'
259322
),
260323
checkBox: __("You are wrong, don't check this anymore!"),
@@ -314,6 +377,14 @@ export default class MyExtension extends Extension {
314377
() => this._onHybridSleepClicked()
315378
);
316379

380+
this._suspendThenHibernateMenuItem = new PopupMenu.PopupMenuItem(
381+
__('Suspend then Hibernate')
382+
);
383+
this._suspendThenHibernateMenuItemId = this._suspendThenHibernateMenuItem.connect(
384+
'activate',
385+
() => this._onSuspendThenHibernateClicked()
386+
);
387+
317388
let afterSuspendPosition =
318389
this.systemMenu._systemItem.menu.numMenuItems - 5;
319390

@@ -325,13 +396,18 @@ export default class MyExtension extends Extension {
325396
this._hibernateMenuItem,
326397
afterSuspendPosition
327398
);
399+
this.systemMenu._systemItem.menu.addMenuItem(
400+
this._suspendThenHibernateMenuItem,
401+
afterSuspendPosition
402+
);
328403

329404
this._menuOpenStateChangedId = this.systemMenu._systemItem.menu.connect(
330405
'open-state-changed',
331406
(menu, open) => {
332407
if (!open) return;
333408
this._updateHaveHibernate();
334409
this._updateHaveHybridSleep();
410+
this._updateHaveSuspendThenHibernate();
335411
}
336412
);
337413
}
@@ -382,50 +458,15 @@ var ConfirmDialog = GObject.registerClass(
382458
destroyOnClose: true,
383459
});
384460

385-
let mainContentLayout = new St.BoxLayout({
386-
vertical: false,
387-
x_expand: true,
388-
y_expand: false,
389-
});
390-
this.contentLayout.add(mainContentLayout);
391461

392-
this._iconBin = new St.Bin({
393-
x_expand: true,
394-
y_expand: false,
395-
x_align: Clutter.ActorAlign.END,
396-
y_align: Clutter.ActorAlign.START,
397-
});
398-
mainContentLayout.add(this._iconBin);
462+
this._messageDialogContent = new Dialog.MessageDialogContent();
399463

400-
let messageLayout = new St.BoxLayout({
401-
vertical: true,
402-
y_align: Clutter.ActorAlign.START,
403-
});
404-
mainContentLayout.add(messageLayout);
405-
406-
this._subjectLabel = new St.Label({
407-
style_class: 'end-session-dialog-subject',
408-
y_expand: false,
409-
y_align: Clutter.ActorAlign.START,
410-
});
411464

412-
messageLayout.add(this._subjectLabel);
413-
414-
this._descriptionLabel = new St.Label({
415-
style_class: 'end-session-dialog-description',
416-
y_expand: true,
417-
y_align: Clutter.ActorAlign.START,
418-
});
419-
420-
messageLayout.add(this._descriptionLabel);
421-
422-
// fill dialog
423-
424-
_setLabelText(this._descriptionLabel, dialog.description);
425-
_setLabelText(this._subjectLabel, dialog.subject);
465+
this._messageDialogContent.description = dialog.description;
466+
this._messageDialogContent.title = dialog.subject;
426467

427468
if (dialog.iconName) {
428-
this._iconBin.child = new St.Icon({
469+
this._icon = new St.Icon({
429470
icon_name: dialog.iconName,
430471
icon_size: _DIALOG_ICON_SIZE,
431472
style_class: dialog.iconStyleClass,
@@ -434,9 +475,11 @@ var ConfirmDialog = GObject.registerClass(
434475

435476
if (dialog.checkBox) {
436477
this._checkBox = new CheckBox(dialog.checkBox);
437-
mainContentLayout.add(this._checkBox.actor);
478+
this._messageDialogContent.add(this._checkBox.actor);
438479
}
439480

481+
this.contentLayout.add_child(this._messageDialogContent);
482+
440483
let buttons = [];
441484
for (let i = 0; i < dialog.confirmButtons.length; i++) {
442485
let signal = dialog.confirmButtons[i].signal;
@@ -471,13 +514,3 @@ var ConfirmDialog = GObject.registerClass(
471514
);
472515

473516
const _DIALOG_ICON_SIZE = 32;
474-
475-
function _setLabelText(label, text) {
476-
if (text) {
477-
label.set_text(text);
478-
label.show();
479-
} else {
480-
label.set_text('');
481-
label.hide();
482-
}
483-
}

prefs.js

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,16 +94,31 @@ export default class Prefs extends ExtensionPreferences {
9494
window.add(page);
9595

9696
const group = new Adw.PreferencesGroup({
97-
title: __('No settings available'),
98-
description: __('Settings have not yet been implemented'),
97+
title: __('Modes'),
98+
description: __('Which buttons should be enabled'),
9999
});
100100
page.add(group);
101101

102102
// Create a new preferences row
103-
const row = new Adw.SwitchRow({
104-
title: __('N/A'),
105-
subtitle: __('N/A'),
103+
const hibernate_row = new Adw.SwitchRow({
104+
title: __('Hibernate'),
106105
});
107-
group.add(row);
106+
group.add(hibernate_row);
107+
const hybrid_row = new Adw.SwitchRow({
108+
title: __('Hybrid sleep'),
109+
});
110+
group.add(hybrid_row);
111+
const suspend_then_hibernate_row = new Adw.SwitchRow({
112+
title: __('Suspend then hibernate'),
113+
});
114+
group.add(suspend_then_hibernate_row);
115+
116+
window._settings = this.getSettings();
117+
window._settings.bind('show-hibernate', hibernate_row, 'active',
118+
Gio.SettingsBindFlags.DEFAULT);
119+
window._settings.bind('show-hybrid-sleep', hybrid_row, 'active',
120+
Gio.SettingsBindFlags.DEFAULT);
121+
window._settings.bind('show-suspend-then-hibernate', suspend_then_hibernate_row, 'active',
122+
Gio.SettingsBindFlags.DEFAULT);
108123
}
109124
}

schemas/org.gnome.shell.extensions.hibernate-status-button.gschema.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,14 @@
44
<key type="b" name="hibernate-works-check">
55
<default>true</default>
66
</key>
7+
<key type="b" name="show-hibernate">
8+
<default>true</default>
9+
</key>
10+
<key type="b" name="show-hybrid-sleep">
11+
<default>true</default>
12+
</key>
13+
<key type="b" name="show-suspend-then-hibernate">
14+
<default>true</default>
15+
</key>
716
</schema>
817
</schemalist>

0 commit comments

Comments
 (0)