e_desk: Make E_Desk has geometry, and clients can be membered to E_Desk's smart object. 68/90468/3
authorSeunghun Lee <shiin.lee@samsung.com>
Thu, 29 Sep 2016 02:47:21 +0000 (11:47 +0900)
committerGwanglim Lee <gl77.lee@samsung.com>
Fri, 30 Sep 2016 10:58:10 +0000 (03:58 -0700)
By this patch, we can change the geometry of E_Desk, and the geometry of clients
can be also changed by the E_Desk, not E_Zone.

Added New APIs :
E_API void e_desk_client_add(E_Desk *desk, E_Client *ec);
E_API void e_desk_client_del(E_Desk *desk, E_Client *ec);
E_API void e_desk_geometry_set(E_Desk *desk, int x, int y, int w, int h);

Usage in console :
$ enlightenment_info -desktop_geometry_set [X] [Y] [W] [H]

Change-Id: Id728a8d9187e6e513e4f69737f7d2e08a5eadaf5

src/bin/e_client.c
src/bin/e_desk.c
src/bin/e_desk.h
src/bin/e_info_client.c
src/bin/e_info_server.c
src/bin/e_policy.c
src/bin/e_policy_visibility.c
src/bin/e_policy_wl.c

index 04d16da..93eec8c 100644 (file)
@@ -914,6 +914,8 @@ _e_client_del(E_Client *ec)
    ec->transform_core.result.enable = EINA_FALSE;
 
    e_client_visibility_calculate();
+
+   e_desk_client_del(ec->desk, ec);
 }
 
 ///////////////////////////////////////////
@@ -1808,15 +1810,15 @@ _e_client_maximize(E_Client *ec, E_Maximize max)
         break;
 
       case E_MAXIMIZE_FULLSCREEN:
-        w = ec->zone->w;
-        h = ec->zone->h;
+        w = ec->desk->geom.w;
+        h = ec->desk->geom.h;
 
         evas_object_smart_callback_call(ec->frame, "fullscreen", NULL);
         e_client_resize_limit(ec, &w, &h);
         /* center x-direction */
-        x1 = ec->zone->x + (ec->zone->w - w) / 2;
+        x1 = ec->desk->geom.x + (ec->desk->geom.w - w) / 2;
         /* center y-direction */
-        yy1 = ec->zone->y + (ec->zone->h - h) / 2;
+        yy1 = ec->desk->geom.y + (ec->desk->geom.h - h) / 2;
 
         switch (max & E_MAXIMIZE_DIRECTION)
           {
@@ -1833,11 +1835,11 @@ _e_client_maximize(E_Client *ec, E_Maximize max)
              break;
 
            case E_MAXIMIZE_LEFT:
-             evas_object_geometry_set(ec->frame, ec->zone->x, ec->zone->y, w / 2, h);
+             evas_object_geometry_set(ec->frame, ec->desk->geom.x, ec->desk->geom.y, w / 2, h);
              break;
 
            case E_MAXIMIZE_RIGHT:
-             evas_object_geometry_set(ec->frame, x1, ec->zone->y, w / 2, h);
+             evas_object_geometry_set(ec->frame, x1, ec->desk->geom.y, w / 2, h);
              break;
           }
         break;
@@ -1845,13 +1847,18 @@ _e_client_maximize(E_Client *ec, E_Maximize max)
       case E_MAXIMIZE_SMART:
       case E_MAXIMIZE_EXPAND:
         if (ec->desk->visible)
-          e_zone_useful_geometry_get(ec->zone, &zx, &zy, &zw, &zh);
+          {
+             zx = ec->desk->geom.x;
+             zy = ec->desk->geom.y;
+             zw = ec->desk->geom.w;
+             zh = ec->desk->geom.h;
+          }
         else
           {
-             x1 = ec->zone->x;
-             yy1 = ec->zone->y;
-             x2 = ec->zone->x + ec->zone->w;
-             y2 = ec->zone->y + ec->zone->h;
+             x1 = ec->desk->geom.x;
+             yy1 = ec->desk->geom.y;
+             x2 = ec->desk->geom.x + ec->desk->geom.w;
+             y2 = ec->desk->geom.y + ec->desk->geom.h;
              e_maximize_client_shelf_fill(ec, &x1, &yy1, &x2, &y2, max);
              zx = x1, zy = yy1;
              zw = x2 - x1;
@@ -1909,10 +1916,10 @@ _e_client_maximize(E_Client *ec, E_Maximize max)
         break;
 
       case E_MAXIMIZE_FILL:
-        x1 = ec->zone->x;
-        yy1 = ec->zone->y;
-        x2 = ec->zone->x + ec->zone->w;
-        y2 = ec->zone->y + ec->zone->h;
+        x1 = ec->desk->geom.x;
+        yy1 = ec->desk->geom.y;
+        x2 = ec->desk->geom.x + ec->desk->geom.w;
+        y2 = ec->desk->geom.y + ec->desk->geom.h;
 
         /* walk through all shelves */
         e_maximize_client_shelf_fill(ec, &x1, &yy1, &x2, &y2, max);
@@ -1945,11 +1952,11 @@ _e_client_maximize(E_Client *ec, E_Maximize max)
              break;
 
            case E_MAXIMIZE_LEFT:
-             evas_object_geometry_set(ec->frame, ec->zone->x, ec->zone->y, w / 2, h);
+             evas_object_geometry_set(ec->frame, ec->desk->geom.x, ec->desk->geom.y, w / 2, h);
              break;
 
            case E_MAXIMIZE_RIGHT:
-             evas_object_geometry_set(ec->frame, x1, ec->zone->y, w / 2, h);
+             evas_object_geometry_set(ec->frame, x1, ec->desk->geom.y, w / 2, h);
              break;
           }
         break;
@@ -3495,7 +3502,10 @@ e_client_desk_set(E_Client *ec, E_Desk *desk)
         desk->fullscreen_clients = eina_list_append(desk->fullscreen_clients, ec);
      }
    old_desk = ec->desk;
+   if (old_desk)
+     e_desk_client_del(old_desk, ec);
    ec->desk = desk;
+   e_desk_client_add(desk, ec);
    e_comp_object_effect_unclip(ec->frame);
    e_comp_object_effect_set(ec->frame, NULL);
    if (desk->visible || ec->sticky)
@@ -4515,13 +4525,13 @@ e_client_maximize(E_Client *ec, E_Maximize max)
    if (!(ec->maximized & E_MAXIMIZE_HORIZONTAL))
      {
         /* Horizontal hasn't been set */
-        ec->saved.x = ec->client.x - ec->zone->x;
+        ec->saved.x = ec->client.x - ec->desk->geom.x;
         ec->saved.w = ec->client.w;
      }
    if (!(ec->maximized & E_MAXIMIZE_VERTICAL))
      {
         /* Vertical hasn't been set */
-        ec->saved.y = ec->client.y - ec->zone->y;
+        ec->saved.y = ec->client.y - ec->desk->geom.y;
         ec->saved.h = ec->client.h;
      }
 
index eab16a8..b431028 100644 (file)
@@ -5,6 +5,24 @@
  * number of desktops.
  */
 
+#define E_DESK_SMART_OBJ_TYPE "E_Desk_Smart_Object"
+
+#define E_DESK_SMART_DATA_GET(obj, ptr)                        \
+   E_Desk_Smart_Data *ptr = evas_object_smart_data_get(obj);
+
+#define E_DESK_SMART_DATA_GET_OR_RETURN(obj, ptr)              \
+   E_DESK_SMART_DATA_GET(obj, ptr);                            \
+   if (!ptr) return
+
+typedef struct _E_Desk_Smart_Data E_Desk_Smart_Data;
+
+struct _E_Desk_Smart_Data
+{
+   Evas_Object_Smart_Clipped_Data base;
+
+   Eina_List   *clients;
+};
+
 static void      _e_desk_free(E_Desk *desk);
 static void      _e_desk_event_desk_show_free(void *data, void *ev);
 static void      _e_desk_event_desk_before_show_free(void *data, void *ev);
@@ -15,6 +33,15 @@ static void      _e_desk_show_begin(E_Desk *desk, int dx, int dy);
 static void      _e_desk_hide_begin(E_Desk *desk, int dx, int dy);
 static void      _e_desk_event_desk_window_profile_change_free(void *data, void *ev);
 
+static void      _e_desk_smart_add(Evas_Object *obj);
+static void      _e_desk_smart_del(Evas_Object *obj);
+static void      _e_desk_smart_client_add(Evas_Object *obj, E_Client *ec);
+static void      _e_desk_smart_client_del(Evas_Object *obj, E_Client *ec);
+
+EVAS_SMART_SUBCLASS_NEW(E_DESK_SMART_OBJ_TYPE, _e_desk,
+                        Evas_Smart_Class, Evas_Smart_Class,
+                        evas_object_smart_clipped_class_get, NULL)
+
 static E_Desk_Flip_Cb _e_desk_flip_cb = NULL;
 static void *_e_desk_flip_data = NULL;
 
@@ -59,6 +86,9 @@ e_desk_new(E_Zone *zone, int x, int y)
    desk = E_OBJECT_ALLOC(E_Desk, E_DESK_TYPE, _e_desk_free);
    if (!desk) return NULL;
 
+   desk->smart_obj = evas_object_smart_add(e_comp->evas, _e_desk_smart_class_new());
+   e_desk_geometry_set(desk, zone->x, zone->y, zone->w, zone->h);
+
    desk->zone = zone;
    desk->x = x;
    desk->y = y;
@@ -237,6 +267,7 @@ e_desk_show(E_Desk *desk)
              dy = desk->y - desk2->y;
           }
         _e_desk_hide_begin(desk2, dx, dy);
+        evas_object_hide(desk2->smart_obj);
      }
 
    desk->zone->desk_x_prev = desk->zone->desk_x_current;
@@ -260,6 +291,7 @@ e_desk_show(E_Desk *desk)
    if (desk->zone->bg_object) was_zone = 1;
 #endif
    _e_desk_show_begin(desk, dx, dy);
+   evas_object_show(desk->smart_obj);
 
 #ifndef ENABLE_QUICK_INIT
    if (was_zone)
@@ -678,9 +710,73 @@ e_desks_count(void)
    return count;
 }
 
+E_API void
+e_desk_client_add(E_Desk *desk, E_Client *ec)
+{
+   E_OBJECT_CHECK(desk);
+   E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
+
+   E_OBJECT_CHECK(ec);
+   E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
+
+   _e_desk_smart_client_add(desk->smart_obj, ec);
+}
+
+E_API void
+e_desk_client_del(E_Desk *desk, E_Client *ec)
+{
+   E_OBJECT_CHECK(desk);
+   E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
+
+   E_OBJECT_CHECK(ec);
+   E_OBJECT_TYPE_CHECK(ec, E_CLIENT_TYPE);
+
+   _e_desk_smart_client_del(desk->smart_obj, ec);
+}
+
+E_API void
+e_desk_geometry_set(E_Desk *desk, int x, int y, int w, int h)
+{
+   E_Client *ec;
+   E_Maximize max;
+   Eina_List *l;
+   int cx, cy, dx, dy;
+
+   E_OBJECT_CHECK(desk);
+   E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
+
+   E_DESK_SMART_DATA_GET_OR_RETURN(desk->smart_obj, sd);
+
+   if ((desk->geom.x == x) && (desk->geom.y == y) &&
+       (desk->geom.w == w) && (desk->geom.h == h))
+     return;
+
+   dx = x - desk->geom.x;
+   dy = y - desk->geom.y;
+   EINA_RECTANGLE_SET(&desk->geom, x, y, w, h);
+
+   EINA_LIST_FOREACH(sd->clients, l, ec)
+     {
+        if (ec->maximized)
+          {
+             max = ec->maximized;
+             ec->maximized = E_MAXIMIZE_NONE;
+             e_client_maximize(ec, max);
+          }
+        else
+          {
+             e_client_geometry_get(ec, &cx, &cy, NULL, NULL);
+             e_client_util_move_without_frame(ec, cx + dx, cy + dy);
+          }
+     }
+
+   evas_object_geometry_set(desk->smart_obj, x, y, w, h);
+}
+
 static void
 _e_desk_free(E_Desk *desk)
 {
+   evas_object_del(desk->smart_obj);
    eina_stringshare_del(desk->name);
    desk->name = NULL;
    free(desk);
@@ -842,3 +938,51 @@ _e_desk_hide_begin(E_Desk *desk, int dx, int dy)
         e_client_comp_hidden_set(ec, EINA_TRUE);
      }
 }
+
+static void
+_e_desk_smart_add(Evas_Object *obj)
+{
+   EVAS_SMART_DATA_ALLOC(obj, E_Desk_Smart_Data);
+
+   _e_desk_parent_sc->add(obj);
+}
+
+static void
+_e_desk_smart_del(Evas_Object *obj)
+{
+   _e_desk_parent_sc->del(obj);
+
+   E_DESK_SMART_DATA_GET_OR_RETURN(obj, sd);
+
+   eina_list_free(sd->clients);
+   free(sd);
+
+   evas_object_smart_data_set(obj, NULL);
+}
+
+static void
+_e_desk_smart_set_user(Evas_Smart_Class *sc)
+{
+   sc->add = _e_desk_smart_add;
+   sc->del = _e_desk_smart_del;
+}
+
+static void
+_e_desk_smart_client_add(Evas_Object *obj, E_Client *ec)
+{
+   E_DESK_SMART_DATA_GET_OR_RETURN(obj, sd);
+
+   sd->clients = eina_list_append(sd->clients, ec);
+   evas_object_smart_member_add(ec->frame, obj);
+   evas_object_smart_changed(obj);
+}
+
+static void
+_e_desk_smart_client_del(Evas_Object *obj, E_Client *ec)
+{
+   E_DESK_SMART_DATA_GET_OR_RETURN(obj, sd);
+
+   sd->clients = eina_list_remove(sd->clients, ec);
+   evas_object_smart_member_del(ec->frame);
+   evas_object_smart_changed(obj);
+}
index 59fa66f..24cda2a 100644 (file)
@@ -36,6 +36,9 @@ struct _E_Desk
    Evas_Object         *layout;      /* Desk's splitlayout*/
 
    Evas_Object         *bg_object;
+   Evas_Object         *smart_obj;
+
+   Eina_Rectangle       geom;
 
    unsigned int animate_count;
 };
@@ -96,6 +99,10 @@ E_API void         e_desk_flip_end(E_Desk *desk);
 
 E_API unsigned int e_desks_count(void);
 
+E_API void         e_desk_geometry_set(E_Desk *desk, int x, int y, int w, int h);
+E_API void         e_desk_client_add(E_Desk *desk, E_Client *ec);
+E_API void         e_desk_client_del(E_Desk *desk, E_Client *ec);
+
 extern E_API int E_EVENT_DESK_SHOW;
 extern E_API int E_EVENT_DESK_BEFORE_SHOW;
 extern E_API int E_EVENT_DESK_AFTER_SHOW;
index 5513189..756892e 100644 (file)
@@ -1512,6 +1512,35 @@ _e_info_client_proc_slot_set(int argc, char **argv)
 }
 
 static void
+_e_info_client_proc_desktop_geometry_set(int argc, char **argv)
+{
+   int x, y, w, h;
+
+   if (argc != 6)
+     {
+        printf("Error Check Args: enlightenment_info -desktop_geometry_set [X] [Y] [W] [H]\n");
+        return;
+     }
+
+   x = atoi(argv[2]);
+   y = atoi(argv[3]);
+   w = atoi(argv[4]);
+   h = atoi(argv[5]);
+
+   if ((w < 0) || (h < 0))
+     {
+        printf("Error Check Args: Width(%d) and Height(%d) must not be less than 1.\n", w, h);
+        return;
+     }
+
+   if (!_e_info_client_eldbus_message_with_args("desktop_geometry_set", NULL, "iiii", x, y, w, h))
+     {
+        printf("_e_info_client_eldbus_message_with_args error");
+        return;
+     }
+}
+
+static void
 _e_info_client_proc_buffer_shot(int argc, char **argv)
 {
    int dumprun = 0;
@@ -1978,6 +2007,12 @@ static struct
       USAGE_SLOT,
       "Set slot in runtime",
       _e_info_client_proc_slot_set
+   },
+   {
+      "desktop_geometry_set",
+      "[X Y W H]",
+      "Set geometry of current desktop",
+      _e_info_client_proc_desktop_geometry_set
    }
 };
 
index a8bc072..ad968ce 100644 (file)
@@ -1713,6 +1713,33 @@ e_info_server_cb_slot_message(const Eldbus_Service_Interface *iface EINA_UNUSED,
    return reply;
 }
 
+static Eldbus_Message *
+_e_info_server_cb_desktop_geometry_set(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
+{
+   Eldbus_Message *reply = eldbus_message_method_return_new(msg);
+   E_Zone *zone;
+   E_Desk *desk;
+   int x, y, w, h;
+
+   if (!eldbus_message_arguments_get(msg, "iiii", &x, &y, &w, &h))
+     {
+        ERR("Error getting arguments.");
+        return reply;
+     }
+
+   if ((w < 0) || (h < 0))
+     {
+        ERR("Error: Invalid parameter w %d h %d", w, h);
+        return reply;
+     }
+
+   zone = e_zone_current_get();
+   desk = e_desk_current_get(zone);
+   e_desk_geometry_set(desk, x, y, w, h);
+
+   return reply;
+}
+
 static Eina_Bool
 _e_info_server_cb_buffer_change(void *data, int type, void *event)
 {
@@ -2070,6 +2097,7 @@ static const Eldbus_Method methods[] = {
    { "aux_msg", ELDBUS_ARGS({"s","window id" }, {"s", "key"}, {"s", "value"}, {"as", "options"}), NULL, e_info_server_cb_aux_message, 0},
    { "scrsaver", ELDBUS_ARGS({SIGNATURE_SCRSAVER_CLIENT, "scrsaver_params"}), ELDBUS_ARGS({SIGNATURE_SCRSAVER_SERVER, "scrsaver_result"}), _e_info_server_cb_scrsaver, 0},
    { "slot_message", ELDBUS_ARGS({"iiiiii", "slot_message"}), ELDBUS_ARGS({"a(ss)", "array of ec"}), e_info_server_cb_slot_message, 0},
+   { "desktop_geometry_set", ELDBUS_ARGS({"iiii", "Geometry"}), NULL, _e_info_server_cb_desktop_geometry_set, 0},
    { NULL, NULL, NULL, NULL, 0 }
 };
 
index b9d92b9..3e5f524 100644 (file)
@@ -253,6 +253,16 @@ _e_policy_client_maximize_policy_apply(E_Policy_Client *pc)
 
    if (!ec->maximized)
      {
+        /* This is added to support e_desk_geometry_set().
+         * The geometry of client is calculated based on E_Desk by
+         * e_client_maximize() from now.
+         * But, if we don't set ec->placed, geometry of new client will be
+         * calculated again based on E_Zone by _e_client_eval().
+         * FIXME: we can delete it if calculation of placement is based on
+         * E_Desk.
+         */
+        ec->placed = 1;
+
         e_client_maximize(ec, E_MAXIMIZE_EXPAND | E_MAXIMIZE_BOTH);
 
         if (ec->changes.need_maximize)
index 35976eb..cef1a39 100644 (file)
@@ -898,7 +898,7 @@ _e_vis_ec_activity_check(E_Client *ec)
    if (_e_vis_ec_special_check(ec)) return EINA_FALSE;
    /* check if full screen */
    e_client_geometry_get(ec, &x, &y, &w, &h);
-   if (!E_CONTAINS(x, y, w, h, ec->zone->x, ec->zone->y, ec->zone->w, ec->zone->h))
+   if (!E_CONTAINS(x, y, w, h, ec->desk->geom.x, ec->desk->geom.y, ec->desk->geom.w, ec->desk->geom.h))
      return EINA_FALSE;
    return EINA_TRUE;
 }
index c6c042a..876462d 100644 (file)
@@ -1124,8 +1124,8 @@ _tzpos_iface_cb_set(struct wl_client *client EINA_UNUSED, struct wl_resource *re
 
    if (!ec->lock_client_location)
      {
-        ec->x = ec->client.x = x;
-        ec->y = ec->client.y = y;
+        ec->x = ec->client.x = ec->desk->geom.x + x;
+        ec->y = ec->client.y = ec->desk->geom.y + y;
         ec->placed = 1;
      }
 }