containers: Add some client getters about client stack 04/320604/1
authorJunseok Kim <juns.kim@samsung.com>
Wed, 23 Oct 2024 06:54:08 +0000 (15:54 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Wed, 5 Mar 2025 05:00:11 +0000 (14:00 +0900)
To support multi desk area, Add some getters about client stack
NOTE:: the client list iterator temporary alternated using evas stack
It should be roll backed after modify the layer list of eda.

Change-Id: I8c0f32ee031b666f889e03bc00f921860c81f67b

src/bin/core/e_client.c
src/bin/core/e_client_intern.h
src/bin/core/e_desk.c
src/bin/core/e_desk_area.c
src/bin/core/e_desk_area_intern.h
src/bin/core/e_desk_intern.h
src/bin/core/e_zone.c
src/bin/core/e_zone_intern.h
src/bin/windowmgr/e_policy_desk.c
src/bin/windowmgr/e_policy_desk_area.c
src/bin/windowmgr/e_policy_zone.c

index aa87399f1c3a0743528b7325c38be9473f2687b8..8f395e12b6436e7e2ccb59361f490fdf46aeb1d3 100644 (file)
@@ -110,6 +110,8 @@ struct _E_Client_Private
         struct wl_signal get_below;
         struct wl_signal get_visible_above;
         struct wl_signal get_visible_below;
+        struct wl_signal get_top;
+        struct wl_signal get_bottom;
         struct wl_signal subsurface_stack_update;
 
         struct wl_signal delete_request;
@@ -1052,6 +1054,8 @@ _e_client_private_init(E_Client *ec)
    wl_signal_init(&priv->events.get_below);
    wl_signal_init(&priv->events.get_visible_above);
    wl_signal_init(&priv->events.get_visible_below);
+   wl_signal_init(&priv->events.get_top);
+   wl_signal_init(&priv->events.get_bottom);
    wl_signal_init(&priv->events.subsurface_stack_update);
 
    wl_signal_init(&priv->events.delete_request);
@@ -3962,13 +3966,13 @@ e_client_above_get(const E_Client *ec)
 {
    API_ENTRY_VAL(NULL);
 
-   E_Client_Data_Get_Above data;
+   E_Client_Data_Get_Client data = {0};
 
-   data.above_ec = NULL;
+   data.criterion_ec = (E_Client *) ec;
 
    wl_signal_emit(&priv->events.get_above, &data);
 
-   return data.above_ec;
+   return data.result_ec;
 }
 
 E_API E_Client *
@@ -3976,13 +3980,13 @@ e_client_below_get(const E_Client *ec)
 {
    API_ENTRY_VAL(NULL);
 
-   E_Client_Data_Get_Below data;
+   E_Client_Data_Get_Client data = {0};
 
-   data.below_ec = NULL;
+   data.criterion_ec = (E_Client *) ec;
 
    wl_signal_emit(&priv->events.get_below, &data);
 
-   return data.below_ec;
+   return data.result_ec;
 }
 
 EINTERN E_Client *
@@ -3990,13 +3994,13 @@ e_client_visible_above_get(E_Client *ec)
 {
    API_ENTRY_VAL(NULL);
 
-   E_Client_Data_Get_Visible_Above data;
+   E_Client_Data_Get_Client data = {0};
 
-   data.above_ec = NULL;
+   data.criterion_ec = ec;
 
    wl_signal_emit(&priv->events.get_visible_above, &data);
 
-   return data.above_ec;
+   return data.result_ec;
 }
 
 EINTERN E_Client *
@@ -4004,39 +4008,35 @@ e_client_visible_below_get(E_Client *ec)
 {
    API_ENTRY_VAL(NULL);
 
-   E_Client_Data_Get_Visible_Below data;
+   E_Client_Data_Get_Client data = {0};
 
-   data.below_ec = NULL;
+   data.criterion_ec = ec;
 
    wl_signal_emit(&priv->events.get_visible_below, &data);
 
-   return data.below_ec;
+   return data.result_ec;
 }
 
 E_API E_Client *
 e_client_bottom_get(void)
 {
    E_Zone *zone;
-   E_Desk *desk;
 
-   // get the bottom ec from current desk at current zone
+   // get the bottom ec from current zone
    zone = e_zone_current_get();
-   desk = e_desk_current_get(zone);
 
-   return e_desk_bottom_ec_get(desk);
+   return e_zone_client_bottom_get(zone);
 }
 
 E_API E_Client *
 e_client_top_get(void)
 {
    E_Zone *zone;
-   E_Desk *desk;
 
-   // get the top ec from current desk at current zone
+   // get the top ec from current zone
    zone = e_zone_current_get();
-   desk = e_desk_current_get(zone);
 
-   return e_desk_top_ec_get(desk);
+   return e_zone_client_top_get(zone);
 }
 
 EINTERN unsigned int
@@ -7182,6 +7182,20 @@ e_client_subsurface_stack_update_listener_add(E_Client *ec, struct wl_listener *
    wl_signal_add(&priv->events.subsurface_stack_update, listener);
 }
 
+EINTERN void
+e_client_get_top_listener_add(E_Client *ec, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.get_top, listener);
+}
+
+EINTERN void
+e_client_get_bottom_listener_add(E_Client *ec, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.get_bottom, listener);
+}
+
 EINTERN void
 e_client_delete_request_listener_add(E_Client *ec, struct wl_listener *listener)
 {
index 4814844bf46931ef71377b43a67dc35c9abafdd5..9fef2213e929874ee0617cdb95cf84b676d3f759 100644 (file)
@@ -8,25 +8,11 @@
 
 #include <wayland-server.h>
 
-typedef struct _E_Client_Data_Get_Above
+typedef struct _E_Client_Data_Get_Client
 {
-   E_Client *above_ec; // returned above_ec
-} E_Client_Data_Get_Above;
-
-typedef struct _E_Client_Data_Get_Below
-{
-   E_Client *below_ec; // returned below_ec
-} E_Client_Data_Get_Below;
-
-typedef struct _E_Client_Data_Get_Visible_Above
-{
-   E_Client *above_ec; // returned above_ec
-} E_Client_Data_Get_Visible_Above;
-
-typedef struct _E_Client_Data_Get_Visible_Below
-{
-   E_Client *below_ec; // returned below_ec
-} E_Client_Data_Get_Visible_Below;
+   E_Client *criterion_ec;
+   E_Client *result_ec;
+} E_Client_Data_Get_Client;
 
 EINTERN Eina_Bool e_client_init(void);
 EINTERN void      e_client_shutdown(void);
@@ -233,6 +219,8 @@ EINTERN void e_client_get_above_listener_add(E_Client *ec, struct wl_listener *l
 EINTERN void e_client_get_below_listener_add(E_Client *ec, struct wl_listener *listener);
 EINTERN void e_client_get_visible_above_listener_add(E_Client *ec, struct wl_listener *listener);
 EINTERN void e_client_get_visible_below_listener_add(E_Client *ec, struct wl_listener *listener);
+EINTERN void e_client_get_top_listener_add(E_Client *ec, struct wl_listener *listener);
+EINTERN void e_client_get_bottom_listener_add(E_Client *ec, struct wl_listener *listener);
 EINTERN void e_client_subsurface_stack_update_listener_add(E_Client *ec, struct wl_listener *listener);
 
 EINTERN void e_client_delete_request_listener_add(E_Client *ec, struct wl_listener *listener);
index 74c86ee6e0364e8d8541a7d02e1d2752f6ebc287..9e721470046ab712bad27d751142bd4cbc38e407 100644 (file)
@@ -61,6 +61,12 @@ struct _E_Desk_Private
         struct wl_signal visible_client_restore_all;
         struct wl_signal client_iconified_list_remove;
         struct wl_signal client_iconified_list_remove_all;
+        struct wl_signal client_top_get;
+        struct wl_signal client_bottom_get;
+        struct wl_signal client_above_get;
+        struct wl_signal client_below_get;
+        struct wl_signal client_visible_above_get;
+        struct wl_signal client_visible_below_get;
      } events;
 };
 
@@ -115,6 +121,12 @@ _e_desk_private_init(E_Desk *desk)
    wl_signal_init(&priv->events.visible_client_restore_all);
    wl_signal_init(&priv->events.client_iconified_list_remove);
    wl_signal_init(&priv->events.client_iconified_list_remove_all);
+   wl_signal_init(&priv->events.client_top_get);
+   wl_signal_init(&priv->events.client_bottom_get);
+   wl_signal_init(&priv->events.client_above_get);
+   wl_signal_init(&priv->events.client_below_get);
+   wl_signal_init(&priv->events.client_visible_above_get);
+   wl_signal_init(&priv->events.client_visible_below_get);
 
    e_object_data_set(E_OBJECT(desk), priv);
 
@@ -748,45 +760,110 @@ e_desk_has_ec(E_Desk *desk, E_Client *ec)
 }
 
 EINTERN E_Client *
-e_desk_top_ec_get(E_Desk *desk)
+e_desk_client_top_get(E_Desk *desk)
 {
-   E_Desk_Area *eda;
+   E_Desk_Data_Client_Get client_data = {0,};
 
-   EINA_SAFETY_ON_NULL_RETURN_VAL(desk, EINA_FALSE);
+   E_OBJECT_CHECK_RETURN(desk, NULL);
+   E_OBJECT_TYPE_CHECK_RETURN(desk, E_DESK_TYPE, NULL);
 
-   // TODO: get the desk_area which is at top among the desk_areas in this desk
-   eda = desk->desk_area.base;
+   wl_signal_emit(&PRI(desk)->events.client_top_get, &client_data);
 
-   return e_desk_area_top_ec_get(eda);
+   return client_data.result_ec;
 }
 
 EINTERN E_Client *
-e_desk_bottom_ec_get(E_Desk *desk)
+e_desk_client_bottom_get(E_Desk *desk)
 {
-   E_Desk_Area *eda;
+   E_Desk_Data_Client_Get client_data = {0,};
 
-   EINA_SAFETY_ON_NULL_RETURN_VAL(desk, EINA_FALSE);
+   E_OBJECT_CHECK_RETURN(desk, NULL);
+   E_OBJECT_TYPE_CHECK_RETURN(desk, E_DESK_TYPE, NULL);
+
+   wl_signal_emit(&PRI(desk)->events.client_bottom_get, &client_data);
+
+   return client_data.result_ec;
+}
+
+EINTERN E_Client *
+e_desk_client_above_get(E_Desk *desk, E_Client *ec)
+{
+   E_Desk_Data_Client_Get client_data = {0,};
+
+   E_OBJECT_CHECK_RETURN(desk, NULL);
+   E_OBJECT_TYPE_CHECK_RETURN(desk, E_DESK_TYPE, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
+
+   client_data.criterion_ec = ec;
+   wl_signal_emit(&PRI(desk)->events.client_above_get, &client_data);
+
+   return client_data.result_ec;
+}
+
+EINTERN E_Client *
+e_desk_client_below_get(E_Desk *desk, E_Client *ec)
+{
+   E_Desk_Data_Client_Get client_data = {0,};
+
+   E_OBJECT_CHECK_RETURN(desk, NULL);
+   E_OBJECT_TYPE_CHECK_RETURN(desk, E_DESK_TYPE, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
+
+   client_data.criterion_ec = ec;
+   wl_signal_emit(&PRI(desk)->events.client_below_get, &client_data);
+
+   return client_data.result_ec;
+}
+
+EINTERN E_Client *
+e_desk_client_visible_above_get(E_Desk *desk, E_Client *ec)
+{
+   E_Desk_Data_Client_Get client_data = {0,};
+
+   E_OBJECT_CHECK_RETURN(desk, NULL);
+   E_OBJECT_TYPE_CHECK_RETURN(desk, E_DESK_TYPE, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
+
+   client_data.criterion_ec = ec;
+   wl_signal_emit(&PRI(desk)->events.client_visible_above_get, &client_data);
+
+   return client_data.result_ec;
+}
+
+EINTERN E_Client *
+e_desk_client_visible_below_get(E_Desk *desk, E_Client *ec)
+{
+   E_Desk_Data_Client_Get client_data = {0,};
+
+   E_OBJECT_CHECK_RETURN(desk, NULL);
+   E_OBJECT_TYPE_CHECK_RETURN(desk, E_DESK_TYPE, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
 
-   // TODO: get the desk_area which is at bottom among the desk_areas in this desk
-   eda = desk->desk_area.base;
+   client_data.criterion_ec = ec;
+   wl_signal_emit(&PRI(desk)->events.client_visible_below_get, &client_data);
 
-   return e_desk_area_bottom_ec_get(eda);
+   return client_data.result_ec;
 }
 
 E_API E_Desk_Area *
 e_desk_desk_area_find_by_ec(E_Desk *desk, E_Client *ec)
 {
    E_Desk_Area *eda;
+   Eina_List *l;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(desk, NULL);
    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
 
    if (!e_desk_has_ec(desk, ec)) return NULL;
 
-   // TODO: find the desk_area which has the ec among the desk_areas in this desk
-   eda = desk->desk_area.base;
-   if (e_desk_area_has_ec(eda, ec))
-     return eda;
+   for (int i=E_DESK_AREA_LAYER_COUNT-1; i>=0; i--)
+     {
+       EINA_LIST_FOREACH(desk->desk_area.list[i], l, eda)
+         {
+            if (e_desk_area_has_ec(eda, ec))
+              return eda;
+         }
+     }
 
    return NULL;
 }
@@ -993,3 +1070,45 @@ e_desk_client_iconified_list_remove_all_listener_add(E_Desk *desk, struct wl_lis
    API_ENTRY;
    wl_signal_add(&priv->events.client_iconified_list_remove_all, listener);
 }
+
+EINTERN void
+e_desk_client_top_get_listener_add(E_Desk *desk, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.client_top_get, listener);
+}
+
+EINTERN void
+e_desk_client_bottom_get_listener_add(E_Desk *desk, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.client_bottom_get, listener);
+}
+
+EINTERN void
+e_desk_client_above_get_listener_add(E_Desk *desk, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.client_above_get, listener);
+}
+
+EINTERN void
+e_desk_client_below_get_listener_add(E_Desk *desk, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.client_below_get, listener);
+}
+
+EINTERN void
+e_desk_client_visible_above_get_listener_add(E_Desk *desk, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.client_visible_above_get, listener);
+}
+
+EINTERN void
+e_desk_client_visible_below_get_listener_add(E_Desk *desk, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.client_visible_below_get, listener);
+}
index 87f2117c50ae49f917943daa8a7619cf3cc54145..fbaf8ed970cbad33fdf218522001d7569f7ea2ff 100644 (file)
@@ -31,6 +31,10 @@ struct _E_Desk_Area_Private
       struct wl_signal lower;
       struct wl_signal top_ec_get;
       struct wl_signal bottom_ec_get;
+      struct wl_signal client_above_get;
+      struct wl_signal client_below_get;
+      struct wl_signal client_visible_above_get;
+      struct wl_signal client_visible_below_get;
       struct wl_signal has_ec;
 
       struct wl_signal client_add;
@@ -89,6 +93,10 @@ _e_desk_area_private_init(E_Desk_Area *eda)
    wl_signal_init(&priv->events.lower);
    wl_signal_init(&priv->events.top_ec_get);
    wl_signal_init(&priv->events.bottom_ec_get);
+   wl_signal_init(&priv->events.client_above_get);
+   wl_signal_init(&priv->events.client_below_get);
+   wl_signal_init(&priv->events.client_visible_above_get);
+   wl_signal_init(&priv->events.client_visible_below_get);
    wl_signal_init(&priv->events.has_ec);
    wl_signal_init(&priv->events.client_add);
    wl_signal_init(&priv->events.client_del);
@@ -313,7 +321,7 @@ e_desk_area_top_ec_get(E_Desk_Area *eda)
    get_data.eda = eda;
    wl_signal_emit(&PRI(eda)->events.top_ec_get, &get_data);
 
-   return get_data.ec;
+   return get_data.result_ec;
 }
 
 EINTERN E_Client *
@@ -326,7 +334,67 @@ e_desk_area_bottom_ec_get(E_Desk_Area *eda)
    get_data.eda = eda;
    wl_signal_emit(&PRI(eda)->events.bottom_ec_get, &get_data);
 
-   return get_data.ec;
+   return get_data.result_ec;
+}
+
+EINTERN E_Client *
+e_desk_area_client_above_get(E_Desk_Area *eda, E_Client *ec)
+{
+   E_Desk_Area_Data_EC_Get get_data = {};
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(eda, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
+
+   get_data.eda = eda;
+   get_data.criterion_ec = ec;
+   wl_signal_emit(&PRI(eda)->events.client_above_get, &get_data);
+
+   return get_data.result_ec;
+}
+
+EINTERN E_Client *
+e_desk_area_client_below_get(E_Desk_Area *eda, E_Client *ec)
+{
+   E_Desk_Area_Data_EC_Get get_data = {};
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(eda, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
+
+   get_data.eda = eda;
+   get_data.criterion_ec = ec;
+   wl_signal_emit(&PRI(eda)->events.client_below_get, &get_data);
+
+   return get_data.result_ec;
+}
+
+EINTERN E_Client *
+e_desk_area_client_visible_above_get(E_Desk_Area *eda, E_Client *ec)
+{
+   E_Desk_Area_Data_EC_Get get_data = {};
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(eda, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
+
+   get_data.eda = eda;
+   get_data.criterion_ec = ec;
+   wl_signal_emit(&PRI(eda)->events.client_visible_above_get, &get_data);
+
+   return get_data.result_ec;
+}
+
+EINTERN E_Client *
+e_desk_area_client_visible_below_get(E_Desk_Area *eda, E_Client *ec)
+{
+   E_Desk_Area_Data_EC_Get get_data = {};
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(eda, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
+
+   get_data.eda = eda;
+   get_data.criterion_ec = ec;
+   wl_signal_emit(&PRI(eda)->events.client_visible_below_get, &get_data);
+
+   return get_data.result_ec;
 }
 
 EINTERN Eina_Bool
@@ -335,6 +403,7 @@ e_desk_area_has_ec(E_Desk_Area *eda, E_Client *ec)
    E_Desk_Area_Data_Has_EC data = {0,};
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(eda, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
 
    data.eda = eda;
    data.ec = ec;
@@ -394,6 +463,34 @@ e_desk_area_bottom_ec_get_listener_add(E_Desk_Area *eda, struct wl_listener *lis
    wl_signal_add(&priv->events.bottom_ec_get, listener);
 }
 
+EINTERN void
+e_desk_area_client_above_get_listener_add(E_Desk_Area *eda, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.client_above_get, listener);
+}
+
+EINTERN void
+e_desk_area_client_below_get_listener_add(E_Desk_Area *eda, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.client_below_get, listener);
+}
+
+EINTERN void
+e_desk_area_client_visible_above_get_listener_add(E_Desk_Area *eda, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.client_visible_above_get, listener);
+}
+
+EINTERN void
+e_desk_area_client_visible_below_get_listener_add(E_Desk_Area *eda, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.client_visible_below_get, listener);
+}
+
 EINTERN void
 e_desk_area_has_ec_listener_add(E_Desk_Area *eda, struct wl_listener *listener)
 {
index 057391a45ab136107a5f6b4b6cc51db0b7b910b9..0a61707853aed660d70f0efe8ccc7f2f718d6782 100644 (file)
@@ -61,7 +61,8 @@ struct _E_Desk_Area
 typedef struct _E_Desk_Area_Data_EC_Get
 {
    E_Desk_Area *eda;
-   E_Client *ec;
+   E_Client *criterion_ec;
+   E_Client *result_ec;
 } E_Desk_Area_Data_EC_Get;
 
 typedef struct _E_Desk_Area_Data_Has_EC
@@ -80,6 +81,10 @@ EINTERN Eina_Bool    e_desk_area_layer_set(E_Desk_Area *eda, E_Desk_Area_Layer l
 EINTERN const char  *e_desk_area_name_get(E_Desk_Area *eda);
 EINTERN E_Client    *e_desk_area_top_ec_get(E_Desk_Area *eda);
 EINTERN E_Client    *e_desk_area_bottom_ec_get(E_Desk_Area *eda);
+EINTERN E_Client    *e_desk_area_client_above_get(E_Desk_Area *eda, E_Client *ec);
+EINTERN E_Client    *e_desk_area_client_below_get(E_Desk_Area *eda, E_Client *ec);
+EINTERN E_Client    *e_desk_area_client_visible_above_get(E_Desk_Area *eda, E_Client *ec);
+EINTERN E_Client    *e_desk_area_client_visible_below_get(E_Desk_Area *eda, E_Client *ec);
 EINTERN Eina_Bool    e_desk_area_has_ec(E_Desk_Area *eda, E_Client *ec);
 
 // for debug
@@ -93,6 +98,10 @@ EINTERN void e_desk_area_raise_listener_add(E_Desk_Area *eda, struct wl_listener
 EINTERN void e_desk_area_lower_listener_add(E_Desk_Area *eda, struct wl_listener *listener);
 EINTERN void e_desk_area_top_ec_get_listener_add(E_Desk_Area *eda, struct wl_listener *listener);
 EINTERN void e_desk_area_bottom_ec_get_listener_add(E_Desk_Area *eda, struct wl_listener *listener);
+EINTERN void e_desk_area_client_above_get_listener_add(E_Desk_Area *eda, struct wl_listener *listener);
+EINTERN void e_desk_area_client_below_get_listener_add(E_Desk_Area *eda, struct wl_listener *listener);
+EINTERN void e_desk_area_client_visible_above_get_listener_add(E_Desk_Area *eda, struct wl_listener *listener);
+EINTERN void e_desk_area_client_visible_below_get_listener_add(E_Desk_Area *eda, struct wl_listener *listener);
 EINTERN void e_desk_area_has_ec_listener_add(E_Desk_Area *eda, struct wl_listener *listener);
 EINTERN void e_desk_area_client_add_listener_add(E_Desk_Area *eda, struct wl_listener *listener);
 EINTERN void e_desk_area_client_del_listener_add(E_Desk_Area *eda, struct wl_listener *listener);
index 2f630a710ef2b2a1eec097b7bfe220d7e55bb437..9f663713ec6f3ea85c7e665de2a71d8e47cf4d66 100644 (file)
@@ -43,6 +43,12 @@ typedef struct _E_Desk_Data_Client_Zoom
    Eina_Bool result;
 } E_Desk_Data_Client_Zoom;
 
+typedef struct _E_Desk_Data_Client_Get
+{
+   E_Client *criterion_ec;
+   E_Client *result_ec;
+} E_Desk_Data_Client_Get;
+
 extern EINTERN int E_EVENT_DESK_SHOW;
 extern EINTERN int E_EVENT_DESK_BEFORE_SHOW;
 extern EINTERN int E_EVENT_DESK_AFTER_SHOW;
@@ -61,8 +67,12 @@ EINTERN void         e_desk_deskshow(E_Zone *zone);
 EINTERN E_Client    *e_desk_client_top_visible_get(E_Desk *desk);
 EINTERN void         e_desk_xy_get(E_Desk *desk, int *x, int *y);
 EINTERN Eina_Bool    e_desk_has_ec(E_Desk *desk, E_Client *ec);
-EINTERN E_Client    *e_desk_top_ec_get(E_Desk *desk);
-EINTERN E_Client    *e_desk_bottom_ec_get(E_Desk *desk);
+EINTERN E_Client    *e_desk_client_top_get(E_Desk *desk);
+EINTERN E_Client    *e_desk_client_bottom_get(E_Desk *desk);
+EINTERN E_Client    *e_desk_client_above_get(E_Desk *desk, E_Client *ec);
+EINTERN E_Client    *e_desk_client_below_get(E_Desk *desk, E_Client *ec);
+EINTERN E_Client    *e_desk_client_visible_above_get(E_Desk *desk, E_Client *ec);
+EINTERN E_Client    *e_desk_client_visible_below_get(E_Desk *desk, E_Client *ec);
 EINTERN unsigned int e_desks_count(void);
 
 EINTERN Eina_Bool    e_desk_zoom_get_center_coordinate(E_Desk *desk, double zoomx, double zoomy, int rectx, int recty, int *cx, int *cy);
@@ -110,5 +120,12 @@ EINTERN void e_desk_visible_client_iconify_all_listener_add(E_Desk *desk, struct
 EINTERN void e_desk_visible_client_restore_all_listener_add(E_Desk *desk, struct wl_listener *listener);
 EINTERN void e_desk_client_iconified_list_remove_listener_add(E_Desk *desk, struct wl_listener *listener);
 EINTERN void e_desk_client_iconified_list_remove_all_listener_add(E_Desk *desk, struct wl_listener *listener);
+EINTERN void e_desk_client_top_get_listener_add(E_Desk *desk, struct wl_listener *listener);
+EINTERN void e_desk_client_bottom_get_listener_add(E_Desk *desk, struct wl_listener *listener);
+EINTERN void e_desk_client_above_get_listener_add(E_Desk *desk, struct wl_listener *listener);
+EINTERN void e_desk_client_below_get_listener_add(E_Desk *desk, struct wl_listener *listener);
+EINTERN void e_desk_client_visible_above_get_listener_add(E_Desk *desk, struct wl_listener *listener);
+EINTERN void e_desk_client_visible_below_get_listener_add(E_Desk *desk, struct wl_listener *listener);
+
 
 #endif
index ceefe199bf507b39329250d56a0df9e63b081947..0130cdce732a8b21b2e08cfe1841cc1521b5be9a 100644 (file)
@@ -54,6 +54,12 @@ struct _E_Zone_Private
         struct wl_signal desk_count;
         struct wl_signal client_add;
         struct wl_signal focused_client_get;
+        struct wl_signal zone_client_top_get;
+        struct wl_signal zone_client_bottom_get;
+        struct wl_signal zone_client_above_get;
+        struct wl_signal zone_client_below_get;
+        struct wl_signal zone_client_visible_above_get;
+        struct wl_signal zone_client_visible_below_get;
      } events;
 
    struct wl_listener focus_focused_ec_changed;
@@ -139,6 +145,12 @@ _e_zone_private_init(E_Zone *zone)
    wl_signal_init(&priv->events.desk_count);
    wl_signal_init(&priv->events.client_add);
    wl_signal_init(&priv->events.focused_client_get);
+   wl_signal_init(&priv->events.zone_client_top_get);
+   wl_signal_init(&priv->events.zone_client_bottom_get);
+   wl_signal_init(&priv->events.zone_client_above_get);
+   wl_signal_init(&priv->events.zone_client_below_get);
+   wl_signal_init(&priv->events.zone_client_visible_above_get);
+   wl_signal_init(&priv->events.zone_client_visible_below_get);
 
    e_object_data_set(E_OBJECT(zone), priv);
 
@@ -1148,6 +1160,86 @@ e_zone_client_set_event_emit(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);
 }
 
+EINTERN E_Client *
+e_zone_client_top_get(E_Zone *zone)
+{
+   E_Zone_Data_Client_Get data = {0};
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(zone, NULL);
+
+   wl_signal_emit(&PRI(zone)->events.zone_client_top_get, &data);
+
+   return data.result_ec;
+}
+
+EINTERN E_Client *
+e_zone_client_bottom_get(E_Zone *zone)
+{
+   E_Zone_Data_Client_Get data = {0};
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(zone, NULL);
+
+   wl_signal_emit(&PRI(zone)->events.zone_client_bottom_get, &data);
+
+   return data.result_ec;
+}
+
+EINTERN E_Client *
+e_zone_client_above_get(E_Zone *zone, E_Client *ec)
+{
+   E_Zone_Data_Client_Get data = {0};
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(zone, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
+
+   data.criterion_ec = ec;
+   wl_signal_emit(&PRI(zone)->events.zone_client_above_get, &data);
+
+   return data.result_ec;
+}
+
+EINTERN E_Client *
+e_zone_client_below_get(E_Zone *zone, E_Client *ec)
+{
+   E_Zone_Data_Client_Get data = {0};
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(zone, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
+
+   data.criterion_ec = ec;
+   wl_signal_emit(&PRI(zone)->events.zone_client_below_get, &data);
+
+   return data.result_ec;
+}
+
+EINTERN E_Client *
+e_zone_client_visible_above_get(E_Zone *zone, E_Client *ec)
+{
+   E_Zone_Data_Client_Get data = {0};
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(zone, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
+
+   data.criterion_ec = ec;
+   wl_signal_emit(&PRI(zone)->events.zone_client_visible_above_get, &data);
+
+   return data.result_ec;
+}
+
+EINTERN E_Client *
+e_zone_client_visible_below_get(E_Zone *zone, E_Client *ec)
+{
+   E_Zone_Data_Client_Get data = {0};
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(zone, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
+
+   data.criterion_ec = ec;
+   wl_signal_emit(&PRI(zone)->events.zone_client_visible_below_get, &data);
+
+   return data.result_ec;
+}
+
 EINTERN void
 e_zone_destroy_listener_add(E_Zone *zone, struct wl_listener *listener)
 {
@@ -1251,6 +1343,48 @@ e_zone_focused_client_get_listener_add(E_Zone *zone, struct wl_listener *listene
    wl_signal_add(&priv->events.focused_client_get, listener);
 }
 
+EINTERN void
+e_zone_client_top_get_listener_add(E_Zone *zone, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.zone_client_top_get, listener);
+}
+
+EINTERN void
+e_zone_client_bottom_get_listener_add(E_Zone *zone, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.zone_client_bottom_get, listener);
+}
+
+EINTERN void
+e_zone_client_above_get_listener_add(E_Zone *zone, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.zone_client_above_get, listener);
+}
+
+EINTERN void
+e_zone_client_below_get_listener_add(E_Zone *zone, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.zone_client_below_get, listener);
+}
+
+EINTERN void
+e_zone_client_visible_above_get_listener_add(E_Zone *zone, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.zone_client_visible_above_get, listener);
+}
+
+EINTERN void
+e_zone_client_visible_below_get_listener_add(E_Zone *zone, struct wl_listener *listener)
+{
+   API_ENTRY;
+   wl_signal_add(&priv->events.zone_client_visible_below_get, listener);
+}
+
 EINTERN void
 e_desk_row_add(E_Zone *zone)
 {
index 1bf652561daa1755dddd7df49475720fee50f36e..0742d9a4208848a583bcde23be2541c4f94d6dfc 100644 (file)
@@ -87,6 +87,12 @@ typedef struct _E_Zone_Data_Desk_Count
    unsigned int count;
 } E_Zone_Data_Desk_Count;
 
+typedef struct _E_Zone_Data_Client_Get
+{
+   E_Client *criterion_ec;
+   E_Client *result_ec;
+} E_Zone_Data_Client_Get;
+
 
 EINTERN int e_zone_init(void);
 EINTERN int e_zone_shutdown(void);
@@ -114,6 +120,13 @@ EINTERN void      e_zone_obstacle_remove(E_Zone *zone, E_Client *ec);
 
 EINTERN void      e_zone_client_set_event_emit(E_Zone *zone, E_Client *ec);
 
+EINTERN E_Client *e_zone_client_top_get(E_Zone *zone);
+EINTERN E_Client *e_zone_client_bottom_get(E_Zone *zone);
+EINTERN E_Client *e_zone_client_above_get(E_Zone *zone, E_Client *ec);
+EINTERN E_Client *e_zone_client_below_get(E_Zone *zone, E_Client *ec);
+EINTERN E_Client *e_zone_client_visible_above_get(E_Zone *zone, E_Client *ec);
+EINTERN E_Client *e_zone_client_visible_below_get(E_Zone *zone, E_Client *ec);
+
 // listeners
 EINTERN void e_zone_destroy_listener_add(E_Zone *zone, struct wl_listener *listener);
 EINTERN void e_zone_move_listener_add(E_Zone *zone, struct wl_listener *listener);
@@ -129,6 +142,12 @@ EINTERN void e_zone_bg_mouse_down_listener_add(E_Zone *zone, struct wl_listener
 EINTERN void e_zone_bg_mouse_up_listener_add(E_Zone *zone, struct wl_listener *listener);
 EINTERN void e_zone_client_add_listener_add(E_Zone *zone, struct wl_listener *listener);
 EINTERN void e_zone_focused_client_get_listener_add(E_Zone *zone, struct wl_listener *listener);
+EINTERN void e_zone_client_top_get_listener_add(E_Zone *zone, struct wl_listener *listener);
+EINTERN void e_zone_client_bottom_get_listener_add(E_Zone *zone, struct wl_listener *listener);
+EINTERN void e_zone_client_above_get_listener_add(E_Zone *zone, struct wl_listener *listener);
+EINTERN void e_zone_client_below_get_listener_add(E_Zone *zone, struct wl_listener *listener);
+EINTERN void e_zone_client_visible_above_get_listener_add(E_Zone *zone, struct wl_listener *listener);
+EINTERN void e_zone_client_visible_below_get_listener_add(E_Zone *zone, struct wl_listener *listener);
 
 EINTERN void         e_desk_row_add(E_Zone *zone);
 EINTERN void         e_desk_row_remove(E_Zone *zone);
index 8eceefd315cbafaa682d3b99e9f8f5950fc65b9e..db8df5b4b0850e90dd7f85bb2e4c3d29b2d57755 100644 (file)
@@ -68,6 +68,12 @@ struct _E_Policy_Desk
    struct wl_listener visible_client_restore_all;
    struct wl_listener client_iconified_list_remove;
    struct wl_listener client_iconified_list_remove_all;
+   struct wl_listener client_top_get;
+   struct wl_listener client_bottom_get;
+   struct wl_listener client_above_get;
+   struct wl_listener client_below_get;
+   struct wl_listener client_visible_above_get;
+   struct wl_listener client_visible_below_get;
 };
 
 struct _E_Policy_Desk_Private_Client
@@ -1751,6 +1757,271 @@ _e_policy_desk_cb_client_iconified_list_remove_all(struct wl_listener *listener,
    desk->iconified_list = NULL;
 }
 
+static void
+_e_policy_desk_cb_client_top_get(struct wl_listener *listener, void *data)
+{
+   E_Desk_Data_Client_Get *client_data;
+   E_Policy_Desk *pd;
+   E_Desk *desk;
+   E_Desk_Area *eda;
+   E_Client *ec;
+   Eina_List *l;
+
+   pd = wl_container_of(listener, pd, client_top_get);
+   desk = pd->desk;
+   client_data = (E_Desk_Data_Client_Get *) data;
+
+   for (int i=E_DESK_AREA_LAYER_COUNT-1; i>=0; i--)
+     {
+       EINA_LIST_FOREACH(desk->desk_area.list[i], l, eda)
+         {
+            ec = e_desk_area_top_ec_get(eda);
+            if (!ec) continue;
+
+            DBG("E_DESK::found TOPMOST EC(%p):%s on eda", ec, e_client_icccm_title_get(ec));
+            client_data->result_ec = ec;
+            return;
+         }
+     }
+
+   DBG("E_DESK::could not find top ec, return from base desk_area");
+   client_data->result_ec = e_desk_area_top_ec_get(desk->desk_area.base);
+}
+
+static void
+_e_policy_desk_cb_client_bottom_get(struct wl_listener *listener, void *data)
+{
+   E_Desk_Data_Client_Get *client_data;
+   E_Policy_Desk *pd;
+   E_Desk *desk;
+   E_Desk_Area *eda;
+   E_Client *ec;
+   Eina_List *l;
+
+   pd = wl_container_of(listener, pd, client_bottom_get);
+   desk = pd->desk;
+   client_data = (E_Desk_Data_Client_Get *) data;
+
+   for (int i=0; i<E_DESK_AREA_LAYER_COUNT; i++)
+     {
+       EINA_LIST_REVERSE_FOREACH(desk->desk_area.list[i], l, eda)
+         {
+            ec = e_desk_area_bottom_ec_get(eda);
+            if (!ec) continue;
+
+            DBG("E_DESK::found BOTTOM EC(%p):%s on eda", ec, e_client_icccm_title_get(ec));
+            client_data->result_ec = ec;
+            return;
+         }
+     }
+
+   DBG("E_DESK::could not find bottom ec, return from base desk_area");
+   client_data->result_ec = e_desk_area_bottom_ec_get(desk->desk_area.base);
+}
+
+static void
+_e_policy_desk_cb_client_above_get(struct wl_listener *listener, void *data)
+{
+   E_Desk_Data_Client_Get *client_data;
+   E_Policy_Desk *pd;
+   E_Desk *desk;
+   E_Desk_Area *eda, *above_eda = NULL;
+   E_Client *ec;
+   Eina_List *l;
+
+   pd = wl_container_of(listener, pd, client_above_get);
+   desk = pd->desk;
+   client_data = (E_Desk_Data_Client_Get *) data;
+   ec = client_data->criterion_ec;
+
+   for (int i=E_DESK_AREA_LAYER_COUNT-1; i>=0; i--)
+     {
+       EINA_LIST_FOREACH(desk->desk_area.list[i], l, eda)
+         {
+            if (!e_desk_area_has_ec(eda, ec)) continue;
+
+            DBG("E_DESK::found EC(%p):%s on eda(%p), get above", ec, e_client_icccm_title_get(ec), eda);
+            client_data->result_ec = e_desk_area_client_above_get(eda, ec);
+            if (client_data->result_ec) return;
+
+            for (above_eda = e_desk_desk_area_above_get(desk, eda);
+                 above_eda != NULL;
+                 above_eda = e_desk_desk_area_above_get(desk, above_eda))
+              {
+                 client_data->result_ec = e_desk_area_bottom_ec_get(above_eda);
+                 if (client_data->result_ec)
+                   {
+                      DBG("E_DESK::found above ec(%p) on above eda(%p)", client_data->result_ec, above_eda);
+                      return;
+                   }
+              }
+            return;
+         }
+     }
+
+   DBG("E_DESK::could not find ec... FIXME");
+   client_data->result_ec = NULL;
+}
+
+static void
+_e_policy_desk_cb_client_below_get(struct wl_listener *listener, void *data)
+{
+   E_Desk_Data_Client_Get *client_data;
+   E_Policy_Desk *pd;
+   E_Desk *desk;
+   E_Desk_Area *eda, *below_eda = NULL;
+   E_Client *ec;
+   Eina_List *l;
+
+   pd = wl_container_of(listener, pd, client_below_get);
+   desk = pd->desk;
+   client_data = (E_Desk_Data_Client_Get *) data;
+   ec = client_data->criterion_ec;
+
+   for (int i=E_DESK_AREA_LAYER_COUNT-1; i>=0; i--)
+     {
+       EINA_LIST_FOREACH(desk->desk_area.list[i], l, eda)
+         {
+            if (!e_desk_area_has_ec(eda, ec)) continue;
+
+            DBG("E_DESK::found EC(%p):%s on eda(%p), get below", ec, e_client_icccm_title_get(ec), eda);
+            client_data->result_ec = e_desk_area_client_below_get(eda, ec);
+            if (client_data->result_ec) return;
+
+            for (below_eda = e_desk_desk_area_below_get(desk, eda);
+                 below_eda != NULL;
+                 below_eda = e_desk_desk_area_below_get(desk, below_eda))
+              {
+                 client_data->result_ec = e_desk_area_top_ec_get(below_eda);
+                 if (client_data->result_ec)
+                   {
+                      DBG("E_DESK::found below ec(%p) on below eda(%p)", client_data->result_ec, below_eda);
+                      return;
+                   }
+              }
+            DBG("E_DESK::could not find ec even all the eda iterated... FIXME");
+            return;
+         }
+     }
+
+   DBG("E_DESK::could not find ec... FIXME");
+   client_data->result_ec = NULL;
+}
+
+static Eina_Bool
+_desk_client_check_visible(E_Client *ec)
+{
+   if (!ec) return EINA_FALSE;
+   if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
+   if (e_client_util_ignored_get(ec)) return EINA_FALSE;
+   if (!e_client_frame_get(ec)) return EINA_FALSE;
+   return e_client_visible_get(ec);
+}
+
+static void
+_e_policy_desk_cb_client_visible_above_get(struct wl_listener *listener, void *data)
+{
+   E_Desk_Data_Client_Get *client_data;
+   E_Policy_Desk *pd;
+   E_Desk *desk;
+   E_Desk_Area *eda, *above_eda = NULL;
+   E_Client *ec, *bottom_ec;
+   Eina_List *l;
+
+   pd = wl_container_of(listener, pd, client_visible_above_get);
+   desk = pd->desk;
+   client_data = (E_Desk_Data_Client_Get *) data;
+   ec = client_data->criterion_ec;
+
+   for (int i=E_DESK_AREA_LAYER_COUNT-1; i>=0; i--)
+     {
+        EINA_LIST_FOREACH(desk->desk_area.list[i], l, eda)
+          {
+             if (!e_desk_area_has_ec(eda, ec)) continue;
+
+             DBG("E_DESK::found EC(%p):%s on eda(%p), get visible above", ec, e_client_icccm_title_get(ec), eda);
+             client_data->result_ec = e_desk_area_client_visible_above_get(eda, ec);
+             if (client_data->result_ec) return;
+
+             for (above_eda = e_desk_desk_area_above_get(desk, eda);
+                  above_eda != NULL;
+                  above_eda = e_desk_desk_area_above_get(desk, above_eda))
+               {
+                  bottom_ec = e_desk_area_bottom_ec_get(above_eda);
+                  if (_desk_client_check_visible(bottom_ec))
+                    {
+                       client_data->result_ec = bottom_ec;
+                       DBG("E_DESK::found visible above ec(%p) on above eda(%p)", client_data->result_ec, above_eda);
+                       return;
+                    }
+                  client_data->result_ec = e_desk_area_client_visible_above_get(above_eda, bottom_ec);
+                  if (client_data->result_ec)
+                    {
+                       DBG("E_DESK::found visible above ec(%p) on above eda(%p)", client_data->result_ec, above_eda);
+                       return;
+                    }
+               }
+             DBG("E_DESK::could not find ec even all the eda iterated... FIXME");
+             return;
+         }
+     }
+
+   DBG("E_DESK::could not find ec... FIXME");
+   client_data->result_ec = NULL;
+}
+
+static void
+_e_policy_desk_cb_client_visible_below_get(struct wl_listener *listener, void *data)
+{
+   E_Desk_Data_Client_Get *client_data;
+   E_Policy_Desk *pd;
+   E_Desk *desk;
+   E_Desk_Area *eda, *below_eda = NULL;
+   E_Client *ec, *top_ec = NULL;
+   Eina_List *l;
+
+   pd = wl_container_of(listener, pd, client_visible_below_get);
+   desk = pd->desk;
+   client_data = (E_Desk_Data_Client_Get *) data;
+   ec = client_data->criterion_ec;
+
+   for (int i=E_DESK_AREA_LAYER_COUNT-1; i>=0; i--)
+     {
+       EINA_LIST_FOREACH(desk->desk_area.list[i], l, eda)
+         {
+            if (!e_desk_area_has_ec(eda, ec)) continue;
+
+            DBG("E_DESK::found EC(%p):%s on eda(%p), get below", ec, e_client_icccm_title_get(ec), eda);
+            client_data->result_ec = e_desk_area_client_visible_below_get(eda, ec);
+            if (client_data->result_ec) return;
+
+            for (below_eda = e_desk_desk_area_below_get(desk, eda);
+                 below_eda != NULL;
+                 below_eda = e_desk_desk_area_below_get(desk, below_eda))
+              {
+                 top_ec = e_desk_area_top_ec_get(below_eda);
+                 if (_desk_client_check_visible(top_ec))
+                   {
+                      client_data->result_ec = top_ec;
+                      DBG("E_DESK::found visible below ec(%p) on below eda(%p)", client_data->result_ec, below_eda);
+                      return;
+                   }
+                 client_data->result_ec = e_desk_area_client_visible_below_get(below_eda, top_ec);
+                 if (client_data->result_ec)
+                   {
+                      DBG("E_DESK::found below ec(%p) on below eda(%p)", client_data->result_ec, below_eda);
+                      return;
+                   }
+              }
+            DBG("E_DESK::could not find ec even all the eda iterated... FIXME");
+            return;
+         }
+     }
+
+   DBG("E_DESK::could not find ec... FIXME");
+   client_data->result_ec = NULL;
+}
+
 static void
 _e_policy_desk_cb_client_destroy(struct wl_listener *listener, void *data)
 {
@@ -1914,6 +2185,18 @@ e_policy_desk_add(E_Desk *desk)
    e_desk_client_iconified_list_remove_listener_add(pd->desk, &pd->client_iconified_list_remove);
    pd->client_iconified_list_remove_all.notify = _e_policy_desk_cb_client_iconified_list_remove_all;
    e_desk_client_iconified_list_remove_all_listener_add(pd->desk, &pd->client_iconified_list_remove_all);
+   pd->client_top_get.notify = _e_policy_desk_cb_client_top_get;
+   e_desk_client_top_get_listener_add(pd->desk, &pd->client_top_get);
+   pd->client_bottom_get.notify = _e_policy_desk_cb_client_bottom_get;
+   e_desk_client_bottom_get_listener_add(pd->desk, &pd->client_bottom_get);
+   pd->client_above_get.notify = _e_policy_desk_cb_client_above_get;
+   e_desk_client_above_get_listener_add(pd->desk, &pd->client_above_get);
+   pd->client_below_get.notify = _e_policy_desk_cb_client_below_get;
+   e_desk_client_below_get_listener_add(pd->desk, &pd->client_below_get);
+   pd->client_visible_above_get.notify = _e_policy_desk_cb_client_visible_above_get;
+   e_desk_client_visible_above_get_listener_add(pd->desk, &pd->client_visible_above_get);
+   pd->client_visible_below_get.notify = _e_policy_desk_cb_client_visible_below_get;
+   e_desk_client_visible_below_get_listener_add(pd->desk, &pd->client_visible_below_get);
 }
 
 EINTERN void
index a8e5e3c55bb0a5f4656792306cdbe45dd06fa3da..82a04b8b2432206c1b90791734f2485d6caf14e3 100644 (file)
@@ -34,6 +34,10 @@ struct _E_Policy_Desk_Area
    struct wl_listener lower;
    struct wl_listener top_ec_get;
    struct wl_listener bottom_ec_get;
+   struct wl_listener client_above_get;
+   struct wl_listener client_below_get;
+   struct wl_listener client_visible_above_get;
+   struct wl_listener client_visible_below_get;
    struct wl_listener has_ec;
 
    struct wl_listener client_add;
@@ -47,10 +51,6 @@ struct _E_Policy_Desk_Area_Private_Client
 
    // client listeners
    struct wl_listener client_destroy;
-   struct wl_listener client_get_above;
-   struct wl_listener client_get_below;
-   struct wl_listener client_get_visible_above;
-   struct wl_listener client_get_visible_below;
    struct wl_listener client_subsurface_stack_update;
    struct wl_listener client_fullscreen;
    struct wl_listener client_unfullscreen;
@@ -336,7 +336,7 @@ _e_policy_desk_area_cb_top_ec_get(struct wl_listener *listener, void *data)
    get_data = (E_Desk_Area_Data_EC_Get *) data;
    eda = get_data->eda;
 
-   e_comp_ec_list_lock();;
+   e_comp_ec_list_lock();
 
    for (x = e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); x >= e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x--)
      {
@@ -346,7 +346,7 @@ _e_policy_desk_area_cb_top_ec_get(struct wl_listener *listener, void *data)
             if (!e_object_is_del(E_OBJECT(ec)))
               {
                  e_comp_ec_list_unlock();
-                 get_data->ec = ec;
+                 get_data->result_ec = ec;
                  return;
               }
      }
@@ -368,7 +368,7 @@ _e_policy_desk_area_cb_bottom_ec_get(struct wl_listener *listener, void *data)
    get_data = (E_Desk_Area_Data_EC_Get *) data;
    eda = get_data->eda;
 
-   e_comp_ec_list_lock();;
+   e_comp_ec_list_lock();
 
    for (x = e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x <= e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); x++)
      {
@@ -378,7 +378,7 @@ _e_policy_desk_area_cb_bottom_ec_get(struct wl_listener *listener, void *data)
             if (!e_object_is_del(E_OBJECT(ec)))
               {
                  e_comp_ec_list_unlock();
-                 get_data->ec = ec;
+                 get_data->result_ec = ec;
                  return;
               }
      }
@@ -430,15 +430,15 @@ _desk_area_cb_client_destroy(struct wl_listener *listener, void *data)
 static void
 _desk_area_cb_client_get_above(struct wl_listener *listener, void *data)
 {
-   E_Policy_Desk_Area_Private_Client *eda_client;
-   E_Client_Data_Get_Above *get_above_data = data;
+   E_Policy_Desk_Area *pda;
+   E_Desk_Area_Data_EC_Get *client_data = (E_Desk_Area_Data_EC_Get *) data;
    E_Desk_Area *eda;
    E_Client *ec, *ec2;
    unsigned int x;
 
-   eda_client = wl_container_of(listener, eda_client, client_get_above);
-   eda = eda_client->eda;
-   ec = eda_client->ec;
+   pda = wl_container_of(listener, pda, client_above_get);
+   eda = pda->desk_area;
+   ec = client_data->criterion_ec;
 
    e_comp_ec_list_lock();
 
@@ -453,7 +453,7 @@ _desk_area_cb_client_get_above(struct wl_listener *listener, void *data)
                }
              if (!e_object_is_del(E_OBJECT(ec2)))
                {
-                  get_above_data->above_ec = ec2;
+                  client_data->result_ec = ec2;
                   e_comp_ec_list_unlock();
                   return;
                }
@@ -482,7 +482,7 @@ _desk_area_cb_client_get_above(struct wl_listener *listener, void *data)
                }
              if (!e_object_is_del(E_OBJECT(ec2)))
                {
-                  get_above_data->above_ec = ec2;
+                  client_data->result_ec = ec2;
                   e_comp_ec_list_unlock();
                   return;
                }
@@ -495,8 +495,8 @@ _desk_area_cb_client_get_above(struct wl_listener *listener, void *data)
 static void
 _desk_area_cb_client_get_below(struct wl_listener *listener, void *data)
 {
-   E_Policy_Desk_Area_Private_Client *eda_client;
-   E_Client_Data_Get_Below *get_below_data = data;
+   E_Policy_Desk_Area *pda;
+   E_Desk_Area_Data_EC_Get *client_data = (E_Desk_Area_Data_EC_Get *) data;
    E_Desk_Area *eda;
    E_Client *ec, *ec2;
    unsigned int x;
@@ -504,9 +504,9 @@ _desk_area_cb_client_get_below(struct wl_listener *listener, void *data)
    E_Layer ec_layer, ec_layer_cw;
    int cw_layer;
 
-   eda_client = wl_container_of(listener, eda_client, client_get_below);
-   eda = eda_client->eda;
-   ec = eda_client->ec;
+   pda = wl_container_of(listener, pda, client_below_get);
+   eda = pda->desk_area;
+   ec = client_data->criterion_ec;
 
    e_comp_ec_list_lock();
 
@@ -522,7 +522,7 @@ _desk_area_cb_client_get_below(struct wl_listener *listener, void *data)
                }
              if (!e_object_is_del(E_OBJECT(ec2)))
                {
-                  get_below_data->below_ec = ec2;
+                  client_data->result_ec = ec2;
                   e_comp_ec_list_unlock();
                   return;
                }
@@ -571,7 +571,7 @@ _desk_area_cb_client_get_below(struct wl_listener *listener, void *data)
                }
              if (!e_object_is_del(E_OBJECT(ec2)))
                {
-                  get_below_data->below_ec = ec2;
+                  client_data->result_ec = ec2;
                   e_comp_ec_list_unlock();
                   return;
                }
@@ -581,18 +581,28 @@ _desk_area_cb_client_get_below(struct wl_listener *listener, void *data)
    e_comp_ec_list_unlock();
 }
 
+static Eina_Bool
+_desk_area_client_check_visible(E_Client *ec)
+{
+   if (!ec) return EINA_FALSE;
+   if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
+   if (e_client_util_ignored_get(ec)) return EINA_FALSE;
+   if (!e_client_frame_get(ec)) return EINA_FALSE;
+   return e_client_visible_get(ec);
+}
+
 static void
 _desk_area_cb_client_get_visible_above(struct wl_listener *listener, void *data)
 {
-   E_Policy_Desk_Area_Private_Client *eda_client;
-   E_Client_Data_Get_Visible_Above *get_visible_above_data = data;
+   E_Policy_Desk_Area *pda;
+   E_Desk_Area_Data_EC_Get *client_data = (E_Desk_Area_Data_EC_Get *) data;
    E_Desk_Area *eda;
    E_Client *ec, *ec2;
    unsigned int x;
 
-   eda_client = wl_container_of(listener, eda_client, client_get_visible_above);
-   eda = eda_client->eda;
-   ec = eda_client->ec;
+   pda = wl_container_of(listener, pda, client_visible_above_get);
+   eda = pda->desk_area;
+   ec = client_data->criterion_ec;
 
    e_comp_ec_list_lock();
 
@@ -601,12 +611,9 @@ _desk_area_cb_client_get_visible_above(struct wl_listener *listener, void *data)
         EINA_INLIST_FOREACH(EINA_INLIST_GET(ec)->next, ec2)
           {
              if (ec == ec2) continue;
-             if ((!e_object_is_del(E_OBJECT(ec2))) &&
-                 (!e_client_util_ignored_get(ec2)) &&
-                 (ec2->visible) &&
-                 (ec2->frame))
+             if (_desk_area_client_check_visible(ec2))
                {
-                  get_visible_above_data->above_ec = ec2;
+                  client_data->result_ec = ec2;
                   e_comp_ec_list_unlock();
                   return;
                }
@@ -627,12 +634,9 @@ _desk_area_cb_client_get_visible_above(struct wl_listener *listener, void *data)
         EINA_INLIST_FOREACH(eda->layers[x].clients, ec2)
           {
              if (ec == ec2) continue;
-             if ((!e_object_is_del(E_OBJECT(ec2))) &&
-                 (!e_client_util_ignored_get(ec2)) &&
-                 (ec2->visible) &&
-                 (ec2->frame))
+             if (_desk_area_client_check_visible(ec2))
                {
-                  get_visible_above_data->above_ec = ec2;
+                  client_data->result_ec = ec2;
                   e_comp_ec_list_unlock();
                   return;
                }
@@ -645,8 +649,8 @@ _desk_area_cb_client_get_visible_above(struct wl_listener *listener, void *data)
 static void
 _desk_area_cb_client_get_visible_below(struct wl_listener *listener, void *data)
 {
-   E_Policy_Desk_Area_Private_Client *eda_client;
-   E_Client_Data_Get_Visible_Below *get_visible_below_data = data;
+   E_Policy_Desk_Area *pda;
+   E_Desk_Area_Data_EC_Get *client_data = (E_Desk_Area_Data_EC_Get *) data;
    E_Desk_Area *eda;
    E_Client *ec, *ec2;
    unsigned int x;
@@ -654,9 +658,9 @@ _desk_area_cb_client_get_visible_below(struct wl_listener *listener, void *data)
    E_Layer ec_layer, ec_layer_cw;
    int cw_layer;
 
-   eda_client = wl_container_of(listener, eda_client, client_get_visible_below);
-   eda = eda_client->eda;
-   ec = eda_client->ec;
+   pda = wl_container_of(listener, pda, client_visible_below_get);
+   eda = pda->desk_area;
+   ec = client_data->criterion_ec;
 
    e_comp_ec_list_lock();
 
@@ -666,12 +670,9 @@ _desk_area_cb_client_get_visible_below(struct wl_listener *listener, void *data)
           {
              ec2 = EINA_INLIST_CONTAINER_GET(l, E_Client);
              if (ec == ec2) continue;
-             if ((!e_object_is_del(E_OBJECT(ec2))) &&
-                 (!e_client_util_ignored_get(ec2)) &&
-                 (ec2->visible) &&
-                 (ec2->frame))
+             if (_desk_area_client_check_visible(ec2))
                {
-                  get_visible_below_data->below_ec = ec2;
+                  client_data->result_ec = ec2;
                   e_comp_ec_list_unlock();
                   return;
                }
@@ -708,12 +709,9 @@ _desk_area_cb_client_get_visible_below(struct wl_listener *listener, void *data)
         EINA_INLIST_REVERSE_FOREACH(eda->layers[x].clients, ec2)
           {
              if (ec == ec2) continue;
-             if ((!e_object_is_del(E_OBJECT(ec2))) &&
-                 (!e_client_util_ignored_get(ec2)) &&
-                 (ec2->visible) &&
-                 (ec2->frame))
+             if (_desk_area_client_check_visible(ec2))
                {
-                  get_visible_below_data->below_ec = ec2;
+                  client_data->result_ec = ec2;
                   return;
                }
           }
@@ -2551,10 +2549,6 @@ _e_policy_desk_area_private_client_del(E_Policy_Desk_Area_Private_Client *eda_cl
    wl_list_remove(&eda_client->client_unfullscreen.link);
    wl_list_remove(&eda_client->client_fullscreen.link);
    wl_list_remove(&eda_client->client_subsurface_stack_update.link);
-   wl_list_remove(&eda_client->client_get_visible_below.link);
-   wl_list_remove(&eda_client->client_get_visible_above.link);
-   wl_list_remove(&eda_client->client_get_below.link);
-   wl_list_remove(&eda_client->client_get_above.link);
    wl_list_remove(&eda_client->client_destroy.link);
 
    E_FREE(eda_client);
@@ -2581,19 +2575,9 @@ _e_policy_desk_area_cb_client_add(struct wl_listener *listener, void *data)
    eda_client->eda = eda;
    eda_client->ec = ec;
 
-
    // e_client listeners
    eda_client->client_destroy.notify = _desk_area_cb_client_destroy;
    e_client_destroy_listener_add(ec, &eda_client->client_destroy);
-
-   eda_client->client_get_above.notify = _desk_area_cb_client_get_above;
-   e_client_get_above_listener_add(ec, &eda_client->client_get_above);
-   eda_client->client_get_below.notify = _desk_area_cb_client_get_below;
-   e_client_get_below_listener_add(ec, &eda_client->client_get_below);
-   eda_client->client_get_visible_above.notify = _desk_area_cb_client_get_visible_above;
-   e_client_get_visible_above_listener_add(ec, &eda_client->client_get_visible_above);
-   eda_client->client_get_visible_below.notify = _desk_area_cb_client_get_visible_below;
-   e_client_get_visible_below_listener_add(ec, &eda_client->client_get_visible_below);
    eda_client->client_subsurface_stack_update.notify = _desk_area_cb_client_subsurface_stack_update;
    e_client_subsurface_stack_update_listener_add(ec, &eda_client->client_subsurface_stack_update);
    eda_client->client_fullscreen.notify = _desk_area_cb_client_fullscreen;
@@ -2767,6 +2751,14 @@ e_policy_desk_area_new(E_Desk_Area *eda)
    e_desk_area_top_ec_get_listener_add(eda, &pda->top_ec_get);
    pda->bottom_ec_get.notify = _e_policy_desk_area_cb_bottom_ec_get;
    e_desk_area_bottom_ec_get_listener_add(eda, &pda->bottom_ec_get);
+   pda->client_above_get.notify = _desk_area_cb_client_get_above;
+   e_desk_area_client_above_get_listener_add(eda, &pda->client_above_get);
+   pda->client_below_get.notify = _desk_area_cb_client_get_below;
+   e_desk_area_client_below_get_listener_add(eda, &pda->client_below_get);
+   pda->client_visible_above_get.notify = _desk_area_cb_client_get_visible_above;
+   e_desk_area_client_visible_above_get_listener_add(eda, &pda->client_visible_above_get);
+   pda->client_visible_below_get.notify = _desk_area_cb_client_get_visible_below;
+   e_desk_area_client_visible_below_get_listener_add(eda, &pda->client_visible_below_get);
    pda->has_ec.notify = _e_policy_desk_area_cb_has_ec;
    e_desk_area_has_ec_listener_add(eda, &pda->has_ec);
 
@@ -2790,6 +2782,12 @@ e_policy_desk_area_del(E_Policy_Desk_Area *pda)
    wl_list_remove(&pda->activate.link);
    wl_list_remove(&pda->raise.link);
    wl_list_remove(&pda->lower.link);
+   wl_list_remove(&pda->top_ec_get.link);
+   wl_list_remove(&pda->bottom_ec_get.link);
+   wl_list_remove(&pda->client_above_get.link);
+   wl_list_remove(&pda->client_below_get.link);
+   wl_list_remove(&pda->client_visible_above_get.link);
+   wl_list_remove(&pda->client_visible_below_get.link);
 
    wl_list_remove(&pda->client_add.link);
    wl_list_remove(&pda->client_del.link);
index b50bb412f58dbc2fdffe8e099a0bcf82226870cf..890eb6449d97a245b6e8966a294ae7e84ee9181d 100644 (file)
@@ -54,6 +54,13 @@ struct _E_Policy_Zone
    struct wl_listener desk_count;
    struct wl_listener focused_client_get;
 
+   struct wl_listener zone_client_top_get;            // from e_zone
+   struct wl_listener zone_client_bottom_get;         // from e_zone
+   struct wl_listener zone_client_above_get;          // from e_zone
+   struct wl_listener zone_client_below_get;          // from e_zone
+   struct wl_listener zone_client_visible_above_get;  // from e_zone
+   struct wl_listener zone_client_visible_below_get;  // from e_zone
+
    struct
      {
         struct wl_signal client_add;
@@ -71,6 +78,10 @@ struct _E_Policy_Zone_Client
    struct wl_listener client_destroy;
    struct wl_listener client_eval_post_new_client;
    struct wl_listener client_focus_set;
+   struct wl_listener client_above_get;               // from e_client
+   struct wl_listener client_below_get;               // from e_client
+   struct wl_listener client_visible_above_get;       // from e_client
+   struct wl_listener client_visible_below_get;       // from e_client
 };
 
 static void
@@ -786,6 +797,161 @@ _policy_zone_cb_focus_focused_ec_changed(struct wl_listener *listener, void *dat
      }
 }
 
+static void
+_policy_zone_cb_client_top_get(struct wl_listener *listener, void *data)
+{
+   E_Policy_Zone *policy_zone;
+   E_Zone *zone;
+   E_Desk *desk;
+   E_Zone_Data_Client_Get *client_data;
+
+   policy_zone = wl_container_of(listener, policy_zone, zone_client_top_get);
+   zone = policy_zone->zone;
+   client_data = (E_Zone_Data_Client_Get *) data;
+
+   // iterate desk of zone
+   // TODO:: is it correct way to iterate?
+   int x, y;
+   for (x = 0; x < zone->desk_x_count; x++)
+     {
+        for (y = 0; y < zone->desk_y_count; y++)
+          {
+             desk = zone->desks[x + (y * zone->desk_x_count)];
+             client_data->result_ec = e_desk_client_top_get(desk);
+             if (client_data->result_ec) return;
+          }
+     }
+}
+
+static void
+_policy_zone_cb_client_bottom_get(struct wl_listener *listener, void *data)
+{
+   E_Policy_Zone *policy_zone;
+   E_Zone *zone;
+   E_Desk *desk;
+   E_Zone_Data_Client_Get *client_data;
+
+   policy_zone = wl_container_of(listener, policy_zone, zone_client_bottom_get);
+   zone = policy_zone->zone;
+   client_data = (E_Zone_Data_Client_Get *) data;
+
+   // iterate desk of zone
+   // TODO:: is it correct way to iterate?
+   int x, y;
+   for (x = 0; x < zone->desk_x_count; x++)
+     {
+        for (y = 0; y < zone->desk_y_count; y++)
+          {
+             desk = zone->desks[x + (y * zone->desk_x_count)];
+             client_data->result_ec = e_desk_client_bottom_get(desk);
+             if (client_data->result_ec) return;
+          }
+     }
+}
+
+static void
+_policy_zone_cb_client_above_get(struct wl_listener *listener, void *data)
+{
+   E_Policy_Zone *policy_zone;
+   E_Zone *zone;
+   E_Desk *desk;
+   E_Zone_Data_Client_Get *client_data;
+
+   policy_zone = wl_container_of(listener, policy_zone, zone_client_above_get);
+   zone = policy_zone->zone;
+   client_data = (E_Zone_Data_Client_Get *) data;
+
+   // iterate desk of zone
+   // TODO:: is it correct way to iterate?
+   int x, y;
+   for (x = 0; x < zone->desk_x_count; x++)
+     {
+        for (y = 0; y < zone->desk_y_count; y++)
+          {
+             desk = zone->desks[x + (y * zone->desk_x_count)];
+             client_data->result_ec = e_desk_client_above_get(desk, client_data->criterion_ec);
+             if (client_data->result_ec) return;
+          }
+     }
+}
+
+static void
+_policy_zone_cb_client_below_get(struct wl_listener *listener, void *data)
+{
+   E_Policy_Zone *policy_zone;
+   E_Zone *zone;
+   E_Desk *desk;
+   E_Zone_Data_Client_Get *client_data;
+
+   policy_zone = wl_container_of(listener, policy_zone, zone_client_below_get);
+   zone = policy_zone->zone;
+   client_data = (E_Zone_Data_Client_Get *) data;
+
+   // iterate desk of zone
+   // TODO:: is it correct way to iterate?
+   int x, y;
+   for (x = 0; x < zone->desk_x_count; x++)
+     {
+        for (y = 0; y < zone->desk_y_count; y++)
+          {
+             desk = zone->desks[x + (y * zone->desk_x_count)];
+             client_data->result_ec = e_desk_client_below_get(desk, client_data->criterion_ec);
+             if (client_data->result_ec) return;
+          }
+     }
+}
+
+static void
+_policy_zone_cb_client_visible_above_get(struct wl_listener *listener, void *data)
+{
+   E_Policy_Zone *policy_zone;
+   E_Zone *zone;
+   E_Desk *desk;
+   E_Zone_Data_Client_Get *client_data;
+
+   policy_zone = wl_container_of(listener, policy_zone, zone_client_visible_above_get);
+   zone = policy_zone->zone;
+   client_data = (E_Zone_Data_Client_Get *) data;
+
+   // iterate desk of zone
+   // TODO:: is it correct way to iterate?
+   int x, y;
+   for (x = 0; x < zone->desk_x_count; x++)
+     {
+        for (y = 0; y < zone->desk_y_count; y++)
+          {
+             desk = zone->desks[x + (y * zone->desk_x_count)];
+             client_data->result_ec = e_desk_client_visible_above_get(desk, client_data->criterion_ec);
+             if (client_data->result_ec) return;
+          }
+     }
+}
+
+static void
+_policy_zone_cb_client_visible_below_get(struct wl_listener *listener, void *data)
+{
+   E_Policy_Zone *policy_zone;
+   E_Zone *zone;
+   E_Desk *desk;
+   E_Zone_Data_Client_Get *client_data;
+
+   policy_zone = wl_container_of(listener, policy_zone, zone_client_visible_below_get);
+   zone = policy_zone->zone;
+   client_data = (E_Zone_Data_Client_Get *) data;
+
+   // iterate desk of zone
+   // TODO:: is it correct way to iterate?
+   int x, y;
+   for (x = 0; x < zone->desk_x_count; x++)
+     {
+        for (y = 0; y < zone->desk_y_count; y++)
+          {
+             desk = zone->desks[x + (y * zone->desk_x_count)];
+             client_data->result_ec = e_desk_client_visible_below_get(desk, client_data->criterion_ec);
+             if (client_data->result_ec) return;
+          }
+     }
+}
 
 static void
 _policy_zone_cb_client_destroy(struct wl_listener *listener, void *data)
@@ -817,7 +983,10 @@ _policy_zone_cb_client_destroy(struct wl_listener *listener, void *data)
    wl_signal_emit_mutable(&policy_zone->events.client_remove, ec);
 
    e_desk_client_del(desk, ec);
-
+   wl_list_remove(&zone_client->client_above_get.link);
+   wl_list_remove(&zone_client->client_below_get.link);
+   wl_list_remove(&zone_client->client_visible_above_get.link);
+   wl_list_remove(&zone_client->client_visible_below_get.link);
    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);
@@ -984,6 +1153,70 @@ _policy_zone_cb_client_focus_set(struct wl_listener *listener, void *data)
      e_desk_client_add(e_desk_current_get(zone), ec);
 }
 
+static void
+_policy_zone_client_cb_client_above_get(struct wl_listener *listener, void *data)
+{
+   E_Policy_Zone_Client *zone_client;
+   E_Policy_Zone *policy_zone;
+   E_Zone *zone;
+   E_Client_Data_Get_Client *client_data;
+
+   zone_client = wl_container_of(listener, zone_client, client_above_get);
+   policy_zone = zone_client->policy_zone;
+   zone = policy_zone->zone;
+   client_data = (E_Client_Data_Get_Client *) data;
+
+   client_data->result_ec = e_zone_client_above_get(zone, client_data->criterion_ec);
+}
+
+static void
+_policy_zone_client_cb_client_below_get(struct wl_listener *listener, void *data)
+{
+   E_Policy_Zone_Client *zone_client;
+   E_Policy_Zone *policy_zone;
+   E_Zone *zone;
+   E_Client_Data_Get_Client *client_data;
+
+   zone_client = wl_container_of(listener, zone_client, client_below_get);
+   policy_zone = zone_client->policy_zone;
+   zone = policy_zone->zone;
+   client_data = (E_Client_Data_Get_Client *) data;
+
+   client_data->result_ec = e_zone_client_below_get(zone, client_data->criterion_ec);
+}
+
+static void
+_policy_zone_client_cb_client_visible_above_get(struct wl_listener *listener, void *data)
+{
+   E_Policy_Zone_Client *zone_client;
+   E_Policy_Zone *policy_zone;
+   E_Zone *zone;
+   E_Client_Data_Get_Client *client_data;
+
+   zone_client = wl_container_of(listener, zone_client, client_visible_above_get);
+   policy_zone = zone_client->policy_zone;
+   zone = policy_zone->zone;
+   client_data = (E_Client_Data_Get_Client *) data;
+
+   client_data->result_ec = e_zone_client_visible_above_get(zone, client_data->criterion_ec);
+}
+
+static void
+_policy_zone_client_cb_client_visible_below_get(struct wl_listener *listener, void *data)
+{
+   E_Policy_Zone_Client *zone_client;
+   E_Policy_Zone *policy_zone;
+   E_Zone *zone;
+   E_Client_Data_Get_Client *client_data;
+
+   zone_client = wl_container_of(listener, zone_client, client_visible_below_get);
+   policy_zone = zone_client->policy_zone;
+   zone = policy_zone->zone;
+   client_data = (E_Client_Data_Get_Client *) data;
+
+   client_data->result_ec = e_zone_client_visible_below_get(zone, client_data->criterion_ec);
+}
+
 static void
 _e_policy_zone_cb_hook_client_new_client_post(void *d, E_Client *ec)
 {
@@ -1037,12 +1270,18 @@ _e_policy_zone_cb_client_add(struct wl_listener *listener, void *data)
    // 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);
+   zone_client->client_above_get.notify = _policy_zone_client_cb_client_above_get;
+   e_client_get_above_listener_add(ec, &zone_client->client_above_get);
+   zone_client->client_below_get.notify = _policy_zone_client_cb_client_below_get;
+   e_client_get_below_listener_add(ec, &zone_client->client_below_get);
+   zone_client->client_visible_above_get.notify = _policy_zone_client_cb_client_visible_above_get;
+   e_client_get_visible_above_listener_add(ec, &zone_client->client_visible_above_get);
+   zone_client->client_visible_below_get.notify = _policy_zone_client_cb_client_visible_below_get;
+   e_client_get_visible_below_listener_add(ec, &zone_client->client_visible_below_get);
 
    _e_policy_zone_client_set(zone, ec);
    _e_policy_zone_client_data_set(zone, ec);
@@ -1759,29 +1998,42 @@ e_policy_zone_new(E_Zone *zone)
    e_zone_focused_client_get_listener_add(zone, &policy_zone->focused_client_get);
 
    policy_zone->desk_row_add.notify = _e_policy_zone_cb_desk_row_add;
-   e_zone_desk_row_add_listener_add(policy_zone->zone, &policy_zone->desk_row_add);
+   e_zone_desk_row_add_listener_add(zone, &policy_zone->desk_row_add);
    policy_zone->desk_row_remove.notify = _e_policy_zone_cb_desk_row_remove;
-   e_zone_desk_row_remove_listener_add(policy_zone->zone, &policy_zone->desk_row_remove);
+   e_zone_desk_row_remove_listener_add(zone, &policy_zone->desk_row_remove);
    policy_zone->desk_col_add.notify = _e_policy_zone_cb_desk_col_add;
-   e_zone_desk_col_add_listener_add(policy_zone->zone, &policy_zone->desk_col_add);
+   e_zone_desk_col_add_listener_add(zone, &policy_zone->desk_col_add);
    policy_zone->desk_col_remove.notify = _e_policy_zone_cb_desk_col_remove;
-   e_zone_desk_col_remove_listener_add(policy_zone->zone, &policy_zone->desk_col_remove);
+   e_zone_desk_col_remove_listener_add(zone, &policy_zone->desk_col_remove);
    policy_zone->desk_current_get.notify = _e_policy_zone_cb_desk_current_get;
-   e_zone_desk_current_get_listener_add(policy_zone->zone, &policy_zone->desk_current_get);
+   e_zone_desk_current_get_listener_add(zone, &policy_zone->desk_current_get);
    policy_zone->desk_at_xy_get.notify = _e_policy_zone_cb_desk_at_xy_get;
-   e_zone_desk_at_xy_get_listener_add(policy_zone->zone, &policy_zone->desk_at_xy_get);
+   e_zone_desk_at_xy_get_listener_add(zone, &policy_zone->desk_at_xy_get);
    policy_zone->desk_at_pos_get.notify = _e_policy_zone_cb_desk_at_pos_get;
-   e_zone_desk_at_pos_get_listener_add(policy_zone->zone, &policy_zone->desk_at_pos_get);
+   e_zone_desk_at_pos_get_listener_add(zone, &policy_zone->desk_at_pos_get);
    policy_zone->desk_next.notify = _e_policy_zone_cb_desk_next;
-   e_zone_desk_next_listener_add(policy_zone->zone, &policy_zone->desk_next);
+   e_zone_desk_next_listener_add(zone, &policy_zone->desk_next);
    policy_zone->desk_prev.notify = _e_policy_zone_cb_desk_prev;
-   e_zone_desk_prev_listener_add(policy_zone->zone, &policy_zone->desk_prev);
+   e_zone_desk_prev_listener_add(zone, &policy_zone->desk_prev);
    policy_zone->desk_count.notify = _e_policy_zone_cb_desk_count;
-   e_zone_desk_count_listener_add(policy_zone->zone, &policy_zone->desk_count);
+   e_zone_desk_count_listener_add(zone, &policy_zone->desk_count);
 
    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);
 
+   policy_zone->zone_client_top_get.notify = _policy_zone_cb_client_top_get;
+   e_zone_client_top_get_listener_add(zone, &policy_zone->zone_client_top_get);
+   policy_zone->zone_client_bottom_get.notify = _policy_zone_cb_client_bottom_get;
+   e_zone_client_bottom_get_listener_add(zone, &policy_zone->zone_client_bottom_get);
+   policy_zone->zone_client_above_get.notify = _policy_zone_cb_client_above_get;
+   e_zone_client_above_get_listener_add(zone, &policy_zone->zone_client_above_get);
+   policy_zone->zone_client_below_get.notify = _policy_zone_cb_client_below_get;
+   e_zone_client_below_get_listener_add(zone, &policy_zone->zone_client_below_get);
+   policy_zone->zone_client_visible_above_get.notify = _policy_zone_cb_client_visible_above_get;
+   e_zone_client_visible_above_get_listener_add(zone, &policy_zone->zone_client_visible_above_get);
+   policy_zone->zone_client_visible_below_get.notify = _policy_zone_cb_client_visible_below_get;
+   e_zone_client_visible_below_get_listener_add(zone, &policy_zone->zone_client_visible_below_get);
+
    return policy_zone;
 }
 
@@ -1795,6 +2047,14 @@ e_policy_zone_del(E_Policy_Zone *policy_zone)
    // TODO:: need policy desk remove?
 
    // zone listeners
+
+
+   wl_list_remove(&policy_zone->zone_client_visible_below_get.link);
+   wl_list_remove(&policy_zone->zone_client_visible_above_get.link);
+   wl_list_remove(&policy_zone->zone_client_below_get.link);
+   wl_list_remove(&policy_zone->zone_client_above_get.link);
+   wl_list_remove(&policy_zone->zone_client_bottom_get.link);
+   wl_list_remove(&policy_zone->zone_client_top_get.link);
    wl_list_remove(&policy_zone->zone_destroy.link);
 
    E_FREE(policy_zone);