diff --git a/src/bin/e_acpi.c b/src/bin/e_acpi.c index fff5b7fb0..e8e5fcfa2 100644 --- a/src/bin/e_acpi.c +++ b/src/bin/e_acpi.c @@ -344,7 +344,7 @@ _e_acpi_cb_server_data(void *data EINA_UNUSED, int type EINA_UNUSED, void *event case E_ACPI_TYPE_LID: acpi_event->status = _e_acpi_lid_status_get(device, bus); - printf("RRR: acpi event\n"); + printf("RRR: acpi event @%1.8f\n", ecore_time_get()); /* no change in lid state */ if (lid_is_closed == (acpi_event->status == E_ACPI_LID_CLOSED)) break; lid_is_closed = (acpi_event->status == E_ACPI_LID_CLOSED); diff --git a/src/bin/e_actions.c b/src/bin/e_actions.c index 2913cc36d..1e3f525f1 100644 --- a/src/bin/e_actions.c +++ b/src/bin/e_actions.c @@ -2394,7 +2394,6 @@ ACT_FN_GO(suspend, ) static Eina_Bool _have_lid_and_external_screens_on(void) { -#ifndef HAVE_WAYLAND_ONLY Eina_List *l; E_Randr2_Screen *s; int lids = 0; @@ -2409,7 +2408,6 @@ _have_lid_and_external_screens_on(void) ext_screens++; } if ((lids > 0) && (ext_screens > 0)) return EINA_TRUE; -#endif return EINA_FALSE; } diff --git a/src/bin/e_randr2.c b/src/bin/e_randr2.c index fc0375a8c..c90b2fa6e 100644 --- a/src/bin/e_randr2.c +++ b/src/bin/e_randr2.c @@ -582,8 +582,10 @@ _screens_fingerprint(E_Randr2 *r) eina_strbuf_append(buf, ":"); eina_strbuf_append(buf, s->id); eina_strbuf_append(buf, ":"); - if (s->info.lid_closed) eina_strbuf_append(buf, ":LC:"); - else eina_strbuf_append(buf, ":LO:"); +// Don't do this asbecause this forces a screen replug when you open and +// close your laptop lid and if that is the only thing you open or close... +// if (s->info.lid_closed) eina_strbuf_append(buf, ":LC:"); +// else eina_strbuf_append(buf, ":LO:"); } } str = eina_strbuf_string_steal(buf); @@ -598,6 +600,7 @@ _screens_differ(E_Randr2 *r1, E_Randr2 *r2) Eina_Bool changed = EINA_FALSE; Eina_List *l, *ll; E_Randr2_Screen *s, *ss; + int r1_screen_num = 0, r2_screen_num = 0; // check monitor outputs and edids, plugged in things s1 = _screens_fingerprint(r1); @@ -609,6 +612,26 @@ _screens_differ(E_Randr2 *r1, E_Randr2 *r2) free(s1); free(s2); // check screen config + printf("RRR: screens lists %i -> %i\n", eina_list_count(r1->screens), eina_list_count(r2->screens)); + printf("RRR: --------\n"); + EINA_LIST_FOREACH(r1->screens, l, s) + { + if (!s->id) continue; + if ((s->info.connected) && + (!((s->info.is_lid) && (s->info.lid_closed)))) + r1_screen_num++; + } + printf("RRR: --------\n"); + EINA_LIST_FOREACH(r2->screens, l, s) + { + if (!s->id) continue; + if ((s->info.connected) && + (!((s->info.is_lid) && (s->info.lid_closed)))) + r2_screen_num++; + } + printf("RRR: --------\n"); + printf("RRR: screens %i -> %i\n", r1_screen_num, r2_screen_num); + printf("RRR: --------\n"); EINA_LIST_FOREACH(r2->screens, l, s) { if (!s->id) continue; @@ -625,14 +648,62 @@ _screens_differ(E_Randr2 *r1, E_Randr2 *r2) (s->config.mode.w != ss->config.mode.w) || (s->config.mode.h != ss->config.mode.h) || (s->config.enabled != ss->config.enabled) || - (s->config.rotation != ss->config.rotation) || - (s->info.lid_closed != ss->info.lid_closed)) + (s->config.rotation != ss->config.rotation)) changed = EINA_TRUE; + else + { + if (r1_screen_num != r2_screen_num) + { + printf("RRR: do change because screen count changed\n"); + changed = EINA_TRUE; + } + else + { + if ((r2_screen_num != 1) && + (s->info.lid_closed != ss->info.lid_closed)) + { + printf("RRR: change because laptop lid open/close and number of screens > 1\n"); + changed = EINA_TRUE; + } + else + printf("RRR: skip change because of single laptop lid\n"); + } + } } + printf("RRR: --------\n"); printf("RRR: changed = %i\n", changed); return changed; } +static Eina_Bool +_cb_deferred_suspend_screen_change(void *data EINA_UNUSED) +{ + Eina_List *l; + E_Randr2_Screen *s; + int lids = 0; + int ext_screens = 0; + + EINA_LIST_FOREACH(e_randr2->screens, l, s) + { + if (s->info.is_lid) lids++; + else if ((s->config.enabled) && + (s->config.geom.w > 0) && + (s->config.geom.h > 0)) + ext_screens++; + } + printf("RRR: =========================== deferred suspend.... %i %i\n", lids, ext_screens); + if ((lids > 0) && (ext_screens == 0)) + { + if ((e_config->screensaver_suspend_on_ac) || + (e_powersave_mode_get() > E_POWERSAVE_MODE_LOW)) + { + printf("RRR: =========================== powermd low / suspend on ac"); + e_sys_action_do(E_SYS_SUSPEND, NULL); + } + } + return EINA_FALSE; +} + static Eina_Bool _cb_screen_change_delay(void *data EINA_UNUSED) { @@ -642,6 +713,11 @@ _cb_screen_change_delay(void *data EINA_UNUSED) // if we had a screen plug/unplug etc. event and we shouldnt ignore it... if ((event_screen) && (!event_ignore)) { + Eina_List *l; + E_Randr2_Screen *s; + int lid_screens = 0; + int close_lid_screens = 0; + int external_screens = 0; E_Randr2 *rtemp; printf("RRR: reconfigure screens due to event...\n"); @@ -658,12 +734,74 @@ _cb_screen_change_delay(void *data EINA_UNUSED) change = EINA_TRUE; } } + EINA_LIST_FOREACH(rtemp->screens, l, s) + { +// if (!s->id) continue; + if (s->info.is_lid) + { + lid_screens++; + if (s->info.lid_closed) close_lid_screens++; + } + else + { + if ((s->info.connected) && (s->config.enabled)) + external_screens++; + } + } + printf("RRR: lids=%i closed=%i ext=%i\n", lid_screens, close_lid_screens, external_screens); _info_free(rtemp); } printf("RRR: change = %i\n", change); // we plugged or unplugged some monitor - re-apply config so // known screens can be configured - if (change) e_randr2_config_apply(); + if (change) + { + if ((lid_screens > 0) && (close_lid_screens == lid_screens) && + (external_screens == 0)) + { + printf("RRR: skip change with all lids closed and no ext\n"); + change = EINA_FALSE; + e_screensaver_now_set(EINA_TRUE); + e_screensaver_attrs_set + (1, e_config->screensaver_blanking, + e_config->screensaver_expose); + e_screensaver_update(); + e_dpms_force_update(); + e_screensaver_activate(); + e_screensaver_eval(EINA_TRUE); + // force dpms... + } + if ((lid_screens > 0) && (close_lid_screens < lid_screens) && + (external_screens == 0)) + { + printf("RRR: skip change with lid screens open and no ext\n"); + change = EINA_FALSE; + e_screensaver_now_set(EINA_FALSE); + e_screensaver_attrs_set + (e_config->screensaver_timeout, + e_config->screensaver_blanking, + e_config->screensaver_expose); + e_screensaver_update(); + e_dpms_force_update(); + e_screensaver_deactivate(); + } + if (change) + e_randr2_config_apply(); + } + if (change) + { + if ((lid_screens > 0) && (close_lid_screens == lid_screens) && + (external_screens == 0)) + { + printf("RRR: have all closed laptop screens and no external\n"); + if ((e_config->screensaver_suspend_on_ac) || + (e_powersave_mode_get() > E_POWERSAVE_MODE_LOW)) + { + printf("RRR: we should try and suspend now because on ac or suspend on ac is on\n"); + ecore_timer_add(1.0, _cb_deferred_suspend_screen_change, NULL); + } + } + } } // update screen info after the above apply or due to external changes e_randr2_screeninfo_update(); diff --git a/src/bin/e_screensaver.c b/src/bin/e_screensaver.c index 89bca5e28..da0ea2d3a 100644 --- a/src/bin/e_screensaver.c +++ b/src/bin/e_screensaver.c @@ -31,6 +31,7 @@ static Eina_Bool _e_screensaver_inhibited = EINA_FALSE; #endif static Eina_Bool _screensaver_ignore = EINA_FALSE; +static Eina_Bool _screensaver_now = EINA_FALSE; E_API int E_EVENT_SCREENSAVER_ON = -1; E_API int E_EVENT_SCREENSAVER_OFF = -1; @@ -51,6 +52,7 @@ e_screensaver_timeout_get(Eina_Bool use_idle) { int timeout = 0, count = (1 + _e_screensaver_ask_presentation_count); + if (_screensaver_now) return 1; if ((e_config->screensaver_enable) && (!e_config->mode.presentation)) { if ((e_desklock_state_get()) && @@ -138,7 +140,23 @@ e_screensaver_update(void) if (e_comp->comp_type != E_PIXMAP_TYPE_WL) { if (changed) - ecore_x_screensaver_set(timeout, interval, blanking, expose); + { + // this toggling of dpms is a bug workaround in x that i found + // where if we change screensaver timeouts and force a manual + // wake of the screen e.g. on lid open/close we have to toggle + // it for x to stop thinking the monitor is off when it's + // actually on and this causes later dpms issues where the + // screen doesnt turn off at all because x thinks interanlly + // that the monitor is still off... so this is odd, but it's + // necessary on some hardware. + int enabled; + + enabled = ((e_config->screensaver_enable) && + (!e_config->mode.presentation)); + ecore_x_dpms_enabled_set(!enabled); + ecore_x_dpms_enabled_set(enabled); + ecore_x_screensaver_set(timeout, interval, blanking, expose); + } } #endif #ifdef HAVE_WAYLAND @@ -518,6 +536,12 @@ e_screensaver_deactivate(void) #endif } +E_API void +e_screensaver_now_set(Eina_Bool now) +{ + _screensaver_now = now; +} + E_API void e_screensaver_eval(Eina_Bool saver_on) { @@ -529,6 +553,7 @@ e_screensaver_eval(Eina_Bool saver_on) e_config->backlight.timer; if (t < 1.0) t = 1.0; + if (_screensaver_now) t = 1.0; E_FREE_FUNC(screensaver_idle_timer, ecore_timer_del); if (!_screensaver_ignore) { diff --git a/src/bin/e_screensaver.h b/src/bin/e_screensaver.h index 9c26afc98..5b1cd6187 100644 --- a/src/bin/e_screensaver.h +++ b/src/bin/e_screensaver.h @@ -19,6 +19,7 @@ E_API Eina_Bool e_screensaver_on_get(void); E_API void e_screensaver_activate(void); E_API void e_screensaver_deactivate(void); +E_API void e_screensaver_now_set(Eina_Bool now); E_API void e_screensaver_eval(Eina_Bool saver_on); E_API void e_screensaver_notidle(void); E_API void e_screensaver_inhibit_toggle(Eina_Bool inhibit); diff --git a/src/bin/e_sys.c b/src/bin/e_sys.c index 6781a9b5a..5dc7754cc 100644 --- a/src/bin/e_sys.c +++ b/src/bin/e_sys.c @@ -36,6 +36,8 @@ static E_Dialog *_e_sys_logout_confirm_dialog = NULL; static Ecore_Timer *_e_sys_susp_hib_check_timer = NULL; static double _e_sys_susp_hib_check_last_tick = 0.0; static Ecore_Timer *_e_sys_phantom_wake_check_timer = NULL; +static Ecore_Timer *_e_sys_resume_delay_timer = NULL; +static Eina_Bool _e_sys_suspended = EINA_FALSE; static Ecore_Event_Handler *_e_sys_acpi_handler = NULL; @@ -254,6 +256,7 @@ _e_sys_comp_resume2(void *data EINA_UNUSED) _e_sys_phantom_wake_check_timer = ecore_timer_add(1.0, _e_sys_phantom_wake_check_cb, NULL); } + printf("SSS: sys resume2 @ %1.8f\n", ecore_time_get()); return EINA_FALSE; } @@ -284,6 +287,7 @@ _e_sys_comp_resume(void) _e_sys_screensaver_unignore_timer = ecore_timer_add(0.3, _e_sys_screensaver_unignore_delay, NULL); ecore_timer_add(0.6, _e_sys_comp_resume2, NULL); + printf("SSS: sys resume @ %1.8f\n", ecore_time_get()); } static void @@ -293,7 +297,7 @@ _e_sys_systemd_signal_prepare_shutdown(void *data EINA_UNUSED, const Eldbus_Mess Eina_Bool b = EINA_FALSE; if (!eldbus_message_arguments_get(msg, "b", &b)) return; - fprintf(stderr, "SSS: systemd said to prepare for shutdown! bool=%i @%1.8f\n", (int)b, ecore_time_get()); + printf("SSS: systemd said to prepare for shutdown! bool=%i @%1.8f\n", (int)b, ecore_time_get()); } static void @@ -305,12 +309,17 @@ _e_sys_systemd_signal_prepare_sleep(void *data EINA_UNUSED, const Eldbus_Message if (!eldbus_message_arguments_get(msg, "b", &b)) return; // 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()); + printf("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(); + if (_e_sys_suspended) + { + _e_sys_suspended = EINA_FALSE; + ecore_event_add(E_EVENT_SYS_RESUME, NULL, NULL, NULL); + _e_sys_comp_resume(); + } } + else _e_sys_suspended = EINA_TRUE; } /* externally accessible functions */ @@ -347,12 +356,15 @@ e_sys_init(void) EINTERN int e_sys_shutdown(void) { + if (_e_sys_resume_delay_timer) + ecore_timer_del(_e_sys_resume_delay_timer); if (_e_sys_screensaver_unignore_timer) ecore_timer_del(_e_sys_screensaver_unignore_timer); if (_e_sys_acpi_handler) ecore_event_handler_del(_e_sys_acpi_handler); if (_e_sys_exe_exit_handler) ecore_event_handler_del(_e_sys_exe_exit_handler); + _e_sys_resume_delay_timer = NULL; _e_sys_screensaver_unignore_timer = NULL; _e_sys_acpi_handler = NULL; _e_sys_exe_exit_handler = NULL; @@ -612,8 +624,13 @@ _e_sys_systemd_hibernate(void) static Eina_Bool _e_sys_resume_delay(void *d EINA_UNUSED) { - ecore_event_add(E_EVENT_SYS_RESUME, NULL, NULL, NULL); - _e_sys_comp_resume(); + _e_sys_resume_delay_timer = NULL; + if (_e_sys_suspended) + { + _e_sys_suspended = EINA_FALSE; + ecore_event_add(E_EVENT_SYS_RESUME, NULL, NULL, NULL); + _e_sys_comp_resume(); + } return EINA_FALSE; } @@ -622,10 +639,14 @@ _e_sys_susp_hib_check_timer_cb(void *data EINA_UNUSED) { double t = ecore_time_unix_get(); + printf("SSS: hib check @%1.8f (unix %1.8f, delt %1.8f)\n", ecore_time_get(), t, t - _e_sys_susp_hib_check_last_tick); if ((t - _e_sys_susp_hib_check_last_tick) > 0.5) { _e_sys_susp_hib_check_timer = NULL; - ecore_timer_add(0.2, _e_sys_resume_delay, NULL); + if (_e_sys_resume_delay_timer) + ecore_timer_del(_e_sys_resume_delay_timer); + _e_sys_resume_delay_timer = + ecore_timer_add(0.2, _e_sys_resume_delay, NULL); return EINA_FALSE; } _e_sys_susp_hib_check_last_tick = t; @@ -640,6 +661,7 @@ _e_sys_susp_hib_check(void) _e_sys_susp_hib_check_last_tick = ecore_time_unix_get(); _e_sys_susp_hib_check_timer = ecore_timer_loop_add(0.1, _e_sys_susp_hib_check_timer_cb, NULL); + printf("SSS: hib check begin @%1.8f (unix %1.8f)\n", ecore_time_get(), _e_sys_susp_hib_check_last_tick); } /* local subsystem functions */ @@ -1163,17 +1185,18 @@ _e_sys_action_do(E_Sys_Action a, char *param EINA_UNUSED, Eina_Bool raw) _e_sys_phantom_wake_check_timer = NULL; if (raw) { + _e_sys_suspended = EINA_TRUE; if (e_config->desklock_on_suspend) // XXX: this desklock - ensure its instant e_desklock_show(EINA_TRUE); _e_sys_begin_time = ecore_time_get(); if (e_config->suspend_connected_standby == 0) { - _e_sys_susp_hib_check(); if (systemd_works) _e_sys_systemd_suspend(); else { + _e_sys_susp_hib_check(); _e_sys_exe = ecore_exe_run(buf, NULL); ret = 1; } @@ -1223,7 +1246,7 @@ _e_sys_action_do(E_Sys_Action a, char *param EINA_UNUSED, Eina_Bool raw) _e_sys_phantom_wake_check_timer = NULL; if (raw) { - _e_sys_susp_hib_check(); + _e_sys_suspended = EINA_TRUE; if (e_config->desklock_on_suspend) // XXX: this desklock - ensure its instant e_desklock_show(EINA_TRUE); @@ -1232,6 +1255,7 @@ _e_sys_action_do(E_Sys_Action a, char *param EINA_UNUSED, Eina_Bool raw) _e_sys_systemd_hibernate(); else { + _e_sys_susp_hib_check(); _e_sys_exe = ecore_exe_run(buf, NULL); ret = 1; }