From: Seunghun Lee Date: Tue, 20 Oct 2020 09:26:56 +0000 (+0900) Subject: e_client: Checks if it's valid operation for sub-surface. X-Git-Tag: submit/tizen/20201028.025427~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1cf2f111f9ff9a1043cde8c0f201ee53d74ef0a4;p=platform%2Fupstream%2Fenlightenment.git e_client: Checks if it's valid operation for sub-surface. 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 --- diff --git a/src/bin/e_client.c b/src/bin/e_client.c index e6cd36f97f..ca3c4987b8 100644 --- a/src/bin/e_client.c +++ b/src/bin/e_client.c @@ -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 diff --git a/src/bin/e_comp_wl_subsurface.c b/src/bin/e_comp_wl_subsurface.c index ea7b903e17..aa9991cc4e 100644 --- a/src/bin/e_comp_wl_subsurface.c +++ b/src/bin/e_comp_wl_subsurface.c @@ -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) { diff --git a/src/bin/e_comp_wl_subsurface.h b/src/bin/e_comp_wl_subsurface.h index 6f19387935..d137c44408 100644 --- a/src/bin/e_comp_wl_subsurface.h +++ b/src/bin/e_comp_wl_subsurface.h @@ -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 diff --git a/src/bin/e_policy_stack.c b/src/bin/e_policy_stack.c index aaf16370df..f9a2f1e588 100644 --- a/src/bin/e_policy_stack.c +++ b/src/bin/e_policy_stack.c @@ -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;