Video buffers are included into window transition effect 62/120062/4
authorMinJeong Kim <minjjj.kim@samsung.com>
Mon, 20 Mar 2017 07:23:21 +0000 (16:23 +0900)
committerMinJeong Kim <minjjj.kim@samsung.com>
Wed, 5 Apr 2017 07:10:28 +0000 (00:10 -0700)
Change-Id: I996b5cf329ce871fc3100f6d0b8dcfbd47a69b74
Signed-off-by: MinJeong Kim <minjjj.kim@samsung.com>
configure.ac
data/group/zoom.edc
packaging/e-mod-tizen-effect.spec
src/e_mod_effect.c
src/e_mod_effect.h

index d1e0713..50adf4e 100644 (file)
@@ -60,7 +60,7 @@ PKG_PROG_PKG_CONFIG
 dnl ========================================================================
 # checks for pkg-config
 dnl ========================================================================
-PKG_CHECK_MODULES(ENLIGHTENMENT, [enlightenment])
+PKG_CHECK_MODULES(ENLIGHTENMENT, [enlightenment, wayland-server, tizen-extension-server, wayland-tbm-server, libtdm])
 AC_SUBST(ENLIGHTENMENT_CFLAGS)
 AC_SUBST(ENLIGHTENMENT_LIBS)
 
index e82b0a8..c266440 100644 (file)
@@ -10,30 +10,35 @@ group { name: "e/comp/effects/zoom";
                        set_state(PART:"clipper", "default", 0.0);
                        set_state(PART:"shower", "default", 0.0);
                        set_state(PART:"e.swallow.content", "default", 0.0);
+                       set_state(PART:"under", "default", 0.0);
                     }
                   else if (st == 1)
                     {
                        set_state(PART:"clipper", "visible", 0.0);
                        set_state(PART:"shower", "visible", 0.0);
                        set_state(PART:"e.swallow.content", "visible", 0.0);
+                       set_state(PART:"under", "visible", 0.0);
                     }
                   else if (st == 2)
                     {
                        set_state(PART:"clipper", "restack_hidden", 0.0);
                        set_state(PART:"shower", "restack_hidden", 0.0);
                        set_state(PART:"e.swallow.content", "restack_hidden", 0.0);
+                       set_state(PART:"under", "restack_hidden", 0.0);
                     }
                   else if (st == 3)
                     {
                        set_state(PART:"clipper", "restack_visible", 0.0);
                        set_state(PART:"shower", "restack_visible", 0.0);
                        set_state(PART:"e.swallow.content", "restack_visible", 0.0);
+                       set_state(PART:"under", "restack_visible", 0.0);
                     }
                   else if (st == 4)
                     {
                        set_state(PART:"clipper", "restack_done", 0.0);
                        set_state(PART:"shower", "restack_done", 0.0);
                        set_state(PART:"e.swallow.content", "restack_done", 0.0);
+                       set_state(PART:"under", "restack_done", 0.0);
                     }
              } else if ((type == MSG_INT_SET) && (id == 1))
                {
@@ -137,6 +142,49 @@ group { name: "e/comp/effects/zoom";
            inherit: "visible" 0.0;
         }
      }
+     part { name: "under";
+       type: SWALLOW;
+       clip_to: "clipper";
+        description { state: "default" 0.0;
+           rel1.to: "shower";
+           rel2.to: "shower";
+           map {
+              on: 1;
+              smooth: 1;
+              zoom.x: 0.9;
+              zoom.y: 0.9;
+           }
+        }
+        description { state: "visible" 0.0;
+           rel1.to: "shower";
+           rel2.to: "shower";
+            map {
+              on: 1;
+              smooth: 1;
+              zoom.x: 1;
+              zoom.y: 1;
+           }
+        }
+        description { state: "visible_default" 0.0;
+             rel1.to: "shower";
+             rel2.to: "shower";
+             rel1.relative: 0 0;
+             rel2.relative: 1 1;
+             map.on : 0;
+        }
+        description { state: "hide" 0.0;
+           inherit: "default" 0.0;
+        }
+        description { state: "restack_visible" 0.0;
+           inherit: "visible" 0.0;
+        }
+        description { state: "restack_hidden" 0.0;
+           inherit: "default" 0.0;
+        }
+        description { state: "restack_done" 0.0;
+           inherit: "visible" 0.0;
+        }
+     }
    }
     programs {
      program { name: "show1";
@@ -148,6 +196,7 @@ group { name: "e/comp/effects/zoom";
         target: "shower";
         target: "clipper";
         target: "e.swallow.content";
+        target: "under";
         after: "show2";
      }
      program { name: "show2";
@@ -156,10 +205,12 @@ group { name: "e/comp/effects/zoom";
         target: "shower";
         target: "clipper";
         target: "e.swallow.content";
+        target: "under";
         after: "show3";
      }
      program { name: "show3";
         action: STATE_SET "visible_default" 0.0;
+        target: "under";
         target: "e.swallow.content";
         after: "done";
      }
@@ -172,6 +223,7 @@ group { name: "e/comp/effects/zoom";
         target: "shower";
         target: "clipper";
         target: "e.swallow.content";
+        target: "under";
         after: "hide2";
      }
      program { name: "hide2";
@@ -180,6 +232,7 @@ group { name: "e/comp/effects/zoom";
         target: "shower";
         target: "clipper";
         target: "e.swallow.content";
+        target: "under";
         after: "hide3";
      }
      program { name: "hide3";
@@ -187,6 +240,7 @@ group { name: "e/comp/effects/zoom";
         target: "shower";
         target: "clipper";
         target: "e.swallow.content";
+        target: "under";
         after: "done";
      }
      program { name: "restack,show1";
@@ -198,6 +252,7 @@ group { name: "e/comp/effects/zoom";
         target: "shower";
         target: "clipper";
         target: "e.swallow.content";
+        target: "under";
         after: "restack,show2";
      }
      program { name: "restack,show2";
@@ -206,11 +261,13 @@ group { name: "e/comp/effects/zoom";
         target: "shower";
         target: "clipper";
         target: "e.swallow.content";
+        target: "under";
         after: "restack,show3";
      }
      program { name: "restack,show3";
         action: STATE_SET "visible_default" 0.0;
         target: "e.swallow.content";
+        target: "under";
         after: "done";
      }
      program { name: "restack,hide1";
@@ -222,6 +279,7 @@ group { name: "e/comp/effects/zoom";
         target: "shower";
         target: "clipper";
         target: "e.swallow.content";
+        target: "under";
         after: "restack,hide2";
      }
      program { name: "restack,hide2";
@@ -230,6 +288,7 @@ group { name: "e/comp/effects/zoom";
         target: "shower";
         target: "clipper";
         target: "e.swallow.content";
+        target: "under";
         after: "done";
      }
      program { name: "restack,finish";
@@ -240,6 +299,7 @@ group { name: "e/comp/effects/zoom";
         target: "shower";
         target: "clipper";
         target: "e.swallow.content";
+        target: "under";
         after: "done";
      }
      program { name: "done";
index b091dde..1b44363 100644 (file)
@@ -12,9 +12,10 @@ BuildRequires: pkgconfig(ecore)
 BuildRequires: pkgconfig(edje)
 BuildRequires:  gettext
 BuildRequires:  edje-tools
-BuildRequires:  pkgconfig(wayland-server)
-BuildRequires:  pkgconfig(tizen-extension-server)
+BuildRequires: pkgconfig(wayland-server)
+BuildRequires: pkgconfig(tizen-extension-server)
 BuildRequires: pkgconfig(wayland-tbm-server)
+BuildRequires: pkgconfig(libtdm)
 
 %global TZ_SYS_RO_SHARE  %{?TZ_SYS_RO_SHARE:%TZ_SYS_RO_SHARE}%{!?TZ_SYS_RO_SHARE:/usr/share}
 
index d8d4a06..2fb2cc5 100644 (file)
@@ -1,4 +1,5 @@
 #include "e_mod_effect.h"
+#include <tdm.h>
 
 static E_Effect *_eff = NULL;
 
@@ -10,8 +11,169 @@ typedef struct _E_Effect_Client
    E_Comp_Wl_Buffer_Ref buffer_ref;
    E_Pixmap *ep;
    E_Client *reverse_ec;
+
+   Evas_Object *under;
+   unsigned int under_ref;
 } E_Effect_Client;
 
+typedef struct
+{
+   tdm_layer *tlayer;
+   int zpos;
+} Under_Layer;
+
+static int
+_eff_object_underlayer_sort(const void *data1, const void *data2)
+{
+   const Under_Layer *layer1, *layer2;
+
+   layer1 = data1;
+   layer2 = data2;
+
+   if (layer1->zpos < layer2->zpos)
+     return -1;
+   else if (layer1->zpos > layer2->zpos)
+     return 1;
+   else
+     return 0;
+}
+
+static Evas_Object *
+_eff_object_underlayer_get(E_Client *ec)
+{
+   Evas_Object *underlay = NULL;
+   E_Comp_Screen *e_comp_screen;
+   Eina_List *l;
+   tdm_layer *layer;
+   Under_Layer *ulayer;
+
+   e_comp_screen = e_comp->e_comp_screen;
+   if (!e_comp_screen)
+     return NULL;
+
+   if (e_client_video_client_has(ec))
+     {
+        if ((!_eff->under_layers) && (!_eff->under_checked))
+          {
+             int i, count;
+             int primary_index, primary_zpos;
+             tdm_layer *primary_layer;
+             tdm_output *output;
+             tdm_layer_capability capabilities;
+
+             output = tdm_display_get_output(e_comp_screen->tdisplay, 0, NULL);
+             if (!output) return NULL;
+
+             tdm_output_get_primary_index(output, &primary_index);
+             primary_layer = tdm_output_get_layer(output, primary_index, NULL);
+             if (!primary_layer) return NULL;
+
+             tdm_layer_get_zpos(primary_layer, &primary_zpos);
+             tdm_output_get_layer_count(output, &count);
+
+             for (i = 0; i < count; i++)
+               {
+                  int zpos;
+
+                  if (i == primary_index) continue;
+
+                  layer = tdm_output_get_layer(output, i, NULL);
+                  if (!layer) continue;
+
+                  tdm_layer_get_capabilities(layer, &capabilities);
+                  if (!(capabilities & TDM_LAYER_CAPABILITY_GRAPHIC)) continue;
+
+                  tdm_layer_get_zpos(layer, &zpos);
+                  if (zpos >= primary_zpos) continue;
+
+                  ulayer = E_NEW(Under_Layer, 1);
+                  ulayer->zpos = zpos;
+                  ulayer->tlayer = layer;
+
+                  _eff->under_layers = eina_list_append(_eff->under_layers,
+                                                        ulayer);
+               }
+
+             _eff->under_checked = EINA_TRUE;
+
+             if (!_eff->under_layers)
+               return NULL;
+
+             _eff->under_layers = eina_list_sort(_eff->under_layers,
+                                                 eina_list_count(_eff->under_layers),
+                                                 _eff_object_underlayer_sort);
+          }
+
+        if (!_eff->under_layers) return NULL;
+
+        EINA_LIST_FOREACH(_eff->under_layers, l, ulayer)
+          {
+             tdm_layer *layer;
+             Evas_Object *img;
+             tbm_surface_h buffer;
+             Evas_Native_Surface ns;
+             tdm_info_layer info;
+
+             layer = ulayer->tlayer;
+
+             buffer = tdm_layer_get_displaying_buffer(layer, NULL);
+             if (!buffer) continue;
+
+             img = evas_object_image_filled_add(e_comp->evas);
+             if (!img) continue;
+
+             tdm_layer_get_info(layer, &info);
+
+             if (info.dst_pos.w <= 0 || info.dst_pos.h <= 0)
+
+             memset(&ns, 0, sizeof(Evas_Native_Surface));
+             ns.version = EVAS_NATIVE_SURFACE_VERSION;
+             ns.type = EVAS_NATIVE_SURFACE_TBM;
+             ns.data.tbm.buffer = buffer;
+
+             evas_object_image_size_set(img, info.dst_pos.w, info.dst_pos.h);
+             evas_object_image_native_surface_set(img, &ns);
+             evas_object_image_pixels_dirty_set(img, EINA_TRUE);
+
+             if (!underlay)
+               {
+                  Evas_Object *bg;
+
+                  underlay = e_layout_add(e_comp->evas);
+                  if (!underlay)
+                    {
+                       evas_object_del(img);
+                       return NULL;
+                    }
+
+                  evas_object_name_set(underlay, "effect-under-layout");
+                  e_layout_virtual_size_set(underlay, ec->zone->w, ec->zone->h);
+                  evas_object_move(underlay, ec->zone->x, ec->zone->y);
+
+                  bg = evas_object_rectangle_add(e_comp->evas);
+                  evas_object_color_set(bg, 0, 0, 0, 255);
+                  e_layout_pack(underlay, bg);
+                  e_layout_child_move(bg, 0, 0);
+                  e_layout_child_resize(bg, ec->zone->w, ec->zone->h);
+                  evas_object_show(bg);
+               }
+
+             e_layout_pack(underlay, img);
+             e_layout_child_move(img, info.dst_pos.x, info.dst_pos.y);
+             e_layout_child_resize(img, info.dst_pos.w, info.dst_pos.h);
+             e_layout_child_raise(img);
+             evas_object_show(img);
+
+             EFFDBG("Video Object Created img(%p) %d,%d %dx%d underlay(%p)",
+                    ec->pixmap, ec,
+                    img, info.dst_pos.x, info.dst_pos.y, info.dst_pos.w, info.dst_pos.h,
+                    underlay);
+          }
+     }
+
+   return underlay;
+}
+
 static void
 _eff_event_send(E_Client *ec, Eina_Bool start, E_Effect_Type type)
 {
@@ -87,6 +249,8 @@ _eff_client_new(E_Client *ec)
    efc->animating = 0;
    efc->delay_del_ref = 0;
    efc->ep = NULL;
+   efc->under_ref = 0;
+   efc->under = NULL;
 
    return efc;
 }
@@ -147,97 +311,6 @@ _eff_group_angle_get(E_Client *ec, E_Effect_Group group)
    return ec->e.state.rot.ang.curr;
 }
 
-static Eina_Bool
-_eff_ref(E_Client *ec)
-{
-   E_Effect_Client *efc;
-
-   if (!_eff) return EINA_FALSE;
-
-   efc = _eff_client_get(ec);
-   if (!efc) return EINA_FALSE;
-
-   if (e_object_is_del(E_OBJECT(ec)))
-     {
-        if (!e_object_delay_del_ref_get(E_OBJECT(ec)))
-          {
-             ERR("Client is deleted already! ec(%p)", ec);
-             eina_hash_del_by_key(_eff->clients, &ec);
-             return EINA_FALSE;
-          }
-     }
-
-   if (!ec->pixmap) return EINA_FALSE;
-   if ((e_comp_object_content_type_get(ec->frame) == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) &&
-       (!e_pixmap_usable_get(ec->pixmap)))
-     return EINA_FALSE;
-
-   if (e_object_is_del(E_OBJECT(ec)))
-     {
-        e_object_delay_del_ref(E_OBJECT(ec));
-        efc->delay_del_ref ++;
-     }
-
-   efc->animating++;
-   e_object_ref(E_OBJECT(ec));
-   efc->ep = e_pixmap_ref(ec->pixmap);
-
-   EFFINF("effect ref efc(%p) animating:%d",
-          efc->ep, efc->ec, efc, efc->animating);
-
-   return EINA_TRUE;
-}
-
-static E_Client *
-_eff_unref(E_Client *ec)
-{
-   E_Effect_Client *efc;
-   int do_unref = 1;
-
-   if (!_eff) return NULL;
-   if (!ec) return NULL;
-
-   efc = _eff_client_get(ec);
-   if (!efc) return NULL;
-
-   while (efc->delay_del_ref)
-     {
-        e_object_delay_del_unref(E_OBJECT(ec));
-        efc->delay_del_ref--;
-     }
-
-   if (e_object_is_del(E_OBJECT(ec)))
-     do_unref = efc->animating;
-
-   efc->animating -= do_unref;
-   while (do_unref)
-     {
-        e_pixmap_free(efc->ep);
-        if (!e_object_unref(E_OBJECT(ec)))
-          {
-             EFFINF("eff unref ec(%p) ep(%p) efc(%p) Client free'd",
-                    NULL, NULL, ec, efc->ep, efc);
-
-             efc->ec = NULL;
-             efc = NULL;
-             eina_hash_del_by_key(_eff->clients, &ec);
-             return NULL;
-          }
-        do_unref --;
-     }
-
-   EFFINF("eff Unref efc(%p) animating:%d",
-          ec->pixmap, ec, efc, efc->animating);
-
-   /* The reference count of wl_buffer will get decremented
-    * immediately after window effect.
-    */
-   if ((efc) && (efc->buffer_ref.buffer))
-     e_comp_wl_buffer_reference(&efc->buffer_ref, NULL);
-
-   return ec;
-}
-
 static void
 _eff_object_setup(E_Client *ec, E_Effect_Group group)
 {
@@ -278,6 +351,103 @@ _eff_object_setup(E_Client *ec, E_Effect_Group group)
 }
 
 static void
+_eff_object_under_cb_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+   E_Effect_Client *efc = (E_Effect_Client *)data;
+   Eina_List *children;
+   Evas_Object *child;
+
+   if (efc->under != obj) return;
+
+   children = e_layout_children_get(obj);
+   EINA_LIST_FREE(children, child)
+     {
+        e_layout_unpack(child);
+        evas_object_del(child);
+     }
+
+   efc->under = NULL;
+   efc->under_ref = 0;
+}
+
+static void
+_eff_object_under_setup(E_Client *ec)
+{
+   E_Effect_Client *efc = NULL;
+   Evas_Object *underlay = NULL;
+
+   efc = _eff_client_get(ec);
+   if (!efc) return;
+
+   if (efc->under)
+     {
+        efc->under_ref ++;
+     }
+   else if ((underlay = _eff_object_underlayer_get(ec)))
+     {
+        Eina_List *children;
+        Evas_Object *child;
+
+        if (e_comp_object_effect_object_part_swallow(ec->frame, "under", underlay))
+          {
+             evas_object_event_callback_add(underlay,
+                                            EVAS_CALLBACK_DEL,
+                                            _eff_object_under_cb_del,
+                                            efc);
+             evas_object_show(underlay);
+             efc->under = underlay;
+             efc->under_ref ++;
+          }
+        else
+          {
+             children = e_layout_children_get(underlay);
+             EINA_LIST_FREE(children, child)
+               {
+                  e_layout_unpack(child);
+                  evas_object_del(child);
+               }
+
+             evas_object_del(underlay);
+          }
+     }
+}
+
+static void
+_eff_object_under_del(E_Client *ec)
+{
+   E_Effect_Client *efc = NULL;
+   Eina_List *children;
+   Evas_Object *child;
+
+   efc = _eff_client_get(ec);
+   if (!efc) return;
+   if (!efc->under) return;
+   if (efc->under_ref <= 0)
+     {
+        efc->under_ref = 0;
+        return;
+     }
+
+   efc->under_ref --;
+   if (efc->under_ref > 0) return;
+
+   evas_object_event_callback_del_full(efc->under,
+                                       EVAS_CALLBACK_DEL,
+                                       _eff_object_under_cb_del,
+                                       efc);
+
+   children = e_layout_children_get(efc->under);
+   EINA_LIST_FREE(children, child)
+     {
+        e_layout_unpack(child);
+        evas_object_del(child);
+     }
+
+   evas_object_del(efc->under);
+   efc->under = NULL;
+}
+
+static void
 _eff_object_layer_up(E_Client *ec)
 {
    int map_ly;
@@ -452,6 +622,100 @@ _eff_restack_effect_check(E_Client *ec)
    return emission;
 }
 
+static Eina_Bool
+_eff_ref(E_Client *ec)
+{
+   E_Effect_Client *efc;
+
+   if (!_eff) return EINA_FALSE;
+
+   efc = _eff_client_get(ec);
+   if (!efc) return EINA_FALSE;
+
+   if (e_object_is_del(E_OBJECT(ec)))
+     {
+        if (!e_object_delay_del_ref_get(E_OBJECT(ec)))
+          {
+             ERR("Client is deleted already! ec(%p)", ec);
+             eina_hash_del_by_key(_eff->clients, &ec);
+             return EINA_FALSE;
+          }
+     }
+
+   if (!ec->pixmap) return EINA_FALSE;
+   if ((e_comp_object_content_type_get(ec->frame) == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE) &&
+       (!e_pixmap_usable_get(ec->pixmap)))
+     return EINA_FALSE;
+
+   if (e_object_is_del(E_OBJECT(ec)))
+     {
+        e_object_delay_del_ref(E_OBJECT(ec));
+        efc->delay_del_ref ++;
+     }
+
+   efc->animating++;
+   e_object_ref(E_OBJECT(ec));
+   efc->ep = e_pixmap_ref(ec->pixmap);
+
+   EFFINF("effect ref efc(%p) animating:%d",
+          efc->ep, efc->ec, efc, efc->animating);
+
+   return EINA_TRUE;
+}
+
+static E_Client *
+_eff_unref(E_Client *ec)
+{
+   E_Effect_Client *efc;
+   int do_unref = 1;
+
+   if (!_eff) return NULL;
+   if (!ec) return NULL;
+
+   efc = _eff_client_get(ec);
+   if (!efc) return NULL;
+
+   while (efc->delay_del_ref)
+     {
+        e_object_delay_del_unref(E_OBJECT(ec));
+        efc->delay_del_ref--;
+     }
+
+   if (e_object_is_del(E_OBJECT(ec)))
+     do_unref = efc->animating;
+
+   efc->animating -= do_unref;
+   while (do_unref)
+     {
+        e_pixmap_free(efc->ep);
+        if (efc->under)
+          _eff_object_under_del(ec);
+        if (!e_object_unref(E_OBJECT(ec)))
+          {
+             EFFINF("eff unref ec(%p) ep(%p) efc(%p) Client free'd",
+                    NULL, NULL, ec, efc->ep, efc);
+
+             efc->ec = NULL;
+             efc = NULL;
+             eina_hash_del_by_key(_eff->clients, &ec);
+             return NULL;
+          }
+        do_unref --;
+     }
+
+   EFFINF("eff Unref efc(%p) animating:%d",
+          ec->pixmap, ec, efc, efc->animating);
+
+   /* The reference count of wl_buffer will get decremented
+    * immediately after window effect.
+    */
+   if ((efc) && (efc->buffer_ref.buffer))
+     e_comp_wl_buffer_reference(&efc->buffer_ref, NULL);
+
+   return ec;
+}
+
+
 static void
 _eff_cb_visible_done(void *data, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
 {
@@ -494,6 +758,8 @@ _eff_cb_visible(void *data, Evas_Object *obj, const char *signal)
    ec->extra_animating = EINA_TRUE;
 
    _eff_object_setup(ec, group);
+   _eff_object_under_setup(ec);
+
    ang = _eff_group_angle_get(ec, group);
    e_comp_object_effect_params_set(ec->frame, 0, (int[]){0, ang}, 2);
    if (e_comp->nocomp)
@@ -588,6 +854,8 @@ _eff_cb_hidden(void *data, Evas_Object *obj, const char *signal)
      _eff_object_layer_up(ec);
 
    _eff_object_setup(ec, group);
+   _eff_object_under_setup(ec);
+
    ang = _eff_group_angle_get(ec, group);
    e_comp_object_effect_params_set(ec->frame, 0, (int[]){1, ang}, 2);
 
@@ -696,6 +964,8 @@ _eff_cb_uniconify(void *data, Evas_Object *obj, const char *signal)
         e_comp_override_add();
 
         _eff_object_setup(ec, group);
+        _eff_object_under_setup(ec);
+
         ang = _eff_group_angle_get(ec, group);
         e_comp_object_effect_params_set(ec->frame, 0, (int[]){0, ang}, 2);
 
@@ -770,6 +1040,8 @@ _eff_cb_iconify(void *data, Evas_Object *obj, const char *signal)
    e_comp_override_add();
 
    _eff_object_setup(ec, group);
+   _eff_object_under_setup(ec);
+
    ang = _eff_group_angle_get(ec, group);
    e_comp_object_effect_params_set(ec->frame, 0, (int[]){1, ang}, 2);
 
@@ -931,6 +1203,8 @@ _eff_cb_restack(void *data, Evas_Object *obj, const char *signal)
         e_comp_override_add();
 
         _eff_object_setup(ec, group);
+        _eff_object_under_setup(ec);
+
         ang = _eff_group_angle_get(ec, group);
         e_comp_object_effect_params_set(ec->frame, 0, (int[]){2, ang}, 2);
 
@@ -981,6 +1255,8 @@ _eff_cb_restack(void *data, Evas_Object *obj, const char *signal)
         _eff_object_layer_up(ec);
 
         _eff_object_setup(ec, group);
+        _eff_object_under_setup(ec);
+
         ang = _eff_group_angle_get(ec, group);
         e_comp_object_effect_params_set(ec->frame, 0, (int[]){3, ang}, 2);
 
@@ -1003,6 +1279,8 @@ _eff_cb_restack(void *data, Evas_Object *obj, const char *signal)
         e_comp_override_add();
 
         _eff_object_setup(ec, group);
+        _eff_object_under_setup(ec);
+
         ang = _eff_group_angle_get(ec, group);
         e_comp_object_effect_params_set(ec->frame, 0, (int[]){4, ang}, 2);
 
@@ -1086,7 +1364,10 @@ _eff_cb_hook_client_del(void *d EINA_UNUSED, E_Client *ec)
    if ((efc = _eff_client_get(ec)))
      {
         if (!efc->animating)
-          eina_hash_del_by_key(_eff->clients, &ec);
+          {
+             _eff_object_under_del(ec);
+             eina_hash_del_by_key(_eff->clients, &ec);
+          }
      }
 }
 
@@ -1311,6 +1592,7 @@ e_mod_effect_shutdown()
    E_FREE_FUNC(_eff->stack.old, eina_list_free);
    E_FREE_FUNC(_eff->stack.cur, eina_list_free);
 
+   E_FREE_LIST(_eff->under_layers, free);
    E_FREE_LIST(_eff->providers, e_comp_object_effect_mover_del);
    E_FREE_LIST(_eff->event_hdlrs, ecore_event_handler_del);
    E_FREE_LIST(_eff->hooks_ec, e_client_hook_del);
index ab319a9..b7074ba 100644 (file)
@@ -74,6 +74,8 @@ struct _E_Effect
       E_Effect_Type type;
    } next_done;
 
+   Eina_List *under_layers;
+   Eina_Bool under_checked;
 };
 
 EAPI Eina_Bool e_mod_effect_init(void);