From 0fada409175333e4ebeee30cab2ccd4ff457445f Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Wed, 18 Oct 2017 13:33:47 +0900 Subject: [PATCH] smart suspend - honor suspend on ac or not flag as it should so if you closed the lid ANd didn't have external screens ANd had ac plugged in ... e would suspend even if youdidn't have "suspend on ac" checked in blanking dialog. respect this and handle it properly. @fix side note... i've notced acpid no longer reporting lid events on one of my systems. this is very sucky. you now have to open /dev/input/event2 (this may vary from device to device) to get lid events... it's an input device. this means elput needs to start doing this as we cant get power button or lid events anymore .... and we may have to do this for x11 too. --- src/bin/e_acpi.c | 1 + src/bin/e_actions.c | 23 +++++++++++++++++++++-- src/bin/e_powersave.c | 35 +++++++++++++++++++++++++++++++++++ src/bin/e_powersave.h | 3 +++ src/bin/e_sys.c | 5 +++++ 5 files changed, 65 insertions(+), 2 deletions(-) diff --git a/src/bin/e_acpi.c b/src/bin/e_acpi.c index bc6b11a35..fff5b7fb0 100644 --- a/src/bin/e_acpi.c +++ b/src/bin/e_acpi.c @@ -351,6 +351,7 @@ _e_acpi_cb_server_data(void *data EINA_UNUSED, int type EINA_UNUSED, void *event printf("RRR: lid event for lid %i\n", lid_is_closed); if (!e_randr2_cfg->ignore_acpi_events) e_randr2_screen_refresh_queue(EINA_TRUE); + if (!lid_is_closed) e_powersave_defer_cancel(); break; default: diff --git a/src/bin/e_actions.c b/src/bin/e_actions.c index 81c302fcc..2913cc36d 100644 --- a/src/bin/e_actions.c +++ b/src/bin/e_actions.c @@ -2413,10 +2413,24 @@ _have_lid_and_external_screens_on(void) return EINA_FALSE; } +static Eina_Bool +_should_suspend_if_plugged_in(void) +{ + if ((e_config->screensaver_suspend_on_ac) || + (e_powersave_mode_get() > E_POWERSAVE_MODE_LOW)) + return EINA_TRUE; + return EINA_FALSE; +} + ACT_FN_GO(suspend_smart, EINA_UNUSED) { if (!_have_lid_and_external_screens_on()) - e_sys_action_do(E_SYS_SUSPEND, NULL); + { + if (_should_suspend_if_plugged_in()) + e_sys_action_do(E_SYS_SUSPEND, NULL); + else + e_powersave_defer_suspend(); + } } /***************************************************************************/ @@ -2484,7 +2498,12 @@ ACT_FN_GO(hibernate, ) ACT_FN_GO(hibernate_smart, EINA_UNUSED) { if (!_have_lid_and_external_screens_on()) - e_sys_action_do(E_SYS_HIBERNATE, NULL); + { + if (_should_suspend_if_plugged_in()) + e_sys_action_do(E_SYS_HIBERNATE, NULL); + else + e_powersave_defer_hibernate(); + } } /***************************************************************************/ diff --git a/src/bin/e_powersave.c b/src/bin/e_powersave.c index 55021b38d..baac18a3e 100644 --- a/src/bin/e_powersave.c +++ b/src/bin/e_powersave.c @@ -33,6 +33,8 @@ static E_Powersave_Mode powersave_mode_force = E_POWERSAVE_MODE_NONE; static double defer_time = 5.0; static Eina_Bool powersave_force = EINA_FALSE; static Eina_List *powersave_sleepers = NULL; +static Eina_Bool powersave_deferred_suspend = EINA_FALSE; +static Eina_Bool powersave_deferred_hibernate = EINA_FALSE; /* externally accessible functions */ EINTERN int @@ -198,6 +200,25 @@ e_powersave_sleeper_sleep(E_Powersave_Sleeper *sleeper, int poll_interval) } } +E_API void +e_powersave_defer_suspend(void) +{ + powersave_deferred_suspend = EINA_TRUE; +} + +E_API void +e_powersave_defer_hibernate(void) +{ + powersave_deferred_hibernate = EINA_TRUE; +} + +E_API void +e_powersave_defer_cancel(void) +{ + powersave_deferred_suspend = EINA_FALSE; + powersave_deferred_hibernate = EINA_FALSE; +} + /* local subsystem functions */ static void @@ -288,7 +309,21 @@ _e_powersave_mode_eval(void) static void _e_powersave_event_update_free(void *data EINA_UNUSED, void *event) { + E_Powersave_Mode mode; + + if (powersave_force) mode = powersave_mode_force; + else mode = powersave_mode; free(event); + + if (mode > E_POWERSAVE_MODE_LOW) + { + if (powersave_deferred_hibernate) + e_sys_action_do(E_SYS_HIBERNATE, NULL); + else if (powersave_deferred_suspend) + e_sys_action_do(E_SYS_SUSPEND, NULL); + } + powersave_deferred_hibernate = EINA_FALSE; + powersave_deferred_suspend = EINA_FALSE; } static void diff --git a/src/bin/e_powersave.h b/src/bin/e_powersave.h index 1cf20678a..de52d1ee1 100644 --- a/src/bin/e_powersave.h +++ b/src/bin/e_powersave.h @@ -37,6 +37,9 @@ E_API void e_powersave_mode_force(E_Powersave_Mode mode) E_API void e_powersave_mode_unforce(void); E_API E_Powersave_Sleeper *e_powersave_sleeper_new(void); E_API void e_powersave_sleeper_free(E_Powersave_Sleeper *sleeper); +E_API void e_powersave_defer_suspend(void); +E_API void e_powersave_defer_hibernate(void); +E_API void e_powersave_defer_cancel(void); // the below function is INTENDED to be called from a thread E_API void e_powersave_sleeper_sleep(E_Powersave_Sleeper *sleeper, int poll_interval); diff --git a/src/bin/e_sys.c b/src/bin/e_sys.c index ab08e5cae..6781a9b5a 100644 --- a/src/bin/e_sys.c +++ b/src/bin/e_sys.c @@ -306,6 +306,11 @@ _e_sys_systemd_signal_prepare_sleep(void *data EINA_UNUSED, const Eldbus_Message // b == 1 -> suspending // b == 0 -> resuming fprintf(stderr, "SSS: systemd said to prepare for sleep! bool=%i @%1.8f\n", (int)b, ecore_time_get()); + if (b == EINA_FALSE) + { + ecore_event_add(E_EVENT_SYS_RESUME, NULL, NULL, NULL); + _e_sys_comp_resume(); + } } /* externally accessible functions */