e_policy_zone: Seperate logic code from E_Zone to E_Policy_Zone 20/317320/1
authorJunseok Kim <juns.kim@samsung.com>
Thu, 18 Jul 2024 07:52:34 +0000 (16:52 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Mon, 9 Sep 2024 03:14:32 +0000 (12:14 +0900)
Change-Id: I116f0c3c146bc2b51cf00c7ceb6b50f9cf933136

16 files changed:
src/bin/compmgr/e_comp.c
src/bin/compmgr/e_comp_canvas.c
src/bin/compmgr/e_comp_canvas_intern.h
src/bin/compmgr/e_comp_object.c
src/bin/core/e_client.c
src/bin/core/e_desk.c
src/bin/core/e_zone.c
src/bin/core/e_zone_intern.h
src/bin/debug/e_info_server.c
src/bin/windowmgr/e_focus.c
src/bin/windowmgr/e_focus_intern.h
src/bin/windowmgr/e_focus_policy_history.c
src/bin/windowmgr/e_focus_policy_iface.h
src/bin/windowmgr/e_focus_policy_topmost.c
src/bin/windowmgr/e_policy_zone.c
src/bin/windowmgr/e_policy_zone_intern.h

index 45c65ae..bfc897d 100644 (file)
 #include "e_server_intern.h"
 #include "e_display_intern.h"
 
+#ifdef CONTAINER_POLICY
+#include "e_policy_zone_intern.h"
+#endif
+
 #include <sys/xattr.h>
 #include <sys/types.h>
 #include <grp.h>
@@ -706,7 +710,12 @@ e_comp_ungrab_input(Eina_Bool mouse, Eina_Bool kbd)
    E_Zone *zone = e_zone_current_get();
    if (!zone) return;
 
+#ifdef CONTAINER_POLICY
+   E_Policy_Zone *policy_zone = e_comp_canvas_policy_zone_get(zone);
+   e_policy_zone_focus_reset(policy_zone);
+#else
    e_zone_focus_reset(zone);
+#endif
 }
 
 EINTERN Eina_Bool
@@ -1473,7 +1482,11 @@ e_comp_idler_before(void)
         EINA_LIST_FOREACH(e_comp->zones, zl, zone)
            {
               if (e_comp_visibility_calculation_get())
+#ifdef CONTAINER_POLICY
+                e_visibility_changed = e_policy_zone_visibility_calculate(zone);
+#else
                 e_visibility_changed = e_zone_visibility_calculate(zone);
+#endif
 
               if (check_focus ||
                   (e_client_focused_get() == NULL) ||
@@ -1550,7 +1563,12 @@ e_comp_ungrab_input_without_inout(Eina_Bool mouse, Eina_Bool kbd)
    E_Zone *zone = e_zone_current_get();
    if (!zone) return;
 
+#ifdef CONTAINER_POLICY
+   E_Policy_Zone *policy_zone = e_comp_canvas_policy_zone_get(zone);
+   e_policy_zone_focus_reset(policy_zone);
+#else
    e_zone_focus_reset(zone);
+#endif
 }
 
 EINTERN Eina_Bool
index 4239667..1824680 100644 (file)
@@ -49,6 +49,34 @@ _e_comp_cb_zone_change()
    return ECORE_CALLBACK_PASS_ON;
 }
 
+#ifdef CONTAINER_POLICY
+static Eina_Bool
+_e_comp_cb_zone_del(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
+{
+   E_Event_Zone_Del *ev;
+   E_Zone *zone;
+   E_Policy_Zone *policy_zone;
+   Eina_List *l, *ll;
+
+   ev = event;
+   zone = ev->zone;
+
+   EINA_LIST_FOREACH_SAFE(g_policy_zones, l, ll, policy_zone)
+     {
+        if (e_policy_zone_get_zone(policy_zone) == zone)
+          {
+             e_policy_zone_del(policy_zone);
+             g_policy_zones = eina_list_remove(g_policy_zones, policy_zone);
+             break;
+          }
+     }
+
+   e_comp_canvas_update();
+
+   return ECORE_CALLBACK_PASS_ON;
+}
+#endif
+
 ////////////////////////////////////
 
 static int
@@ -112,16 +140,23 @@ e_comp_canvas_init(int w, int h)
    e_comp->w = w;
    e_comp->h = h;
 
+#ifdef CONTAINER_POLICY
+#else
    if (e_config)
      {
-        color[0] = e_config->comp_canvas_bg.r;
-        color[1] = e_config->comp_canvas_bg.g;
-        color[2] = e_config->comp_canvas_bg.b;
-        color[3] = e_config->comp_canvas_bg.a;
+#endif
+   color[0] = e_config->comp_canvas_bg.r;
+   color[1] = e_config->comp_canvas_bg.g;
+   color[2] = e_config->comp_canvas_bg.b;
+   color[3] = e_config->comp_canvas_bg.a;
+
+   if (e_config->comp_canvas_bg.opmode == EVAS_RENDER_COPY)
+     opmode = E_VIEW_RENDER_COPY;
 
-        if (e_config->comp_canvas_bg.opmode == EVAS_RENDER_COPY)
-          opmode = E_VIEW_RENDER_COPY;
+#ifdef CONTAINER_POLICY
+#else
      }
+#endif
 
    layer_tree = e_canvas_layer_view_tree_get(e_comp->canvas, E_CANVAS_LAYER_BOTTOM);
    rect = e_view_rect_create(layer_tree, e_comp->w, e_comp->h, color);
@@ -153,6 +188,7 @@ e_comp_canvas_init(int w, int h)
 #ifdef CONTAINER_POLICY
              policy_zone = e_policy_zone_new(zone);
              g_policy_zones = eina_list_append(g_policy_zones, policy_zone);
+             e_policy_zone_desk_count_set(policy_zone, e_config->zone_desks_x_count, e_config->zone_desks_y_count);
 #endif
              tizen_screen = e_tizen_screen_create(zone);
              if (scr->id) zone->output_id = strdup(scr->id);
@@ -165,6 +201,7 @@ e_comp_canvas_init(int w, int h)
 #ifdef CONTAINER_POLICY
         policy_zone = e_policy_zone_new(zone);
         g_policy_zones = eina_list_append(g_policy_zones, policy_zone);
+        e_policy_zone_desk_count_set(policy_zone, e_config->zone_desks_x_count, e_config->zone_desks_y_count);
 #endif
         tizen_screen = e_tizen_screen_create(zone);
         printf("@@@ NEW ZONE = %p, %p\n", zone, tizen_screen);
@@ -172,7 +209,11 @@ e_comp_canvas_init(int w, int h)
 
    E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_MOVE_RESIZE, _e_comp_cb_zone_change, NULL);
    E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_ADD, _e_comp_cb_zone_change, NULL);
+#ifdef CONTAINER_POLICY
+   E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_DEL, _e_comp_cb_zone_del, NULL);
+#else
    E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_DEL, _e_comp_cb_zone_change, NULL);
+#endif
    E_LIST_HANDLER_APPEND(handlers, E_EVENT_COMPOSITOR_ENABLE,    _e_comp_cb_compositor_enabled, NULL);
 
    ecore_evas_callback_pre_render_set(e_comp->ee, _e_comp_canvas_prerender);
@@ -363,6 +404,7 @@ e_comp_canvas_update(void)
 #ifdef CONTAINER_POLICY
                   policy_zone = e_policy_zone_new(zone);
                   g_policy_zones = eina_list_append(g_policy_zones, policy_zone);
+                  e_policy_zone_desk_count_set(policy_zone, e_config->zone_desks_x_count, e_config->zone_desks_y_count);
 #endif
                   tizen_screen = e_tizen_screen_create(zone);
                   if (scr->id) zone->output_id = strdup(scr->id);
@@ -621,3 +663,22 @@ e_comp_canvas_norender_get(void)
 
    return e_output_norender_get(primary_output);
 }
+
+#ifdef CONTAINER_POLICY
+EINTERN E_Policy_Zone *
+e_comp_canvas_policy_zone_get(E_Zone *zone)
+{
+   E_Policy_Zone *policy_zone;
+   Eina_List *l;
+
+   EINA_LIST_FOREACH(g_policy_zones, l, policy_zone)
+     {
+        if (e_policy_zone_get_zone(policy_zone) == zone)
+          {
+             return policy_zone;
+          }
+     }
+
+   return NULL;
+}
+#endif
\ No newline at end of file
index 0060e64..5228316 100644 (file)
@@ -3,6 +3,9 @@
 
 #include "e_intern.h"
 #include "e_comp_canvas.h"
+#ifdef  CONTAINER_POLICY
+#include "e_policy_zone_intern.h"
+#endif
 
 EINTERN Eina_Bool  e_comp_canvas_init(int w, int h);
 EINTERN void       e_comp_canvas_clear(void);
@@ -18,6 +21,9 @@ EINTERN void       e_comp_canvas_keys_grab(void);
 EINTERN void       e_comp_canvas_keys_ungrab(void);
 EINTERN void       e_comp_canvas_feed_mouse_up(unsigned int activate_time);
 EINTERN int        e_comp_canvas_norender_get(void);
+#ifdef  CONTAINER_POLICY
+EINTERN E_Policy_Zone * e_comp_canvas_policy_zone_get(E_Zone *zone);
+#endif
 
 /* the following functions are used for adjusting root window coordinates
  * to/from canvas coordinates.
index dc059d0..ca64d64 100644 (file)
@@ -4692,7 +4692,12 @@ _e_comp_object_autoclose_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_O
    E_Zone *zone = e_zone_current_get();
    if (!zone) return;
 
+#ifdef CONTAINER_POLICY
+   E_Policy_Zone *policy_zone = e_comp_canvas_policy_zone_get(zone);
+   e_policy_zone_focus_reset(policy_zone);
+#else
    e_zone_focus_reset(zone);
+#endif
 }
 
 EINTERN void
index 0f0b5e2..3335dc8 100644 (file)
 #include "e_view_intern.h"
 #include "e_view_client_intern.h"
 
+#ifdef CONTAINER_POLICY
+#include "e_policy_zone_intern.h"
+#include "e_comp_canvas_intern.h"
+#endif
+
 #define PRI(ec) ((E_Client_Private *)e_object_data_get(E_OBJECT(ec)))
 
 #define API_ENTRY \
@@ -4124,7 +4129,12 @@ e_client_focused_set(E_Client *ec)
    if (!ec)
      {
         zone = e_comp_zone_find_by_ec(focused_ec);
+#ifdef CONTAINER_POLICY
+        E_Policy_Zone *policy_zone = e_comp_canvas_policy_zone_get(zone);
+        e_policy_zone_focus_clear(policy_zone);
+#else
         e_zone_focus_clear(zone);
+#endif
         TRACE_DS_END();
         return;
      }
index d43923a..f91c786 100644 (file)
@@ -549,7 +549,8 @@ e_desk_current_get(E_Zone *zone)
    E_OBJECT_CHECK_RETURN(zone, NULL);
    E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
 
-   return e_desk_at_xy_get(zone, zone->desk_x_current, zone->desk_y_current);
+   E_Desk *desk = e_desk_at_xy_get(zone, zone->desk_x_current, zone->desk_y_current);
+   return desk;
 }
 
 EINTERN E_Desk *
index f74a72d..0898a4e 100644 (file)
@@ -1,13 +1,15 @@
 #include "e_zone_intern.h"
 #include "e_client_intern.h"
 #include "e_desk_intern.h"
+#include "e_comp_intern.h"
+
 #include "e_actions_intern.h"
 #include "e_appinfo_intern.h"
 #include "e_bindings_intern.h"
 #include "e_comp_wl_intern.h"
 #include "e_comp_wl_rsm_intern.h"
 #include "e_comp_wl_subsurface_intern.h"
-#include "e_comp_intern.h"
+#include "e_comp_wl_intern.h"
 #include "e_input_intern.h"
 #include "e_input_device_intern.h"
 #include "e_input_backend_intern.h"
    EINA_SAFETY_ON_NULL_RETURN_VAL(priv, ret);
 
 typedef struct _E_Zone_Private E_Zone_Private;
+#ifdef CONTAINER_POLICY
+#else
 typedef struct _E_Zone_Private_Client E_Zone_Private_Client;
+#endif
 
 struct _E_Zone_Private
 {
@@ -47,16 +52,35 @@ struct _E_Zone_Private
    struct
      {
         struct wl_signal destroy;
+#ifdef CONTAINER_POLICY
+        struct wl_signal zone_new;
+        struct wl_signal move;
+        struct wl_signal resize;
+        struct wl_signal move_resize;
+        struct wl_signal is_current;
+        struct wl_signal desk_count_set;
+        struct wl_signal obstacle_add;
+        struct wl_signal obstacle_update;
+        struct wl_signal obstacle_remove;
+        struct wl_signal useful_geometry_get;
+        struct wl_signal bg_mouse_down;
+        struct wl_signal bg_mouse_up;
+#endif
         struct wl_signal client_add;
+#ifdef CONTAINER_POLICY
+#else
         struct wl_signal client_remove;
         struct wl_signal display_state_change;
         struct wl_signal focus_clear;
         struct wl_signal focus_reset;
+#endif
      } events;
 
    struct wl_listener focus_focused_ec_changed;
 };
 
+#ifdef CONTAINER_POLICY
+#else
 struct _E_Zone_Private_Client
 {
    E_Zone *zone;
@@ -66,7 +90,7 @@ struct _E_Zone_Private_Client
    struct wl_listener client_eval_post_new_client;
    struct wl_listener client_focus_set;
 };
-
+#endif
 
 /* E_Zone is a child object of E_Comp. There is one zone per screen
  * in a xinerama setup. Each zone has one or more desktops.
@@ -123,11 +147,28 @@ _e_zone_private_init(E_Zone *zone)
    priv->zone = zone;
 
    wl_signal_init(&priv->events.destroy);
+#ifdef CONTAINER_POLICY
+   wl_signal_init(&priv->events.zone_new);
+   wl_signal_init(&priv->events.move);
+   wl_signal_init(&priv->events.resize);
+   wl_signal_init(&priv->events.move_resize);
+   wl_signal_init(&priv->events.is_current);
+   wl_signal_init(&priv->events.desk_count_set);
+   wl_signal_init(&priv->events.obstacle_add);
+   wl_signal_init(&priv->events.obstacle_update);
+   wl_signal_init(&priv->events.obstacle_remove);
+   wl_signal_init(&priv->events.useful_geometry_get);
+   wl_signal_init(&priv->events.bg_mouse_down);
+   wl_signal_init(&priv->events.bg_mouse_up);
+#endif
    wl_signal_init(&priv->events.client_add);
+#ifdef CONTAINER_POLICY
+#else
    wl_signal_init(&priv->events.client_remove);
    wl_signal_init(&priv->events.display_state_change);
    wl_signal_init(&priv->events.focus_clear);
    wl_signal_init(&priv->events.focus_reset);
+#endif
 
    e_object_data_set(E_OBJECT(zone), priv);
 
@@ -176,6 +217,8 @@ e_zone_shutdown(void)
    return 1;
 }
 
+#ifdef  CONTAINER_POLICY
+#else
 static void
 _e_zone_client_apply_auto_placement(E_Zone *zone, E_Client *ec)
 {
@@ -466,7 +509,10 @@ _e_zone_client_data_set(E_Zone *zone, E_Client *ec)
 
   e_view_data_set(e_view_client_view_get(e_client_view_get(ec)), ZONE_EC_DATA_KEY, zone);
 }
+#endif
 
+#ifdef CONTAINER_POLICY
+#else
 static void
 _e_zone_input_thread_focused_client_set(void *data)
 {
@@ -499,6 +545,7 @@ _zone_cb_focus_focused_ec_changed(struct wl_listener *listener, void *data)
         e_input_backend_thread_safe_call(_e_zone_input_thread_focused_client_set, &ec_data, sizeof(E_Input_Thread_Request_EClient_Data));
      }
 }
+#endif
 
 EINTERN E_Zone *
 e_zone_new(int num, int id, int x, int y, int w, int h)
@@ -526,6 +573,8 @@ e_zone_new(int num, int id, int x, int y, int w, int h)
 
    zone->display_state = E_ZONE_DISPLAY_STATE_ON;
 
+#ifdef CONTAINER_POLICY
+#else
    // Create E_Focus at only default zone which the zone num is 0
    if (zone->num == 0)
      {
@@ -549,6 +598,7 @@ e_zone_new(int num, int id, int x, int y, int w, int h)
         priv->focus_focused_ec_changed.notify = _zone_cb_focus_focused_ec_changed;
         e_focus_focused_ec_changed_listener_add(zone->focus, &priv->focus_focused_ec_changed);
      }
+#endif
 
    //printf("@@@@@@@@@@ e_zone_new: %i %i | %i %i %ix%i = %p\n", num, id, x, y, w, h, zone);
 
@@ -587,13 +637,19 @@ e_zone_new(int num, int id, int x, int y, int w, int h)
    zone->desk_y_count = 0;
    zone->desk_x_current = 0;
    zone->desk_y_current = 0;
+#ifdef CONTAINER_POLICY
+#else
    e_zone_desk_count_set(zone, e_config->zone_desks_x_count,
                          e_config->zone_desks_y_count);
+#endif
 
    e_object_del_attach_func_set(E_OBJECT(zone), _e_zone_object_del_attach);
 
+#ifdef CONTAINER_POLICY
+#else
    // CLIENT HOOK Handlers
    E_LIST_HOOK_APPEND(zone->ec_hooks, E_CLIENT_HOOK_NEW_CLIENT_POST, _e_zone_cb_hook_client_new_client_post, zone);
+#endif
 
    if (starting) return zone;
 
@@ -619,6 +675,8 @@ e_zone_name_set(E_Zone *zone,
    zone->name = eina_stringshare_add(name);
 }
 
+#ifdef CONTAINER_POLICY
+#else
 static void
 e_zone_reconfigure_clients(E_Zone *zone, int dx, int dy, int dw, int dh)
 {
@@ -638,6 +696,7 @@ e_zone_reconfigure_clients(E_Zone *zone, int dx, int dy, int dw, int dh)
           }
      }
 }
+#endif
 
 EINTERN void
 e_zone_move(E_Zone *zone,
@@ -666,7 +725,14 @@ e_zone_move(E_Zone *zone,
         ecore_event_add(E_EVENT_ZONE_MOVE_RESIZE, ev, _e_zone_event_generic_free, NULL);
      }
 
+#ifdef CONTAINER_POLICY
+   E_Zone_Data_Move_Resize move_resize_data = {0,};
+   move_resize_data.dx = dx;
+   move_resize_data.dy = dy;
+   wl_signal_emit(&PRI(zone)->events.move, &move_resize_data);
+#else
    e_zone_reconfigure_clients(zone, dx, dy, 0, 0);
+#endif
 }
 
 EINTERN void
@@ -698,7 +764,14 @@ e_zone_resize(E_Zone *zone,
                         _e_zone_event_generic_free, NULL);
      }
 
+#ifdef CONTAINER_POLICY
+   E_Zone_Data_Move_Resize move_resize_data = {0,};
+   move_resize_data.dw = dw;
+   move_resize_data.dh = dh;
+   wl_signal_emit(&PRI(zone)->events.resize, &move_resize_data);
+#else
    e_zone_reconfigure_clients(zone, 0, 0, dw, dh);
+#endif
 }
 
 EINTERN Eina_Bool
@@ -740,7 +813,16 @@ e_zone_move_resize(E_Zone *zone,
                         _e_zone_event_generic_free, NULL);
      }
 
+#ifdef CONTAINER_POLICY
+   E_Zone_Data_Move_Resize move_resize_data = {0,};
+   move_resize_data.dx = dx;
+   move_resize_data.dy = dy;
+   move_resize_data.dw = dw;
+   move_resize_data.dh = dh;
+   wl_signal_emit(&PRI(zone)->events.move_resize, &move_resize_data);
+#else
    e_zone_reconfigure_clients(zone, dx, dy, dw, dh);
+#endif
    return EINA_TRUE;
 }
 
@@ -749,16 +831,28 @@ e_zone_current_get(void)
 {
    Eina_List *l = NULL;
    E_Zone *zone;
+#ifdef CONTAINER_POLICY
+   E_Zone_Data_Is_Current data;
+   data.is_current = EINA_FALSE;
+#endif
 
    if (!starting)
      {
+#ifdef CONTAINER_POLICY
+#else
         int x, y;
 
         e_input_device_pointer_xy_get(NULL, &x, &y);
+#endif
 
         EINA_LIST_FOREACH(e_comp->zones, l, zone)
           {
+#ifdef CONTAINER_POLICY
+             wl_signal_emit(&PRI(zone)->events.is_current, &data);
+             if (data.is_current)
+#else
              if (E_INSIDE(x, y, zone->x, zone->y, zone->w, zone->h))
+#endif
                return zone;
           }
      }
@@ -825,10 +919,16 @@ e_zone_desk_count_set(E_Zone *zone,
                       int x_count,
                       int y_count)
 {
+   E_Event_Zone_Desk_Count_Set *ev;
+#ifdef CONTAINER_POLICY
+   E_Zone_Data_Desk_Count_Set desk_count_data = {0,};
+   desk_count_data.x_count = x_count;
+   desk_count_data.y_count = y_count;
+   wl_signal_emit(&PRI(zone)->events.desk_count_set, &desk_count_data);
+#else
    E_Desk **new_desks;
    E_Desk *desk, *new_desk;
    E_Client *ec;
-   E_Event_Zone_Desk_Count_Set *ev;
    int x, y, xx, yy, moved, nx, ny;
 
    E_OBJECT_CHECK(zone);
@@ -926,6 +1026,7 @@ e_zone_desk_count_set(E_Zone *zone,
         e_desk_show(desk);
         starting = s;
      }
+#endif
 
    ev = E_NEW(E_Event_Zone_Desk_Count_Set, 1);
    if (!ev) return;
@@ -950,14 +1051,27 @@ e_zone_desk_count_get(E_Zone *zone,
 EINTERN Eina_Bool
 e_zone_obstacle_add(E_Zone *zone, E_Client *ec, Eina_Rectangle *geom, Eina_Bool vertical)
 {
+#ifdef CONTAINER_POLICY
+#else
    E_Zone_Obstacle *obs;
    Eina_List *l;
+#endif
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(zone, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(geom, EINA_FALSE);
    EINA_SAFETY_ON_FALSE_RETURN_VAL(e_zone_has_ec(zone, ec), EINA_FALSE);
 
+#ifdef CONTAINER_POLICY
+   E_Zone_Data_Obstacle obstacle_data = {0,};
+   obstacle_data.ec = ec;
+   obstacle_data.geom = geom;
+   obstacle_data.vertical = vertical;
+   wl_signal_emit(&PRI(zone)->events.obstacle_add, &obstacle_data);
+
+   return !obstacle_data.result;
+#else
+
    // check in the list...
    EINA_LIST_FOREACH(zone->obstacles, l, obs)
      {
@@ -983,19 +1097,32 @@ e_zone_obstacle_add(E_Zone *zone, E_Client *ec, Eina_Rectangle *geom, Eina_Bool
 
    e_zone_useful_geometry_dirty(zone);
    return EINA_TRUE;
+#endif
 }
 
 EINTERN Eina_Bool
 e_zone_obstacle_update(E_Zone *zone, E_Client *ec, Eina_Rectangle *geom, Eina_Bool vertical)
 {
+#ifdef CONTAINER_POLICY
+#else
    E_Zone_Obstacle *obs;
    Eina_List *l;
    Eina_Bool changed = EINA_FALSE;
+#endif
 
    if (!zone) return EINA_FALSE;
    if (!ec) return EINA_FALSE;
    if (!e_zone_has_ec(zone, ec)) return EINA_FALSE;
 
+#ifdef CONTAINER_POLICY
+   E_Zone_Data_Obstacle obstacle_data = {0,};
+   obstacle_data.ec = ec;
+   obstacle_data.geom = geom;
+   obstacle_data.vertical = vertical;
+   wl_signal_emit(&PRI(zone)->events.obstacle_update, &obstacle_data);
+
+   return !obstacle_data.result;
+#else
    EINA_LIST_FOREACH(zone->obstacles, l, obs)
      {
         if (obs->ec == ec)
@@ -1035,18 +1162,27 @@ e_zone_obstacle_update(E_Zone *zone, E_Client *ec, Eina_Rectangle *geom, Eina_Bo
      e_zone_useful_geometry_dirty(zone);
 
    return EINA_TRUE;
+#endif
 }
 
 EINTERN void
 e_zone_obstacle_remove(E_Zone *zone, E_Client *ec)
 {
+#ifdef  CONTAINER_POLICY
+#else
    E_Zone_Obstacle *obs;
    Eina_List *l, *ll;
+#endif
 
    if (!zone) return;
    if (!ec) return;
    if (!e_zone_has_ec(zone, ec)) return;
 
+#ifdef CONTAINER_POLICY
+   E_Zone_Data_Obstacle obstacle_data = {0,};
+   obstacle_data.ec = ec;
+   wl_signal_emit(&PRI(zone)->events.obstacle_remove, &obstacle_data);
+#else
    EINA_LIST_FOREACH_SAFE(zone->obstacles, l, ll, obs)
      {
         if (obs->ec == ec)
@@ -1059,8 +1195,11 @@ e_zone_obstacle_remove(E_Zone *zone, E_Client *ec)
      }
 
    e_zone_useful_geometry_dirty(zone);
+#endif
 }
 
+#ifdef CONTAINER_POLICY
+#else
 static void
 _e_zone_useful_geometry_calc(const E_Zone *zone, E_Desk *desk, int *x, int *y, int *w, int *h)
 {
@@ -1114,6 +1253,7 @@ _e_zone_useful_geometry_calc(const E_Zone *zone, E_Desk *desk, int *x, int *y, i
    if (w) *w = geom.w;
    if (h) *h = geom.h;
 }
+#endif
 
 /**
  * Get (or calculate) the useful (or free, without any shelves) area.
@@ -1143,6 +1283,16 @@ e_zone_desk_useful_geometry_get(E_Zone *zone, E_Desk *desk, int *x, int *y, int
    E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
    E_OBJECT_CHECK(desk->zone);
 
+#ifdef CONTAINER_POLICY
+   E_Zone_Data_Useful_Geometry useful_geom_data = {0,};
+   useful_geom_data.desk = desk;
+   useful_geom_data.x = x;
+   useful_geom_data.y = y;
+   useful_geom_data.w = w;
+   useful_geom_data.h = h;
+   useful_geom_data.consider_obstacle_area = consider_obstacle_area;
+   wl_signal_emit(&PRI(zone)->events.useful_geometry_get, &useful_geom_data);
+#else
    if (desk->zone != zone)
      {
         ELOGF("E_ZONE", "CRI... Zone(%d) and Desk's zone(%d) mismatch!", NULL, zone->id, desk->zone->id);
@@ -1153,6 +1303,7 @@ e_zone_desk_useful_geometry_get(E_Zone *zone, E_Desk *desk, int *x, int *y, int
      _e_zone_useful_geometry_calc(zone, desk, x, y, w, h);
    else
      e_zone_useful_geometry_get(zone, x, y, w, h);
+#endif
 }
 
 /**
@@ -1185,7 +1336,10 @@ e_zone_display_state_set(E_Zone *zone, E_Zone_Display_State state)
 
    zone->display_state = state;
 
+#ifdef CONTAINER_POLICY
+#else
    wl_signal_emit(&PRI(zone)->events.display_state_change, NULL);
+#endif
    _e_zone_hook_call(E_ZONE_HOOK_DISPLAY_STATE_CHANGE, zone);
 
    ev = E_NEW(E_Event_Zone_Display_State_Change, 1);
@@ -1263,8 +1417,11 @@ e_zone_orientation_force_update_del(E_Zone *zone, E_Client *client)
 static void
 _e_zone_free(E_Zone *zone)
 {
+#ifdef CONTAINER_POLICY
+#else
    int x, y;
    E_Zone_Obstacle *obs;
+#endif
 
    wl_signal_emit(&PRI(zone)->events.destroy, NULL);
 
@@ -1283,8 +1440,11 @@ _e_zone_free(E_Zone *zone)
 
    E_FREE_FUNC(zone->cur_mouse_action, e_object_unref);
 
+#ifdef CONTAINER_POLICY
+#else
    /* remove handlers */
    E_FREE_LIST(zone->handlers, ecore_event_handler_del);
+#endif
 
    if (zone->name) eina_stringshare_del(zone->name);
    e_comp->zones = eina_list_remove(e_comp->zones, zone);
@@ -1294,6 +1454,8 @@ _e_zone_free(E_Zone *zone)
    e_view_destroy(zone->base);
    e_view_destroy(zone->over);
 
+#ifdef CONTAINER_POLICY
+#else
    /* free desks */
    for (x = 0; x < zone->desk_x_count; x++)
      {
@@ -1306,6 +1468,7 @@ _e_zone_free(E_Zone *zone)
      }
    free(zone->desks);
    free(zone->output_id);
+#endif
 
    _e_zone_private_finish(zone);
    free(zone);
@@ -1320,6 +1483,9 @@ _e_zone_cb_bg_mouse_down(void *data,
    E_Zone *zone;
 
    zone = data;
+#ifdef CONTAINER_POLICY
+   wl_signal_emit(&PRI(zone)->events.bg_mouse_down, event_info);
+#else
    if (e_comp_util_mouse_grabbed()) return;
 
    if (!zone->cur_mouse_action)
@@ -1336,6 +1502,7 @@ _e_zone_cb_bg_mouse_down(void *data,
                e_object_ref(E_OBJECT(zone->cur_mouse_action));
           }
      }
+#endif
 }
 
 static void
@@ -1347,6 +1514,10 @@ _e_zone_cb_bg_mouse_up(void *data,
    E_Zone *zone;
 
    zone = data;
+
+#ifdef CONTAINER_POLICY
+   wl_signal_emit(&PRI(zone)->events.bg_mouse_up, event_info);
+#else
    if (zone->cur_mouse_action)
      {
         E_Binding_Event_Mouse_Button event;
@@ -1368,6 +1539,7 @@ _e_zone_cb_bg_mouse_up(void *data,
         e_bindings_mouse_up_event_handle(E_BINDING_CONTEXT_ZONE,
                                          E_OBJECT(zone), &event);
      }
+#endif
 }
 
 static void
@@ -1687,6 +1859,8 @@ _e_client_event_zone_set_free(void *d EINA_UNUSED, E_Event_Client_Zone_Set *ev)
    free(ev);
 }
 
+#ifdef CONTAINER_POLICY
+#else
 static void
 _e_zone_client_set(E_Zone *zone, E_Client *ec)
 {
@@ -1731,12 +1905,16 @@ _e_zone_client_set(E_Zone *zone, E_Client *ec)
 
    ecore_event_add(E_EVENT_CLIENT_ZONE_SET, ev, (Ecore_End_Cb)_e_client_event_zone_set_free, NULL);
 }
+#endif
 
 EINTERN void
 e_zone_client_add(E_Zone *zone, E_Client *ec)
 {
+#ifdef CONTAINER_POLICY
+#else
    E_Desk *desk;
    E_Zone_Private_Client *zone_client;
+#endif
 
    EINA_SAFETY_ON_NULL_RETURN(zone);
    EINA_SAFETY_ON_NULL_RETURN(ec);
@@ -1744,6 +1922,9 @@ e_zone_client_add(E_Zone *zone, E_Client *ec)
 
    ELOGF("ZONE", "CLIENT ADD", ec);
 
+#ifdef CONTAINER_POLICY
+   wl_signal_emit(&PRI(zone)->events.client_add, ec);
+#else
    zone_client = E_NEW(E_Zone_Private_Client, 1);
    EINA_SAFETY_ON_NULL_RETURN(zone_client);
 
@@ -1778,6 +1959,7 @@ e_zone_client_add(E_Zone *zone, E_Client *ec)
    e_client_res_change_geometry_save(ec);
    e_client_res_change_geometry_restore(ec);
    ec->pre_res_change.valid = 0;
+#endif
 }
 
 EINTERN Eina_Bool
@@ -1806,6 +1988,13 @@ e_zone_is_displaying(E_Zone *zone)
   return ret;
 }
 
+#ifdef CONTAINER_POLICY
+#else
+
+#ifdef EC_IS_NOT_VISIBLE
+# undef EC_IS_NOT_VISIBLE
+#endif
+
 #define EC_IS_NOT_VISIBLE if (e_client_visibility_get(ec) != E_VISIBILITY_UNOBSCURED)
 
 EINTERN Eina_Bool
@@ -2126,6 +2315,7 @@ e_zone_visibility_calculate(E_Zone *zone)
 
    return e_visibility_changed;
 }
+#endif
 
 E_API E_Desk *
 e_zone_desk_find_by_ec(E_Zone *zone, E_Client *ec)
@@ -2146,6 +2336,8 @@ e_zone_desk_find_by_ec(E_Zone *zone, E_Client *ec)
    return NULL;
 }
 
+#ifdef CONTAINER_POLICY
+#else
 EINTERN void
 e_zone_focus_clear(E_Zone *zone)
 {
@@ -2161,6 +2353,24 @@ e_zone_focus_reset(E_Zone *zone)
 
    wl_signal_emit(&PRI(zone)->events.focus_reset, NULL);
 }
+#endif
+
+EINTERN void
+e_zone_client_set_event_emit(E_Zone *zone, E_Client *ec)
+{
+   E_Event_Client_Zone_Set *ev;
+
+   ev = E_NEW(E_Event_Client_Zone_Set, 1);
+   if (!ev) return;
+
+   ev->ec = ec;
+   REFD(ec, 5);
+   e_object_ref(E_OBJECT(ec));
+   ev->zone = zone;
+   e_object_ref(E_OBJECT(zone));
+
+   ecore_event_add(E_EVENT_CLIENT_ZONE_SET, ev, (Ecore_End_Cb)_e_client_event_zone_set_free, NULL);
+}
 
 EINTERN void
 e_zone_destroy_listener_add(E_Zone *zone, struct wl_listener *listener)
@@ -2169,6 +2379,90 @@ e_zone_destroy_listener_add(E_Zone *zone, struct wl_listener *listener)
    wl_signal_add(&priv->events.destroy, listener);
 }
 
+#ifdef CONTAINER_POLICY
+EINTERN void
+e_zone_zone_new_listener_add(E_Zone *zone, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.zone_new, listener);
+}
+
+EINTERN void
+e_zone_move_listener_add(E_Zone *zone, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.move, listener);
+}
+EINTERN void
+e_zone_resize_listener_add(E_Zone *zone, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.resize, listener);
+}
+EINTERN void
+e_zone_move_resize_listener_add(E_Zone *zone, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.move_resize, listener);
+}
+
+EINTERN void
+e_zone_is_current_listener_add(E_Zone *zone, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.is_current, listener);
+}
+
+EINTERN void
+e_zone_desk_count_set_listener_add(E_Zone *zone, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.desk_count_set, listener);
+}
+
+EINTERN void
+e_zone_obstacle_add_listener_add(E_Zone *zone, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.obstacle_add, listener);
+}
+
+EINTERN void
+e_zone_obstacle_update_listener_add(E_Zone *zone, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.obstacle_update, listener);
+}
+
+EINTERN void
+e_zone_obstacle_remove_listener_add(E_Zone *zone, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.obstacle_remove, listener);
+}
+
+EINTERN void
+e_zone_useful_geometry_get_listener_add(E_Zone *zone, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.useful_geometry_get, listener);
+}
+
+EINTERN void
+e_zone_bg_mouse_down_listener_add(E_Zone *zone, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.bg_mouse_down, listener);
+}
+
+EINTERN void
+e_zone_bg_mouse_up_listener_add(E_Zone *zone, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.bg_mouse_up, listener);
+}
+#endif
+
 EINTERN void
 e_zone_client_add_listener_add(E_Zone *zone, struct wl_listener *listener)
 {
@@ -2176,6 +2470,8 @@ e_zone_client_add_listener_add(E_Zone *zone, struct wl_listener *listener)
    wl_signal_add(&priv->events.client_add, listener);
 }
 
+#ifdef CONTAINER_POLICY
+#else
 EINTERN void
 e_zone_client_remove_listener_add(E_Zone *zone, struct wl_listener *listener)
 {
@@ -2203,3 +2499,4 @@ e_zone_focus_reset_listener_add(E_Zone *zone, struct wl_listener *listener)
    API_ENTRY;
    wl_signal_add(&priv->events.focus_reset, listener);
 }
+#endif
index ac94a5f..7ff76bf 100644 (file)
@@ -12,6 +12,38 @@ extern EINTERN int E_EVENT_ZONE_DEL;
 extern EINTERN int E_EVENT_ZONE_DISPLAY_STATE_CHANGE;
 extern EINTERN int E_EVENT_ZONE_USEFUL_GEOMETRY_CHANGE;
 
+#ifdef CONTAINER_POLICY
+typedef struct _E_Zone_Data_Move_Resize
+{
+   int dx, dy, dw, dh;
+} E_Zone_Data_Move_Resize;
+
+typedef struct _E_Zone_Data_Is_Current
+{
+   Eina_Bool is_current;
+} E_Zone_Data_Is_Current;
+
+typedef struct _E_Zone_Data_Desk_Count_Set
+{
+   int x_count, y_count;
+} E_Zone_Data_Desk_Count_Set;
+
+typedef struct _E_Zone_Data_Obstacle
+{
+   E_Client *ec;
+   Eina_Rectangle *geom;
+   Eina_Bool vertical;
+   Eina_Bool result;
+} E_Zone_Data_Obstacle;
+
+typedef struct _E_Zone_Data_Useful_Geometry
+{
+   E_Desk *desk;
+   int *x, *y, *w, *h;
+   Eina_Bool consider_obstacle_area;
+} E_Zone_Data_Useful_Geometry;
+#endif
+
 EINTERN int e_zone_init(void);
 EINTERN int e_zone_shutdown(void);
 
@@ -27,7 +59,10 @@ EINTERN void                 e_zone_useful_geometry_dirty(E_Zone *zone);
 EINTERN void                 e_zone_client_add(E_Zone *zone, E_Client *ec);
 EINTERN Eina_Bool            e_zone_has_ec(E_Zone *zone, E_Client *ec);
 EINTERN Eina_Bool            e_zone_is_displaying(E_Zone *zone);
+#ifdef CONTAINER_POLICY
+#else
 EINTERN Eina_Bool            e_zone_visibility_calculate(E_Zone *zone);
+#endif
 
 EINTERN void      e_zone_desk_count_set(E_Zone *zone, int x_count, int y_count);
 EINTERN void      e_zone_desk_count_get(E_Zone *zone, int *x_count, int *y_count);
@@ -37,15 +72,38 @@ EINTERN Eina_Bool e_zone_obstacle_add(E_Zone *zone, E_Client *ec, Eina_Rectangle
 EINTERN Eina_Bool e_zone_obstacle_update(E_Zone *zone, E_Client *ec, Eina_Rectangle *geom, Eina_Bool vertical);
 EINTERN void      e_zone_obstacle_remove(E_Zone *zone, E_Client *ec);
 
+#ifdef CONTAINER_POLICY
+#else
 EINTERN void      e_zone_focus_clear(E_Zone *zone);
 EINTERN void      e_zone_focus_reset(E_Zone *zone);
+#endif
+#ifdef CONTAINER_POLICY
+EINTERN void      e_zone_client_set_event_emit(E_Zone *zone, E_Client *ec);
+#endif
 
 // listeners
 EINTERN void e_zone_destroy_listener_add(E_Zone *zone, struct wl_listener *listener);
+#ifdef CONTAINER_POLICY
+EINTERN void e_zone_move_listener_add(E_Zone *zone, struct wl_listener *listener);
+EINTERN void e_zone_resize_listener_add(E_Zone *zone, struct wl_listener *listener);
+EINTERN void e_zone_move_resize_listener_add(E_Zone *zone, struct wl_listener *listener);
+EINTERN void e_zone_is_current_listener_add(E_Zone *zone, struct wl_listener *listener);
+EINTERN void e_zone_desk_count_set_listener_add(E_Zone *zone, struct wl_listener *listener);
+EINTERN void e_zone_obstacle_add_listener_add(E_Zone *zone, struct wl_listener *listener);
+EINTERN void e_zone_obstacle_update_listener_add(E_Zone *zone, struct wl_listener *listener);
+EINTERN void e_zone_obstacle_remove_listener_add(E_Zone *zone, struct wl_listener *listener);
+EINTERN void e_zone_useful_geometry_get_listener_add(E_Zone *zone, struct wl_listener *listener);
+EINTERN void e_zone_bg_mouse_down_listener_add(E_Zone *zone, struct wl_listener *listener);
+EINTERN void e_zone_bg_mouse_up_listener_add(E_Zone *zone, struct wl_listener *listener);
+#endif
 EINTERN void e_zone_client_add_listener_add(E_Zone *zone, struct wl_listener *listener);
+
+#ifdef CONTAINER_POLICY
+#else
 EINTERN void e_zone_client_remove_listener_add(E_Zone *zone, struct wl_listener *listener);
 EINTERN void e_zone_display_state_change_listener_add(E_Zone *zone, struct wl_listener *listener);
 EINTERN void e_zone_focus_clear_listener_add(E_Zone *zone, struct wl_listener *listener);
 EINTERN void e_zone_focus_reset_listener_add(E_Zone *zone, struct wl_listener *listener);
+#endif
 
 #endif
index a6b8153..e266c6d 100644 (file)
 #include <dlfcn.h>
 #include <mcheck.h>
 
+#ifdef CONTAINER_POLICY
+#include "e_comp_canvas_intern.h"
+#endif
+
 #define EDJE_EDIT_IS_UNSTABLE_AND_I_KNOW_ABOUT_IT
 #include <Edje_Edit.h>
 
@@ -6582,7 +6586,11 @@ _e_info_server_cb_focus_policy_ext_set(const Eldbus_Service_Interface *iface EIN
         if (zone && zone->focus)
           {
              e_focus_del(zone->focus);
+#ifdef CONTAINER_POLICY
+             zone->focus = e_focus_new(e_comp_canvas_policy_zone_get(zone), res);
+#else
              zone->focus = e_focus_new(zone, res);
+#endif
              if (!zone->focus)
                ERR("Failed to create E_Focus.");
           }
index 6c0ef66..86b8901 100644 (file)
@@ -1,24 +1,40 @@
 #include "e_focus_intern.h"
 #include "e_focus_policy_iface.h"
+#ifdef CONTAINER_POLICY
+#include "e_policy_zone_intern.h"
+#endif
 
 struct _E_Focus {
    E_Focus_Policy_Ext    policy_type;     // the focus policy type
    E_Focus_Policy_Iface *policy_iface;    // the focus policy iface
 };
 
+#ifdef CONTAINER_POLICY
+static E_Focus_Policy_Iface *
+_e_focus_policy_iface_get(E_Policy_Zone* policy_zone, E_Focus_Policy_Ext type)
+#else
 static E_Focus_Policy_Iface *
 _e_focus_policy_iface_get(E_Zone* zone, E_Focus_Policy_Ext type)
+#endif
 {
    E_Focus_Policy_Iface *policy;
 
    if (type == E_FOCUS_EXT_TOP_STACK)
      {
+#ifdef CONTAINER_POLICY
+        policy = e_focus_policy_iface_topmost_new(policy_zone);
+#else
         policy = e_focus_policy_iface_topmost_new(zone);
+#endif
         EINA_SAFETY_ON_NULL_RETURN_VAL(policy, NULL);
      }
    else if (type == E_FOCUS_EXT_HISTORY)
      {
+#ifdef CONTAINER_POLICY
+        policy = e_focus_policy_iface_history_new(policy_zone);
+#else
         policy = e_focus_policy_iface_history_new(zone);
+#endif
         EINA_SAFETY_ON_NULL_RETURN_VAL(policy, NULL);
      }
    else
@@ -30,18 +46,31 @@ _e_focus_policy_iface_get(E_Zone* zone, E_Focus_Policy_Ext type)
    return policy;
 }
 
+#ifdef CONTAINER_POLICY
+EINTERN E_Focus *
+e_focus_new(E_Policy_Zone* policy_zone, E_Focus_Policy_Ext policy_type)
+#else
 EINTERN E_Focus *
 e_focus_new(E_Zone* zone, E_Focus_Policy_Ext policy_type)
+#endif
 {
    E_Focus *focus;
    E_Focus_Policy_Iface *policy_iface;
 
+#ifdef CONTAINER_POLICY
+   EINA_SAFETY_ON_NULL_RETURN_VAL(policy_zone, NULL);
+#else
    EINA_SAFETY_ON_NULL_RETURN_VAL(zone, NULL);
+#endif
 
    focus = E_NEW(E_Focus, 1);
    EINA_SAFETY_ON_NULL_RETURN_VAL(focus, NULL);
 
+#ifdef CONTAINER_POLICY
+   policy_iface = _e_focus_policy_iface_get(policy_zone, policy_type);
+#else
    policy_iface = _e_focus_policy_iface_get(zone, policy_type);
+#endif
    if (!policy_iface)
      {
         ERR("Fail to get the E_Focus_Policy_Iface type: %d", policy_type);
@@ -52,7 +81,11 @@ e_focus_new(E_Zone* zone, E_Focus_Policy_Ext policy_type)
    focus->policy_type = policy_type;
    focus->policy_iface = policy_iface;
 
-   ELOGF("FOCUS", "Create E_Focus(%d)", NULL, policy_type);
+#ifdef CONTAINER_POLICY
+   ELOGF("FOCUS", "Create E_Focus(%d) for policy_zone:%p", NULL, policy_type, policy_zone);
+#else
+   ELOGF("FOCUS", "Create E_Focus(%d) for zone:%p", NULL, policy_type, zone);
+#endif
 
    return focus;
 }
index fb3e3f1..22918b2 100644 (file)
@@ -2,10 +2,17 @@
 #define E_FOCUS_INTERN_H
 
 #include "e_intern.h"
+#ifdef  CONTAINER_POLICY
+#include "e_policy_zone_intern.h"
+#endif
 
 typedef struct _E_Focus E_Focus;
 
+#ifdef CONTAINER_POLICY
+EINTERN E_Focus   *e_focus_new(E_Policy_Zone* policy_zone, E_Focus_Policy_Ext policy_type);
+#else
 EINTERN E_Focus   *e_focus_new(E_Zone* zone, E_Focus_Policy_Ext policy_type);
+#endif
 EINTERN void       e_focus_del(E_Focus *focus);
 EINTERN E_Client  *e_focus_focused_ec_get(E_Focus *focus);  // get the current focused ec
 EINTERN Eina_Bool  e_focus_update(E_Focus *focus); // update (find and set) the current focused ec
index 60af3a3..57788ab 100644 (file)
@@ -7,6 +7,11 @@
 #include "e_config_intern.h"
 #include "e_view_client_intern.h"
 
+#ifdef CONTAINER_POLICY
+#include "e_policy_zone_intern.h"
+#include "e_comp_canvas_intern.h"
+#endif
+
 typedef struct _E_Focus_Policy_History_Impl E_Focus_Policy_History;
 typedef struct _E_Focus_Policy_History_Client E_Focus_Policy_History_Client;
 
@@ -24,6 +29,7 @@ struct _E_Focus_Policy_History_Impl
      } events;
 
    struct wl_listener zone_client_add;
+   struct wl_listener policy_zone_client_add;
    struct wl_listener zone_client_remove;
    struct wl_listener zone_focus_clear;
    struct wl_listener zone_focus_reset;
@@ -103,7 +109,7 @@ _focus_policy_history_focus_stack_lower(E_Focus_Policy_History *history_policy,
 static void
 _e_focus_policy_history_focus_focus_defer_set(E_Focus_Policy_History *history_policy, E_Client *ec)
 {
-   ELOGF("FOCUS_HISTORY", "focus defer set", ec);
+   ELOGF("FOCUS_HISTORY", "focus defer set, focusPpolic:%p", ec, history_policy);
 
    history_policy->defer_focus_stack = eina_list_remove(history_policy->defer_focus_stack, ec);
    history_policy->defer_focus_stack = eina_list_prepend(history_policy->defer_focus_stack, ec);
@@ -783,7 +789,6 @@ _focus_policy_history_cb_client_activate_done(struct wl_listener *listener, void
            }
          else
            {
-              ELOGF("FOCUS_HISTORY", "focus set   | client activate", focus_ec);
               e_client_frame_focus_set(focus_ec, EINA_TRUE);
            }
       }
@@ -1002,11 +1007,25 @@ static void
 _focus_policy_history_cb_zone_client_add(struct wl_listener *listener, void *data)
 {
    E_Focus_Policy_History *history_policy;
+   E_Client *ec;
+
+   history_policy = wl_container_of(listener, history_policy, zone_client_add);
+
+   ec = (E_Client *)data;
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+
+   E_FOCUS_HISTORY_TRACE(history_policy, ec);
+}
+
+static void
+_focus_policy_history_cb_policy_zone_client_add(struct wl_listener *listener, void *data)
+{
+   E_Focus_Policy_History *history_policy;
    E_Focus_Policy_History_Client *history_client;
    E_Client *ec;
    E_View_Client *view_client;
 
-   history_policy = wl_container_of(listener, history_policy, zone_client_add);
+   history_policy = wl_container_of(listener, history_policy, policy_zone_client_add);
 
    ec = (E_Client *)data;
    EINA_SAFETY_ON_NULL_RETURN(ec);
@@ -1168,6 +1187,7 @@ _focus_policy_history_del(E_Focus_Policy_Impl *impl)
    wl_list_remove(&history_policy->zone_focus_clear.link);
    wl_list_remove(&history_policy->zone_client_remove.link);
    wl_list_remove(&history_policy->zone_client_add.link);
+   wl_list_remove(&history_policy->policy_zone_client_add.link);
 
    E_FREE(history_policy);
 }
@@ -1267,13 +1287,24 @@ _focus_policy_history_focused_ec_changed_listener_add(E_Focus_Policy_Impl *impl,
    wl_signal_add(&history_policy->events.focused_ec_changed, listener);
 }
 
+#ifdef  CONTAINER_POLICY
+EINTERN E_Focus_Policy_Iface *
+e_focus_policy_iface_history_new(E_Policy_Zone* policy_zone)
+#else
 EINTERN E_Focus_Policy_Iface *
 e_focus_policy_iface_history_new(E_Zone* zone)
+#endif
 {
    E_Focus_Policy_Iface *policy_iface;
    E_Focus_Policy_History *history_policy;
 
+#ifdef  CONTAINER_POLICY
+   E_Zone *zone;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(policy_zone, NULL);
+   zone = e_policy_zone_get_zone(policy_zone);
+#else
    EINA_SAFETY_ON_NULL_RETURN_VAL(zone, NULL);
+#endif
 
    policy_iface = E_NEW(E_Focus_Policy_Iface, 1);
    EINA_SAFETY_ON_NULL_RETURN_VAL(policy_iface, NULL);
@@ -1296,12 +1327,23 @@ e_focus_policy_iface_history_new(E_Zone* zone)
    // zone listeners
    history_policy->zone_client_add.notify = _focus_policy_history_cb_zone_client_add;
    e_zone_client_add_listener_add(zone, &history_policy->zone_client_add);
+#ifdef CONTAINER_POLICY
+   history_policy->policy_zone_client_add.notify = _focus_policy_history_cb_policy_zone_client_add;
+   e_policy_zone_client_add_listener_add(policy_zone, &history_policy->policy_zone_client_add);
+   history_policy->zone_client_remove.notify = _focus_policy_history_cb_zone_client_remove;
+   e_policy_zone_client_remove_listener_add(policy_zone, &history_policy->zone_client_remove);
+   history_policy->zone_focus_clear.notify = _focus_policy_history_cb_zone_focus_clear;
+   e_policy_zone_focus_clear_listener_add(policy_zone, &history_policy->zone_focus_clear);
+   history_policy->zone_focus_reset.notify = _focus_policy_history_cb_zone_focus_reset;
+   e_policy_zone_focus_reset_listener_add(policy_zone, &history_policy->zone_focus_reset);
+#else
    history_policy->zone_client_remove.notify = _focus_policy_history_cb_zone_client_remove;
    e_zone_client_remove_listener_add(zone, &history_policy->zone_client_remove);
    history_policy->zone_focus_clear.notify = _focus_policy_history_cb_zone_focus_clear;
    e_zone_focus_clear_listener_add(zone, &history_policy->zone_focus_clear);
    history_policy->zone_focus_reset.notify = _focus_policy_history_cb_zone_focus_reset;
    e_zone_focus_reset_listener_add(zone, &history_policy->zone_focus_reset);
+#endif
 
    return policy_iface;
 
index f1fcf75..05a0cff 100644 (file)
@@ -2,6 +2,9 @@
 #define E_FOCUS_POLICY_IFACE_H
 
 #include "e_intern.h"
+#ifdef  CONTAINER_POLICY
+#include "e_policy_zone_intern.h"
+#endif
 
 typedef struct _E_Focus_Policy_Iface E_Focus_Policy_Iface;
 typedef void                         E_Focus_Policy_Impl;
@@ -17,8 +20,14 @@ struct _E_Focus_Policy_Iface
    void        (*focused_ec_changed_listener_add)(E_Focus_Policy_Impl *impl, struct wl_listener *listener); // add the listener to notify focused_ec_changed
 };
 
+
+#ifdef  CONTAINER_POLICY
+EINTERN E_Focus_Policy_Iface *e_focus_policy_iface_topmost_new(E_Policy_Zone* policy_zone);
+EINTERN E_Focus_Policy_Iface *e_focus_policy_iface_history_new(E_Policy_Zone* policy_zone);
+#else
 EINTERN E_Focus_Policy_Iface *e_focus_policy_iface_topmost_new(E_Zone* zone);
 EINTERN E_Focus_Policy_Iface *e_focus_policy_iface_history_new(E_Zone* zone);
+#endif
 
 EINTERN void            e_focus_policy_iface_del(E_Focus_Policy_Iface *policy_iface);
 
index 24b938f..f346614 100644 (file)
@@ -5,6 +5,9 @@
 #include "e_config_intern.h"
 #include "e_view_client_intern.h"
 
+#include "e_comp_canvas_intern.h"
+#include "e_policy_zone_intern.h"
+
 typedef struct _E_Focus_Policy_Topmost_Impl E_Focus_Policy_Topmost;
 typedef struct _E_Focus_Policy_Topmost_Client E_Focus_Policy_Topmost_Client;
 
@@ -612,13 +615,24 @@ _focus_policy_topmost_focused_ec_changed_listener_add(E_Focus_Policy_Impl *impl,
    wl_signal_add(&topmost_policy->events.focused_ec_changed, listener);
 }
 
+#ifdef CONTAINER_POLICY
+EINTERN E_Focus_Policy_Iface *
+e_focus_policy_iface_topmost_new(E_Policy_Zone* policy_zone)
+#else
 EINTERN E_Focus_Policy_Iface *
 e_focus_policy_iface_topmost_new(E_Zone* zone)
+#endif
 {
    E_Focus_Policy_Iface *policy_iface;
    E_Focus_Policy_Topmost *topmost_policy;
 
+#ifdef CONTAINER_POLICY
+   E_Zone *zone;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(policy_zone, NULL);
+   zone = e_policy_zone_get_zone(policy_zone);
+#else
    EINA_SAFETY_ON_NULL_RETURN_VAL(zone, NULL);
+#endif
 
    policy_iface = E_NEW(E_Focus_Policy_Iface, 1);
    EINA_SAFETY_ON_NULL_RETURN_VAL(policy_iface, NULL);
@@ -637,12 +651,19 @@ e_focus_policy_iface_topmost_new(E_Zone* zone)
    policy_iface->focused_ec_changed_listener_add = _focus_policy_topmost_focused_ec_changed_listener_add;
 
    // zone listeners
+#ifdef CONTAINER_POLICY
    topmost_policy->zone_client_add.notify = _focus_policy_topmost_cb_zone_client_add;
-   e_zone_client_add_listener_add(zone, &topmost_policy->zone_client_add);
+   e_policy_zone_client_add_listener_add(policy_zone, &topmost_policy->zone_client_add);
+   topmost_policy->zone_client_remove.notify = _focus_policy_topmost_cb_zone_client_remove;
+   e_policy_zone_client_remove_listener_add(policy_zone, &topmost_policy->zone_client_remove);
+   topmost_policy->zone_focus_clear.notify = _focus_policy_topmost_cb_zone_focus_clear;
+   e_policy_zone_focus_clear_listener_add(policy_zone, &topmost_policy->zone_focus_clear);
+#else
    topmost_policy->zone_client_remove.notify = _focus_policy_topmost_cb_zone_client_remove;
    e_zone_client_remove_listener_add(zone, &topmost_policy->zone_client_remove);
    topmost_policy->zone_focus_clear.notify = _focus_policy_topmost_cb_zone_focus_clear;
    e_zone_focus_clear_listener_add(zone, &topmost_policy->zone_focus_clear);
+#endif
 
    return policy_iface;
 
index e1623ee..88fd196 100644 (file)
 #include "e_policy_zone_intern.h"
+#include "e_zone_intern.h"
 #include "e_policy_intern.h"
+#include "e_client_intern.h"
+#include "e_input_device_intern.h"
+#include "e_comp_wl_intern.h"
+#include "e_comp_wl_subsurface_intern.h"
+#include "e_view_client_intern.h"
 
 #ifdef CONTAINER_POLICY
+#include "e_desk_intern.h"
+#include "e_comp_canvas_intern.h"
+#include "e_comp_object_intern.h"
+#include "e_appinfo_intern.h"
+#include "e_place_intern.h"
+#include "e_focus_intern.h"
+#include "e_input_thread_client_intern.h"
+#include "e_input_backend_intern.h"
+#include "e_comp_input_intern.h"
+#include "e_bindings_intern.h"
+#include "e_comp_intern.h"
+#endif
+
+#ifdef CONTAINER_POLICY
+#define ZONE_EC_DATA_KEY  "E_Zone_Client"
+
+typedef struct _E_Policy_Zone_Client E_Policy_Zone_Client;
 
 struct _E_Policy_Zone
 {
    E_Zone *zone;
 
+   struct wl_listener client_add;
    struct wl_listener zone_destroy;
+   struct wl_listener move;
+   struct wl_listener resize;
+   struct wl_listener move_resize;
+   struct wl_listener is_current;
+   struct wl_listener desk_count_set;
+   struct wl_listener obstacle_add;
+   struct wl_listener obstacle_update;
+   struct wl_listener obstacle_remove;
+   struct wl_listener useful_geometry_get;
+   struct wl_listener bg_mouse_down;
+   struct wl_listener bg_mouse_up;
+   struct wl_listener focus_focused_ec_changed;
+
+   struct
+     {
+        struct wl_signal client_add;
+        struct wl_signal client_remove;
+        struct wl_signal focus_clear;
+        struct wl_signal focus_reset;
+     } events;
+};
+
+struct _E_Policy_Zone_Client
+{
+   E_Policy_Zone *policy_zone;
+   E_Client *ec;
+
+   struct wl_listener client_destroy;
+   struct wl_listener client_eval_post_new_client;
+   struct wl_listener client_focus_set;
 };
 
 static void
+e_zone_reconfigure_clients(E_Zone *zone, int dx, int dy, int dw, int dh)
+{
+   E_Client *ec;
+
+   E_CLIENT_FOREACH(ec)
+     {
+        if (!e_zone_has_ec(zone, ec)) continue;
+
+        if ((dx != 0) || (dy != 0))
+          e_view_position_set(e_view_client_view_get(e_client_view_get(ec)), ec->x + dx, ec->y + dy);
+        // we shrank the zone - adjust windows more
+        if ((dw < 0) || (dh < 0))
+          {
+             e_client_res_change_geometry_save(ec);
+             e_client_res_change_geometry_restore(ec);
+          }
+     }
+}
+
+static void
+_e_policy_zone_useful_geometry_calc(const E_Zone *zone, E_Desk *desk, int *x, int *y, int *w, int *h)
+{
+   Eina_Tiler *tiler;
+   E_Zone_Obstacle *obs;
+   Eina_List *l;
+   int zx, zy, zw, zh;
+   Eina_Iterator *it;
+   Eina_Rectangle geom = { 0 } , *rect;
+   int size = 0;
+
+   zx = zone->x;
+   zy = zone->y;
+   zw = zone->w;
+   zh = zone->h;
+
+   if (desk)
+     {
+        zx = desk->geom.x;
+        zy = desk->geom.y;
+        zw = desk->geom.w;
+        zh = desk->geom.h;
+     }
+
+   tiler = eina_tiler_new(zw, zh);
+   eina_tiler_tile_size_set(tiler, 1, 1);
+   eina_tiler_rect_add(tiler, &(Eina_Rectangle){0, 0, zw, zh});
+
+   EINA_LIST_FOREACH(zone->obstacles, l, obs)
+     {
+        if (!E_INTERSECTS(obs->x, obs->y, obs->w, obs->h, zx, zy, zw, zh)) continue;
+
+        if (obs->vertical)
+          eina_tiler_rect_del(tiler, &(Eina_Rectangle){obs->x - zx, 0, obs->w, zh});
+        else
+          eina_tiler_rect_del(tiler, &(Eina_Rectangle){0, obs->y - zy, zw, obs->h});
+     }
+
+   it = eina_tiler_iterator_new(tiler);
+   EINA_ITERATOR_FOREACH(it, rect)
+     {
+        if (rect->w * rect->h < size) continue;
+        size = rect->w * rect->h;
+        geom = *rect;
+     }
+   eina_iterator_free(it);
+   eina_tiler_free(tiler);
+
+   if (x) *x = geom.x + zx;
+   if (y) *y = geom.y + zy;
+   if (w) *w = geom.w;
+   if (h) *h = geom.h;
+}
+
+static void
+_e_policy_zone_client_apply_auto_placement(E_Zone *zone, E_Client *ec)
+{
+   E_Desk *desk;
+   Eina_List *skiplist = NULL;
+   int new_x, new_y, t = 0;
+   int type;
+   E_Client *parent_ec;
+   int zx = 0, zy = 0, zw = 0, zh = 0;
+   unsigned int seed = (unsigned int)time(NULL);
+
+   // call the intercept hook of the auto placement
+   if (e_client_intercept_hook_auto_placement_call(ec))
+     {
+        ELOGF("POL", "Intercepted auto_placement policy.", ec);
+        return;
+     }
+
+   e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
+
+   if (zw > ec->w)
+     new_x = zx + (rand_r(&seed) % (zw - ec->w));
+   else
+     new_x = zx;
+   if (zh > ec->h)
+     new_y = zy + (rand_r(&seed) % (zh - ec->h));
+   else
+     new_y = zy;
+
+   e_view_client_frame_geometry_get(e_client_view_get(ec), NULL, NULL, &t, NULL);
+
+   parent_ec = ec->parent;
+   if (parent_ec)
+     {
+        type = 1;
+        new_x = parent_ec->x;
+        new_y = parent_ec->y;
+     }
+   else if ((e_config->window_placement_policy == E_WINDOW_PLACEMENT_SMART) ||
+            (e_config->window_placement_policy == E_WINDOW_PLACEMENT_ANTIGADGET))
+     {
+        type = 2;
+        skiplist = eina_list_append(skiplist, ec);
+        desk = e_zone_desk_find_by_ec(zone, ec);
+        if (desk)
+          e_place_desk_region_smart(desk, skiplist,
+                                    ec->x, ec->y, ec->w, ec->h,
+                                    &new_x, &new_y);
+        else
+          e_place_zone_region_smart(zone, skiplist,
+                                    ec->x, ec->y, ec->w, ec->h,
+                                    &new_x, &new_y);
+
+        eina_list_free(skiplist);
+     }
+   else if (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL)
+     {
+        type = 3;
+        e_place_zone_manual(zone, ec->w, t, &new_x, &new_y);
+     }
+   else
+     {
+        type = 0;
+        e_place_zone_cursor(zone, ec->x, ec->y, ec->w, ec->h,
+                            t, &new_x, &new_y);
+     }
+
+   ELOGF("POL", "Apply auto placement (type:%d). (%d,%d) -> (%d,%d).", ec, type, ec->x, ec->y, new_x, new_y);
+   e_client_pos_set(ec, new_x, new_y);
+   ec->changes.pos = 1;
+   ec->placed = 1;
+   ec->pre_cb.x = ec->x; ec->pre_cb.y = ec->y;
+}
+
+static void
+_e_policy_zone_client_set(E_Zone *zone, E_Client *ec)
+{
+   /* if the window does not lie in the new zone, move it so that it does */
+   if (!E_INTERSECTS(ec->x, ec->y, ec->w, ec->h, zone->x, zone->y, zone->w, zone->h))
+     {
+        int x, y;
+
+        x = ec->x, y = ec->y;
+
+        /* keep window from hanging off bottom and left */
+        if (x + ec->w > zone->x + zone->w) x += (zone->x + zone->w) - (x + ec->w);
+        if (y + ec->h > zone->y + zone->h) y += (zone->y + zone->h) - (y + ec->h);
+
+        /* make sure to and left are on screen (if the window is larger than the zone, it will hang off the bottom / right) */
+        if (x < zone->x) x = zone->x;
+        if (y < zone->y) y = zone->y;
+
+        if (!E_INTERSECTS(x, y, ec->w, ec->h, zone->x, zone->y, zone->w, zone->h))
+          {
+             /* still not in zone at all, so just move it to closest edge */
+             if (x < zone->x) x = zone->x;
+             if (x >= zone->x + zone->w) x = zone->x + zone->w - ec->w;
+             if (y < zone->y) y = zone->y;
+             if (y >= zone->y + zone->h) y = zone->y + zone->h - ec->h;
+          }
+        e_view_position_set(e_view_client_view_get(e_client_view_get(ec)), x, y);
+     }
+
+   ec->zone = zone; // FIXME: This line must be deleted.
+
+   e_zone_client_set_event_emit(zone, ec);
+}
+
+static void
+_e_policy_zone_client_data_set(E_Zone *zone, E_Client *ec)
+{
+   E_Zone *data;
+
+   data = e_view_data_get(e_view_client_view_get(e_client_view_get(ec)), ZONE_EC_DATA_KEY);
+   if (data)
+     {
+        if (data == zone)
+          {
+             ELOGF("E_Zone", "EC is already added to zone_id:%d", ec, zone->id);
+             return;
+          }
+
+        e_view_data_del(e_view_client_view_get(e_client_view_get(ec)), ZONE_EC_DATA_KEY);
+     }
+
+   e_view_data_set(e_view_client_view_get(e_client_view_get(ec)), ZONE_EC_DATA_KEY, zone);
+}
+
+static void
 _e_policy_zone_cb_zone_destroy(struct wl_listener *listener, void *data)
 {
-  E_Policy_Zone *policy_zone;
+   E_Policy_Zone *policy_zone;
+   E_Zone *zone;
+   int x, y;
+   E_Zone_Obstacle *obs;
+
+   policy_zone = wl_container_of(listener, policy_zone, zone_destroy);
+   zone = policy_zone->zone;
+
+   /* free desks */
+   for (x = 0; x < zone->desk_x_count; x++)
+     {
+        for (y = 0; y < zone->desk_y_count; y++)
+          e_object_del(E_OBJECT(zone->desks[x + (y * zone->desk_x_count)]));
+     }
+   EINA_LIST_FREE(zone->obstacles, obs)
+     {
+        E_FREE(obs);
+     }
+   free(zone->desks);
+   free(zone->output_id);
+
+   e_object_unref(E_OBJECT(policy_zone->zone));
+   policy_zone->zone = NULL;
+}
+
+static void
+_e_policy_zone_cb_move(struct wl_listener *listener, void *data)
+{
+   E_Zone_Data_Move_Resize *move_resize_data = (E_Zone_Data_Move_Resize *) data;
+   E_Policy_Zone *policy_zone;
+   E_Zone *zone;
+
+   policy_zone = wl_container_of(listener, policy_zone, move);
+   zone = policy_zone->zone;
+
+   e_zone_reconfigure_clients(zone, move_resize_data->dx, move_resize_data->dy, 0, 0);
+
+   return;
+}
+
+static void
+_e_policy_zone_cb_resize(struct wl_listener *listener, void *data)
+{
+   E_Zone_Data_Move_Resize *move_resize_data = (E_Zone_Data_Move_Resize *) data;
+   E_Policy_Zone *policy_zone;
+   E_Zone *zone;
+
+   policy_zone = wl_container_of(listener, policy_zone, move);
+   zone = policy_zone->zone;
+
+   e_zone_reconfigure_clients(zone, 0, 0, move_resize_data->dw, move_resize_data->dh);
+
+   return;
+}
+
+static void
+_e_policy_zone_cb_move_resize(struct wl_listener *listener, void *data)
+{
+   E_Zone_Data_Move_Resize *move_resize_data = (E_Zone_Data_Move_Resize *) data;
+   E_Policy_Zone *policy_zone;
+   E_Zone *zone;
+
+   policy_zone = wl_container_of(listener, policy_zone, move);
+   zone = policy_zone->zone;
+
+   e_zone_reconfigure_clients(zone, move_resize_data->dx, move_resize_data->dy, move_resize_data->dw, move_resize_data->dh);
+
+   return;
+}
+
+static void
+_e_policy_zone_cb_is_current(struct wl_listener *listener, void *data)
+{
+   E_Zone_Data_Is_Current *is_current = (E_Zone_Data_Is_Current *) data;
+   E_Policy_Zone *policy_zone;
+   E_Zone *zone;
+   int x, y;
+
+   policy_zone = wl_container_of(listener, policy_zone, is_current);
+   zone = policy_zone->zone;
+
+   e_input_device_pointer_xy_get(NULL, &x, &y);
+
+   if (E_INSIDE(x, y, zone->x, zone->y, zone->w, zone->h))
+     is_current->is_current = EINA_TRUE;
+
+   return;
+}
+
+static void
+_e_policy_zone_cb_desk_count_set(struct wl_listener *listener, void *data)
+{
+   E_Zone_Data_Desk_Count_Set *desk_count_data = (E_Zone_Data_Desk_Count_Set *) data;
+   E_Policy_Zone *policy_zone;
+   E_Zone *zone;
+
+   E_Desk **new_desks;
+   E_Desk *desk, *new_desk;
+   E_Client *ec;
+   int x, y, xx, yy, moved, nx, ny;
+
+   policy_zone = wl_container_of(listener, policy_zone, desk_count_set);
+   zone = policy_zone->zone;
+
+   E_OBJECT_CHECK(zone);
+   E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
+
+   xx = desk_count_data->x_count;
+   if (xx < 1) xx = 1;
+   yy = desk_count_data->y_count;
+   if (yy < 1) yy = 1;
+
+   /* Orphaned window catcher; in case desk count gets reset */
+   moved = 0;
+   if (zone->desk_x_current >= xx) moved = 1;
+   if (zone->desk_y_current >= yy) moved = 1;
+   if (moved)
+     {
+        nx = zone->desk_x_current;
+        ny = zone->desk_y_current;
+        if (zone->desk_x_current >= xx) nx = xx - 1;
+        if (zone->desk_y_current >= yy) ny = yy - 1;
+        e_desk_show(e_desk_at_xy_get(zone, nx, ny));
+     }
+
+   new_desks = malloc(xx * yy * sizeof(E_Desk *));
+   if (!new_desks) return;
+   for (x = 0; x < xx; x++)
+     {
+        for (y = 0; y < yy; y++)
+          {
+             if ((x < zone->desk_x_count) && (y < zone->desk_y_count))
+               desk = zone->desks[x + (y * zone->desk_x_count)];
+             else
+               desk = e_desk_new(zone, x, y);
+             new_desks[x + (y * xx)] = desk;
+          }
+     }
+
+   /* catch windows that have fallen off the end if we got smaller */
+   if (xx < zone->desk_x_count)
+     {
+        for (y = 0; y < zone->desk_y_count; y++)
+          {
+             new_desk = zone->desks[xx - 1 + (y * zone->desk_x_count)];
+             for (x = xx; x < zone->desk_x_count; x++)
+               {
+                  desk = zone->desks[x + (y * zone->desk_x_count)];
+
+                  E_CLIENT_FOREACH(ec)
+                    {
+                       if (e_desk_has_ec(desk, ec))
+                         e_desk_client_add(new_desk, ec);
+                    }
+                  e_object_del(E_OBJECT(desk));
+               }
+          }
+     }
+   if (yy < zone->desk_y_count)
+     {
+        for (x = 0; x < zone->desk_x_count; x++)
+          {
+             new_desk = zone->desks[x + ((yy - 1) * zone->desk_x_count)];
+             for (y = yy; y < zone->desk_y_count; y++)
+               {
+                  desk = zone->desks[x + (y * zone->desk_x_count)];
+
+                  E_CLIENT_FOREACH(ec)
+                    {
+                       if (e_desk_has_ec(desk, ec))
+                         e_desk_client_add(new_desk, ec);
+                    }
+                  e_object_del(E_OBJECT(desk));
+               }
+          }
+     }
+   free(zone->desks);
+   zone->desks = new_desks;
+
+   zone->desk_x_count = xx;
+   zone->desk_y_count = yy;
+   e_config->zone_desks_x_count = xx;
+   e_config->zone_desks_y_count = yy;
+   e_config_save_queue();
+
+   /* Cannot call desk_current_get until the zone desk counts have been set
+    * or else we end up with a "white background" because desk_current_get will
+    * return NULL.
+    */
+   desk = e_desk_current_get(zone);
+   if (desk)
+     {
+        /* need to simulate "startup" conditions to force desk show to reevaluate here */
+        int s = starting;
+        desk->visible = 0;
+        starting = 1;
+        e_desk_show(desk);
+        starting = s;
+     }
+
+   return;
+}
+
+static void
+_e_policy_zone_cb_obstacle_add(struct wl_listener *listener, void *data)
+{
+   E_Zone_Data_Obstacle *obstacle_data = (E_Zone_Data_Obstacle *) data;
+   E_Policy_Zone *policy_zone;
+   E_Zone *zone;
+   E_Client *ec;
+   Eina_Rectangle *geom;
+   Eina_Bool vertical;
+   E_Zone_Obstacle *obs;
+   Eina_List *l;
+
+   policy_zone = wl_container_of(listener, policy_zone, obstacle_add);
+   zone = policy_zone->zone;
+   ec = obstacle_data->ec;
+   geom = obstacle_data->geom;
+   vertical = obstacle_data->vertical;
+
+   // check in the list...
+   EINA_LIST_FOREACH(zone->obstacles, l, obs)
+     {
+        if (obs->ec == ec)
+          {
+             ELOGF("POL_ZONE", "Already ADDED in the obstacle list", ec);
+             obstacle_data->result = EINA_FALSE;
+             return;
+          }
+     }
+
+   obs = E_NEW(E_Zone_Obstacle, 1);
+   if (!obs)
+     {
+        obstacle_data->result = EINA_FALSE;
+        return;
+     }
+   obs->ec = ec;
+   obs->x = geom->x;
+   obs->y = geom->y;
+   obs->w = geom->w;
+   obs->h = geom->h;
+   obs->vertical = !!vertical;
+
+   ELOGF("POL_ZONE", "ADD obstacle... geo(%d,%d,%dx%d), vertical:%d", ec, obs->x, obs->y, obs->w, obs->h, obs->vertical);
+
+   zone->obstacles = eina_list_append(zone->obstacles, obs);
+
+   e_zone_useful_geometry_dirty(zone);
+
+   obstacle_data->result = EINA_TRUE;
+   return;
+}
+
+static void
+_e_policy_zone_cb_obstacle_update(struct wl_listener *listener, void *data)
+{
+   E_Zone_Data_Obstacle *obstacle_data = (E_Zone_Data_Obstacle *) data;
+   E_Policy_Zone *policy_zone;
+   E_Zone *zone;
+   E_Client *ec;
+   Eina_Rectangle *geom;
+   Eina_Bool vertical;
+   E_Zone_Obstacle *obs;
+   Eina_List *l;
+   Eina_Bool changed = EINA_FALSE;
+
+   policy_zone = wl_container_of(listener, policy_zone, obstacle_update);
+   zone = policy_zone->zone;
+   ec = obstacle_data->ec;
+   geom = obstacle_data->geom;
+   vertical = obstacle_data->vertical;
+
+   EINA_LIST_FOREACH(zone->obstacles, l, obs)
+     {
+        if (obs->ec == ec)
+          break;
+     }
+
+   if (!obs)
+     {
+        ELOGF("POL_ZONE", "Not found in the obstacle list", ec);
+
+        obstacle_data->result = EINA_FALSE;
+        return;
+     }
+
+   if (geom)
+     {
+        if ((obs->x != geom->x) ||
+            (obs->y != geom->y) ||
+            (obs->w != geom->w) ||
+            (obs->h != geom->h))
+          {
+             obs->x = geom->x;
+             obs->y = geom->y;
+             obs->w = geom->w;
+             obs->h = geom->h;
+             changed = EINA_TRUE;
+          }
+     }
+
+   if (obs->vertical != vertical)
+     {
+        obs->vertical = !!vertical;
+        changed = EINA_TRUE;
+     }
+
+   ELOGF("POL_ZONE", "UPDATE obstacle... geo(%d,%d,%dx%d), vertical:%d", ec, obs->x, obs->y, obs->w, obs->h, obs->vertical);
+
+   if (changed)
+     e_zone_useful_geometry_dirty(zone);
+
+   obstacle_data->result = EINA_TRUE;
+   return;
+}
+
+static void
+_e_policy_zone_cb_obstacle_remove(struct wl_listener *listener, void *data)
+{
+   E_Zone_Data_Obstacle *obstacle_data = (E_Zone_Data_Obstacle *) data;
+   E_Policy_Zone *policy_zone;
+   E_Zone *zone;
+   E_Client *ec;
+   E_Zone_Obstacle *obs;
+   Eina_List *l, *ll;
+
+   policy_zone = wl_container_of(listener, policy_zone, obstacle_remove);
+   zone = policy_zone->zone;
+   ec = obstacle_data->ec;
+
+   EINA_LIST_FOREACH_SAFE(zone->obstacles, l, ll, obs)
+     {
+        if (obs->ec == ec)
+          {
+             ELOGF("POL_ZONE", "REMOVE obstacle...", ec);
+             zone->obstacles = eina_list_remove_list(zone->obstacles, l);
+             E_FREE(obs);
+             break;
+          }
+     }
+
+   e_zone_useful_geometry_dirty(zone);
+
+   return;
+}
+
+static void
+_e_policy_zone_cb_useful_geometry_get(struct wl_listener *listener, void *data)
+{
+   E_Zone_Data_Useful_Geometry *useful_geom_data = (E_Zone_Data_Useful_Geometry *) data;
+   E_Policy_Zone *policy_zone;
+   E_Zone *zone;
+   E_Desk *desk;
+   int *x, *y, *w, *h;
+   Eina_Bool consider_obstacle_area;
+
+   policy_zone = wl_container_of(listener, policy_zone, useful_geometry_get);
+   zone = policy_zone->zone;
+   desk = useful_geom_data->desk;
+   x = useful_geom_data->x;
+   y = useful_geom_data->y;
+   w = useful_geom_data->w;
+   h = useful_geom_data->h;
+   consider_obstacle_area = useful_geom_data->consider_obstacle_area;
+
+   if (desk->zone != zone)
+     {
+        ELOGF("POL_ZONE", "CRI... Zone(%d) and Desk's zone(%d) mismatch!", NULL, zone->id, desk->zone->id);
+        return;
+     }
+
+   if (consider_obstacle_area)
+     _e_policy_zone_useful_geometry_calc(zone, desk, x, y, w, h);
+   else
+     e_zone_useful_geometry_get(zone, x, y, w, h);
+
+   return;
+}
+
+static void
+_e_policy_zone_cb_bg_mouse_up(struct wl_listener *listener, void *data)
+{
+   E_Policy_Zone *policy_zone;
+   E_Zone *zone;
+
+   policy_zone = wl_container_of(listener, policy_zone, bg_mouse_up);
+   zone = policy_zone->zone;
+
+   if (zone->cur_mouse_action)
+     {
+        E_Binding_Event_Mouse_Button event;
+
+        e_bindings_evas_event_mouse_up_button_convert(data, &event);
+        if (zone->cur_mouse_action->func.end_mouse)
+          zone->cur_mouse_action->func.end_mouse(E_OBJECT(zone), "", &event);
+        else if (zone->cur_mouse_action->func.end)
+          zone->cur_mouse_action->func.end(E_OBJECT(zone), "");
+
+        e_object_unref(E_OBJECT(zone->cur_mouse_action));
+        zone->cur_mouse_action = NULL;
+     }
+   else
+     {
+        E_Binding_Event_Mouse_Button event;
+
+        e_bindings_ecore_event_mouse_button_convert(data, &event);
+        e_bindings_mouse_up_event_handle(E_BINDING_CONTEXT_ZONE,
+                                         E_OBJECT(zone), &event);
+     }
+
+   return;
+}
+
+static void
+_e_policy_zone_cb_bg_mouse_down(struct wl_listener *listener, void *data)
+{
+   E_Policy_Zone *policy_zone;
+   E_Zone *zone;
+
+   policy_zone = wl_container_of(listener, policy_zone, bg_mouse_down);
+   zone = policy_zone->zone;
+
+   if (e_comp_util_mouse_grabbed()) return;
+
+   if (!zone->cur_mouse_action)
+     {
+        zone->cur_mouse_action =
+            e_bindings_mouse_down_evas_event_handle(E_BINDING_CONTEXT_ZONE,
+                                                    E_OBJECT(zone), data);
+        if (zone->cur_mouse_action)
+          {
+             if ((!zone->cur_mouse_action->func.end_mouse) &&
+                 (!zone->cur_mouse_action->func.end))
+               zone->cur_mouse_action = NULL;
+             if (zone->cur_mouse_action)
+               e_object_ref(E_OBJECT(zone->cur_mouse_action));
+          }
+     }
+
+   return;
+}
+
+static void
+_e_zone_policy_input_thread_focused_client_set(void *data)
+{
+   E_Input_Thread_Request_EClient_Data *ec_data = data;
+   EINA_SAFETY_ON_NULL_RETURN(ec_data);
+
+   if (e_comp_input->focused_ec != ec_data->ec)
+     {
+        INF("[input thread|%s] focused ec(%p)\n", __func__, ec_data->ec);
+        e_comp_input->focused_ec = ec_data->ec;
+     }
+}
+
+static void
+_policy_zone_cb_focus_focused_ec_changed(struct wl_listener *listener, void *data)
+{
+   E_Client *focused_ec;
+
+   focused_ec = (E_Client *)data;
+
+   if (e_input_thread_check_client_cloning_needed())
+     {
+        E_Input_Thread_Request_EClient_Data ec_data;
+        memset(&ec_data, 0, sizeof(E_Input_Thread_Request_EClient_Data));
+        ec_data.ec = focused_ec;
+
+        INF("[%s] focused ec(%p)\n", __func__, focused_ec);
+        e_input_backend_thread_safe_call(_e_zone_policy_input_thread_focused_client_set, &ec_data, sizeof(E_Input_Thread_Request_EClient_Data));
+     }
+}
+
+
+static void
+_policy_zone_cb_client_destroy(struct wl_listener *listener, void *data)
+{
+   E_Policy_Zone_Client *zone_client;
+   E_Policy_Zone *policy_zone;
+   E_Zone *zone;
+   E_Client *ec;
+   E_Desk *desk;
+
+   zone_client = wl_container_of(listener, zone_client, client_destroy);
+   policy_zone = zone_client->policy_zone;
+   zone = policy_zone->zone;
+   ec = zone_client->ec;
+
+   desk = e_zone_desk_find_by_ec(zone, ec);
+   EINA_SAFETY_ON_NULL_RETURN(desk);
+
+   ELOGF("POL_ZONE", "CLIENT DEL", ec);
+
+   e_desk_visible_client_iconified_list_remove(desk, ec);
+
+   // desk_zoom
+   e_client_transform_core_remove(ec, ec->desk_zoom.transform);
+   e_util_transform_del(ec->desk_zoom.transform);
+   ec->desk_zoom.transform = NULL;
+   E_FREE_FUNC(ec->desk_zoom.hook_subsurf_create, e_comp_wl_hook_del);
+
+   wl_signal_emit_mutable(&policy_zone->events.client_remove, ec);
+
+   e_desk_client_del(desk, ec);
+
+   wl_list_remove(&zone_client->client_focus_set.link);
+   wl_list_remove(&zone_client->client_eval_post_new_client.link);
+   wl_list_remove(&zone_client->client_destroy.link);
+
+   E_FREE(zone_client);
+}
+
+static void
+_policy_zone_cb_client_eval_post_new_client(struct wl_listener *listener, void *data)
+{
+   E_Policy_Zone_Client *zone_client;
+   E_Policy_Zone *policy_zone;
+   E_Zone *zone;
+   E_Client *ec;
+   int tx, ty, tw, th;
+   int nw, nh;
+   int zx = 0, zy = 0, zw = 0, zh = 0;
+
+   zone_client = wl_container_of(listener, zone_client, client_eval_post_new_client);
+   policy_zone = zone_client->policy_zone;
+   zone = policy_zone->zone;
+   ec = zone_client->ec;
+
+   e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
+   /* enforce wm size hints for initial sizing */
+   if (e_config->screen_limits == E_CLIENT_OFFSCREEN_LIMIT_ALLOW_NONE)
+     {
+        tw = MIN(ec->w, zone->w);
+        th = MIN(ec->h, zone->h);
+        e_client_size_set(ec, tw, th);
+     }
+
+   nw = ec->w;
+   nh = ec->h;
+   e_client_resize_limit(ec, &nw, &nh);
+   e_client_size_set(ec, nw, nh);
+
+   if (ec->re_manage)
+     {
+        int x = ec->x, y = ec->y;
+        if (ec->x) e_view_client_frame_xy_adjust(e_client_view_get(ec), ec->x, 0, &ec->x, NULL);
+        if (ec->y) e_view_client_frame_xy_adjust(e_client_view_get(ec), 0, ec->y, NULL, &ec->y);
+        if ((x != ec->x) || (y != ec->y)) ec->changes.pos = 1;
+        ec->placed = 1;
+        ec->pre_cb.x = ec->x; ec->pre_cb.y = ec->y;
+     }
+
+   if (!ec->placed)
+     {
+        if (ec->dialog)
+          {
+             tx = zx + ((zw - ec->w) / 2);
+             ty = zy + ((zh - ec->h) / 2);
+             e_client_pos_set(ec, tx, ty);
+
+             ec->changes.pos = 1;
+             ec->placed = 1;
+             ec->pre_cb.x = ec->x; ec->pre_cb.y = ec->y;
+          }
+     }
+
+   E_Appinfo *eai;
+   eai = e_appinfo_find_with_pid(ec->netwm.pid);
+   if (!eai)
+     {
+        if (!ec->placed)
+          _e_policy_zone_client_apply_auto_placement(zone, ec);
+     }
+   else
+     {
+        if (e_appinfo_auto_placement_get(eai))
+          _e_policy_zone_client_apply_auto_placement(zone, ec);
+     }
+
+   /* if the explicit geometry request asks for the app to be
+    * in another zone - well move it there */
+     {
+        E_Zone *zone1 = NULL;
+        int x, y;
+
+        x = MAX(ec->x, 0);
+        y = MAX(ec->y, 0);
+        if ((!ec->re_manage) && ((ec->x != x) || (ec->y != y)))
+          zone1 = e_comp_zone_xy_get(x, y);
+
+        if (!zone1)
+          {
+             zone1 = e_comp_zone_xy_get(ec->x + (ec->w / 2), ec->y + (ec->h / 2));
+             if (zone1)
+               {
+                  E_Zone *z2 = e_comp_zone_xy_get(ec->x, ec->y);
+
+                  if (z2 && (z2 != zone1))
+                    {
+                       size_t psz = 0;
+                       E_Zone *zf = z2;
+                       Eina_List *l, *comp_zone_list;
+
+                     if ((comp_zone_list = e_comp_zone_list_get()) != NULL)
+                       {
+                          EINA_LIST_FOREACH(comp_zone_list, l, z2)
+                            {
+                               int w, h;
+
+                               x = ec->x, y = ec->y, w = ec->w, h = ec->h;
+                               E_RECTS_CLIP_TO_RECT(x, y, w, h, z2->x, z2->y, z2->w, z2->h);
+                               if (w * h == z2->w * z2->h)
+                                 {
+                                    /* client fully covering zone */
+                                    zf = z2;
+                                    break;
+                                 }
+                               if ((unsigned)(w * h) > psz)
+                                 {
+                                    psz = w * h;
+                                    zf = z2;
+                                 }
+                            }
+                       }
+
+                       zone = zf;
+                    }
+               }
+          }
+        if (!zone1)
+          zone1 = e_comp_zone_xy_get(ec->x, ec->y);
+        if (!zone1)
+          zone1 = e_comp_zone_xy_get(ec->x + ec->w - 1, ec->y);
+        if (!zone1)
+          zone1 = e_comp_zone_xy_get(ec->x + ec->w - 1, ec->y + ec->h - 1);
+        if (!zone1)
+          zone1 = e_comp_zone_xy_get(ec->x, ec->y + ec->h - 1);
+        if ((zone1) && (zone1 != zone))
+          e_zone_client_add(zone1, ec);
+     }
+}
+
+static void
+_policy_zone_cb_client_focus_set(struct wl_listener *listener, void *data)
+{
+   E_Policy_Zone_Client *zone_client;
+   E_Policy_Zone *policy_zone;
+   E_Zone *zone;
+   E_Client *ec;
+   E_Desk *desk;
+
+   zone_client = wl_container_of(listener, zone_client, client_focus_set);
+   policy_zone = zone_client->policy_zone;
+   zone = policy_zone->zone;
+   ec = zone_client->ec;
+
+   desk = e_zone_desk_find_by_ec(zone, ec);
+   EINA_SAFETY_ON_NULL_RETURN(desk);
+
+   if (!desk->visible && ec->sticky)
+     e_desk_client_add(e_desk_current_get(zone), ec);
+}
+
+static void
+_e_policy_zone_cb_hook_client_new_client_post(void *d, E_Client *ec)
+{
+   E_Zone *zone;
+
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+
+   zone = (E_Zone *)d;
+   EINA_SAFETY_ON_NULL_RETURN(zone);
+
+   // FIXME: A ec is set the current zone now.
+   //        We need to make a policy for the placement of the ec at the zone.
+   if (zone != e_zone_current_get()) return;
+
+   e_policy_client_add(ec);
+   e_zone_client_add(zone, ec);
+}
+
+static void
+_e_policy_zone_cb_client_add(struct wl_listener *listener, void *data)
+{
+   E_Policy_Zone_Client *zone_client;
+   E_Policy_Zone *policy_zone;
+   E_Zone *zone;
+   E_Desk *desk;
+   E_Client *ec = (E_Client *) data;
+
+   policy_zone = wl_container_of(listener, policy_zone, client_add);
+   zone = policy_zone->zone;
+
+   if (!ec) return;
+
+   zone_client = calloc(1, sizeof(E_Policy_Zone_Client));
+   if (!zone_client)
+     {
+        ERR("Failed to allocate memory");
+        return;
+     }
+
+   zone_client->policy_zone = policy_zone;
+   zone_client->ec = ec;
+
+   // e_client listeners
+   zone_client->client_destroy.notify = _policy_zone_cb_client_destroy;
+   e_client_destroy_listener_add(ec, &zone_client->client_destroy);
+
+   zone_client->client_eval_post_new_client.notify = _policy_zone_cb_client_eval_post_new_client;
+   e_client_eval_post_new_client_listener_add(ec, &zone_client->client_eval_post_new_client);
+
+   zone_client->client_focus_set.notify = _policy_zone_cb_client_focus_set;
+   e_client_focus_set_listener_add(ec, &zone_client->client_focus_set);
+
+   _e_policy_zone_client_set(zone, ec);
+   _e_policy_zone_client_data_set(zone, ec);
+
+   wl_signal_emit(&policy_zone->events.client_add, ec);
+
+   // Currently, ec is set to the current desk now.
+   // At this moment, ec should not belong to any desk
+   desk = e_desk_current_get(zone);
+   e_desk_client_add(desk, ec);
+
+   if (ec->override)
+     e_client_layer_set(ec, E_LAYER_CLIENT_ABOVE);
+   else
+     e_client_layer_set(ec, E_LAYER_CLIENT_NORMAL);
+
+   e_client_res_change_geometry_save(ec);
+   e_client_res_change_geometry_restore(ec);
+   ec->pre_res_change.valid = 0;
+
+   return;
+}
+
+#ifdef EC_IS_NOT_VISIBLE
+# undef EC_IS_NOT_VISIBLE
+#endif
+#define EC_IS_NOT_VISIBLE if (e_client_visibility_get(ec) != E_VISIBILITY_UNOBSCURED)
+
+EINTERN Eina_Bool
+e_policy_zone_visibility_calculate(E_Zone *zone)
+{
+   E_Client *ec;
+
+   Eina_Tiler *t;
+   Eina_Rectangle r, *_r;
+   Eina_Iterator *it;
+   Eina_Bool canvas_vis = EINA_TRUE;
+   Eina_Bool ec_vis, ec_opaque, calc_region;
+   Eina_Bool skip_rot_pending_show = EINA_FALSE;
+   int skip_by_pending_show = 0;
+   Eina_Bool is_above_show_pending = EINA_FALSE;
+   Eina_Bool is_launching_effect = EINA_FALSE;
+   Eina_Bool is_vis_on_skip = EINA_FALSE;
+
+   int x = 0, y = 0, w = 0, h = 0;
+   const int edge = 1;
+   E_Comp_Wl_Client_Data *cdata;
+   Eina_List *changed_list = NULL;
+   Eina_List *l = NULL;
+   Eina_Bool effect_running = EINA_FALSE;
+   Eina_Bool ec_frame_visible = EINA_FALSE;
+   int calc_skip_type = 0;
+
+   Eina_Bool touched_win_changed = EINA_FALSE;
+   E_Client *touched_ec;
+
+   Eina_Bool iconified_by_client = EINA_FALSE;
+   Eina_Bool e_visibility_changed = EINA_FALSE;
+
+   if (!e_config->calc_vis_without_effect)
+     {
+        E_Comp *comp = e_comp_get();
+
+        if (comp && comp->animating) return EINA_FALSE;
+     }
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(zone, EINA_FALSE);
+
+   TRACE_DS_BEGIN(CLIENT:VISIBILITY CALCULATE);
+
+   t = eina_tiler_new(zone->w + zone->x + edge, zone->h + zone->y + edge);
+   eina_tiler_tile_size_set(t, 1, 1);
+
+   if (e_zone_is_displaying(zone))
+     {
+        EINA_RECTANGLE_SET(&r, zone->x, zone->y, zone->w, zone->h);
+        eina_tiler_rect_add(t, &r);
+     }
+   else
+     {
+        canvas_vis = EINA_FALSE;
+     }
+
+   E_CLIENT_REVERSE_FOREACH(ec)
+     {
+        calc_skip_type = 0;
+        if (e_object_is_del(E_OBJECT(ec))) continue;
+        if (e_client_util_ignored_get(ec)) continue;
+        if (!e_zone_has_ec(zone, ec)) continue;
+        if (!e_client_view_get(ec)) continue;
+        if (ec->visibility.skip) continue;
+        if (ec->is_cursor) continue;
+        cdata = e_client_cdata_get(ec);
+        if (e_comp_wl_subsurface_check(ec)) continue;
+        if ((!ec->first_mapped) &&
+            (e_comp_object_content_type_get(ec->frame) == E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)) continue;
+
+        /* TODO: need to check whether window intersects with entire screen, not zone. */
+        /* if (!E_INTERSECTS(ec->x, ec->y, ec->w, ec->h, zone->x, zone->y, zone->w, zone->h)) continue; */
+
+        if (!e_zone_is_displaying(zone))
+          {
+             if ((e_client_visibility_get(ec) == E_VISIBILITY_FULLY_OBSCURED) &&
+                 (ec->visibility.last_sent_type != E_VISIBILITY_FULLY_OBSCURED))
+               {
+                  ec->visibility.changed = 1;
+               }
+          }
 
-  policy_zone = wl_container_of(listener, policy_zone, zone_destroy);
+        if (!e_config->calc_vis_without_effect)
+          {
+             if ((e_view_client_is_animating(e_client_view_get(ec))) ||
+                 (e_view_data_get(e_view_client_view_get(e_client_view_get(ec)), "effect_running")))
+               {
+                  effect_running = EINA_TRUE;
+                  if (ec->launching)
+                    is_launching_effect = EINA_TRUE;
+                  continue;
+               }
+          }
+
+        e_client_geometry_get(ec, &x, &y, &w, &h);
+        w = w + edge;
+        h = h + edge;
+
+        ec_vis = ec_opaque = skip_rot_pending_show = is_vis_on_skip = EINA_FALSE;
+        skip_by_pending_show = 0;
+        calc_region = EINA_TRUE;
+        ec_frame_visible = e_view_client_visible_get(e_client_view_get(ec));
+        iconified_by_client = e_client_is_iconified_by_client(ec);
+
+        if (!ec->visible)
+          {
+             EC_IS_NOT_VISIBLE continue;
+             calc_region = EINA_FALSE;
+             calc_skip_type |= 0x01;
+          }
+        else if (!ec_frame_visible)
+          {
+             if (ec->e.state.rot.pending_show)
+               {
+                  calc_region = EINA_FALSE;
+                  calc_skip_type |= 0x02;
+                  skip_rot_pending_show = EINA_TRUE;
+                  skip_by_pending_show = 1;
+               }
+             else if (ec->show_pending.count > 0)
+               {
+                  calc_region = EINA_FALSE;
+                  calc_skip_type |= 0x100;
+                  skip_by_pending_show = 2;
+               }
+             else
+               {
+                  if (cdata && !cdata->mapped)
+                    {
+                       EC_IS_NOT_VISIBLE continue;
+                       calc_region = EINA_FALSE;
+                       calc_skip_type |= 0x04;
+                    }
 
-  e_object_unref(E_OBJECT(policy_zone->zone));
-  policy_zone->zone = NULL;
+                  if (!ec->iconic)
+                    {
+                       EC_IS_NOT_VISIBLE continue;
+                       calc_region = EINA_FALSE;
+                       calc_skip_type |= 0x08;
+                    }
+                  else
+                    {
+                       if (iconified_by_client)
+                         {
+                            EC_IS_NOT_VISIBLE continue;
+
+                            E_Iconified_Type iconified_type;
+                            iconified_type = e_client_iconified_type_get(ec);
+                            if (iconified_type == E_ICONIFIED_TYPE_ICONIFY_BY_CLIENT)
+                              calc_skip_type |= 0x10;
+                            else if (iconified_type == E_ICONIFIED_TYPE_DESK_ICONIFY_BY_CLIENT)
+                              calc_skip_type |= 0x20;
+                            else if (iconified_type == E_ICONIFIED_TYPE_PARENT_ICONIFY_BY_CLIENT)
+                              calc_skip_type |= 0x40;
+                            else
+                              {
+                                 ELOGF("POL_VIS", "CRI. Check iconified_type... cur type:%d", ec, iconified_type);
+                                 calc_skip_type |= 0x80;
+                              }
+                            calc_region = EINA_FALSE;
+                         }
+                    }
+
+                  if (ec->bg_state)
+                    {
+                       EC_IS_NOT_VISIBLE continue;
+                       calc_region = EINA_FALSE;
+                       calc_skip_type |= 0x200;
+                    }
+               }
+          }
+
+        if (ec->visibility.ignore_geometry)
+          {
+             calc_region = EINA_FALSE;
+             if (e_zone_is_displaying(zone) && ec_frame_visible)
+               ec_vis = EINA_TRUE;
+          }
+
+        if (canvas_vis)
+          {
+             if (calc_region &&
+                 (!ec->visibility.force_obscured) &&
+                 (!ec->iconic || (ec->iconic && (!iconified_by_client))))
+               {
+                  it = eina_tiler_iterator_new(t);
+                  EINA_ITERATOR_FOREACH(it, _r)
+                    {
+                       if (E_INTERSECTS(x, y, w, h,
+                                        _r->x, _r->y, _r->w, _r->h))
+                         {
+                            ec_vis = EINA_TRUE;
+                            break;
+                         }
+                    }
+                  eina_iterator_free(it);
+               }
+          }
+
+        if (ec_vis)
+          {
+             /* unobscured case */
+             EC_IS_NOT_VISIBLE
+               {
+                  if ((!is_above_show_pending) &&
+                      ((!effect_running) ||
+                       ((effect_running) && (!is_launching_effect))))
+                    {
+                       /* previous state is obscured: -1 or 1 */
+                       e_client_visibility_set(ec, E_VISIBILITY_UNOBSCURED);
+                       ec->visibility.changed = 1;
+                       ELOGF("POL_VIS", "CLIENT VIS ON.  argb:%d, opaque:%2d, frame_v:%d, ignore_geometry:%d, cdata:%p, geo(%d,%d,%dx%d), asp:%d, er:%d, le:%d", ec, ec->argb, ec->visibility.opaque, ec_frame_visible, ec->visibility.ignore_geometry, cdata, x, y, w, h, is_above_show_pending, effect_running, is_launching_effect);
+                    }
+                  else
+                    {
+                       if (!is_above_show_pending)
+                         is_vis_on_skip = EINA_TRUE;
+                       ELOGF("POL_VIS", "CLIENT VIS ON-SKIP. argb:%d, opaque:%2d, frame_v:%d, ignore_geometry:%d, cdata:%p, geo(%d,%d,%dx%d), asp:%d, er:%d, le:%d", ec, ec->argb, ec->visibility.opaque, ec_frame_visible, ec->visibility.ignore_geometry, cdata, x, y, w, h, is_above_show_pending, effect_running, is_launching_effect);
+                    }
+               }
+
+             /* subtract window region from canvas region */
+             if (canvas_vis && !skip_by_pending_show && !is_vis_on_skip)
+               {
+                  /* check alpha window is opaque or not. */
+                  if ((ec->visibility.opaque > 0) && (ec->argb))
+                    ec_opaque = EINA_TRUE;
+
+                  /* if e_client is not alpha or opaque then delete intersect rect */
+                  if (((!ec->argb) || (ec_opaque)) &&
+                      (!ec->floating))
+                    {
+                       EINA_RECTANGLE_SET(&r,
+                                          x,
+                                          y,
+                                          w,
+                                          h);
+                       eina_tiler_rect_del(t, &r);
+
+                       if (eina_tiler_empty(t))
+                         canvas_vis = EINA_FALSE;
+                    }
+               }
+          }
+        else
+          {
+             /* It prevents unwanted iconification of the top visible window
+              * while showing an window with rotation mode.
+              * However, with rotation mode, iconification is done if client
+              * is iconified by itself.
+              */
+             if ((!skip_by_pending_show) ||
+                 (ec->visibility.force_obscured) ||
+                 (ec->bg_state) ||
+                 (iconified_by_client))
+               {
+                  /* obscured case */
+                  if (e_client_visibility_get(ec) != E_VISIBILITY_FULLY_OBSCURED)
+                    {
+                       /* previous state is unobscured: -1 or 0 */
+                       e_client_visibility_set(ec, E_VISIBILITY_FULLY_OBSCURED);
+                       ec->visibility.changed = 1;
+                       ELOGF("POL_VIS", "CLIENT VIS OFF. argb:%d, opaque:%2d, frame_v:%d, canvas_v:%d, calc_r:%d(%d), ignore_geometry:%d, show_p:%d, geo(%d,%d,%dx%d)",
+                             ec, ec->argb, ec->visibility.opaque,
+                             ec_frame_visible, canvas_vis, calc_region, calc_skip_type, ec->visibility.ignore_geometry, skip_by_pending_show, x, y, w, h);
+                    }
+               }
+          }
+
+        if (!is_vis_on_skip &&
+            (!skip_rot_pending_show || ec->visibility.changed))
+          changed_list = eina_list_append(changed_list, ec);
+
+        if (skip_rot_pending_show)
+          {
+             if (ec->e.state.rot.pending_show && !ec->argb)
+               is_above_show_pending = EINA_TRUE;
+             ELOGF("POL_VIS", "Rotation pending show. srps:%d, rps:%d, argb:%d, asp:%d", ec, skip_rot_pending_show, ec->e.state.rot.pending_show, ec->argb, is_above_show_pending);
+          }
+     }
+
+   if (changed_list)
+     {
+        E_Comp_Wl_Data *comp_wl = e_comp_wl_get();
+        if (comp_wl)
+          {
+             touched_ec = comp_wl->ptr.ec ? comp_wl->ptr.ec : comp_wl->touch.faked_ec;
+             EINA_LIST_FOREACH(changed_list, l, ec)
+               {
+                  e_client_visibility_change_notify(ec);
+
+                  if (ec == touched_ec)
+                     touched_win_changed = EINA_TRUE;
+
+                  if (e_client_visibility_get(ec) == E_VISIBILITY_UNOBSCURED)
+                    {
+                       if (comp_wl->touch.pressed && !touched_win_changed && !e_policy_client_is_keyboard_sub(ec))
+                         {
+                            if (e_client_visibility_touched_check(ec))
+                              {
+                                 touched_win_changed = EINA_TRUE;
+                                 e_comp_wl_touch_cancel();
+                              }
+                         }
+                    }
+
+                  if (ec->visibility.changed)
+                    {
+                       ec->visibility.changed = 0;
+                       e_visibility_changed = EINA_TRUE;
+                    }
+               }
+
+             changed_list = eina_list_free(changed_list);
+          }
+     }
+   eina_tiler_free(t);
+
+   // FIXME: need to notify a hook call for zone, not for client
+   e_client_visibility_end_notify();
+
+   TRACE_DS_END();
+
+   return e_visibility_changed;
+}
+
+EINTERN void
+e_policy_zone_desk_count_set(E_Policy_Zone *policy_zone, int x_count, int y_count)
+{
+   E_Zone *zone;
+   EINA_SAFETY_ON_NULL_RETURN(policy_zone);
+   EINA_SAFETY_ON_NULL_RETURN(policy_zone->zone);
+
+   zone = policy_zone->zone;
+
+   e_zone_desk_count_set(zone, x_count, y_count);
+}
+
+EINTERN void
+e_policy_zone_focus_clear(E_Policy_Zone *policy_zone)
+{
+   EINA_SAFETY_ON_NULL_RETURN(policy_zone);
+
+   wl_signal_emit(&policy_zone->events.focus_clear, NULL);
+}
+
+EINTERN void
+e_policy_zone_focus_reset(E_Policy_Zone *policy_zone)
+{
+   EINA_SAFETY_ON_NULL_RETURN(policy_zone);
+
+   wl_signal_emit(&policy_zone->events.focus_reset, NULL);
+}
+
+EINTERN void
+e_policy_zone_client_add_listener_add(E_Policy_Zone *policy_zone, struct wl_listener *listener)
+{
+   EINA_SAFETY_ON_NULL_RETURN(policy_zone);
+   wl_signal_add(&policy_zone->events.client_add, listener);
+}
+
+EINTERN void
+e_policy_zone_client_remove_listener_add(E_Policy_Zone *policy_zone, struct wl_listener *listener)
+{
+   EINA_SAFETY_ON_NULL_RETURN(policy_zone);
+   wl_signal_add(&policy_zone->events.client_remove, listener);
+}
+
+EINTERN void
+e_policy_zone_focus_clear_listener_add(E_Policy_Zone *policy_zone, struct wl_listener *listener)
+{
+   EINA_SAFETY_ON_NULL_RETURN(policy_zone);
+   wl_signal_add(&policy_zone->events.focus_clear, listener);
+}
+
+EINTERN void
+e_policy_zone_focus_reset_listener_add(E_Policy_Zone *policy_zone, struct wl_listener *listener)
+{
+   EINA_SAFETY_ON_NULL_RETURN(policy_zone);
+   wl_signal_add(&policy_zone->events.focus_reset, listener);
+}
+
+EINTERN E_Zone *
+e_policy_zone_get_zone(E_Policy_Zone *policy_zone)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(policy_zone, NULL);
+   return policy_zone->zone;
 }
 
 EINTERN E_Policy_Zone *
@@ -33,6 +1413,12 @@ e_policy_zone_new(E_Zone *zone)
    policy_zone->zone = zone;
    e_object_ref(E_OBJECT(zone));
 
+   // events
+   wl_signal_init(&policy_zone->events.client_add);
+   wl_signal_init(&policy_zone->events.client_remove);
+   wl_signal_init(&policy_zone->events.focus_clear);
+   wl_signal_init(&policy_zone->events.focus_reset);
+
    n = zone->desk_y_count * zone->desk_x_count;
    for (i = 0; i < n; i++)
      {
@@ -48,11 +1434,75 @@ e_policy_zone_new(E_Zone *zone)
           e_policy_desk_add(zone->desks[i]);
      }
 
+   // TODO: adjust each focus poicy to each zone.
+   // Create E_Focus at only default zone which the zone num is 0
+   if (zone->num == 0)
+     {
+        if (e_config->focus_policy_ext == E_FOCUS_EXT_TOP_STACK)
+          zone->focus = e_focus_new(policy_zone, E_FOCUS_EXT_TOP_STACK);
+        else
+          // default focus policy is E_FOCUS_EXT_HISTORY
+          zone->focus = e_focus_new(policy_zone, E_FOCUS_EXT_HISTORY);
+        if (!zone->focus)
+          {
+             e_object_del(E_OBJECT(zone));
+             ERR("Fail to create focus object at zone %d", zone->num);
+             return NULL;
+          }
+     }
+
+   // CLIENT HOOK Handlers
+   E_LIST_HOOK_APPEND(zone->ec_hooks, E_CLIENT_HOOK_NEW_CLIENT_POST, _e_policy_zone_cb_hook_client_new_client_post, zone);
+
    // zone listeners
+   policy_zone->client_add.notify = _e_policy_zone_cb_client_add;
+   e_zone_client_add_listener_add(zone, &policy_zone->client_add);
    policy_zone->zone_destroy.notify = _e_policy_zone_cb_zone_destroy;
    e_zone_destroy_listener_add(zone, &policy_zone->zone_destroy);
+   policy_zone->move.notify = _e_policy_zone_cb_move;
+   e_zone_move_listener_add(zone, &policy_zone->move);
+   policy_zone->resize.notify = _e_policy_zone_cb_resize;
+   e_zone_resize_listener_add(zone, &policy_zone->resize);
+   policy_zone->move_resize.notify = _e_policy_zone_cb_move_resize;
+   e_zone_move_resize_listener_add(zone, &policy_zone->move_resize);
+   policy_zone->is_current.notify = _e_policy_zone_cb_is_current;
+   e_zone_is_current_listener_add(zone, &policy_zone->is_current);
+   policy_zone->desk_count_set.notify = _e_policy_zone_cb_desk_count_set;
+   e_zone_desk_count_set_listener_add(zone, &policy_zone->desk_count_set);
+   policy_zone->obstacle_add.notify = _e_policy_zone_cb_obstacle_add;
+   e_zone_obstacle_add_listener_add(zone, &policy_zone->obstacle_add);
+   policy_zone->obstacle_update.notify = _e_policy_zone_cb_obstacle_update;
+   e_zone_obstacle_update_listener_add(zone, &policy_zone->obstacle_update);
+   policy_zone->obstacle_remove.notify = _e_policy_zone_cb_obstacle_remove;
+   e_zone_obstacle_remove_listener_add(zone, &policy_zone->obstacle_remove);
+   policy_zone->useful_geometry_get.notify = _e_policy_zone_cb_useful_geometry_get;
+   e_zone_useful_geometry_get_listener_add(zone, &policy_zone->useful_geometry_get);
+   policy_zone->bg_mouse_down.notify = _e_policy_zone_cb_bg_mouse_down;
+   e_zone_bg_mouse_down_listener_add(zone, &policy_zone->bg_mouse_down);
+   policy_zone->bg_mouse_up.notify = _e_policy_zone_cb_bg_mouse_up;
+   e_zone_bg_mouse_up_listener_add(zone, &policy_zone->bg_mouse_up);
+
+   policy_zone->focus_focused_ec_changed.notify = _policy_zone_cb_focus_focused_ec_changed;
+   e_focus_focused_ec_changed_listener_add(zone->focus, &policy_zone->focus_focused_ec_changed);
 
    return policy_zone;
 }
 
-#endif
+EINTERN void
+e_policy_zone_del(E_Policy_Zone *policy_zone)
+{
+   EINA_SAFETY_ON_NULL_RETURN(policy_zone);
+
+   e_object_unref(E_OBJECT(policy_zone->zone));
+
+   // TODO:: need policy desk remove?
+
+   // zone listeners
+   wl_list_remove(&policy_zone->zone_destroy.link);
+
+   E_FREE(policy_zone);
+
+   return;
+}
+
+#endif // CONTAINER_POLICY
index b4887c1..7a951c5 100644 (file)
@@ -6,6 +6,19 @@
 
 typedef struct _E_Policy_Zone E_Policy_Zone;
 
-E_Policy_Zone *e_policy_zone_new(E_Zone *zone);
+EINTERN Eina_Bool e_policy_zone_visibility_calculate(E_Zone *zone);
+
+EINTERN void e_policy_zone_desk_count_set(E_Policy_Zone *policy_zone, int x_count, int y_count);
+EINTERN void e_policy_zone_focus_clear(E_Policy_Zone *policy_zone);
+EINTERN void e_policy_zone_focus_reset(E_Policy_Zone *policy_zone);
+
+EINTERN void e_policy_zone_client_add_listener_add(E_Policy_Zone *policy_zone, struct wl_listener *listener);
+EINTERN void e_policy_zone_client_remove_listener_add(E_Policy_Zone *policy_zone, struct wl_listener *listener);
+EINTERN void e_policy_zone_focus_clear_listener_add(E_Policy_Zone *policy_zone, struct wl_listener *listener);
+EINTERN void e_policy_zone_focus_reset_listener_add(E_Policy_Zone *policy_zone, struct wl_listener *listener);
+
+EINTERN E_Zone        *e_policy_zone_get_zone(E_Policy_Zone *policy_zone);
+EINTERN E_Policy_Zone *e_policy_zone_new(E_Zone *zone);
+EINTERN void           e_policy_zone_del(E_Policy_Zone *policy_zone);
 
 #endif