e_client: Checks if it's valid operation for sub-surface. 61/246161/3
authorSeunghun Lee <shiin.lee@samsung.com>
Tue, 20 Oct 2020 09:26:56 +0000 (18:26 +0900)
committerSeunghun Lee <shiin.lee@samsung.com>
Tue, 27 Oct 2020 02:32:58 +0000 (11:32 +0900)
For now wl_surface and wl_subsurface are all mapped to e_client.
e_client_stack_above/below and e_client_raise/lower are for changing
stacking order of e_client as its name says.
In this reason, the functions related to stacking order in e_client
are responsible for checking if it's valid operation for sub-surface
and updating stacking order of sub-surfaces.

Change-Id: I29a3524856ac4cc0151cbaf1221e9bc003e2216a

src/bin/e_client.c
src/bin/e_comp_wl_subsurface.c
src/bin/e_comp_wl_subsurface.h
src/bin/e_policy_stack.c

index e6cd36f..ca3c498 100644 (file)
@@ -8093,6 +8093,10 @@ e_client_raise(E_Client *ec)
 {
    if (!ec) return;
 
+   /* Do not mess up the stacking order of sub-surfaces. */
+   if (e_comp_wl_subsurface_check(ec))
+     return;
+
    if (ec->desk_group.enable)
      {
         E_Desk_Group *edg;
@@ -8112,6 +8116,10 @@ e_client_lower(E_Client *ec)
 {
    if (!ec) return;
 
+   /* Do not mess up the stacking order of sub-surfaces. */
+   if (e_comp_wl_subsurface_check(ec))
+     return;
+
    if (ec->desk_group.enable)
      {
         E_Desk_Group *edg;
@@ -8134,6 +8142,21 @@ e_client_stack_above(E_Client *ec, E_Client *above)
    if (!above) return;
    if (!above->frame) return;
 
+   /* If at least one of the given clients is sub-surface. */
+   if ((e_comp_wl_subsurface_check(ec)) ||
+       (e_comp_wl_subsurface_check(above)))
+     {
+        /* Both should be sibling. */
+        if (!e_comp_wl_subsurface_sibling_check(ec, above))
+          {
+             ELOGF("CLIENT", "Invalid operation: given clients are not sibling."
+                   "\nec(%p, parent: %p) above(%p, parent: %p)",
+                   ec, ec, e_comp_wl_subsurface_parent_get(ec),
+                   above, e_comp_wl_subsurface_parent_get(above));
+             return;
+          }
+     }
+
    if (ec->desk_group.enable)
      {
         E_Desk_Group *edg;
@@ -8146,6 +8169,12 @@ e_client_stack_above(E_Client *ec, E_Client *above)
      }
 
    evas_object_stack_above(ec->frame, above->frame);
+
+   /* Since calling evas_object_stack_above() messes up the stacking order of
+    * sub-surface of above, it should be updated. */
+   if ((above->comp_data->sub.list) &&
+       (eina_list_count(above->comp_data->sub.list) > 0))
+     e_comp_wl_subsurface_stack_update(above);
 }
 
 E_API void
@@ -8156,6 +8185,21 @@ e_client_stack_below(E_Client *ec, E_Client *below)
    if (!below) return;
    if (!below->frame) return;
 
+   /* If at least one of the given clients is sub-surface. */
+   if ((e_comp_wl_subsurface_check(ec)) ||
+       (e_comp_wl_subsurface_check(below)))
+     {
+        /* Both should be sibling. */
+        if (!e_comp_wl_subsurface_sibling_check(ec, below))
+          {
+             ELOGF("CLIENT", "Invalid operation: given clients are not sibling."
+                   "\nec(%p, parent: %p) below(%p, parent: %p)",
+                   ec, ec, e_comp_wl_subsurface_parent_get(ec),
+                   below, e_comp_wl_subsurface_parent_get(below));
+             return;
+          }
+     }
+
    if (ec->desk_group.enable)
      {
         E_Desk_Group *edg;
@@ -8168,6 +8212,12 @@ e_client_stack_below(E_Client *ec, E_Client *below)
      }
 
    evas_object_stack_below(ec->frame, below->frame);
+
+   /* Since calling evas_object_stack_below() messes up the stacking order of
+    * sub-surface of below, it should be updated. */
+   if ((below->comp_data->sub.below_list) &&
+       (eina_list_count(below->comp_data->sub.below_list) > 0))
+     e_comp_wl_subsurface_stack_update(below);
 }
 
 E_API int
index ea7b903..aa9991c 100644 (file)
@@ -49,6 +49,9 @@ _e_comp_wl_subsurface_restack(E_Client *ec)
 
    if (!ec || !ec->comp_data || e_object_is_del(E_OBJECT(ec))) return;
 
+   if (ec->comp_data->sub.restacking)
+       return;
+
    ec->comp_data->sub.restacking = EINA_TRUE;
 
    temp = ec;
@@ -1291,6 +1294,71 @@ e_comp_wl_subsurface_check_below_bg_rectangle(E_Client *ec)
    _e_comp_wl_subsurface_check_below_bg_rectangle(ec);
 }
 
+EINTERN Eina_Bool
+e_comp_wl_subsurface_check(E_Client *ec)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+
+   return (_e_comp_wl_subsurface_data_get(ec) != NULL) ? EINA_TRUE : EINA_FALSE;
+}
+
+EINTERN E_Client *
+e_comp_wl_subsurface_parent_get(E_Client *ec)
+{
+   E_Comp_Wl_Subsurf_Data *sdata;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
+
+   sdata = _e_comp_wl_subsurface_data_get(ec);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(sdata, NULL);
+
+   return sdata->parent;
+}
+
+EINTERN Eina_Bool
+e_comp_wl_subsurface_sibling_check(E_Client *ec1, E_Client *ec2)
+{
+   E_Comp_Wl_Subsurf_Data *sd1, *sd2;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec1, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec2, EINA_FALSE);
+
+   sd1 = _e_comp_wl_subsurface_data_get(ec1);
+   /* ec1 is sub-surface. */
+   if (sd1)
+     {
+        /* ec2 is the parent of ec1. */
+        if (sd1->parent == ec2)
+          return EINA_TRUE;
+
+        sd2 = _e_comp_wl_subsurface_data_get(ec2);
+        if (sd2)
+          {
+             /* ec1 is the parent of ec2. */
+             if (sd2->parent == ec1)
+               return EINA_TRUE;
+
+             /* both have same parent. */
+             if (sd1->parent == sd2->parent)
+               return EINA_TRUE;
+          }
+     }
+   /* ec1 is not sub-surface. */
+   else
+     {
+        sd2 = _e_comp_wl_subsurface_data_get(ec2);
+        /* ec2 is sub-surface. */
+        if (sd2)
+          {
+             /* ec1 is the parent of ec2. */
+             if (sd2->parent == ec1)
+               return EINA_TRUE;
+          }
+     }
+
+   return EINA_FALSE;
+}
+
 static void
 _e_comp_wl_subsurface_cb_dummy_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
 {
index 6f19387..d137c44 100644 (file)
@@ -25,4 +25,27 @@ EINTERN Eina_Bool     e_comp_wl_video_subsurface_has(E_Client *ec);
 EINTERN Eina_Bool     e_comp_wl_normal_subsurface_has(E_Client *ec);
 EINTERN void          e_comp_wl_subsurface_check_below_bg_rectangle(E_Client *ec);
 
+/**
+ * @brief   Checks if given ec is sub-surface.
+ * @in  ec  The E_Client instance to be checked.
+ * @return  EINA_TRUE if it's sub-surface. Otherwise, EINA_FALSE.
+ */
+EINTERN Eina_Bool     e_comp_wl_subsurface_check(E_Client *ec);
+
+/** 
+ * @brief   Gets the parent of a ec.
+ * @in  ec  The E_Client instance.
+ * @return  The E_Client instance of parent.
+ */
+EINTERN E_Client     *e_comp_wl_subsurface_parent_get(E_Client *ec);
+
+/** 
+ * @brief   Checks if given two clients are siblings
+ *          or the one of two is a parent.
+ * @in  ec1 The E_Client instance to be checked.
+ * @in  ec2 The another one E_Client instance to be checked.
+ * @return  EINA_TRUE if these are sibling. Otherwise, EINA_FALSE.
+ */
+EINTERN Eina_Bool     e_comp_wl_subsurface_sibling_check(E_Client *ec1, E_Client *ec2);
+
 #endif
index aaf1637..f9a2f1e 100644 (file)
@@ -469,7 +469,6 @@ e_policy_stack_below(E_Client *ec, E_Client *below_ec)
    EINA_SAFETY_ON_NULL_RETURN(below_ec->frame);
 
    e_client_stack_below(ec, below_ec);
-   e_comp_wl_subsurface_stack_update(below_ec);
    if (e_config->transient.iconify)
      {
         E_Client *child;
@@ -492,7 +491,6 @@ e_policy_stack_above(E_Client *ec, E_Client *above_ec)
    EINA_SAFETY_ON_NULL_RETURN(above_ec->frame);
 
    e_client_stack_above(ec, above_ec);
-   e_comp_wl_subsurface_stack_update(above_ec);
    if (e_config->transient.iconify)
      {
         E_Client *child;