#endif
#ifdef REFACTOR_DESK_AREA
+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)
+{
+ g_rec_mutex_lock(&e_comp->ec_list_mutex);
+
+ 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));
+ 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));
+ if ((!above) && (!below))
+ {
+ if (prepend)
+ eda->layers[cw->layer].clients = eina_inlist_prepend(eda->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
+ 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));
+ }
+ eda->layers[cw->layer].clients_count++;
+
+ g_rec_mutex_unlock(&e_comp->ec_list_mutex);
+}
+
+static void
+_e_comp_object_layers_remove(E_Desk_Area *eda, E_Comp_Object *cw)
+{
+ g_rec_mutex_lock(&e_comp->ec_list_mutex);
+
+ 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--;
+ }
+
+ g_rec_mutex_unlock(&e_comp->ec_list_mutex);
+}
+
+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();
+}
#else
static Eina_Bool
_check_desk_area_client_layer_validation(E_Desk_Area_Client_Layer edgc_layer)
unsigned int x;
eda_client = wl_container_of(listener, eda_client, client_get_above);
- ec = eda_client->ec;
eda = eda_client->eda;
+ ec = eda_client->ec;
if (EINA_INLIST_GET(ec)->next) //check current layer
{
/* 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 (!e_comp->layers[x].clients) continue;
+ if (!eda->layers[x].clients) continue;
- EINA_INLIST_FOREACH(e_comp->layers[x].clients, ec2)
+ EINA_INLIST_FOREACH(eda->layers[x].clients, ec2)
{
if (ec == ec2)
{
int cw_layer;
eda_client = wl_container_of(listener, eda_client, client_get_below);
- ec = eda_client->ec;
eda = eda_client->eda;
+ ec = eda_client->ec;
if (EINA_INLIST_GET(ec)->prev) //check current layer
{
for (; x >= e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x--)
{
- if (!e_comp->layers[x].clients) continue;
+ if (!eda->layers[x].clients) continue;
- EINA_INLIST_REVERSE_FOREACH(e_comp->layers[x].clients, ec2)
+ EINA_INLIST_REVERSE_FOREACH(eda->layers[x].clients, ec2)
{
if (ec == ec2)
{
{
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;
if (EINA_INLIST_GET(ec)->next) //check current layer
/* 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 (!e_comp->layers[x].clients) continue;
- EINA_INLIST_FOREACH(e_comp->layers[x].clients, ec2)
+ 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))) &&
int cw_layer;
eda_client = wl_container_of(listener, eda_client, client_get_visible_below);
- ec = eda_client->ec;
eda = eda_client->eda;
+ ec = eda_client->ec;
if (EINA_INLIST_GET(ec)->prev) //check current layer
{
for (; x >= e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x--)
{
- if (!e_comp->layers[x].clients) continue;
- EINA_INLIST_REVERSE_FOREACH(e_comp->layers[x].clients, ec2)
+ 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))) &&
_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
{
//stack above done
o = evas_object_below_get(ec->frame);
- e_comp_object_layer_update(ec->frame, o, NULL);
+ _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(ec->frame, NULL, o);
+ _e_comp_object_layer_update(eda, ec->frame, NULL, o);
}
}
}
_desk_area_cb_comp_object_lower(struct wl_listener *listener, void *data)
{
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(obj, NULL, obj);
+ _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(cw);
+ _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(cw, NULL, NULL, 1);
+ _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);
_desk_area_cb_comp_object_raise(struct wl_listener *listener, void *data)
{
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;
{
int obj_layer = evas_object_layer_get(obj);
if (cw->ec->layer != obj_layer)
- e_comp_object_layer_update(obj, NULL, NULL);
+ _e_comp_object_layer_update(eda, obj, NULL, NULL);
}
_e_comp_object_raise(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 = e_comp->layers[cw->layer].obj;
- o && o != e_comp->layers[cw->layer - 1].obj;
+ 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))
_desk_area_cb_comp_object_set_layer(struct wl_listener *listener, void *data)
{
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;
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;
evas_object_stack_below(obj, ec2->frame);
}
else
- evas_object_stack_below(obj, ec2 ? ec2->frame : e_comp->layers[cw->layer].obj);
+ evas_object_stack_below(obj, ec2 ? ec2->frame : eda->layers[cw->layer].obj);
}
return;
}
e_config->transient.raise = oldraise;
- _e_comp_object_layers_remove(cw);
+ _e_comp_object_layers_remove(eda, cw);
cw->layer = e_comp_canvas_layer_map(layer);
- _e_comp_object_layers_add(cw, NULL, NULL, 0);
+ _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 (!e_comp->layers[cw->layer].obj) return; //this is a layer marker
- evas_object_stack_below(obj, e_comp->layers[cw->layer].obj);
- if (evas_object_below_get(obj) == e_comp->layers[cw->layer].obj)
+ 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);
_desk_area_cb_comp_object_stack_above(struct wl_listener *listener, void *data)
{
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;
if (evas_object_below_get(obj) == above)
{
- e_comp_object_layer_update(obj, above, NULL);
+ _e_comp_object_layer_update(eda, obj, above, NULL);
return;
}
- _e_comp_intercept_stack_helper(cw, above, _e_comp_object_stack_above);
+ _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);
_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;
if (evas_object_above_get(obj) == below)
{
- e_comp_object_layer_update(obj, NULL, below);
+ _e_comp_object_layer_update(eda, obj, NULL, below);
return;
}
- _e_comp_intercept_stack_helper(cw, below, _e_comp_object_stack_below);
+ _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);
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 = e_comp->layers[ec_layer].obj = evas_object_rectangle_add(e_comp->evas);
+ obj = eda->layers[ec_layer].obj = evas_object_rectangle_add(e_comp->evas);
evas_object_layer_set(obj, e_comp_canvas_layer_map_to(ec_layer));
evas_object_name_set(obj, "layer_obj");
}
{
#ifdef REFACTOR_DESK_AREA
E_Desk_Area_Private_Client *eda_client;
+ E_Comp_Object *cw;
E_OBJECT_CHECK(eda);
E_OBJECT_TYPE_CHECK(eda, E_DESK_AREA_TYPE);
ELOGF("EDA", "CLIENT DEL", ec);
+ 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);
+
_e_desk_area_smart_client_del(eda->smart_obj, ec);
eda->clients = eina_list_remove(eda->clients, eda_client);
for (x = e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); x >= e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x--)
{
- if (!e_comp->layers[x].clients) continue;
+ if (!eda->layers[x].clients) continue;
- EINA_INLIST_REVERSE_FOREACH(e_comp->layers[x].clients, ec)
+ EINA_INLIST_REVERSE_FOREACH(eda->layers[x].clients, ec)
if (!e_object_is_del(E_OBJECT(ec)))
{
g_rec_mutex_unlock(&e_comp->ec_list_mutex);
for (x = e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x <= e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); x++)
{
- if (!e_comp->layers[x].clients) continue;
+ if (!eda->layers[x].clients) continue;
- EINA_INLIST_FOREACH(e_comp->layers[x].clients, ec)
+ EINA_INLIST_FOREACH(eda->layers[x].clients, ec)
if (!e_object_is_del(E_OBJECT(ec)))
{
g_rec_mutex_unlock(&e_comp->ec_list_mutex);