e_service_launcher: fix frame sync issue in case launcher is widget 38/235638/4
authorChangyeon Lee <cyeon.lee@samsung.com>
Thu, 4 Jun 2020 10:25:07 +0000 (19:25 +0900)
committerChangyeon Lee <cyeon.lee@samsung.com>
Wed, 10 Jun 2020 04:43:13 +0000 (13:43 +0900)
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

src/bin/services/e_service_launcher.c

index 840c595..b0d13fd 100644 (file)
@@ -4,8 +4,9 @@
 #include <wayland-tbm-server.h>
 #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)
      {