add place_belw_parent request to tizen_surface_extension 63/39463/2
authorBoram Park <boram1288.park@samsung.com>
Fri, 15 May 2015 10:51:26 +0000 (19:51 +0900)
committerBoram Park <boram1288.park@samsung.com>
Fri, 15 May 2015 10:52:28 +0000 (19:52 +0900)
Change-Id: I2a599d07f34bfa6b03369bd7744c7c78ee9db34a

src/bin/e_comp_wl.c
src/bin/e_comp_wl.h
src/modules/wl_desktop_shell/e_mod_main.c
src/modules/wl_desktop_shell/tizen_extension.xml
src/modules/wl_desktop_shell/tizen_extension_protocol.c
src/modules/wl_desktop_shell/tizen_extension_server_protocol.h

index c13fa931d054a83495de0a9da169c072d58cda53..51d1075391e08fd7b696326d532962f1b4e8fba9 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 static void _e_comp_wl_subsurface_parent_commit(E_Client *ec, Eina_Bool parent_synchronized);
+static void _e_comp_wl_subsurface_restack(E_Client *ec);
 
 /* local variables */
 /* static Eina_Hash *clients_win_hash = NULL; */
@@ -310,6 +311,48 @@ _e_comp_wl_evas_cb_hide(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EIN
      evas_object_hide(tmp->frame);
 }
 
+static void
+_e_comp_wl_evas_cb_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   E_Client *ec;
+   E_Client *subc;
+   Eina_List *l;
+   int x, y;
+
+   if (!(ec = data)) return;
+
+   EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc)
+     {
+        x = ec->x + subc->comp_data->sub.data->position.x;
+        y = ec->y + subc->comp_data->sub.data->position.y;
+        evas_object_move(subc->frame, x, y);
+     }
+}
+
+static void
+_e_comp_wl_evas_cb_restack(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   E_Client *ec;
+   E_Client *parent = NULL;
+
+   if (!(ec = data)) return;
+
+   /* return if ec isn't both a parent of a subsurface and a subsurface itself */
+   if (!ec->comp_data->sub.list && !ec->comp_data->sub.below_list && !ec->comp_data->sub.data) return;
+
+   if (ec->comp_data->sub.data)
+     parent = ec->comp_data->sub.data->parent;
+   else
+     parent = ec;
+
+   /* return if parent is in restacking progress */
+   if (parent->comp_data->sub.restacking) return;
+
+   EINA_SAFETY_ON_NULL_RETURN(parent);
+
+   _e_comp_wl_subsurface_restack(parent);
+}
+
 static void
 _e_comp_wl_evas_cb_mouse_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
 {
@@ -838,6 +881,12 @@ _e_comp_wl_client_evas_init(E_Client *ec)
    evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_HIDE,
                                   _e_comp_wl_evas_cb_hide, ec);
 
+   evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOVE,
+                                  _e_comp_wl_evas_cb_move, ec);
+   evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_RESTACK,
+                                  _e_comp_wl_evas_cb_restack, ec);
+
+
    /* setup input callbacks */
    evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOUSE_IN,
                                   _e_comp_wl_evas_cb_mouse_in, ec);
@@ -1071,21 +1120,32 @@ _e_comp_wl_cb_input_event(void *data EINA_UNUSED, int type, void *ev)
    return ECORE_CALLBACK_RENEW;
 }
 
-static E_Client*
+static void
 _e_comp_wl_subsurface_restack(E_Client *ec)
 {
-   E_Client *subc, *below = ec;
+   E_Client *subc, *temp;
    Eina_List *l;
 
-   if (!ec->comp_data->sub.list) return ec;
+   ec->comp_data->sub.restacking = EINA_TRUE;
 
+   temp = ec;
    EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc)
      {
-        evas_object_stack_above(subc->frame, below->frame);
-        below = subc;
+        evas_object_stack_above(subc->frame, temp->frame);
+        temp = subc;
+     }
+
+   temp = ec;
+   EINA_LIST_REVERSE_FOREACH(ec->comp_data->sub.below_list, l, subc)
+     {
+        evas_object_stack_below(subc->frame, temp->frame);
+        temp = subc;
      }
 
-   return below;
+   if (ec->comp_data->sub.below_obj)
+     evas_object_stack_below(ec->comp_data->sub.below_obj, temp->frame);
+
+   ec->comp_data->sub.restacking = EINA_FALSE;
 }
 
 static void
@@ -1097,6 +1157,7 @@ _e_comp_wl_surface_subsurface_order_commit(E_Client *ec)
    if (!ec->comp_data->sub.list_changed) return;
    ec->comp_data->sub.list_changed = EINA_FALSE;
 
+   /* TODO: need to check more complicated subsurface tree */
    EINA_LIST_FOREACH(ec->comp_data->sub.list_pending, l, subc)
      {
         ec->comp_data->sub.list = eina_list_remove(ec->comp_data->sub.list, subc);
@@ -1105,6 +1166,14 @@ _e_comp_wl_surface_subsurface_order_commit(E_Client *ec)
         _e_comp_wl_surface_subsurface_order_commit(subc);
      }
 
+   EINA_LIST_FOREACH(ec->comp_data->sub.below_list_pending, l, subc)
+     {
+        ec->comp_data->sub.below_list = eina_list_remove(ec->comp_data->sub.below_list, subc);
+        ec->comp_data->sub.below_list = eina_list_append(ec->comp_data->sub.below_list, subc);
+
+        _e_comp_wl_surface_subsurface_order_commit(subc);
+     }
+
    _e_comp_wl_subsurface_restack(ec);
 }
 
@@ -1256,9 +1325,12 @@ _e_comp_wl_surface_state_commit(E_Client *ec, E_Comp_Wl_Surface_State *state)
              else
                {
                   evas_object_hide(ec->frame);
-                  ec->comp_data->mapped = EINA_TRUE;
+                  ec->comp_data->mapped = EINA_FALSE;
                }
           }
+
+        if (ec->comp_data->sub.below_obj && evas_object_visible_get(ec->comp_data->sub.below_obj))
+          evas_object_hide(ec->comp_data->sub.below_obj);
      }
    else
      {
@@ -1272,6 +1344,9 @@ _e_comp_wl_surface_state_commit(E_Client *ec, E_Comp_Wl_Surface_State *state)
                   ec->comp_data->mapped = EINA_TRUE;
                }
           }
+
+        if (ec->comp_data->sub.below_obj && !evas_object_visible_get(ec->comp_data->sub.below_obj))
+          evas_object_show(ec->comp_data->sub.below_obj);
      }
 
    if (state->new_attach || state->buffer_viewport.changed)
@@ -1572,6 +1647,12 @@ _e_comp_wl_surface_cb_commit(struct wl_client *client EINA_UNUSED, struct wl_res
         if (ec != subc)
           _e_comp_wl_subsurface_parent_commit(subc, EINA_FALSE);
      }
+
+   EINA_LIST_FOREACH(ec->comp_data->sub.below_list, l, subc)
+     {
+        if (ec != subc)
+          _e_comp_wl_subsurface_parent_commit(subc, EINA_FALSE);
+     }
 }
 
 static void
@@ -1877,6 +1958,10 @@ _e_comp_wl_subsurface_destroy(struct wl_resource *resource)
           eina_list_remove(sdata->parent->comp_data->sub.list, ec);
         sdata->parent->comp_data->sub.list_pending =
           eina_list_remove(sdata->parent->comp_data->sub.list_pending, ec);
+        sdata->parent->comp_data->sub.below_list =
+          eina_list_remove(sdata->parent->comp_data->sub.below_list, ec);
+        sdata->parent->comp_data->sub.below_list_pending =
+          eina_list_remove(sdata->parent->comp_data->sub.below_list_pending, ec);
      }
 
    _e_comp_wl_surface_state_finish(&sdata->cached);
@@ -1904,6 +1989,22 @@ _e_comp_wl_subsurface_synchronized_get(E_Comp_Wl_Subsurf_Data *sdata)
    return EINA_FALSE;
 }
 
+static void
+_e_comp_wl_subsurface_create_below_bg_rectangle(E_Client *ec)
+{
+   short layer = evas_object_layer_get(ec->frame);
+
+   ec->comp_data->sub.below_obj = evas_object_rectangle_add(ec->comp->evas);
+   EINA_SAFETY_ON_NULL_RETURN(ec->comp_data->sub.below_obj);
+
+   evas_object_layer_set(ec->comp_data->sub.below_obj, layer);
+   evas_object_render_op_set(ec->comp_data->sub.below_obj, EVAS_RENDER_COPY);
+   evas_object_color_set(ec->comp_data->sub.below_obj, 0x00, 0x00, 0x00, 0xff);
+   evas_object_move(ec->comp_data->sub.below_obj, ec->x, ec->y);
+   evas_object_resize(ec->comp_data->sub.below_obj, ec->w, ec->h);
+   evas_object_name_set(ec->comp_data->sub.below_obj, "below_bg_rectangle");
+}
+
 static void
 _e_comp_wl_subsurface_commit_to_cache(E_Client *ec)
 {
@@ -2019,6 +2120,11 @@ _e_comp_wl_subsurface_parent_commit(E_Client *ec, Eina_Bool parent_synchronized)
              if (ec != subc)
                _e_comp_wl_subsurface_parent_commit(subc, EINA_TRUE);
           }
+        EINA_LIST_FOREACH(ec->comp_data->sub.below_list, l, subc)
+          {
+             if (ec != subc)
+               _e_comp_wl_subsurface_parent_commit(subc, EINA_TRUE);
+          }
      }
 }
 
@@ -2214,6 +2320,19 @@ _e_comp_wl_subsurface_create(E_Client *ec, E_Client *epc, uint32_t id, struct wl
    ec->comp_data->surface = surface_resource;
    ec->comp_data->sub.data = sdata;
 
+   ec->lock_user_location = 0;
+   ec->lock_client_location = 0;
+   ec->lock_user_size = 0;
+   ec->lock_client_size = 0;
+   ec->lock_client_stacking = 0;
+   ec->lock_user_shade = 0;
+   ec->lock_client_shade = 0;
+   ec->lock_user_maximize = 0;
+   ec->lock_client_maximize = 0;
+   ec->changes.need_maximize = 0;
+   ec->maximized = E_MAXIMIZE_NONE;
+   EC_CHANGED(ec);
+
    return EINA_TRUE;
 
 res_err:
@@ -2393,6 +2512,10 @@ _e_comp_wl_client_cb_del(void *data EINA_UNUSED, E_Client *ec)
      subc->comp_data->sub.data->parent = NULL;
    EINA_LIST_FREE(ec->comp_data->sub.list_pending, subc)
      subc->comp_data->sub.data->parent = NULL;
+   EINA_LIST_FREE(ec->comp_data->sub.below_list, subc)
+     subc->comp_data->sub.data->parent = NULL;
+   EINA_LIST_FREE(ec->comp_data->sub.below_list_pending, subc)
+     subc->comp_data->sub.data->parent = NULL;
 
    if ((ec->parent) && (ec->parent->modal == ec))
      {
@@ -3066,6 +3189,12 @@ e_comp_wl_surface_commit(E_Client *ec)
 {
    _e_comp_wl_surface_state_commit(ec, &ec->comp_data->pending);
 
+   if (ec->comp_data->sub.below_list || ec->comp_data->sub.below_list_pending)
+     {
+        if (!ec->comp_data->sub.below_obj)
+          _e_comp_wl_subsurface_create_below_bg_rectangle(ec);
+     }
+
    _e_comp_wl_surface_subsurface_order_commit(ec);
 
    /* schedule repaint */
@@ -3084,9 +3213,12 @@ e_comp_wl_surface_commit(E_Client *ec)
              else
                {
                   evas_object_hide(ec->frame);
-                  ec->comp_data->mapped = EINA_TRUE;
+                  ec->comp_data->mapped = EINA_FALSE;
                }
           }
+
+        if (ec->comp_data->sub.below_obj && evas_object_visible_get(ec->comp_data->sub.below_obj))
+          evas_object_hide(ec->comp_data->sub.below_obj);
      }
    else
      {
@@ -3100,6 +3232,9 @@ e_comp_wl_surface_commit(E_Client *ec)
                   ec->comp_data->mapped = EINA_TRUE;
                }
           }
+
+        if (ec->comp_data->sub.below_obj && !evas_object_visible_get(ec->comp_data->sub.below_obj))
+          evas_object_show(ec->comp_data->sub.below_obj);
      }
 
    return EINA_TRUE;
@@ -3133,6 +3268,11 @@ e_comp_wl_subsurface_commit(E_Client *ec)
              if (ec != subc)
                _e_comp_wl_subsurface_parent_commit(subc, EINA_FALSE);
           }
+        EINA_LIST_FOREACH(ec->comp_data->sub.below_list, l, subc)
+          {
+             if (ec != subc)
+               _e_comp_wl_subsurface_parent_commit(subc, EINA_FALSE);
+          }
      }
 
    return EINA_TRUE;
index 81462d2b1bd8a6080abadd54a2c27ada8d220e12..3695c93d0ec3bc851ac120ce0ab9f91ef99e48e6 100644 (file)
@@ -260,10 +260,16 @@ struct _E_Comp_Wl_Client_Data
    struct
      {
         E_Comp_Wl_Subsurf_Data *data;
-        E_Client *restack_target;
+
         Eina_List *list;
         Eina_List *list_pending;
         Eina_Bool list_changed : 1;
+
+        Eina_List *below_list;
+        Eina_List *below_list_pending;
+        Evas_Object *below_obj;
+
+        Eina_Bool restacking : 1;
      } sub;
 
    /* regular surface resource (wl_compositor_create_surface) */
index 30f513d55b09e738840c212608c17eca54a4b7fe..6a241136c59f97ae8d13fda7d9ed4ea9a84d1d0d 100644 (file)
@@ -1420,10 +1420,46 @@ _e_tz_surf_ext_cb_transient_for_set(struct wl_client *client, struct wl_resource
    _e_shell_surface_parent_set(ec, parent_res);
 }
 
+static void
+_e_tz_surf_ext_cb_place_below_parent(struct wl_client *client, struct wl_resource *resource, struct wl_resource *subsurface)
+{
+   E_Client *ec;
+   E_Client *epc;
+   E_Comp_Wl_Subsurf_Data *sdata;
+
+   /* try to get the client from resource data */
+   if (!(ec = wl_resource_get_user_data(subsurface)))
+     {
+        wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "Invalid subsurface");
+        return;
+     }
+
+   sdata = ec->comp_data->sub.data;
+   if (!sdata)
+     {
+        wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "Not subsurface");
+        return;
+     }
+
+   epc = sdata->parent;
+   EINA_SAFETY_ON_NULL_RETURN(epc);
+
+   /* check if a subsurface has already placed below a parent */
+   if (eina_list_data_find(epc->comp_data->sub.below_list, ec)) return;
+
+   epc->comp_data->sub.list = eina_list_remove(epc->comp_data->sub.list, ec);
+   epc->comp_data->sub.list_pending = eina_list_remove(epc->comp_data->sub.list_pending, ec);
+   epc->comp_data->sub.below_list_pending = eina_list_append(epc->comp_data->sub.below_list_pending, ec);
+   epc->comp_data->sub.list_changed = EINA_TRUE;
+}
+
 static const struct tizen_surface_extension_interface  _e_tz_surf_ext_interface =
 {
    _e_tz_surf_ext_cb_tz_res_get,
-   _e_tz_surf_ext_cb_transient_for_set
+   _e_tz_surf_ext_cb_transient_for_set,
+   _e_tz_surf_ext_cb_place_below_parent,
 };
 
 static const struct wl_shell_interface _e_shell_interface =
index 81e70b087e14e4de2035bcdc56214f1d9c644601..cf3da89a4e60eca9785f5f8971fe7541d55ca634 100644 (file)
@@ -14,5 +14,8 @@
          <arg name="child_id" type="uint" /> 
          <arg name="parent_id" type="uint" /> 
       </request>
+      <request name="place_below_parent">
+         <arg name="subsurface" type="object" interface="wl_subsurface"/>
+      </request>
    </interface>
 </protocol>
index 23af7ac36400ad48dbb0ad02d0358ef9f985a032..30851a3270a602d7f7c43f9de14469c870a14daf 100644 (file)
@@ -3,6 +3,7 @@
 #include "wayland-util.h"
 
 extern const struct wl_interface tizen_resource_interface;
+extern const struct wl_interface wl_subsurface_interface;
 extern const struct wl_interface wl_surface_interface;
 
 static const struct wl_interface *types[] = {
@@ -10,6 +11,7 @@ static const struct wl_interface *types[] = {
        NULL,
        &tizen_resource_interface,
        &wl_surface_interface,
+       &wl_subsurface_interface,
 };
 
 static const struct wl_message tizen_resource_requests[] = {
@@ -29,11 +31,12 @@ WL_EXPORT const struct wl_interface tizen_resource_interface = {
 static const struct wl_message tizen_surface_extension_requests[] = {
        { "get_tizen_resource", "no", types + 2 },
        { "set_transient_for", "uu", types + 0 },
+       { "place_below_parent", "o", types + 4 },
 };
 
 WL_EXPORT const struct wl_interface tizen_surface_extension_interface = {
        "tizen_surface_extension", 1,
-       2, tizen_surface_extension_requests,
+       3, tizen_surface_extension_requests,
        0, NULL,
 };
 
index a3ad9fb8fea45cc71231404a5e7fa1bf3a9f01d8..d1ce426159f6e609aa0900acf290f47fc3c6fe48 100644 (file)
@@ -55,6 +55,13 @@ struct tizen_surface_extension_interface {
                                  struct wl_resource *resource,
                                  uint32_t child_id,
                                  uint32_t parent_id);
+       /**
+        * place_below_parent - (none)
+        * @subsurface: (none)
+        */
+       void (*place_below_parent)(struct wl_client *client,
+                                  struct wl_resource *resource,
+                                  struct wl_resource *subsurface);
 };