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