From: Changyeon Lee Date: Thu, 4 Jun 2020 10:25:07 +0000 (+0900) Subject: e_service_launcher: fix frame sync issue in case launcher is widget X-Git-Tag: accepted/tizen/unified/20200618.130049~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F38%2F235638%2F4;p=platform%2Fupstream%2Fenlightenment.git e_service_launcher: fix frame sync issue in case launcher is widget It is possible that previous frame of backward effect is shown by widget viewer window even if showing of launcher client is pending until after prepare event is sent and launcher client attach buffer, because pre visibility and iconify changed event is sent to widget viewer before prepare event is sent to launcher client. so this patch grap uniconify job of widget viewer until widget viewer attach buffer between backward effect launching and done. Change-Id: Ib7c868da83021cd0ceb970181f543b0d33005014 --- diff --git a/src/bin/services/e_service_launcher.c b/src/bin/services/e_service_launcher.c index 840c595..b0d13fd 100644 --- a/src/bin/services/e_service_launcher.c +++ b/src/bin/services/e_service_launcher.c @@ -4,8 +4,9 @@ #include #include "services/e_service_launcher.h" -typedef struct _E_Service_Launcher E_Service_Launcher; -typedef struct _E_Service_Launcher_Handler E_Service_Launcher_Handler; +typedef struct _E_Service_Launcher E_Service_Launcher; +typedef struct _E_Service_Launcher_Handler E_Service_Launcher_Handler; +typedef struct _E_Service_Launcher_Consumer E_Service_Launcher_Consumer; typedef enum { @@ -19,6 +20,18 @@ typedef enum LAUNCHER_STATE_WAIT_RESPONSE_FROM_CALLEE, } Launcher_State; +struct _E_Service_Launcher_Consumer +{ + E_Service_Launcher *lc; + E_Vis_Grab *vis_grab; //grab of client's visibility + + E_Client *ec; + E_Object_Delfn *delfn; //del callback of E_Client + + Ecore_Event_Handler *buff_attach; //event handler for BUFFER_CHANGE + int buff_attach_count; +}; + struct _E_Service_Launcher { Launcher_State state; //current state of launcher @@ -53,6 +66,8 @@ struct _E_Service_Launcher Eina_Bool swl_done; //flag indicating done of callee Eina_Bool block_input; //input is blocked(1) or not(0) while running client side animation + + Eina_List *consumers; //list launcher consumer of launcher ec }; struct _E_Service_Launcher_Handler @@ -178,6 +193,93 @@ _launcher_state_set(E_Service_Launcher *lc, } static void +_launcher_consumer_del(E_Service_Launcher_Consumer *consumer) +{ + E_Service_Launcher *lc; + + EINA_SAFETY_ON_NULL_RETURN(consumer); + + lc = consumer->lc; + + ELOGF("LAUNCHER_SRV", "Del launcher_consumer ec:%p", lc ? lc->ec : NULL, consumer->ec); + + if (consumer->ec) + { + e_object_delfn_del(E_OBJECT(consumer->ec), consumer->delfn); + consumer->ec = NULL; + consumer->delfn = NULL; + } + + if (consumer->vis_grab) + { + e_policy_visibility_client_grab_release(consumer->vis_grab); + consumer->vis_grab = NULL; + } + + if (consumer->buff_attach) + E_FREE_FUNC(consumer->buff_attach, ecore_event_handler_del); + + if (lc) + lc->consumers = eina_list_remove(lc->consumers, consumer); + + free(consumer); +} + +static void +_launcher_cb_consumer_ec_del(void *data, void *obj) +{ + E_Service_Launcher_Consumer *consumer; + E_Client *ec; + + ec = (E_Client *)obj; + EINA_SAFETY_ON_NULL_RETURN(ec); + + consumer= (E_Service_Launcher_Consumer *)data; + EINA_SAFETY_ON_NULL_RETURN(consumer); + EINA_SAFETY_ON_TRUE_RETURN(consumer->ec != ec); + + consumer->ec = NULL; + consumer->delfn = NULL; + + _launcher_consumer_del(consumer); +} + +static E_Service_Launcher_Consumer * +_launcher_consumer_create(E_Service_Launcher *lc, E_Client *ec) +{ + E_Service_Launcher_Consumer *consumer; + + EINA_SAFETY_ON_NULL_RETURN_VAL(lc, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL); + + consumer = E_NEW(E_Service_Launcher_Consumer, 1); + EINA_SAFETY_ON_NULL_RETURN_VAL(consumer, NULL); + + consumer->ec = ec; + consumer->delfn = e_object_delfn_add(E_OBJECT(ec), + _launcher_cb_consumer_ec_del, consumer); + + consumer->lc = lc; + lc->consumers = eina_list_append(lc->consumers, consumer); + + ELOGF("LAUNCHER_SRV", "Create launcher_consumer ec:%p", lc->ec, ec); + + return consumer; +} + +static void +_launcher_consumers_reset(E_Service_Launcher *lc) +{ + E_Service_Launcher_Consumer *consumer; + Eina_List *l, *ll; + + EINA_SAFETY_ON_NULL_RETURN(lc); + + EINA_LIST_FOREACH_SAFE(lc->consumers, l, ll, consumer) + _launcher_consumer_del(consumer); +} + +static void _launcher_post_forward(E_Service_Launcher *lc, Eina_Bool success) { E_Client *target_ec = NULL; @@ -268,6 +370,8 @@ _launcher_post_backward(E_Service_Launcher *lc, Eina_Bool success) lc->vis_grab = NULL; lc->target.vis_grab = NULL; + _launcher_consumers_reset(lc); + if (!target_ec) return; if (success) @@ -546,6 +650,10 @@ _launcher_prepare_backward_send(E_Service_Launcher *lc, { int x, y; Eina_Bool sent = EINA_FALSE; + Eina_List *consumers; + Eina_List *l; + E_Client *ec; + E_Service_Launcher_Consumer *consumer; EINA_SAFETY_ON_NULL_RETURN_VAL(lc, EINA_FALSE); EINA_SAFETY_ON_NULL_RETURN_VAL(activity, EINA_FALSE); @@ -564,6 +672,23 @@ _launcher_prepare_backward_send(E_Service_Launcher *lc, e_policy_animatable_lock(target_ec, E_POLICY_ANIMATABLE_CUSTOMIZED, 1); e_comp_client_override_add(target_ec); + if ((lc->ec) && (lc->ec->remote_surface.provider)) + { + consumers = e_comp_wl_remote_surface_consumers_get(lc->ec); + EINA_LIST_FOREACH(consumers, l, ec) + { + if (e_object_is_del(E_OBJECT(ec))) continue; + if (!e_policy_visibility_client_is_uniconify_render_running(ec)) continue; + + consumer = _launcher_consumer_create(lc, ec); + consumer->vis_grab = e_policy_visibility_client_filtered_grab_get(ec, + (E_VIS_JOB_TYPE_UNICONIFY | + E_VIS_JOB_TYPE_UNICONIFY_BY_VISIBILITY), + __func__); + } + eina_list_free(consumers); + } + if (activity == target_ec) { lc->vis_grab = e_policy_visibility_client_filtered_grab_get(lc->ec, job_type, __func__); @@ -619,6 +744,7 @@ _launcher_data_reset(E_Service_Launcher *lc) _launcher_state_set(lc, LAUNCHER_STATE_IDLE); _launcher_launched_ec_set(lc, NULL); + _launcher_consumers_reset(lc); _launcher_handler_launcher_runner_unset(lc); _launcher_handler_launcher_pre_runner_unset(lc); @@ -664,6 +790,57 @@ clean: } static Eina_Bool +_launcher_cb_launching_consumer_buff_attach(void *data, int type EINA_UNUSED, void *event) +{ + E_Service_Launcher *lc; + E_Service_Launcher_Consumer *consumer; + E_Client *ec; + E_Event_Client *ev; + + consumer = (E_Service_Launcher_Consumer*)data; + EINA_SAFETY_ON_NULL_RETURN_VAL(consumer, ECORE_CALLBACK_PASS_ON); + lc = consumer->lc; + EINA_SAFETY_ON_NULL_GOTO(lc, clean); + EINA_SAFETY_ON_FALSE_GOTO(lc->direction == TWS_SERVICE_LAUNCHER_DIRECTION_BACKWARD, clean); + + ev = (E_Event_Client *)event; + EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON); + EINA_SAFETY_ON_NULL_RETURN_VAL(ev->ec, ECORE_CALLBACK_PASS_ON); + + ec = ev->ec; + if (ec != consumer->ec) return ECORE_CALLBACK_PASS_ON; + + ELOGF("LAUNCHER_SRV", "Event cb(BUFFER_CHANGE) for WAIT_CONSUMER_LAUNCHING count:%d", + ec, consumer->buff_attach_count); + + consumer->buff_attach_count++; + if (consumer->buff_attach_count < 2) return ECORE_CALLBACK_PASS_ON; + + if (consumer->vis_grab) + { + e_policy_visibility_client_grab_release(consumer->vis_grab); + consumer->vis_grab = NULL; + } + +clean: + _launcher_consumer_del(consumer); + + return ECORE_CALLBACK_PASS_ON; +} + +static void +_launcher_consumers_buffer_change_wait(E_Service_Launcher *lc) +{ + E_Service_Launcher_Consumer *consumer; + Eina_List *l; + + EINA_LIST_FOREACH(lc->consumers, l, consumer) + consumer->buff_attach = ecore_event_handler_add(E_EVENT_CLIENT_BUFFER_CHANGE, + _launcher_cb_launching_consumer_buff_attach, + consumer); +} + +static Eina_Bool _launcher_cb_launching_buff_attach(void *data, int type EINA_UNUSED, void *event) { E_Service_Launcher *lc; @@ -684,7 +861,10 @@ _launcher_cb_launching_buff_attach(void *data, int type EINA_UNUSED, void *event ELOGF("LAUNCHER_SRV", "Event cb(BUFFER_CHANGE) for LAUNCHING", ec); if (lc->state == LAUNCHER_STATE_LAUNCHING_WAIT_BUFFER) - _launcher_state_set(lc, LAUNCHER_STATE_LAUNCHING); + { + _launcher_consumers_buffer_change_wait(lc); + _launcher_state_set(lc, LAUNCHER_STATE_LAUNCHING); + } if (lc->vis_grab) {