From 32f6b25a155e5b73636b39a33f92f2c88a94c1cc Mon Sep 17 00:00:00 2001 From: poma Date: Wed, 17 Aug 2016 01:57:12 +0200 Subject: [PATCH] Hybrid Sleep support - "hibernate" and suspend the system Hybrid Sleep initially only writes hibernation image to SWAP space, it does not power off the machine, as a whole Suspend To Disk (S4) does, it rather Suspend To RAM (S3). The benefit of this combination is pronto RESUME from S3, whilst in case of battery drained or interruptions in power supply of any kind, you ain't gonna lose your work. Hybrid Sleep is the feature of the Linux kernel. To test it directly via cli: echo suspend > /sys/power/disk ; echo disk > /sys/power/state However to make this feature work, both Suspend To RAM (S3) and Suspend To Disk (S4) must be provided by the hardware dmesg: ACPI: (supports ... S3 S4 ...) in working order. Furthermore Suspend To Disk (S4) requires a relatively simple configuration an appendix to kernel command line: resume= i.e. directive to utilize particular SWAP space man 7 dracut.cmdline Ref. https://www.kernel.org/doc/Documentation/power/swsusp.txt --- configure.ac.in | 2 +- xfce4-session-logout/main.c | 17 ++++++++ xfce4-session-logout/xfce4-session-logout.1 | 3 ++ xfce4-session/xfsm-consolekit.c | 41 +++++++++++++++++++ xfce4-session/xfsm-consolekit.h | 20 +++++++--- xfce4-session/xfsm-logout-dialog.c | 35 ++++++++++++++++- xfce4-session/xfsm-manager-dbus.xml | 16 ++++++++ xfce4-session/xfsm-manager.c | 61 ++++++++++++++++++++++++++++- xfce4-session/xfsm-shutdown-fallback.c | 51 ++++++++++++++++++++++-- xfce4-session/xfsm-shutdown-fallback.h | 14 ++++--- xfce4-session/xfsm-shutdown.c | 59 ++++++++++++++++++++++++++++ xfce4-session/xfsm-shutdown.h | 9 +++++ xfce4-session/xfsm-systemd.c | 34 ++++++++++++++++ xfce4-session/xfsm-systemd.h | 10 ++++- 14 files changed, 351 insertions(+), 21 deletions(-) diff --git a/configure.ac.in b/configure.ac.in index 738fd71..622a54c 100644 --- a/configure.ac.in +++ b/configure.ac.in @@ -186,7 +186,7 @@ AC_DEFINE_UNQUOTED(BACKEND, "$with_backend", [backend]) AC_SUBST(BACKEND, "$with_backend") if test x$with_backend = xlinux; then - AC_DEFINE(BACKEND_TYPE_LINUX, 1, [Linux suspend/hibernate backend]) + AC_DEFINE(BACKEND_TYPE_LINUX, 1, [Linux suspend/hibernate/hybrid-sleep backend]) fi if test x$with_backend = xfreebsd; then AC_DEFINE(BACKEND_TYPE_FREEBSD, 1, [FreeBSD suspend/hibernate backend]) diff --git a/xfce4-session-logout/main.c b/xfce4-session-logout/main.c index e94d015..8ced69a 100644 --- a/xfce4-session-logout/main.c +++ b/xfce4-session-logout/main.c @@ -47,6 +47,7 @@ gboolean opt_halt = FALSE; gboolean opt_reboot = FALSE; gboolean opt_suspend = FALSE; gboolean opt_hibernate = FALSE; +gboolean opt_hybrid_sleep = FALSE; gboolean opt_switch_user = FALSE; gboolean opt_fast = FALSE; gboolean opt_version = FALSE; @@ -59,6 +60,7 @@ enum XFSM_SHUTDOWN_REBOOT, XFSM_SHUTDOWN_SUSPEND, XFSM_SHUTDOWN_HIBERNATE, + XFSM_SHUTDOWN_HYBRID_SLEEP, XFSM_SHUTDOWN_SWITCH_USER }; @@ -84,6 +86,10 @@ static GOptionEntry option_entries[] = N_("Hibernate without displaying the logout dialog"), NULL }, + { "hybrid-sleep", 'h', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &opt_hybrid_sleep, + N_("Hybrid Sleep without displaying the logout dialog"), + NULL + }, { "switch-user", 'u', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &opt_switch_user, N_("Switch user without displaying the logout dialog"), NULL @@ -200,6 +206,15 @@ main (int argc, char **argv) NULL, &err); } + else if (opt_hybrid_sleep) + { + result = g_dbus_proxy_call_sync (proxy, "HybridSleep", + g_variant_new("()"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err); + } else if (opt_switch_user) { result = g_dbus_proxy_call_sync (proxy, "SwitchUser", @@ -240,6 +255,8 @@ main (int argc, char **argv) shutdown_type = XFSM_SHUTDOWN_SUSPEND; else if (opt_hibernate) shutdown_type = XFSM_SHUTDOWN_HIBERNATE; + else if (opt_hybrid_sleep) + shutdown_type = XFSM_SHUTDOWN_HYBRID_SLEEP; else if (opt_switch_user) shutdown_type = XFSM_SHUTDOWN_SWITCH_USER; else diff --git a/xfce4-session-logout/xfce4-session-logout.1 b/xfce4-session-logout/xfce4-session-logout.1 index bbcc365..30ce971 100644 --- a/xfce4-session-logout/xfce4-session-logout.1 +++ b/xfce4-session-logout/xfce4-session-logout.1 @@ -34,6 +34,9 @@ Suspend without displaying the logout dialog. .B \-\-hibernate Hibernate without displaying the logout dialog. .TP +.B \-\-hybrid-sleep +Hybrid Sleep without displaying the logout dialog. +.TP .B \-\-fast Do a fast shutdown. This instructs the session manager not to save the session, but instead to quit everything diff --git a/xfce4-session/xfsm-consolekit.c b/xfce4-session/xfsm-consolekit.c index 33a995f..00859e6 100644 --- a/xfce4-session/xfsm-consolekit.c +++ b/xfce4-session/xfsm-consolekit.c @@ -452,6 +452,33 @@ xfsm_consolekit_try_hibernate (XfsmConsolekit *consolekit, gboolean +xfsm_consolekit_try_hybrid_sleep (XfsmConsolekit *consolekit, + GError **error) +{ + gboolean can_hybrid_sleep, auth_hybrid_sleep; + + g_return_val_if_fail (XFSM_IS_CONSOLEKIT (consolekit), FALSE); + + /* Check if consolekit can hybrid sleep before we call lock screen. */ + if (xfsm_consolekit_can_hybrid_sleep (consolekit, &can_hybrid_sleep, &auth_hybrid_sleep, NULL)) + { + if (!can_hybrid_sleep) + return FALSE; + } + else + { + return FALSE; + } + + if (!lock_screen (consolekit, error)) + return FALSE; + + return xfsm_consolekit_try_sleep (consolekit, "HybridSleep", error); +} + + + +gboolean xfsm_consolekit_can_suspend (XfsmConsolekit *consolekit, gboolean *can_suspend, gboolean *auth_suspend, @@ -476,3 +503,17 @@ xfsm_consolekit_can_hibernate (XfsmConsolekit *consolekit, return xfsm_consolekit_can_sleep (consolekit, "CanHibernate", can_hibernate, auth_hibernate, error); } + + + +gboolean +xfsm_consolekit_can_hybrid_sleep (XfsmConsolekit *consolekit, + gboolean *can_hybrid_sleep, + gboolean *auth_hybrid_sleep, + GError **error) +{ + g_return_val_if_fail (XFSM_IS_CONSOLEKIT (consolekit), FALSE); + + return xfsm_consolekit_can_sleep (consolekit, "CanHybridSleep", + can_hybrid_sleep, auth_hybrid_sleep, error); +} diff --git a/xfce4-session/xfsm-consolekit.h b/xfce4-session/xfsm-consolekit.h index 413ad68..556e716 100644 --- a/xfce4-session/xfsm-consolekit.h +++ b/xfce4-session/xfsm-consolekit.h @@ -54,18 +54,26 @@ gboolean xfsm_consolekit_can_shutdown (XfsmConsolekit *consolekit, gboolean xfsm_consolekit_try_suspend (XfsmConsolekit *consolekit, GError **error); -gboolean xfsm_consolekit_try_hibernate(XfsmConsolekit *consolekit, - GError **error); +gboolean xfsm_consolekit_try_hibernate (XfsmConsolekit *consolekit, + GError **error); + +gboolean xfsm_consolekit_try_hybrid_sleep (XfsmConsolekit *consolekit, + GError **error); gboolean xfsm_consolekit_can_suspend (XfsmConsolekit *consolekit, gboolean *can_suspend, gboolean *auth_suspend, GError **error); -gboolean xfsm_consolekit_can_hibernate(XfsmConsolekit *consolekit, - gboolean *can_hibernate, - gboolean *auth_hibernate, - GError **error); +gboolean xfsm_consolekit_can_hibernate (XfsmConsolekit *consolekit, + gboolean *can_hibernate, + gboolean *auth_hibernate, + GError **error); + +gboolean xfsm_consolekit_can_hybrid_sleep (XfsmConsolekit *consolekit, + gboolean *can_hybrid_sleep, + gboolean *auth_hybrid_sleep, + GError **error); #endif /* !__XFSM_CONSOLEKIT_HELPER_H__ */ diff --git a/xfce4-session/xfsm-logout-dialog.c b/xfce4-session/xfsm-logout-dialog.c index 83863ea..74cc8e0 100644 --- a/xfce4-session/xfsm-logout-dialog.c +++ b/xfce4-session/xfsm-logout-dialog.c @@ -146,9 +146,11 @@ xfsm_logout_dialog_init (XfsmLogoutDialog *dialog) gboolean can_restart; gboolean can_suspend = FALSE; gboolean can_hibernate = FALSE; + gboolean can_hybrid_sleep = FALSE; gboolean can_switch_user = FALSE; gboolean auth_suspend = FALSE; gboolean auth_hibernate = FALSE; + gboolean auth_hybrid_sleep = FALSE; GError *error = NULL; XfconfChannel *channel; GtkWidget *image; @@ -269,7 +271,7 @@ xfsm_logout_dialog_init (XfsmLogoutDialog *dialog) gtk_widget_set_sensitive (button, can_shutdown); gtk_widget_show (button); - /* new row for suspend/hibernate */ + /* new row for suspend/hibernate/hybrid sleep */ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, BORDER); gtk_box_pack_start (GTK_BOX (button_vbox), hbox, FALSE, TRUE, 0); @@ -338,6 +340,37 @@ xfsm_logout_dialog_init (XfsmLogoutDialog *dialog) } /** + * Hybrid Sleep + * + * Hide the button if UPower is not installed or system cannot suspend + **/ + if (!upower_not_found + && xfconf_channel_get_bool (channel, "/shutdown/ShowHybridSleep", TRUE)) + { + if (xfsm_shutdown_can_hybrid_sleep (dialog->shutdown, &can_hybrid_sleep, &auth_hybrid_sleep, &error)) + { + if (can_hybrid_sleep) + { + button = xfsm_logout_dialog_button (_("_Hybrid Sleep"), "system-hibernate", + "xfsm-hibernate", XFSM_SHUTDOWN_HYBRID_SLEEP, + dialog); + + gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); + gtk_widget_set_sensitive (button, auth_hybrid_sleep); + gtk_widget_show (button); + + gtk_widget_show (hbox); + } + } + else + { + g_printerr ("%s: Querying hybrid-sleep failed: %s\n\n", + PACKAGE_NAME, ERROR_MSG (error)); + g_clear_error (&error); + } + } + + /** * Switch User * * Hide the button if system cannot switch user, requires the display diff --git a/xfce4-session/xfsm-manager-dbus.xml b/xfce4-session/xfsm-manager-dbus.xml index 73dd663..c4b6735 100644 --- a/xfce4-session/xfsm-manager-dbus.xml +++ b/xfce4-session/xfsm-manager-dbus.xml @@ -149,6 +149,22 @@ + + + + + + + + diff --git a/xfce4-session/xfsm-manager.c b/xfce4-session/xfsm-manager.c index c9ed0e3..2bb68bd 100644 --- a/xfce4-session/xfsm-manager.c +++ b/xfce4-session/xfsm-manager.c @@ -1201,10 +1201,11 @@ xfsm_manager_save_yourself_global (XfsmManager *manager, manager->shutdown_type = shutdown_type; /* we only save the session and quit if we're actually shutting down; - * suspend, hibernate, and switch user will (if successful) return us to + * suspend, hibernate, hybrid sleep and switch user will (if successful) return us to * exactly the same state, so there's no need to save session */ if (manager->shutdown_type == XFSM_SHUTDOWN_SUSPEND || manager->shutdown_type == XFSM_SHUTDOWN_HIBERNATE + || manager->shutdown_type == XFSM_SHUTDOWN_HYBRID_SLEEP || manager->shutdown_type == XFSM_SHUTDOWN_SWITCH_USER) { if (!xfsm_shutdown_try_type (manager->shutdown_helper, @@ -1218,6 +1219,8 @@ xfsm_manager_save_yourself_global (XfsmManager *manager, ? _("Failed to suspend session") : manager->shutdown_type == XFSM_SHUTDOWN_HIBERNATE ? _("Failed to hibernate session") + : manager->shutdown_type == XFSM_SHUTDOWN_HYBRID_SLEEP + ? _("Failed to hybrid sleep session") : _("Failed to switch user"), error->message, XFCE_BUTTON_TYPE_MIXED, "window-close", _("_Close"), GTK_RESPONSE_ACCEPT, @@ -1225,7 +1228,7 @@ xfsm_manager_save_yourself_global (XfsmManager *manager, g_error_free (error); } - /* at this point, either we failed to suspend/hibernate/switch user, + /* at this point, either we failed to suspend/hibernate/hybrid sleep/switch user, * or we successfully did and we've been woken back * up or returned to the session, so return control to the user */ return; @@ -1970,6 +1973,10 @@ static gboolean xfsm_manager_dbus_hibernate (XfsmDbusManager *object, GDBusMethodInvocation *invocation); static gboolean xfsm_manager_dbus_can_hibernate (XfsmDbusManager *object, GDBusMethodInvocation *invocation); +static gboolean xfsm_manager_dbus_hybrid_sleep (XfsmDbusManager *object, + GDBusMethodInvocation *invocation); +static gboolean xfsm_manager_dbus_can_hybrid_sleep (XfsmDbusManager *object, + GDBusMethodInvocation *invocation); static gboolean xfsm_manager_dbus_switch_user (XfsmDbusManager *object, GDBusMethodInvocation *invocation); static gboolean xfsm_manager_dbus_register_client (XfsmDbusManager *object, @@ -2071,6 +2078,7 @@ static void xfsm_manager_iface_init (XfsmDbusManagerIface *iface) { iface->handle_can_hibernate = xfsm_manager_dbus_can_hibernate; + iface->handle_can_hybrid_sleep = xfsm_manager_dbus_can_hybrid_sleep; iface->handle_can_restart = xfsm_manager_dbus_can_restart; iface->handle_can_shutdown = xfsm_manager_dbus_can_shutdown; iface->handle_can_suspend = xfsm_manager_dbus_can_suspend; @@ -2078,6 +2086,7 @@ xfsm_manager_iface_init (XfsmDbusManagerIface *iface) iface->handle_get_info = xfsm_manager_dbus_get_info; iface->handle_get_state = xfsm_manager_dbus_get_state; iface->handle_hibernate = xfsm_manager_dbus_hibernate; + iface->handle_hybrid_sleep = xfsm_manager_dbus_hybrid_sleep; iface->handle_switch_user = xfsm_manager_dbus_switch_user; iface->handle_list_clients = xfsm_manager_dbus_list_clients; iface->handle_logout = xfsm_manager_dbus_logout; @@ -2442,6 +2451,54 @@ xfsm_manager_dbus_can_hibernate (XfsmDbusManager *object, } static gboolean +xfsm_manager_dbus_hybrid_sleep (XfsmDbusManager *object, + GDBusMethodInvocation *invocation) +{ + GError *error = NULL; + + xfsm_verbose ("entering\n"); + + g_return_val_if_fail (XFSM_IS_MANAGER (object), FALSE); + if (xfsm_shutdown_try_hybrid_sleep (XFSM_MANAGER (object)->shutdown_helper, &error) == FALSE) + { + throw_error (invocation, XFSM_ERROR_BAD_STATE, error->message); + g_clear_error (&error); + return TRUE; + } + + xfsm_dbus_manager_complete_hybrid_sleep (object, invocation); + return TRUE; +} + +static gboolean +xfsm_manager_dbus_can_hybrid_sleep (XfsmDbusManager *object, + GDBusMethodInvocation *invocation) +{ + gboolean auth_hybrid_sleep = FALSE; + gboolean can_hybrid_sleep = FALSE; + GError *error = NULL; + + xfsm_verbose ("entering\n"); + + g_return_val_if_fail (XFSM_IS_MANAGER (object), FALSE); + + xfsm_shutdown_can_hybrid_sleep (XFSM_MANAGER (object)->shutdown_helper, &can_hybrid_sleep, &auth_hybrid_sleep, &error); + + if (error) + { + throw_error (invocation, XFSM_ERROR_BAD_STATE, error->message); + g_clear_error(&error); + return TRUE; + } + + if (!auth_hybrid_sleep) + can_hybrid_sleep = FALSE; + + xfsm_dbus_manager_complete_can_hybrid_sleep (object, invocation, can_hybrid_sleep); + return TRUE; +} + +static gboolean xfsm_manager_dbus_switch_user (XfsmDbusManager *object, GDBusMethodInvocation *invocation) { diff --git a/xfce4-session/xfsm-shutdown-fallback.c b/xfce4-session/xfsm-shutdown-fallback.c index c9d8222..1903161 100644 --- a/xfce4-session/xfsm-shutdown-fallback.c +++ b/xfce4-session/xfsm-shutdown-fallback.c @@ -68,10 +68,11 @@ #include -#define POLKIT_AUTH_SHUTDOWN_XFSM "org.xfce.session.xfsm-shutdown-helper" -#define POLKIT_AUTH_RESTART_XFSM "org.xfce.session.xfsm-shutdown-helper" -#define POLKIT_AUTH_SUSPEND_XFSM "org.xfce.session.xfsm-shutdown-helper" -#define POLKIT_AUTH_HIBERNATE_XFSM "org.xfce.session.xfsm-shutdown-helper" +#define POLKIT_AUTH_SHUTDOWN_XFSM "org.xfce.session.xfsm-shutdown-helper" +#define POLKIT_AUTH_RESTART_XFSM "org.xfce.session.xfsm-shutdown-helper" +#define POLKIT_AUTH_SUSPEND_XFSM "org.xfce.session.xfsm-shutdown-helper" +#define POLKIT_AUTH_HIBERNATE_XFSM "org.xfce.session.xfsm-shutdown-helper" +#define POLKIT_AUTH_HYBRID_SLEEP_XFSM "org.xfce.session.xfsm-shutdown-helper" @@ -264,6 +265,12 @@ xfsm_shutdown_fallback_try_action (XfsmShutdownType type, if (!lock_screen (error)) return FALSE; break; + case XFSM_SHUTDOWN_HYBRID_SLEEP: + action = "hybrid-sleep"; + /* On hybrid sleep we try to lock the screen */ + if (!lock_screen (error)) + return FALSE; + break; default: return FALSE; } @@ -324,6 +331,29 @@ xfsm_shutdown_fallback_can_hibernate (void) /** + * xfsm_shutdown_fallback_can_hybrid_sleep: + * + * Return value: Returns whether the *system* is capable of hybrid sleep. + **/ +gboolean +xfsm_shutdown_fallback_can_hybrid_sleep (void) +{ +#ifdef BACKEND_TYPE_FREEBSD + return freebsd_supports_sleep_state ("S4"); +#endif +#ifdef BACKEND_TYPE_LINUX + return linux_supports_sleep_state ("hibernate"); +#endif +#ifdef BACKEND_TYPE_OPENBSD + return TRUE; +#endif + + return FALSE; +} + + + +/** * xfsm_shutdown_fallback_auth_shutdown: * * Return value: Returns whether the user is authorized to perform a shutdown. @@ -372,3 +402,16 @@ xfsm_shutdown_fallback_auth_hibernate (void) { return xfsm_shutdown_fallback_check_auth (POLKIT_AUTH_HIBERNATE_XFSM); } + + + +/** + * xfsm_shutdown_fallback_auth_hybrid_sleep: + * + * Return value: Returns whether the user is authorized to perform a hybrid sleep. + **/ +gboolean +xfsm_shutdown_fallback_auth_hybrid_sleep (void) +{ + return xfsm_shutdown_fallback_check_auth (POLKIT_AUTH_HYBRID_SLEEP_XFSM); +} diff --git a/xfce4-session/xfsm-shutdown-fallback.h b/xfce4-session/xfsm-shutdown-fallback.h index e4909e7..7bfc8e8 100644 --- a/xfce4-session/xfsm-shutdown-fallback.h +++ b/xfce4-session/xfsm-shutdown-fallback.h @@ -25,13 +25,15 @@ #include -gboolean xfsm_shutdown_fallback_auth_shutdown (void); -gboolean xfsm_shutdown_fallback_auth_restart (void); -gboolean xfsm_shutdown_fallback_auth_suspend (void); -gboolean xfsm_shutdown_fallback_auth_hibernate (void); +gboolean xfsm_shutdown_fallback_auth_shutdown (void); +gboolean xfsm_shutdown_fallback_auth_restart (void); +gboolean xfsm_shutdown_fallback_auth_suspend (void); +gboolean xfsm_shutdown_fallback_auth_hibernate (void); +gboolean xfsm_shutdown_fallback_auth_hybrid_sleep (void); -gboolean xfsm_shutdown_fallback_can_suspend (void); -gboolean xfsm_shutdown_fallback_can_hibernate (void); +gboolean xfsm_shutdown_fallback_can_suspend (void); +gboolean xfsm_shutdown_fallback_can_hibernate (void); +gboolean xfsm_shutdown_fallback_can_hybrid_sleep (void); gboolean xfsm_shutdown_fallback_try_action (XfsmShutdownType type, GError **error); diff --git a/xfce4-session/xfsm-shutdown.c b/xfce4-session/xfsm-shutdown.c index 5690176..bfcf0bf 100644 --- a/xfce4-session/xfsm-shutdown.c +++ b/xfce4-session/xfsm-shutdown.c @@ -209,6 +209,9 @@ xfsm_shutdown_try_type (XfsmShutdown *shutdown, case XFSM_SHUTDOWN_HIBERNATE: return xfsm_shutdown_try_hibernate (shutdown, error); + case XFSM_SHUTDOWN_HYBRID_SLEEP: + return xfsm_shutdown_try_hybrid_sleep (shutdown, error); + case XFSM_SHUTDOWN_SWITCH_USER: return xfsm_shutdown_try_switch_user (shutdown, error); @@ -333,6 +336,26 @@ xfsm_shutdown_try_hibernate (XfsmShutdown *shutdown, return xfsm_shutdown_fallback_try_action (XFSM_SHUTDOWN_HIBERNATE, error); } + + +gboolean +xfsm_shutdown_try_hybrid_sleep (XfsmShutdown *shutdown, + GError **error) +{ + g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE); + + /* Try each way to hybrid-sleep - it will handle NULL. + */ + + if (try_sleep_method (shutdown->systemd, (SleepFunc)xfsm_systemd_try_hybrid_sleep)) + return TRUE; + + if (try_sleep_method (shutdown->consolekit, (SleepFunc)xfsm_consolekit_try_hybrid_sleep)) + return TRUE; + + return xfsm_shutdown_fallback_try_action (XFSM_SHUTDOWN_HYBRID_SLEEP, error); +} + gboolean xfsm_shutdown_try_switch_user (XfsmShutdown *shutdown, GError **error) @@ -515,6 +538,42 @@ xfsm_shutdown_can_hibernate (XfsmShutdown *shutdown, gboolean +xfsm_shutdown_can_hybrid_sleep (XfsmShutdown *shutdown, + gboolean *can_hybrid_sleep, + gboolean *auth_hybrid_sleep, + GError **error) +{ + g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE); + + if (!xfsm_shutdown_kiosk_can_shutdown (shutdown, NULL)) + { + *can_hybrid_sleep = FALSE; + return TRUE; + } + + if (shutdown->systemd != NULL) + { + if (xfsm_systemd_can_hybrid_sleep (shutdown->systemd, can_hybrid_sleep, auth_hybrid_sleep, NULL)) + { + return TRUE; + } + } + else if (shutdown->consolekit != NULL) + { + if (xfsm_consolekit_can_hybrid_sleep (shutdown->consolekit, can_hybrid_sleep, auth_hybrid_sleep, NULL)) + { + return TRUE; + } + } + + *can_hybrid_sleep = xfsm_shutdown_fallback_can_hybrid_sleep (); + *auth_hybrid_sleep = xfsm_shutdown_fallback_auth_hybrid_sleep (); + return TRUE; +} + + + +gboolean xfsm_shutdown_can_switch_user (XfsmShutdown *shutdown, gboolean *can_switch_user, GError **error) diff --git a/xfce4-session/xfsm-shutdown.h b/xfce4-session/xfsm-shutdown.h index 0af91f3..5b69be8 100644 --- a/xfce4-session/xfsm-shutdown.h +++ b/xfce4-session/xfsm-shutdown.h @@ -40,6 +40,7 @@ typedef enum XFSM_SHUTDOWN_RESTART, XFSM_SHUTDOWN_SUSPEND, XFSM_SHUTDOWN_HIBERNATE, + XFSM_SHUTDOWN_HYBRID_SLEEP, XFSM_SHUTDOWN_SWITCH_USER, } XfsmShutdownType; @@ -79,6 +80,9 @@ gboolean xfsm_shutdown_try_suspend (XfsmShutdown *shutdown, gboolean xfsm_shutdown_try_hibernate (XfsmShutdown *shutdown, GError **error); +gboolean xfsm_shutdown_try_hybrid_sleep (XfsmShutdown *shutdown, + GError **error); + gboolean xfsm_shutdown_try_switch_user (XfsmShutdown *shutdown, GError **error); @@ -100,6 +104,11 @@ gboolean xfsm_shutdown_can_hibernate (XfsmShutdown *shutdown, gboolean *auth_hibernate, GError **error); +gboolean xfsm_shutdown_can_hybrid_sleep (XfsmShutdown *shutdown, + gboolean *can_hybrid_sleep, + gboolean *auth_hybrid_sleep, + GError **error); + gboolean xfsm_shutdown_can_switch_user (XfsmShutdown *shutdown, gboolean *can_switch_user, GError **error); diff --git a/xfce4-session/xfsm-systemd.c b/xfce4-session/xfsm-systemd.c index 3b69f0d..246fca0 100644 --- a/xfce4-session/xfsm-systemd.c +++ b/xfce4-session/xfsm-systemd.c @@ -37,10 +37,12 @@ #define SYSTEMD_POWEROFF_ACTION "PowerOff" #define SYSTEMD_SUSPEND_ACTION "Suspend" #define SYSTEMD_HIBERNATE_ACTION "Hibernate" +#define SYSTEMD_HYBRID_SLEEP_ACTION "HybridSleep" #define SYSTEMD_REBOOT_TEST "org.freedesktop.login1.reboot" #define SYSTEMD_POWEROFF_TEST "org.freedesktop.login1.power-off" #define SYSTEMD_SUSPEND_TEST "org.freedesktop.login1.suspend" #define SYSTEMD_HIBERNATE_TEST "org.freedesktop.login1.hibernate" +#define SYSTEMD_HYBRID_SLEEP_TEST "org.freedesktop.login1.hibernate" @@ -269,6 +271,20 @@ xfsm_systemd_try_hibernate (XfsmSystemd *systemd, gboolean +xfsm_systemd_try_hybrid_sleep (XfsmSystemd *systemd, + GError **error) +{ + if (!xfsm_systemd_lock_screen (systemd, error)) + return FALSE; + + return xfsm_systemd_try_method (systemd, + SYSTEMD_HYBRID_SLEEP_ACTION, + error); +} + + + +gboolean xfsm_systemd_can_restart (XfsmSystemd *systemd, gboolean *can_restart, GError **error) @@ -327,3 +343,21 @@ xfsm_systemd_can_hibernate (XfsmSystemd *systemd, *auth_hibernate = *can_hibernate; return ret; } + + + +gboolean +xfsm_systemd_can_hybrid_sleep (XfsmSystemd *systemd, + gboolean *can_hybrid_sleep, + gboolean *auth_hybrid_sleep, + GError **error) +{ + gboolean ret = FALSE; + + ret = xfsm_systemd_can_method (systemd, + can_hybrid_sleep, + SYSTEMD_HYBRID_SLEEP_TEST, + error); + *auth_hybrid_sleep = *can_hybrid_sleep; + return ret; +} diff --git a/xfce4-session/xfsm-systemd.h b/xfce4-session/xfsm-systemd.h index c5e74b5..9b3d897 100644 --- a/xfce4-session/xfsm-systemd.h +++ b/xfce4-session/xfsm-systemd.h @@ -48,7 +48,10 @@ gboolean xfsm_systemd_try_suspend (XfsmSystemd *systemd, GError **error); gboolean xfsm_systemd_try_hibernate (XfsmSystemd *systemd, - GError **error); + GError **error); + +gboolean xfsm_systemd_try_hybrid_sleep (XfsmSystemd *systemd, + GError **error); gboolean xfsm_systemd_can_restart (XfsmSystemd *systemd, gboolean *can_restart, @@ -68,6 +71,11 @@ gboolean xfsm_systemd_can_hibernate (XfsmSystemd *systemd, gboolean *auth_hibernate, GError **error); +gboolean xfsm_systemd_can_hybrid_sleep (XfsmSystemd *systemd, + gboolean *can_hybrid_sleep, + gboolean *auth_hybrid_sleep, + GError **error); + G_END_DECLS #endif /* __XFSM_SYSTEMD_H__ */ -- 2.7.4