From: Doyoun Kang Date: Tue, 21 Apr 2020 05:40:22 +0000 (+0900) Subject: e_desk_group: modify desk_group feature X-Git-Tag: submit/tizen/20200421.091649~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f0032764422dfc2de36828bfc31a11153baa0b9e;p=platform%2Fupstream%2Fenlightenment.git e_desk_group: modify desk_group feature Change-Id: I18a6b6ca95423d826d0227c1b0e44d993c852e0f --- diff --git a/src/bin/e_client.c b/src/bin/e_client.c index e3f279e714..f219163646 100644 --- a/src/bin/e_client.c +++ b/src/bin/e_client.c @@ -454,7 +454,6 @@ _e_client_event_zone_set_free(void *d EINA_UNUSED, E_Event_Client_Zone_Set *ev) e_object_unref(E_OBJECT(ev->zone)); free(ev); } - //////////////////////////////////////////////// static int @@ -1343,7 +1342,10 @@ _e_client_del(E_Client *ec) } ec->transform_core.result.enable = EINA_FALSE; + e_client_desk_group_set(ec, NULL); + e_util_transform_del(ec->desk_group.transform); + ec->desk_group.transform = NULL; e_client_visibility_calculate(); } @@ -4512,6 +4514,8 @@ e_client_desk_set(E_Client *ec, E_Desk *desk) edg = e_desk_desk_group_base_get(ec->desk); e_client_desk_group_set(ec, edg); } + + e_client_desk_group_enable_set(ec, EINA_TRUE); } } @@ -7808,6 +7812,17 @@ e_client_layer_set(E_Client *ec, if (e_comp_canvas_client_layer_map(layer) == 9999) return EINA_FALSE; //invalid layer is not allowed + if (ec->desk_group.enable) + { + if (e_client_layer_set_by_desk_group(ec, layer)) + { + // restack according to desk group rule + e_desk_group_ec_rearrange(ec->desk_group.desk_group, ec); + return EINA_TRUE; + } + } + ec->desk_group.layer_backup = layer; + evas_object_layer_set(ec->frame, layer); if (ec->layer != layer) { @@ -7861,22 +7876,93 @@ e_client_layer_get(E_Client *ec) return ec->layer; } +static void +_e_client_desk_group_original_layer_save(E_Client *ec, E_Layer layer) +{ + E_OBJECT_CHECK(ec); + E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE); + ec->desk_group.layer_backup = layer; +} + EINTERN Eina_Bool -e_client_desk_group_layer_set(E_Client *ec, E_Desk_Group_Layer layer) +e_client_layer_set_by_desk_group(E_Client *ec, E_Layer layer) +{ + E_Desk_Group *edg; + E_Layer edg_layer; + E_Layer org_layer; + + ELOGF("EDG", "layer_set by desk_group... layer:%d, edg_info(edg:%p, enable:%d)", ec, layer, ec->desk_group.desk_group, ec->desk_group.enable); + + if (!ec) return EINA_FALSE; + if (!ec->frame) return EINA_FALSE; + if (!ec->desk_group.enable) return EINA_FALSE; + if (!ec->desk_group.desk_group) return EINA_FALSE; + + edg = ec->desk_group.desk_group; + + // save original layer + _e_client_desk_group_original_layer_save(ec, layer); + + // get desk_group layer + edg_layer = (E_Layer)e_desk_group_layer_get(edg); + org_layer = e_client_desk_group_original_layer_get(ec); + + ELOGF("EDG", "layer_set by desk_group... org_layer:%d, new_layer:%d", ec, org_layer, edg_layer); + if (org_layer == edg_layer) + { + evas_object_raise(ec->frame); + } + else + { + evas_object_layer_set(ec->frame, edg_layer); + if (edg_layer == ec->layer) + evas_object_raise(ec->frame); + } + + return EINA_TRUE; +} + +EINTERN void +e_client_desk_group_original_layer_restore(E_Client *ec) +{ + if (!ec) return; + + // Do we need to check ec->desk_group.enable? + // if ec->desk_group.enable is true, then e_client_layer_set calls + // e_desk_group_ec_layer_set(). that's too bad. :( + // so, we MUST make a policy for ordering of the desk group layer restore + // and the desk group enable. + if (ec->desk_group.enable) return; + e_client_layer_set(ec, ec->desk_group.layer_backup); +} + +EINTERN E_Layer +e_client_desk_group_original_layer_get(E_Client *ec) +{ + if (!ec) return E_LAYER_DESKTOP; + + if (ec->desk_group.enable) + return ec->desk_group.layer_backup; + else + return ec->layer; +} + +EINTERN Eina_Bool +e_client_desk_group_client_layer_set(E_Client *ec, E_Desk_Group_Client_Layer edgc_layer) { E_OBJECT_CHECK_RETURN(ec, EINA_FALSE); E_OBJECT_TYPE_CHECK_RETURN(ec, E_CLIENT_TYPE, EINA_FALSE); - ec->desk_group.layer = layer; + ec->desk_group.edgc_layer = edgc_layer; return EINA_TRUE; } -EINTERN E_Desk_Group_Layer -e_client_desk_group_layer_get(E_Client *ec) +EINTERN E_Desk_Group_Client_Layer +e_client_desk_group_client_layer_get(E_Client *ec) { - E_OBJECT_CHECK_RETURN(ec, E_DESK_GROUP_LAYER_BACKGROUND); + E_OBJECT_CHECK_RETURN(ec, E_DESK_GROUP_CLIENT_LAYER_DESKTOP); - return ec->desk_group.layer; + return ec->desk_group.edgc_layer; } EINTERN Eina_Bool @@ -7887,6 +7973,26 @@ e_client_desk_group_enable_set(E_Client *ec, Eina_Bool enable) ec->desk_group.enable = enable; + ELOGF("EDG", "Desk group enable set to %d", ec, enable); + if (enable) + { + if (!ec->desk_group.transform) + { + ec->desk_group.transform = e_util_transform_new(); + e_client_transform_core_add(ec, ec->desk_group.transform); + } + } + else + { + if (ec->desk_group.transform) + { + e_client_transform_core_remove(ec, ec->desk_group.transform); + e_util_transform_del(ec->desk_group.transform); + ec->desk_group.transform = NULL; + } + } + + e_desk_group_ec_update(ec->desk_group.desk_group, ec); return EINA_TRUE; } @@ -7897,9 +8003,12 @@ e_client_desk_group_set(E_Client *ec, E_Desk_Group *edg) if (!ec) return EINA_FALSE; +#if 0 // if this is removed.. then below if (edg != old_edg) is removed also... if (ec->desk_group.desk_group == edg) return EINA_TRUE; +#endif + ELOGF("EDG", "Desk Group Set (new:%p, old:%p)", ec, edg, ec->desk_group.desk_group); old_edg = ec->desk_group.desk_group; if (old_edg) e_desk_group_ec_remove(old_edg, ec); @@ -7907,6 +8016,13 @@ e_client_desk_group_set(E_Client *ec, E_Desk_Group *edg) ec->desk_group.desk_group = edg; e_desk_group_ec_add(edg, ec); +#if 0 // if this is removed.. then above if (ec->desk_group.desk_group == edg) is removed also... + if (edg != old_edg) +#endif + { + e_desk_group_ec_update(edg, ec); + } + return EINA_TRUE; } @@ -7956,6 +8072,17 @@ e_client_stack_above(E_Client *ec, E_Client *above) if (!above) return; if (!above->frame) return; + if (ec->desk_group.enable) + { + E_Desk_Group *edg; + edg = ec->desk_group.desk_group; + if (edg) + { + e_desk_group_ec_stack_above(edg, ec, above); + return; + } + } + evas_object_stack_above(ec->frame, above->frame); } @@ -7967,6 +8094,17 @@ e_client_stack_below(E_Client *ec, E_Client *below) if (!below) return; if (!below->frame) return; + if (ec->desk_group.enable) + { + E_Desk_Group *edg; + edg = ec->desk_group.desk_group; + if (edg) + { + e_desk_group_ec_stack_below(edg, ec, below); + return; + } + } + evas_object_stack_below(ec->frame, below->frame); } diff --git a/src/bin/e_client.h b/src/bin/e_client.h index 94221a0d1e..a6c2027d31 100644 --- a/src/bin/e_client.h +++ b/src/bin/e_client.h @@ -1004,8 +1004,9 @@ struct E_Client { Eina_Bool enable; E_Desk_Group *desk_group; - int layer; - int layer_backup; + E_Desk_Group_Client_Layer edgc_layer; // used by desk_group mode + E_Layer layer_backup; // original layer (used by no desk_group mode) + E_Util_Transform *transform; } desk_group; }; @@ -1223,8 +1224,11 @@ E_API Eina_Bool e_client_layer_set(E_Client *ec, E_Layer layer); */ E_API E_Layer e_client_layer_get(E_Client *ec); -EINTERN Eina_Bool e_client_desk_group_layer_set(E_Client *ec, E_Desk_Group_Layer layer); -EINTERN E_Desk_Group_Layer e_client_desk_group_layer_get(E_Client *ec); +EINTERN Eina_Bool e_client_layer_set_by_desk_group(E_Client *ec, E_Layer layer); +EINTERN void e_client_desk_group_original_layer_restore(E_Client *ec); +EINTERN E_Layer e_client_desk_group_original_layer_get(E_Client *ec); +EINTERN Eina_Bool e_client_desk_group_client_layer_set(E_Client *ec, E_Desk_Group_Client_Layer edgc_layer); +EINTERN E_Desk_Group_Client_Layer e_client_desk_group_client_layer_get(E_Client *ec); EINTERN Eina_Bool e_client_desk_group_enable_set(E_Client *ec, Eina_Bool enable); E_API Eina_Bool e_client_desk_group_set(E_Client *ec, E_Desk_Group *edg); diff --git a/src/bin/e_desk.c b/src/bin/e_desk.c index f1f18272e2..fa91deebde 100644 --- a/src/bin/e_desk.c +++ b/src/bin/e_desk.c @@ -46,6 +46,8 @@ static void _e_desk_object_zoom(Evas_Object *obj, double zoomx, double zoom static void _e_desk_client_zoom(E_Client *ec, double zoomx, double zoomy, Evas_Coord cx, Evas_Coord cy); static void _e_desk_util_comp_hwc_disable_set(Eina_Bool enable); +static Eina_Bool _e_desk_desk_group_base_new(E_Desk *desk); + EVAS_SMART_SUBCLASS_NEW(E_DESK_SMART_OBJ_TYPE, _e_desk, Evas_Smart_Class, Evas_Smart_Class, evas_object_smart_clipped_class_get, NULL) @@ -178,11 +180,8 @@ e_desk_new(E_Zone *zone, int x, int y) if (!ok) desk->window_profile = eina_stringshare_ref(e_config->desktop_default_window_profile); - if (e_config->use_desk_group) - { - // Add a base e_desk_group - desk->desk_group.base = e_desk_desk_group_add(desk, desk->geom.x, desk->geom.y, desk->geom.w, desk->geom.h, E_DESK_GROUP_LAYER_NORMAL); - } + // new a base e_desk_group + _e_desk_desk_group_base_new(desk); return desk; } @@ -1211,12 +1210,15 @@ _e_desk_free(E_Desk *desk) if (e_config->use_desk_group) { - EINA_LIST_FOREACH(desk->desk_group.list, l, edg) + for (int i=E_DESK_GROUP_LAYER_COUNT-1; i>=0; i--) { - e_desk_group_del(edg); + EINA_LIST_FOREACH(desk->desk_group.list[i], l, edg) + { + e_desk_group_del(edg); + } + eina_list_free(desk->desk_group.list[i]); + desk->desk_group.list[i] = NULL; } - eina_list_free(desk->desk_group.list); - desk->desk_group.list = NULL; desk->desk_group.base = NULL; desk->desk_group.active = NULL; } @@ -1586,11 +1588,30 @@ _e_desk_client_zoom(E_Client *ec, double zoomx, double zoomy, Evas_Coord cx, Eva } } +static unsigned int +_e_desk_desk_group_layer_map(E_Desk_Group_Layer layer) +{ + switch (layer) + { + case E_DESK_GROUP_LAYER_BACKGROUND: return 0; + case E_DESK_GROUP_LAYER_NORMAL_BELOW: return 1; + case E_DESK_GROUP_LAYER_NORMAL: return 2; + case E_DESK_GROUP_LAYER_NORMAL_ABOVE: return 3; + case E_DESK_GROUP_LAYER_NOTIFICATION_LOW: return 4; + case E_DESK_GROUP_LAYER_NOTIFICATION_NORMAL: return 5; + case E_DESK_GROUP_LAYER_NOTIFICATION_HIGH: return 6; + case E_DESK_GROUP_LAYER_NOTIFICATION_TOP: return 7; + case E_DESK_GROUP_LAYER_SYSTEM: return 8; + default: return 0; + } +} + E_API E_Desk_Group * e_desk_desk_group_add(E_Desk *desk, int x, int y, int w, int h, E_Desk_Group_Layer layer) { E_Desk_Group *edg; int id; + unsigned int list_id; if (!e_config->use_desk_group) return NULL; @@ -1605,7 +1626,8 @@ e_desk_desk_group_add(E_Desk *desk, int x, int y, int w, int h, E_Desk_Group_Lay return NULL; } - desk->desk_group.list = eina_list_append(desk->desk_group.list, edg); + list_id = _e_desk_desk_group_layer_map(layer); + desk->desk_group.list[list_id] = eina_list_prepend(desk->desk_group.list[list_id], edg); desk->desk_group.id++; return edg; @@ -1614,6 +1636,8 @@ e_desk_desk_group_add(E_Desk *desk, int x, int y, int w, int h, E_Desk_Group_Lay E_API void e_desk_desk_group_del(E_Desk *desk, E_Desk_Group *edg) { + unsigned int list_id; + E_OBJECT_CHECK(desk); E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE); @@ -1621,7 +1645,8 @@ e_desk_desk_group_del(E_Desk *desk, E_Desk_Group *edg) if (!edg) return; - desk->desk_group.list = eina_list_remove(desk->desk_group.list, edg); + list_id = _e_desk_desk_group_layer_map(edg->layer); + desk->desk_group.list[list_id] = eina_list_remove(desk->desk_group.list[list_id], edg); } E_API E_Desk_Group * @@ -1633,13 +1658,34 @@ e_desk_desk_group_get_by_id(E_Desk *desk, int id) E_OBJECT_CHECK_RETURN(desk, NULL); E_OBJECT_TYPE_CHECK_RETURN(desk, E_DESK_TYPE, NULL); - EINA_LIST_FOREACH(desk->desk_group.list, l, edg) + for (int i=0; iid == id) - break; + EINA_LIST_FOREACH(desk->desk_group.list[i], l, edg) + { + if (edg->id == id) + return edg; + } } - return edg; + return NULL; +} + +static Eina_Bool +_e_desk_desk_group_base_new(E_Desk *desk) +{ + if (!desk) return EINA_FALSE; + if (!e_config->use_desk_group) return EINA_FALSE; + + if (!desk->desk_group.base) + { + // Add a base e_desk_group + desk->desk_group.base = e_desk_desk_group_add(desk, desk->geom.x, desk->geom.y, desk->geom.w/2, desk->geom.h/2, E_DESK_GROUP_LAYER_NORMAL); + } + + if (!desk->desk_group.base) + return EINA_FALSE; + else + return EINA_TRUE; } E_API E_Desk_Group * @@ -1697,9 +1743,12 @@ e_desk_desk_group_enable(E_Desk *desk) // check all ec is included in desk group _e_desk_desk_group_check_ec_in_desk_group(desk); - EINA_LIST_FOREACH(desk->desk_group.list, l, edg) + for (int i=0; idesk_group.list[i], l, edg) + { + e_desk_group_enable_set(edg, EINA_TRUE); + } } return EINA_TRUE; @@ -1720,14 +1769,108 @@ e_desk_desk_group_disable(E_Desk *desk) if (!desk->desk_group.enable) return EINA_TRUE; desk->desk_group.enable = EINA_FALSE; - EINA_LIST_FOREACH(desk->desk_group.list, l, edg) + for (int i=0; idesk_group.list[i], l, edg) + { + e_desk_group_enable_set(edg, EINA_FALSE); + } } - return EINA_TRUE; } +EINTERN void +e_desk_desk_group_raise(E_Desk *desk, E_Desk_Group *edg) +{ + unsigned int list_id; + + if (!e_config->use_desk_group) return; + + E_OBJECT_CHECK(desk); + E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE); + + if (!edg) return; + + ELOGF("EDG", "Raise Desk_Group... edg:%p", NULL, edg); + + list_id = _e_desk_desk_group_layer_map(edg->layer); + desk->desk_group.list[list_id] = eina_list_remove(desk->desk_group.list[list_id], edg); + desk->desk_group.list[list_id] = eina_list_prepend(desk->desk_group.list[list_id], edg); + + e_desk_group_raise(edg); +} + +EINTERN void +e_desk_desk_group_lower(E_Desk *desk, E_Desk_Group *edg) +{ + unsigned int list_id; + + if (!e_config->use_desk_group) return; + + E_OBJECT_CHECK(desk); + E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE); + + if (!edg) return; + + ELOGF("EDG", "Lower Desk_Group...", NULL); + + list_id = _e_desk_desk_group_layer_map(edg->layer); + desk->desk_group.list[list_id] = eina_list_remove(desk->desk_group.list[list_id], edg); + desk->desk_group.list[list_id] = eina_list_append(desk->desk_group.list[list_id], edg); + + e_desk_group_lower(edg); +} + +// get above E_Desk_Group in the same edg layer +EINTERN E_Desk_Group * +e_desk_desk_group_above_get(E_Desk *desk, E_Desk_Group *edg) +{ + Eina_List *l = NULL; + E_Desk_Group *above = NULL; + E_Desk_Group *temp = NULL; + unsigned int list_id; + + if (!desk) return NULL; + if (!edg) return NULL; + + list_id = _e_desk_desk_group_layer_map(edg->layer); + EINA_LIST_FOREACH(desk->desk_group.list[list_id], l, temp) + { + if (temp != edg) + above = temp; + else + break; + } + + ELOGF("EDG", "Get Above E_Desk_Group:%p... current:%p", NULL, above, edg); + return above; +} + +// get below E_Desk_Group in the same edg layer +EINTERN E_Desk_Group * +e_desk_desk_group_below_get(E_Desk *desk, E_Desk_Group *edg) +{ + Eina_List *l = NULL; + E_Desk_Group *below = NULL; + E_Desk_Group *temp = NULL; + unsigned int list_id; + + if (!desk) return NULL; + if (!edg) return NULL; + + list_id = _e_desk_desk_group_layer_map(edg->layer); + EINA_LIST_REVERSE_FOREACH(desk->desk_group.list[list_id], l, temp) + { + if (temp != edg) + below = temp; + else + break; + } + + ELOGF("EDG", "Get Below E_Desk_Group:%p... current:%p", NULL, below, edg); + return below; +} + EINTERN void e_desk_desk_group_info_print(E_Desk *desk) { @@ -1737,8 +1880,11 @@ e_desk_desk_group_info_print(E_Desk *desk) E_OBJECT_CHECK(desk); E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE); - EINA_LIST_FOREACH(desk->desk_group.list, l, edg) + for (int i=E_DESK_GROUP_LAYER_COUNT-1; i>=0; i--) { - e_desk_group_info_print(edg); + EINA_LIST_FOREACH(desk->desk_group.list[i], l, edg) + { + e_desk_group_info_print(edg); + } } } diff --git a/src/bin/e_desk.h b/src/bin/e_desk.h index 8dba59f658..a6e71386f9 100644 --- a/src/bin/e_desk.h +++ b/src/bin/e_desk.h @@ -14,6 +14,20 @@ typedef struct _E_Event_Desk_Geometry_Change E_Event_Desk_Geometry_Change; typedef void (*E_Desk_Flip_Cb)(void *data, E_Desk *desk, int dx, int dy, Eina_Bool show); +typedef enum _E_Desk_Group_Layer +{ + E_DESK_GROUP_LAYER_BACKGROUND = 0, //E_LAYER_DESKTOP + E_DESK_GROUP_LAYER_NORMAL_BELOW = 150, //E_LAYER_CLIENT_BELOW + E_DESK_GROUP_LAYER_NORMAL = 200, //E_LAYER_CLIENT_NORMAL, + E_DESK_GROUP_LAYER_NORMAL_ABOVE = 250, //E_LAYER_CLIENT_ABOVE, + E_DESK_GROUP_LAYER_NOTIFICATION_LOW = 650, //E_LAYER_CLIENT_NOTIFICATION_LOW, + E_DESK_GROUP_LAYER_NOTIFICATION_NORMAL = 700, //E_LAYER_CLIENT_NOTIFICATION_NORMAL, + E_DESK_GROUP_LAYER_NOTIFICATION_HIGH = 750, //E_LAYER_CLIENT_NOTIFICATION_HIGH, + E_DESK_GROUP_LAYER_NOTIFICATION_TOP = 800, //E_LAYER_CLIENT_NOTIFICATION_TOP, + E_DESK_GROUP_LAYER_SYSTEM = 900, //E_LAYER_CLIENT_ALERT, +} E_Desk_Group_Layer; +#define E_DESK_GROUP_LAYER_COUNT 9 + #else #ifndef E_DESK_H #define E_DESK_H @@ -53,7 +67,7 @@ struct _E_Desk { Eina_Bool enable; int id; - Eina_List *list; + Eina_List *list[E_DESK_GROUP_LAYER_COUNT]; E_Desk_Group *base; E_Desk_Group *active; } desk_group; @@ -124,6 +138,11 @@ E_API E_Desk_Group *e_desk_desk_group_base_get(E_Desk *desk); E_API E_Desk_Group *e_desk_desk_group_active_get(E_Desk *desk); E_API Eina_Bool e_desk_desk_group_enable(E_Desk *desk); E_API Eina_Bool e_desk_desk_group_disable(E_Desk *desk); +EINTERN void e_desk_desk_group_raise(E_Desk *desk, E_Desk_Group *edg); +EINTERN void e_desk_desk_group_lower(E_Desk *desk, E_Desk_Group *edg); +EINTERN E_Desk_Group *e_desk_desk_group_above_get(E_Desk *desk, E_Desk_Group *edg); +EINTERN E_Desk_Group *e_desk_desk_group_below_get(E_Desk *desk, E_Desk_Group *edg); + EINTERN void e_desk_desk_group_info_print(E_Desk *desk); diff --git a/src/bin/e_desk_group.c b/src/bin/e_desk_group.c index 4dbc1b942c..53775056f7 100644 --- a/src/bin/e_desk_group.c +++ b/src/bin/e_desk_group.c @@ -1,5 +1,100 @@ #include "e.h" +static void +_e_desk_group_ec_prepend(E_Desk_Group *edg, E_Client *ec) +{ + E_Desk_Group_Client_Layer edgc_layer; + + edgc_layer = e_client_desk_group_client_layer_get(ec); + edg->ec_lists[edgc_layer] = eina_list_remove(edg->ec_lists[edgc_layer], ec); + edg->ec_lists[edgc_layer] = eina_list_prepend(edg->ec_lists[edgc_layer], ec); + + e_client_desk_group_client_layer_set(ec, edgc_layer); +} + +static void +_e_desk_group_ec_append(E_Desk_Group *edg, E_Client *ec) +{ + E_Desk_Group_Client_Layer edgc_layer; + + edgc_layer = e_client_desk_group_client_layer_get(ec); + edg->ec_lists[edgc_layer] = eina_list_remove(edg->ec_lists[edgc_layer], ec); + edg->ec_lists[edgc_layer] = eina_list_append(edg->ec_lists[edgc_layer], ec); + + e_client_desk_group_client_layer_set(ec, edgc_layer); +} + +static void +_e_desk_group_ec_prepend_relative(E_Desk_Group *edg, E_Client *ec, E_Client *above) +{ + E_Desk_Group_Client_Layer edgc_layer; + E_Desk_Group_Client_Layer above_edgc_layer; + + // update edg's ec_list order + edgc_layer = e_client_desk_group_client_layer_get(ec); + above_edgc_layer = e_client_desk_group_client_layer_get(above); + + ELOGF("EDG", "STACK_ABOVE... edg:%p. layer:%d, above(win:%zx, ec:%p, layer:%d)", ec, edg, edgc_layer, e_client_util_win_get(above), above, above_edgc_layer); + + if (edgc_layer == above_edgc_layer) + { + edg->ec_lists[edgc_layer] = eina_list_remove(edg->ec_lists[edgc_layer], ec); + edg->ec_lists[edgc_layer] = eina_list_prepend_relative(edg->ec_lists[edgc_layer], ec, above); + } + else + { + edg->ec_lists[edgc_layer] = eina_list_remove(edg->ec_lists[edgc_layer], ec); + edg->ec_lists[above_edgc_layer] = eina_list_prepend_relative(edg->ec_lists[above_edgc_layer], ec, above); + } + + e_client_desk_group_client_layer_set(ec, above_edgc_layer); +} + +static void +_e_desk_group_ec_append_relative(E_Desk_Group *edg, E_Client *ec, E_Client *below) +{ + E_Desk_Group_Client_Layer edgc_layer; + E_Desk_Group_Client_Layer below_edgc_layer; + + // update edg's ec_list order + edgc_layer = e_client_desk_group_client_layer_get(ec); + below_edgc_layer = e_client_desk_group_client_layer_get(below); + + ELOGF("EDG", "STACK_BELOW... edg:%p. layer:%d, below(win:%zx, ec:%p, layer:%d)", ec, edg, edgc_layer, e_client_util_win_get(below), below, below_edgc_layer); + + if (edgc_layer == below_edgc_layer) + { + edg->ec_lists[edgc_layer] = eina_list_remove(edg->ec_lists[edgc_layer], ec); + edg->ec_lists[edgc_layer] = eina_list_append_relative(edg->ec_lists[edgc_layer], ec, below); + } + else + { + edg->ec_lists[edgc_layer] = eina_list_remove(edg->ec_lists[edgc_layer], ec); + edg->ec_lists[below_edgc_layer] = eina_list_append_relative(edg->ec_lists[below_edgc_layer], ec, below); + } + + e_client_desk_group_client_layer_set(ec, below_edgc_layer); +} + +static void +_e_desk_geometry_info_set(E_Desk_Group *edg, int x, int y, int w, int h) +{ + E_Desk *desk; + + if (!edg) return; + if (!edg->desk) return; + + desk = edg->desk; + + edg->x = x; + edg->y = y; + edg->w = w; + edg->h = h; + + edg->scale_w = (double)w / (double)desk->geom.w; + edg->scale_h = (double)h / (double)desk->geom.h; +} + EINTERN int e_desk_group_init(void) { @@ -26,10 +121,7 @@ e_desk_group_new(E_Desk *desk, int id, int x, int y, int w, int h, E_Desk_Group_ edg->desk = desk; edg->id = id; - edg->x = x; - edg->y = y; - edg->w = w; - edg->h = h; + _e_desk_geometry_info_set(edg, x, y, w, h); edg->layer = layer; @@ -41,7 +133,7 @@ e_desk_group_del(E_Desk_Group *edg) { if (!edg) return; - for (int i=0; iec_lists[i]); } @@ -49,35 +141,71 @@ e_desk_group_del(E_Desk_Group *edg) E_FREE(edg); } +void _e_desk_group_ec_geometry_apply(E_Desk_Group *edg, E_Client *ec) +{ + E_Util_Transform *transform; + + transform = ec->desk_group.transform; + if (!transform) return; + + e_util_transform_move(transform, edg->x, edg->y, 0); + e_util_transform_scale(transform, edg->scale_w, edg->scale_h, 1.0); + + e_client_transform_core_update(ec); +} + +void _e_desk_group_ec_geometry_restore(E_Desk_Group *edg, E_Client *ec) +{ + e_client_transform_core_update(ec); +} + void _e_desk_group_enable(E_Desk_Group *edg) { int i; E_Client *ec; Eina_List *l; + Eina_List *list; - for (i=0; iec_lists[i], l, ec) + list = eina_list_clone(edg->ec_lists[i]); + EINA_LIST_REVERSE_FOREACH(list, l, ec) { e_client_desk_group_enable_set(ec, EINA_TRUE); } + eina_list_free(list); + list = NULL; } - - e_desk_group_all_ec_update(edg); } void _e_desk_group_disable(E_Desk_Group *edg) { int i; E_Client *ec; - Eina_List *l; + Eina_List *l = NULL; + Eina_List *list = NULL; - for (i=0; iec_lists[i], l, ec) + list = eina_list_clone(edg->ec_lists[i]); + EINA_LIST_REVERSE_FOREACH(list, l, ec) { + // unset ec's desk_group enable flag e_client_desk_group_enable_set(ec, EINA_FALSE); + // restore original ec->layer + e_client_desk_group_original_layer_restore(ec); + // restore ec's original geometry (changing real geometry or using transform) + _e_desk_group_ec_geometry_restore(edg, ec); + + e_client_desk_group_set(ec, NULL); } + eina_list_free(list); + list = NULL; + + eina_list_free(edg->ec_lists[i]); + edg->ec_lists[i] = NULL; } } @@ -104,10 +232,7 @@ e_desk_group_geometry_set(E_Desk_Group *edg, int x, int y, int w, int h) { if (!edg) return EINA_FALSE; - edg->x = x; - edg->y = y; - edg->w = w; - edg->h = h; + _e_desk_geometry_info_set(edg, x, y, w, h); return EINA_TRUE; } @@ -161,13 +286,14 @@ e_desk_group_raise(E_Desk_Group *edg) { int i; E_Client *ec; - Eina_List *l; + Eina_List *l = NULL; + Eina_List *ll = NULL; if (!edg) return; - for (i=0; iec_lists[i], l, ec) + EINA_LIST_REVERSE_FOREACH_SAFE(edg->ec_lists[i], l, ll, ec) { evas_object_raise(ec->frame); } @@ -179,60 +305,45 @@ e_desk_group_lower(E_Desk_Group *edg) { int i; E_Client *ec; - Eina_List *l; + Eina_List *l = NULL; + Eina_List *ll = NULL; if (!edg) return; - for (i=E_DESK_GROUP_LAYER_COUNT-1; i>=0; i--) + for (i=E_DESK_GROUP_CLIENT_LAYER_MAX-1; i>=0; i--) { - EINA_LIST_FOREACH(edg->ec_lists[i], l, ec) + //EINA_LIST_FOREACH(edg->ec_lists[i], l, ec) + EINA_LIST_FOREACH_SAFE(edg->ec_lists[i], l, ll, ec) { evas_object_lower(ec->frame); } } } -static unsigned int -_e_desk_group_layer_map(E_Desk_Group_Layer layer) -{ - switch (layer) - { - case E_DESK_GROUP_LAYER_BACKGROUND: return 0; - case E_DESK_GROUP_LAYER_NORMAL_BELOW: return 1; - case E_DESK_GROUP_LAYER_NORMAL: return 2; - case E_DESK_GROUP_LAYER_NORMAL_ABOVE: return 3; - case E_DESK_GROUP_LAYER_NOTIFICATION_LOW: return 4; - case E_DESK_GROUP_LAYER_NOTIFICATION_NORMAL: return 5; - case E_DESK_GROUP_LAYER_NOTIFICATION_HIGH: return 6; - case E_DESK_GROUP_LAYER_NOTIFICATION_TOP: return 7; - case E_DESK_GROUP_LAYER_SYSTEM: return 7; - default: return 1; - } -} -static E_Desk_Group_Layer -_e_desk_group_layer_convert_from_elayer(E_Layer elayer) +static E_Desk_Group_Client_Layer +_e_desk_group_client_layer_convert_from_layer(E_Layer layer) { - E_Desk_Group_Layer edg_layer; - - if (elayer < E_LAYER_CLIENT_BELOW) - edg_layer = E_DESK_GROUP_LAYER_BACKGROUND; - else if (elayer < E_LAYER_CLIENT_NORMAL) - edg_layer = E_DESK_GROUP_LAYER_NORMAL_BELOW; - else if (elayer < E_LAYER_CLIENT_ABOVE) - edg_layer = E_DESK_GROUP_LAYER_NORMAL; - else if (elayer < E_LAYER_CLIENT_NOTIFICATION_LOW) - edg_layer = E_DESK_GROUP_LAYER_NORMAL_ABOVE; - else if (elayer < E_LAYER_CLIENT_NOTIFICATION_NORMAL) - edg_layer = E_DESK_GROUP_LAYER_NOTIFICATION_LOW; - else if (elayer < E_LAYER_CLIENT_NOTIFICATION_HIGH) - edg_layer = E_DESK_GROUP_LAYER_NOTIFICATION_NORMAL; - else if (elayer < E_LAYER_CLIENT_NOTIFICATION_TOP) - edg_layer = E_DESK_GROUP_LAYER_NOTIFICATION_HIGH; - else if (elayer < E_LAYER_CLIENT_ALERT_LOW) - edg_layer = E_DESK_GROUP_LAYER_NOTIFICATION_TOP; + E_Desk_Group_Client_Layer edg_layer; + + if (layer <= E_LAYER_CLIENT_DESKTOP) + edg_layer = E_DESK_GROUP_CLIENT_LAYER_DESKTOP; + else if (layer <= E_LAYER_CLIENT_BELOW) + edg_layer = E_DESK_GROUP_CLIENT_LAYER_BELOW; + else if (layer <= E_LAYER_CLIENT_NORMAL) + edg_layer = E_DESK_GROUP_CLIENT_LAYER_NORMAL; + else if (layer <= E_LAYER_CLIENT_ABOVE) + edg_layer = E_DESK_GROUP_CLIENT_LAYER_ABOVE; + else if (layer <= E_LAYER_CLIENT_NOTIFICATION_LOW) + edg_layer = E_DESK_GROUP_CLIENT_LAYER_NOTIFICATION_LOW; + else if (layer <= E_LAYER_CLIENT_NOTIFICATION_NORMAL) + edg_layer = E_DESK_GROUP_CLIENT_LAYER_NOTIFICATION_NORMAL; + else if (layer <= E_LAYER_CLIENT_NOTIFICATION_HIGH) + edg_layer = E_DESK_GROUP_CLIENT_LAYER_NOTIFICATION_HIGH; + else if (layer <= E_LAYER_CLIENT_NOTIFICATION_TOP) + edg_layer = E_DESK_GROUP_CLIENT_LAYER_NOTIFICATION_TOP; else - edg_layer = E_DESK_GROUP_LAYER_SYSTEM; + edg_layer = E_DESK_GROUP_CLIENT_LAYER_ALERT; return edg_layer; } @@ -240,18 +351,19 @@ _e_desk_group_layer_convert_from_elayer(E_Layer elayer) E_API Eina_Bool e_desk_group_ec_add(E_Desk_Group *edg, E_Client *ec) { - int edg_layer; - int index; + E_Desk_Group_Client_Layer edgc_layer; + E_Layer layer; if (!edg) return EINA_FALSE; if (!ec) return EINA_FALSE; - edg_layer = _e_desk_group_layer_convert_from_elayer(ec->layer); - index = _e_desk_group_layer_map(edg_layer); - edg->ec_lists[index] = eina_list_prepend(edg->ec_lists[index], ec); + layer = e_client_desk_group_original_layer_get(ec); + edgc_layer = _e_desk_group_client_layer_convert_from_layer(layer); - e_client_desk_group_layer_set(ec, edg_layer); + edg->ec_lists[edgc_layer] = eina_list_prepend(edg->ec_lists[edgc_layer], ec); + + e_client_desk_group_client_layer_set(ec, edgc_layer); return EINA_TRUE; } @@ -259,49 +371,556 @@ e_desk_group_ec_add(E_Desk_Group *edg, E_Client *ec) E_API void e_desk_group_ec_remove(E_Desk_Group *edg, E_Client *ec) { - int edg_layer; - int index; + E_Desk_Group_Client_Layer edgc_layer; if (!edg) return; if (!ec) return; - edg_layer = e_client_desk_group_layer_get(ec); - index = _e_desk_group_layer_map(edg_layer); + edgc_layer = e_client_desk_group_client_layer_get(ec); + + edg->ec_lists[edgc_layer] = eina_list_remove(edg->ec_lists[edgc_layer], ec); +} + +static E_Client * +_get_bottom_ec_of_above_edg(E_Desk_Group *edg) +{ + E_Desk_Group *prev_edg = NULL; + E_Client *bottom = NULL; + + prev_edg = e_desk_desk_group_above_get(edg->desk, edg); + if (prev_edg) + { + Eina_List *l; + int i; + + for (i=0; iec_lists[i], l, bottom) + { + if (bottom) + goto find_bottom; + } + } + } + +find_bottom: + return bottom; +} + +static E_Client * +_get_top_ec_of_below_edg(E_Desk_Group *edg) +{ + E_Desk_Group *next_edg = NULL; + E_Client *top = NULL; + Eina_List *l; + int i; + + next_edg = e_desk_desk_group_below_get(edg->desk, edg); + if (next_edg) + { + for (i=E_DESK_GROUP_CLIENT_LAYER_MAX-1; i>=0; i--) + { + EINA_LIST_FOREACH(next_edg->ec_lists[i], l, top) + { + if (top) + goto find_top; + } + } + } + +find_top: + return top; +} + +static E_Client * +_find_above_ec_in_same_edgc_layer(E_Desk_Group *edg, E_Client *ec) +{ + Eina_List *l; + E_Client *above = NULL; + E_Client *temp = NULL; + E_Desk_Group_Client_Layer edgc_layer; + Eina_Bool find = EINA_FALSE; + + edgc_layer = e_client_desk_group_client_layer_get(ec); + EINA_LIST_REVERSE_FOREACH(edg->ec_lists[edgc_layer], l, temp) + { + if (find) + { + above = temp; + break; + } + + if (temp == ec) + { + find = EINA_TRUE; + } + } + + // TODO: do we need check below->frame??? - edg->ec_lists[index] = eina_list_remove(edg->ec_lists[index], ec); + return above; +} + +static E_Client * +_find_bottom_ec_in_above_edgc_layer(E_Desk_Group *edg, E_Client *ec) +{ + Eina_List *l; + E_Client *bottom = NULL; + E_Desk_Group_Client_Layer edgc_layer; + int i; + + edgc_layer = e_client_desk_group_client_layer_get(ec); + for (i = edgc_layer+1; i < E_DESK_GROUP_CLIENT_LAYER_MAX; i++) + { + EINA_LIST_REVERSE_FOREACH(edg->ec_lists[i], l, bottom) + { + // TODO: do we need check below->frame??? + if (bottom) + return bottom; + } + } + + return NULL; +} + +static E_Client * +_find_bottom_ec_in_above_edg(E_Desk_Group *edg) +{ + E_Desk_Group *above_edg = NULL; + E_Client *bottom = NULL; + Eina_List *l; + int i; + + above_edg = e_desk_desk_group_above_get(edg->desk, edg); + while (above_edg) + { + for (i=E_DESK_GROUP_CLIENT_LAYER_DESKTOP; iec_lists[i], l, bottom) + { + if (bottom) + goto find_bottom; + } + } + + bottom = NULL; + above_edg = e_desk_desk_group_above_get(above_edg->desk, above_edg); + } + +find_bottom: + return bottom; +} + +static E_Client * +_find_below_ec_in_same_edgc_layer(E_Desk_Group *edg, E_Client *ec) +{ + Eina_List *l; + E_Client *below = NULL; + E_Client *temp = NULL; + E_Desk_Group_Client_Layer edgc_layer; + Eina_Bool find = EINA_FALSE; + + edgc_layer = e_client_desk_group_client_layer_get(ec); + EINA_LIST_FOREACH(edg->ec_lists[edgc_layer], l, temp) + { + if (find) + { + below = temp; + break; + } + + if (temp == ec) + { + find = EINA_TRUE; + } + } + + // TODO: do we need check below->frame??? + + return below; +} + +static E_Client * +_find_top_ec_in_below_edgc_layer(E_Desk_Group *edg, E_Client *ec) +{ + Eina_List *l; + E_Client *top = NULL; + E_Desk_Group_Client_Layer edgc_layer; + int i; + + edgc_layer = e_client_desk_group_client_layer_get(ec); + for (i = edgc_layer-1; i >= E_DESK_GROUP_CLIENT_LAYER_DESKTOP; i--) + { + EINA_LIST_FOREACH(edg->ec_lists[i], l, top) + { + // TODO: do we need check top->frame??? + if (top) + return top; + } + } + + return NULL; +} + +static E_Client * +_find_top_ec_in_below_edg(E_Desk_Group *edg) +{ + E_Desk_Group *below_edg = NULL; + E_Client *top = NULL; + Eina_List *l; + int i; + + below_edg = e_desk_desk_group_below_get(edg->desk, edg); + while (below_edg) + { + for (i=E_DESK_GROUP_CLIENT_LAYER_MAX-1; i>=E_DESK_GROUP_CLIENT_LAYER_DESKTOP; i--) + { + EINA_LIST_FOREACH(below_edg->ec_lists[i], l, top) + { + if (top) + goto find_top; + } + } + + top = NULL; + below_edg = e_desk_desk_group_below_get(below_edg->desk, below_edg); + } + +find_top: + return top; } EINTERN void e_desk_group_ec_raise(E_Desk_Group *edg, E_Client *ec) { + E_Client *below = NULL; + E_Client *above = NULL; + if (!edg) return; if (!ec) return; + ELOGF("EDG", "RAISE... edg:%p", ec, edg); + + _e_desk_group_ec_prepend(edg, ec); + + // 1. find below ec in same edgc layer in same edg + below = _find_below_ec_in_same_edgc_layer(edg, ec); + if (below) goto find_below; + + // 2. find above ec in same edgc layer in same edg + above = _find_above_ec_in_same_edgc_layer(edg, ec); + if (above) goto find_above; + + // 3. find bottom ec in above edgc layer in same edg + above = _find_bottom_ec_in_above_edgc_layer(edg, ec); + if (above) goto find_above; + + // 4. find bottom ec in above edg + above = _find_bottom_ec_in_above_edg(edg); + if (above) goto find_above; + + // 5. if not found, just evas_object_raise + ELOGF("EDG", "RAISE... call evas_object_raise", ec); evas_object_raise(ec->frame); + return; - // update edg's ec_list order +find_below: + if (below) + { + ELOGF("EDG", "STACK_ABOVE... below(win:0x%08zx, ec:%p)", ec, e_client_util_win_get(below), below); + if (below->frame) + { + ELOGF("EDG", "STACK_ABOVE... call evas_object_stack_above", ec); + evas_object_stack_above(ec->frame, below->frame); + } + } + return; + +find_above: + if (above) + { + ELOGF("EDG", "STACK_BELOW... above(win:0x%08zx, ec:%p)", ec, e_client_util_win_get(above), above); + if (above->frame) + { + ELOGF("EDG", "STACK_BELOW... call evas_object_stack_below", ec); + evas_object_stack_below(ec->frame, above->frame); + } + } + return; } EINTERN void e_desk_group_ec_lower(E_Desk_Group *edg, E_Client *ec) { + E_Client *above = NULL; + E_Client *below = NULL; + if (!edg) return; if (!ec) return; + ELOGF("EDG", "LOWER... edg:%p", ec, edg); + + _e_desk_group_ec_append(edg, ec); + + // 1. find above ec in same edgc layer in same edg + above = _find_above_ec_in_same_edgc_layer(edg, ec); + if (above) goto find_above; + + // 2. find below ec in same edgc layer in same edg + below = _find_below_ec_in_same_edgc_layer(edg, ec); + if (below) goto find_below; + + // 3. find top ec in below edgc layer in same edg + below = _find_top_ec_in_below_edgc_layer(edg, ec); + if (below) goto find_below; + + // 4. find top ec in below edg + below = _find_top_ec_in_below_edg(edg); + if (below) goto find_below; + + // 5. if not found, just evas_object_raise + ELOGF("EDG", "LOWER... call evas_object_raise", ec); evas_object_lower(ec->frame); + return; - // update edg's ec_list order +find_below: + if (below) + { + ELOGF("EDG", "STACK_ABOVE... below(win:0x%08zx, ec:%p)", ec, e_client_util_win_get(below), below); + if (below->frame) + { + ELOGF("EDG", "STACK_ABOVE... call evas_object_stack_above", ec); + evas_object_stack_above(ec->frame, below->frame); + } + } + return; + +find_above: + if (above) + { + ELOGF("EDG", "STACK_BELOW... above(win:0x%08zx, ec:%p)", ec, e_client_util_win_get(above), above); + if (above->frame) + { + ELOGF("EDG", "STACK_BELOW... call evas_object_stack_below", ec); + evas_object_stack_below(ec->frame, above->frame); + } + } + return; +} + +EINTERN void +e_desk_group_ec_stack_above(E_Desk_Group *edg, E_Client *ec, E_Client *above) +{ + if (!edg) return; + if (!ec) return; + if (!ec->frame) return; + if (!above) return; + if (!above->frame) return; + + _e_desk_group_ec_prepend_relative(edg, ec, above); + + evas_object_stack_above(ec->frame, above->frame); +} + +EINTERN void +e_desk_group_ec_stack_below(E_Desk_Group *edg, E_Client *ec, E_Client *below) +{ + if (!edg) return; + if (!ec) return; + if (!ec->frame) return; + if (!below) return; + if (!below->frame) return; + + _e_desk_group_ec_append_relative(edg, ec, below); + + evas_object_stack_below(ec->frame, below->frame); +} + +EINTERN void +e_desk_group_ec_layer_set(E_Desk_Group *edg, E_Client *ec, E_Layer layer) +{ + E_Desk_Group_Client_Layer edg_layer; + + if (!edg) return; + if (!ec) return; + + // save original layer + + edg_layer = edg->layer; + evas_object_layer_set(ec->frame, edg_layer); +} + +static E_Client * +_find_above_ec(E_Desk_Group *edg, E_Client *ec) +{ + E_Client *above = NULL; + E_Desk_Group_Client_Layer edgc_layer; + Eina_List *l; + int index; + int i; + + edgc_layer = e_client_desk_group_client_layer_get(ec); + + index = eina_list_data_idx(edg->ec_lists[edgc_layer], ec); + if (index < 0) + { + // error... + return NULL; + } + else if (index > 0) + { + above = eina_list_nth(edg->ec_lists[edgc_layer], index-1); + if (above && above->frame) + { + // find above ec in same layer + return above; + } + } + + // search for above layer + for (i=edgc_layer+1; iec_lists[i], l, above) + { + if (above && above->frame) + { + // find above ec + return above; + } + } + } + + return NULL; +} + +static E_Client * +_find_below_ec(E_Desk_Group *edg, E_Client *ec) +{ + E_Client *below = NULL; + E_Desk_Group_Client_Layer edgc_layer; + Eina_List *l; + int index; + int i; + + edgc_layer = e_client_desk_group_client_layer_get(ec); + + index = eina_list_data_idx(edg->ec_lists[edgc_layer], ec); + if (index < 0) + { + // error... + return NULL; + } + else + { + below = eina_list_nth(edg->ec_lists[edgc_layer], index+1); + if (below && below->frame) + { + // find below ec in same layer + return below; + } + } + + // search for below layer + for (i=edgc_layer-1; i>=E_DESK_GROUP_CLIENT_LAYER_DESKTOP; i--) + { + EINA_LIST_FOREACH(edg->ec_lists[i], l, below) + { + if (below && below->frame) + { + // find below ec + return below; + } + } + } + + return NULL; +} + +static void +_e_desk_group_ec_restack(E_Desk_Group *edg, E_Client *ec) +{ + E_Client *above = NULL, *below = NULL; + + above = _find_above_ec(edg, ec); + if (above) + { + evas_object_stack_below(ec->frame, above->frame); + goto end; + } + + below = _find_below_ec(edg, ec); + if (below) + { + evas_object_stack_above(ec->frame, below->frame); + goto end; + } + + if (!above && !below) + { + // check another edg... + above = _get_bottom_ec_of_above_edg(edg); + if (above) + { + if (above->frame) + { + evas_object_stack_below(ec->frame, above->frame); + goto end; + } + } + + below = _get_top_ec_of_below_edg(edg); + if (below) + { + if (below->frame) + { + evas_object_stack_above(ec->frame, below->frame); + goto end; + } + } + } + +end: + return; +} + +EINTERN void +e_desk_group_ec_rearrange(E_Desk_Group *edg, E_Client *ec) +{ + E_Layer layer; + E_Desk_Group_Client_Layer edgc_layer, prev_edgc_layer; + + prev_edgc_layer = e_client_desk_group_client_layer_get(ec); + edg->ec_lists[prev_edgc_layer] = eina_list_remove(edg->ec_lists[prev_edgc_layer], ec); + + layer = e_client_desk_group_original_layer_get(ec); + edgc_layer = _e_desk_group_client_layer_convert_from_layer(layer); + edg->ec_lists[edgc_layer] = eina_list_prepend(edg->ec_lists[edgc_layer], ec); + + e_client_desk_group_client_layer_set(ec, edgc_layer); + + _e_desk_group_ec_restack(edg, ec); +} + +EINTERN void +e_desk_group_ec_stack_change(E_Desk_Group *edg, E_Client *ec) +{ } E_API void e_desk_group_ec_update(E_Desk_Group *edg, E_Client *ec) { + E_Layer layer; + if (!edg) return; if (!ec) return; - e_client_pos_set(ec, edg->x, edg->y); - e_client_size_set(ec, edg->w, edg->h); - ec->changes.pos = 1; + layer = e_client_desk_group_original_layer_get(ec); + + // update stack + e_client_layer_set_by_desk_group(ec, layer); + + // update geometry + _e_desk_group_ec_geometry_apply(edg, ec); } E_API void @@ -310,15 +929,21 @@ e_desk_group_all_ec_update(E_Desk_Group *edg) int i; E_Client *ec; Eina_List *l; + Eina_List *list; if (!edg) return; - for (i=0; iec_lists[i], l, ec) + list = eina_list_clone(edg->ec_lists[i]); + + EINA_LIST_REVERSE_FOREACH(list, l, ec) { e_desk_group_ec_update(edg, ec); } + + eina_list_free(list); + list = NULL; } } @@ -343,11 +968,11 @@ e_desk_group_info_print(E_Desk_Group *edg) ELOGF("EDG_INFO", "===========================================", NULL); ELOGF("EDG_INFO", "E_Desk_Group(%p), ID(%d), Geo(%d,%d,%d,%d), Layer:%d", NULL, edg, edg->id, edg->x, edg->y, edg->w, edg->h, edg->layer); ELOGF("EDG_INFO", "-------------------------------------------", NULL); - for (int i=E_DESK_GROUP_LAYER_COUNT-1; i>=0; i--) + for (int i=E_DESK_GROUP_CLIENT_LAYER_MAX-1; i>=0; i--) { EINA_LIST_FOREACH(edg->ec_lists[i], l, ec) { - ELOGF("EDG_INFO", "EDG_Layer[%d] EC(win:%lx, ec:%p), ec->layer:%d, org_layer:%d", NULL, i, (long unsigned int)e_client_util_win_get(ec), ec, ec->layer, ec->desk_group.layer_backup); + ELOGF("EDG_INFO", "EDG_Layer[%d] Win:0x%08zx, EC:%p, frame:%p, ec->layer:%d, org_layer:%d, name:%s", NULL, i, e_client_util_win_get(ec), ec, ec->frame, ec->layer, ec->desk_group.layer_backup, ec->icccm.title ? ec->icccm.title:"NO NAME"); } } ELOGF("EDG_INFO", "===========================================", NULL); diff --git a/src/bin/e_desk_group.h b/src/bin/e_desk_group.h index 1abfd5487f..d89a4affff 100644 --- a/src/bin/e_desk_group.h +++ b/src/bin/e_desk_group.h @@ -3,20 +3,19 @@ typedef struct _E_Desk_Group E_Desk_Group; typedef struct _E_Event_Desk_Group E_Event_Desk_Group; -typedef enum _E_Desk_Group_Layer +typedef enum _E_Desk_Group_Client_Layer { - E_DESK_GROUP_LAYER_BACKGROUND = 0, - E_DESK_GROUP_LAYER_NORMAL_BELOW = 150, - E_DESK_GROUP_LAYER_NORMAL = 200, - E_DESK_GROUP_LAYER_NORMAL_ABOVE = 250, - E_DESK_GROUP_LAYER_NOTIFICATION_LOW = 650, - E_DESK_GROUP_LAYER_NOTIFICATION_NORMAL = 700, - E_DESK_GROUP_LAYER_NOTIFICATION_HIGH = 750, - E_DESK_GROUP_LAYER_NOTIFICATION_TOP = 800, - E_DESK_GROUP_LAYER_SYSTEM = 990, -} E_Desk_Group_Layer; - -# define E_DESK_GROUP_LAYER_COUNT 9 + E_DESK_GROUP_CLIENT_LAYER_DESKTOP, + E_DESK_GROUP_CLIENT_LAYER_BELOW, + E_DESK_GROUP_CLIENT_LAYER_NORMAL, + E_DESK_GROUP_CLIENT_LAYER_ABOVE, + E_DESK_GROUP_CLIENT_LAYER_NOTIFICATION_LOW, + E_DESK_GROUP_CLIENT_LAYER_NOTIFICATION_NORMAL, + E_DESK_GROUP_CLIENT_LAYER_NOTIFICATION_HIGH, + E_DESK_GROUP_CLIENT_LAYER_NOTIFICATION_TOP, + E_DESK_GROUP_CLIENT_LAYER_ALERT, + E_DESK_GROUP_CLIENT_LAYER_MAX, +} E_Desk_Group_Client_Layer; #else #ifndef E_DESK_GROUP_H @@ -32,10 +31,11 @@ struct _E_Desk_Group Eina_Stringshare *name; int x, y, w, h; + double scale_w, scale_h; unsigned char enable : 1; unsigned char visible : 1; - Eina_List *ec_lists[E_DESK_GROUP_LAYER_COUNT]; + Eina_List *ec_lists[E_DESK_GROUP_CLIENT_LAYER_MAX]; Eina_List *handlers; }; @@ -57,7 +57,7 @@ E_API Eina_Bool e_desk_group_geometry_set(E_Desk_Group *edg, int x, int y, E_API Eina_Bool e_desk_group_geometry_get(E_Desk_Group *edg, int *x, int *y, int *w, int *h); EINTERN Eina_Bool e_desk_group_layer_set(E_Desk_Group *edg, E_Desk_Group_Layer layer); -E_API E_Desk_Group_Layer e_desk_group_layer_get(E_Desk_Group *edg); +E_API E_Desk_Group_Layer e_desk_group_layer_get(E_Desk_Group *edg); E_API void e_desk_group_activate(E_Desk_Group *edg); E_API Eina_Bool e_desk_group_is_activate(E_Desk_Group *edg); @@ -70,7 +70,11 @@ E_API Eina_Bool e_desk_group_ec_add(E_Desk_Group *edg, E_Client *ec); E_API void e_desk_group_ec_remove(E_Desk_Group *edg, E_Client *ec); EINTERN void e_desk_group_ec_raise(E_Desk_Group *edg, E_Client *ec); EINTERN void e_desk_group_ec_lower(E_Desk_Group *edg, E_Client *ec); - +EINTERN void e_desk_group_ec_stack_above(E_Desk_Group *edg, E_Client *ec, E_Client *above); +EINTERN void e_desk_group_ec_stack_below(E_Desk_Group *edg, E_Client *ec, E_Client *below); +EINTERN void e_desk_group_ec_layer_set(E_Desk_Group *edg, E_Client *ec, E_Layer layer); +EINTERN void e_desk_group_ec_rearrange(E_Desk_Group *edg, E_Client *ec); +EINTERN void e_desk_group_ec_stack_change(E_Desk_Group *edg, E_Client *ec); E_API void e_desk_group_ec_update(E_Desk_Group *edg, E_Client *ec); E_API void e_desk_group_all_ec_update(E_Desk_Group *edg); @@ -79,5 +83,8 @@ E_API Eina_List *e_desk_group_ec_list_get(E_Desk_Group *edg); // for debug EINTERN void e_desk_group_info_print(E_Desk_Group *edg); + +extern E_API int E_EVENT_DESK_GROUP_CHANGE; + #endif #endif diff --git a/src/bin/e_includes.h b/src/bin/e_includes.h index e96903997f..24420fdb7a 100644 --- a/src/bin/e_includes.h +++ b/src/bin/e_includes.h @@ -4,7 +4,6 @@ #include "e_error.h" #include "e_zone.h" #include "e_desk.h" -#include "e_desk_group.h" #include "e_pixmap.h" #include "e_comp_object.h" #include "e_util_transform.h" @@ -94,4 +93,5 @@ #include "e_comp_wl_video.h" #include "e_comp_wl_video_buffer.h" #include "e_msg.h" +#include "e_desk_group.h" #include "e_comp_wl_capture.h" diff --git a/src/bin/e_policy_stack.c b/src/bin/e_policy_stack.c index b43e4b18de..d1e6ab38d6 100644 --- a/src/bin/e_policy_stack.c +++ b/src/bin/e_policy_stack.c @@ -105,23 +105,56 @@ _e_policy_stack_transient_for_apply(E_Client *ec) return; } - if (ec->parent->layer != ec->layer) + if (ec->desk_group.enable) { - raise = e_config->transient.raise; + E_Layer layer; + E_Layer parent_layer; - ec->saved.layer = ec->layer; - if (e_config->transient.layer) + layer = e_client_desk_group_original_layer_get(ec); + if (ec->parent) + parent_layer = e_client_desk_group_original_layer_get(ec->parent); + else + parent_layer = e_client_desk_group_original_layer_get(ec); + + if (parent_layer != layer) { - e_config->transient.raise = 1; - EINA_LIST_FOREACH(ec->transients, l, child) + raise = e_config->transient.raise; + + ec->saved.layer = layer; + if (e_config->transient.layer) { - if (!child) continue; - child->saved.layer = child->layer; + e_config->transient.raise = 1; + EINA_LIST_FOREACH(ec->transients, l, child) + { + if (!child) continue; + child->saved.layer = e_client_desk_group_original_layer_get(child); + } } + + e_client_layer_set(ec, parent_layer); + e_config->transient.raise = raise; } + } + else + { + if (ec->parent->layer != ec->layer) + { + raise = e_config->transient.raise; - e_client_layer_set(ec, ec->parent->layer); - e_config->transient.raise = raise; + ec->saved.layer = ec->layer; + if (e_config->transient.layer) + { + e_config->transient.raise = 1; + EINA_LIST_FOREACH(ec->transients, l, child) + { + if (!child) continue; + child->saved.layer = child->layer; + } + } + + e_client_layer_set(ec, ec->parent->layer); + e_config->transient.raise = raise; + } } if (ec->transient_policy == E_TRANSIENT_ABOVE) @@ -254,6 +287,17 @@ _e_policy_stack_fetch_icccm_transient_for(E_Client *ec) ps->transient.fetched = 1; } + if (parent) + { + if (ec->desk_group.desk_group && parent->desk_group.desk_group) + { + if (ec->desk_group.desk_group != parent->desk_group.desk_group) + { + e_client_desk_group_set(ec, parent->desk_group.desk_group); + } + } + } + ec->icccm.fetch.transient_for = 0; } } diff --git a/src/bin/e_policy_wl.c b/src/bin/e_policy_wl.c index 9b1cbc3c0a..b95b1b8770 100644 --- a/src/bin/e_policy_wl.c +++ b/src/bin/e_policy_wl.c @@ -1944,6 +1944,7 @@ _tzpol_iface_cb_conformant_get(struct wl_client *client EINA_UNUSED, struct wl_r static void _tzpol_notilv_set(E_Client *ec, int lv) { + short cur_ly; short ly; switch (lv) @@ -1959,7 +1960,12 @@ _tzpol_notilv_set(E_Client *ec, int lv) default: ly = E_LAYER_CLIENT_NOTIFICATION_LOW; break; } - if (ec->layer != ly) + if (e_config->use_desk_group) + cur_ly = e_client_desk_group_original_layer_get(ec); + else + cur_ly = e_client_layer_get(ec); + + if (cur_ly != ly) { if (ly == E_LAYER_CLIENT_NORMAL) e_policy_animatable_lock(ec, E_POLICY_ANIMATABLE_LAYER, 0); @@ -1968,7 +1974,6 @@ _tzpol_notilv_set(E_Client *ec, int lv) e_client_layer_set(ec, ly); } - e_policy_hook_call(E_POLICY_HOOK_CLIENT_NOTILAYER_SET, ec); } diff --git a/src/bin/services/e_service_lockscreen.c b/src/bin/services/e_service_lockscreen.c index 91bf359e30..f97d46d54a 100644 --- a/src/bin/services/e_service_lockscreen.c +++ b/src/bin/services/e_service_lockscreen.c @@ -4,6 +4,8 @@ EINTERN Eina_Bool e_service_lockscreen_client_set(E_Client *ec) { + E_Layer layer; + if (!ec) return EINA_TRUE; if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE; @@ -12,11 +14,15 @@ e_service_lockscreen_client_set(E_Client *ec) e_client_window_role_set(ec, "lockscreen"); // set lockscreen layer - if (E_LAYER_CLIENT_NOTIFICATION_LOW > ec->layer) + if (e_config->use_desk_group) + layer = e_client_desk_group_original_layer_get(ec); + else + layer = e_client_layer_get(ec); + + if (E_LAYER_CLIENT_NOTIFICATION_LOW > layer) { e_client_layer_set(ec, E_LAYER_CLIENT_NOTIFICATION_LOW); } - return EINA_TRUE; } diff --git a/src/bin/services/e_service_quickpanel.c b/src/bin/services/e_service_quickpanel.c index 05b9dcae75..502d84de5e 100644 --- a/src/bin/services/e_service_quickpanel.c +++ b/src/bin/services/e_service_quickpanel.c @@ -2028,6 +2028,7 @@ EINTERN void e_service_quickpanel_client_add(E_Client *ec, E_Service_Quickpanel_Type type) { E_Policy_Quickpanel *qp = NULL; + E_Layer layer; BACKEND_FUNC_CALL(quickpanel_client_add, ec, type); @@ -2068,7 +2069,12 @@ e_service_quickpanel_client_add(E_Client *ec, E_Service_Quickpanel_Type type) e_comp_screen_rotation_ignore_output_transform_send(qp->ec, EINA_TRUE); // set quickpanel layer - if (E_POLICY_QUICKPANEL_LAYER != evas_object_layer_get(ec->frame)) + if (e_config->use_desk_group) + layer = e_client_desk_group_original_layer_get(ec); + else + layer = e_client_layer_get(ec); + + if (E_POLICY_QUICKPANEL_LAYER != layer) e_client_layer_set(ec, E_POLICY_QUICKPANEL_LAYER); // set skip iconify diff --git a/src/bin/services/e_service_scrsaver.c b/src/bin/services/e_service_scrsaver.c index 2c453fe0ef..bd464dba67 100644 --- a/src/bin/services/e_service_scrsaver.c +++ b/src/bin/services/e_service_scrsaver.c @@ -4,13 +4,20 @@ EINTERN Eina_Bool e_service_scrsaver_client_set(E_Client *ec) { + E_Layer layer; + if (!ec) return EINA_TRUE; if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE; ELOGF("SCRSAVER","Set Client", ec); // set screensaver layer - if (E_POLICY_SCRSAVER_LAYER != ec->layer) + if (e_config->use_desk_group) + layer = e_client_desk_group_original_layer_get(ec); + else + layer = e_client_layer_get(ec); + + if (E_POLICY_SCRSAVER_LAYER != layer) { e_client_layer_set(ec, E_POLICY_SCRSAVER_LAYER); } diff --git a/src/bin/services/e_service_volume.c b/src/bin/services/e_service_volume.c index bf991e8e0f..1dc8c11f9e 100644 --- a/src/bin/services/e_service_volume.c +++ b/src/bin/services/e_service_volume.c @@ -256,6 +256,8 @@ end: EINTERN Eina_Bool e_service_volume_client_set(E_Client *ec) { + E_Layer layer; + if (!ec) { if (_volume_ec) @@ -289,7 +291,12 @@ e_service_volume_client_set(E_Client *ec) e_client_hook_add(E_CLIENT_HOOK_DEL, _volume_hook_client_del, NULL); // set volume layer - if (E_POLICY_VOLUME_LAYER != ec->layer) + if (e_config->use_desk_group) + layer = e_client_desk_group_original_layer_get(ec); + else + layer = e_client_layer_get(ec); + + if (E_POLICY_VOLUME_LAYER != layer) { e_client_layer_set(ec, E_POLICY_VOLUME_LAYER); }