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