e_client: Introduce a way of embdding a client to support wtz_foreign protocol 00/255100/6 accepted/tizen/unified/20210403.020828 submit/tizen/20210331.060244 submit/tizen/20210401.063607 submit/tizen/20210402.004228
authorSeunghun Lee <shiin.lee@samsung.com>
Wed, 10 Mar 2021 08:25:46 +0000 (17:25 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Wed, 31 Mar 2021 03:28:34 +0000 (03:28 +0000)
This is an attempt to embed one E_Client into another E_Client and make
it live in. Thus embbeded E_Client will follow stack order of its
container E_Client automatically by evas smart object.

This patch will be necessary in the future patch to support wtz_foreign
protocol.

Change-Id: I3b0dde95e13aee0ae58275e3afdeb0befd6a37ca

src/bin/e_client.c
src/bin/e_client.h
src/bin/e_comp_object.c
src/bin/e_comp_object.h
src/bin/e_comp_wl.c

index d3a60a3..196d5b6 100644 (file)
@@ -1,5 +1,7 @@
 #include "e.h"
 
+const char *EMBEDDED_CLIENT_DATA_KEY = "Embedded Client";
+
 static int _e_client_hooks_delete = 0;
 static int _e_client_hooks_walking = 0;
 
@@ -1235,6 +1237,8 @@ _e_client_free(E_Client *ec)
         e_object_unref(E_OBJECT(ec->e.state.profile.wait_desk));
      }
    ec->e.state.profile.wait_desk = NULL;
+
+   evas_object_data_del(ec->frame, EMBEDDED_CLIENT_DATA_KEY);
    E_FREE_FUNC(ec->frame, evas_object_del);
 
    if (ec == focused)
@@ -8352,4 +8356,52 @@ e_client_cdata_get(E_Client *ec)
    if (!ec) return NULL;
 
    return ec->comp_data;
-}
\ No newline at end of file
+}
+
+EINTERN Eina_Bool
+e_client_embedded_client_set(E_Client *ec, E_Client *embedded_ec)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec->frame, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(embedded_ec, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(embedded_ec->frame, EINA_FALSE);
+
+   eina_stringshare_replace(&ec->netwm.name, "Container Client");
+   eina_stringshare_replace(&embedded_ec->netwm.name, "Embedded Client");
+
+   evas_object_data_set(ec->frame, EMBEDDED_CLIENT_DATA_KEY, embedded_ec);
+   e_comp_object_embedded_comp_object_set(ec->frame, embedded_ec->frame);
+
+   return EINA_TRUE;
+}
+
+EINTERN void
+e_client_embedded_client_unset(E_Client *ec)
+{
+   E_Client *embedded_ec;
+
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+   EINA_SAFETY_ON_NULL_RETURN(ec->frame);
+
+   embedded_ec = evas_object_data_get(ec->frame, EMBEDDED_CLIENT_DATA_KEY);
+   if (!embedded_ec)
+     {
+        ELOGF("E_CLIENT", "Cannot find data for embedded client", ec);
+        return;
+     }
+
+   eina_stringshare_replace(&ec->netwm.name, NULL);
+   eina_stringshare_replace(&embedded_ec->netwm.name, NULL);
+
+   e_comp_object_embedded_comp_object_unset(ec->frame);
+   evas_object_data_del(ec->frame, EMBEDDED_CLIENT_DATA_KEY);
+}
+
+EINTERN Eina_Bool
+e_client_embedded_client_check(E_Client *ec)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec->frame, EINA_FALSE);
+
+   return !!evas_object_data_get(ec->frame, EMBEDDED_CLIENT_DATA_KEY);
+}
index 43fcf39..1b46ab6 100644 (file)
@@ -1266,6 +1266,10 @@ EINTERN E_Comp_Wl_Client_Data   *e_client_cdata_new(E_Client *ec);
 EINTERN void                     e_client_cdata_free(E_Client *ec);
 EINTERN E_Comp_Wl_Client_Data   *e_client_cdata_get(E_Client *ec);
 
+EINTERN Eina_Bool e_client_embedded_client_set(E_Client *ec, E_Client *in_ec);
+EINTERN void      e_client_embedded_client_unset(E_Client *ec);
+EINTERN Eina_Bool e_client_embedded_client_check(E_Client *ec);
+
 /**
  * Move window to coordinates that do not account client decorations yet.
  *
index 1a876e8..7d434d2 100644 (file)
@@ -137,6 +137,7 @@ typedef struct _E_Comp_Object
    Eina_Bool            external_content : 1; // e.swallow.content(obj) is set by external evas object
    Eina_Bool            user_alpha_set : 1;
    Eina_Bool            user_alpha : 1;
+   Eina_Bool            embedded : 1;
 
    struct
      {
@@ -621,8 +622,9 @@ _e_comp_object_alpha_set(E_Comp_Object *cw)
 {
    Eina_Bool alpha = cw->ec->argb;
 
-   if ((cw->external_content) &&
-       (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
+   if (((cw->external_content) &&
+        (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE)) ||
+       (cw->embedded))
      {
         return;
      }
@@ -1689,8 +1691,9 @@ _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
        (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph))))
      return;
 
-   if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
-       cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE)
+   if ((cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE ||
+        cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) ||
+       (cw->embedded))
      pw = w, ph = h;
    prev_w = cw->w, prev_h = cw->h;
    e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh);
@@ -2275,6 +2278,14 @@ _e_comp_intercept_hide(void *data, Evas_Object *obj)
         evas_object_hide(obj);
         return;
      }
+
+   if (cw->embedded)
+     {
+        ELOGF("COMP", "Hide container evas_object:%p", cw->ec, obj);
+        evas_object_hide(obj);
+        return;
+     }
+
    /* already hidden or currently animating */
    if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic)))
      {
@@ -2375,7 +2386,7 @@ _e_comp_intercept_show_helper(E_Comp_Object *cw)
 
         return;
      }
-   if ((!cw->updates) && (!ec->input_only) && (!ec->ignored))
+   if ((!cw->updates) && (!ec->input_only) && (!ec->ignored) && (!cw->embedded))
      {
         int pw, ph;
 
@@ -2411,7 +2422,7 @@ _e_comp_intercept_show_helper(E_Comp_Object *cw)
         ELOGF("COMP", "show_helper. return. new_client", ec);
         return;
      }
-   if (ec->input_only)
+   if ((ec->input_only) || (cw->embedded))
      {
         /* who cares */
         cw->real_hid = 0;
@@ -3211,6 +3222,13 @@ _e_comp_smart_show(Evas_Object *obj)
 
    e_comp_object_map_update(obj);
 
+   if (cw->embedded)
+     {
+        evas_object_show(cw->effect_obj);
+        TRACE_DS_END();
+        return;
+     }
+
    EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp)
      evas_object_show(tmp->frame);
 
@@ -3348,6 +3366,9 @@ _e_comp_smart_move(Evas_Object *obj, int x, int y)
    if (cw->input_obj) evas_object_move(cw->input_obj, x, y);
 
    e_comp_object_map_update(obj);
+
+   if (cw->embedded)
+     evas_object_move(cw->obj, x, y);
 }
 
 static void
@@ -5443,8 +5464,9 @@ e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha)
 {
    API_ENTRY;
 
-   if ((cw->external_content) &&
-       (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
+   if (((cw->external_content) &&
+        (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE)) ||
+       (cw->embedded))
      {
         WRN("Can set up alpha value to ONLY evas \"image\" object. "
             "But current external content is %d object for %p.",
@@ -5532,8 +5554,9 @@ e_comp_object_size_update(Evas_Object *obj, int w, int h)
    int tw, th;
    API_ENTRY;
 
-   if ((cw->external_content) &&
-       (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE))
+   if (((cw->external_content) &&
+        (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE)) ||
+       (cw->embedded))
      {
         WRN("Can set up size to ONLY evas \"image\" object. "
             "But current external content is %d object for %p.",
@@ -6383,3 +6406,56 @@ e_comp_object_color_visible_get(Evas_Object *obj)
 
    return EINA_TRUE;
 }
+
+static void
+_e_comp_object_cb_embedded_comp_object_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+   E_Comp_Object *cw;
+
+   cw = data;
+
+   evas_object_smart_member_del(cw->obj);
+   evas_object_event_callback_del(cw->obj, EVAS_CALLBACK_DEL, _e_comp_object_cb_embedded_comp_object_del);
+   cw->obj = NULL;
+}
+
+EINTERN Eina_Bool
+e_comp_object_embedded_comp_object_set(Evas_Object *obj, Evas_Object *in_obj)
+{
+   API_ENTRY EINA_FALSE;
+
+   cw->embedded = EINA_TRUE;
+   cw->external_content = EINA_TRUE;
+
+   cw->effect_obj = evas_object_rectangle_add(e_comp->evas);
+   evas_object_color_set(cw->effect_obj, 0, 0, 0, 0);
+   evas_object_smart_member_add(cw->effect_obj, cw->smart_obj);
+
+   cw->obj = in_obj;
+   evas_object_smart_member_add(cw->obj, cw->smart_obj);
+   evas_object_event_callback_add(cw->obj, EVAS_CALLBACK_DEL, _e_comp_object_cb_embedded_comp_object_del, cw);
+
+   return EINA_TRUE;
+}
+
+EINTERN void
+e_comp_object_embedded_comp_object_unset(Evas_Object *obj)
+{
+   API_ENTRY;
+
+   if (!cw->embedded)
+     return;
+
+   cw->embedded = EINA_FALSE;
+   cw->external_content = EINA_FALSE;
+
+   evas_object_del(cw->effect_obj);
+   cw->effect_obj = NULL;
+
+   if (cw->obj)
+     {
+        evas_object_event_callback_del(cw->obj, EVAS_CALLBACK_DEL, _e_comp_object_cb_embedded_comp_object_del);
+        evas_object_smart_member_del(cw->obj);
+        cw->obj = NULL;
+     }
+}
index 0b0cd1d..c4b63f0 100644 (file)
@@ -203,6 +203,9 @@ EINTERN void e_comp_object_damage_trace_debug(Eina_Bool onoff);
 
 EINTERN Eina_Bool e_comp_object_redirected_get(Evas_Object *obj);
 EINTERN Eina_Bool e_comp_object_color_visible_get(Evas_Object *obj);
+
+EINTERN Eina_Bool e_comp_object_embedded_comp_object_set(Evas_Object *obj, Evas_Object *in_obj);
+EINTERN void      e_comp_object_embedded_comp_object_unset(Evas_Object *obj);
 #endif
 #endif
 
index f2d46ec..9892ee8 100644 (file)
@@ -2534,80 +2534,83 @@ _e_comp_wl_surface_state_commit(E_Client *ec, E_Comp_Wl_Surface_State *state)
           }
      }
 
-   /* map or unmap ec */
-   if (!e_pixmap_usable_get(ec->pixmap))
+   if (!e_client_embedded_client_check(ec))
      {
-        /* unmap ec */
-        if (cdata->mapped)
+        /* map or unmap ec */
+        if (!e_pixmap_usable_get(ec->pixmap))
           {
-             if ((cdata->shell.surface) &&
-                 (cdata->shell.unmap))
+             /* unmap ec */
+             if (cdata->mapped)
                {
-                  ELOGF("COMP", "Try to unmap. Call shell.unmap.", ec);
-                  if (ec->show_pending.count > 0)
+                  if ((cdata->shell.surface) &&
+                      (cdata->shell.unmap))
                     {
-                       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)
+                       ELOGF("COMP", "Try to unmap. Call shell.unmap.", ec);
+                       if (ec->show_pending.count > 0)
                          {
-                            // 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);
+                            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->show_pending.running = EINA_FALSE;
+                       cdata->shell.unmap(cdata->shell.surface);
+                    }
+                  else if ((ec->internal) ||
+                           (cdata->sub.data) ||
+                           (ec == e_comp_wl->drag_client))
+                    {
+                       ELOGF("COMP", "Try to unmap. Hide window. internal:%d, sub:%p, drag:%d",
+                             ec, ec->internal, cdata->sub.data, (ec == e_comp_wl->drag_client));
+                       ec->visible = EINA_FALSE;
+                       evas_object_hide(ec->frame);
+                       cdata->mapped = 0;
                     }
-                  cdata->shell.unmap(cdata->shell.surface);
                }
-             else if ((ec->internal) ||
-                      (cdata->sub.data) ||
-                      (ec == e_comp_wl->drag_client))
+
+             if ((cdata->sub.below_obj) &&
+                 (evas_object_visible_get(cdata->sub.below_obj)))
                {
-                  ELOGF("COMP", "Try to unmap. Hide window. internal:%d, sub:%p, drag:%d",
-                        ec, ec->internal, cdata->sub.data, (ec == e_comp_wl->drag_client));
-                  ec->visible = EINA_FALSE;
-                  evas_object_hide(ec->frame);
-                  cdata->mapped = 0;
+                  evas_object_hide(cdata->sub.below_obj);
                }
           }
-
-        if ((cdata->sub.below_obj) &&
-            (evas_object_visible_get(cdata->sub.below_obj)))
-          {
-             evas_object_hide(cdata->sub.below_obj);
-          }
-     }
-   else
-     {
-        /* map ec */
-        if (!cdata->mapped)
+        else
           {
-             if ((cdata->shell.surface) &&
-                 (cdata->shell.map) &&
-                 (!ec->ignored))
+             /* map ec */
+             if (!cdata->mapped)
                {
-                  ELOGF("COMP", "Try to map. Call shell.map.", ec);
-                  cdata->shell.map(cdata->shell.surface);
+                  if ((cdata->shell.surface) &&
+                      (cdata->shell.map) &&
+                      (!ec->ignored))
+                    {
+                       ELOGF("COMP", "Try to map. Call shell.map.", ec);
+                       cdata->shell.map(cdata->shell.surface);
+                    }
+                  else if ((ec->internal) ||
+                           (e_comp_wl_subsurface_can_show(ec)) ||
+                           (ec == e_comp_wl->drag_client))
+                    {
+                       ELOGF("COMP", "Try to map. Show window. internal:%d, drag:%d",
+                             ec, ec->internal, (ec == e_comp_wl->drag_client));
+                       ec->visible = EINA_TRUE;
+                       ec->ignored = 0;
+                       evas_object_show(ec->frame);
+                       cdata->mapped = 1;
+                    }
                }
-             else if ((ec->internal) ||
-                      (e_comp_wl_subsurface_can_show(ec)) ||
-                      (ec == e_comp_wl->drag_client))
+
+             if ((cdata->sub.below_obj) &&
+                 (!evas_object_visible_get(cdata->sub.below_obj)) &&
+                 (evas_object_visible_get(ec->frame)))
                {
-                  ELOGF("COMP", "Try to map. Show window. internal:%d, drag:%d",
-                        ec, ec->internal, (ec == e_comp_wl->drag_client));
-                  ec->visible = EINA_TRUE;
-                  ec->ignored = 0;
-                  evas_object_show(ec->frame);
-                  cdata->mapped = 1;
+                  evas_object_show(cdata->sub.below_obj);
                }
           }
-
-        if ((cdata->sub.below_obj) &&
-            (!evas_object_visible_get(cdata->sub.below_obj)) &&
-            (evas_object_visible_get(ec->frame)))
-          {
-             evas_object_show(cdata->sub.below_obj);
-          }
      }
 
    if ((state->new_attach) ||
@@ -4423,55 +4426,59 @@ e_comp_wl_surface_commit(E_Client *ec)
         e_comp_wl_subsurface_restack_bg_rectangle(topmost);
      }
 
-   if (!e_pixmap_usable_get(ec->pixmap))
+   if (!e_client_embedded_client_check(ec))
      {
-        if (ec->comp_data->mapped)
+        if (!e_pixmap_usable_get(ec->pixmap))
           {
-             if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.unmap))
-               {
-                  ELOGF("COMP", "Try to unmap2. Call shell.unmap.", ec);
-                  ec->comp_data->shell.unmap(ec->comp_data->shell.surface);
-               }
-             else if (ec->internal || ec->comp_data->sub.data ||
-                      (ec == e_comp_wl->drag_client))
+             if (ec->comp_data->mapped)
                {
-                  ELOGF("COMP", "Try to unmap2. Hide window. internal:%d, sub:%p, drag:%d",
-                        ec, ec->internal, ec->comp_data->sub.data, (ec == e_comp_wl->drag_client));
-                  ec->visible = EINA_FALSE;
-                  evas_object_hide(ec->frame);
-                  ec->comp_data->mapped = 0;
+                  if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.unmap))
+                    {
+                       ELOGF("COMP", "Try to unmap2. Call shell.unmap.", ec);
+                       ec->comp_data->shell.unmap(ec->comp_data->shell.surface);
+                    }
+                  else if (ec->internal || ec->comp_data->sub.data ||
+                           (ec == e_comp_wl->drag_client))
+                    {
+                       ELOGF("COMP", "Try to unmap2. Hide window. internal:%d, sub:%p, drag:%d",
+                             ec, ec->internal, ec->comp_data->sub.data, (ec == e_comp_wl->drag_client));
+                       ec->visible = EINA_FALSE;
+                       evas_object_hide(ec->frame);
+                       ec->comp_data->mapped = 0;
+                    }
                }
-          }
 
-        if (ec->comp_data->sub.below_obj && evas_object_visible_get(ec->comp_data->sub.below_obj))
-          evas_object_hide(ec->comp_data->sub.below_obj);
-     }
-   else
-     {
-        if (!ec->comp_data->mapped)
+             if (ec->comp_data->sub.below_obj && evas_object_visible_get(ec->comp_data->sub.below_obj))
+               evas_object_hide(ec->comp_data->sub.below_obj);
+          }
+        else
           {
-             if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.map) &&
-                 (!ec->ignored))
-               {
-                  ELOGF("COMP", "Try to map2. Call shell.map.", ec);
-                  ec->comp_data->shell.map(ec->comp_data->shell.surface);
-               }
-             else if (ec->internal || e_comp_wl_subsurface_can_show(ec) ||
-                      (ec == e_comp_wl->drag_client))
+             if (!ec->comp_data->mapped)
                {
-                  ELOGF("COMP", "Try to map2. Show window. internal:%d, drag:%d",
-                        ec, ec->internal, (ec == e_comp_wl->drag_client));
-                  ec->visible = EINA_TRUE;
-                  ec->ignored = 0;
-                  evas_object_show(ec->frame);
-                  ec->comp_data->mapped = 1;
+                  if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.map) &&
+                      (!ec->ignored))
+                    {
+                       ELOGF("COMP", "Try to map2. Call shell.map.", ec);
+                       ec->comp_data->shell.map(ec->comp_data->shell.surface);
+                    }
+                  else if (ec->internal || e_comp_wl_subsurface_can_show(ec) ||
+                           (ec == e_comp_wl->drag_client))
+                    {
+                       ELOGF("COMP", "Try to map2. Show window. internal:%d, drag:%d",
+                             ec, ec->internal, (ec == e_comp_wl->drag_client));
+                       ec->visible = EINA_TRUE;
+                       ec->ignored = 0;
+                       evas_object_show(ec->frame);
+                       ec->comp_data->mapped = 1;
+                    }
                }
-          }
 
-        if (ec->comp_data->sub.below_obj && !evas_object_visible_get(ec->comp_data->sub.below_obj)
-            && evas_object_visible_get(ec->frame))
-          evas_object_show(ec->comp_data->sub.below_obj);
+             if (ec->comp_data->sub.below_obj && !evas_object_visible_get(ec->comp_data->sub.below_obj)
+                 && evas_object_visible_get(ec->frame))
+               evas_object_show(ec->comp_data->sub.below_obj);
+          }
      }
+
    ec->ignored = ignored;
 
    if (ec->is_cursor && ec->visible)