My power menu looks the following and I want to have a hibernate option:
In Freya I was able to activate the hibernate option by following the steps outlined in this answer. I tried the same steps in Loki, but this didn't add the hibernate option.
My power menu looks the following and I want to have a hibernate option:
In Freya I was able to activate the hibernate option by following the steps outlined in this answer. I tried the same steps in Loki, but this didn't add the hibernate option.
I wanted this functionality as well but couldn't find it online anywhere. It looks like the Hibernate option was removed a long time ago because it fails on some systems (which perhaps was the case a long time ago :-). On my Dell XPS 9350, hibernate works just fine with elementary OS (via 'sudo systemctl hibernate').
This aspect of elementary OS is handled by the "wingpanel", and more specifically, by the wingpanel's session indicator application (the specific indicator that provides the 'power button' icon on the top right corner of the screen).
In order to get this functionality, I had to download the latest source code for the wingpanel session indicator, learn how to compile and install it, and learn how to add the missing functionality. If you have a background in coding it's fairly straight forward, if not, hopefully this guideline will help you figure it out.
Note, in order to hibernate as my regular user (and not the root user) I added the following to /etc/sudoers (although now I'm not sure if that's entirely necessary or not, previously I wrote my own indicator app to perform hiberntaion but this alternative is more elegant):
(where devin is my regular user name)
The changes I had to make were as follows. Note that instructions for building are shown later in this post.
/* * Copyright (c) 2011-2015 Tom Beckmann * * 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 2 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, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */ public class Session.Widgets.HibernateDialog : Gtk.Dialog { public HibernateDialog () { Object ( title: "", deletable: false, resizable: false, skip_taskbar_hint: true, skip_pager_hint: true, type_hint: Gdk.WindowTypeHint.DIALOG ); } construct { string icon_name, heading_text, button_text, content_text; icon_name = "system-log-out"; heading_text = "Are you sure you want to Hibernate this computer?"; content_text = "This will save the contents of RAM to disk and shut down the computer."; button_text = "Hibernate"; set_position (Gtk.WindowPosition.CENTER_ALWAYS); set_keep_above (true); stick (); var image = new Gtk.Image.from_icon_name (icon_name, Gtk.IconSize.DIALOG); image.valign = Gtk.Align.START; var heading = new Gtk.Label (heading_text); heading.get_style_context ().add_class ("primary"); heading.xalign = 0; var secondary_label = new Gtk.Label (content_text); secondary_label.xalign = 0; var grid = new Gtk.Grid (); grid.column_spacing = 12; grid.row_spacing = 6; grid.margin_left = grid.margin_right = grid.margin_bottom = 12; grid.attach (image, 0, 0, 1, 2); grid.attach (heading, 1, 0, 1, 1); grid.attach (secondary_label, 1, 1, 1, 1); var cancel = add_button (_("Cancel"), Gtk.ResponseType.CANCEL) as Gtk.Button; cancel.clicked.connect (() => { destroy (); }); var confirm = add_button (button_text, Gtk.ResponseType.OK) as Gtk.Button; confirm.get_style_context ().add_class ("destructive-action"); confirm.clicked.connect (() => { try { Posix.system("systemctl hibernate"); } catch (IOError e) { stderr.printf ("%s\n", e.message); } destroy (); }); set_default (confirm); get_content_area ().add (grid); var action_area = get_action_area (); action_area.margin = 6; } }
/* * Copyright (c) 2011-2017 elementary LLC. * * 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 2 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, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */ public class Session.Indicator : Wingpanel.Indicator { private const string ICON_NAME = "system-shutdown-symbolic"; private SystemInterface suspend_interface; private LockInterface lock_interface; private SeatInterface seat_interface; private Wingpanel.IndicatorManager.ServerType server_type; private Wingpanel.Widgets.OverlayIcon indicator_icon; private Wingpanel.Widgets.Separator users_separator; private Wingpanel.Widgets.Button lock_screen; private Wingpanel.Widgets.Button log_out; private Wingpanel.Widgets.Button suspend; private Wingpanel.Widgets.Button shutdown; private Wingpanel.Widgets.Button hibernate; private Session.Services.UserManager manager; private Gtk.Grid main_grid; private Session.Widgets.EndSessionDialog? shutdown_dialog = null; private Session.Widgets.HibernateDialog? hibernate_dialog = null; public Indicator (Wingpanel.IndicatorManager.ServerType server_type) { Object (code_name: Wingpanel.Indicator.SESSION, display_name: _("Session"), description: _("The session indicator")); this.server_type = server_type; } public override Gtk.Widget get_display_widget () { if (indicator_icon == null) { indicator_icon = new Wingpanel.Widgets.OverlayIcon (ICON_NAME); indicator_icon.button_press_event.connect ((e) => { if (e.button == Gdk.BUTTON_MIDDLE) { close (); show_shutdown_dialog (); return Gdk.EVENT_STOP; } return Gdk.EVENT_PROPAGATE; }); } return indicator_icon; } public override Gtk.Widget? get_widget () { if (main_grid == null) { init_interfaces (); main_grid = new Gtk.Grid (); main_grid.set_orientation (Gtk.Orientation.VERTICAL); log_out = new Wingpanel.Widgets.Button (_("Log Out…")); lock_screen = new Wingpanel.Widgets.Button (_("Lock")); shutdown = new Wingpanel.Widgets.Button (_("Shut Down…")); suspend = new Wingpanel.Widgets.Button (_("Suspend")); hibernate = new Wingpanel.Widgets.Button ("Hibernate"); if (server_type == Wingpanel.IndicatorManager.ServerType.SESSION) { users_separator = new Wingpanel.Widgets.Separator (); manager = new Session.Services.UserManager (users_separator); var scrolled_box = new Wingpanel.Widgets.AutomaticScrollBox (null, null); scrolled_box.max_height = 300; scrolled_box.set_policy (Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC); scrolled_box.add (manager.user_grid); main_grid.add (scrolled_box); if (manager.has_guest) { manager.add_guest (false); } main_grid.add (users_separator); main_grid.add (lock_screen); main_grid.add (log_out); main_grid.add (new Wingpanel.Widgets.Separator ()); } main_grid.add (suspend); main_grid.add (hibernate); main_grid.add (shutdown); main_grid.margin_top = 6; connections (); } this.visible = true; return main_grid; } private void init_interfaces () { try { suspend_interface = Bus.get_proxy_sync (BusType.SYSTEM,"org.freedesktop.login1", "/org/freedesktop/login1"); } catch (IOError e) { stderr.printf ("%s\n", e.message); suspend.set_sensitive (false); } if (server_type == Wingpanel.IndicatorManager.ServerType.SESSION) { try { lock_interface = Bus.get_proxy_sync(BusType.SESSION, "org.freedesktop.ScreenSaver", "/org/freedesktop/ScreenSaver"); } catch (IOError e) { stderr.printf ("%s\n", e.message); lock_screen.set_sensitive (false); } try { seat_interface = Bus.get_proxy_sync (BusType.SESSION, "org.freedesktop.DisplayManager","/org/freedesktop/DisplayManager/Seat0"); } catch (IOError e) { stderr.printf ("%s\n", e.message); lock_screen.set_sensitive (false); } } } public void connections () { manager.close.connect (() => close ()); lock_screen.clicked.connect (() => { close (); try { lock_interface.lock (); } catch (IOError e) { stderr.printf ("%s\n", e.message); } }); log_out.clicked.connect (() => { close (); var dialog = new Session.Widgets.EndSessionDialog (Session.Widgets.EndSessionDialogType.LOGOUT); dialog.set_transient_for (indicator_icon.get_toplevel () as Gtk.Window); dialog.show_all (); }); shutdown.clicked.connect (() => { close (); show_shutdown_dialog (); }); hibernate.clicked.connect (() => { close (); show_hibernate_dialog (); }); suspend.clicked.connect (() => { close (); try { suspend_interface.suspend (true); } catch (IOError e) { stderr.printf ("%s\n", e.message); } }); } public override void opened () { manager.update_all (); } public override void closed () {} private void show_shutdown_dialog () { if (shutdown_dialog == null) { shutdown_dialog = new Session.Widgets.EndSessionDialog (Session.Widgets.EndSessionDialogType.RESTART); shutdown_dialog.destroy.connect (() => { shutdown_dialog = null; }); shutdown_dialog.set_transient_for (indicator_icon.get_toplevel () as Gtk.Window); shutdown_dialog.show_all (); } shutdown_dialog.present (); } private void show_hibernate_dialog () { if (hibernate_dialog == null) { hibernate_dialog = new Session.Widgets.HibernateDialog (); hibernate_dialog.destroy.connect (() => { hibernate_dialog = null; }); hibernate_dialog.set_transient_for (indicator_icon.get_toplevel () as Gtk.Window); hibernate_dialog.show_all (); } hibernate_dialog.present (); } } public Wingpanel.Indicator? get_indicator (Module module, Wingpanel.IndicatorManager.ServerType server_type) { debug ("Activating Sample Indicator"); var indicator = new Session.Indicator (server_type); return indicator; }
find_package (PkgConfig) # Add all your dependencies to the list below pkg_check_modules (DEPS REQUIRED gthread-2.0 gtk+-3.0 gio-2.0 accountsservice wingpanel-2.0 granite) add_definitions (${DEPS_CFLAGS}) link_directories (${DEPS_LIBRARY_DIRS}) find_package (Vala REQUIRED) include (ValaVersion) ensure_vala_version ("0.22.0" MINIMUM) include (ValaPrecompile) # Add all your vala files and requires packages to the List below to include them in the build vala_precompile (VALA_C ${CMAKE_PROJECT_NAME} Indicator.vala Widgets/UserBox.vala Widgets/UserListBox.vala Widgets/EndSessionDialog.vala Widgets/HibernateDialog.vala Services/UserManager.vala Services/DbusInterfaces.vala ${CMAKE_CURRENT_BINARY_DIR}/config.vala PACKAGES gio-2.0 gtk+-3.0 wingpanel-2.0 granite AccountsService-1.0 posix OPTIONS --thread ) add_library (${CMAKE_PROJECT_NAME} MODULE ${VALA_C}) target_link_libraries(${CMAKE_PROJECT_NAME} ${DEPS_LIBRARIES}) # Installation install (TARGETS ${CMAKE_PROJECT_NAME} DESTINATION ${PKGDATADIR})
Rough guideline for recompiling and installing a new wingpanel session indicator is as follows. You'll likely need to install several missing libraries for it to compile to completion.
For example, if you get an error about a dependency missing, then use "sudo apt-cache search dependency_name" to find it. It was fairly straight forward when I tried this. I think there was one exception though, which was 'sudo apt-get install elementary-sdk' (for "GObject").
Note: I replaced the shutdown logo with my own logo. To do this, find all "system-shutdown-symbolic" icons in /usr/share and replace them with your own .svg icon file. For example, find the existing ones via:
find /usr/share -name '*system-shutdown-symbolic*'
Note: I didn't care about the various translations for i18n so I just used hard coded English strings instead of _("string"). I didn't feel like learning about i18n for this as I'm only ever using my PC in English.
a simple solution may be: 1. go to system settings -> power. 2. enable hibernate for power button.
everytime you want to hibernate the system, just press power button.
You could install pm-utils
(sudo apt install pm-utils
). It worked for me, although it doesn't appear in the power menu, I could hibernate by calling:
sudo pm-hibernate
And it will hibernate.
You could assign your power button to hibernate the system by going to system settings -> Power -> select "Hibernate" next to "power button" like so:
Hope that helps.
Cheers!
Setting up a swapfile, and adding pm-utils and uswsusp worked for me just fine with sudo pm-hibernate, but no way to add it in the power menu without rebuilding wingpanel....ouch.