From 0ce9e1e920050692e28c75cd1cfc3cc38cc0be2e Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Mon, 19 Oct 2020 20:15:23 +0900 Subject: [PATCH] subsurface: Handles restack event only for topmost parent of sub-surface. This patch removes a handler of restack event in e_comp_wl, and adds it for topmost parent of sub-surface. Because it's not necessary to handle restack event for sub-surface. The reason is as follow. 1. Sub-surface can be re-stacked only by a request from wl_client. In other words, it shouldn't be re-stacked by compositor policy. 2. A topmost parent of sub-surface can be re-stacked only by compositor policy. For these reason, it's sufficient for sub-surface implementation to add a handler of restack event for topmost parent. Change-Id: I6874425fd864c83039911dcf4ece75e5d2c8a79b --- src/bin/e_comp_wl.c | 14 ---- src/bin/e_comp_wl_subsurface.c | 175 ++++++++++++++++++++++++++++++----------- 2 files changed, 128 insertions(+), 61 deletions(-) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 00847c8..1300ce6 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -697,18 +697,6 @@ _e_comp_wl_touch_cancel(void) _e_comp_wl_send_touch_cancel(ec); } -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 *)data; - - if ((!ec) || (!ec->comp_data)) return; - if (e_object_is_del(E_OBJECT(ec))) return; - if (ec->comp_data->sub.restacking) return; - - e_comp_wl_subsurface_stack_update(ec); -} - static E_Devicemgr_Input_Device * _e_comp_wl_device_last_device_get(Ecore_Device_Class dev_class) { @@ -2069,8 +2057,6 @@ _e_comp_wl_client_evas_init(E_Client *ec) evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_SHOW, _e_comp_wl_evas_cb_show, 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); - evas_object_event_callback_priority_add(ec->frame, EVAS_CALLBACK_MOUSE_IN, EVAS_CALLBACK_PRIORITY_AFTER, _e_comp_wl_evas_cb_mouse_in, ec); evas_object_event_callback_priority_add(ec->frame, EVAS_CALLBACK_MOUSE_OUT, EVAS_CALLBACK_PRIORITY_AFTER, _e_comp_wl_evas_cb_mouse_out, ec); diff --git a/src/bin/e_comp_wl_subsurface.c b/src/bin/e_comp_wl_subsurface.c index 5728416..ea7b903 100644 --- a/src/bin/e_comp_wl_subsurface.c +++ b/src/bin/e_comp_wl_subsurface.c @@ -13,6 +13,10 @@ static void _e_comp_wl_subsurface_parent_commit(E_Client *ec, Eina_Bool pa static Eina_Bool _e_comp_wl_subsurface_synchronized_get(E_Comp_Wl_Subsurf_Data *sdata); static void _e_comp_wl_subsurface_synchronized_commit(E_Client *ec); static void _e_comp_wl_subsurface_remove_from_parent(E_Client *parent, E_Client *subc); +static void _e_comp_wl_subsurface_stack_update(E_Client *ec); +static Eina_Bool _e_comp_wl_subsurface_empty_check(E_Client *ec); + +static void _e_comp_wl_subsurface_cb_evas_restack(void *data, Evas *e, Evas_Object *obj, void *event_info); static void _e_comp_wl_subsurface_restack_bg_rectangle(E_Client *ec) @@ -45,13 +49,13 @@ _e_comp_wl_subsurface_restack(E_Client *ec) if (!ec || !ec->comp_data || e_object_is_del(E_OBJECT(ec))) return; + ec->comp_data->sub.restacking = EINA_TRUE; + temp = ec; EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc) { if (!subc || !subc->comp_data || e_object_is_del(E_OBJECT(subc))) continue; - subc->comp_data->sub.restacking = EINA_TRUE; e_client_stack_above(subc, temp); - subc->comp_data->sub.restacking = EINA_FALSE; temp = subc; } @@ -59,9 +63,7 @@ _e_comp_wl_subsurface_restack(E_Client *ec) EINA_LIST_REVERSE_FOREACH(ec->comp_data->sub.below_list, l, subc) { if (!subc || !subc->comp_data || e_object_is_del(E_OBJECT(subc))) continue; - subc->comp_data->sub.restacking = EINA_TRUE; e_client_stack_below(subc, temp); - subc->comp_data->sub.restacking = EINA_FALSE; temp = subc; } @@ -70,6 +72,8 @@ _e_comp_wl_subsurface_restack(E_Client *ec) EINA_LIST_REVERSE_FOREACH(ec->comp_data->sub.below_list, l, subc) _e_comp_wl_subsurface_restack(subc); + + ec->comp_data->sub.restacking = EINA_FALSE; } static void @@ -855,6 +859,10 @@ _e_comp_wl_subsurface_cb_ec_del(void *data EINA_UNUSED, E_Client *ec) ec->comp_data->sub.below_list = NULL; _e_comp_wl_surface_sub_list_free(ec->comp_data->sub.below_list_pending); ec->comp_data->sub.below_list_pending = NULL; + + evas_object_event_callback_del(ec->frame, + EVAS_CALLBACK_RESTACK, + _e_comp_wl_subsurface_cb_evas_restack); } static void @@ -1032,6 +1040,16 @@ e_comp_wl_subsurface_create(E_Client *ec, E_Client *epc, uint32_t id, struct wl_ { E_Layer layer = e_client_layer_get(epc); if (layer > E_LAYER_BOTTOM) e_client_layer_set(ec, layer); + + if ((!_e_comp_wl_subsurface_data_get(epc)) && + (_e_comp_wl_subsurface_empty_check(epc))) + { + /* Add a callback function for restacking of topmost. */ + evas_object_event_callback_add(epc->frame, + EVAS_CALLBACK_RESTACK, + _e_comp_wl_subsurface_cb_evas_restack, + epc); + } } if (epc->comp_data) @@ -1068,6 +1086,13 @@ e_comp_wl_subsurface_create(E_Client *ec, E_Client *epc, uint32_t id, struct wl_ * It's not for subsurface. */ E_FREE_FUNC(ec->comp_data->sub.below_obj, evas_object_del); + /* Delete a listener for restack of evas. + * There is no need to watch restack of evas for sub-surface because + * stacking for sub-surface is happened only by client, not compositor. */ + evas_object_event_callback_del(ec->frame, + EVAS_CALLBACK_RESTACK, + _e_comp_wl_subsurface_cb_evas_restack); + e_comp_wl_hook_call(E_COMP_WL_HOOK_SUBSURFACE_CREATE, ec); return EINA_TRUE; @@ -1195,59 +1220,28 @@ e_comp_wl_subsurface_restack_bg_rectangle(E_Client *ec) EINTERN void e_comp_wl_subsurface_restack(E_Client *ec) { - EINA_SAFETY_ON_NULL_RETURN(ec); - - _e_comp_wl_subsurface_restack(ec); -} - -E_API void -e_comp_wl_subsurface_stack_update(E_Client *ec) -{ E_Client *topmost; EINA_SAFETY_ON_NULL_RETURN(ec); - if (!ec->comp_data) return; - if (e_object_is_del(E_OBJECT(ec))) return; - if (ec->comp_data->sub.restacking) 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) + topmost = e_comp_wl_topmost_parent_get(ec); + if (topmost != ec) { - if (ec->comp_data->sub.below_obj) - _e_comp_wl_subsurface_restack_bg_rectangle(ec); + ELOGF("SUB-COMP", + "WARN: This API is only for topmost parent, not sub-surface.", + ec); return; } - topmost = e_comp_wl_topmost_parent_get(ec); - - _e_comp_wl_subsurface_restack(topmost); - _e_comp_wl_subsurface_restack_bg_rectangle(topmost); - - //To update client stack list - if ((ec->comp_data->sub.data) && - (ec->comp_data->sub.data->parent)) - { - E_Client *parent; - Evas_Object *o; + _e_comp_wl_subsurface_restack(ec); +} - parent = ec->comp_data->sub.data->parent; +E_API void +e_comp_wl_subsurface_stack_update(E_Client *ec) +{ + EINA_SAFETY_ON_NULL_RETURN(ec); - if ((parent->comp_data->sub.list) && - (eina_list_data_find(parent->comp_data->sub.list, ec))) - { - //stack above done - o = evas_object_below_get(ec->frame); - e_comp_object_layer_update(ec->frame, o, NULL); - } - else if ((parent->comp_data->sub.below_list) && - (eina_list_data_find(parent->comp_data->sub.below_list, ec))) - { - //stack below done - o = evas_object_above_get(ec->frame); - e_comp_object_layer_update(ec->frame, NULL, o); - } - } + _e_comp_wl_subsurface_stack_update(ec); } EINTERN Eina_Bool @@ -1362,6 +1356,18 @@ _e_comp_wl_subsurface_remove_from_parent(E_Client *parent, E_Client *subc) eina_list_remove(parent->comp_data->sub.below_list, subc); parent->comp_data->sub.below_list_pending = eina_list_remove(parent->comp_data->sub.below_list_pending, subc); + + if ((!_e_comp_wl_subsurface_data_get(parent)) && + (_e_comp_wl_subsurface_empty_check(parent))) + { + /* No need to watch restack of evas since this surface doesn't have + * sub-surface anymore. */ + evas_object_event_callback_del(parent->frame, + EVAS_CALLBACK_RESTACK, + _e_comp_wl_subsurface_cb_evas_restack); + } + + } static E_Comp_Wl_Subsurf_Data * @@ -1369,3 +1375,78 @@ _e_comp_wl_subsurface_data_get(E_Client *ec) { return (ec->comp_data) ? (ec->comp_data->sub.data) : NULL; } + +static void +_e_comp_wl_subsurface_stack_update(E_Client *ec) +{ + E_Client *topmost; + + if (!ec->comp_data) return; + if (e_object_is_del(E_OBJECT(ec))) return; + if (ec->comp_data->sub.restacking) 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) + { + if (ec->comp_data->sub.below_obj) + _e_comp_wl_subsurface_restack_bg_rectangle(ec); + return; + } + + topmost = e_comp_wl_topmost_parent_get(ec); + + _e_comp_wl_subsurface_restack(topmost); + _e_comp_wl_subsurface_restack_bg_rectangle(topmost); + + //To update client stack list + if ((ec->comp_data->sub.data) && + (ec->comp_data->sub.data->parent)) + { + E_Client *parent; + Evas_Object *o; + + parent = ec->comp_data->sub.data->parent; + + if ((parent->comp_data->sub.list) && + (eina_list_data_find(parent->comp_data->sub.list, ec))) + { + //stack above done + o = evas_object_below_get(ec->frame); + e_comp_object_layer_update(ec->frame, o, NULL); + } + else if ((parent->comp_data->sub.below_list) && + (eina_list_data_find(parent->comp_data->sub.below_list, ec))) + { + //stack below done + o = evas_object_above_get(ec->frame); + e_comp_object_layer_update(ec->frame, NULL, o); + } + } +} + +static void +_e_comp_wl_subsurface_cb_evas_restack(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + E_Client *topmost; + + /* Given data must be a topmost E_Client of subsurfaces. */ + topmost = data; + if (topmost->comp_data->sub.restacking) + { + ELOGF("SUB-COMP", "A topmost parent is getting restacked", topmost); + return; + } + + _e_comp_wl_subsurface_stack_update(topmost); +} + + +static Eina_Bool +_e_comp_wl_subsurface_empty_check(E_Client *ec) +{ + return (!ec->comp_data) || + ((eina_list_count(ec->comp_data->sub.list) == 0) && + (eina_list_count(ec->comp_data->sub.list_pending) == 0) && + (eina_list_count(ec->comp_data->sub.below_list) == 0) && + (eina_list_count(ec->comp_data->sub.below_list_pending) == 0)); +} -- 2.7.4