From d1fa3ab24ff4783cc299458b52d86bcf93f97ed4 Mon Sep 17 00:00:00 2001 From: Doyoun Kang Date: Wed, 21 Oct 2020 13:58:36 +0900 Subject: [PATCH] e_client: add feature - show_pending E supports show_pending feature. If an ec set show_pending, then e doesn't show it's frame, doesn't calculate visiblity and doesn't send visibility change event until unsetting show_pending. - e_client_show_pending_set - e_client_show_pending_unset FYI, if an ec which is running show_pending requests unmap, then e set ec's visibility to UNOBSCURED. By this, its visibility can be changed to FULLY-OBSCURED by calculating visibility. Change-Id: I3fd89b706ac2d93c01248e988d271ac77f03ecb6 --- src/bin/e_client.c | 61 +++++++++++++++++++++++++++++++++------ src/bin/e_client.h | 8 +++++ src/bin/e_comp_object.c | 7 +++++ src/bin/e_comp_wl.c | 13 +++++++++ src/bin/e_comp_wl_shell.c | 2 +- 5 files changed, 81 insertions(+), 10 deletions(-) diff --git a/src/bin/e_client.c b/src/bin/e_client.c index 1113ef4810..e6cd36f97f 100644 --- a/src/bin/e_client.c +++ b/src/bin/e_client.c @@ -3284,7 +3284,8 @@ _e_client_visibility_zone_calculate(E_Zone *zone) Eina_Bool canvas_vis = EINA_TRUE; Eina_Bool ec_vis, ec_opaque, calc_region; Eina_Bool skip_rot_pending_show = EINA_FALSE; - Eina_Bool is_above_rot_pending = EINA_FALSE; + int skip_by_pending_show = 0; + Eina_Bool is_above_show_pending = EINA_FALSE; Eina_Bool is_launching_effect = EINA_FALSE; Eina_Bool is_vis_on_skip = EINA_FALSE; Eina_Bool is_display_off = EINA_FALSE; @@ -3366,6 +3367,7 @@ _e_client_visibility_zone_calculate(E_Zone *zone) e_client_geometry_get(ec, &x, &y, &w, &h); ec_vis = ec_opaque = skip_rot_pending_show = is_vis_on_skip = EINA_FALSE; + skip_by_pending_show = 0; calc_region = EINA_TRUE; ec_frame_visible = evas_object_visible_get(ec->frame); @@ -3382,6 +3384,13 @@ _e_client_visibility_zone_calculate(E_Zone *zone) calc_region = EINA_FALSE; calc_skip_type |= 0x02; skip_rot_pending_show = EINA_TRUE; + skip_by_pending_show = 1; + } + else if (ec->show_pending.count > 0) + { + calc_region = EINA_FALSE; + calc_skip_type |= 0x40; + skip_by_pending_show = 2; } else { @@ -3442,7 +3451,7 @@ _e_client_visibility_zone_calculate(E_Zone *zone) /* unobscured case */ EC_IS_NOT_VISIBLE { - if ((!is_above_rot_pending) && + if ((!is_above_show_pending) && ((!effect_running) || ((effect_running) && (!is_launching_effect)))) { @@ -3453,14 +3462,14 @@ _e_client_visibility_zone_calculate(E_Zone *zone) } else { - if (!is_above_rot_pending) + if (!is_above_show_pending) is_vis_on_skip = EINA_TRUE; ELOGF("POL_VIS", "CLIENT VIS ON-SKIP. argb:%d, opaque:%2d, frame_v:%d, cdata:%p", ec, ec->argb, ec->visibility.opaque, ec_frame_visible, cdata); } } /* subtract window region from canvas region */ - if (canvas_vis && !skip_rot_pending_show && !is_vis_on_skip) + if (canvas_vis && !skip_by_pending_show && !is_vis_on_skip) { /* check alpha window is opaque or not. */ if ((ec->visibility.opaque > 0) && (ec->argb)) @@ -3489,7 +3498,7 @@ _e_client_visibility_zone_calculate(E_Zone *zone) * However, with rotation mode, iconification is done if client * is iconified by itself. */ - if ((!skip_rot_pending_show) || + if ((!skip_by_pending_show) || (ec->visibility.force_obscured) || (ec->bg_state) || (ec->exp_iconify.by_client)) @@ -3500,16 +3509,18 @@ _e_client_visibility_zone_calculate(E_Zone *zone) /* previous state is unobscured: -1 or 0 */ ec->visibility.obscured = E_VISIBILITY_FULLY_OBSCURED; ec->visibility.changed = 1; - ELOGF("POL_VIS", "CLIENT VIS OFF. argb:%d, opaque:%2d, frame_v:%d, canvas_v:%d, calc_r:%d(%d), rot_p:%d", - ec, ec->argb, ec->visibility.opaque, - ec_frame_visible, canvas_vis, calc_region, calc_skip_type, skip_rot_pending_show); + ELOGF("POL_VIS", "CLIENT VIS OFF. argb:%d, opaque:%2d, frame_v:%d, canvas_v:%d, calc_r:%d(%d), show_p:%d", + ec, ec->argb, ec->visibility.opaque, + ec_frame_visible, canvas_vis, calc_region, calc_skip_type, skip_by_pending_show); } } } if (!is_vis_on_skip) changed_list = eina_list_append(changed_list, ec); - is_above_rot_pending |= skip_rot_pending_show; + + if (skip_rot_pending_show) + is_above_show_pending = EINA_TRUE; } if (changed_list) @@ -8159,6 +8170,38 @@ e_client_stack_below(E_Client *ec, E_Client *below) evas_object_stack_below(ec->frame, below->frame); } +E_API int +e_client_show_pending_set(E_Client *ec) +{ + if (!ec) return 0; + + ec->show_pending.count++; + ELOGF("E_CLIENT", "SET show_pending. (count:%d, run:%d)", ec, ec->show_pending.count, ec->show_pending.running); + return ec->show_pending.count; +} + +E_API int +e_client_show_pending_unset(E_Client *ec) +{ + if (!ec) return 0; + if (ec->show_pending.count <= 0) return 0; + + ec->show_pending.count--; + ELOGF("E_CLIENT", "UNSET show_pending. (count:%d, run:%d)", ec, ec->show_pending.count, ec->show_pending.running); + if (ec->show_pending.count == 0 && ec->show_pending.running) + { + ec->show_pending.running = EINA_FALSE; + if (ec->frame) + { + ELOGF("E_CLIENT", "evas_object_show by unset show_pending", ec); + evas_object_show(ec->frame); + //e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h); + } + } + + return ec->show_pending.count; +} + static Eina_Bool _e_client_surface_tree_foreach_helper(E_Client *ec, E_Client_Surface_Tree_Foreach func, void *data) { diff --git a/src/bin/e_client.h b/src/bin/e_client.h index 4aef0c40f3..fb20dcbced 100644 --- a/src/bin/e_client.h +++ b/src/bin/e_client.h @@ -1012,6 +1012,11 @@ struct E_Client } desk_group; Eina_Bool transient_for_always_on_top; + struct + { + int count; + Eina_Bool running; + } show_pending; }; #define e_client_focus_policy_click(ec) \ @@ -1244,6 +1249,9 @@ E_API void e_client_stack_above(E_Client *ec, E_Client *above); // ec is placed under the below E_API void e_client_stack_below(E_Client *ec, E_Client *below); +E_API int e_client_show_pending_set(E_Client *ec); +E_API int e_client_show_pending_unset(E_Client *ec); + EINTERN void e_client_surface_tree_foreach(E_Client *ec, E_Client_Surface_Tree_Foreach func, void *data); /** diff --git a/src/bin/e_comp_object.c b/src/bin/e_comp_object.c index 19b236c635..a943cc1c58 100644 --- a/src/bin/e_comp_object.c +++ b/src/bin/e_comp_object.c @@ -2303,6 +2303,13 @@ _e_comp_intercept_show_helper(E_Comp_Object *cw) EINA_SAFETY_ON_NULL_RETURN(cw->ec); + if (ec->show_pending.count > 0) + { + ELOGF("COMP", "show_helper. Show PENDING!!! show_pending:%d", ec, ec->show_pending.count); + ec->show_pending.running = EINA_TRUE; + return; + } + #ifdef _F_E_COMP_OBJECT_INTERCEPT_HOOK_ if (!_e_comp_object_intercept_hook_call(E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER, ec)) { diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index fe3352937f..00847c8c49 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -2509,6 +2509,19 @@ _e_comp_wl_surface_state_commit(E_Client *ec, E_Comp_Wl_Surface_State *state) (ec->comp_data->shell.unmap)) { ELOGF("COMP", "Try to unmap. Call shell.unmap.", ec); + if (ec->show_pending.count > 0) + { + ELOGF("E_CLIENT", "Reset show_pending!!! (count:%d, run:%d)", ec, ec->show_pending.count, ec->show_pending.running); + ec->show_pending.count = 0; + if (ec->show_pending.running) + { + // need to send visibility false; + ec->visibility.obscured = E_VISIBILITY_UNOBSCURED; + ELOGF("POL_VIS", "CLIENT VIS ON (fake). argb:%d, opaque:%2d", ec, ec->argb, ec->visibility.opaque); + EC_CHANGED(ec); + } + ec->show_pending.running = EINA_FALSE; + } ec->comp_data->shell.unmap(ec->comp_data->shell.surface); } else if ((ec->internal) || diff --git a/src/bin/e_comp_wl_shell.c b/src/bin/e_comp_wl_shell.c index 4fbe8bb407..71afc7e005 100644 --- a/src/bin/e_comp_wl_shell.c +++ b/src/bin/e_comp_wl_shell.c @@ -798,7 +798,7 @@ _e_shell_client_map_common_post(E_Client *ec) ec->first_mapped = 1; e_policy_visibility_client_hide_job_cancel(ec); - if (!(ec->iconic && ec->exp_iconify.by_client) && !ec->bg_state) + if (!(ec->iconic && ec->exp_iconify.by_client) && !ec->bg_state && (ec->show_pending.count == 0)) e_vis_client_check_send_pre_visibility_event(ec, EINA_FALSE); ELOGF("COMP", "Un-Set launching flag", ec); -- 2.34.1