From 3d390d0704342b2f6dcfddb467e93df85817ec5f Mon Sep 17 00:00:00 2001 From: Nico Kreipke Date: Sun, 15 Feb 2015 05:30:11 +0000 Subject: [PATCH] Support hybrid sleep for systemd users (experimental) --- common/xfpm-enum-glib.h | 4 +- settings/xfpm-settings-main.c | 4 +- settings/xfpm-settings.c | 39 ++++++++++++++- settings/xfpm-settings.h | 1 + src/xfpm-manager.c | 12 +++-- src/xfpm-power.c | 107 ++++++++++++++++++++++++++---------------- src/xfpm-power.h | 5 ++ src/xfpm-systemd.c | 15 ++++++ src/xfpm-xfconf.c | 4 +- 9 files changed, 142 insertions(+), 49 deletions(-) diff --git a/common/xfpm-enum-glib.h b/common/xfpm-enum-glib.h index c7cfe3f..65b0e08 100644 --- a/common/xfpm-enum-glib.h +++ b/common/xfpm-enum-glib.h @@ -45,7 +45,8 @@ typedef enum XFPM_DO_SUSPEND, XFPM_DO_HIBERNATE, XFPM_ASK, - XFPM_DO_SHUTDOWN + XFPM_DO_SHUTDOWN, + XFPM_DO_HYBRID_SLEEP } XfpmShutdownRequest; @@ -55,6 +56,7 @@ typedef enum LID_TRIGGER_SUSPEND, LID_TRIGGER_HIBERNATE, LID_TRIGGER_LOCK_SCREEN, + LID_TRIGGER_HYBRID_SLEEP = XFPM_DO_HYBRID_SLEEP } XfpmLidTriggerAction; diff --git a/settings/xfpm-settings-main.c b/settings/xfpm-settings-main.c index c27208a..ea04d20 100644 --- a/settings/xfpm-settings-main.c +++ b/settings/xfpm-settings-main.c @@ -61,6 +61,7 @@ int main (int argc, char **argv) gboolean can_suspend; gboolean can_hibernate; gboolean can_shutdown; + gboolean can_hybrid_sleep; gboolean has_lcd_brightness; gboolean has_sleep_button; gboolean has_hibernate_button; @@ -179,6 +180,7 @@ int main (int argc, char **argv) has_lid = xfpm_string_to_bool (g_hash_table_lookup (config_hash, "has-lid")); can_suspend = xfpm_string_to_bool (g_hash_table_lookup (config_hash, "can-suspend")); can_hibernate = xfpm_string_to_bool (g_hash_table_lookup (config_hash, "can-hibernate")); + can_hybrid_sleep = xfpm_string_to_bool (g_hash_table_lookup (config_hash, "can-hybrid-sleep")); auth_suspend = xfpm_string_to_bool (g_hash_table_lookup (config_hash, "auth-suspend")); auth_hibernate = xfpm_string_to_bool (g_hash_table_lookup (config_hash, "auth-hibernate")); has_lcd_brightness = xfpm_string_to_bool (g_hash_table_lookup (config_hash, "has-brightness")); @@ -190,7 +192,7 @@ int main (int argc, char **argv) g_hash_table_destroy (config_hash); dialog = xfpm_settings_dialog_new (channel, auth_suspend, auth_hibernate, - can_suspend, can_hibernate, can_shutdown, has_battery, has_lcd_brightness, + can_suspend, can_hibernate, can_shutdown, can_hybrid_sleep, has_battery, has_lcd_brightness, has_lid, has_sleep_button, has_hibernate_button, has_power_button, socket_id, device_id); diff --git a/settings/xfpm-settings.c b/settings/xfpm-settings.c index 44b8086..df096f2 100644 --- a/settings/xfpm-settings.c +++ b/settings/xfpm-settings.c @@ -850,6 +850,7 @@ static void xfpm_settings_on_battery (XfconfChannel *channel, gboolean auth_suspend, gboolean auth_hibernate, gboolean can_suspend, gboolean can_hibernate, gboolean can_shutdown, + gboolean can_hybrid_sleep, gboolean has_lcd_brightness, gboolean has_lid) { gboolean valid, handle_dpms; @@ -884,6 +885,16 @@ xfpm_settings_on_battery (XfconfChannel *channel, gboolean auth_suspend, { gtk_widget_set_tooltip_text (inact_action, _("Suspend operation not supported")); } + + if ( can_hybrid_sleep && auth_suspend && auth_hibernate ) + { + gtk_list_store_append(list_store, &iter); + gtk_list_store_set (list_store, &iter, 0, _("Hybrid Sleep"), 1, XFPM_DO_HYBRID_SLEEP, -1); + } + else + { + gtk_widget_set_tooltip_text (inact_action, _("Hybrid sleep operation not supported")); + } if ( can_hibernate ) { @@ -898,6 +909,7 @@ xfpm_settings_on_battery (XfconfChannel *channel, gboolean auth_suspend, { gtk_widget_set_tooltip_text (inact_action, _("Hibernate operation not supported")); } + gtk_combo_box_set_active (GTK_COMBO_BOX (inact_action), 0); @@ -1076,6 +1088,7 @@ static void xfpm_settings_on_ac (XfconfChannel *channel, gboolean auth_suspend, gboolean auth_hibernate, gboolean can_suspend, gboolean can_hibernate, gboolean has_lcd_brightness, + gboolean can_hybrid_sleep, gboolean has_lid) { gboolean valid, handle_dpms; @@ -1110,6 +1123,16 @@ xfpm_settings_on_ac (XfconfChannel *channel, gboolean auth_suspend, { gtk_widget_set_tooltip_text (inact_action, _("Suspend operation not supported")); } + + if ( can_hybrid_sleep && auth_suspend && auth_hibernate ) + { + gtk_list_store_append(list_store, &iter); + gtk_list_store_set (list_store, &iter, 0, _("Hybrid Sleep"), 1, XFPM_DO_HYBRID_SLEEP, -1); + } + else + { + gtk_widget_set_tooltip_text (inact_action, _("Hybrid sleep operation not supported")); + } if ( can_hibernate ) { @@ -1255,6 +1278,7 @@ static void xfpm_settings_general (XfconfChannel *channel, gboolean auth_suspend, gboolean auth_hibernate, gboolean can_suspend, gboolean can_hibernate, gboolean can_shutdown, + gboolean can_hybrid_sleep, gboolean has_sleep_button, gboolean has_hibernate_button, gboolean has_power_button) { @@ -1302,6 +1326,13 @@ xfpm_settings_general (XfconfChannel *channel, gboolean auth_suspend, gtk_list_store_append (list_store, &iter); gtk_list_store_set (list_store, &iter, 0, _("Suspend"), 1, XFPM_DO_SUSPEND, -1); } + + if ( can_hybrid_sleep && auth_suspend && auth_hibernate ) + { + gtk_list_store_append(list_store, &iter); + gtk_list_store_set (list_store, &iter, 0, _("Hybrid Sleep"), 1, XFPM_DO_HYBRID_SLEEP, -1); + } + if ( can_hibernate && auth_hibernate ) { @@ -2247,6 +2278,7 @@ GtkWidget * xfpm_settings_dialog_new (XfconfChannel *channel, gboolean auth_suspend, gboolean auth_hibernate, gboolean can_suspend, gboolean can_hibernate, gboolean can_shutdown, + gboolean can_hybrid_sleep, gboolean has_battery, gboolean has_lcd_brightness, gboolean has_lid, gboolean has_sleep_button, gboolean has_hibernate_button, gboolean has_power_button, @@ -2264,12 +2296,13 @@ xfpm_settings_dialog_new (XfconfChannel *channel, gboolean auth_suspend, GError *error = NULL; guint val; - XFPM_DEBUG ("auth_hibernate=%s auth_suspend=%s can_shutdown=%s can_suspend=%s can_hibernate=%s " \ + XFPM_DEBUG ("auth_hibernate=%s auth_suspend=%s can_shutdown=%s can_suspend=%s can_hibernate=%s can_hybrid_sleep=%s " \ "has_battery=%s has_lcd_brightness=%s has_lid=%s has_sleep_button=%s " \ "has_hibernate_button=%s has_power_button=%s", xfpm_bool_to_string (has_battery), xfpm_bool_to_string (auth_hibernate), xfpm_bool_to_string (can_shutdown), xfpm_bool_to_string (auth_suspend), xfpm_bool_to_string (can_suspend), xfpm_bool_to_string (can_hibernate), + xfpm_bool_to_string (can_hybrid_sleep), xfpm_bool_to_string (has_lcd_brightness), xfpm_bool_to_string (has_lid), xfpm_bool_to_string (has_sleep_button), xfpm_bool_to_string (has_hibernate_button), xfpm_bool_to_string (has_power_button)); @@ -2362,6 +2395,7 @@ xfpm_settings_dialog_new (XfconfChannel *channel, gboolean auth_suspend, auth_hibernate, can_suspend, can_hibernate, + can_hybrid_sleep, has_lcd_brightness, has_lid); @@ -2371,6 +2405,7 @@ xfpm_settings_dialog_new (XfconfChannel *channel, gboolean auth_suspend, auth_hibernate, can_suspend, can_hibernate, + can_hybrid_sleep, can_shutdown, has_lcd_brightness, has_lid); @@ -2397,7 +2432,7 @@ xfpm_settings_dialog_new (XfconfChannel *channel, gboolean auth_suspend, } xfpm_settings_general (channel, auth_suspend, auth_hibernate, can_suspend, can_hibernate, can_shutdown, - has_sleep_button, has_hibernate_button, has_power_button ); + can_hybrid_sleep, has_sleep_button, has_hibernate_button, has_power_button ); xfpm_settings_advanced (channel, auth_suspend, auth_hibernate, can_suspend, can_hibernate, has_battery); diff --git a/settings/xfpm-settings.h b/settings/xfpm-settings.h index b5a6cb4..91abf30 100644 --- a/settings/xfpm-settings.h +++ b/settings/xfpm-settings.h @@ -27,6 +27,7 @@ GtkWidget *xfpm_settings_dialog_new (XfconfChannel *channel, gboolean auth_hibernate, gboolean can_suspend, gboolean can_hibernate, + gboolean can_hybrid_sleep, gboolean can_shutdown, gboolean has_battery, gboolean has_lcd_brightness, diff --git a/src/xfpm-manager.c b/src/xfpm-manager.c index 9549b66..b8302e8 100644 --- a/src/xfpm-manager.c +++ b/src/xfpm-manager.c @@ -258,6 +258,9 @@ xfpm_manager_sleep_request (XfpmManager *manager, XfpmShutdownRequest req, gbool case XFPM_DO_SHUTDOWN: xfpm_manager_shutdown (manager); break; + case XFPM_DO_HYBRID_SLEEP: + xfpm_power_hybrid_sleep (manager->priv->power, force); + break; case XFPM_ASK: xfpm_manager_ask_shutdown (manager); break; @@ -777,6 +780,7 @@ GHashTable *xfpm_manager_get_config (XfpmManager *manager) gboolean auth_suspend = FALSE; gboolean can_suspend = FALSE; gboolean can_hibernate = FALSE; + gboolean can_hybrid_sleep = FALSE; gboolean has_sleep_button = FALSE; gboolean has_hibernate_button = FALSE; gboolean has_power_button = FALSE; @@ -802,11 +806,12 @@ GHashTable *xfpm_manager_get_config (XfpmManager *manager) g_object_get (G_OBJECT (manager->priv->power), "auth-suspend", &auth_suspend, - "auth-hibernate", &auth_hibernate, + "auth-hibernate", &auth_hibernate, "can-suspend", &can_suspend, "can-hibernate", &can_hibernate, - "has-lid", &has_lid, - NULL); + "can-hybrid-sleep", &can_hybrid_sleep, + "has-lid", &has_lid, + NULL); has_battery = xfpm_power_has_battery (manager->priv->power); has_lcd_brightness = xfpm_backlight_has_hw (manager->priv->backlight); @@ -828,6 +833,7 @@ GHashTable *xfpm_manager_get_config (XfpmManager *manager) g_hash_table_insert (hash, g_strdup ("can-suspend"), g_strdup (xfpm_bool_to_string (can_suspend))); g_hash_table_insert (hash, g_strdup ("can-hibernate"), g_strdup (xfpm_bool_to_string (can_hibernate))); g_hash_table_insert (hash, g_strdup ("can-shutdown"), g_strdup (xfpm_bool_to_string (can_shutdown))); + g_hash_table_insert (hash, g_strdup ("can-hybrid-sleep"), g_strdup (xfpm_bool_to_string (can_hybrid_sleep))); g_hash_table_insert (hash, g_strdup ("has-battery"), g_strdup (xfpm_bool_to_string (has_battery))); g_hash_table_insert (hash, g_strdup ("has-lid"), g_strdup (xfpm_bool_to_string (has_lid))); diff --git a/src/xfpm-power.c b/src/xfpm-power.c index 07085ff..f2f0a2b 100644 --- a/src/xfpm-power.c +++ b/src/xfpm-power.c @@ -128,6 +128,7 @@ struct XfpmPowerPrivate gchar *daemon_version; gboolean can_suspend; gboolean can_hibernate; + gboolean can_hybrid_sleep; /** * Warning dialog to use when notification daemon @@ -145,6 +146,7 @@ enum PROP_AUTH_HIBERNATE, PROP_CAN_SUSPEND, PROP_CAN_HIBERNATE, + PROP_CAN_HYBRID_SLEEP, PROP_HAS_LID, PROP_PRESENTATION_MODE, PROP_ON_AC_BLANK, @@ -313,26 +315,31 @@ xfpm_power_get_properties (XfpmPower *power) g_object_get (G_OBJECT (power->priv->systemd), "can-suspend", &power->priv->can_suspend, NULL); - g_object_get (G_OBJECT (power->priv->systemd), + g_object_get (G_OBJECT (power->priv->systemd), "can-hibernate", &power->priv->can_hibernate, NULL); + g_object_get (G_OBJECT (power->priv->systemd), + "can-hybrid-sleep", &power->priv->can_hybrid_sleep, + NULL); } else { - if (check_for_consolekit2 (power)) - { - g_object_get (G_OBJECT (power->priv->console), - "can-suspend", &power->priv->can_suspend, - NULL); - g_object_get (G_OBJECT (power->priv->console), - "can-hibernate", &power->priv->can_hibernate, - NULL); - } - else - { - power->priv->can_suspend = xfpm_suspend_can_suspend (); - power->priv->can_hibernate = xfpm_suspend_can_hibernate (); - } + if (check_for_consolekit2 (power)) + { + g_object_get (G_OBJECT (power->priv->console), + "can-suspend", &power->priv->can_suspend, + NULL); + g_object_get (G_OBJECT (power->priv->console), + "can-hibernate", &power->priv->can_hibernate, + NULL); + power->priv->can_hybrid_sleep = FALSE; + } + else + { + power->priv->can_suspend = xfpm_suspend_can_suspend (); + power->priv->can_hibernate = xfpm_suspend_can_hibernate (); + power->priv->can_hybrid_sleep = FALSE; + } } #endif g_object_get (power->priv->upower, @@ -455,43 +462,47 @@ xfpm_power_sleep (XfpmPower *power, const gchar *sleep_time, gboolean force) */ if ( LOGIND_RUNNING () ) { - xfpm_systemd_sleep (power->priv->systemd, sleep_time, &error); + xfpm_systemd_sleep (power->priv->systemd, sleep_time, &error); } else { #if !UP_CHECK_VERSION(0, 99, 0) - if (!g_strcmp0 (sleep_time, "Hibernate")) - { - up_client_hibernate_sync(power->priv->upower, NULL, &error); - } - else - { - up_client_suspend_sync(power->priv->upower, NULL, &error); - } + if (!g_strcmp0 (sleep_time, "Hibernate")) + { + up_client_hibernate_sync(power->priv->upower, NULL, &error); + } + else if (!g_strcmp0 (sleep_time, "Suspend")) + { + up_client_suspend_sync(power->priv->upower, NULL, &error); + } #else - if (!g_strcmp0 (sleep_time, "Hibernate")) + if (!g_strcmp0 (sleep_time, "Hibernate")) { - if (check_for_consolekit2 (power)) - { - xfpm_console_kit_hibernate (power->priv->console, &error); - } - else - { + if (check_for_consolekit2 (power)) + { + xfpm_console_kit_hibernate (power->priv->console, &error); + } + else + { xfpm_suspend_try_action (XFPM_HIBERNATE); - } + } } - else + else if (!g_strcmp0 (sleep_time, "Suspend")) { - if (check_for_consolekit2 (power)) - { - xfpm_console_kit_suspend (power->priv->console, &error); - } - else - { + if (check_for_consolekit2 (power)) + { + xfpm_console_kit_suspend (power->priv->console, &error); + } + else + { xfpm_suspend_try_action (XFPM_SUSPEND); - } + } } #endif + else + { + g_set_error (&error, 0, 0, "This action is not supported by this system."); + } } if ( error ) @@ -1135,6 +1146,13 @@ xfpm_power_class_init (XfpmPowerClass *klass) FALSE, G_PARAM_READABLE)); + + g_object_class_install_property (object_class, + PROP_CAN_HYBRID_SLEEP, + g_param_spec_boolean ("can-hybrid-sleep", + NULL, NULL, + FALSE, + G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_HAS_LID, g_param_spec_boolean ("has-lid", @@ -1188,6 +1206,7 @@ xfpm_power_init (XfpmPower *power) power->priv->daemon_version = NULL; power->priv->can_suspend = FALSE; power->priv->can_hibernate = FALSE; + power->priv->can_hybrid_sleep = FALSE; power->priv->auth_hibernate = TRUE; power->priv->auth_suspend = TRUE; power->priv->dialog = NULL; @@ -1277,6 +1296,9 @@ static void xfpm_power_get_property (GObject *object, case PROP_CAN_HIBERNATE: g_value_set_boolean (value, power->priv->can_hibernate); break; + case PROP_CAN_HYBRID_SLEEP: + g_value_set_boolean (value, power->priv->can_hybrid_sleep); + break; case PROP_HAS_LID: g_value_set_boolean (value, power->priv->lid_is_present); break; @@ -1403,6 +1425,11 @@ void xfpm_power_hibernate (XfpmPower *power, gboolean force) xfpm_power_sleep (power, "Hibernate", force); } +void xfpm_power_hybrid_sleep (XfpmPower *power, gboolean force) +{ + xfpm_power_sleep (power, "HybridSleep", force); +} + gboolean xfpm_power_has_battery (XfpmPower *power) { GtkStatusIcon *battery = NULL; diff --git a/src/xfpm-power.h b/src/xfpm-power.h index b3a1860..c91b4ce 100644 --- a/src/xfpm-power.h +++ b/src/xfpm-power.h @@ -73,6 +73,11 @@ void xfpm_power_suspend (XfpmPower *power, void xfpm_power_hibernate (XfpmPower *power, gboolean force); +void xfpm_power__hybrid_sleep (XfpmPower *power, + gboolean force); + + + gboolean xfpm_power_has_battery (XfpmPower *power); gboolean xfpm_power_is_in_presentation_mode (XfpmPower *power); diff --git a/src/xfpm-systemd.c b/src/xfpm-systemd.c index 0c1cda6..94ca724 100644 --- a/src/xfpm-systemd.c +++ b/src/xfpm-systemd.c @@ -52,6 +52,7 @@ struct XfpmSystemdPrivate gboolean can_restart; gboolean can_suspend; gboolean can_hibernate; + gboolean can_hybrid_sleep; #ifdef ENABLE_POLKIT XfpmPolkit *polkit; #endif @@ -64,6 +65,7 @@ enum PROP_CAN_SHUTDOWN, PROP_CAN_SUSPEND, PROP_CAN_HIBERNATE, + PROP_CAN_HYBRID_SLEEP, }; G_DEFINE_TYPE (XfpmSystemd, xfpm_systemd, G_TYPE_OBJECT) @@ -114,6 +116,13 @@ xfpm_systemd_class_init (XfpmSystemdClass *klass) NULL, NULL, FALSE, G_PARAM_READABLE)); + + g_object_class_install_property (object_class, + PROP_CAN_HYBRID_SLEEP, + g_param_spec_boolean ("can-hybrid-sleep", + NULL, NULL, + FALSE, + G_PARAM_READABLE)); g_type_class_add_private (klass, sizeof (XfpmSystemdPrivate)); } @@ -156,6 +165,9 @@ xfpm_systemd_init (XfpmSystemd *systemd) xfpm_systemd_can_method (systemd, &systemd->priv->can_hibernate, SYSTEMD_HIBERNATE_TEST); + systemd->priv->can_hybrid_sleep = + systemd->priv->can_suspend && systemd->priv->can_hibernate; + } static void xfpm_systemd_get_property (GObject *object, @@ -180,6 +192,9 @@ static void xfpm_systemd_get_property (GObject *object, case PROP_CAN_HIBERNATE: g_value_set_boolean (value, systemd->priv->can_hibernate); break; + case PROP_CAN_HYBRID_SLEEP: + g_value_set_boolean (value, systemd->priv->can_hybrid_sleep); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/src/xfpm-xfconf.c b/src/xfpm-xfconf.c index 721d977..9770ff8 100644 --- a/src/xfpm-xfconf.c +++ b/src/xfpm-xfconf.c @@ -356,7 +356,7 @@ xfpm_xfconf_class_init (XfpmXfconfClass *klass) g_param_spec_uint (LID_SWITCH_ON_AC_CFG, NULL, NULL, LID_TRIGGER_NOTHING, - LID_TRIGGER_LOCK_SCREEN, + LID_TRIGGER_HYBRID_SLEEP, LID_TRIGGER_LOCK_SCREEN, G_PARAM_READWRITE)); @@ -392,7 +392,7 @@ xfpm_xfconf_class_init (XfpmXfconfClass *klass) g_param_spec_uint (LID_SWITCH_ON_BATTERY_CFG, NULL, NULL, LID_TRIGGER_NOTHING, - LID_TRIGGER_LOCK_SCREEN, + LID_TRIGGER_HYBRID_SLEEP, LID_TRIGGER_LOCK_SCREEN, G_PARAM_READWRITE)); -- 2.3.0