@@ -11,7 +11,9 @@ import * as StatusSystem from 'resource:///org/gnome/shell/ui/status/system.js';
1111import * as PopupMenu from 'resource:///org/gnome/shell/ui/popupMenu.js' ;
1212import * as ExtensionSystem from 'resource:///org/gnome/shell/ui/extensionSystem.js' ;
1313import * as ModalDialog from 'resource:///org/gnome/shell/ui/modalDialog.js' ;
14+ import * as Dialog from 'resource:///org/gnome/shell/ui/dialog.js' ;
1415import * as CheckBoxImport from 'resource:///org/gnome/shell/ui/checkBox.js' ;
16+ import { loadInterfaceXML } from 'resource:///org/gnome/shell/misc/fileUtils.js' ;
1517
1618const 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
473516const _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- }
0 commit comments