#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
{
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;
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.
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);
return 1;
}
+#ifdef CONTAINER_POLICY
+#else
static void
_e_zone_client_apply_auto_placement(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)
{
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)
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)
{
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);
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;
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)
{
}
}
}
+#endif
EINTERN void
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
_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
_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;
}
{
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;
}
}
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);
e_desk_show(desk);
starting = s;
}
+#endif
ev = E_NEW(E_Event_Zone_Desk_Count_Set, 1);
if (!ev) return;
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)
{
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)
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)
}
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)
{
if (w) *w = geom.w;
if (h) *h = geom.h;
}
+#endif
/**
* Get (or calculate) the useful (or free, without any shelves) area.
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);
_e_zone_useful_geometry_calc(zone, desk, x, y, w, h);
else
e_zone_useful_geometry_get(zone, x, y, w, h);
+#endif
}
/**
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);
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);
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);
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++)
{
}
free(zone->desks);
free(zone->output_id);
+#endif
_e_zone_private_finish(zone);
free(zone);
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)
e_object_ref(E_OBJECT(zone->cur_mouse_action));
}
}
+#endif
}
static void
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;
e_bindings_mouse_up_event_handle(E_BINDING_CONTEXT_ZONE,
E_OBJECT(zone), &event);
}
+#endif
}
static void
free(ev);
}
+#ifdef CONTAINER_POLICY
+#else
static void
_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);
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);
e_client_res_change_geometry_save(ec);
e_client_res_change_geometry_restore(ec);
ec->pre_res_change.valid = 0;
+#endif
}
EINTERN Eina_Bool
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
return e_visibility_changed;
}
+#endif
E_API E_Desk *
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)
{
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)
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)
{
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)
{
API_ENTRY;
wl_signal_add(&priv->events.focus_reset, listener);
}
+#endif
#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 *
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++)
{
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