e_policy_desk_area: Seperate logic code from E_Desk_Area to E_Policy_Desk_Area 52/317352/1
authorJunseok Kim <juns.kim@samsung.com>
Tue, 15 Oct 2024 07:37:26 +0000 (16:37 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Tue, 31 Dec 2024 04:29:58 +0000 (13:29 +0900)
Change-Id: I6ebfa3b32c1d424426b402f8ff2f591556c1918c

src/bin/core/e_desk_area.c
src/bin/core/e_desk_area_intern.h
src/bin/e_comp_screen.c
src/bin/windowmgr/e_policy_desk.c
src/bin/windowmgr/e_policy_desk_area.c
src/bin/windowmgr/e_policy_desk_area_intern.h
src/include/e_desk_area.h

index 1a9054d70c1afbb4d67a5e31988c1c0ddd7c341f..87f2117c50ae49f917943daa8a7619cf3cc54145 100644 (file)
 #include "e_desk_area_intern.h"
 #include "e_client_intern.h"
-#include "e_comp_object_intern.h"
 #include "e_comp_canvas_intern.h"
-#include "e_comp_wl_rsm_intern.h"
-#include "e_policy_intern.h"
-#include "e_maximize_intern.h"
-#include "e_policy_visibility_intern.h"
-#include "e_input_backend_intern.h"
-#include "e_comp_input_intern.h"
-#include "e_comp_wl_subsurface_intern.h"
-#include "e_zone_intern.h"
 #include "e_desk_intern.h"
-#include "e_utils_intern.h"
-#include "e_comp_intern.h"
-#include "e_comp_wl_intern.h"
-#include "e_input_thread_client_intern.h"
-#include "e_view_intern.h"
-#include "e_view_client_intern.h"
 
 #include <libds-tizen/screen.h>
 
 typedef struct _E_Desk_Area_Private         E_Desk_Area_Private;
-typedef struct _E_Desk_Area_Private_Client  E_Desk_Area_Private_Client;
 
-#define E_DESK_AREA_TYPE 0xE0b01006
-#define E_DESK_AREA_SMART_OBJ_TYPE "E_Desk_Area_Smart_Object"
-
-#define DESK_AREA_EC_DATA_KEY  "E_Desk_Area_Client"
-
-#define PRI(eda) ((E_Desk_Area_Private *)e_object_data_get(E_OBJECT(eda)))
-
-#define API_ENTRY \
-   EINA_SAFETY_ON_NULL_RETURN(eda); \
-   E_Desk_Area_Private *priv = PRI(eda); \
-   EINA_SAFETY_ON_NULL_RETURN(priv);
-
-#define API_ENTRY_VAL(ret) \
-   EINA_SAFETY_ON_NULL_RETURN_VAL(eda, ret); \
-   E_Desk_Area_Private *priv = PRI(eda); \
-   EINA_SAFETY_ON_NULL_RETURN_VAL(priv, ret);
-
-typedef struct _E_Desk_Area_Smart_Data E_Desk_Area_Smart_Data;
-typedef void (*E_Desk_Area_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
-
-#define E_DESK_AREA_SMART_DATA_GET(obj, ptr)                        \
-   E_Desk_Area_Smart_Data *ptr = evas_object_smart_data_get(obj);
-
-#define E_DESK_AREA_SMART_DATA_GET_OR_RETURN(obj, ptr)              \
-   E_DESK_AREA_SMART_DATA_GET(obj, ptr);                            \
-   if (!ptr) return
-
-static int _e_desk_area_hooks_delete = 0;
-static int _e_desk_area_hooks_walking = 0;
-
-static Eina_Inlist *_e_desk_area_hooks[] =
-{
-   [E_DESK_AREA_HOOK_SET_APPID] = NULL,
-};
-
-struct _E_Desk_Area_Private
-{
-   E_Desk_Area *eda;
-};
-
-struct _E_Desk_Area_Private_Client
-{
-   E_Desk_Area *eda;
-   E_Client *ec;
-
-   // client listeners
-   struct wl_listener client_destroy;
-   struct wl_listener client_get_above;
-   struct wl_listener client_get_below;
-   struct wl_listener client_get_visible_above;
-   struct wl_listener client_get_visible_below;
-   struct wl_listener client_subsurface_stack_update;
-   struct wl_listener client_fullscreen;
-   struct wl_listener client_unfullscreen;
-   struct wl_listener client_focus_set;
-   struct wl_listener client_iconify;
-   struct wl_listener client_uniconify;
-   struct wl_listener client_stick;
-   struct wl_listener client_unstick;
-   struct wl_listener client_maximize;
-   struct wl_listener client_maximize_done;
-   struct wl_listener client_unmaximize;
-   struct wl_listener client_unmaximize_done;
-   struct wl_listener client_activate_done;
-   struct wl_listener client_stay_within_margin;
-   struct wl_listener client_mouse_move;
-   struct wl_listener client_resize_end;
-   struct wl_listener delete_request;
-   struct wl_listener kill_request;
-   struct wl_listener ping;
-   struct wl_listener redirect;
-
-   // comp_object listeners
-   struct wl_listener comp_object_raise;
-   struct wl_listener comp_object_lower;
-   struct wl_listener comp_object_set_layer;
-   struct wl_listener comp_object_stack_above;
-   struct wl_listener comp_object_stack_below;
-   struct wl_listener comp_object_resize;
-   struct wl_listener comp_object_color_set;
-};
-
-struct _E_Desk_Area_Smart_Data
-{
-   Evas_Object_Smart_Clipped_Data base;
-
-   E_Desk_Area *eda;
-
-   Eina_List      *clients;
-   Eina_List      *handlers;
-};
-
-struct _E_Desk_Area_Hook
-{
-   EINA_INLIST;
-   E_Desk_Area_Hook_Point hookpoint;
-   E_Desk_Area_Hook_Cb    func;
-   void                   *data;
-   unsigned char           delete_me : 1;
-};
-
-static void        _e_desk_area_hooks_clean(void);
-static Eina_Bool   _e_desk_area_hook_call(E_Desk_Area_Hook_Point hookpoint, E_Desk_Area *desk_area, void *appid);
-
-EVAS_SMART_SUBCLASS_NEW(E_DESK_AREA_SMART_OBJ_TYPE, _e_desk_area,
-                        Evas_Smart_Class, Evas_Smart_Class,
-                        evas_object_smart_clipped_class_get, NULL)
-
-static void
-_e_desk_area_client_data_del(E_Desk_Area *eda, E_Client *ec)
-{
-   e_view_data_del(e_view_client_view_get(e_client_view_get(ec)), DESK_AREA_EC_DATA_KEY);
-}
-
-static void
-_e_desk_area_client_data_set(E_Desk_Area *eda, E_Client *ec)
-{
-   E_Desk_Area *data;
-
-   data = e_view_data_get(e_view_client_view_get(e_client_view_get(ec)), DESK_AREA_EC_DATA_KEY);
-   if (data)
-     {
-        if (data == eda)
-          {
-             ELOGF("EDA", "EC is already added to desk_area_id:%d", ec, eda->id);
-             return;
-          }
-
-        _e_desk_area_client_data_del(eda, ec);
-     }
-
-   e_view_data_set(e_view_client_view_get(e_client_view_get(ec)), DESK_AREA_EC_DATA_KEY, eda);
-}
-
-static void
-_e_desk_area_configure_send(E_Client *ec, Eina_Bool edges, Eina_Bool send_size)
-{
-   int w, h;
-   E_Comp_Wl_Data *comp_wl;
-
-   if (send_size)
-     {
-        if (e_view_client_frame_exists(e_client_view_get(ec)))
-          w = ec->client.w, h = ec->client.h;
-        else
-          w = ec->w, h = ec->h;
-     }
-   else
-     {
-        // Width and Height are -1 means that we don't consider size value
-        w = h = -1;
-     }
-
-   comp_wl = e_comp_wl_get();
-   e_client_shell_configure_send(ec, edges * comp_wl->resize.edges, w, h);
-}
-
-static void
-_e_comp_input_thread_layers_update(void *data)
-{
-   E_Comp_Input_Layer_Data *layer_data = data;
-   EINA_SAFETY_ON_NULL_RETURN(layer_data);
-
-   ICINF("[input thread|%s] layer(%u), function type(%d), item(%p), relative(%p)\n",
-         __func__, layer_data->layer, layer_data->type, layer_data->item, layer_data->relative);
-
-   e_comp_input_layers_update(layer_data);
-}
-
-static void
-_e_comp_object_layers_update(unsigned int layer, E_Comp_Input_Inlist_Function_Type type, E_Client *item, E_Client *relative)
-{
-   if (!e_input_thread_check_client_cloning_needed()) return;
-
-   E_Comp_Input_Layer_Data layer_data;
-
-   memset(&layer_data, 0, sizeof(E_Comp_Input_Layer_Data));
-
-   layer_data.layer = layer;
-   layer_data.type = type;
-   layer_data.item = item;
-   layer_data.relative = relative;
-
-   ICINF("[%s] layer(%u), function type(%d), item(%p), relative(%p)\n", __func__, layer, type, item, relative);
-
-   e_input_backend_thread_safe_call(_e_comp_input_thread_layers_update, &layer_data, sizeof(E_Comp_Input_Layer_Data));
-}
-
-static void
-_e_comp_object_layers_add(E_Desk_Area *eda, E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
-{
-   e_comp_ec_list_lock();
-
-   if (above)
-     {
-        eda->layers[above->layer].clients = eina_inlist_append_relative(eda->layers[above->layer].clients, EINA_INLIST_GET(cw->ec), EINA_INLIST_GET(above->ec));
-        eda->layers[above->layer].clients_count++;
-        _e_comp_object_layers_update(above->layer, E_COMP_INPUT_INLIST_APPEND_RELATIVE, cw->ec, above->ec);
-     }
-   else if (below)
-     {
-        eda->layers[below->layer].clients = eina_inlist_prepend_relative(eda->layers[below->layer].clients, EINA_INLIST_GET(cw->ec), EINA_INLIST_GET(below->ec));
-        eda->layers[below->layer].clients_count++;
-        _e_comp_object_layers_update(below->layer, E_COMP_INPUT_INLIST_PREPEND_RELATIVE, cw->ec, below->ec);
-     }
-   else
-     {
-        if (prepend)
-          {
-             eda->layers[cw->layer].clients = eina_inlist_prepend(eda->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
-             _e_comp_object_layers_update(cw->layer, E_COMP_INPUT_INLIST_PREPEND, cw->ec, NULL);
-          }
-        else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
-          {
-             eda->layers[cw->layer].clients = eina_inlist_append(eda->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
-             _e_comp_object_layers_update(cw->layer, E_COMP_INPUT_INLIST_APPEND, cw->ec, NULL);
-          }
-        eda->layers[cw->layer].clients_count++;
-     }
-
-   e_comp_ec_list_unlock();
-}
-
-static void
-_e_comp_object_layers_remove(E_Desk_Area *eda, E_Comp_Object *cw)
-{
-   e_comp_ec_list_lock();
-
-   if (cw->ec && eda->layers[cw->layer].clients)
-     {
-        eda->layers[cw->layer].clients = eina_inlist_remove(eda->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
-        eda->layers[cw->layer].clients_count--;
-        _e_comp_object_layers_update(cw->layer, E_COMP_INPUT_INLIST_REMOVE, cw->ec, NULL);
-     }
-
-   e_comp_ec_list_unlock();
-}
-
-static Eina_Bool
-_e_comp_object_is_pending(E_Client *ec)
-{
-   E_Client *topmost;
-
-   if (!ec) return EINA_FALSE;
-
-   topmost = e_comp_wl_topmost_parent_get(ec);
-
-   return (topmost) ? topmost->layer_pending : EINA_FALSE;
-}
-
-static void
-_e_comp_object_layer_update(E_Desk_Area *eda, Evas_Object *obj,
-                           Evas_Object *above, Evas_Object *below)
-{
-   E_Comp_Object *cw, *cw2 = NULL;
-   Evas_Object *o = NULL;
-   short layer;
-
-   cw = evas_object_smart_data_get(obj);
-   if (!cw) return;
-
-   if (cw->ec->layer_block) return;
-   if ((above) && (below))
-     {
-        ERR("Invalid layer update request! cw=%p", cw);
-        return;
-     }
-
-   o = above?:below;
-
-   if (o)
-     {
-        layer = evas_object_layer_get(o);
-        cw2 = evas_object_data_get(o, "comp_obj");
-        while (!cw2)
-          {
-             if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
-
-             o = evas_object_above_get(o);
-             if ((!o) || (o == cw->smart_obj)) break;
-             if (evas_object_layer_get(o) != layer)
-               {
-                  o = eda->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
-               }
-             if (!o)
-               {
-                  E_Client *ec;
-                  ec = e_client_top_get();
-                  if (ec) o = ec->frame;
-               }
-
-             if (o) cw2 = evas_object_data_get(o, "comp_obj");
-          }
-     }
-
-   _e_comp_object_layers_remove(eda, cw);
-   if (cw2)
-     {
-        if (cw2->layer > cw->layer)
-          _e_comp_object_layers_add(eda, cw, NULL, NULL, 0);
-        else if (cw2->layer == cw->layer)
-          {
-             if (above)
-               _e_comp_object_layers_add(eda, cw, cw2, NULL, 0);
-             else if (o == obj)
-               _e_comp_object_layers_add(eda, cw, NULL, NULL, above? 0 : 1);
-             else if (below)
-               _e_comp_object_layers_add(eda, cw, NULL, cw2, 0);
-          }
-        else
-          _e_comp_object_layers_add(eda, cw, NULL, NULL, 1);
-     }
-   else
-     _e_comp_object_layers_add(eda, cw, NULL, NULL, 0);
-}
-
-static void
-_e_comp_intercept_stack_helper(E_Desk_Area *eda, E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
-{
-   E_Comp_Object *cw2 = NULL;
-   E_Client *ecstack;
-   short layer;
-   Evas_Object *o = stack;
-   Eina_Bool raising = stack_cb == e_comp_object_stack_above;
-
-   /* We should consider topmost's layer_pending for subsurface */
-   if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
-     {
-        if (_e_comp_object_is_pending(cw->ec))
-          _e_comp_object_layer_update(eda, cw->smart_obj,
-                                     raising? stack : NULL,
-                                     raising? NULL : stack);
-
-        /* obey compositor effects! */
-        if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
-          evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
-        stack_cb(cw->smart_obj, stack);
-        if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
-          evas_object_data_del(cw->smart_obj, "client_restack");
-        return;
-     }
-
-   cw2 = evas_object_data_get(o, "comp_obj");
-
-   /* assume someone knew what they were doing during client init */
-   if (cw->ec->new_client)
-     layer = cw->ec->layer;
-   else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
-     layer = cw2->ec->layer;
-   else
-     layer = evas_object_layer_get(stack);
-   ecstack = e_client_below_get(cw->ec);
-   if (layer != e_comp_canvas_layer_map_to(cw->layer))
-     {
-        evas_object_layer_set(cw->smart_obj, layer);
-        /* we got our layer wrangled, return now! */
-        if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
-     }
-
-   /* check if we're stacking below another client */
-   while (!cw2)
-     {
-        /* check for non-client layer object */
-        if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
-          break;
-        /* find an existing client to use for layering
-         * by walking up the object stack
-         *
-         * this is guaranteed to be pretty quick since we'll either:
-         * - run out of client layers
-         * - find a stacking client
-         */
-        o = evas_object_above_get(o);
-        if ((!o) || (o == cw->smart_obj)) break;
-        if (evas_object_layer_get(o) != layer)
-          {
-             /* reached the top client layer somehow
-              * use top client object
-              */
-             o = eda->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
-          }
-        if (!o)
-          /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
-           * return here since the top client layer window
-           */
-          {
-             E_Client *ec;
-
-             ec = e_client_top_get();
-             if (ec)
-               o = ec->frame;
-             //else //wat
-          }
-        if (o) cw2 = evas_object_data_get(o, "comp_obj");
-     }
-
-   if (cw2 && cw->layer != cw2->layer)
-     return;
-
-   /* remove existing layers */
-   _e_comp_object_layers_remove(eda, cw);
-   if (cw2)
-     {
-        if (o == stack) //if stacking above, cw2 is above; else cw2 is below
-          _e_comp_object_layers_add(eda, cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
-        else if (o == cw->smart_obj) //prepend (lower) if not stacking above
-          _e_comp_object_layers_add(eda, cw, NULL, NULL, !raising);
-        else //if no stacking objects found, either raise or lower
-          _e_comp_object_layers_add(eda, cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
-     }
-   else
-     _e_comp_object_layers_add(eda, cw, NULL, NULL, 0);
-
-   /* find new object for stacking if cw2 is on state of layer_pending */
-   if ((cw2) && _e_comp_object_is_pending(cw2->ec))
-     {
-        E_Client *new_stack = NULL, *current_ec = NULL;
-        current_ec = cw2->ec;
-        if (raising)
-          {
-             while ((new_stack = e_client_below_get(current_ec)))
-               {
-                  current_ec = new_stack;
-                  if (new_stack == cw->ec) continue;
-                  if (new_stack->layer != cw2->ec->layer) break;
-                  if (!_e_comp_object_is_pending(new_stack)) break;
-               }
-             if ((new_stack) && (new_stack->layer == cw2->ec->layer))
-               stack = new_stack->frame;
-             else
-               {
-                  /* stack it above layer object */
-                  int below_layer;
-                  below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
-                  stack = eda->layers[below_layer].obj;
-               }
-          }
-        else
-          {
-             while ((new_stack = e_client_above_get(current_ec)))
-               {
-                  current_ec = new_stack;
-                  if (new_stack == cw->ec) continue;
-                  if (new_stack->layer != cw2->ec->layer) break;
-                  if (!_e_comp_object_is_pending(new_stack)) break;
-               }
-             if ((new_stack) && (new_stack->layer == cw2->ec->layer))
-               stack = new_stack->frame;
-             else
-               stack = eda->layers[cw2->layer].obj;
-          }
-     }
-
-   /* set restack if stacking has changed */
-   if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
-     evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
-   stack_cb(cw->smart_obj, stack);
-   if (eda->layers[cw->layer].obj)
-     if (evas_object_below_get(cw->smart_obj) == eda->layers[cw->layer].obj)
-       {
-          CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
-       }
-   if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
-     evas_object_data_del(cw->smart_obj, "client_restack");
-   if (!cw->visible) return;
-   e_comp_render_queue();
-}
-
-static void
-_e_desk_geometry_info_set(E_Desk_Area *eda, int x, int y, int w, int h)
-{
-   E_Desk *desk;
-
-   if (!eda) return;
-   if (!eda->desk) return;
-
-   desk = eda->desk;
-
-   eda->x = x;
-   eda->y = y;
-   eda->w = w;
-   eda->h = h;
-
-   eda->scale_w = (double)w / (double)desk->geom.w;
-   eda->scale_h = (double)h / (double)desk->geom.h;
-}
-
-static void
-_e_desk_area_active_change(E_Desk_Area *eda, E_Desk *desk)
-{
-   E_Desk_Area *prev_active_edg;
-
-   if (!desk) return;
-
-   prev_active_edg = e_desk_desk_area_active_get(desk);
-   if (prev_active_edg == eda) return;
-
-   // 1. reset current active eda info
-   if (prev_active_edg)
-     prev_active_edg->active = EINA_FALSE;
-
-   // 2. set new active eda info
-   if (eda)
-     {
-        eda->active = EINA_TRUE;
-        e_desk_desk_area_active_set(desk, eda);
-     }
-   else
-     {
-        e_desk_desk_area_active_set(desk, NULL);
-     }
-}
-
-static void
-_e_desk_area_cb_hook_subsurface_create(void *data, E_Client *ec)
-{
-   EINA_SAFETY_ON_NULL_RETURN(ec);
-
-   if (ec->desk_area.transform)
-     {
-        e_client_transform_core_remove(ec, ec->desk_area.transform);
-     }
-}
-
-#ifdef CLIENT_DEL_STACK_ISSUE
-static void
-_desk_area_cb_client_free(void *data, E_Client *ec)
-{
-   E_Desk_Area *eda = data;
-   E_Comp_Object *cw;
-
-   ELOGF("EDA", "HOOK CLIENT FREE. desk_area:%p", ec, eda);
-
-   cw = evas_object_smart_data_get(ec->frame);
-   if (cw)
-     _e_comp_object_layers_remove(eda, cw);
-   else
-     ELOGF("EDA", "No Comp Object. Fix Me~!!", ec);
-}
-#endif //CLIENT_DEL_STACK_ISSUE
-
-EINTERN int
-e_desk_area_init(void)
-{
-   return 1;
-}
-
-EINTERN int
-e_desk_area_shutdown(void)
-{
-   return 1;
-}
-
-static Eina_Bool
-_e_desk_area_private_init(E_Desk_Area *eda)
-{
-   E_Desk_Area_Private *priv;
-
-   priv = E_NEW(E_Desk_Area_Private, 1);
-   if (!priv)
-     return EINA_FALSE;
-
-   priv->eda = eda;
-
-   e_object_data_set(E_OBJECT(eda), priv);
-
-   return EINA_TRUE;
-}
-
-static void
-_e_desk_area_private_finish(E_Desk_Area *eda)
-{
-   E_Desk_Area_Private *priv;
-
-   priv = PRI(eda);
-   if (!priv) return;
-
-   e_object_data_set(E_OBJECT(eda), NULL);
-
-   priv->eda = NULL;
-
-   free(priv);
-}
-
-static void
-_e_desk_area_free(E_Desk_Area *eda)
-{
-   E_FREE_FUNC(eda->hook_subsurf_create, e_comp_wl_hook_del);
-#ifdef CLIENT_DEL_STACK_ISSUE
-   E_FREE_FUNC(eda->hook_client_free, e_comp_wl_hook_del);
-#endif // CLIENT_DEL_STACK_ISSUE
-
-   _e_desk_area_private_finish(eda);
-   free(eda);
-}
-
-static void
-_e_desk_area_smart_add(Evas_Object *obj)
-{
-   EVAS_SMART_DATA_ALLOC(obj, E_Desk_Area_Smart_Data);
-
-   _e_desk_area_parent_sc->add(obj);
-}
-
-static void
-_e_desk_area_smart_del(Evas_Object *obj)
-{
-   _e_desk_area_parent_sc->del(obj);
-
-   E_DESK_AREA_SMART_DATA_GET_OR_RETURN(obj, sd);
-
-   E_FREE_LIST(sd->handlers, ecore_event_handler_del);
-   eina_list_free(sd->clients);
-   free(sd);
-
-   evas_object_smart_data_set(obj, NULL);
-}
-
-static void
-_e_desk_area_smart_member_add(Evas_Object *obj, Evas_Object *child)
-{
-   _e_desk_area_parent_sc->member_add(obj, child);
-}
-
-static void
-_e_desk_area_smart_member_del(Evas_Object *obj, Evas_Object *child)
-{
-   _e_desk_area_parent_sc->member_del(obj, child);
-}
-
-static void
-_e_desk_area_smart_set_user(Evas_Smart_Class *sc)
-{
-   sc->add = _e_desk_area_smart_add;
-   sc->del = _e_desk_area_smart_del;
-   sc->member_add = _e_desk_area_smart_member_add;
-   sc->member_del = _e_desk_area_smart_member_del;
-}
-
-static Eina_Bool
-_desk_area_smart_client_find(E_Desk_Area_Smart_Data *sd, E_Client *ec)
-{
-   Eina_List *l;
-   E_Client *temp_ec;
-
-   EINA_LIST_FOREACH(sd->clients, l, temp_ec)
-     {
-        if (temp_ec == ec) return EINA_TRUE;
-     }
-
-   return EINA_FALSE;
-}
-
-static void
-_e_desk_area_smart_client_add(Evas_Object *obj, E_Client *ec)
-{
-   E_DESK_AREA_SMART_DATA_GET_OR_RETURN(obj, sd);
-
-   if (_desk_area_smart_client_find(sd, ec))
-     return;
-
-   sd->clients = eina_list_append(sd->clients, ec);
-
-   evas_object_smart_changed(obj);
-}
-
-static void
-_e_desk_area_smart_client_del(Evas_Object *obj, E_Client *ec)
-{
-   E_DESK_AREA_SMART_DATA_GET_OR_RETURN(obj, sd);
-
-   if (!_desk_area_smart_client_find(sd, ec))
-     return;
-
-   sd->clients = eina_list_remove(sd->clients, ec);
-
-   evas_object_smart_member_del(ec->frame);
-
-   evas_object_smart_changed(obj);
-}
-
-static void
-_e_desk_area_smart_init(E_Desk_Area *eda)
-{
-   eda->smart_obj = evas_object_smart_add(e_comp_evas_get(), _e_desk_area_smart_class_new());
-
-   E_DESK_AREA_SMART_DATA_GET_OR_RETURN(eda->smart_obj, sd);
-
-   sd->eda = eda;
-}
-
-static void
-_e_desk_area_private_client_del(E_Desk_Area_Private_Client *eda_client)
-{
-   E_Desk_Area *eda = eda_client->eda;
-   E_Client *ec = eda_client->ec;
-#ifdef CLIENT_DEL_STACK_ISSUE
-#else
-   E_Comp_Object *cw;
-#endif // CLIENT_DEL_STACK_ISSUE
-
-   if (!e_desk_area_has_ec(eda, ec)) return;
-
-   // TODO: this code has to be refactoring
-   e_util_transform_del(ec->desk_area.transform);
-   ec->desk_area.transform = NULL;
-
-#ifdef CLIENT_DEL_STACK_ISSUE
-#else
-   cw = evas_object_smart_data_get(ec->frame);
-   if (cw)
-     _e_comp_object_layers_remove(eda, cw);
-   else
-     ELOGF("EDA", "No Comp Object. Fix Me~!!", ec);
-#endif // CLIENT_DEL_STACK_ISSUE
-
-   _e_desk_area_smart_client_del(eda->smart_obj, ec);
-   _e_desk_area_client_data_del(eda, ec);
-
-   // wl_list remove
-   if (eda_client->comp_object_color_set.notify)
-     wl_list_remove(&eda_client->comp_object_color_set.link);
-   if (eda_client->comp_object_resize.notify)
-     wl_list_remove(&eda_client->comp_object_resize.link);
-   if (eda_client->redirect.notify)
-     wl_list_remove(&eda_client->redirect.link);
-   if (eda_client->ping.notify)
-     wl_list_remove(&eda_client->ping.link);
-   if (eda_client->kill_request.notify)
-     wl_list_remove(&eda_client->kill_request.link);
-   if (eda_client->delete_request.notify)
-     wl_list_remove(&eda_client->delete_request.link);
-
-   wl_list_remove(&eda_client->comp_object_stack_below.link);
-   wl_list_remove(&eda_client->comp_object_stack_above.link);
-   wl_list_remove(&eda_client->comp_object_set_layer.link);
-   wl_list_remove(&eda_client->comp_object_lower.link);
-   wl_list_remove(&eda_client->comp_object_raise.link);
-
-   wl_list_remove(&eda_client->client_resize_end.link);
-   wl_list_remove(&eda_client->client_mouse_move.link);
-   wl_list_remove(&eda_client->client_stay_within_margin.link);
-   wl_list_remove(&eda_client->client_activate_done.link);
-   wl_list_remove(&eda_client->client_unmaximize_done.link);
-   wl_list_remove(&eda_client->client_unmaximize.link);
-   wl_list_remove(&eda_client->client_maximize_done.link);
-   wl_list_remove(&eda_client->client_maximize.link);
-   wl_list_remove(&eda_client->client_unstick.link);
-   wl_list_remove(&eda_client->client_stick.link);
-   wl_list_remove(&eda_client->client_uniconify.link);
-   wl_list_remove(&eda_client->client_iconify.link);
-   wl_list_remove(&eda_client->client_focus_set.link);
-   wl_list_remove(&eda_client->client_unfullscreen.link);
-   wl_list_remove(&eda_client->client_fullscreen.link);
-   wl_list_remove(&eda_client->client_subsurface_stack_update.link);
-   wl_list_remove(&eda_client->client_get_visible_below.link);
-   wl_list_remove(&eda_client->client_get_visible_above.link);
-   wl_list_remove(&eda_client->client_get_below.link);
-   wl_list_remove(&eda_client->client_get_above.link);
-   wl_list_remove(&eda_client->client_destroy.link);
-
-   E_FREE(eda_client);
-}
-
-static void
-_desk_area_cb_client_destroy(struct wl_listener *listener, void *data)
-{
-   E_Desk_Area_Private_Client *eda_client;
-   E_Desk_Area *eda;
-   E_Client *ec;
-
-   eda_client = wl_container_of(listener, eda_client, client_destroy);
-   eda = eda_client->eda;
-   ec = eda_client->ec;
-
-   ELOGF("EDA", "CLIENT DESTROY. desk_area:%p", ec, eda);
-
-   if (ec->fullscreen)
-     {
-        eda->fullscreen_clients = eina_list_remove(eda->fullscreen_clients, ec);
-        if (!eda->fullscreen_clients)
-          e_comp_render_queue();
-     }
-
-   _e_desk_area_private_client_del(eda_client);
-}
-
-static void
-_desk_area_cb_client_get_above(struct wl_listener *listener, void *data)
-{
-   E_Desk_Area_Private_Client *eda_client;
-   E_Client_Data_Get_Above *get_above_data = data;
-   E_Desk_Area *eda;
-   E_Client *ec, *ec2;
-   unsigned int x;
-
-   eda_client = wl_container_of(listener, eda_client, client_get_above);
-   eda = eda_client->eda;
-   ec = eda_client->ec;
-
-   e_comp_ec_list_lock();
-   if (EINA_INLIST_GET(ec)->next) //check current layer
-     {
-        EINA_INLIST_FOREACH(EINA_INLIST_GET(ec)->next, ec2)
-          {
-             if (ec == ec2)
-               {
-                  ELOGF("FATAL", "CHECK the ec inlist next", ec);
-                  continue;
-               }
-             if (!e_object_is_del(E_OBJECT(ec2)))
-               {
-                  get_above_data->above_ec = ec2;
-                  e_comp_ec_list_unlock();
-                  return;
-               }
-          }
-     }
-   e_comp_ec_list_unlock();
-
-   if (ec->layer == E_LAYER_CLIENT_CURSOR) return;
-   if (e_util_client_layer_map(ec->layer) == 9999) return;
-
-   e_comp_ec_list_lock();;
-
-   /* go up the layers until we find one */
-   for (x = e_comp_canvas_layer_map(ec->layer) + 1; x <= e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); x++)
-     {
-        if (!eda->layers[x].clients) continue;
-
-        EINA_INLIST_FOREACH(eda->layers[x].clients, ec2)
-          {
-             if (ec == ec2)
-               {
-                  ELOGF("FATAL", "[eda:%p] EC exist above layer. ec layer_map:%d, cur layer_map:%d",
-                        ec, eda, e_comp_canvas_layer_map(ec->layer), x);
-                  continue;
-               }
-             if (!e_object_is_del(E_OBJECT(ec2)))
-               {
-                  get_above_data->above_ec = ec2;
-                  e_comp_ec_list_unlock();
-                  return;
-               }
-          }
-     }
-
-   e_comp_ec_list_unlock();
-}
-
-static void
-_desk_area_cb_client_get_below(struct wl_listener *listener, void *data)
-{
-   E_Desk_Area_Private_Client *eda_client;
-   E_Client_Data_Get_Below *get_below_data = data;
-   E_Desk_Area *eda;
-   E_Client *ec, *ec2;
-   unsigned int x;
-   Eina_Inlist *l;
-   E_Layer ec_layer, ec_layer_cw;
-   int cw_layer;
-
-   eda_client = wl_container_of(listener, eda_client, client_get_below);
-   eda = eda_client->eda;
-   ec = eda_client->ec;
-
-   e_comp_ec_list_lock();
-   if (EINA_INLIST_GET(ec)->prev) //check current layer
-     {
-        for (l = EINA_INLIST_GET(ec)->prev; l; l = l->prev)
-          {
-             ec2 = EINA_INLIST_CONTAINER_GET(l, E_Client);
-             if (ec == ec2)
-               {
-                  ELOGF("FATAL", "CHECK the ec inlist prev", ec);
-                  continue;
-               }
-             if (!e_object_is_del(E_OBJECT(ec2)))
-               {
-                  get_below_data->below_ec = ec2;
-                  e_comp_ec_list_unlock();
-                  return;
-               }
-          }
-     }
-   e_comp_ec_list_unlock();
-
-   // check layer validation
-   ec_layer = ec->layer;
-   if (ec->layer_block || ec->layer_pending)
-     {
-        cw_layer = e_comp_object_layer_get(ec->frame);
-        if (cw_layer >= 0)
-          {
-             ec_layer_cw = e_comp_canvas_layer_map_to(cw_layer);
-             if (ec_layer != ec_layer_cw)
-               {
-                  ELOGF("EDA", "[eda:%p] LAYER is not same. USE obj layer! (ec->layer:%d, obj:%d). block:%d, pending:%d)",
-                        ec, eda, ec_layer, ec_layer_cw, ec->layer_block, ec->layer_pending);
-                  ec_layer = ec_layer_cw;
-               }
-          }
-     }
-
-   if (ec_layer == E_LAYER_CLIENT_DESKTOP) return;
-   if (e_util_client_layer_map(ec_layer) == 9999) return;
-
-   /* go down the layers until we find one */
-   x = e_comp_canvas_layer_map(ec_layer);
-   if (x > 0) x--;
-
-   e_comp_ec_list_lock();;
-
-   for (; x >= e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x--)
-     {
-        if (!eda->layers[x].clients) continue;
-
-        EINA_INLIST_REVERSE_FOREACH(eda->layers[x].clients, ec2)
-          {
-             if (ec == ec2)
-               {
-                  ELOGF("FATAL", "[eda:%p] EC exist below layer. ec layer_map:%d, cur layer_map:%d",
-                        ec, eda, e_comp_canvas_layer_map(ec_layer), x);
-                  continue;
-               }
-             if (!e_object_is_del(E_OBJECT(ec2)))
-               {
-                  get_below_data->below_ec = ec2;
-                  e_comp_ec_list_unlock();
-                  return;
-               }
-          }
-     }
-
-   e_comp_ec_list_unlock();
-}
-
-static void
-_desk_area_cb_client_get_visible_above(struct wl_listener *listener, void *data)
-{
-   E_Desk_Area_Private_Client *eda_client;
-   E_Client_Data_Get_Visible_Above *get_visible_above_data = data;
-   E_Desk_Area *eda;
-   E_Client *ec, *ec2;
-   unsigned int x;
-
-   eda_client = wl_container_of(listener, eda_client, client_get_visible_above);
-   eda = eda_client->eda;
-   ec = eda_client->ec;
-
-   e_comp_ec_list_lock();
-   if (EINA_INLIST_GET(ec)->next) //check current layer
-     {
-        EINA_INLIST_FOREACH(EINA_INLIST_GET(ec)->next, ec2)
-          {
-             if (ec == ec2) continue;
-             if ((!e_object_is_del(E_OBJECT(ec2))) &&
-                 (!e_client_util_ignored_get(ec2)) &&
-                 (ec2->visible) &&
-                 (ec2->frame))
-               {
-                  get_visible_above_data->above_ec = ec2;
-                  e_comp_ec_list_unlock();
-                  return;
-               }
-          }
-     }
-   e_comp_ec_list_unlock();
-
-   if (ec->layer == E_LAYER_CLIENT_CURSOR) return;
-   if (e_util_client_layer_map(ec->layer) == 9999) return;
-
-   e_comp_ec_list_lock();;
-
-   /* go up the layers until we find one */
-   for (x = e_comp_canvas_layer_map(ec->layer) + 1; x <= e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); x++)
-     {
-        if (!eda->layers[x].clients) continue;
-        EINA_INLIST_FOREACH(eda->layers[x].clients, ec2)
-          {
-             if (ec == ec2) continue;
-             if ((!e_object_is_del(E_OBJECT(ec2))) &&
-                 (!e_client_util_ignored_get(ec2)) &&
-                 (ec2->visible) &&
-                 (ec2->frame))
-               {
-                  get_visible_above_data->above_ec = ec2;
-                  e_comp_ec_list_unlock();
-                  return;
-               }
-          }
-     }
-
-   e_comp_ec_list_unlock();
-}
-
-static void
-_desk_area_cb_client_get_visible_below(struct wl_listener *listener, void *data)
-{
-   E_Desk_Area_Private_Client *eda_client;
-   E_Client_Data_Get_Visible_Below *get_visible_below_data = data;
-   E_Desk_Area *eda;
-   E_Client *ec, *ec2;
-   unsigned int x;
-   Eina_Inlist *l;
-   E_Layer ec_layer, ec_layer_cw;
-   int cw_layer;
-
-   e_comp_ec_list_lock();
-   eda_client = wl_container_of(listener, eda_client, client_get_visible_below);
-   eda = eda_client->eda;
-   ec = eda_client->ec;
-
-   if (EINA_INLIST_GET(ec)->prev) //check current layer
-     {
-        for (l = EINA_INLIST_GET(ec)->prev; l; l = l->prev)
-          {
-             ec2 = EINA_INLIST_CONTAINER_GET(l, E_Client);
-             if (ec == ec2) continue;
-             if ((!e_object_is_del(E_OBJECT(ec2))) &&
-                 (!e_client_util_ignored_get(ec2)) &&
-                 (ec2->visible) &&
-                 (ec2->frame))
-               {
-                  get_visible_below_data->below_ec = ec2;
-                  e_comp_ec_list_unlock();
-                  return;
-               }
-          }
-     }
-   e_comp_ec_list_unlock();
-
-   // check layer validation
-   ec_layer = ec->layer;
-   if (ec->layer_block || ec->layer_pending)
-     {
-        cw_layer = e_comp_object_layer_get(ec->frame);
-        if (cw_layer >= 0)
-          {
-             ec_layer_cw = e_comp_canvas_layer_map_to(cw_layer);
-             if (ec_layer != ec_layer_cw)
-               {
-                  ELOGF("EDA", "[eda:%p] LAYER is not same. USE obj layer! (ec->layer:%d, obj:%d). block:%d, pending:%d)",
-                        ec, eda, ec_layer, ec_layer_cw, ec->layer_block, ec->layer_pending);
-                  ec_layer = ec_layer_cw;
-               }
-          }
-     }
-
-   /* go down the layers until we find one */
-   if (e_comp_canvas_layer_map(ec->layer) > e_comp_canvas_layer_map(E_LAYER_MAX)) return;
-   x = e_comp_canvas_layer_map(ec->layer);
-   if (x > 0) x--;
-
-   e_comp_ec_list_lock();
-   for (; x >= e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x--)
-     {
-        if (!eda->layers[x].clients) continue;
-        EINA_INLIST_REVERSE_FOREACH(eda->layers[x].clients, ec2)
-          {
-             if (ec == ec2) continue;
-             if ((!e_object_is_del(E_OBJECT(ec2))) &&
-                 (!e_client_util_ignored_get(ec2)) &&
-                 (ec2->visible) &&
-                 (ec2->frame))
-               {
-                  get_visible_below_data->below_ec = ec2;
-                  e_comp_ec_list_unlock();
-                  return;
-               }
-          }
-     }
-   e_comp_ec_list_unlock();
-}
-
-static void
-_desk_area_cb_client_subsurface_stack_update(struct wl_listener *listener, void *data)
-{
-   E_Desk_Area_Private_Client *eda_client;
-   E_Desk_Area *eda;
-   E_Client *ec;
-
-   eda_client = wl_container_of(listener, eda_client, client_subsurface_stack_update);
-   eda = eda_client->eda;
-   ec = eda_client->ec;
-
-   //To update client stack list
-   if ((ec->comp_data->sub.data) &&
-       (ec->comp_data->sub.data->parent))
-     {
-        E_Client *parent;
-        Evas_Object *o;
-
-        parent = ec->comp_data->sub.data->parent;
-
-        if ((parent->comp_data->sub.list) &&
-            (eina_list_data_find(parent->comp_data->sub.list, ec)))
-          {
-             //stack above done
-             o = evas_object_below_get(ec->frame);
-             _e_comp_object_layer_update(eda, ec->frame, o, NULL);
-          }
-        else if ((parent->comp_data->sub.below_list) &&
-                 (eina_list_data_find(parent->comp_data->sub.below_list, ec)))
-          {
-             //stack below done
-             o = evas_object_above_get(ec->frame);
-             _e_comp_object_layer_update(eda, ec->frame, NULL, o);
-          }
-     }
-}
-
-static void
-_desk_area_cb_client_fullscreen(struct wl_listener *listener, void *data)
-{
-   E_Desk_Area_Private_Client *eda_client;
-   E_Desk_Area *eda;
-   E_Client *ec;
-   E_Fullscreen fullscreen_policy;
-
-   eda_client = wl_container_of(listener, eda_client, client_fullscreen);
-   eda = eda_client->eda;
-   ec = eda_client->ec;
-
-   fullscreen_policy = *((E_Fullscreen *)data);
-
-   // "override = 1" means that ec is not controlled by wm policy
-   if (ec->override) return;
-
-   eda->fullscreen_clients = eina_list_append(eda->fullscreen_clients, ec);
-   ec->pre_res_change.valid = 0;
-
-   if (!ec->maximized)
-     {
-        ec->saved.x = ec->client.x - eda->x;
-        ec->saved.y = ec->client.y - eda->y;
-        ec->saved.w = ec->client.w;
-        ec->saved.h = ec->client.h;
-     }
-   ec->saved.maximized = ec->maximized;
-
-   if (fullscreen_policy == E_FULLSCREEN_RESIZE)
-     e_client_frame_geometry_set(ec, eda->x, eda->y, eda->w, eda->h);
-
-   if (!e_client_util_ignored_get(ec))
-     e_client_frame_update(ec);
-
-   e_view_client_fullscreen(e_client_view_get(ec));
-
-   if (ec->comp_data->shell.configure_send)
-     _e_desk_area_configure_send(ec, 0, 1);
-
-   e_client_maximize_pre_set(ec, EINA_FALSE);
-}
-
-static void
-_desk_area_cb_client_unfullscreen(struct wl_listener *listener, void *data)
-{
-   E_Desk_Area_Private_Client *eda_client;
-   E_Desk_Area *eda;
-   E_Client *ec;
-
-   eda_client = wl_container_of(listener, eda_client, client_unfullscreen);
-   eda = eda_client->eda;
-   ec = eda_client->ec;
-
-   // "override = 1" means that ec is not controlled by wm policy
-   if (ec->override) return;
-
-   ec->pre_res_change.valid = 0;
-   eda->fullscreen_clients = eina_list_remove(eda->fullscreen_clients, ec);
-
-   if (!e_client_util_ignored_get(ec))
-     e_client_frame_update(ec);
-
-   e_view_client_unfullscreen(e_client_view_get(ec));
-
-   if (ec->comp_data->shell.configure_send)
-     _e_desk_area_configure_send(ec, 0, 0);
-
-   e_client_maximize_pre_set(ec, EINA_FALSE);
-
-   if (ec->maximized)
-     {
-        int saved_x = ec->saved.x;
-        int saved_y = ec->saved.y;
-        int saved_w = ec->saved.w;
-        int saved_h = ec->saved.h;
-        e_client_maximize_update(ec);
-        ec->saved.x = saved_x;
-        ec->saved.y = saved_y;
-        ec->saved.w = saved_w;
-        ec->saved.h = saved_h;
-     }
-   else
-     {
-        e_client_util_move_resize_without_frame(ec, eda->x + ec->saved.x,
-                                                eda->y + ec->saved.y,
-                                                ec->saved.w, ec->saved.h);
-     }
-
-   if (!eda->fullscreen_clients)
-     e_comp_render_queue();
-}
-
-static void
-_desk_area_cb_client_focus_set(struct wl_listener *listener, void *data)
-{
-   E_Desk_Area_Private_Client *eda_client;
-   E_Desk_Area *eda;
-   E_Client *ec, *ec2;
-   Eina_List *l, *ll;
-
-   eda_client = wl_container_of(listener, eda_client, client_focus_set);
-   eda = eda_client->eda;
-   ec = eda_client->ec;
-
-   /* if there's any fullscreen non-parents on this desk, unfullscreen them */
-   EINA_LIST_FOREACH_SAFE(eda->fullscreen_clients, l, ll, ec2)
-     {
-        if (ec2 == ec) continue;
-        if (e_object_is_del(E_OBJECT(ec2))) continue;
-
-        /* but only if it's the same desk or one of the clients is sticky */
-        if (ec->sticky || ec2->sticky)
-          {
-             if (!eina_list_data_find(ec->transients, ec2))
-               e_client_unfullscreen(ec2);
-          }
-     }
-}
-
-static void
-_desk_area_cb_client_iconify(struct wl_listener *listener, void *data)
-{
-   E_Desk_Area_Private_Client *eda_client;
-   E_Desk_Area *eda;
-   E_Client *ec;
-
-   eda_client = wl_container_of(listener, eda_client, client_iconify);
-   eda = eda_client->eda;
-   ec = eda_client->ec;
-
-   e_comp_wl_remote_surface_image_save(ec);
-
-   ec->iconic = 1;
-   ec->want_focus = ec->take_focus = 0;
-   ec->changes.visible = 0;
-   if (ec->fullscreen)
-     eda->fullscreen_clients = eina_list_remove(eda->fullscreen_clients, ec);
-   e_client_comp_hidden_set(ec, 1);
-   e_view_client_hide(e_client_view_get(ec));
-
-   e_client_iconify_event_send(ec);
-
-   if (e_config->transient.iconify)
-     {
-        E_Client *child;
-        Eina_List *list = eina_list_clone(ec->transients);
-
-        EINA_LIST_FREE(list, child)
-          {
-             if ((!child->exp_iconify.skip_iconify) &&
-                 (child->exp_iconify.type != E_ICONIFIED_TYPE_ICONIFY_BY_CLIENT) &&
-                 (e_client_is_parent_iconify_by_client(child)))
-               {
-                  ELOGF("EDA", "ICONIFY|iconify by parent iconify. parent:%p", child, ec);
-                  e_client_iconified_type_set(child, E_ICONIFIED_TYPE_PARENT_ICONIFY_BY_CLIENT);
-                  child->exp_iconify.by_client = 1;
-                  e_policy_client_iconic_state_change_send(child, 1);
-               }
-             else
-               ELOGF("EDA", "ICONIFY|SKIP iconify by parent iconify. parent:%p, skip_iconify:%d, iconify.type:%d",
-                     child, ec, child->exp_iconify.skip_iconify, e_client_iconified_type_get(child));
-             e_client_iconify(child);
-          }
-     }
-}
-
-static void
-_desk_area_cb_client_uniconify(struct wl_listener *listener, void *data)
-{
-   E_Desk_Area_Private_Client *eda_client;
-   E_Desk_Area *eda;
-   E_Client *ec;
-   Eina_Bool not_raise;
-
-   eda_client = wl_container_of(listener, eda_client, client_uniconify);
-   eda = eda_client->eda;
-   ec = eda_client->ec;
-
-   e_comp_wl_remote_surface_image_save_cancel(ec);
-
-   not_raise = ec->exp_iconify.not_raise;
-
-   ec->exp_iconify.by_client = 0;
-   e_client_iconified_type_set(ec, E_ICONIFIED_TYPE_NONE);
-
-   if (e_config->transient.iconify)
-     {
-        E_Client *child;
-        Eina_List *list = eina_list_clone(ec->transients);
-
-        EINA_LIST_FREE(list, child)
-          {
-             if (e_client_transient_policy_get(child) == E_TRANSIENT_BELOW)
-               {
-                  child->exp_iconify.not_raise = not_raise;
-                  e_client_uniconify(child);
-               }
-          }
-     }
-
-   if (!not_raise)
-     e_client_raise(ec);
-
-   if (ec->internal)
-     {
-        ELOGF("EDA", "UNICONIFY|internal object force show. eda:%p", ec, eda);
-        e_view_client_show(e_client_view_get(ec));
-     }
-
-   if (ec->pixmap)
-     {
-         E_Comp_Wl_Client_Data *cdata;
-
-         cdata = e_client_cdata_get(ec);
-
-        if (e_pixmap_usable_get(ec->pixmap))
-          {
-             if (cdata && cdata->mapped)
-               {
-                  ELOGF("EDA", "UNICONIFY|object show. eda:%p frame_visible:%d(%d)",
-                        ec, eda, evas_object_visible_get(ec->frame), e_view_client_visible_get(e_client_view_get(ec)));
-                  e_view_client_show(e_client_view_get(ec));
-               }
-             else
-               {
-                  ELOGF("EDA", "UNICONIFY|object no show. currently unmapped. eda:%p",
-                        ec, eda);
-               }
-          }
-        else
-          {
-             if (!ec->exp_iconify.buffer_flush &&
-                 !ec->exp_iconify.deiconify_update)
-               {
-                  if (cdata && cdata->mapped)
-                    {
-                       ELOGF("EDA", "UNICONIFY|object show. no use buffer flush. eda:%p frame_visible:%d(%d)",
-                           ec, eda, evas_object_visible_get(ec->frame), e_view_client_visible_get(e_client_view_get(ec)));
-                       e_view_client_show(e_client_view_get(ec));
-                    }
-               }
-          }
-     }
-
-   e_client_comp_hidden_set(ec, 0);
-   ec->deskshow = ec->iconic = 0;
-
-#if 0 // focus should be set to the top window not uniconify window
-   if (ec->pixmap && e_pixmap_usable_get(ec->pixmap))
-      e_client_frame_focus_set(ec, EINA_TRUE);
-#endif
-
-   // send the uniconify event of a client
-   e_client_uniconify_event_send(ec);
-
-   if (e_config->transient.iconify)
-     {
-        E_Client *child;
-        Eina_List *list = eina_list_clone(ec->transients);
-
-        EINA_LIST_FREE(list, child)
-          {
-             if (e_client_transient_policy_get(child) == E_TRANSIENT_ABOVE)
-               {
-                  if (child->exp_iconify.type == E_ICONIFIED_TYPE_PARENT_ICONIFY_BY_CLIENT)
-                    e_policy_client_iconic_state_change_send(child, 0);
-                  child->exp_iconify.not_raise = not_raise;
-                  e_client_uniconify(child);
-               }
-          }
-     }
-
-   ec->exp_iconify.not_raise = 0;
-}
-
-static void
-_desk_area_cb_client_stick(struct wl_listener *listener, void *data)
-{
-   E_Desk_Area_Private_Client *eda_client;
-   E_Client *ec;
-   E_Client *child;
-   Eina_List *list;
-
-   eda_client = wl_container_of(listener, eda_client, client_stick);
-   ec = eda_client->ec;
-
-   //TODO: No need to make a callback at desk_area.
-   //      Implement this at e_client_stick() function.
-   ec->sticky = 1;
-   ec->hidden = 0;
-
-   if (e_config->transient.desktop)
-     {
-        list = eina_list_clone(ec->transients);
-        EINA_LIST_FREE(list, child)
-          {
-             child->sticky = 1;
-             e_view_client_show(e_client_view_get(ec));
-          }
-     }
-}
-
-static void
-_desk_area_cb_client_unstick(struct wl_listener *listener, void *data)
-{
-   E_Desk_Area_Private_Client *eda_client;
-   E_Client *ec;
-   E_Client *child;
-   Eina_List *list;
-
-   eda_client = wl_container_of(listener, eda_client, client_unstick);
-   ec = eda_client->ec;
-
-   //TODO: No need to make a callback at desk_area.
-   //      Implement this at e_client_unstick() function.
-   ec->hidden = ec->sticky = 0;
-
-   if (e_config->transient.desktop)
-     {
-        list = eina_list_clone(ec->transients);
-        EINA_LIST_FREE(list, child)
-          {
-             child->sticky = 0;
-          }
-     }
-}
-
-static void
-_e_desk_area_ec_maximize(E_Desk_Area *eda, E_Client *ec, E_Maximize max)
-{
-   int x1, yy1, x2, y2;
-//FIXME: TODO: This is ugly. Use the x,y,w,y of this desk_area
-   int zx, zy, zw, zh;
-   Eina_Bool override = ec->maximize_override;
-
-//FIXME: TODO: This is ugly. Use the x,y,w,y of this desk_area
-// Obstacles of zone should be the desk_areas by the window manager policy.
-// If the Obstacles assigns the desk_areas, this maximize callback does not need
-// e_zone_desk_useful_geometry_get() function. Because the geometry of this desk_area
-// already be calcuated by the obstacles desk_areas. Therefore, the zx, zy, zw, zh in
-// this function can use the x,y,w,h of this desk_area.
-   E_Desk *desk;
-   E_Zone *zone;
-   desk = eda->desk;
-   zone = desk->zone;
-
-   zx = zy = zw = zh = 0;
-   ec->maximize_override = 1;
-
-   switch (max & E_MAXIMIZE_TYPE)
-     {
-      case E_MAXIMIZE_NONE:
-         /* Ignore */
-         break;
-
-      case E_MAXIMIZE_FULLSCREEN:
-      case E_MAXIMIZE_FILL:
-         if (ec->base_output_resolution.use)
-           {
-              zx = eda->x;
-              zy = eda->y;
-              zw = ec->base_output_resolution.w;
-              zh = ec->base_output_resolution.h;
-           }
-         else
-           {
-              //FIXME: TODO: This is ugly. Use the x,y,w,y of this desk_area
-              e_zone_desk_useful_geometry_get(zone, desk, &zx, &zy, &zw, &zh, EINA_FALSE);
-           }
-
-         switch (max & E_MAXIMIZE_DIRECTION)
-           {
-            case E_MAXIMIZE_BOTH:
-               e_client_maximized_geometry_set(ec, zx, zy, zw, zh);
-               break;
-
-            case E_MAXIMIZE_VERTICAL:
-               e_client_maximized_geometry_set(ec, ec->x, zy, ec->w, zh);
-               break;
-
-            case E_MAXIMIZE_HORIZONTAL:
-               e_client_maximized_geometry_set(ec, zx, ec->y, zw, ec->h);
-               break;
-
-            case E_MAXIMIZE_LEFT:
-               e_client_maximized_geometry_set(ec, zx, zy, zw / 2, zh);
-               break;
-
-            case E_MAXIMIZE_RIGHT:
-               e_client_maximized_geometry_set(ec, zx + zw / 2, zy, zw / 2, zh);
-               break;
-           }
-         break;
-
-      case E_MAXIMIZE_SMART:
-      case E_MAXIMIZE_EXPAND:
-         if (desk->visible)
-           {
-              // base_output_resolution
-              if (ec->base_output_resolution.use)
-                {
-                   zx = eda->x;
-                   zy = eda->y;
-                   zw = ec->base_output_resolution.w;
-                   zh = ec->base_output_resolution.h;
-                }
-              else
-                {
-                   //FIXME: TODO: This is ugly. Use the x,y,w,y of this desk_area
-                   e_zone_desk_useful_geometry_get(zone, desk, &zx, &zy, &zw, &zh, EINA_TRUE);
-                }
-           }
-         else
-           {
-              x1 = eda->x;
-              yy1 = eda->y;
-              x2 = eda->x + eda->w;
-              y2 = eda->y + eda->h;
-              e_maximize_client_shelf_fill(ec, &x1, &yy1, &x2, &y2, max);
-              zx = x1, zy = yy1;
-              zw = x2 - x1;
-              zh = y2 - yy1;
-           }
-
-         e_view_client_maximize(e_client_view_get(ec));
-
-         switch (max & E_MAXIMIZE_DIRECTION)
-           {
-            case E_MAXIMIZE_BOTH:
-               e_client_maximized_geometry_set(ec, zx, zy, zw, zh);
-               break;
-
-            case E_MAXIMIZE_VERTICAL:
-               e_client_maximized_geometry_set(ec, ec->x, zy, ec->w, zh);
-               break;
-
-            case E_MAXIMIZE_HORIZONTAL:
-               e_client_maximized_geometry_set(ec, zx, ec->y, zw, ec->h);
-               break;
-
-            case E_MAXIMIZE_LEFT:
-               e_client_maximized_geometry_set(ec, zx, zy, zw / 2, zh);
-               break;
-
-            case E_MAXIMIZE_RIGHT:
-               e_client_maximized_geometry_set(ec, zx + zw / 2, zy, zw / 2, zh);
-               break;
-           }
-         break;
-     }
-
-   if (ec->maximize_override)
-     ec->maximize_override = override;
-}
-
-static void
-_desk_area_cb_client_maximize(struct wl_listener *listener, void *data)
-{
-   E_Desk_Area_Private_Client *eda_client;
-   E_Desk_Area *eda;
-   E_Client *ec;
-   E_Maximize max;
-
-   eda_client = wl_container_of(listener, eda_client, client_maximize);
-   eda = eda_client->eda;
-   ec = eda_client->ec;
-
-   // "override = 1" means that ec is not controlled by wm policy
-   if (ec->override) return;
-
-   max = *((E_Maximize *)data);
-
-   ec->pre_res_change.valid = 0;
-
-   if (!ec->fullscreen)
-     {
-        e_client_maximize_pre_set(ec, EINA_TRUE);
-
-        if (!(ec->maximized & E_MAXIMIZE_HORIZONTAL))
-          {
-             /* Horizontal hasn't been set */
-             ec->saved.x = ec->client.x - eda->x;
-             ec->saved.w = ec->client.w;
-          }
-        if (!(ec->maximized & E_MAXIMIZE_VERTICAL))
-          {
-             /* Vertical hasn't been set */
-             ec->saved.y = ec->client.y - eda->y;
-             ec->saved.h = ec->client.h;
-          }
-
-        _e_desk_area_ec_maximize(eda, ec, max);
-     }
-}
-
-static void
-_desk_area_cb_client_maximize_done(struct wl_listener *listener, void *data)
-{
-   E_Desk_Area_Private_Client *eda_client;
-   E_Client *ec;
-   int w, h;
-
-   eda_client = wl_container_of(listener, eda_client, client_maximize_done);
-   ec = eda_client->ec;
-
-   e_client_maximized_geometry_get(ec, NULL, NULL, &w, &h);
-   e_client_shell_configure_send(ec, 0, w, h);
-
-   e_client_maximize_pre_set(ec, EINA_FALSE);
-}
-
-static void
-_desk_area_cb_client_unmaximize(struct wl_listener *listener, void *data)
-{
-   E_Desk_Area_Private_Client *eda_client;
-   E_Desk_Area *eda;
-   E_Client *ec;
-   E_Maximize max;
-
-   eda_client = wl_container_of(listener, eda_client, client_unmaximize);
-   eda = eda_client->eda;
-   ec = eda_client->ec;
-
-   // "override = 1" means that ec is not controlled by wm policy
-   if (ec->override) return;
-   if (ec->fullscreen) return;
-
-   max = *((E_Maximize *)data);
-
-   if (ec->maximized & E_MAXIMIZE_TYPE)
-     {
-        e_client_maximize_pre_set(ec, EINA_TRUE);
-
-        ec->pre_res_change.valid = 0;
-        ec->changes.need_maximize = 0;
-
-        if ((ec->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN)
-          {
-             E_Maximize tmp_max = ec->maximized;
-
-             //un-set maximized state for updating frame.
-             ec->maximized = E_MAXIMIZE_NONE;
-             e_client_frame_update(ec);
-
-             // re-set maximized state for unmaximize smart callback.
-             ec->maximized = tmp_max;
-             if (ec->comp_data && ec->comp_data->shell.configure_send)
-               _e_desk_area_configure_send(ec, 0, 0);
-             e_client_maximize_pre_set(ec, EINA_FALSE);
-
-             // un-set maximized state.
-             ec->maximized = E_MAXIMIZE_NONE;
-             e_client_util_move_resize_without_frame(ec,
-                                                     ec->saved.x + eda->x,
-                                                     ec->saved.y + eda->y,
-                                                     ec->saved.w, ec->saved.h);
-             ec->saved.x = ec->saved.y = ec->saved.w = ec->saved.h = 0;
-          }
-        else
-          {
-             int w, h, x, y;
-             Eina_Bool horiz = EINA_FALSE, vert = EINA_FALSE;
-
-             w = ec->client.w;
-             h = ec->client.h;
-             x = ec->client.x;
-             y = ec->client.y;
-
-             if (max & E_MAXIMIZE_VERTICAL)
-               {
-                  /* Remove vertical */
-                  h = ec->saved.h;
-                  vert = EINA_TRUE;
-                  y = ec->saved.y + eda->y;
-                  if ((max & E_MAXIMIZE_VERTICAL) == E_MAXIMIZE_VERTICAL)
-                    {
-                       ec->maximized &= ~E_MAXIMIZE_VERTICAL;
-                       ec->maximized &= ~E_MAXIMIZE_LEFT;
-                       ec->maximized &= ~E_MAXIMIZE_RIGHT;
-                    }
-                  if ((max & E_MAXIMIZE_LEFT) == E_MAXIMIZE_LEFT)
-                    ec->maximized &= ~E_MAXIMIZE_LEFT;
-                  if ((max & E_MAXIMIZE_RIGHT) == E_MAXIMIZE_RIGHT)
-                    ec->maximized &= ~E_MAXIMIZE_RIGHT;
-               }
-             if (max & E_MAXIMIZE_HORIZONTAL)
-               {
-                  /* Remove horizontal */
-                  w = ec->saved.w;
-                  x = ec->saved.x + eda->x;
-                  horiz = EINA_TRUE;
-                  ec->maximized &= ~E_MAXIMIZE_HORIZONTAL;
-               }
-
-             if (!(ec->maximized & E_MAXIMIZE_DIRECTION))
-               {
-                  ec->maximized = E_MAXIMIZE_NONE;
-                  e_client_frame_update(ec);
-                  e_client_resize_limit(ec, &w, &h);
-                  e_client_pos_set(ec, x, y);
-                  if ((ec->saved.w != 0) && (ec->saved.h != 0))
-                    {
-                       if ((w != ec->saved.w) || (h != ec->saved.h))
-                         {
-                            e_policy_visibility_client_defer_move(ec);
-                         }
-                    }
-               }
-             else
-               {
-                  e_client_resize_limit(ec, &w, &h);
-                  e_client_pos_set(ec, x, y);
-                  if ((ec->saved.w != 0) && (ec->saved.h != 0))
-                    {
-                       if ((w != ec->saved.w) || (h != ec->saved.h))
-                         {
-                            e_policy_visibility_client_defer_move(ec);
-                         }
-                    }
-               }
-             if (vert)
-               ec->saved.h = ec->saved.y = 0;
-             if (horiz)
-               ec->saved.w = ec->saved.x = 0;
-          }
-     }
-}
-
-static void
-_desk_area_cb_client_unmaximize_done(struct wl_listener *listener, void *data)
-{
-   E_Desk_Area_Private_Client *eda_client;
-   E_Client *ec;
-
-   eda_client = wl_container_of(listener, eda_client, client_unmaximize_done);
-   ec = eda_client->ec;
-
-   if (ec->comp_data && ec->comp_data->shell.configure_send)
-     _e_desk_area_configure_send(ec, 0, 0);
-
-   e_client_maximize_pre_set(ec, EINA_FALSE);
-}
-
-static void
-_desk_area_cb_client_activate_done(struct wl_listener *listener, void *data)
-{
-   E_Desk_Area_Private_Client *eda_client;
-   E_Desk_Area *eda;
-   E_Client *ec;
-
-   eda_client = wl_container_of(listener, eda_client, client_activate_done);
-   eda = eda_client->eda;
-   ec = eda_client->ec;
-
-   ELOGF("EDA", "CLIENT ACTIVATE DONE. eda:%p", ec, eda);
-
-   if (!ec->lock_user_stacking)
-     e_client_raise(ec);
-}
-
-static void
-_desk_area_cb_client_delete_request(struct wl_listener *listener, void *data)
-{
-   E_Desk_Area_Private_Client *eda_client;
-   E_Desk_Area *eda;
-   E_Client *ec;
-
-   eda_client = wl_container_of(listener, eda_client, delete_request);
-   eda = eda_client->eda;
-   ec = eda_client->ec;
-
-   ELOGF("EDA", "CLIENT DELETE REQUEST. eda:%p", ec, eda);
-
-   e_comp_ignore_win_del(E_PIXMAP_TYPE_WL, e_pixmap_window_get(ec->pixmap));
-
-   e_object_del(E_OBJECT(ec));
-
-   e_comp_wl_focus_check();
-
-   /* TODO: Delete request send ??
-    * NB: No such animal wrt wayland */
-}
-
-static void
-_desk_area_cb_client_kill_request(struct wl_listener *listener, void *data)
-{
-   E_Desk_Area_Private_Client *eda_client;
-   E_Desk_Area *eda;
-   E_Client *ec;
-
-   eda_client = wl_container_of(listener, eda_client, kill_request);
-   eda = eda_client->eda;
-   ec = eda_client->ec;
-
-   ELOGF("EDA", "CLIENT KILL REQUEST. eda:%p", ec, eda);
-
-   e_comp_ignore_win_del(E_PIXMAP_TYPE_WL, e_pixmap_window_get(ec->pixmap));
-   if (ec->comp_data)
-     {
-        if (ec->comp_data->reparented)
-          e_client_comp_hidden_set(ec, EINA_TRUE);
-     }
-
-   e_view_pass_events_set(e_view_client_view_get(e_client_view_get(ec)), true);
-   if (ec->visible) e_view_client_hide(e_client_view_get(ec));
-   if (!ec->internal) e_object_del(E_OBJECT(ec));
-
-   e_comp_wl_focus_check();
-}
-
-static void
-_desk_area_cb_client_ping(struct wl_listener *listener, void *data)
-{
-   E_Desk_Area_Private_Client *eda_client;
-   E_Desk_Area *eda;
-   E_Client *ec;
-
-   eda_client = wl_container_of(listener, eda_client, ping);
-   eda = eda_client->eda;
-   ec = eda_client->ec;
-
-   ELOGF("EDA", "CLIENT PING. eda:%p", ec, eda);
-
-   e_client_shell_ping(ec);
-}
-
-static void
-_desk_area_cb_client_redirect(struct wl_listener *listener, void *data)
-{
-   E_Desk_Area_Private_Client *eda_client;
-   E_Desk_Area *eda;
-   E_Client *ec;
-   int w, h, pw, ph;
-
-   eda_client = wl_container_of(listener, eda_client, redirect);
-   eda = eda_client->eda;
-   ec = eda_client->ec;
-
-   ELOGF("EDA", "CLIENT REDIRECT. eda:%p", ec, eda);
-
-   /* - get current size
-    * - calc new size
-    * - readjust for new frame size
-    */
-
-   w = ec->w, h = ec->h;
-   e_view_client_frame_wh_unadjust(e_client_view_get(ec), w, h, &pw, &ph);
-
-   e_view_client_frame_recalc(e_client_view_get(ec));
-
-   if (!ec->fullscreen)
-     e_view_client_frame_wh_adjust(e_client_view_get(ec), ec->client.w, ec->client.h, &w, &h);
-
-   if (ec->fullscreen)
-     {
-        e_view_client_size_set(e_client_view_get(ec), eda->w, eda->h);
-     }
-   else if (ec->new_client)
-     {
-        if ((ec->w < 1) || (ec->h < 1)) return;
-        e_view_client_frame_wh_adjust(e_client_view_get(ec), pw, ph, &w, &h);
-        e_view_client_size_set(e_client_view_get(ec), w, h);
-     }
-   else if ((w != ec->w) || (h != ec->h))
-     e_view_client_size_set(e_client_view_get(ec), w, h);
-}
-
-static void
-_e_client_zones_layout_calc(E_Client *ec, int *zx, int *zy, int *zw, int *zh)
-{
-   int x, y, w, h;
-   E_Zone *zone_above, *zone_below, *zone_left, *zone_right;
-   E_Zone *zone;
-
-   zone = e_comp_zone_find_by_ec(ec);
-   if (!zone) return;
-   x = zone->x;
-   y = zone->y;
-   w = zone->w;
-   h = zone->h;
-
-   if (eina_list_count(e_comp_zone_list_get()) == 1)
-     {
-        if (zx) *zx = x;
-        if (zy) *zy = y;
-        if (zw) *zw = w;
-        if (zh) *zh = h;
-        return;
-     }
-
-   zone_left = e_comp_zone_xy_get((x - w + 5), y);
-   zone_right = e_comp_zone_xy_get((x + w + 5), y);
-   zone_above = e_comp_zone_xy_get(x, (y - h + 5));
-   zone_below = e_comp_zone_xy_get(x, (y + h + 5));
-
-   if (!(zone_above) && (y))
-     zone_above = e_comp_zone_xy_get(x, (h - 5));
-
-   if (!(zone_left) && (x))
-     zone_left = e_comp_zone_xy_get((x - 5), y);
-
-   if (zone_right)
-     w = zone_right->x + zone_right->w;
-
-   if (zone_left)
-     w = zone->x + zone->w;
-
-   if (zone_below)
-     h = zone_below->y + zone_below->h;
-
-   if (zone_above)
-     h = zone->y + zone->h;
-
-   if ((zone_left) && (zone_right))
-     w = zone->w + zone_right->x;
-
-   if ((zone_above) && (zone_below))
-     h = zone->h + zone_below->y;
-
-   if (x) x -= zone->w;
-   if (y) y -= zone->h;
-
-   if (zx) *zx = x > 0 ? x : 0;
-   if (zy) *zy = y > 0 ? y : 0;
-   if (zw) *zw = w;
-   if (zh) *zh = h;
-}
-
-static void
-_e_client_stay_within_canvas_margin(E_Client *ec, int x, int y, int *new_x, int *new_y)
-{
-   // TODO: FIXME: fix the x, y in Desk_Area
-   int new_x_max, new_y_max, new_x_min, new_y_min;
-   int margin_w, margin_h;
-   int zw = 0, zh = 0;
-   int cw, ch;
-   E_Zone *zone;
-
-   zone = e_comp_zone_find_by_ec(ec);
-   if (!zone)
-     {
-        if (new_x) *new_x = x;
-        if (new_y) *new_y = y;
-        return;
-     }
-
-   cw = ec->w;
-   ch = ec->h;
-
-   _e_client_zones_layout_calc(ec, NULL, NULL, &zw, &zh);
-
-   margin_w = zw/3;
-   margin_h = zh/10;
-
-   new_x_min = (margin_w > cw) ? 0 : -(cw - margin_w);
-   new_x_max = (margin_w > cw) ? (zw - cw) : (zw - margin_w);
-   new_y_min = (margin_h > ch) ? 0 : -(ch - margin_h);
-   new_y_max = (margin_h > ch) ? (zh - ch) : (zh - margin_h);
-
-   if (x >= new_x_max)
-     *new_x = new_x_max;
-   else if (x <= new_x_min)
-     *new_x = new_x_min;
-
-   if (y >= new_y_max)
-     *new_y = new_y_max;
-   else if (y <= new_y_min)
-     *new_y = new_y_min;
-
-}
-
-static void
-_desk_area_cb_client_stay_within_margin(struct wl_listener *listener, void *data)
-{
-   E_Desk_Area_Private_Client *eda_client;
-   E_Client *ec;
-   int new_x, new_y;
-
-   eda_client = wl_container_of(listener, eda_client, client_stay_within_margin);
-   ec = eda_client->ec;
-
-   new_x = ec->x;
-   new_y = ec->y;
-
-   if (ec->floating)
-     {
-        _e_client_stay_within_canvas_margin(ec, ec->x, ec->y, &new_x, &new_y);
-
-        if ((ec->x != new_x) || (ec->y != new_y))
-          e_view_position_set(e_view_client_view_get(e_client_view_get(ec)), new_x, new_y);
-     }
-}
-
-static void
-_e_client_stay_within_canvas(E_Client *ec, int x, int y, int *new_x, int *new_y)
-{
-   int new_x_max, new_y_max;
-   int zw, zh;
-   Eina_Bool lw, lh;
-   E_Zone *zone;
-
-   zone = e_comp_zone_find_by_ec(ec);
-   if (!zone)
-     {
-        if (new_x) *new_x = x;
-        if (new_y) *new_y = y;
-        return;
-     }
-
-   _e_client_zones_layout_calc(ec, NULL, NULL, &zw, &zh);
-
-   new_x_max = zw - ec->w;
-   new_y_max = zh - ec->h;
-   lw = ec->w > zw ? EINA_TRUE : EINA_FALSE;
-   lh = ec->h > zh ? EINA_TRUE : EINA_FALSE;
-
-   if (lw)
-     {
-        if (x <= new_x_max)
-          *new_x = new_x_max;
-        else if (x >= 0)
-          *new_x = 0;
-     }
-   else
-     {
-        if (x >= new_x_max)
-          *new_x = new_x_max;
-        else if (x <= 0)
-          *new_x = 0;
-     }
-
-   if (lh)
-     {
-        if (y <= new_y_max)
-          *new_y = new_y_max;
-        else if (y >= 0)
-          *new_y = 0;
-     }
-   else
-     {
-        if (y >= new_y_max)
-          *new_y = new_y_max;
-        else if (y <= 0)
-          *new_y = 0;
-     }
-}
-
-static void
-_e_client_move_handle(E_Client *ec)
-{
-   int x, y;
-
-   if ((ec->moveinfo.down.button >= 1) && (ec->moveinfo.down.button <= 3))
-     {
-        x = ec->mouse.last_down[ec->moveinfo.down.button - 1].x +
-           (ec->mouse.current.mx - ec->moveinfo.down.mx);
-        y = ec->mouse.last_down[ec->moveinfo.down.button - 1].y +
-           (ec->mouse.current.my - ec->moveinfo.down.my);
-     }
-   else
-     {
-        x = ec->moveinfo.down.x +
-           (ec->mouse.current.mx - ec->moveinfo.down.mx);
-        y = ec->moveinfo.down.y +
-           (ec->mouse.current.my - ec->moveinfo.down.my);
-     }
-
-   if (e_config->screen_limits == E_CLIENT_OFFSCREEN_LIMIT_ALLOW_NONE)
-     _e_client_stay_within_canvas(ec, x, y, &x, &y);
-
-   if (ec->floating)
-     _e_client_stay_within_canvas_margin(ec, x, y, &x, &y);
-
-   e_view_position_set(e_view_client_view_get(e_client_view_get(ec)), x, y);
-
-   if (e_client_transform_core_enable_get(ec))
-     {
-        e_client_transform_core_update(ec);
-     }
-}
-
-static void
-_desk_area_cb_client_mouse_move(struct wl_listener *listener, void *data)
-{
-   E_Desk_Area_Private_Client *eda_client;
-   E_Client *ec;
-   Evas_Point *output;
-
-   eda_client = wl_container_of(listener, eda_client, client_mouse_move);
-   ec = eda_client->ec;
-
-   output = (Evas_Point *)data;
-
-   if (ec->iconic || e_client_util_ignored_get(ec)) return;
+#define PRI(eda) ((E_Desk_Area_Private *)e_object_data_get(E_OBJECT(eda)))
 
-   ec->mouse.current.mx = output->x;
-   ec->mouse.current.my = output->y;
+#define API_ENTRY \
+   EINA_SAFETY_ON_NULL_RETURN(eda); \
+   E_Desk_Area_Private *priv = PRI(eda); \
+   EINA_SAFETY_ON_NULL_RETURN(priv);
 
-   if (e_client_util_moving_get(ec))
-     {
-        _e_client_move_handle(ec);
-     }
-   else if (e_client_util_resizing_get(ec))
-     {
-        e_client_resize_handle(ec);
-     }
-}
+#define API_ENTRY_VAL(ret) \
+   EINA_SAFETY_ON_NULL_RETURN_VAL(eda, ret); \
+   E_Desk_Area_Private *priv = PRI(eda); \
+   EINA_SAFETY_ON_NULL_RETURN_VAL(priv, ret);
 
-static void
-_desk_area_cb_client_resize_end(struct wl_listener *listener, void *data)
+struct _E_Desk_Area_Private
 {
-   E_Desk_Area_Private_Client *eda_client;
-   E_Client *ec;
-
-   eda_client = wl_container_of(listener, eda_client, client_resize_end);
-   ec = eda_client->ec;
-
-   if (!e_client_util_resizing_get(ec)) return;
-
-   e_client_resize_handle(ec);
-   e_client_resize_end(ec);
-
-   ec->changes.reset_gravity = 1;
-
-   EC_CHANGED(ec);
-}
+   E_Desk_Area *eda;
 
+   struct {
+      struct wl_signal geometry_set;
+      struct wl_signal layer_set;
+      struct wl_signal activate;
+      struct wl_signal raise;
+      struct wl_signal lower;
+      struct wl_signal top_ec_get;
+      struct wl_signal bottom_ec_get;
+      struct wl_signal has_ec;
+
+      struct wl_signal client_add;
+      struct wl_signal client_del;
+   } events;
+};
 
 static void
-_desk_area_cb_comp_object_lower(struct wl_listener *listener, void *data)
+_e_desk_geometry_info_set(E_Desk_Area *eda, int x, int y, int w, int h)
 {
-   E_Desk_Area_Private_Client *eda_client;
-   E_Desk_Area *eda;
-   E_Client *ec;
-   Evas_Object *obj, *o;
-   E_Comp_Object *cw;
-
-   eda_client = wl_container_of(listener, eda_client, comp_object_lower);
-   eda = eda_client->eda;
-   ec = eda_client->ec;
-   obj = ec->frame;
-   cw = (E_Comp_Object *)data;
-
-   if ((cw->ec->layer_block) || (cw->ec->layer_pending))
-     {
-        if (cw->ec->layer_pending)
-          _e_comp_object_layer_update(eda, obj, NULL, obj);
-
-        e_comp_object_lower(cw, obj);
-        return;
-     }
+   E_Desk *desk;
 
-   if (!EINA_INLIST_GET(cw->ec)->prev) return; //already lowest on layer
+   if (!eda) return;
+   if (!eda->desk) return;
 
-   o = evas_object_below_get(obj);
-   _e_comp_object_layers_remove(eda, cw);
-   /* prepend to client list since this client should be the first item now */
-   _e_comp_object_layers_add(eda, cw, NULL, NULL, 1);
-   if (evas_object_layer_get(o) != evas_object_layer_get(obj)) return; //already at bottom!
+   desk = eda->desk;
 
-   evas_object_data_set(obj, "client_restack", (void*)1);
-   e_comp_object_lower(cw, obj);
-   evas_object_data_del(obj, "client_restack");
+   eda->x = x;
+   eda->y = y;
+   eda->w = w;
+   eda->h = h;
 
-   if (!cw->visible) return;
-   e_comp_render_queue();
-   e_comp_object_transform_obj_stack_update(obj);
+   eda->scale_w = (double)w / (double)desk->geom.w;
+   eda->scale_h = (double)h / (double)desk->geom.h;
 }
 
-static void
-_desk_area_cb_comp_object_raise(struct wl_listener *listener, void *data)
+EINTERN int
+e_desk_area_init(void)
 {
-   E_Desk_Area_Private_Client *eda_client;
-   E_Desk_Area *eda;
-   E_Client *ec;
-   Evas_Object *obj, *o, *op;
-   E_Comp_Object *cw;
-
-   eda_client = wl_container_of(listener, eda_client, comp_object_raise);
-   eda = eda_client->eda;
-   ec = eda_client->ec;
-   obj = ec->frame;
-   cw = (E_Comp_Object *)data;
-
-   if ((cw->ec->layer_block) || (cw->ec->layer_pending))
-     {
-        if (cw->ec->layer_pending)
-          {
-             int obj_layer = evas_object_layer_get(obj);
-             if (cw->ec->layer != obj_layer)
-               _e_comp_object_layer_update(eda, obj, NULL, NULL);
-          }
-
-        e_comp_object_raise(obj);
-        return;
-     }
-   if (!EINA_INLIST_GET(cw->ec)->next) return;//already highest on layer
-   o = evas_object_above_get(obj);
-   if (evas_object_layer_get(o) != evas_object_layer_get(obj)) return; //already at top!
-
-   /* still stack below override below the layer marker */
-   for (op = o = eda->layers[cw->layer].obj;
-        o && o != eda->layers[cw->layer - 1].obj;
-        op = o, o = evas_object_below_get(o))
-     {
-        if (evas_object_smart_smart_get(o))
-          {
-             E_Client *ec;
-
-             ec = e_comp_object_client_get(o);
-             if (ec && (!ec->override)) break;
-          }
-     }
-   e_comp_object_stack_below(obj, op);
-   e_client_focus_defer_set(cw->ec);
-
-   if (!cw->visible) return;
-   e_comp_render_queue();
-   e_comp_object_transform_obj_stack_update(obj);
+   return 1;
 }
 
-static void
-_desk_area_cb_comp_object_set_layer(struct wl_listener *listener, void *data)
+EINTERN int
+e_desk_area_shutdown(void)
 {
-   E_Desk_Area_Private_Client *eda_client;
-   E_Desk_Area *eda;
-   E_Client *ec;
-   Evas_Object *obj;
-   E_Comp_Object_Data_Set_Layer *layer_set_data;
-   E_Comp_Object *cw;
-   int layer;
-   E_Comp_Wl_Client_Data *child_cdata;
-   unsigned int l;
-   int oldraise;
-
-   eda_client = wl_container_of(listener, eda_client, comp_object_set_layer);
-   eda = eda_client->eda;
-   ec = eda_client->ec;
-   obj = ec->frame;
-   layer_set_data = (E_Comp_Object_Data_Set_Layer *)data;
-   cw = layer_set_data->cw;
-   layer = layer_set_data->layer;
-   l = e_comp_canvas_layer_map(layer);
-
-   if ((cw->ec->layer_block) || (cw->ec->layer_pending))
-     {
-        /* doing a compositor effect, follow directions */
-        e_comp_object_layer_set(obj, layer);
-        if (layer == cw->ec->layer) //trying to put layer back
-          {
-             E_Client *ec2;
-
-             /* if ec->layer and layer are the same but the client is not belong to the given(l)
-                 that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
-             if (cw->layer != l) goto layer_set;
-
-             if (cw->visible)
-               {
-                  e_comp_render_queue();
-               }
-             ec2 = e_client_above_get(cw->ec);
-             /* skip subsurface: stacking subsurface is handled by e_comp_wl */
-             while ((ec2) && (e_comp_wl_subsurface_check(ec2)))
-               ec2 = e_client_above_get(ec2);
-             if (ec2 && (evas_object_layer_get(ec2->frame) != evas_object_layer_get(obj)))
-               {
-                  ec2 = e_client_below_get(cw->ec);
-                  /* skip subsurface: stacking subsurface is handled by e_comp_wl */
-                  while ((ec2) && (e_comp_wl_subsurface_check(ec2)))
-                    ec2 = e_client_below_get(ec2);
-                  if (ec2 && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
-                    {
-                       evas_object_stack_above(obj, ec2->frame);
-                       return;
-                    }
-                  ec2 = NULL;
-               }
-             if (ec2 && (cw->ec->parent == ec2))
-               {
-                  if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
-                    evas_object_stack_above(obj, ec2->frame);
-                  else
-                    evas_object_stack_below(obj, ec2->frame);
-               }
-             else
-               evas_object_stack_below(obj, ec2 ? ec2->frame : eda->layers[cw->layer].obj);
-          }
-        return;
-     }
-
-layer_set:
-   if (cw->layer == l) return;
-   if (e_util_client_layer_map(layer) == 9999)
-     return; //invalid layer for clients not doing comp effects
-   if (cw->ec->fullscreen)
-     {
-        cw->ec->saved.layer = layer;
-        return;
-     }
-   oldraise = e_config->transient.raise;
-
-   /* clamp to valid client layer */
-   layer = e_comp_canvas_client_layer_map_nearest(layer);
-   cw->ec->layer = layer;
-   e_client_input_thread_layer_set(cw->ec, layer);
-   if (e_config->transient.layer)
-     {
-        E_Client *child;
-        Eina_List *list = eina_list_clone(cw->ec->transients);
-
-        /* We need to set raise to one, else the child won't
-         * follow to the new layer. It should be like this,
-         * even if the user usually doesn't want to raise
-         * the transients.
-         */
-        e_config->transient.raise = 1;
-        EINA_LIST_FREE(list, child)
-          {
-             child_cdata = e_client_cdata_get(child);
-             if (child_cdata && !child_cdata->mapped)
-               {
-                  ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
-                  continue;
-               }
-             e_client_layer_set(child, layer);
-          }
-     }
-
-   e_config->transient.raise = oldraise;
-
-   _e_comp_object_layers_remove(eda, cw);
-   cw->layer = e_comp_canvas_layer_map(layer);
-   _e_comp_object_layers_add(eda, cw, NULL, NULL, 0);
-   //if (cw->ec->new_client)
-     //INF("CLIENT STACKED %p: %u", cw->ec, layer);
-   e_comp_object_layer_set(obj, layer);
-   if (!eda->layers[cw->layer].obj) return; //this is a layer marker
-   evas_object_stack_below(obj, eda->layers[cw->layer].obj);
-   if (evas_object_below_get(obj) == eda->layers[cw->layer].obj)
-     {
-        /* can't stack a client above its own layer marker */
-        CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
-     }
+   return 1;
 }
 
-static void
-_desk_area_cb_comp_object_stack_above(struct wl_listener *listener, void *data)
+static Eina_Bool
+_e_desk_area_private_init(E_Desk_Area *eda)
 {
-   E_Desk_Area_Private_Client *eda_client;
-   E_Desk_Area *eda;
-   E_Client *ec;
-   Evas_Object *obj, *above;
-   E_Comp_Object_Data_Stack_Above *stack_above_data;
-   E_Comp_Object *cw;
-
-   eda_client = wl_container_of(listener, eda_client, comp_object_stack_above);
-   eda = eda_client->eda;
-   ec = eda_client->ec;
-   obj = ec->frame;
-   stack_above_data = (E_Comp_Object_Data_Stack_Above *)data;
-   cw = stack_above_data->cw;
-   above = stack_above_data->above_obj;
-
-   if (evas_object_below_get(obj) == above)
-     {
-        _e_comp_object_layer_update(eda, obj, above, NULL);
-        return;
-     }
-
-   _e_comp_intercept_stack_helper(eda, cw, above, e_comp_object_stack_above);
-
-   e_comp_object_transform_obj_stack_update(obj);
-   e_comp_object_transform_obj_stack_update(above);
+   E_Desk_Area_Private *priv;
 
-}
+   priv = E_NEW(E_Desk_Area_Private, 1);
+   if (!priv)
+     return EINA_FALSE;
 
-static void
-_desk_area_cb_comp_object_stack_below(struct wl_listener *listener, void *data)
-{
-   E_Desk_Area_Private_Client *eda_client;
-   E_Desk_Area *eda;
-   E_Client *ec;
-   Evas_Object *obj, *below;
-   E_Comp_Object_Data_Stack_Below *stack_below_data;
-   E_Comp_Object *cw;
-
-   eda_client = wl_container_of(listener, eda_client, comp_object_stack_below);
-   eda = eda_client->eda;
-   ec = eda_client->ec;
-   obj = ec->frame;
-   stack_below_data = (E_Comp_Object_Data_Stack_Below *)data;
-   cw = stack_below_data->cw;
-   below = stack_below_data->below_obj;
-
-   if (evas_object_above_get(obj) == below)
-     {
-        _e_comp_object_layer_update(eda, obj, NULL, below);
-        return;
-     }
+   priv->eda = eda;
 
-   _e_comp_intercept_stack_helper(eda, cw, below, e_comp_object_stack_below);
+   e_object_data_set(E_OBJECT(eda), priv);
 
-   if (evas_object_smart_smart_get(obj))
-     e_comp_object_transform_obj_stack_update(obj);
-   if (evas_object_smart_smart_get(below))
-     e_comp_object_transform_obj_stack_update(below);
+   wl_signal_init(&priv->events.geometry_set);
+   wl_signal_init(&priv->events.layer_set);
+   wl_signal_init(&priv->events.activate);
+   wl_signal_init(&priv->events.raise);
+   wl_signal_init(&priv->events.lower);
+   wl_signal_init(&priv->events.top_ec_get);
+   wl_signal_init(&priv->events.bottom_ec_get);
+   wl_signal_init(&priv->events.has_ec);
+   wl_signal_init(&priv->events.client_add);
+   wl_signal_init(&priv->events.client_del);
 
+   return EINA_TRUE;
 }
 
 static void
-_desk_area_cb_comp_object_resize(struct wl_listener *listener, void *data)
+_e_desk_area_private_finish(E_Desk_Area *eda)
 {
-   E_Desk_Area_Private_Client *eda_client;
-   E_Client *ec;
-   E_Comp_Wl_Data *comp_wl;
-
-   eda_client = wl_container_of(listener, eda_client, comp_object_resize);
-   ec = eda_client->ec;
-
-   // "override = 1" means that ec is not controlled by wm policy
-   if (ec->override) return;
-   if (!ec->comp_data->shell.configure_send) return;
+   E_Desk_Area_Private *priv;
 
-   /* TODO: calculate x, y with transfrom object */
-   comp_wl = e_comp_wl_get();
-   if ((e_client_util_resizing_get(ec)) && (!ec->transformed) && (comp_wl->resize.edges))
-     {
-        int w, h;
+   priv = PRI(eda);
+   if (!priv) return;
 
-        w = ec->mouse.last_down[ec->moveinfo.down.button - 1].w;
-        h = ec->mouse.last_down[ec->moveinfo.down.button - 1].h;
-        if (e_view_client_frame_exists(e_client_view_get(ec)))
-          e_view_client_frame_wh_unadjust(e_client_view_get(ec), w, h, &w, &h);
+   e_object_data_set(E_OBJECT(eda), NULL);
 
-        switch (ec->resize_mode)
-          {
-           case E_POINTER_RESIZE_TL:
-           case E_POINTER_RESIZE_L:
-           case E_POINTER_RESIZE_BL:
-             w += ec->mouse.last_down[ec->moveinfo.down.button - 1].mx -
-               ec->mouse.current.mx;
-             break;
-           case E_POINTER_RESIZE_TR:
-           case E_POINTER_RESIZE_R:
-           case E_POINTER_RESIZE_BR:
-             w += ec->mouse.current.mx - ec->mouse.last_down[ec->moveinfo.down.button - 1].mx;
-             break;
-           default:
-             break;;
-          }
-        switch (ec->resize_mode)
-          {
-           case E_POINTER_RESIZE_TL:
-           case E_POINTER_RESIZE_T:
-           case E_POINTER_RESIZE_TR:
-             h += ec->mouse.last_down[ec->moveinfo.down.button - 1].my -
-               ec->mouse.current.my;
-             break;
-           case E_POINTER_RESIZE_BL:
-           case E_POINTER_RESIZE_B:
-           case E_POINTER_RESIZE_BR:
-             h += ec->mouse.current.my - ec->mouse.last_down[ec->moveinfo.down.button - 1].my;
-             break;
-           default:
-             break;
-          }
-        w = E_CLAMP(w, 1, w);
-        h = E_CLAMP(h, 1, h);
-        e_client_resize_limit(ec, &w, &h);
+   priv->eda = NULL;
 
-        e_client_shell_configure_send(ec, comp_wl->resize.edges, w, h);
-     }
-   else if ((!ec->fullscreen) && (!ec->maximized) &&
-            (!e_client_maximize_pre_get(ec)))
-     {
-        int pw = 0;
-        int ph = 0;
-        e_pixmap_size_get(ec->pixmap, &pw, &ph);
-        if ((pw != ec->w) || (ph != ec->h))
-          {
-             _e_desk_area_configure_send(ec, 1, 1);
-          }
-     }
+   free(priv);
 }
 
 static void
-_desk_area_cb_comp_object_color_set(struct wl_listener *listener, void *data)
+_e_desk_area_free(E_Desk_Area *eda)
 {
-   E_Desk_Area_Private_Client *eda_client;
-   E_Client *ec;
-   int a = 0;
-
-   eda_client = wl_container_of(listener, eda_client, comp_object_color_set);
-   ec = eda_client->ec;
-
-   e_view_client_color_get(e_client_view_get(ec), NULL, NULL, NULL, &a);
-   if (ec->netwm.opacity == a) return;
-
-   ec->netwm.opacity = a;
-   ec->netwm.opacity_changed = EINA_TRUE;
+   _e_desk_area_private_finish(eda);
+   free(eda);
 }
 
 EINTERN E_Desk_Area *
 e_desk_area_new(E_Desk *desk, int id, int x, int y, int w, int h, E_Desk_Area_Layer eda_layer)
 {
    E_Desk_Area *eda;
-   Evas_Object *obj;
-   E_Layer ec_layer;
 
    E_OBJECT_CHECK_RETURN(desk, NULL);
    E_OBJECT_TYPE_CHECK_RETURN(desk, E_DESK_TYPE, NULL);
@@ -2559,32 +137,9 @@ e_desk_area_new(E_Desk *desk, int id, int x, int y, int w, int h, E_Desk_Area_La
 
    eda->desk = desk;
    eda->id = id;
-
-   _e_desk_geometry_info_set(eda, x, y, w, h);
-
    eda->layer = eda_layer;
+   _e_desk_geometry_info_set(eda, x, y, w, h);
 
-   /* init smart object */
-   _e_desk_area_smart_init(eda);
-
-   /* init client's layers */
-   for (ec_layer = e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); ec_layer <= e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); ec_layer++)
-     {
-
-        obj = eda->layers[ec_layer].obj = evas_object_rectangle_add(e_comp_evas_get());
-        evas_object_layer_set(obj, e_comp_canvas_layer_map_to(ec_layer));
-        evas_object_name_set(obj, "layer_obj");
-     }
-
-   eda->hook_subsurf_create = e_comp_wl_hook_add(E_COMP_WL_HOOK_SUBSURFACE_CREATE,
-                                                 _e_desk_area_cb_hook_subsurface_create,
-                                                 NULL);
-
-#ifdef CLIENT_DEL_STACK_ISSUE
-   eda->hook_client_free = e_client_hook_add(E_CLIENT_HOOK_FREE,
-                                             _desk_area_cb_client_free,
-                                             eda);
-#endif // CLIENT_DEL_STACK_ISSUE
    return eda;
 }
 
@@ -2605,6 +160,8 @@ e_desk_area_geometry_set(E_Desk_Area *eda, int x, int y, int w, int h)
 
    _e_desk_geometry_info_set(eda, x, y, w, h);
 
+   wl_signal_emit(&PRI(eda)->events.geometry_set, eda);
+
    return EINA_TRUE;
 }
 
@@ -2630,6 +187,8 @@ e_desk_area_layer_set(E_Desk_Area *eda, E_Desk_Area_Layer eda_layer)
 
    eda->layer = eda_layer;
 
+   wl_signal_emit(&PRI(eda)->events.layer_set, eda);
+
    return EINA_TRUE;
 }
 
@@ -2648,54 +207,31 @@ e_desk_area_activate(E_Desk_Area *eda)
    if (!eda) return;
    if (!eda->desk) return;
 
-   e_desk_area_raise(eda);
-   _e_desk_area_active_change(eda, eda->desk);
+   wl_signal_emit(&PRI(eda)->events.activate, eda);
 }
 
 E_API Eina_Bool
 e_desk_area_is_activate(E_Desk_Area *eda)
 {
    if (!eda) return EINA_FALSE;
+
    return eda->active;
 }
 
 E_API void
 e_desk_area_raise(E_Desk_Area *eda)
 {
-   int i;
-   E_Client *ec;
-   Eina_List *l = NULL;
-   Eina_List *ll = NULL;
-
    if (!eda) return;
 
-   for (i=0; i<E_DESK_AREA_CLIENT_LAYER_MAX; i++)
-     {
-        EINA_LIST_REVERSE_FOREACH_SAFE(eda->ec_lists[i], l, ll, ec)
-          {
-             e_view_raise_to_top(e_view_client_view_get(e_client_view_get(ec)));
-          }
-     }
+   wl_signal_emit(&PRI(eda)->events.raise, eda);
 }
 
 E_API void
 e_desk_area_lower(E_Desk_Area *eda)
 {
-   int i;
-   E_Client *ec;
-   Eina_List *l = NULL;
-   Eina_List *ll = NULL;
-
    if (!eda) return;
 
-   for (i=E_DESK_AREA_CLIENT_LAYER_MAX-1; i>=0; i--)
-     {
-        //EINA_LIST_FOREACH(eda->ec_lists[i], l, ec)
-        EINA_LIST_FOREACH_SAFE(eda->ec_lists[i], l, ll, ec)
-          {
-             e_view_lower_to_bottom(e_view_client_view_get(e_client_view_get(ec)));
-          }
-     }
+   wl_signal_emit(&PRI(eda)->events.lower, eda);
 }
 
 E_API Evas_Object *
@@ -2707,22 +243,10 @@ e_desk_area_layer_object_get(E_Desk_Area *eda, E_Layer layer)
    return eda->layers[e_comp_canvas_layer_map(layer)].obj;
 }
 
-static E_Desk_Area_Private_Client *
-_e_desk_area_private_client_get(E_Client *ec)
-{
-   E_Desk_Area_Private_Client *eda_client;
-   struct wl_listener *listener;
-
-   listener = e_client_destroy_listener_get(ec, _desk_area_cb_client_destroy);
-   if (!listener) return NULL;
-
-   return wl_container_of(listener, eda_client, client_destroy);
-}
 
 E_API Eina_Bool
 e_desk_area_ec_add(E_Desk_Area *eda, E_Client *ec)
 {
-   E_Desk_Area_Private_Client *eda_client;
 
    E_OBJECT_CHECK_RETURN(eda, EINA_FALSE);
    E_OBJECT_TYPE_CHECK_RETURN(eda, E_DESK_AREA_TYPE, EINA_FALSE);
@@ -2737,87 +261,7 @@ e_desk_area_ec_add(E_Desk_Area *eda, E_Client *ec)
 
    ELOGF("EAD", "CLIENT ADD", ec);
 
-   eda_client = E_NEW(E_Desk_Area_Private_Client, 1);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(eda_client, EINA_FALSE);
-
-   eda_client->eda = eda;
-   eda_client->ec = ec;
-
-   // e_client listeners
-   eda_client->client_destroy.notify = _desk_area_cb_client_destroy;
-   e_client_destroy_listener_add(ec, &eda_client->client_destroy);
-   eda_client->client_get_above.notify = _desk_area_cb_client_get_above;
-   e_client_get_above_listener_add(ec, &eda_client->client_get_above);
-   eda_client->client_get_below.notify = _desk_area_cb_client_get_below;
-   e_client_get_below_listener_add(ec, &eda_client->client_get_below);
-   eda_client->client_get_visible_above.notify = _desk_area_cb_client_get_visible_above;
-   e_client_get_visible_above_listener_add(ec, &eda_client->client_get_visible_above);
-   eda_client->client_get_visible_below.notify = _desk_area_cb_client_get_visible_below;
-   e_client_get_visible_below_listener_add(ec, &eda_client->client_get_visible_below);
-   eda_client->client_subsurface_stack_update.notify = _desk_area_cb_client_subsurface_stack_update;
-   e_client_subsurface_stack_update_listener_add(ec, &eda_client->client_subsurface_stack_update);
-   eda_client->client_fullscreen.notify = _desk_area_cb_client_fullscreen;
-   e_client_fullscreen_listener_add(ec, &eda_client->client_fullscreen);
-   eda_client->client_unfullscreen.notify = _desk_area_cb_client_unfullscreen;
-   e_client_unfullscreen_listener_add(ec, &eda_client->client_unfullscreen);
-   eda_client->client_focus_set.notify = _desk_area_cb_client_focus_set;
-   e_client_focus_set_listener_add(ec, &eda_client->client_focus_set);
-   eda_client->client_iconify.notify = _desk_area_cb_client_iconify;
-   e_client_iconify_listener_add(ec, &eda_client->client_iconify);
-   eda_client->client_uniconify.notify = _desk_area_cb_client_uniconify;
-   e_client_uniconify_listener_add(ec, &eda_client->client_uniconify);
-   eda_client->client_stick.notify = _desk_area_cb_client_stick;
-   e_client_stick_listener_add(ec, &eda_client->client_stick);
-   eda_client->client_unstick.notify = _desk_area_cb_client_unstick;
-   e_client_unstick_listener_add(ec, &eda_client->client_unstick);
-   eda_client->client_maximize.notify = _desk_area_cb_client_maximize;
-   e_client_maximize_listener_add(ec, &eda_client->client_maximize);
-   eda_client->client_maximize_done.notify = _desk_area_cb_client_maximize_done;
-   e_client_maximize_done_listener_add(ec, &eda_client->client_maximize_done);
-   eda_client->client_unmaximize.notify = _desk_area_cb_client_unmaximize;
-   e_client_unmaximize_listener_add(ec, &eda_client->client_unmaximize);
-   eda_client->client_unmaximize_done.notify = _desk_area_cb_client_unmaximize_done;
-   e_client_unmaximize_done_listener_add(ec, &eda_client->client_unmaximize_done);
-   eda_client->client_activate_done.notify = _desk_area_cb_client_activate_done;
-   e_client_activate_done_listener_add(ec, &eda_client->client_activate_done);
-   eda_client->client_stay_within_margin.notify = _desk_area_cb_client_stay_within_margin;
-   e_client_stay_within_margin_listener_add(ec, &eda_client->client_stay_within_margin);
-   eda_client->client_mouse_move.notify = _desk_area_cb_client_mouse_move;
-   e_client_mouse_move_listener_add(ec, &eda_client->client_mouse_move);
-   eda_client->client_resize_end.notify = _desk_area_cb_client_resize_end;
-   e_client_resize_end_listener_add(ec, &eda_client->client_resize_end);
-
-   // e_comp_object listeners
-   eda_client->comp_object_lower.notify = _desk_area_cb_comp_object_lower;
-   e_comp_object_lower_listener_add(ec->frame, &eda_client->comp_object_lower);
-   eda_client->comp_object_raise.notify = _desk_area_cb_comp_object_raise;
-   e_comp_object_raise_listener_add(ec->frame, &eda_client->comp_object_raise);
-   eda_client->comp_object_set_layer.notify = _desk_area_cb_comp_object_set_layer;
-   e_comp_object_set_layer_listener_add(ec->frame, &eda_client->comp_object_set_layer);
-   eda_client->comp_object_stack_above.notify = _desk_area_cb_comp_object_stack_above;
-   e_comp_object_stack_above_listener_add(ec->frame, &eda_client->comp_object_stack_above);
-   eda_client->comp_object_stack_below.notify = _desk_area_cb_comp_object_stack_below;
-   e_comp_object_stack_below_listener_add(ec->frame, &eda_client->comp_object_stack_below);
-
-   // needs ec->comp_data listeners
-   if (ec->comp_data)
-     {
-        eda_client->redirect.notify = _desk_area_cb_client_redirect;
-        e_client_redirect_listener_add(ec, &eda_client->redirect);
-        eda_client->ping.notify = _desk_area_cb_client_ping;
-        e_client_ping_listener_add(ec, &eda_client->ping);
-        eda_client->kill_request.notify = _desk_area_cb_client_kill_request;
-        e_client_kill_request_listener_add(ec, &eda_client->kill_request);
-        eda_client->delete_request.notify = _desk_area_cb_client_delete_request;
-        e_client_delete_request_listener_add(ec, &eda_client->delete_request);
-        eda_client->comp_object_resize.notify = _desk_area_cb_comp_object_resize;
-        e_comp_object_resize_listener_add(ec->frame, &eda_client->comp_object_resize);
-        eda_client->comp_object_color_set.notify = _desk_area_cb_comp_object_color_set;
-        e_comp_object_color_set_listener_add(ec->frame, &eda_client->comp_object_color_set);
-     }
-
-   _e_desk_area_client_data_set(eda, ec);
-   _e_desk_area_smart_client_add(eda->smart_obj, ec);
+   wl_signal_emit(&PRI(eda)->events.client_add, ec);
 
    return EINA_TRUE;
 }
@@ -2825,8 +269,6 @@ e_desk_area_ec_add(E_Desk_Area *eda, E_Client *ec)
 E_API void
 e_desk_area_ec_remove(E_Desk_Area *eda, E_Client *ec)
 {
-   E_Desk_Area_Private_Client *eda_client;
-
    E_OBJECT_CHECK(eda);
    E_OBJECT_TYPE_CHECK(eda, E_DESK_AREA_TYPE);
    E_OBJECT_CHECK(ec);
@@ -2836,10 +278,7 @@ e_desk_area_ec_remove(E_Desk_Area *eda, E_Client *ec)
 
    ELOGF("EDA", "CLIENT REMOVE. desk_area:%p", ec, eda);
 
-   eda_client = _e_desk_area_private_client_get(ec);
-   EINA_SAFETY_ON_NULL_RETURN(eda_client);
-
-   _e_desk_area_private_client_del(eda_client);
+   wl_signal_emit(&PRI(eda)->events.client_del, ec);
 }
 
 // for debug
@@ -2864,147 +303,115 @@ e_desk_area_info_print(E_Desk_Area *eda)
    ELOGF("EDG_INFO", "===========================================", NULL);
 }
 
-static void
-_e_desk_area_hooks_clean(void)
-{
-   Eina_Inlist *l;
-   E_Desk_Area_Hook *dgh;
-   unsigned int x;
-
-   for (x = 0; x < E_DESK_AREA_HOOK_LAST; x++)
-     EINA_INLIST_FOREACH_SAFE(_e_desk_area_hooks[x], l, dgh)
-       {
-          if (!dgh->delete_me) continue;
-          _e_desk_area_hooks[x] = eina_inlist_remove(_e_desk_area_hooks[x], EINA_INLIST_GET(dgh));
-          free(dgh);
-       }
-
-   _e_desk_area_hooks_delete = 0;
-}
-
-static Eina_Bool
-_e_desk_area_hook_call(E_Desk_Area_Hook_Point hookpoint, E_Desk_Area *desk_area, void *data)
+EINTERN E_Client *
+e_desk_area_top_ec_get(E_Desk_Area *eda)
 {
-   E_Desk_Area_Hook *dgh;
+   E_Desk_Area_Data_EC_Get get_data = {};
 
-   e_object_ref(E_OBJECT(desk_area));
-   _e_desk_area_hooks_walking++;
-   EINA_INLIST_FOREACH(_e_desk_area_hooks[hookpoint], dgh)
-     {
-        if (dgh->delete_me) continue;
-        dgh->func(dgh->data, desk_area, data);
-     }
-   _e_desk_area_hooks_walking--;
-   if ((_e_desk_area_hooks_walking == 0) && (_e_desk_area_hooks_delete > 0))
-     _e_desk_area_hooks_clean();
+   EINA_SAFETY_ON_NULL_RETURN_VAL(eda, NULL);
 
-   return !!e_object_unref(E_OBJECT(desk_area));
-}
+   get_data.eda = eda;
+   wl_signal_emit(&PRI(eda)->events.top_ec_get, &get_data);
 
-EINTERN Eina_Bool
-e_desk_area_hook_call(E_Desk_Area *eda, E_Desk_Area_Hook_Point hookpoint, void *data)
-{
-   return _e_desk_area_hook_call(hookpoint, eda, data);
+   return get_data.ec;
 }
 
-E_API E_Desk_Area_Hook *
-e_desk_area_hook_add(E_Desk_Area_Hook_Point hookpoint,
-      E_Desk_Area_Hook_Cb func, const void *data)
+EINTERN E_Client *
+e_desk_area_bottom_ec_get(E_Desk_Area *eda)
 {
-   E_Desk_Area_Hook *dgh;
+   E_Desk_Area_Data_EC_Get get_data = {};
 
-   EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_DESK_AREA_HOOK_LAST, NULL);
-   dgh = E_NEW(E_Desk_Area_Hook, 1);
-   if (!dgh) return NULL;
-
-   dgh->hookpoint = hookpoint;
-   dgh->func = func;
-   dgh->data = (void*)data;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(eda, NULL);
 
-   _e_desk_area_hooks[hookpoint] =
-      eina_inlist_append(_e_desk_area_hooks[hookpoint], EINA_INLIST_GET(dgh));
+   get_data.eda = eda;
+   wl_signal_emit(&PRI(eda)->events.bottom_ec_get, &get_data);
 
-   return dgh;
+   return get_data.ec;
 }
 
-E_API void
-e_desk_area_hook_del(E_Desk_Area_Hook * dgh)
+EINTERN Eina_Bool
+e_desk_area_has_ec(E_Desk_Area *eda, E_Client *ec)
 {
-   dgh->delete_me = 1;
-
-   if (_e_desk_area_hooks_walking == 0)
-     {
-        _e_desk_area_hooks[dgh->hookpoint] =
-            eina_inlist_remove(_e_desk_area_hooks[dgh->hookpoint], EINA_INLIST_GET(dgh));
-        free(dgh);
-     }
-   else
-     _e_desk_area_hooks_delete++;
-}
+   E_Desk_Area_Data_Has_EC data = {0,};
 
-EINTERN E_Client *
-e_desk_area_top_ec_get(E_Desk_Area *eda)
-{
-   E_Client *ec;
-   unsigned int x;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(eda, EINA_FALSE);
 
-   EINA_SAFETY_ON_NULL_RETURN_VAL(eda, NULL);
+   data.eda = eda;
+   data.ec = ec;
 
-   e_comp_ec_list_lock();;
+   wl_signal_emit(&PRI(eda)->events.has_ec, &data);
 
-   for (x = e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); x >= e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x--)
-     {
-        if (!eda->layers[x].clients) continue;
-
-        EINA_INLIST_REVERSE_FOREACH(eda->layers[x].clients, ec)
-          if (!e_object_is_del(E_OBJECT(ec)))
-            {
-               e_comp_ec_list_unlock();
-               return ec;
-            }
-     }
+   return data.result;
+}
 
-   e_comp_ec_list_unlock();
 
-   return NULL;
+EINTERN void
+e_desk_area_geometry_set_listener_add(E_Desk_Area *eda, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.geometry_set, listener);
 }
 
-EINTERN E_Client *
-e_desk_area_bottom_ec_get(E_Desk_Area *eda)
+EINTERN void
+e_desk_area_layer_set_listener_add(E_Desk_Area *eda, struct wl_listener *listener)
 {
-   E_Client *ec;
-   unsigned int x;
+   API_ENTRY;
+   wl_signal_add(&priv->events.layer_set, listener);
+}
 
-   EINA_SAFETY_ON_NULL_RETURN_VAL(eda, NULL);
+EINTERN void
+e_desk_area_activate_listener_add(E_Desk_Area *eda, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.activate, listener);
+}
 
-   e_comp_ec_list_lock();;
+EINTERN void
+e_desk_area_raise_listener_add(E_Desk_Area *eda, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.raise, listener);
+}
 
-   for (x = e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x <= e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); x++)
-     {
-        if (!eda->layers[x].clients) continue;
-
-        EINA_INLIST_FOREACH(eda->layers[x].clients, ec)
-          if (!e_object_is_del(E_OBJECT(ec)))
-            {
-               e_comp_ec_list_unlock();
-               return ec;
-            }
-     }
+EINTERN void
+e_desk_area_lower_listener_add(E_Desk_Area *eda, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.lower, listener);
+}
 
-   e_comp_ec_list_unlock();
+EINTERN void
+e_desk_area_top_ec_get_listener_add(E_Desk_Area *eda, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.top_ec_get, listener);
+}
 
-   return NULL;
+EINTERN void
+e_desk_area_bottom_ec_get_listener_add(E_Desk_Area *eda, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.bottom_ec_get, listener);
 }
 
-EINTERN Eina_Bool
-e_desk_area_has_ec(E_Desk_Area *eda, E_Client *ec)
+EINTERN void
+e_desk_area_has_ec_listener_add(E_Desk_Area *eda, struct wl_listener *listener)
 {
-   E_Desk_Area *data;
+   API_ENTRY;
+   wl_signal_add(&priv->events.has_ec, listener);
+}
 
-   EINA_SAFETY_ON_NULL_RETURN_VAL(eda, EINA_FALSE);
+EINTERN void
+e_desk_area_client_add_listener_add(E_Desk_Area *eda, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.client_add, listener);
+}
 
-   data = e_view_data_get(e_view_client_view_get(e_client_view_get(ec)), DESK_AREA_EC_DATA_KEY);
-   if (data == eda) return EINA_TRUE;
 
-   return EINA_FALSE;
+EINTERN void
+e_desk_area_client_del_listener_add(E_Desk_Area *eda, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.client_del, listener);
 }
index 1c3592b15f9f4769ec37e0889a117919b6fb33d9..057391a45ab136107a5f6b4b6cc51db0b7b910b9 100644 (file)
@@ -7,6 +7,22 @@
 #include <wayland-server.h>
 #include <libds-tizen/screen.h>
 
+#define E_DESK_AREA_TYPE 0xE0b01006
+
+typedef enum _E_Desk_Area_Client_Layer
+{
+   E_DESK_AREA_CLIENT_LAYER_DESKTOP,
+   E_DESK_AREA_CLIENT_LAYER_BELOW,
+   E_DESK_AREA_CLIENT_LAYER_NORMAL,
+   E_DESK_AREA_CLIENT_LAYER_ABOVE,
+   E_DESK_AREA_CLIENT_LAYER_NOTIFICATION_LOW,
+   E_DESK_AREA_CLIENT_LAYER_NOTIFICATION_NORMAL,
+   E_DESK_AREA_CLIENT_LAYER_NOTIFICATION_HIGH,
+   E_DESK_AREA_CLIENT_LAYER_NOTIFICATION_TOP,
+   E_DESK_AREA_CLIENT_LAYER_ALERT,
+   E_DESK_AREA_CLIENT_LAYER_MAX,
+} E_Desk_Area_Client_Layer;
+
 struct _E_Desk_Area
 {
    E_Object             e_obj_inherit;
@@ -42,6 +58,19 @@ struct _E_Desk_Area
 #endif // CLIENT_DEL_STACK_ISSUE
 };
 
+typedef struct _E_Desk_Area_Data_EC_Get
+{
+   E_Desk_Area *eda;
+   E_Client *ec;
+} E_Desk_Area_Data_EC_Get;
+
+typedef struct _E_Desk_Area_Data_Has_EC
+{
+   E_Desk_Area *eda;
+   E_Client *ec;
+   Eina_Bool result;
+} E_Desk_Area_Data_Has_EC;
+
 EINTERN int e_desk_area_init(void);
 EINTERN int e_desk_area_shutdown(void);
 
@@ -56,6 +85,16 @@ EINTERN Eina_Bool    e_desk_area_has_ec(E_Desk_Area *eda, E_Client *ec);
 // for debug
 EINTERN void          e_desk_area_info_print(E_Desk_Area *eda);
 
-EINTERN Eina_Bool        e_desk_area_hook_call(E_Desk_Area *eda, E_Desk_Area_Hook_Point hookpoint, void *data);
+
+EINTERN void e_desk_area_geometry_set_listener_add(E_Desk_Area *eda, struct wl_listener *listener);
+EINTERN void e_desk_area_layer_set_listener_add(E_Desk_Area *eda, struct wl_listener *listener);
+EINTERN void e_desk_area_activate_listener_add(E_Desk_Area *eda, struct wl_listener *listener);
+EINTERN void e_desk_area_raise_listener_add(E_Desk_Area *eda, struct wl_listener *listener);
+EINTERN void e_desk_area_lower_listener_add(E_Desk_Area *eda, struct wl_listener *listener);
+EINTERN void e_desk_area_top_ec_get_listener_add(E_Desk_Area *eda, struct wl_listener *listener);
+EINTERN void e_desk_area_bottom_ec_get_listener_add(E_Desk_Area *eda, struct wl_listener *listener);
+EINTERN void e_desk_area_has_ec_listener_add(E_Desk_Area *eda, struct wl_listener *listener);
+EINTERN void e_desk_area_client_add_listener_add(E_Desk_Area *eda, struct wl_listener *listener);
+EINTERN void e_desk_area_client_del_listener_add(E_Desk_Area *eda, struct wl_listener *listener);
 
 #endif
index 46c570dc5f1bb2cc7c67512b16d876f78fb34ba2..7b0479c70c5268a780f4cdd1862beb7bfba6c7e0 100644 (file)
@@ -25,6 +25,7 @@
 #include "e_display_intern.h"
 #include "e_policy_zone_intern.h"
 #include "e_policy_desk_intern.h"
+#include "e_policy_desk_area_intern.h"
 #include "e_zone_intern.h"
 #include "e_tizen_screen_manager_intern.h"
 
@@ -699,6 +700,7 @@ _e_comp_screen_screen_policy_setup(void)
    Eina_List *l;
 
    e_policy_desk_init();
+   e_policy_desk_area_init();
 
    screens = (Eina_List *)_e_comp_screen_e_screens_get(e_comp_screen_get());
    if (!screens) return EINA_FALSE;
@@ -1088,6 +1090,8 @@ e_comp_screen_shutdown()
 
    if (comp_screen->bufmgr) tbm_bufmgr_deinit(comp_screen->bufmgr);
 
+   e_policy_desk_area_shutdown();
+   e_policy_desk_shutdown();
    e_server_shutdown();
    e_input_shutdown();
 
index 5b705339e0043fd7ea373fab3e75f7a1f7a4bcbe..8da2dec853c66e818bd5025d7043d154df16e6ec 100644 (file)
@@ -1,4 +1,5 @@
 #include "e_policy_desk_intern.h"
+#include "e_policy_desk_area_intern.h"
 
 #include "e_policy_intern.h"
 #include "e_policy_softkey_intern.h"
@@ -739,7 +740,6 @@ _e_policy_desk_cb_desk_free(struct wl_listener *listener, void *data)
         desk->desk_area.list[i] = NULL;
      }
 
-   e_desk_desk_area_del(desk, desk->desk_area.base);
    desk->desk_area.base = NULL;
    desk->desk_area.active = NULL;
 
@@ -1851,6 +1851,8 @@ e_policy_desk_add(E_Desk *desk)
 
    eina_hash_add(hash_policy_desks, &desk, pd);
 
+   e_policy_desk_area_new(desk->desk_area.base);
+
    /* add clients */
    E_CLIENT_FOREACH(ec)
      {
index d16441b194ffd853992805d2144f7f778a02d49b..c9ad4366dd98220c6025c50cd53737a4f14a6e2d 100644 (file)
+#include "e_desk_area_intern.h"
 #include "e_policy_desk_area_intern.h"
+#include "e_client_intern.h"
+#include "e_comp_object_intern.h"
+#include "e_comp_canvas_intern.h"
+#include "e_comp_wl_rsm_intern.h"
+#include "e_policy_intern.h"
+#include "e_maximize_intern.h"
+#include "e_policy_visibility_intern.h"
+#include "e_input_backend_intern.h"
+#include "e_comp_input_intern.h"
+#include "e_comp_wl_subsurface_intern.h"
+#include "e_zone_intern.h"
+#include "e_desk_intern.h"
+#include "e_utils_intern.h"
+#include "e_comp_intern.h"
+#include "e_comp_wl_intern.h"
+#include "e_input_thread_client_intern.h"
+#include "e_view_intern.h"
+#include "e_view_client_intern.h"
 
+
+typedef struct _E_Policy_Desk_Area_Private_Client  E_Policy_Desk_Area_Private_Client;
+
+#define POLICY_DESK_AREA_EC_DATA_KEY  "E_Policy_Desk_Area_Client"
 struct _E_Policy_Desk_Area
 {
    E_Desk_Area *desk_area;
+
+   struct wl_listener geometry_set;
+   struct wl_listener layer_set;
+   struct wl_listener activate;
+   struct wl_listener raise;
+   struct wl_listener lower;
+   struct wl_listener top_ec_get;
+   struct wl_listener bottom_ec_get;
+   struct wl_listener has_ec;
+
+   struct wl_listener client_add;
+   struct wl_listener client_del;
+};
+
+struct _E_Policy_Desk_Area_Private_Client
+{
+   E_Desk_Area *eda;
+   E_Client *ec;
+
+   // client listeners
+   struct wl_listener client_destroy;
+   struct wl_listener client_get_above;
+   struct wl_listener client_get_below;
+   struct wl_listener client_get_visible_above;
+   struct wl_listener client_get_visible_below;
+   struct wl_listener client_subsurface_stack_update;
+   struct wl_listener client_fullscreen;
+   struct wl_listener client_unfullscreen;
+   struct wl_listener client_focus_set;
+   struct wl_listener client_iconify;
+   struct wl_listener client_uniconify;
+   struct wl_listener client_stick;
+   struct wl_listener client_unstick;
+   struct wl_listener client_maximize;
+   struct wl_listener client_maximize_done;
+   struct wl_listener client_unmaximize;
+   struct wl_listener client_unmaximize_done;
+   struct wl_listener client_activate_done;
+   struct wl_listener client_stay_within_margin;
+   struct wl_listener client_mouse_move;
+   struct wl_listener client_resize_end;
+   struct wl_listener delete_request;
+   struct wl_listener kill_request;
+   struct wl_listener ping;
+   struct wl_listener redirect;
+
+   // comp_object listeners
+   struct wl_listener comp_object_raise;
+   struct wl_listener comp_object_lower;
+   struct wl_listener comp_object_set_layer;
+   struct wl_listener comp_object_stack_above;
+   struct wl_listener comp_object_stack_below;
+   struct wl_listener comp_object_resize;
+   struct wl_listener comp_object_color_set;
+};
+
+struct _E_Policy_Desk_Area_Smart_Data
+{
+   Evas_Object_Smart_Clipped_Data base;
+
+   E_Desk_Area *eda;
+
+   Eina_List      *clients;
+   Eina_List      *handlers;
+};
+
+Eina_Hash *hash_policy_desk_area;
+
+static int _e_policy_desk_area_hooks_delete = 0;
+static int _e_policy_desk_area_hooks_walking = 0;
+
+static Eina_Inlist *_e_policy_desk_area_hooks[] =
+{
+   [E_DESK_AREA_HOOK_SET_APPID] = NULL,
+};
+
+struct _E_Desk_Area_Hook
+{
+   EINA_INLIST;
+   E_Desk_Area_Hook_Point hookpoint;
+   E_Desk_Area_Hook_Cb    func;
+   void                  *data;
+   unsigned char          delete_me : 1;
 };
+
+static void        _e_policy_desk_area_hooks_clean(void);
+static Eina_Bool   _e_policy_desk_area_hook_call(E_Desk_Area_Hook_Point hookpoint, E_Desk_Area *desk_area, void *appid);
+static void        _e_policy_desk_area_private_client_del(E_Policy_Desk_Area_Private_Client *eda_client);
+static void        _e_policy_desk_area_configure_send(E_Client *ec, Eina_Bool edges, Eina_Bool send_size);
+static void        _e_comp_object_layer_update(E_Desk_Area *eda, Evas_Object *obj, Evas_Object *above, Evas_Object *below);
+
+
+typedef struct _E_Policy_Desk_Area_Smart_Data E_Policy_Desk_Area_Smart_Data;
+typedef void (*E_Policy_Desk_Area_Stack_Func)(Evas_Object *obj, Evas_Object *stack);
+
+#define E_POLICY_DESK_AREA_SMART_DATA_GET(obj, ptr)                        \
+    E_Policy_Desk_Area_Smart_Data *ptr = evas_object_smart_data_get(obj);
+
+#define E_POLICY_DESK_AREA_SMART_DATA_GET_OR_RETURN(obj, ptr)              \
+    E_POLICY_DESK_AREA_SMART_DATA_GET(obj, ptr);                           \
+    if (!ptr) return
+
+
+EVAS_SMART_SUBCLASS_NEW(E_POLICY_DESK_AREA_SMART_OBJ_TYPE, _e_policy_desk_area,
+                        Evas_Smart_Class, Evas_Smart_Class,
+                        evas_object_smart_clipped_class_get, NULL)
+
+static void
+_e_policy_desk_area_hooks_clean(void)
+{
+   Eina_Inlist *l;
+   E_Desk_Area_Hook *dgh;
+   unsigned int x;
+
+   for (x = 0; x < E_DESK_AREA_HOOK_LAST; x++)
+     EINA_INLIST_FOREACH_SAFE(_e_policy_desk_area_hooks[x], l, dgh)
+       {
+          if (!dgh->delete_me) continue;
+          _e_policy_desk_area_hooks[x] = eina_inlist_remove(_e_policy_desk_area_hooks[x], EINA_INLIST_GET(dgh));
+          free(dgh);
+       }
+
+   _e_policy_desk_area_hooks_delete = 0;
+}
+
+static Eina_Bool
+_e_policy_desk_area_hook_call(E_Desk_Area_Hook_Point hookpoint, E_Desk_Area *desk_area, void *data)
+{
+   E_Desk_Area_Hook *dgh;
+
+   e_object_ref(E_OBJECT(desk_area));
+   _e_policy_desk_area_hooks_walking++;
+   EINA_INLIST_FOREACH(_e_policy_desk_area_hooks[hookpoint], dgh)
+     {
+        if (dgh->delete_me) continue;
+        dgh->func(dgh->data, desk_area, data);
+     }
+   _e_policy_desk_area_hooks_walking--;
+   if ((_e_policy_desk_area_hooks_walking == 0) && (_e_policy_desk_area_hooks_delete > 0))
+     _e_policy_desk_area_hooks_clean();
+
+   return !!e_object_unref(E_OBJECT(desk_area));
+}
+
+EINTERN Eina_Bool
+e_policy_desk_area_hook_call(E_Desk_Area *eda, E_Desk_Area_Hook_Point hookpoint, void *data)
+{
+   return _e_policy_desk_area_hook_call(hookpoint, eda, data);
+}
+
+E_API E_Desk_Area_Hook *
+e_desk_area_hook_add(E_Desk_Area_Hook_Point hookpoint,
+                     E_Desk_Area_Hook_Cb func, const void *data)
+{
+   E_Desk_Area_Hook *dgh;
+
+   EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_DESK_AREA_HOOK_LAST, NULL);
+   dgh = E_NEW(E_Desk_Area_Hook, 1);
+   if (!dgh) return NULL;
+
+   dgh->hookpoint = hookpoint;
+   dgh->func = func;
+   dgh->data = (void*)data;
+
+   _e_policy_desk_area_hooks[hookpoint] =
+       eina_inlist_append(_e_policy_desk_area_hooks[hookpoint], EINA_INLIST_GET(dgh));
+
+   return dgh;
+}
+
+E_API void
+e_desk_area_hook_del(E_Desk_Area_Hook * dgh)
+{
+   dgh->delete_me = 1;
+
+   if (_e_policy_desk_area_hooks_walking == 0)
+     {
+        _e_policy_desk_area_hooks[dgh->hookpoint] =
+            eina_inlist_remove(_e_policy_desk_area_hooks[dgh->hookpoint], EINA_INLIST_GET(dgh));
+        free(dgh);
+     }
+   else
+     _e_policy_desk_area_hooks_delete++;
+}
+
+static void
+_e_policy_desk_area_smart_add(Evas_Object *obj)
+{
+   EVAS_SMART_DATA_ALLOC(obj, E_Policy_Desk_Area_Smart_Data);
+
+   _e_policy_desk_area_parent_sc->add(obj);
+}
+
+static void
+_e_policy_desk_area_smart_del(Evas_Object *obj)
+{
+   _e_policy_desk_area_parent_sc->del(obj);
+
+   E_POLICY_DESK_AREA_SMART_DATA_GET_OR_RETURN(obj, sd);
+
+   E_FREE_LIST(sd->handlers, ecore_event_handler_del);
+   eina_list_free(sd->clients);
+   free(sd);
+
+   evas_object_smart_data_set(obj, NULL);
+}
+
+static void
+_e_policy_desk_area_smart_member_add(Evas_Object *obj, Evas_Object *child)
+{
+   _e_policy_desk_area_parent_sc->member_add(obj, child);
+}
+
+static void
+_e_policy_desk_area_smart_member_del(Evas_Object *obj, Evas_Object *child)
+{
+   _e_policy_desk_area_parent_sc->member_del(obj, child);
+}
+
+static void
+_e_policy_desk_area_smart_set_user(Evas_Smart_Class *sc)
+{
+   sc->add = _e_policy_desk_area_smart_add;
+   sc->del = _e_policy_desk_area_smart_del;
+   sc->member_add = _e_policy_desk_area_smart_member_add;
+   sc->member_del = _e_policy_desk_area_smart_member_del;
+}
+
+static Eina_Bool
+_e_policy_desk_area_smart_client_find(E_Policy_Desk_Area_Smart_Data *sd, E_Client *ec)
+{
+   Eina_List *l;
+   E_Client *temp_ec;
+
+   EINA_LIST_FOREACH(sd->clients, l, temp_ec)
+     {
+        if (temp_ec == ec) return EINA_TRUE;
+     }
+
+   return EINA_FALSE;
+}
+
+static void
+_e_policy_desk_area_smart_client_add(Evas_Object *obj, E_Client *ec)
+{
+   E_POLICY_DESK_AREA_SMART_DATA_GET_OR_RETURN(obj, sd);
+
+   if (_e_policy_desk_area_smart_client_find(sd, ec))
+     return;
+
+   sd->clients = eina_list_append(sd->clients, ec);
+
+   evas_object_smart_changed(obj);
+}
+
+static void
+_e_policy_desk_area_smart_client_del(Evas_Object *obj, E_Client *ec)
+{
+   E_POLICY_DESK_AREA_SMART_DATA_GET_OR_RETURN(obj, sd);
+
+   if (!_e_policy_desk_area_smart_client_find(sd, ec))
+     return;
+
+   sd->clients = eina_list_remove(sd->clients, ec);
+
+   evas_object_smart_member_del(ec->frame);
+
+   evas_object_smart_changed(obj);
+}
+
+static void
+_e_policy_desk_area_smart_init(E_Desk_Area *eda)
+{
+   eda->smart_obj = evas_object_smart_add(e_comp_evas_get(), _e_policy_desk_area_smart_class_new());
+
+   E_POLICY_DESK_AREA_SMART_DATA_GET_OR_RETURN(eda->smart_obj, sd);
+
+   sd->eda = eda;
+}
+
+
+static void
+_e_policy_desk_area_active_change(E_Desk_Area *eda, E_Desk *desk)
+{
+   E_Desk_Area *prev_active_edg;
+
+   if (!desk) return;
+
+   prev_active_edg = e_desk_desk_area_active_get(desk);
+   if (prev_active_edg == eda) return;
+
+   // 1. reset current active eda info
+   if (prev_active_edg)
+     prev_active_edg->active = EINA_FALSE;
+
+   // 2. set new active eda info
+   if (eda)
+     {
+        eda->active = EINA_TRUE;
+        e_desk_desk_area_active_set(desk, eda);
+     }
+   else
+     {
+        e_desk_desk_area_active_set(desk, NULL);
+     }
+}
+
+
+static void
+_e_policy_desk_area_client_data_del(E_Client *ec)
+{
+   e_view_data_del(e_view_client_view_get(e_client_view_get(ec)), POLICY_DESK_AREA_EC_DATA_KEY);
+}
+
+static void
+_e_policy_desk_area_client_data_set(E_Policy_Desk_Area *pda, E_Client *ec)
+{
+   E_Desk_Area *eda = pda->desk_area;
+   E_Desk_Area *data;
+
+   data = e_view_data_get(e_view_client_view_get(e_client_view_get(ec)), POLICY_DESK_AREA_EC_DATA_KEY);
+   if (data)
+     {
+        if (data == eda)
+          {
+             ELOGF("EDA", "EC is already added to desk_area_id:%d", ec, eda->id);
+             return;
+          }
+
+        _e_policy_desk_area_client_data_del(ec);
+     }
+
+   e_view_data_set(e_view_client_view_get(e_client_view_get(ec)), POLICY_DESK_AREA_EC_DATA_KEY, eda);
+}
+
+static void
+_e_policy_desk_area_cb_geometry_set(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area *pda;
+
+   pda = wl_container_of(listener, pda, geometry_set);
+
+   ;// Do something
+}
+
+static void
+_e_policy_desk_area_cb_layer_set(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area *pda;
+
+   pda = wl_container_of(listener, pda, layer_set);
+
+   ;// Do something
+}
+
+static void
+_e_policy_desk_area_cb_activate(struct wl_listener *listener, void *data)
+{
+   E_Desk_Area *eda;
+   E_Policy_Desk_Area *pda;
+
+   pda = wl_container_of(listener, pda, activate);
+   eda = pda->desk_area;
+
+   e_desk_area_raise(eda);
+   _e_policy_desk_area_active_change(eda, eda->desk);
+}
+
+static void
+_e_policy_desk_area_cb_raise(struct wl_listener *listener, void *data)
+{
+   E_Desk_Area *eda;
+   E_Policy_Desk_Area *pda;
+
+   int i;
+   E_Client *ec;
+   Eina_List *l = NULL;
+   Eina_List *ll = NULL;
+
+   pda = wl_container_of(listener, pda, raise);
+   eda = pda->desk_area;
+
+   for (i=0; i<E_DESK_AREA_CLIENT_LAYER_MAX; i++)
+     {
+        EINA_LIST_REVERSE_FOREACH_SAFE(eda->ec_lists[i], l, ll, ec)
+          {
+             e_view_raise_to_top(e_view_client_view_get(e_client_view_get(ec)));
+          }
+     }
+}
+
+static void
+_e_policy_desk_area_cb_lower(struct wl_listener *listener, void *data)
+{
+   E_Desk_Area *eda;
+   E_Policy_Desk_Area *pda;
+
+   int i;
+   E_Client *ec;
+   Eina_List *l = NULL;
+   Eina_List *ll = NULL;
+
+   pda = wl_container_of(listener, pda, lower);
+   eda = pda->desk_area;
+
+   for (i=E_DESK_AREA_CLIENT_LAYER_MAX-1; i>=0; i--)
+     {
+        //EINA_LIST_FOREACH(eda->ec_lists[i], l, ec)
+        EINA_LIST_FOREACH_SAFE(eda->ec_lists[i], l, ll, ec)
+          {
+             e_view_lower_to_bottom(e_view_client_view_get(e_client_view_get(ec)));
+          }
+     }
+}
+
+static void
+_e_policy_desk_area_cb_top_ec_get(struct wl_listener *listener, void *data)
+{
+   E_Desk_Area_Data_EC_Get *get_data;
+   E_Desk_Area *eda;
+   E_Policy_Desk_Area *pda;
+
+   E_Client *ec;
+   unsigned int x;
+
+   pda = wl_container_of(listener, pda, top_ec_get);
+   get_data = (E_Desk_Area_Data_EC_Get *) data;
+   eda = get_data->eda;
+
+   e_comp_ec_list_lock();;
+
+   for (x = e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); x >= e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x--)
+     {
+        if (!eda->layers[x].clients) continue;
+
+        EINA_INLIST_REVERSE_FOREACH(eda->layers[x].clients, ec)
+            if (!e_object_is_del(E_OBJECT(ec)))
+              {
+                 e_comp_ec_list_unlock();
+                 get_data->ec = ec;
+                 return;
+              }
+     }
+
+   e_comp_ec_list_unlock();
+}
+
+static void
+_e_policy_desk_area_cb_bottom_ec_get(struct wl_listener *listener, void *data)
+{
+   E_Desk_Area_Data_EC_Get *get_data;
+   E_Desk_Area *eda;
+   E_Policy_Desk_Area *pda;
+
+   E_Client *ec;
+   unsigned int x;
+
+   pda = wl_container_of(listener, pda, bottom_ec_get);
+   get_data = (E_Desk_Area_Data_EC_Get *) data;
+   eda = get_data->eda;
+
+   e_comp_ec_list_lock();;
+
+   for (x = e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x <= e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); x++)
+     {
+        if (!eda->layers[x].clients) continue;
+
+        EINA_INLIST_FOREACH(eda->layers[x].clients, ec)
+            if (!e_object_is_del(E_OBJECT(ec)))
+              {
+                 e_comp_ec_list_unlock();
+                 get_data->ec = ec;
+                 return;
+              }
+     }
+
+   e_comp_ec_list_unlock();
+}
+
+static void
+_e_policy_desk_area_cb_has_ec(struct wl_listener *listener, void *data)
+{
+   E_Desk_Area_Data_Has_EC *has_ec_data = (E_Desk_Area_Data_Has_EC *) data;
+   E_Desk_Area *eda, *view_eda;
+   E_Client *ec;
+   E_Policy_Desk_Area *pda;
+
+   pda = wl_container_of(listener, pda, has_ec);
+   eda = has_ec_data->eda;
+   ec = has_ec_data->ec;
+
+   view_eda = e_view_data_get(e_view_client_view_get(e_client_view_get(ec)), POLICY_DESK_AREA_EC_DATA_KEY);
+   if (view_eda == eda) has_ec_data->result = EINA_TRUE;
+   else has_ec_data->result = EINA_FALSE;
+}
+
+
+static void
+_desk_area_cb_client_destroy(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Desk_Area *eda;
+   E_Client *ec;
+
+   eda_client = wl_container_of(listener, eda_client, client_destroy);
+   eda = eda_client->eda;
+   ec = eda_client->ec;
+
+   ELOGF("EDA", "CLIENT DESTROY. desk_area:%p", ec, eda);
+
+   if (ec->fullscreen)
+     {
+        eda->fullscreen_clients = eina_list_remove(eda->fullscreen_clients, ec);
+        if (!eda->fullscreen_clients)
+          e_comp_render_queue();
+     }
+
+   _e_policy_desk_area_private_client_del(eda_client);
+}
+
+static void
+_desk_area_cb_client_get_above(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Client_Data_Get_Above *get_above_data = data;
+   E_Desk_Area *eda;
+   E_Client *ec, *ec2;
+   unsigned int x;
+
+   eda_client = wl_container_of(listener, eda_client, client_get_above);
+   eda = eda_client->eda;
+   ec = eda_client->ec;
+
+   e_comp_ec_list_lock();
+
+   if (EINA_INLIST_GET(ec)->next) //check current layer
+     {
+        EINA_INLIST_FOREACH(EINA_INLIST_GET(ec)->next, ec2)
+          {
+             if (ec == ec2)
+               {
+                  ELOGF("FATAL", "CHECK the ec inlist next", ec);
+                  continue;
+               }
+             if (!e_object_is_del(E_OBJECT(ec2)))
+               {
+                  get_above_data->above_ec = ec2;
+                  e_comp_ec_list_unlock();
+                  return;
+               }
+          }
+     }
+
+   e_comp_ec_list_unlock();
+
+   if (ec->layer == E_LAYER_CLIENT_CURSOR) return;
+   if (e_util_client_layer_map(ec->layer) == 9999) return;
+
+   e_comp_ec_list_lock();;
+
+   /* go up the layers until we find one */
+   for (x = e_comp_canvas_layer_map(ec->layer) + 1; x <= e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); x++)
+     {
+        if (!eda->layers[x].clients) continue;
+
+        EINA_INLIST_FOREACH(eda->layers[x].clients, ec2)
+          {
+             if (ec == ec2)
+               {
+                  ELOGF("FATAL", "[eda:%p] EC exist above layer. ec layer_map:%d, cur layer_map:%d",
+                        ec, eda, e_comp_canvas_layer_map(ec->layer), x);
+                  continue;
+               }
+             if (!e_object_is_del(E_OBJECT(ec2)))
+               {
+                  get_above_data->above_ec = ec2;
+                  e_comp_ec_list_unlock();
+                  return;
+               }
+          }
+     }
+
+   e_comp_ec_list_unlock();
+}
+
+static void
+_desk_area_cb_client_get_below(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Client_Data_Get_Below *get_below_data = data;
+   E_Desk_Area *eda;
+   E_Client *ec, *ec2;
+   unsigned int x;
+   Eina_Inlist *l;
+   E_Layer ec_layer, ec_layer_cw;
+   int cw_layer;
+
+   eda_client = wl_container_of(listener, eda_client, client_get_below);
+   eda = eda_client->eda;
+   ec = eda_client->ec;
+
+   e_comp_ec_list_lock();
+
+   if (EINA_INLIST_GET(ec)->prev) //check current layer
+     {
+        for (l = EINA_INLIST_GET(ec)->prev; l; l = l->prev)
+          {
+             ec2 = EINA_INLIST_CONTAINER_GET(l, E_Client);
+             if (ec == ec2)
+               {
+                  ELOGF("FATAL", "CHECK the ec inlist prev", ec);
+                  continue;
+               }
+             if (!e_object_is_del(E_OBJECT(ec2)))
+               {
+                  get_below_data->below_ec = ec2;
+                  e_comp_ec_list_unlock();
+                  return;
+               }
+          }
+     }
+
+   e_comp_ec_list_unlock();
+
+   // check layer validation
+   ec_layer = ec->layer;
+   if (ec->layer_block || ec->layer_pending)
+     {
+        cw_layer = e_comp_object_layer_get(ec->frame);
+        if (cw_layer >= 0)
+          {
+             ec_layer_cw = e_comp_canvas_layer_map_to(cw_layer);
+             if (ec_layer != ec_layer_cw)
+               {
+                  ELOGF("EDA", "[eda:%p] LAYER is not same. USE obj layer! (ec->layer:%d, obj:%d). block:%d, pending:%d)",
+                        ec, eda, ec_layer, ec_layer_cw, ec->layer_block, ec->layer_pending);
+                  ec_layer = ec_layer_cw;
+               }
+          }
+     }
+
+   if (ec_layer == E_LAYER_CLIENT_DESKTOP) return;
+   if (e_util_client_layer_map(ec_layer) == 9999) return;
+
+   /* go down the layers until we find one */
+   x = e_comp_canvas_layer_map(ec_layer);
+   if (x > 0) x--;
+
+   e_comp_ec_list_lock();;
+
+   for (; x >= e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x--)
+     {
+        if (!eda->layers[x].clients) continue;
+
+        EINA_INLIST_REVERSE_FOREACH(eda->layers[x].clients, ec2)
+          {
+             if (ec == ec2)
+               {
+                  ELOGF("FATAL", "[eda:%p] EC exist below layer. ec layer_map:%d, cur layer_map:%d",
+                        ec, eda, e_comp_canvas_layer_map(ec_layer), x);
+                  continue;
+               }
+             if (!e_object_is_del(E_OBJECT(ec2)))
+               {
+                  get_below_data->below_ec = ec2;
+                  e_comp_ec_list_unlock();
+                  return;
+               }
+          }
+     }
+
+   e_comp_ec_list_unlock();
+}
+
+static void
+_desk_area_cb_client_get_visible_above(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Client_Data_Get_Visible_Above *get_visible_above_data = data;
+   E_Desk_Area *eda;
+   E_Client *ec, *ec2;
+   unsigned int x;
+
+   eda_client = wl_container_of(listener, eda_client, client_get_visible_above);
+   eda = eda_client->eda;
+   ec = eda_client->ec;
+
+   e_comp_ec_list_lock();
+
+   if (EINA_INLIST_GET(ec)->next) //check current layer
+     {
+        EINA_INLIST_FOREACH(EINA_INLIST_GET(ec)->next, ec2)
+          {
+             if (ec == ec2) continue;
+             if ((!e_object_is_del(E_OBJECT(ec2))) &&
+                 (!e_client_util_ignored_get(ec2)) &&
+                 (ec2->visible) &&
+                 (ec2->frame))
+               {
+                  get_visible_above_data->above_ec = ec2;
+                  e_comp_ec_list_unlock();
+                  return;
+               }
+          }
+     }
+
+   e_comp_ec_list_unlock();
+
+   if (ec->layer == E_LAYER_CLIENT_CURSOR) return;
+   if (e_util_client_layer_map(ec->layer) == 9999) return;
+
+   e_comp_ec_list_lock();;
+
+   /* go up the layers until we find one */
+   for (x = e_comp_canvas_layer_map(ec->layer) + 1; x <= e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); x++)
+     {
+        if (!eda->layers[x].clients) continue;
+        EINA_INLIST_FOREACH(eda->layers[x].clients, ec2)
+          {
+             if (ec == ec2) continue;
+             if ((!e_object_is_del(E_OBJECT(ec2))) &&
+                 (!e_client_util_ignored_get(ec2)) &&
+                 (ec2->visible) &&
+                 (ec2->frame))
+               {
+                  get_visible_above_data->above_ec = ec2;
+                  e_comp_ec_list_unlock();
+                  return;
+               }
+          }
+     }
+
+   e_comp_ec_list_unlock();
+}
+
+static void
+_desk_area_cb_client_get_visible_below(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Client_Data_Get_Visible_Below *get_visible_below_data = data;
+   E_Desk_Area *eda;
+   E_Client *ec, *ec2;
+   unsigned int x;
+   Eina_Inlist *l;
+   E_Layer ec_layer, ec_layer_cw;
+   int cw_layer;
+
+   eda_client = wl_container_of(listener, eda_client, client_get_visible_below);
+   eda = eda_client->eda;
+   ec = eda_client->ec;
+
+   e_comp_ec_list_lock();
+
+   if (EINA_INLIST_GET(ec)->prev) //check current layer
+     {
+        for (l = EINA_INLIST_GET(ec)->prev; l; l = l->prev)
+          {
+             ec2 = EINA_INLIST_CONTAINER_GET(l, E_Client);
+             if (ec == ec2) continue;
+             if ((!e_object_is_del(E_OBJECT(ec2))) &&
+                 (!e_client_util_ignored_get(ec2)) &&
+                 (ec2->visible) &&
+                 (ec2->frame))
+               {
+                  get_visible_below_data->below_ec = ec2;
+                  e_comp_ec_list_unlock();
+                  return;
+               }
+          }
+     }
+
+   e_comp_ec_list_unlock();
+
+   // check layer validation
+   ec_layer = ec->layer;
+   if (ec->layer_block || ec->layer_pending)
+     {
+        cw_layer = e_comp_object_layer_get(ec->frame);
+        if (cw_layer >= 0)
+          {
+             ec_layer_cw = e_comp_canvas_layer_map_to(cw_layer);
+             if (ec_layer != ec_layer_cw)
+               {
+                  ELOGF("EDA", "[eda:%p] LAYER is not same. USE obj layer! (ec->layer:%d, obj:%d). block:%d, pending:%d)",
+                        ec, eda, ec_layer, ec_layer_cw, ec->layer_block, ec->layer_pending);
+                  ec_layer = ec_layer_cw;
+               }
+          }
+     }
+
+   /* go down the layers until we find one */
+   if (e_comp_canvas_layer_map(ec->layer) > e_comp_canvas_layer_map(E_LAYER_MAX)) return;
+   x = e_comp_canvas_layer_map(ec->layer);
+   if (x > 0) x--;
+
+   for (; x >= e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x--)
+     {
+        if (!eda->layers[x].clients) continue;
+        EINA_INLIST_REVERSE_FOREACH(eda->layers[x].clients, ec2)
+          {
+             if (ec == ec2) continue;
+             if ((!e_object_is_del(E_OBJECT(ec2))) &&
+                 (!e_client_util_ignored_get(ec2)) &&
+                 (ec2->visible) &&
+                 (ec2->frame))
+               {
+                  get_visible_below_data->below_ec = ec2;
+                  return;
+               }
+          }
+     }
+}
+
+static void
+_desk_area_cb_client_subsurface_stack_update(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Desk_Area *eda;
+   E_Client *ec;
+
+   eda_client = wl_container_of(listener, eda_client, client_subsurface_stack_update);
+   eda = eda_client->eda;
+   ec = eda_client->ec;
+
+   //To update client stack list
+   if ((ec->comp_data->sub.data) &&
+       (ec->comp_data->sub.data->parent))
+     {
+        E_Client *parent;
+        Evas_Object *o;
+
+        parent = ec->comp_data->sub.data->parent;
+
+        if ((parent->comp_data->sub.list) &&
+            (eina_list_data_find(parent->comp_data->sub.list, ec)))
+          {
+             //stack above done
+             o = evas_object_below_get(ec->frame);
+             _e_comp_object_layer_update(eda, ec->frame, o, NULL);
+          }
+        else if ((parent->comp_data->sub.below_list) &&
+                 (eina_list_data_find(parent->comp_data->sub.below_list, ec)))
+          {
+             //stack below done
+             o = evas_object_above_get(ec->frame);
+             _e_comp_object_layer_update(eda, ec->frame, NULL, o);
+          }
+     }
+}
+
+static void
+_desk_area_cb_client_fullscreen(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Desk_Area *eda;
+   E_Client *ec;
+   E_Fullscreen fullscreen_policy;
+
+   eda_client = wl_container_of(listener, eda_client, client_fullscreen);
+   eda = eda_client->eda;
+   ec = eda_client->ec;
+
+   fullscreen_policy = *((E_Fullscreen *)data);
+
+   // "override = 1" means that ec is not controlled by wm policy
+   if (ec->override) return;
+
+   eda->fullscreen_clients = eina_list_append(eda->fullscreen_clients, ec);
+   ec->pre_res_change.valid = 0;
+
+   if (!ec->maximized)
+     {
+        ec->saved.x = ec->client.x - eda->x;
+        ec->saved.y = ec->client.y - eda->y;
+        ec->saved.w = ec->client.w;
+        ec->saved.h = ec->client.h;
+     }
+   ec->saved.maximized = ec->maximized;
+
+   if (fullscreen_policy == E_FULLSCREEN_RESIZE)
+     e_client_frame_geometry_set(ec, eda->x, eda->y, eda->w, eda->h);
+
+   if (!e_client_util_ignored_get(ec))
+     e_client_frame_update(ec);
+
+   e_view_client_fullscreen(e_client_view_get(ec));
+
+   if (ec->comp_data->shell.configure_send)
+     _e_policy_desk_area_configure_send(ec, 0, 1);
+
+   e_client_maximize_pre_set(ec, EINA_FALSE);
+}
+
+static void
+_desk_area_cb_client_unfullscreen(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Desk_Area *eda;
+   E_Client *ec;
+
+   eda_client = wl_container_of(listener, eda_client, client_unfullscreen);
+   eda = eda_client->eda;
+   ec = eda_client->ec;
+
+   // "override = 1" means that ec is not controlled by wm policy
+   if (ec->override) return;
+
+   ec->pre_res_change.valid = 0;
+   eda->fullscreen_clients = eina_list_remove(eda->fullscreen_clients, ec);
+
+   if (!e_client_util_ignored_get(ec))
+     e_client_frame_update(ec);
+
+   e_view_client_unfullscreen(e_client_view_get(ec));
+
+   if (ec->comp_data->shell.configure_send)
+     _e_policy_desk_area_configure_send(ec, 0, 0);
+
+   e_client_maximize_pre_set(ec, EINA_FALSE);
+
+   if (ec->maximized)
+     {
+        int saved_x = ec->saved.x;
+        int saved_y = ec->saved.y;
+        int saved_w = ec->saved.w;
+        int saved_h = ec->saved.h;
+        e_client_maximize_update(ec);
+        ec->saved.x = saved_x;
+        ec->saved.y = saved_y;
+        ec->saved.w = saved_w;
+        ec->saved.h = saved_h;
+     }
+   else
+     {
+        e_client_util_move_resize_without_frame(ec, eda->x + ec->saved.x,
+                                                eda->y + ec->saved.y,
+                                                ec->saved.w, ec->saved.h);
+     }
+
+   if (!eda->fullscreen_clients)
+     e_comp_render_queue();
+}
+
+static void
+_desk_area_cb_client_focus_set(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Desk_Area *eda;
+   E_Client *ec, *ec2;
+   Eina_List *l, *ll;
+
+   eda_client = wl_container_of(listener, eda_client, client_focus_set);
+   eda = eda_client->eda;
+   ec = eda_client->ec;
+
+   /* if there's any fullscreen non-parents on this desk, unfullscreen them */
+   EINA_LIST_FOREACH_SAFE(eda->fullscreen_clients, l, ll, ec2)
+     {
+        if (ec2 == ec) continue;
+        if (e_object_is_del(E_OBJECT(ec2))) continue;
+
+        /* but only if it's the same desk or one of the clients is sticky */
+        if (ec->sticky || ec2->sticky)
+          {
+             if (!eina_list_data_find(ec->transients, ec2))
+               e_client_unfullscreen(ec2);
+          }
+     }
+}
+
+static void
+_desk_area_cb_client_iconify(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Desk_Area *eda;
+   E_Client *ec;
+
+   eda_client = wl_container_of(listener, eda_client, client_iconify);
+   eda = eda_client->eda;
+   ec = eda_client->ec;
+
+   e_comp_wl_remote_surface_image_save(ec);
+
+   ec->iconic = 1;
+   ec->want_focus = ec->take_focus = 0;
+   ec->changes.visible = 0;
+   if (ec->fullscreen)
+     eda->fullscreen_clients = eina_list_remove(eda->fullscreen_clients, ec);
+   e_client_comp_hidden_set(ec, 1);
+   e_view_client_hide(e_client_view_get(ec));
+
+   e_client_iconify_event_send(ec);
+
+   if (e_config->transient.iconify)
+     {
+        E_Client *child;
+        Eina_List *list = eina_list_clone(ec->transients);
+
+        EINA_LIST_FREE(list, child)
+          {
+             if ((!child->exp_iconify.skip_iconify) &&
+                 (child->exp_iconify.type != E_ICONIFIED_TYPE_ICONIFY_BY_CLIENT) &&
+                 (e_client_is_parent_iconify_by_client(child)))
+               {
+                  ELOGF("EDA", "ICONIFY|iconify by parent iconify. parent:%p", child, ec);
+                  e_client_iconified_type_set(child, E_ICONIFIED_TYPE_PARENT_ICONIFY_BY_CLIENT);
+                  child->exp_iconify.by_client = 1;
+                  e_policy_client_iconic_state_change_send(child, 1);
+               }
+             else
+               ELOGF("EDA", "ICONIFY|SKIP iconify by parent iconify. parent:%p, skip_iconify:%d, iconify.type:%d",
+                     child, ec, child->exp_iconify.skip_iconify, e_client_iconified_type_get(child));
+             e_client_iconify(child);
+          }
+     }
+}
+
+static void
+_desk_area_cb_client_uniconify(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Desk_Area *eda;
+   E_Client *ec;
+   Eina_Bool not_raise;
+
+   eda_client = wl_container_of(listener, eda_client, client_uniconify);
+   eda = eda_client->eda;
+   ec = eda_client->ec;
+
+   e_comp_wl_remote_surface_image_save_cancel(ec);
+
+   not_raise = ec->exp_iconify.not_raise;
+
+   ec->exp_iconify.by_client = 0;
+   e_client_iconified_type_set(ec, E_ICONIFIED_TYPE_NONE);
+
+   if (e_config->transient.iconify)
+     {
+        E_Client *child;
+        Eina_List *list = eina_list_clone(ec->transients);
+
+        EINA_LIST_FREE(list, child)
+          {
+             if (e_client_transient_policy_get(child) == E_TRANSIENT_BELOW)
+               {
+                  child->exp_iconify.not_raise = not_raise;
+                  e_client_uniconify(child);
+               }
+          }
+     }
+
+   if (!not_raise)
+     e_client_raise(ec);
+
+   if (ec->internal)
+     {
+        ELOGF("EDA", "UNICONIFY|internal object force show. eda:%p", ec, eda);
+        e_view_client_show(e_client_view_get(ec));
+     }
+
+   if (ec->pixmap)
+     {
+        E_Comp_Wl_Client_Data *cdata;
+
+        cdata = e_client_cdata_get(ec);
+
+        if (e_pixmap_usable_get(ec->pixmap))
+          {
+             if (cdata && cdata->mapped)
+               {
+                  ELOGF("EDA", "UNICONIFY|object show. eda:%p frame_visible:%d(%d)",
+                        ec, eda, evas_object_visible_get(ec->frame), e_view_client_visible_get(e_client_view_get(ec)));
+                  e_view_client_show(e_client_view_get(ec));
+               }
+             else
+               {
+                  ELOGF("EDA", "UNICONIFY|object no show. currently unmapped. eda:%p",
+                        ec, eda);
+               }
+          }
+        else
+          {
+             if (!ec->exp_iconify.buffer_flush &&
+                 !ec->exp_iconify.deiconify_update)
+               {
+                  if (cdata && cdata->mapped)
+                    {
+                       ELOGF("EDA", "UNICONIFY|object show. no use buffer flush. eda:%p frame_visible:%d(%d)",
+                             ec, eda, evas_object_visible_get(ec->frame), e_view_client_visible_get(e_client_view_get(ec)));
+                       e_view_client_show(e_client_view_get(ec));
+                    }
+               }
+          }
+     }
+
+   e_client_comp_hidden_set(ec, 0);
+   ec->deskshow = ec->iconic = 0;
+
+#if 0 // focus should be set to the top window not uniconify window
+   if (ec->pixmap && e_pixmap_usable_get(ec->pixmap))
+     e_client_frame_focus_set(ec, EINA_TRUE);
+#endif
+
+   // send the uniconify event of a client
+   e_client_uniconify_event_send(ec);
+
+   if (e_config->transient.iconify)
+     {
+        E_Client *child;
+        Eina_List *list = eina_list_clone(ec->transients);
+
+        EINA_LIST_FREE(list, child)
+          {
+             if (e_client_transient_policy_get(child) == E_TRANSIENT_ABOVE)
+               {
+                  if (child->exp_iconify.type == E_ICONIFIED_TYPE_PARENT_ICONIFY_BY_CLIENT)
+                    e_policy_client_iconic_state_change_send(child, 0);
+                  child->exp_iconify.not_raise = not_raise;
+                  e_client_uniconify(child);
+               }
+          }
+     }
+
+   ec->exp_iconify.not_raise = 0;
+}
+
+static void
+_desk_area_cb_client_stick(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Client *ec;
+   E_Client *child;
+   Eina_List *list;
+
+   eda_client = wl_container_of(listener, eda_client, client_stick);
+   ec = eda_client->ec;
+
+   //TODO: No need to make a callback at desk_area.
+   //      Implement this at e_client_stick() function.
+   ec->sticky = 1;
+   ec->hidden = 0;
+
+   if (e_config->transient.desktop)
+     {
+        list = eina_list_clone(ec->transients);
+        EINA_LIST_FREE(list, child)
+          {
+             child->sticky = 1;
+             e_view_client_show(e_client_view_get(ec));
+          }
+     }
+}
+
+static void
+_desk_area_cb_client_unstick(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Client *ec;
+   E_Client *child;
+   Eina_List *list;
+
+   eda_client = wl_container_of(listener, eda_client, client_unstick);
+   ec = eda_client->ec;
+
+   //TODO: No need to make a callback at desk_area.
+   //      Implement this at e_client_unstick() function.
+   ec->hidden = ec->sticky = 0;
+
+   if (e_config->transient.desktop)
+     {
+        list = eina_list_clone(ec->transients);
+        EINA_LIST_FREE(list, child)
+          {
+             child->sticky = 0;
+          }
+     }
+}
+
+static void
+_e_desk_area_ec_maximize(E_Desk_Area *eda, E_Client *ec, E_Maximize max)
+{
+   int x1, yy1, x2, y2;
+   //FIXME: TODO: This is ugly. Use the x,y,w,y of this desk_area
+   int zx, zy, zw, zh;
+   Eina_Bool override = ec->maximize_override;
+
+   //FIXME: TODO: This is ugly. Use the x,y,w,y of this desk_area
+   // Obstacles of zone should be the desk_areas by the window manager policy.
+   // If the Obstacles assigns the desk_areas, this maximize callback does not need
+   // e_zone_desk_useful_geometry_get() function. Because the geometry of this desk_area
+   // already be calcuated by the obstacles desk_areas. Therefore, the zx, zy, zw, zh in
+   // this function can use the x,y,w,h of this desk_area.
+   E_Desk *desk;
+   E_Zone *zone;
+   desk = eda->desk;
+   zone = desk->zone;
+
+   zx = zy = zw = zh = 0;
+   ec->maximize_override = 1;
+
+   switch (max & E_MAXIMIZE_TYPE)
+     {
+       case E_MAXIMIZE_NONE:
+           /* Ignore */
+           break;
+
+       case E_MAXIMIZE_FULLSCREEN:
+       case E_MAXIMIZE_FILL:
+           if (ec->base_output_resolution.use)
+             {
+                zx = eda->x;
+                zy = eda->y;
+                zw = ec->base_output_resolution.w;
+                zh = ec->base_output_resolution.h;
+             }
+           else
+             {
+                //FIXME: TODO: This is ugly. Use the x,y,w,y of this desk_area
+                e_zone_desk_useful_geometry_get(zone, desk, &zx, &zy, &zw, &zh, EINA_FALSE);
+             }
+
+           switch (max & E_MAXIMIZE_DIRECTION)
+             {
+               case E_MAXIMIZE_BOTH:
+                   e_client_maximized_geometry_set(ec, zx, zy, zw, zh);
+                   break;
+
+               case E_MAXIMIZE_VERTICAL:
+                   e_client_maximized_geometry_set(ec, ec->x, zy, ec->w, zh);
+                   break;
+
+               case E_MAXIMIZE_HORIZONTAL:
+                   e_client_maximized_geometry_set(ec, zx, ec->y, zw, ec->h);
+                   break;
+
+               case E_MAXIMIZE_LEFT:
+                   e_client_maximized_geometry_set(ec, zx, zy, zw / 2, zh);
+                   break;
+
+               case E_MAXIMIZE_RIGHT:
+                   e_client_maximized_geometry_set(ec, zx + zw / 2, zy, zw / 2, zh);
+                   break;
+             }
+           break;
+
+       case E_MAXIMIZE_SMART:
+       case E_MAXIMIZE_EXPAND:
+           if (desk->visible)
+             {
+                // base_output_resolution
+                if (ec->base_output_resolution.use)
+                  {
+                     zx = eda->x;
+                     zy = eda->y;
+                     zw = ec->base_output_resolution.w;
+                     zh = ec->base_output_resolution.h;
+                  }
+                else
+                  {
+                     //FIXME: TODO: This is ugly. Use the x,y,w,y of this desk_area
+                     e_zone_desk_useful_geometry_get(zone, desk, &zx, &zy, &zw, &zh, EINA_TRUE);
+                  }
+             }
+           else
+             {
+                x1 = eda->x;
+                yy1 = eda->y;
+                x2 = eda->x + eda->w;
+                y2 = eda->y + eda->h;
+                e_maximize_client_shelf_fill(ec, &x1, &yy1, &x2, &y2, max);
+                zx = x1, zy = yy1;
+                zw = x2 - x1;
+                zh = y2 - yy1;
+             }
+
+           e_view_client_maximize(e_client_view_get(ec));
+
+           switch (max & E_MAXIMIZE_DIRECTION)
+             {
+               case E_MAXIMIZE_BOTH:
+                   e_client_maximized_geometry_set(ec, zx, zy, zw, zh);
+                   break;
+
+               case E_MAXIMIZE_VERTICAL:
+                   e_client_maximized_geometry_set(ec, ec->x, zy, ec->w, zh);
+                   break;
+
+               case E_MAXIMIZE_HORIZONTAL:
+                   e_client_maximized_geometry_set(ec, zx, ec->y, zw, ec->h);
+                   break;
+
+               case E_MAXIMIZE_LEFT:
+                   e_client_maximized_geometry_set(ec, zx, zy, zw / 2, zh);
+                   break;
+
+               case E_MAXIMIZE_RIGHT:
+                   e_client_maximized_geometry_set(ec, zx + zw / 2, zy, zw / 2, zh);
+                   break;
+             }
+           break;
+     }
+
+   if (ec->maximize_override)
+     ec->maximize_override = override;
+}
+
+static void
+_desk_area_cb_client_maximize(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Desk_Area *eda;
+   E_Client *ec;
+   E_Maximize max;
+
+   eda_client = wl_container_of(listener, eda_client, client_maximize);
+   eda = eda_client->eda;
+   ec = eda_client->ec;
+
+   // "override = 1" means that ec is not controlled by wm policy
+   if (ec->override) return;
+
+   max = *((E_Maximize *)data);
+
+   ec->pre_res_change.valid = 0;
+
+   if (!ec->fullscreen)
+     {
+        e_client_maximize_pre_set(ec, EINA_TRUE);
+
+        if (!(ec->maximized & E_MAXIMIZE_HORIZONTAL))
+          {
+             /* Horizontal hasn't been set */
+             ec->saved.x = ec->client.x - eda->x;
+             ec->saved.w = ec->client.w;
+          }
+        if (!(ec->maximized & E_MAXIMIZE_VERTICAL))
+          {
+             /* Vertical hasn't been set */
+             ec->saved.y = ec->client.y - eda->y;
+             ec->saved.h = ec->client.h;
+          }
+
+        _e_desk_area_ec_maximize(eda, ec, max);
+     }
+}
+
+static void
+_desk_area_cb_client_maximize_done(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Client *ec;
+   int w, h;
+
+   eda_client = wl_container_of(listener, eda_client, client_maximize_done);
+   ec = eda_client->ec;
+
+   e_client_maximized_geometry_get(ec, NULL, NULL, &w, &h);
+   e_client_shell_configure_send(ec, 0, w, h);
+
+   e_client_maximize_pre_set(ec, EINA_FALSE);
+}
+
+static void
+_desk_area_cb_client_unmaximize(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Desk_Area *eda;
+   E_Client *ec;
+   E_Maximize max;
+
+   eda_client = wl_container_of(listener, eda_client, client_unmaximize);
+   eda = eda_client->eda;
+   ec = eda_client->ec;
+
+   // "override = 1" means that ec is not controlled by wm policy
+   if (ec->override) return;
+   if (ec->fullscreen) return;
+
+   max = *((E_Maximize *)data);
+
+   if (ec->maximized & E_MAXIMIZE_TYPE)
+     {
+        e_client_maximize_pre_set(ec, EINA_TRUE);
+
+        ec->pre_res_change.valid = 0;
+        ec->changes.need_maximize = 0;
+
+        if ((ec->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN)
+          {
+             E_Maximize tmp_max = ec->maximized;
+
+             //un-set maximized state for updating frame.
+             ec->maximized = E_MAXIMIZE_NONE;
+             e_client_frame_update(ec);
+
+             // re-set maximized state for unmaximize smart callback.
+             ec->maximized = tmp_max;
+             if (ec->comp_data && ec->comp_data->shell.configure_send)
+               _e_policy_desk_area_configure_send(ec, 0, 0);
+             e_client_maximize_pre_set(ec, EINA_FALSE);
+
+             // un-set maximized state.
+             ec->maximized = E_MAXIMIZE_NONE;
+             e_client_util_move_resize_without_frame(ec,
+                                                     ec->saved.x + eda->x,
+                                                     ec->saved.y + eda->y,
+                                                     ec->saved.w, ec->saved.h);
+             ec->saved.x = ec->saved.y = ec->saved.w = ec->saved.h = 0;
+          }
+        else
+          {
+             int w, h, x, y;
+             Eina_Bool horiz = EINA_FALSE, vert = EINA_FALSE;
+
+             w = ec->client.w;
+             h = ec->client.h;
+             x = ec->client.x;
+             y = ec->client.y;
+
+             if (max & E_MAXIMIZE_VERTICAL)
+               {
+                  /* Remove vertical */
+                  h = ec->saved.h;
+                  vert = EINA_TRUE;
+                  y = ec->saved.y + eda->y;
+                  if ((max & E_MAXIMIZE_VERTICAL) == E_MAXIMIZE_VERTICAL)
+                    {
+                       ec->maximized &= ~E_MAXIMIZE_VERTICAL;
+                       ec->maximized &= ~E_MAXIMIZE_LEFT;
+                       ec->maximized &= ~E_MAXIMIZE_RIGHT;
+                    }
+                  if ((max & E_MAXIMIZE_LEFT) == E_MAXIMIZE_LEFT)
+                    ec->maximized &= ~E_MAXIMIZE_LEFT;
+                  if ((max & E_MAXIMIZE_RIGHT) == E_MAXIMIZE_RIGHT)
+                    ec->maximized &= ~E_MAXIMIZE_RIGHT;
+               }
+             if (max & E_MAXIMIZE_HORIZONTAL)
+               {
+                  /* Remove horizontal */
+                  w = ec->saved.w;
+                  x = ec->saved.x + eda->x;
+                  horiz = EINA_TRUE;
+                  ec->maximized &= ~E_MAXIMIZE_HORIZONTAL;
+               }
+
+             if (!(ec->maximized & E_MAXIMIZE_DIRECTION))
+               {
+                  ec->maximized = E_MAXIMIZE_NONE;
+                  e_client_frame_update(ec);
+                  e_client_resize_limit(ec, &w, &h);
+                  e_client_pos_set(ec, x, y);
+                  if ((ec->saved.w != 0) && (ec->saved.h != 0))
+                    {
+                       if ((w != ec->saved.w) || (h != ec->saved.h))
+                         {
+                            e_policy_visibility_client_defer_move(ec);
+                         }
+                    }
+               }
+             else
+               {
+                  e_client_resize_limit(ec, &w, &h);
+                  e_client_pos_set(ec, x, y);
+                  if ((ec->saved.w != 0) && (ec->saved.h != 0))
+                    {
+                       if ((w != ec->saved.w) || (h != ec->saved.h))
+                         {
+                            e_policy_visibility_client_defer_move(ec);
+                         }
+                    }
+               }
+             if (vert)
+               ec->saved.h = ec->saved.y = 0;
+             if (horiz)
+               ec->saved.w = ec->saved.x = 0;
+          }
+     }
+}
+
+static void
+_desk_area_cb_client_unmaximize_done(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Client *ec;
+
+   eda_client = wl_container_of(listener, eda_client, client_unmaximize_done);
+   ec = eda_client->ec;
+
+   if (ec->comp_data && ec->comp_data->shell.configure_send)
+     _e_policy_desk_area_configure_send(ec, 0, 0);
+
+   e_client_maximize_pre_set(ec, EINA_FALSE);
+}
+
+static void
+_desk_area_cb_client_activate_done(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Desk_Area *eda;
+   E_Client *ec;
+
+   eda_client = wl_container_of(listener, eda_client, client_activate_done);
+   eda = eda_client->eda;
+   ec = eda_client->ec;
+
+   ELOGF("EDA", "CLIENT ACTIVATE DONE. eda:%p", ec, eda);
+
+   if (!ec->lock_user_stacking)
+     e_client_raise(ec);
+}
+
+static void
+_desk_area_cb_client_delete_request(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Desk_Area *eda;
+   E_Client *ec;
+
+   eda_client = wl_container_of(listener, eda_client, delete_request);
+   eda = eda_client->eda;
+   ec = eda_client->ec;
+
+   ELOGF("EDA", "CLIENT DELETE REQUEST. eda:%p", ec, eda);
+
+   e_comp_ignore_win_del(E_PIXMAP_TYPE_WL, e_pixmap_window_get(ec->pixmap));
+
+   e_object_del(E_OBJECT(ec));
+
+   e_comp_wl_focus_check();
+
+   /* TODO: Delete request send ??
+    * NB: No such animal wrt wayland */
+}
+
+static void
+_desk_area_cb_client_kill_request(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Desk_Area *eda;
+   E_Client *ec;
+
+   eda_client = wl_container_of(listener, eda_client, kill_request);
+   eda = eda_client->eda;
+   ec = eda_client->ec;
+
+   ELOGF("EDA", "CLIENT KILL REQUEST. eda:%p", ec, eda);
+
+   e_comp_ignore_win_del(E_PIXMAP_TYPE_WL, e_pixmap_window_get(ec->pixmap));
+   if (ec->comp_data)
+     {
+        if (ec->comp_data->reparented)
+          e_client_comp_hidden_set(ec, EINA_TRUE);
+     }
+
+   e_view_pass_events_set(e_view_client_view_get(e_client_view_get(ec)), true);
+   if (ec->visible) e_view_client_hide(e_client_view_get(ec));
+   if (!ec->internal) e_object_del(E_OBJECT(ec));
+
+   e_comp_wl_focus_check();
+}
+
+static void
+_desk_area_cb_client_ping(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Desk_Area *eda;
+   E_Client *ec;
+
+   eda_client = wl_container_of(listener, eda_client, ping);
+   eda = eda_client->eda;
+   ec = eda_client->ec;
+
+   ELOGF("EDA", "CLIENT PING. eda:%p", ec, eda);
+
+   e_client_shell_ping(ec);
+}
+
+static void
+_desk_area_cb_client_redirect(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Desk_Area *eda;
+   E_Client *ec;
+   int w, h, pw, ph;
+
+   eda_client = wl_container_of(listener, eda_client, redirect);
+   eda = eda_client->eda;
+   ec = eda_client->ec;
+
+   ELOGF("EDA", "CLIENT REDIRECT. eda:%p", ec, eda);
+
+   /* - get current size
+    * - calc new size
+    * - readjust for new frame size
+    */
+
+   w = ec->w, h = ec->h;
+   e_view_client_frame_wh_unadjust(e_client_view_get(ec), w, h, &pw, &ph);
+
+   e_view_client_frame_recalc(e_client_view_get(ec));
+
+   if (!ec->fullscreen)
+     e_view_client_frame_wh_adjust(e_client_view_get(ec), ec->client.w, ec->client.h, &w, &h);
+
+   if (ec->fullscreen)
+     {
+        e_view_client_size_set(e_client_view_get(ec), eda->w, eda->h);
+     }
+   else if (ec->new_client)
+     {
+        if ((ec->w < 1) || (ec->h < 1)) return;
+        e_view_client_frame_wh_adjust(e_client_view_get(ec), pw, ph, &w, &h);
+        e_view_client_size_set(e_client_view_get(ec), w, h);
+     }
+   else if ((w != ec->w) || (h != ec->h))
+     e_view_client_size_set(e_client_view_get(ec), w, h);
+}
+
+
+static void
+_e_client_zones_layout_calc(E_Client *ec, int *zx, int *zy, int *zw, int *zh)
+{
+   int x, y, w, h;
+   E_Zone *zone_above, *zone_below, *zone_left, *zone_right;
+   E_Zone *zone;
+
+   zone = e_comp_zone_find_by_ec(ec);
+   if (!zone) return;
+   x = zone->x;
+   y = zone->y;
+   w = zone->w;
+   h = zone->h;
+
+   if (eina_list_count(e_comp_zone_list_get()) == 1)
+     {
+        if (zx) *zx = x;
+        if (zy) *zy = y;
+        if (zw) *zw = w;
+        if (zh) *zh = h;
+        return;
+     }
+
+   zone_left = e_comp_zone_xy_get((x - w + 5), y);
+   zone_right = e_comp_zone_xy_get((x + w + 5), y);
+   zone_above = e_comp_zone_xy_get(x, (y - h + 5));
+   zone_below = e_comp_zone_xy_get(x, (y + h + 5));
+
+   if (!(zone_above) && (y))
+     zone_above = e_comp_zone_xy_get(x, (h - 5));
+
+   if (!(zone_left) && (x))
+     zone_left = e_comp_zone_xy_get((x - 5), y);
+
+   if (zone_right)
+     w = zone_right->x + zone_right->w;
+
+   if (zone_left)
+     w = zone->x + zone->w;
+
+   if (zone_below)
+     h = zone_below->y + zone_below->h;
+
+   if (zone_above)
+     h = zone->y + zone->h;
+
+   if ((zone_left) && (zone_right))
+     w = zone->w + zone_right->x;
+
+   if ((zone_above) && (zone_below))
+     h = zone->h + zone_below->y;
+
+   if (x) x -= zone->w;
+   if (y) y -= zone->h;
+
+   if (zx) *zx = x > 0 ? x : 0;
+   if (zy) *zy = y > 0 ? y : 0;
+   if (zw) *zw = w;
+   if (zh) *zh = h;
+}
+
+static void
+_e_client_stay_within_canvas_margin(E_Client *ec, int x, int y, int *new_x, int *new_y)
+{
+   // TODO: FIXME: fix the x, y in Desk_Area
+   int new_x_max, new_y_max, new_x_min, new_y_min;
+   int margin_w, margin_h;
+   int zw = 0, zh = 0;
+   int cw, ch;
+   E_Zone *zone;
+
+   zone = e_comp_zone_find_by_ec(ec);
+   if (!zone)
+     {
+        if (new_x) *new_x = x;
+        if (new_y) *new_y = y;
+        return;
+     }
+
+   cw = ec->w;
+   ch = ec->h;
+
+   _e_client_zones_layout_calc(ec, NULL, NULL, &zw, &zh);
+
+   margin_w = zw/3;
+   margin_h = zh/10;
+
+   new_x_min = (margin_w > cw) ? 0 : -(cw - margin_w);
+   new_x_max = (margin_w > cw) ? (zw - cw) : (zw - margin_w);
+   new_y_min = (margin_h > ch) ? 0 : -(ch - margin_h);
+   new_y_max = (margin_h > ch) ? (zh - ch) : (zh - margin_h);
+
+   if (x >= new_x_max)
+     *new_x = new_x_max;
+   else if (x <= new_x_min)
+     *new_x = new_x_min;
+
+   if (y >= new_y_max)
+     *new_y = new_y_max;
+   else if (y <= new_y_min)
+     *new_y = new_y_min;
+
+}
+
+static void
+_desk_area_cb_client_stay_within_margin(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Client *ec;
+   int new_x, new_y;
+
+   eda_client = wl_container_of(listener, eda_client, client_stay_within_margin);
+   ec = eda_client->ec;
+
+   new_x = ec->x;
+   new_y = ec->y;
+
+   if (ec->floating)
+     {
+        _e_client_stay_within_canvas_margin(ec, ec->x, ec->y, &new_x, &new_y);
+
+        if ((ec->x != new_x) || (ec->y != new_y))
+          e_view_position_set(e_view_client_view_get(e_client_view_get(ec)), new_x, new_y);
+     }
+}
+
+static void
+_e_client_stay_within_canvas(E_Client *ec, int x, int y, int *new_x, int *new_y)
+{
+   int new_x_max, new_y_max;
+   int zw, zh;
+   Eina_Bool lw, lh;
+   E_Zone *zone;
+
+   zone = e_comp_zone_find_by_ec(ec);
+   if (!zone)
+     {
+        if (new_x) *new_x = x;
+        if (new_y) *new_y = y;
+        return;
+     }
+
+   _e_client_zones_layout_calc(ec, NULL, NULL, &zw, &zh);
+
+   new_x_max = zw - ec->w;
+   new_y_max = zh - ec->h;
+   lw = ec->w > zw ? EINA_TRUE : EINA_FALSE;
+   lh = ec->h > zh ? EINA_TRUE : EINA_FALSE;
+
+   if (lw)
+     {
+        if (x <= new_x_max)
+          *new_x = new_x_max;
+        else if (x >= 0)
+          *new_x = 0;
+     }
+   else
+     {
+        if (x >= new_x_max)
+          *new_x = new_x_max;
+        else if (x <= 0)
+          *new_x = 0;
+     }
+
+   if (lh)
+     {
+        if (y <= new_y_max)
+          *new_y = new_y_max;
+        else if (y >= 0)
+          *new_y = 0;
+     }
+   else
+     {
+        if (y >= new_y_max)
+          *new_y = new_y_max;
+        else if (y <= 0)
+          *new_y = 0;
+     }
+}
+
+static void
+_e_client_move_handle(E_Client *ec)
+{
+   int x, y;
+
+   if ((ec->moveinfo.down.button >= 1) && (ec->moveinfo.down.button <= 3))
+     {
+        x = ec->mouse.last_down[ec->moveinfo.down.button - 1].x +
+            (ec->mouse.current.mx - ec->moveinfo.down.mx);
+        y = ec->mouse.last_down[ec->moveinfo.down.button - 1].y +
+            (ec->mouse.current.my - ec->moveinfo.down.my);
+     }
+   else
+     {
+        x = ec->moveinfo.down.x +
+            (ec->mouse.current.mx - ec->moveinfo.down.mx);
+        y = ec->moveinfo.down.y +
+            (ec->mouse.current.my - ec->moveinfo.down.my);
+     }
+
+   if (e_config->screen_limits == E_CLIENT_OFFSCREEN_LIMIT_ALLOW_NONE)
+     _e_client_stay_within_canvas(ec, x, y, &x, &y);
+
+   if (ec->floating)
+     _e_client_stay_within_canvas_margin(ec, x, y, &x, &y);
+
+   e_view_position_set(e_view_client_view_get(e_client_view_get(ec)), x, y);
+
+   if (e_client_transform_core_enable_get(ec))
+     {
+        e_client_transform_core_update(ec);
+     }
+}
+
+static void
+_desk_area_cb_client_mouse_move(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Client *ec;
+   Evas_Point *output;
+
+   eda_client = wl_container_of(listener, eda_client, client_mouse_move);
+   ec = eda_client->ec;
+
+   output = (Evas_Point *)data;
+
+   if (ec->iconic || e_client_util_ignored_get(ec)) return;
+
+   ec->mouse.current.mx = output->x;
+   ec->mouse.current.my = output->y;
+
+   if (e_client_util_moving_get(ec))
+     {
+        _e_client_move_handle(ec);
+     }
+   else if (e_client_util_resizing_get(ec))
+     {
+        e_client_resize_handle(ec);
+     }
+}
+
+static void
+_desk_area_cb_client_resize_end(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Client *ec;
+
+   eda_client = wl_container_of(listener, eda_client, client_resize_end);
+   ec = eda_client->ec;
+
+   if (!e_client_util_resizing_get(ec)) return;
+
+   e_client_resize_handle(ec);
+   e_client_resize_end(ec);
+
+   ec->changes.reset_gravity = 1;
+
+   EC_CHANGED(ec);
+}
+
+
+static void
+_e_policy_desk_area_configure_send(E_Client *ec, Eina_Bool edges, Eina_Bool send_size)
+{
+   int w, h;
+   E_Comp_Wl_Data *comp_wl;
+
+   if (send_size)
+     {
+        if (e_view_client_frame_exists(e_client_view_get(ec)))
+          w = ec->client.w, h = ec->client.h;
+        else
+          w = ec->w, h = ec->h;
+     }
+   else
+     {
+        // Width and Height are -1 means that we don't consider size value
+        w = h = -1;
+     }
+
+   comp_wl = e_comp_wl_get();
+   e_client_shell_configure_send(ec, edges * comp_wl->resize.edges, w, h);
+}
+
+static void
+_e_comp_input_thread_layers_update(void *data)
+{
+   E_Comp_Input_Layer_Data *layer_data = data;
+   EINA_SAFETY_ON_NULL_RETURN(layer_data);
+
+   ICINF("[input thread|%s] layer(%u), function type(%d), item(%p), relative(%p)\n",
+         __func__, layer_data->layer, layer_data->type, layer_data->item, layer_data->relative);
+
+   e_comp_input_layers_update(layer_data);
+}
+
+static void
+_e_comp_object_layers_update(unsigned int layer, E_Comp_Input_Inlist_Function_Type type, E_Client *item, E_Client *relative)
+{
+   if (!e_input_thread_check_client_cloning_needed()) return;
+
+   E_Comp_Input_Layer_Data layer_data;
+
+   memset(&layer_data, 0, sizeof(E_Comp_Input_Layer_Data));
+
+   layer_data.layer = layer;
+   layer_data.type = type;
+   layer_data.item = item;
+   layer_data.relative = relative;
+
+   ICINF("[%s] layer(%u), function type(%d), item(%p), relative(%p)\n", __func__, layer, type, item, relative);
+
+   e_input_backend_thread_safe_call(_e_comp_input_thread_layers_update, &layer_data, sizeof(E_Comp_Input_Layer_Data));
+}
+
+static void
+_e_comp_object_layers_add(E_Desk_Area *eda, E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
+{
+   e_comp_ec_list_lock();
+
+   if (above)
+     {
+        eda->layers[above->layer].clients = eina_inlist_append_relative(eda->layers[above->layer].clients, EINA_INLIST_GET(cw->ec), EINA_INLIST_GET(above->ec));
+        eda->layers[above->layer].clients_count++;
+        _e_comp_object_layers_update(above->layer, E_COMP_INPUT_INLIST_APPEND_RELATIVE, cw->ec, above->ec);
+     }
+   else if (below)
+     {
+        eda->layers[below->layer].clients = eina_inlist_prepend_relative(eda->layers[below->layer].clients, EINA_INLIST_GET(cw->ec), EINA_INLIST_GET(below->ec));
+        eda->layers[below->layer].clients_count++;
+        _e_comp_object_layers_update(below->layer, E_COMP_INPUT_INLIST_PREPEND_RELATIVE, cw->ec, below->ec);
+     }
+   else
+     {
+        if (prepend)
+          {
+             eda->layers[cw->layer].clients = eina_inlist_prepend(eda->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
+             _e_comp_object_layers_update(cw->layer, E_COMP_INPUT_INLIST_PREPEND, cw->ec, NULL);
+          }
+        else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
+          {
+             eda->layers[cw->layer].clients = eina_inlist_append(eda->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
+             _e_comp_object_layers_update(cw->layer, E_COMP_INPUT_INLIST_APPEND, cw->ec, NULL);
+          }
+        eda->layers[cw->layer].clients_count++;
+     }
+
+   e_comp_ec_list_unlock();
+}
+
+static void
+_e_comp_object_layers_remove(E_Desk_Area *eda, E_Comp_Object *cw)
+{
+   e_comp_ec_list_lock();
+
+   if (cw->ec && eda->layers[cw->layer].clients)
+     {
+        eda->layers[cw->layer].clients = eina_inlist_remove(eda->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
+        eda->layers[cw->layer].clients_count--;
+        _e_comp_object_layers_update(cw->layer, E_COMP_INPUT_INLIST_REMOVE, cw->ec, NULL);
+     }
+
+   e_comp_ec_list_unlock();
+}
+
+static Eina_Bool
+_e_comp_object_is_pending(E_Client *ec)
+{
+   E_Client *topmost;
+
+   if (!ec) return EINA_FALSE;
+
+   topmost = e_comp_wl_topmost_parent_get(ec);
+
+   return (topmost) ? topmost->layer_pending : EINA_FALSE;
+}
+
+static void
+_e_comp_object_layer_update(E_Desk_Area *eda, Evas_Object *obj,
+                            Evas_Object *above, Evas_Object *below)
+{
+   E_Comp_Object *cw, *cw2 = NULL;
+   Evas_Object *o = NULL;
+   short layer;
+
+   cw = evas_object_smart_data_get(obj);
+   if (!cw) return;
+
+   if (cw->ec->layer_block) return;
+   if ((above) && (below))
+     {
+        ERR("Invalid layer update request! cw=%p", cw);
+        return;
+     }
+
+   o = above?:below;
+
+   if (o)
+     {
+        layer = evas_object_layer_get(o);
+        cw2 = evas_object_data_get(o, "comp_obj");
+        while (!cw2)
+          {
+             if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) break;
+
+             o = evas_object_above_get(o);
+             if ((!o) || (o == cw->smart_obj)) break;
+             if (evas_object_layer_get(o) != layer)
+               {
+                  o = eda->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_ALERT)].obj;
+               }
+             if (!o)
+               {
+                  E_Client *ec;
+                  ec = e_client_top_get();
+                  if (ec) o = ec->frame;
+               }
+
+             if (o) cw2 = evas_object_data_get(o, "comp_obj");
+          }
+     }
+
+   _e_comp_object_layers_remove(eda, cw);
+   if (cw2)
+     {
+        if (cw2->layer > cw->layer)
+          _e_comp_object_layers_add(eda, cw, NULL, NULL, 0);
+        else if (cw2->layer == cw->layer)
+          {
+             if (above)
+               _e_comp_object_layers_add(eda, cw, cw2, NULL, 0);
+             else if (o == obj)
+               _e_comp_object_layers_add(eda, cw, NULL, NULL, above? 0 : 1);
+             else if (below)
+               _e_comp_object_layers_add(eda, cw, NULL, cw2, 0);
+          }
+        else
+          _e_comp_object_layers_add(eda, cw, NULL, NULL, 1);
+     }
+   else
+     _e_comp_object_layers_add(eda, cw, NULL, NULL, 0);
+}
+
+static void
+_e_comp_intercept_stack_helper(E_Desk_Area *eda, E_Comp_Object *cw, Evas_Object *stack, E_Comp_Object_Stack_Func stack_cb)
+{
+   E_Comp_Object *cw2 = NULL;
+   E_Client *ecstack;
+   short layer;
+   Evas_Object *o = stack;
+   Eina_Bool raising = stack_cb == e_comp_object_stack_above;
+
+   /* We should consider topmost's layer_pending for subsurface */
+   if ((cw->ec->layer_block) || _e_comp_object_is_pending(cw->ec))
+     {
+        if (_e_comp_object_is_pending(cw->ec))
+          _e_comp_object_layer_update(eda, cw->smart_obj,
+                                      raising? stack : NULL,
+                                      raising? NULL : stack);
+
+        /* obey compositor effects! */
+        if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
+          evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
+        stack_cb(cw->smart_obj, stack);
+        if (cw->ec->layer == evas_object_layer_get(cw->smart_obj))
+          evas_object_data_del(cw->smart_obj, "client_restack");
+        return;
+     }
+
+   cw2 = evas_object_data_get(o, "comp_obj");
+
+   /* assume someone knew what they were doing during client init */
+   if (cw->ec->new_client)
+     layer = cw->ec->layer;
+   else if ((cw2) && _e_comp_object_is_pending(cw2->ec))
+     layer = cw2->ec->layer;
+   else
+     layer = evas_object_layer_get(stack);
+   ecstack = e_client_below_get(cw->ec);
+   if (layer != e_comp_canvas_layer_map_to(cw->layer))
+     {
+        evas_object_layer_set(cw->smart_obj, layer);
+        /* we got our layer wrangled, return now! */
+        if (layer != e_comp_canvas_layer_map_to(cw->layer)) return;
+     }
+
+   /* check if we're stacking below another client */
+   while (!cw2)
+     {
+        /* check for non-client layer object */
+        if (!e_util_strcmp(evas_object_name_get(o), "layer_obj"))
+          break;
+        /* find an existing client to use for layering
+         * by walking up the object stack
+         *
+         * this is guaranteed to be pretty quick since we'll either:
+         * - run out of client layers
+         * - find a stacking client
+         */
+        o = evas_object_above_get(o);
+        if ((!o) || (o == cw->smart_obj)) break;
+        if (evas_object_layer_get(o) != layer)
+          {
+             /* reached the top client layer somehow
+              * use top client object
+              */
+             o = eda->layers[e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR)].obj;
+          }
+        if (!o)
+          /* top client layer window hasn't been stacked yet. this probably shouldn't happen?
+           * return here since the top client layer window
+           */
+          {
+             E_Client *ec;
+
+             ec = e_client_top_get();
+             if (ec)
+               o = ec->frame;
+             //else //wat
+          }
+        if (o) cw2 = evas_object_data_get(o, "comp_obj");
+     }
+
+   if (cw2 && cw->layer != cw2->layer)
+     return;
+
+   /* remove existing layers */
+   _e_comp_object_layers_remove(eda, cw);
+   if (cw2)
+     {
+        if (o == stack) //if stacking above, cw2 is above; else cw2 is below
+          _e_comp_object_layers_add(eda, cw, raising ? cw2 : NULL, raising ? NULL : cw2, 0);
+        else if (o == cw->smart_obj) //prepend (lower) if not stacking above
+          _e_comp_object_layers_add(eda, cw, NULL, NULL, !raising);
+        else //if no stacking objects found, either raise or lower
+          _e_comp_object_layers_add(eda, cw, raising ? NULL : cw2, raising ? cw2 : NULL, 0);
+     }
+   else
+     _e_comp_object_layers_add(eda, cw, NULL, NULL, 0);
+
+   /* find new object for stacking if cw2 is on state of layer_pending */
+   if ((cw2) && _e_comp_object_is_pending(cw2->ec))
+     {
+        E_Client *new_stack = NULL, *current_ec = NULL;
+        current_ec = cw2->ec;
+        if (raising)
+          {
+             while ((new_stack = e_client_below_get(current_ec)))
+               {
+                  current_ec = new_stack;
+                  if (new_stack == cw->ec) continue;
+                  if (new_stack->layer != cw2->ec->layer) break;
+                  if (!_e_comp_object_is_pending(new_stack)) break;
+               }
+             if ((new_stack) && (new_stack->layer == cw2->ec->layer))
+               stack = new_stack->frame;
+             else
+               {
+                  /* stack it above layer object */
+                  int below_layer;
+                  below_layer = (cw2->layer <= 0)? 0 : cw2->layer - 1 ;
+                  stack = eda->layers[below_layer].obj;
+               }
+          }
+        else
+          {
+             while ((new_stack = e_client_above_get(current_ec)))
+               {
+                  current_ec = new_stack;
+                  if (new_stack == cw->ec) continue;
+                  if (new_stack->layer != cw2->ec->layer) break;
+                  if (!_e_comp_object_is_pending(new_stack)) break;
+               }
+             if ((new_stack) && (new_stack->layer == cw2->ec->layer))
+               stack = new_stack->frame;
+             else
+               stack = eda->layers[cw2->layer].obj;
+          }
+     }
+
+   /* set restack if stacking has changed */
+   if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
+     evas_object_data_set(cw->smart_obj, "client_restack", (void*)1);
+   stack_cb(cw->smart_obj, stack);
+   if (eda->layers[cw->layer].obj)
+     if (evas_object_below_get(cw->smart_obj) == eda->layers[cw->layer].obj)
+       {
+          CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
+       }
+   if (cw->ec->new_client || (!ecstack) || (ecstack->frame != o))
+     evas_object_data_del(cw->smart_obj, "client_restack");
+   if (!cw->visible) return;
+   e_comp_render_queue();
+}
+
+
+static void
+_desk_area_cb_comp_object_lower(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Desk_Area *eda;
+   E_Client *ec;
+   Evas_Object *obj, *o;
+   E_Comp_Object *cw;
+
+   eda_client = wl_container_of(listener, eda_client, comp_object_lower);
+   eda = eda_client->eda;
+   ec = eda_client->ec;
+   obj = ec->frame;
+   cw = (E_Comp_Object *)data;
+
+   if ((cw->ec->layer_block) || (cw->ec->layer_pending))
+     {
+        if (cw->ec->layer_pending)
+          _e_comp_object_layer_update(eda, obj, NULL, obj);
+
+        e_comp_object_lower(cw, obj);
+        return;
+     }
+
+   if (!EINA_INLIST_GET(cw->ec)->prev) return; //already lowest on layer
+
+   o = evas_object_below_get(obj);
+   _e_comp_object_layers_remove(eda, cw);
+   /* prepend to client list since this client should be the first item now */
+   _e_comp_object_layers_add(eda, cw, NULL, NULL, 1);
+   if (evas_object_layer_get(o) != evas_object_layer_get(obj)) return; //already at bottom!
+
+   evas_object_data_set(obj, "client_restack", (void*)1);
+   e_comp_object_lower(cw, obj);
+   evas_object_data_del(obj, "client_restack");
+
+   if (!cw->visible) return;
+   e_comp_render_queue();
+   e_comp_object_transform_obj_stack_update(obj);
+}
+
+static void
+_desk_area_cb_comp_object_raise(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Desk_Area *eda;
+   E_Client *ec;
+   Evas_Object *obj, *o, *op;
+   E_Comp_Object *cw;
+
+   eda_client = wl_container_of(listener, eda_client, comp_object_raise);
+   eda = eda_client->eda;
+   ec = eda_client->ec;
+   obj = ec->frame;
+   cw = (E_Comp_Object *)data;
+
+   if ((cw->ec->layer_block) || (cw->ec->layer_pending))
+     {
+        if (cw->ec->layer_pending)
+          {
+             int obj_layer = evas_object_layer_get(obj);
+             if (cw->ec->layer != obj_layer)
+               _e_comp_object_layer_update(eda, obj, NULL, NULL);
+          }
+
+        e_comp_object_raise(obj);
+        return;
+     }
+   if (!EINA_INLIST_GET(cw->ec)->next) return;//already highest on layer
+   o = evas_object_above_get(obj);
+   if (evas_object_layer_get(o) != evas_object_layer_get(obj)) return; //already at top!
+
+   /* still stack below override below the layer marker */
+   for (op = o = eda->layers[cw->layer].obj;
+        o && o != eda->layers[cw->layer - 1].obj;
+        op = o, o = evas_object_below_get(o))
+     {
+        if (evas_object_smart_smart_get(o))
+          {
+             E_Client *ec;
+
+             ec = e_comp_object_client_get(o);
+             if (ec && (!ec->override)) break;
+          }
+     }
+   e_comp_object_stack_below(obj, op);
+   e_client_focus_defer_set(cw->ec);
+
+   if (!cw->visible) return;
+   e_comp_render_queue();
+   e_comp_object_transform_obj_stack_update(obj);
+}
+
+static void
+_desk_area_cb_comp_object_set_layer(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Desk_Area *eda;
+   E_Client *ec;
+   Evas_Object *obj;
+   E_Comp_Object_Data_Set_Layer *layer_set_data;
+   E_Comp_Object *cw;
+   int layer;
+   E_Comp_Wl_Client_Data *child_cdata;
+   unsigned int l;
+   int oldraise;
+
+   eda_client = wl_container_of(listener, eda_client, comp_object_set_layer);
+   eda = eda_client->eda;
+   ec = eda_client->ec;
+   obj = ec->frame;
+   layer_set_data = (E_Comp_Object_Data_Set_Layer *)data;
+   cw = layer_set_data->cw;
+   layer = layer_set_data->layer;
+   l = e_comp_canvas_layer_map(layer);
+
+   if ((cw->ec->layer_block) || (cw->ec->layer_pending))
+     {
+        /* doing a compositor effect, follow directions */
+        e_comp_object_layer_set(obj, layer);
+        if (layer == cw->ec->layer) //trying to put layer back
+          {
+             E_Client *ec2;
+
+             /* if ec->layer and layer are the same but the client is not belong to the given(l)
+                that means, layer is changed during layer_pending. in this case, need to update layer inlist*/
+             if (cw->layer != l) goto layer_set;
+
+             if (cw->visible)
+               {
+                  e_comp_render_queue();
+               }
+             ec2 = e_client_above_get(cw->ec);
+             /* skip subsurface: stacking subsurface is handled by e_comp_wl */
+             while ((ec2) && (e_comp_wl_subsurface_check(ec2)))
+               ec2 = e_client_above_get(ec2);
+             if (ec2 && (evas_object_layer_get(ec2->frame) != evas_object_layer_get(obj)))
+               {
+                  ec2 = e_client_below_get(cw->ec);
+                  /* skip subsurface: stacking subsurface is handled by e_comp_wl */
+                  while ((ec2) && (e_comp_wl_subsurface_check(ec2)))
+                    ec2 = e_client_below_get(ec2);
+                  if (ec2 && (evas_object_layer_get(ec->frame) == evas_object_layer_get(cw->smart_obj)))
+                    {
+                       evas_object_stack_above(obj, ec2->frame);
+                       return;
+                    }
+                  ec2 = NULL;
+               }
+             if (ec2 && (cw->ec->parent == ec2))
+               {
+                  if (e_client_transient_policy_get(cw->ec) == E_TRANSIENT_ABOVE)
+                    evas_object_stack_above(obj, ec2->frame);
+                  else
+                    evas_object_stack_below(obj, ec2->frame);
+               }
+             else
+               evas_object_stack_below(obj, ec2 ? ec2->frame : eda->layers[cw->layer].obj);
+          }
+        return;
+     }
+
+layer_set:
+   if (cw->layer == l) return;
+   if (e_util_client_layer_map(layer) == 9999)
+     return; //invalid layer for clients not doing comp effects
+   if (cw->ec->fullscreen)
+     {
+        cw->ec->saved.layer = layer;
+        return;
+     }
+   oldraise = e_config->transient.raise;
+
+   /* clamp to valid client layer */
+   layer = e_comp_canvas_client_layer_map_nearest(layer);
+   cw->ec->layer = layer;
+   e_client_input_thread_layer_set(cw->ec, layer);
+   if (e_config->transient.layer)
+     {
+        E_Client *child;
+        Eina_List *list = eina_list_clone(cw->ec->transients);
+
+        /* We need to set raise to one, else the child won't
+         * follow to the new layer. It should be like this,
+         * even if the user usually doesn't want to raise
+         * the transients.
+         */
+        e_config->transient.raise = 1;
+        EINA_LIST_FREE(list, child)
+          {
+             child_cdata = e_client_cdata_get(child);
+             if (child_cdata && !child_cdata->mapped)
+               {
+                  ELOGF("COMP", "LAYER_SET CHILD. BUT not mapped. skip. child(ec:%p, win:0x%08zx)", cw->ec, child, e_client_util_win_get(child));
+                  continue;
+               }
+             e_client_layer_set(child, layer);
+          }
+     }
+
+   e_config->transient.raise = oldraise;
+
+   _e_comp_object_layers_remove(eda, cw);
+   cw->layer = e_comp_canvas_layer_map(layer);
+   _e_comp_object_layers_add(eda, cw, NULL, NULL, 0);
+   //if (cw->ec->new_client)
+     //INF("CLIENT STACKED %p: %u", cw->ec, layer);
+   e_comp_object_layer_set(obj, layer);
+   if (!eda->layers[cw->layer].obj) return; //this is a layer marker
+   evas_object_stack_below(obj, eda->layers[cw->layer].obj);
+   if (evas_object_below_get(obj) == eda->layers[cw->layer].obj)
+     {
+        /* can't stack a client above its own layer marker */
+        CRI("STACKING ERROR!!! ec:%p (cw->layer:%d, ec->layer:%d)", cw->ec, cw->layer, cw->ec->layer);
+     }
+}
+
+static void
+_desk_area_cb_comp_object_stack_above(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Desk_Area *eda;
+   E_Client *ec;
+   Evas_Object *obj, *above;
+   E_Comp_Object_Data_Stack_Above *stack_above_data;
+   E_Comp_Object *cw;
+
+   eda_client = wl_container_of(listener, eda_client, comp_object_stack_above);
+   eda = eda_client->eda;
+   ec = eda_client->ec;
+   obj = ec->frame;
+   stack_above_data = (E_Comp_Object_Data_Stack_Above *)data;
+   cw = stack_above_data->cw;
+   above = stack_above_data->above_obj;
+
+   if (evas_object_below_get(obj) == above)
+     {
+        _e_comp_object_layer_update(eda, obj, above, NULL);
+        return;
+     }
+
+   _e_comp_intercept_stack_helper(eda, cw, above, e_comp_object_stack_above);
+
+   e_comp_object_transform_obj_stack_update(obj);
+   e_comp_object_transform_obj_stack_update(above);
+
+}
+
+static void
+_desk_area_cb_comp_object_stack_below(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Desk_Area *eda;
+   E_Client *ec;
+   Evas_Object *obj, *below;
+   E_Comp_Object_Data_Stack_Below *stack_below_data;
+   E_Comp_Object *cw;
+
+   eda_client = wl_container_of(listener, eda_client, comp_object_stack_below);
+   eda = eda_client->eda;
+   ec = eda_client->ec;
+   obj = ec->frame;
+   stack_below_data = (E_Comp_Object_Data_Stack_Below *)data;
+   cw = stack_below_data->cw;
+   below = stack_below_data->below_obj;
+
+   if (evas_object_above_get(obj) == below)
+     {
+        _e_comp_object_layer_update(eda, obj, NULL, below);
+        return;
+     }
+
+   _e_comp_intercept_stack_helper(eda, cw, below, e_comp_object_stack_below);
+
+   if (evas_object_smart_smart_get(obj))
+     e_comp_object_transform_obj_stack_update(obj);
+   if (evas_object_smart_smart_get(below))
+     e_comp_object_transform_obj_stack_update(below);
+
+}
+
+static void
+_desk_area_cb_comp_object_resize(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Client *ec;
+   E_Comp_Wl_Data *comp_wl;
+
+   eda_client = wl_container_of(listener, eda_client, comp_object_resize);
+   ec = eda_client->ec;
+
+   // "override = 1" means that ec is not controlled by wm policy
+   if (ec->override) return;
+   if (!ec->comp_data->shell.configure_send) return;
+
+   /* TODO: calculate x, y with transfrom object */
+   comp_wl = e_comp_wl_get();
+   if ((e_client_util_resizing_get(ec)) && (!ec->transformed) && (comp_wl->resize.edges))
+     {
+        int w, h;
+
+        w = ec->mouse.last_down[ec->moveinfo.down.button - 1].w;
+        h = ec->mouse.last_down[ec->moveinfo.down.button - 1].h;
+        if (e_view_client_frame_exists(e_client_view_get(ec)))
+          e_view_client_frame_wh_unadjust(e_client_view_get(ec), w, h, &w, &h);
+
+        switch (ec->resize_mode)
+          {
+            case E_POINTER_RESIZE_TL:
+            case E_POINTER_RESIZE_L:
+            case E_POINTER_RESIZE_BL:
+                w += ec->mouse.last_down[ec->moveinfo.down.button - 1].mx -
+                    ec->mouse.current.mx;
+                break;
+            case E_POINTER_RESIZE_TR:
+            case E_POINTER_RESIZE_R:
+            case E_POINTER_RESIZE_BR:
+                w += ec->mouse.current.mx - ec->mouse.last_down[ec->moveinfo.down.button - 1].mx;
+                break;
+            default:
+                break;;
+          }
+        switch (ec->resize_mode)
+          {
+            case E_POINTER_RESIZE_TL:
+            case E_POINTER_RESIZE_T:
+            case E_POINTER_RESIZE_TR:
+                h += ec->mouse.last_down[ec->moveinfo.down.button - 1].my -
+                    ec->mouse.current.my;
+                break;
+            case E_POINTER_RESIZE_BL:
+            case E_POINTER_RESIZE_B:
+            case E_POINTER_RESIZE_BR:
+                h += ec->mouse.current.my - ec->mouse.last_down[ec->moveinfo.down.button - 1].my;
+                break;
+            default:
+                break;
+          }
+        w = E_CLAMP(w, 1, w);
+        h = E_CLAMP(h, 1, h);
+        e_client_resize_limit(ec, &w, &h);
+
+        e_client_shell_configure_send(ec, comp_wl->resize.edges, w, h);
+     }
+   else if ((!ec->fullscreen) && (!ec->maximized) &&
+            (!e_client_maximize_pre_get(ec)))
+     {
+        int pw = 0;
+        int ph = 0;
+        e_pixmap_size_get(ec->pixmap, &pw, &ph);
+        if ((pw != ec->w) || (ph != ec->h))
+          {
+             _e_policy_desk_area_configure_send(ec, 1, 1);
+          }
+     }
+}
+
+static void
+_desk_area_cb_comp_object_color_set(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Client *ec;
+   int a = 0;
+
+   eda_client = wl_container_of(listener, eda_client, comp_object_color_set);
+   ec = eda_client->ec;
+
+   e_view_client_color_get(e_client_view_get(ec), NULL, NULL, NULL, &a);
+   if (ec->netwm.opacity == a) return;
+
+   ec->netwm.opacity = a;
+   ec->netwm.opacity_changed = EINA_TRUE;
+}
+
+static E_Policy_Desk_Area_Private_Client *
+_e_policy_desk_area_private_client_get(E_Client *ec)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   struct wl_listener *listener;
+
+   listener = e_client_destroy_listener_get(ec, _desk_area_cb_client_destroy);
+   if (!listener) return NULL;
+
+   return wl_container_of(listener, eda_client, client_destroy);
+}
+
+static void
+_e_policy_desk_area_private_client_del(E_Policy_Desk_Area_Private_Client *eda_client)
+{
+   E_Desk_Area *eda = eda_client->eda;
+   E_Client *ec = eda_client->ec;
+#ifdef CLIENT_DEL_STACK_ISSUE
+#else
+   E_Comp_Object *cw;
+#endif // CLIENT_DEL_STACK_ISSUE
+
+   if (!e_desk_area_has_ec(eda, ec)) return;
+
+   // TODO: this code has to be refactoring
+   e_util_transform_del(ec->desk_area.transform);
+   ec->desk_area.transform = NULL;
+
+#ifdef CLIENT_DEL_STACK_ISSUE
+#else
+   cw = evas_object_smart_data_get(ec->frame);
+   if (cw)
+     _e_comp_object_layers_remove(eda, cw);
+   else
+     ELOGF("EDA", "No Comp Object. Fix Me~!!", ec);
+#endif // CLIENT_DEL_STACK_ISSUE
+
+   _e_policy_desk_area_smart_client_del(eda->smart_obj, ec);
+   _e_policy_desk_area_client_data_del(ec);
+
+   // wl_list remove
+   if (eda_client->comp_object_color_set.notify)
+     wl_list_remove(&eda_client->comp_object_color_set.link);
+   if (eda_client->comp_object_resize.notify)
+     wl_list_remove(&eda_client->comp_object_resize.link);
+   if (eda_client->redirect.notify)
+     wl_list_remove(&eda_client->redirect.link);
+   if (eda_client->ping.notify)
+     wl_list_remove(&eda_client->ping.link);
+   if (eda_client->kill_request.notify)
+     wl_list_remove(&eda_client->kill_request.link);
+   if (eda_client->delete_request.notify)
+     wl_list_remove(&eda_client->delete_request.link);
+
+   wl_list_remove(&eda_client->comp_object_stack_below.link);
+   wl_list_remove(&eda_client->comp_object_stack_above.link);
+   wl_list_remove(&eda_client->comp_object_set_layer.link);
+   wl_list_remove(&eda_client->comp_object_lower.link);
+   wl_list_remove(&eda_client->comp_object_raise.link);
+
+   wl_list_remove(&eda_client->client_resize_end.link);
+   wl_list_remove(&eda_client->client_mouse_move.link);
+   wl_list_remove(&eda_client->client_stay_within_margin.link);
+   wl_list_remove(&eda_client->client_activate_done.link);
+   wl_list_remove(&eda_client->client_unmaximize_done.link);
+   wl_list_remove(&eda_client->client_unmaximize.link);
+   wl_list_remove(&eda_client->client_maximize_done.link);
+   wl_list_remove(&eda_client->client_maximize.link);
+   wl_list_remove(&eda_client->client_unstick.link);
+   wl_list_remove(&eda_client->client_stick.link);
+   wl_list_remove(&eda_client->client_uniconify.link);
+   wl_list_remove(&eda_client->client_iconify.link);
+   wl_list_remove(&eda_client->client_focus_set.link);
+   wl_list_remove(&eda_client->client_unfullscreen.link);
+   wl_list_remove(&eda_client->client_fullscreen.link);
+   wl_list_remove(&eda_client->client_subsurface_stack_update.link);
+   wl_list_remove(&eda_client->client_get_visible_below.link);
+   wl_list_remove(&eda_client->client_get_visible_above.link);
+   wl_list_remove(&eda_client->client_get_below.link);
+   wl_list_remove(&eda_client->client_get_above.link);
+   wl_list_remove(&eda_client->client_destroy.link);
+
+   E_FREE(eda_client);
+}
+
+static void
+_e_policy_desk_area_cb_client_add(struct wl_listener *listener, void *data)
+{
+   E_Desk_Area *eda;
+   E_Policy_Desk_Area *pda;
+
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Client *ec;
+
+   pda = wl_container_of(listener, pda, client_add);
+   eda = pda->desk_area;
+
+
+   eda_client = E_NEW(E_Policy_Desk_Area_Private_Client, 1);
+   EINA_SAFETY_ON_NULL_RETURN(eda_client);
+
+   ec = (E_Client *) data;
+
+   eda_client->eda = eda;
+   eda_client->ec = ec;
+
+
+   // e_client listeners
+   eda_client->client_destroy.notify = _desk_area_cb_client_destroy;
+   e_client_destroy_listener_add(ec, &eda_client->client_destroy);
+
+   eda_client->client_get_above.notify = _desk_area_cb_client_get_above;
+   e_client_get_above_listener_add(ec, &eda_client->client_get_above);
+   eda_client->client_get_below.notify = _desk_area_cb_client_get_below;
+   e_client_get_below_listener_add(ec, &eda_client->client_get_below);
+   eda_client->client_get_visible_above.notify = _desk_area_cb_client_get_visible_above;
+   e_client_get_visible_above_listener_add(ec, &eda_client->client_get_visible_above);
+   eda_client->client_get_visible_below.notify = _desk_area_cb_client_get_visible_below;
+   e_client_get_visible_below_listener_add(ec, &eda_client->client_get_visible_below);
+   eda_client->client_subsurface_stack_update.notify = _desk_area_cb_client_subsurface_stack_update;
+   e_client_subsurface_stack_update_listener_add(ec, &eda_client->client_subsurface_stack_update);
+   eda_client->client_fullscreen.notify = _desk_area_cb_client_fullscreen;
+   e_client_fullscreen_listener_add(ec, &eda_client->client_fullscreen);
+   eda_client->client_unfullscreen.notify = _desk_area_cb_client_unfullscreen;
+   e_client_unfullscreen_listener_add(ec, &eda_client->client_unfullscreen);
+   eda_client->client_focus_set.notify = _desk_area_cb_client_focus_set;
+   e_client_focus_set_listener_add(ec, &eda_client->client_focus_set);
+   eda_client->client_iconify.notify = _desk_area_cb_client_iconify;
+   e_client_iconify_listener_add(ec, &eda_client->client_iconify);
+   eda_client->client_uniconify.notify = _desk_area_cb_client_uniconify;
+   e_client_uniconify_listener_add(ec, &eda_client->client_uniconify);
+   eda_client->client_stick.notify = _desk_area_cb_client_stick;
+   e_client_stick_listener_add(ec, &eda_client->client_stick);
+   eda_client->client_unstick.notify = _desk_area_cb_client_unstick;
+   e_client_unstick_listener_add(ec, &eda_client->client_unstick);
+   eda_client->client_maximize.notify = _desk_area_cb_client_maximize;
+   e_client_maximize_listener_add(ec, &eda_client->client_maximize);
+   eda_client->client_maximize_done.notify = _desk_area_cb_client_maximize_done;
+   e_client_maximize_done_listener_add(ec, &eda_client->client_maximize_done);
+   eda_client->client_unmaximize.notify = _desk_area_cb_client_unmaximize;
+   e_client_unmaximize_listener_add(ec, &eda_client->client_unmaximize);
+   eda_client->client_unmaximize_done.notify = _desk_area_cb_client_unmaximize_done;
+   e_client_unmaximize_done_listener_add(ec, &eda_client->client_unmaximize_done);
+   eda_client->client_activate_done.notify = _desk_area_cb_client_activate_done;
+   e_client_activate_done_listener_add(ec, &eda_client->client_activate_done);
+   eda_client->client_stay_within_margin.notify = _desk_area_cb_client_stay_within_margin;
+   e_client_stay_within_margin_listener_add(ec, &eda_client->client_stay_within_margin);
+   eda_client->client_mouse_move.notify = _desk_area_cb_client_mouse_move;
+   e_client_mouse_move_listener_add(ec, &eda_client->client_mouse_move);
+   eda_client->client_resize_end.notify = _desk_area_cb_client_resize_end;
+   e_client_resize_end_listener_add(ec, &eda_client->client_resize_end);
+
+   // e_comp_object listeners
+   eda_client->comp_object_lower.notify = _desk_area_cb_comp_object_lower;
+   e_comp_object_lower_listener_add(ec->frame, &eda_client->comp_object_lower);
+   eda_client->comp_object_raise.notify = _desk_area_cb_comp_object_raise;
+   e_comp_object_raise_listener_add(ec->frame, &eda_client->comp_object_raise);
+   eda_client->comp_object_set_layer.notify = _desk_area_cb_comp_object_set_layer;
+   e_comp_object_set_layer_listener_add(ec->frame, &eda_client->comp_object_set_layer);
+   eda_client->comp_object_stack_above.notify = _desk_area_cb_comp_object_stack_above;
+   e_comp_object_stack_above_listener_add(ec->frame, &eda_client->comp_object_stack_above);
+   eda_client->comp_object_stack_below.notify = _desk_area_cb_comp_object_stack_below;
+   e_comp_object_stack_below_listener_add(ec->frame, &eda_client->comp_object_stack_below);
+
+   // needs ec->comp_data listeners
+   if (ec->comp_data)
+     {
+        eda_client->redirect.notify = _desk_area_cb_client_redirect;
+        e_client_redirect_listener_add(ec, &eda_client->redirect);
+        eda_client->ping.notify = _desk_area_cb_client_ping;
+        e_client_ping_listener_add(ec, &eda_client->ping);
+        eda_client->kill_request.notify = _desk_area_cb_client_kill_request;
+        e_client_kill_request_listener_add(ec, &eda_client->kill_request);
+        eda_client->delete_request.notify = _desk_area_cb_client_delete_request;
+        e_client_delete_request_listener_add(ec, &eda_client->delete_request);
+        eda_client->comp_object_resize.notify = _desk_area_cb_comp_object_resize;
+        e_comp_object_resize_listener_add(ec->frame, &eda_client->comp_object_resize);
+        eda_client->comp_object_color_set.notify = _desk_area_cb_comp_object_color_set;
+        e_comp_object_color_set_listener_add(ec->frame, &eda_client->comp_object_color_set);
+     }
+
+   _e_policy_desk_area_client_data_set(pda, ec);
+   _e_policy_desk_area_smart_client_add(eda->smart_obj, ec);
+}
+
+static void
+_e_policy_desk_area_cb_client_del(struct wl_listener *listener, void *data)
+{
+   E_Policy_Desk_Area_Private_Client *eda_client;
+   E_Policy_Desk_Area *pda;
+   E_Client *ec;
+
+   pda = wl_container_of(listener, pda, client_del);
+   ec = (E_Client *) data;
+
+   eda_client = _e_policy_desk_area_private_client_get(ec);
+   EINA_SAFETY_ON_NULL_RETURN(eda_client);
+
+   _e_policy_desk_area_private_client_del(eda_client);
+}
+
+static void
+_e_policy_desk_area_cb_desk_area_hash_free(void *data)
+{
+   free(data);
+}
+
+static void
+_e_policy_desk_area_cb_hook_subsurface_create(void *data, E_Client *ec)
+{
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+
+   if (ec->desk_area.transform)
+     {
+        e_client_transform_core_remove(ec, ec->desk_area.transform);
+     }
+}
+
+#ifdef CLIENT_DEL_STACK_ISSUE
+static void
+_e_policy_desk_area_cb_client_free(void *data, E_Client *ec)
+{
+   E_Desk_Area *eda = data;
+   E_Comp_Object *cw;
+
+   ELOGF("EDA", "HOOK CLIENT FREE. desk_area:%p", ec, eda);
+
+   cw = evas_object_smart_data_get(ec->frame);
+   if (cw)
+     _e_comp_object_layers_remove(eda, cw);
+   else
+     ELOGF("EDA", "No Comp Object. Fix Me~!!", ec);
+}
+#endif //CLIENT_DEL_STACK_ISSUE
+
+EINTERN E_Policy_Desk_Area *
+e_policy_desk_area_new(E_Desk_Area *eda)
+{
+   E_Policy_Desk_Area *pda;
+   E_Layer ec_layer;
+   Evas_Object *obj;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(eda, NULL);
+
+   pda = eina_hash_find(hash_policy_desk_area, &eda);
+   if (pda)
+     {
+        ELOGF("POLICY_DESK_AREA", "Already exist policy desk area. | DESK_AREA:%p", NULL, eda);
+        return pda;
+     }
+
+   pda = E_NEW(E_Policy_Desk_Area, 1);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(pda, NULL);
+
+   ELOGF("POLICY_DESK_AREA", "new! | DESK_AREA:%p, Policy_Desk_Area:%p", NULL, eda, pda);
+
+   pda->desk_area = eda;
+
+   eina_hash_add(hash_policy_desk_area, &eda, pda);
+
+   /* init smart object */
+   _e_policy_desk_area_smart_init(eda);
+
+   /* init client's layers */
+   for (ec_layer = e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); ec_layer <= e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); ec_layer++)
+     {
+
+        obj = eda->layers[ec_layer].obj = evas_object_rectangle_add(e_comp_evas_get());
+        evas_object_layer_set(obj, e_comp_canvas_layer_map_to(ec_layer));
+        evas_object_name_set(obj, "layer_obj");
+     }
+
+   eda->hook_subsurf_create = e_comp_wl_hook_add(E_COMP_WL_HOOK_SUBSURFACE_CREATE,
+                                                 _e_policy_desk_area_cb_hook_subsurface_create,
+                                                 NULL);
+
+#ifdef CLIENT_DEL_STACK_ISSUE
+   eda->hook_client_free = e_client_hook_add(E_CLIENT_HOOK_FREE,
+                                             _e_policy_desk_area_cb_client_free,
+                                             eda);
+#endif // CLIENT_DEL_STACK_ISSUE
+
+   pda->geometry_set.notify = _e_policy_desk_area_cb_geometry_set;
+   e_desk_area_geometry_set_listener_add(eda, &pda->geometry_set);
+   pda->layer_set.notify = _e_policy_desk_area_cb_layer_set;
+   e_desk_area_layer_set_listener_add(eda, &pda->layer_set);
+   pda->activate.notify = _e_policy_desk_area_cb_activate;
+   e_desk_area_activate_listener_add(eda, &pda->activate);
+   pda->raise.notify = _e_policy_desk_area_cb_raise;
+   e_desk_area_raise_listener_add(eda, &pda->raise);
+   pda->lower.notify = _e_policy_desk_area_cb_lower;
+   e_desk_area_lower_listener_add(eda, &pda->lower);
+   pda->top_ec_get.notify = _e_policy_desk_area_cb_top_ec_get;
+   e_desk_area_top_ec_get_listener_add(eda, &pda->top_ec_get);
+   pda->bottom_ec_get.notify = _e_policy_desk_area_cb_bottom_ec_get;
+   e_desk_area_bottom_ec_get_listener_add(eda, &pda->bottom_ec_get);
+   pda->has_ec.notify = _e_policy_desk_area_cb_has_ec;
+   e_desk_area_has_ec_listener_add(eda, &pda->has_ec);
+
+   pda->client_add.notify = _e_policy_desk_area_cb_client_add;
+   e_desk_area_client_add_listener_add(eda, &pda->client_add);
+   pda->client_del.notify = _e_policy_desk_area_cb_client_del;
+   e_desk_area_client_del_listener_add(eda, &pda->client_del);
+
+   return pda;
+}
+
+EINTERN void
+e_policy_desk_area_del(E_Policy_Desk_Area *pda)
+{
+   E_Desk_Area *eda;
+
+   eda = pda->desk_area;
+
+   wl_list_remove(&pda->geometry_set.link);
+   wl_list_remove(&pda->layer_set.link);
+   wl_list_remove(&pda->activate.link);
+   wl_list_remove(&pda->raise.link);
+   wl_list_remove(&pda->lower.link);
+
+   wl_list_remove(&pda->client_add.link);
+   wl_list_remove(&pda->client_del.link);
+
+   E_FREE_FUNC(eda->hook_subsurf_create, e_comp_wl_hook_del);
+#ifdef CLIENT_DEL_STACK_ISSUE
+   E_FREE_FUNC(eda->hook_client_free, e_client_hook_del);
+#endif // CLIENT_DEL_STACK_ISSUE
+
+   eina_hash_del_by_key(hash_policy_desk_area, &pda->desk_area);
+
+   E_FREE(pda);
+
+   return;
+}
+
+EINTERN void
+e_policy_desk_area_init(void)
+{
+   if (hash_policy_desk_area)
+     {
+        ERR("Already initialized hash_policy_desk_area.");
+        return;
+     }
+
+   hash_policy_desk_area = eina_hash_pointer_new(_e_policy_desk_area_cb_desk_area_hash_free);
+   if (!hash_policy_desk_area)
+     {
+        ERR("Failed to create hash_policy_desk_area.");
+     }
+
+   return;
+}
+
+EINTERN void
+e_policy_desk_area_shutdown(void)
+{
+   eina_hash_free(hash_policy_desk_area);
+   hash_policy_desk_area = NULL;
+
+   return;
+}
index f56a070f91f66334795dc518aa27be8daa3748a7..a7c4564cf54fffcb8ff3478d0eb5abcb8167b636 100644 (file)
@@ -4,4 +4,13 @@
 #include "e_intern.h"
 #include "e_desk_area_intern.h"
 
+#define E_POLICY_DESK_AREA_SMART_OBJ_TYPE "E_Policy_Desk_Area_Smart_Object"
+
+typedef struct _E_Policy_Desk_Area E_Policy_Desk_Area;
+
+EINTERN Eina_Bool            e_policy_desk_area_hook_call(E_Desk_Area *eda, E_Desk_Area_Hook_Point hookpoint, void *data);
+EINTERN E_Policy_Desk_Area * e_policy_desk_area_new(E_Desk_Area *eda);
+EINTERN void                 e_policy_desk_area_del(E_Policy_Desk_Area *pda);
+EINTERN void                 e_policy_desk_area_init(void);
+EINTERN void                 e_policy_desk_area_shutdown(void);
 #endif
index 8d409ed5199fd7d07b0ccdd6986f471490ef10c6..3d77fab18047c3d9cb198af20d743f3afc20f9f0 100644 (file)
@@ -12,20 +12,6 @@ typedef struct _E_Desk_Area_Hook E_Desk_Area_Hook;
 
 typedef struct _E_Event_Desk_Area E_Event_Desk_Area;
 
-typedef enum _E_Desk_Area_Client_Layer
-{
-   E_DESK_AREA_CLIENT_LAYER_DESKTOP,
-   E_DESK_AREA_CLIENT_LAYER_BELOW,
-   E_DESK_AREA_CLIENT_LAYER_NORMAL,
-   E_DESK_AREA_CLIENT_LAYER_ABOVE,
-   E_DESK_AREA_CLIENT_LAYER_NOTIFICATION_LOW,
-   E_DESK_AREA_CLIENT_LAYER_NOTIFICATION_NORMAL,
-   E_DESK_AREA_CLIENT_LAYER_NOTIFICATION_HIGH,
-   E_DESK_AREA_CLIENT_LAYER_NOTIFICATION_TOP,
-   E_DESK_AREA_CLIENT_LAYER_ALERT,
-   E_DESK_AREA_CLIENT_LAYER_MAX,
-} E_Desk_Area_Client_Layer;
-
 
 typedef enum _E_Desk_Area_Hook_Point
 {