From 403435f9fd4fe95f6bbba79b1e765c6a71a3a4b8 Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Tue, 20 Apr 2021 19:03:02 +0100 Subject: [PATCH] blanking - when screen blanks (pwsave freeze) set windows to iconic also make them hidden too for good measure. this causes many clients to stop rendering. saves power and useless cycles drawing stuff you can't see. --- TODO | 1 - src/bin/e_client.c | 5 ++++ src/bin/e_client.h | 2 ++ src/bin/e_comp.h | 2 ++ src/bin/e_comp_x.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++ src/bin/e_hints.c | 17 ++++++++++-- 6 files changed, 92 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index faf30925d..e089bd0f6 100644 --- a/TODO +++ b/TODO @@ -312,7 +312,6 @@ TODO: * set governor for ac vs battery (or powerstate levels) * set pstate min and max for ac vs battery (or power state levels) * saving power - * when screen blanks set all apps to hidden state * have new property/atom for hidden but visible in a pager orsomething * efl - dont suspend render when this is the case but drop fps to 1/4 * look into x grabserver for long periods (eg 1s) then ungrab for diff --git a/src/bin/e_client.c b/src/bin/e_client.c index c2a1bd51e..1d7659964 100644 --- a/src/bin/e_client.c +++ b/src/bin/e_client.c @@ -1775,6 +1775,11 @@ _e_client_eval(E_Client *ec) if ((ec->new_client) && (!e_client_util_ignored_get(ec)) && (ec->zone)) { + if (e_comp->frozen) + { + ec->frozen = EINA_TRUE; + e_hints_window_state_set(ec); + } _e_client_event_simple(ec, E_EVENT_CLIENT_ADD); e_zone_useful_geometry_get(ec->zone, &zx, &zy, &zw, &zh); /* enforce wm size hints for initial sizing */ diff --git a/src/bin/e_client.h b/src/bin/e_client.h index 4725ba53c..af2823eb8 100644 --- a/src/bin/e_client.h +++ b/src/bin/e_client.h @@ -656,6 +656,8 @@ struct E_Client unsigned int stolen E_BITFIELD; + unsigned int frozen E_BITFIELD; + unsigned int internal E_BITFIELD; unsigned int internal_no_remember E_BITFIELD; unsigned int internal_no_reopen E_BITFIELD; diff --git a/src/bin/e_comp.h b/src/bin/e_comp.h index 347cbccb3..5bdfe45c3 100644 --- a/src/bin/e_comp.h +++ b/src/bin/e_comp.h @@ -190,6 +190,8 @@ struct _E_Comp Eina_Bool rendering E_BITFIELD; // we've received a pre-render callback but no post-render yet. Eina_Bool updating E_BITFIELD; // running client updates + + Eina_Bool frozen E_BITFIELD; // frozen - when power save freeze mode is on }; diff --git a/src/bin/e_comp_x.c b/src/bin/e_comp_x.c index fc740e7b5..dcdb49e8c 100644 --- a/src/bin/e_comp_x.c +++ b/src/bin/e_comp_x.c @@ -2520,6 +2520,72 @@ _e_comp_x_mapping_change(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_X_E return ECORE_CALLBACK_PASS_ON; } +static Eina_Bool +_e_comp_x_powersave(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + E_Event_Powersave_Update *ev = event; + Eina_List *l; + E_Client *ec; + + if (e_comp->comp_type == E_PIXMAP_TYPE_WL) return ECORE_CALLBACK_PASS_ON; + switch (ev->mode) + { + case E_POWERSAVE_MODE_NONE: + case E_POWERSAVE_MODE_LOW: + case E_POWERSAVE_MODE_MEDIUM: + case E_POWERSAVE_MODE_HIGH: + case E_POWERSAVE_MODE_EXTREME: + if (e_comp->frozen) + { + e_comp->frozen = EINA_FALSE; + EINA_LIST_FOREACH(e_comp->clients, l, ec) + { + if (ec->frozen) + { + ec->frozen = EINA_FALSE; + // XXX: update props + if (e_client_has_xwindow(ec)) + { + if (!ec->iconic) + { + ecore_x_icccm_state_set(e_client_util_win_get(ec), + ECORE_X_WINDOW_STATE_HINT_NORMAL); + } + e_hints_window_state_set(ec); + } + } + } + } + break; + case E_POWERSAVE_MODE_FREEZE: + if (!e_comp->frozen) + { + e_comp->frozen = EINA_TRUE; + EINA_LIST_FOREACH(e_comp->clients, l, ec) + { + if (!ec->frozen) + { + ec->frozen = EINA_TRUE; + // XXX: update props + if (e_client_has_xwindow(ec)) + { + if (!ec->iconic) + { + ecore_x_icccm_state_set(e_client_util_win_get(ec), + ECORE_X_WINDOW_STATE_HINT_ICONIC); + } + e_hints_window_state_set(ec); + } + } + } + } + break; + default: + break; + } + return ECORE_CALLBACK_PASS_ON; +} + static void _e_comp_x_mouse_in_job(void *d EINA_UNUSED) { @@ -6043,6 +6109,8 @@ e_comp_x_init(void) e_error_message_show(_("Enlightenment cannot initialize the XSettings system.\n")); E_LIST_HANDLER_APPEND(handlers, E_EVENT_RANDR_CHANGE, _e_comp_x_randr_change, NULL); + E_LIST_HANDLER_APPEND(handlers, E_EVENT_POWERSAVE_UPDATE, _e_comp_x_powersave, NULL); + ecore_x_sync(); _x_idle_flush = ecore_idle_enterer_add(_e_comp_x_flusher, NULL); diff --git a/src/bin/e_hints.c b/src/bin/e_hints.c index a7f010096..1e9bc08cd 100644 --- a/src/bin/e_hints.c +++ b/src/bin/e_hints.c @@ -599,7 +599,7 @@ e_hints_window_state_set(E_Client *ec) if (ec->netwm.state.skip_pager) state[num++] = ECORE_X_WINDOW_STATE_SKIP_PAGER; } - if (ec->netwm.state.hidden) + if ((ec->netwm.state.hidden) || (ec->frozen)) state[num++] = ECORE_X_WINDOW_STATE_HIDDEN; if (ec->netwm.state.fullscreen) state[num++] = ECORE_X_WINDOW_STATE_FULLSCREEN; @@ -1261,11 +1261,18 @@ e_hints_window_visible_set(E_Client *ec) (void)ec; #else if (!e_client_has_xwindow(ec)) return; - if (ec->icccm.state != ECORE_X_WINDOW_STATE_HINT_WITHDRAWN) + if ((ec->icccm.state != ECORE_X_WINDOW_STATE_HINT_WITHDRAWN) && + (!ec->frozen)) { ec->icccm.state = ECORE_X_WINDOW_STATE_HINT_NORMAL; ecore_x_icccm_state_set(e_client_util_win_get(ec), ECORE_X_WINDOW_STATE_HINT_NORMAL); } + else if (ec->frozen) + { + if (ec->icccm.state != ECORE_X_WINDOW_STATE_HINT_WITHDRAWN) + ec->icccm.state = ECORE_X_WINDOW_STATE_HINT_NORMAL; + ecore_x_icccm_state_set(e_client_util_win_get(ec), ECORE_X_WINDOW_STATE_HINT_ICONIC); + } if (ec->netwm.state.hidden) { ec->netwm.update.state = 1; @@ -1288,6 +1295,12 @@ e_hints_window_iconic_set(E_Client *ec) ec->icccm.state = ECORE_X_WINDOW_STATE_HINT_ICONIC; ecore_x_icccm_state_set(e_client_util_win_get(ec), ECORE_X_WINDOW_STATE_HINT_ICONIC); } + else if (ec->frozen) + { + if (ec->icccm.state != ECORE_X_WINDOW_STATE_HINT_WITHDRAWN) + ec->icccm.state = ECORE_X_WINDOW_STATE_HINT_ICONIC; + ecore_x_icccm_state_set(e_client_util_win_get(ec), ECORE_X_WINDOW_STATE_HINT_ICONIC); + } if (!ec->netwm.state.hidden) { ec->netwm.update.state = 1;