e_desk_group: modify desk_group feature 12/231312/3
authorDoyoun Kang <doyoun.kang@samsung.com>
Tue, 21 Apr 2020 05:40:22 +0000 (14:40 +0900)
committerDoyoun Kang <doyoun.kang@samsung.com>
Tue, 21 Apr 2020 07:39:49 +0000 (16:39 +0900)
Change-Id: I18a6b6ca95423d826d0227c1b0e44d993c852e0f

13 files changed:
src/bin/e_client.c
src/bin/e_client.h
src/bin/e_desk.c
src/bin/e_desk.h
src/bin/e_desk_group.c
src/bin/e_desk_group.h
src/bin/e_includes.h
src/bin/e_policy_stack.c
src/bin/e_policy_wl.c
src/bin/services/e_service_lockscreen.c
src/bin/services/e_service_quickpanel.c
src/bin/services/e_service_scrsaver.c
src/bin/services/e_service_volume.c

index e3f279e..f219163 100644 (file)
@@ -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);
 }
 
index 94221a0..a6c2027 100644 (file)
@@ -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);
index f1f1827..fa91dee 100644 (file)
@@ -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; i<E_DESK_GROUP_LAYER_COUNT; i++)
      {
-        if (edg->id == 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; i<E_DESK_GROUP_LAYER_COUNT; i++)
      {
-        e_desk_group_enable_set(edg, EINA_TRUE);
+        EINA_LIST_REVERSE_FOREACH(desk->desk_group.list[i], l, edg)
+          {
+             e_desk_group_enable_set(edg, EINA_TRUE);
+          }
      }
 
    return EINA_TRUE;
@@ -1720,15 +1769,109 @@ 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; i<E_DESK_GROUP_LAYER_COUNT; i++)
      {
-        e_desk_group_enable_set(edg, EINA_FALSE);
+        EINA_LIST_REVERSE_FOREACH(desk->desk_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)
 {
    E_Desk_Group *edg = NULL;
@@ -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);
+          }
      }
 }
index 8dba59f..a6e7138 100644 (file)
@@ -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);
 
 
index 4dbc1b9..5377505 100644 (file)
@@ -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; i<E_DESK_GROUP_LAYER_COUNT; i++)
+   for (int i=0; i<E_DESK_GROUP_CLIENT_LAYER_MAX; i++)
      {
         eina_list_free(edg->ec_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; i<E_DESK_GROUP_LAYER_COUNT; i++)
+   if (!edg) return;
+
+   for (i=0; i<E_DESK_GROUP_CLIENT_LAYER_MAX; i++)
      {
-        EINA_LIST_FOREACH(edg->ec_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; i<E_DESK_GROUP_LAYER_COUNT; i++)
+   for (i=0; i<E_DESK_GROUP_CLIENT_LAYER_MAX; i++)
      {
-        EINA_LIST_FOREACH(edg->ec_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; i<E_DESK_GROUP_LAYER_COUNT; i++)
+   for (i=0; i<E_DESK_GROUP_CLIENT_LAYER_MAX; i++)
      {
-        EINA_LIST_FOREACH(edg->ec_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; i<E_DESK_GROUP_CLIENT_LAYER_MAX; i++)
+          {
+             EINA_LIST_REVERSE_FOREACH(prev_edg->ec_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; i<E_DESK_GROUP_CLIENT_LAYER_MAX; i++)
+          {
+             EINA_LIST_REVERSE_FOREACH(above_edg->ec_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; i<E_DESK_GROUP_CLIENT_LAYER_MAX; i++)
+     {
+        EINA_LIST_REVERSE_FOREACH(edg->ec_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; i<E_DESK_GROUP_LAYER_COUNT; i++)
+   for (i=0; i<E_DESK_GROUP_CLIENT_LAYER_MAX; i++)
      {
-        EINA_LIST_FOREACH(edg->ec_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);
index 1abfd54..d89a4af 100644 (file)
@@ -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
index e969039..24420fd 100644 (file)
@@ -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"
index b43e4b1..d1e6ab3 100644 (file)
@@ -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;
      }
 }
index 9b1cbc3..b95b1b8 100644 (file)
@@ -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);
 }
 
index 91bf359..f97d46d 100644 (file)
@@ -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;
 }
 
index 05b9dca..502d84d 100644 (file)
@@ -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
index 2c453fe..bd464db 100644 (file)
@@ -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);
      }
index bf991e8..1dc8c11 100644 (file)
@@ -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);
      }