From 56b47e62439ec48d93d82bba25b807d2ec26cb38 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Thu, 20 May 2021 13:00:53 +0900 Subject: [PATCH] e_foreign_shell: No longer use embedded client concept There were some tricky side effects because of the concept of embedded client which used smart object mechanism for re-stack operation. So, this patch removes using the concept, instead it gives the e_foreign_shell responsibility for re-stacking on its own. This also reverts following patchs which are no longer used: commit 8b545ca9e79ef2c06fc383cf9cbc788d4561e1e7. Revert "e_comp_object: Set an embedded E_Client as comp_object ..." commit fd9f1eb3cc89980295d923894ea5e016a1a360c1. Revert "e_client: Introduce a way of embdding a client to ..." Change-Id: I912e038da129665b5ba6a62fe7c94aa8dce89176 --- src/bin/e_client.c | 54 +------------ src/bin/e_client.h | 4 - src/bin/e_comp_object.c | 108 +++---------------------- src/bin/e_comp_object.h | 3 - src/bin/e_comp_wl.c | 199 ++++++++++++++++++++++------------------------ src/bin/e_foreign_shell.c | 97 +++++++++++++--------- 6 files changed, 168 insertions(+), 297 deletions(-) diff --git a/src/bin/e_client.c b/src/bin/e_client.c index 68f9f32..a26ee09 100644 --- a/src/bin/e_client.c +++ b/src/bin/e_client.c @@ -1,7 +1,5 @@ #include "e.h" -const char *EMBEDDED_CLIENT_DATA_KEY = "Embedded Client"; - static int _e_client_hooks_delete = 0; static int _e_client_hooks_walking = 0; @@ -1237,8 +1235,6 @@ _e_client_free(E_Client *ec) e_object_unref(E_OBJECT(ec->e.state.profile.wait_desk)); } ec->e.state.profile.wait_desk = NULL; - - evas_object_data_del(ec->frame, EMBEDDED_CLIENT_DATA_KEY); E_FREE_FUNC(ec->frame, evas_object_del); if (ec == focused) @@ -8391,52 +8387,4 @@ e_client_cdata_get(E_Client *ec) if (!ec) return NULL; return ec->comp_data; -} - -EINTERN Eina_Bool -e_client_embedded_client_set(E_Client *ec, E_Client *embedded_ec) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(ec->frame, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(embedded_ec, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(embedded_ec->frame, EINA_FALSE); - - eina_stringshare_replace(&ec->netwm.name, "Container Client"); - eina_stringshare_replace(&embedded_ec->netwm.name, "Embedded Client"); - - evas_object_data_set(ec->frame, EMBEDDED_CLIENT_DATA_KEY, embedded_ec); - e_comp_object_embedded_comp_object_set(ec->frame, embedded_ec->frame); - - return EINA_TRUE; -} - -EINTERN void -e_client_embedded_client_unset(E_Client *ec) -{ - E_Client *embedded_ec; - - EINA_SAFETY_ON_NULL_RETURN(ec); - EINA_SAFETY_ON_NULL_RETURN(ec->frame); - - embedded_ec = evas_object_data_get(ec->frame, EMBEDDED_CLIENT_DATA_KEY); - if (!embedded_ec) - { - ELOGF("E_CLIENT", "Cannot find data for embedded client", ec); - return; - } - - eina_stringshare_replace(&ec->netwm.name, NULL); - eina_stringshare_replace(&embedded_ec->netwm.name, NULL); - - e_comp_object_embedded_comp_object_unset(ec->frame); - evas_object_data_del(ec->frame, EMBEDDED_CLIENT_DATA_KEY); -} - -EINTERN Eina_Bool -e_client_embedded_client_check(E_Client *ec) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(ec->frame, EINA_FALSE); - - return !!evas_object_data_get(ec->frame, EMBEDDED_CLIENT_DATA_KEY); -} +} \ No newline at end of file diff --git a/src/bin/e_client.h b/src/bin/e_client.h index 1e07aef..9615fb4 100644 --- a/src/bin/e_client.h +++ b/src/bin/e_client.h @@ -1269,10 +1269,6 @@ EINTERN E_Comp_Wl_Client_Data *e_client_cdata_new(E_Client *ec); EINTERN void e_client_cdata_free(E_Client *ec); EINTERN E_Comp_Wl_Client_Data *e_client_cdata_get(E_Client *ec); -EINTERN Eina_Bool e_client_embedded_client_set(E_Client *ec, E_Client *in_ec); -EINTERN void e_client_embedded_client_unset(E_Client *ec); -EINTERN Eina_Bool e_client_embedded_client_check(E_Client *ec); - /** * Move window to coordinates that do not account client decorations yet. * diff --git a/src/bin/e_comp_object.c b/src/bin/e_comp_object.c index 1e5e73c..4ea2712 100644 --- a/src/bin/e_comp_object.c +++ b/src/bin/e_comp_object.c @@ -137,7 +137,6 @@ typedef struct _E_Comp_Object Eina_Bool external_content : 1; // e.swallow.content(obj) is set by external evas object Eina_Bool user_alpha_set : 1; Eina_Bool user_alpha : 1; - Eina_Bool embedded : 1; struct { @@ -622,9 +621,8 @@ _e_comp_object_alpha_set(E_Comp_Object *cw) { Eina_Bool alpha = cw->ec->argb; - if (((cw->external_content) && - (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE)) || - (cw->embedded)) + if ((cw->external_content) && + (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE)) { return; } @@ -1691,9 +1689,8 @@ _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h) (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)))) return; - if ((cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE || - cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) || - (cw->embedded)) + if (cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE || + cw->content_type == E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE) pw = w, ph = h; prev_w = cw->w, prev_h = cw->h; e_comp_object_frame_wh_adjust(obj, 0, 0, &fw, &fh); @@ -2278,14 +2275,6 @@ _e_comp_intercept_hide(void *data, Evas_Object *obj) evas_object_hide(obj); return; } - - if (cw->embedded) - { - ELOGF("COMP", "Hide container evas_object:%p", cw->ec, obj); - evas_object_hide(obj); - return; - } - /* already hidden or currently animating */ if ((!cw->visible) || (cw->animating && cw->hiding && (!cw->ec->iconic))) { @@ -2386,7 +2375,7 @@ _e_comp_intercept_show_helper(E_Comp_Object *cw) return; } - if ((!cw->updates) && (!ec->input_only) && (!ec->ignored) && (!cw->embedded)) + if ((!cw->updates) && (!ec->input_only) && (!ec->ignored)) { int pw, ph; @@ -2422,7 +2411,7 @@ _e_comp_intercept_show_helper(E_Comp_Object *cw) ELOGF("COMP", "show_helper. return. new_client", ec); return; } - if ((ec->input_only) || (cw->embedded)) + if (ec->input_only) { /* who cares */ cw->real_hid = 0; @@ -3222,13 +3211,6 @@ _e_comp_smart_show(Evas_Object *obj) e_comp_object_map_update(obj); - if (cw->embedded) - { - evas_object_show(cw->effect_obj); - TRACE_DS_END(); - return; - } - EINA_LIST_FOREACH(cw->ec->e.state.video_child, l, tmp) evas_object_show(tmp->frame); @@ -3366,9 +3348,6 @@ _e_comp_smart_move(Evas_Object *obj, int x, int y) if (cw->input_obj) evas_object_move(cw->input_obj, x, y); e_comp_object_map_update(obj); - - if (cw->embedded) - evas_object_move(cw->obj, x, y); } static void @@ -5464,9 +5443,8 @@ e_comp_object_alpha_set(Evas_Object *obj, Eina_Bool alpha) { API_ENTRY; - if (((cw->external_content) && - (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE)) || - (cw->embedded)) + if ((cw->external_content) && + (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE)) { WRN("Can set up alpha value to ONLY evas \"image\" object. " "But current external content is %d object for %p.", @@ -5554,9 +5532,8 @@ e_comp_object_size_update(Evas_Object *obj, int w, int h) int tw, th; API_ENTRY; - if (((cw->external_content) && - (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE)) || - (cw->embedded)) + if ((cw->external_content) && + (cw->content_type != E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE)) { WRN("Can set up size to ONLY evas \"image\" object. " "But current external content is %d object for %p.", @@ -6402,68 +6379,3 @@ e_comp_object_color_visible_get(Evas_Object *obj) return EINA_TRUE; } - -static void -_e_comp_object_cb_embedded_comp_object_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) -{ - E_Comp_Object *cw; - - cw = data; - - evas_object_smart_member_del(cw->obj); - evas_object_event_callback_del(cw->obj, EVAS_CALLBACK_DEL, _e_comp_object_cb_embedded_comp_object_del); - cw->obj = NULL; -} - -EINTERN Eina_Bool -e_comp_object_embedded_comp_object_set(Evas_Object *obj, Evas_Object *in_obj) -{ - API_ENTRY EINA_FALSE; - - E_Comp_Object *embedded_cw; - - embedded_cw = evas_object_smart_data_get(in_obj); - EINA_SAFETY_ON_NULL_RETURN_VAL(embedded_cw, EINA_FALSE); - - /* Make it return embedded E_Client so that others doesn't need to know - * about details of "embedded" notion. - * The current actual purpose behind this is for e_hwc_winodws to build - * a visible window list with an embedded E_Client, not with a container - * E_Client. */ - evas_object_data_set(obj, "E_Client", embedded_cw->ec); - - cw->embedded = EINA_TRUE; - cw->external_content = EINA_TRUE; - - cw->effect_obj = evas_object_rectangle_add(e_comp->evas); - evas_object_color_set(cw->effect_obj, 0, 0, 0, 0); - evas_object_smart_member_add(cw->effect_obj, cw->smart_obj); - - cw->obj = in_obj; - evas_object_smart_member_add(cw->obj, cw->smart_obj); - evas_object_event_callback_add(cw->obj, EVAS_CALLBACK_DEL, _e_comp_object_cb_embedded_comp_object_del, cw); - - return EINA_TRUE; -} - -EINTERN void -e_comp_object_embedded_comp_object_unset(Evas_Object *obj) -{ - API_ENTRY; - - if (!cw->embedded) - return; - - cw->embedded = EINA_FALSE; - cw->external_content = EINA_FALSE; - - evas_object_del(cw->effect_obj); - cw->effect_obj = NULL; - - if (cw->obj) - { - evas_object_event_callback_del(cw->obj, EVAS_CALLBACK_DEL, _e_comp_object_cb_embedded_comp_object_del); - evas_object_smart_member_del(cw->obj); - cw->obj = NULL; - } -} diff --git a/src/bin/e_comp_object.h b/src/bin/e_comp_object.h index c4b63f0..0b0cd1d 100644 --- a/src/bin/e_comp_object.h +++ b/src/bin/e_comp_object.h @@ -203,9 +203,6 @@ EINTERN void e_comp_object_damage_trace_debug(Eina_Bool onoff); EINTERN Eina_Bool e_comp_object_redirected_get(Evas_Object *obj); EINTERN Eina_Bool e_comp_object_color_visible_get(Evas_Object *obj); - -EINTERN Eina_Bool e_comp_object_embedded_comp_object_set(Evas_Object *obj, Evas_Object *in_obj); -EINTERN void e_comp_object_embedded_comp_object_unset(Evas_Object *obj); #endif #endif diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 61e3015..1618d61 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -2513,83 +2513,80 @@ _e_comp_wl_surface_state_commit(E_Client *ec, E_Comp_Wl_Surface_State *state) } } - if (!e_client_embedded_client_check(ec)) + /* map or unmap ec */ + if (!e_pixmap_usable_get(ec->pixmap)) { - /* map or unmap ec */ - if (!e_pixmap_usable_get(ec->pixmap)) + /* unmap ec */ + if (cdata->mapped) { - /* unmap ec */ - if (cdata->mapped) + if ((cdata->shell.surface) && + (cdata->shell.unmap)) { - if ((cdata->shell.surface) && - (cdata->shell.unmap)) + ELOGF("COMP", "Try to unmap. Call shell.unmap.", ec); + if (ec->show_pending.count > 0) { - ELOGF("COMP", "Try to unmap. Call shell.unmap.", ec); - if (ec->show_pending.count > 0) + ELOGF("E_CLIENT", "Reset show_pending!!! (count:%d, run:%d)", ec, ec->show_pending.count, ec->show_pending.running); + ec->show_pending.count = 0; + if (ec->show_pending.running) { - ELOGF("E_CLIENT", "Reset show_pending!!! (count:%d, run:%d)", ec, ec->show_pending.count, ec->show_pending.running); - ec->show_pending.count = 0; - if (ec->show_pending.running) - { - // need to send visibility false; - ec->visibility.obscured = E_VISIBILITY_UNOBSCURED; - ELOGF("POL_VIS", "CLIENT VIS ON (fake). argb:%d, opaque:%2d", ec, ec->argb, ec->visibility.opaque); - EC_CHANGED(ec); - } - ec->show_pending.running = EINA_FALSE; + // need to send visibility false; + ec->visibility.obscured = E_VISIBILITY_UNOBSCURED; + ELOGF("POL_VIS", "CLIENT VIS ON (fake). argb:%d, opaque:%2d", ec, ec->argb, ec->visibility.opaque); + EC_CHANGED(ec); } - cdata->shell.unmap(cdata->shell.surface); - } - else if ((ec->internal) || - (cdata->sub.data) || - (ec == e_comp_wl->drag_client)) - { - ELOGF("COMP", "Try to unmap. Hide window. internal:%d, sub:%p, drag:%d", - ec, ec->internal, cdata->sub.data, (ec == e_comp_wl->drag_client)); - ec->visible = EINA_FALSE; - evas_object_hide(ec->frame); - cdata->mapped = 0; + ec->show_pending.running = EINA_FALSE; } + cdata->shell.unmap(cdata->shell.surface); } - - if ((cdata->sub.below_obj) && - (evas_object_visible_get(cdata->sub.below_obj))) + else if ((ec->internal) || + (cdata->sub.data) || + (ec == e_comp_wl->drag_client)) { - evas_object_hide(cdata->sub.below_obj); + ELOGF("COMP", "Try to unmap. Hide window. internal:%d, sub:%p, drag:%d", + ec, ec->internal, cdata->sub.data, (ec == e_comp_wl->drag_client)); + ec->visible = EINA_FALSE; + evas_object_hide(ec->frame); + cdata->mapped = 0; } } - else + + if ((cdata->sub.below_obj) && + (evas_object_visible_get(cdata->sub.below_obj))) + { + evas_object_hide(cdata->sub.below_obj); + } + } + else + { + /* map ec */ + if (!cdata->mapped) { - /* map ec */ - if (!cdata->mapped) + if ((cdata->shell.surface) && + (cdata->shell.map) && + (!ec->ignored)) { - if ((cdata->shell.surface) && - (cdata->shell.map) && - (!ec->ignored)) - { - ELOGF("COMP", "Try to map. Call shell.map.", ec); - cdata->shell.map(cdata->shell.surface); - } - else if ((ec->internal) || - (e_comp_wl_subsurface_can_show(ec)) || - (ec == e_comp_wl->drag_client)) - { - ELOGF("COMP", "Try to map. Show window. internal:%d, drag:%d", - ec, ec->internal, (ec == e_comp_wl->drag_client)); - ec->visible = EINA_TRUE; - ec->ignored = 0; - evas_object_show(ec->frame); - cdata->mapped = 1; - } + ELOGF("COMP", "Try to map. Call shell.map.", ec); + cdata->shell.map(cdata->shell.surface); } - - if ((cdata->sub.below_obj) && - (!evas_object_visible_get(cdata->sub.below_obj)) && - (evas_object_visible_get(ec->frame))) + else if ((ec->internal) || + (e_comp_wl_subsurface_can_show(ec)) || + (ec == e_comp_wl->drag_client)) { - evas_object_show(cdata->sub.below_obj); + ELOGF("COMP", "Try to map. Show window. internal:%d, drag:%d", + ec, ec->internal, (ec == e_comp_wl->drag_client)); + ec->visible = EINA_TRUE; + ec->ignored = 0; + evas_object_show(ec->frame); + cdata->mapped = 1; } } + + if ((cdata->sub.below_obj) && + (!evas_object_visible_get(cdata->sub.below_obj)) && + (evas_object_visible_get(ec->frame))) + { + evas_object_show(cdata->sub.below_obj); + } } if ((state->new_attach) || @@ -4408,59 +4405,55 @@ e_comp_wl_surface_commit(E_Client *ec) e_comp_wl_subsurface_restack_bg_rectangle(topmost); } - if (!e_client_embedded_client_check(ec)) + if (!e_pixmap_usable_get(ec->pixmap)) { - if (!e_pixmap_usable_get(ec->pixmap)) + if (ec->comp_data->mapped) { - if (ec->comp_data->mapped) + if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.unmap)) { - if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.unmap)) - { - ELOGF("COMP", "Try to unmap2. Call shell.unmap.", ec); - ec->comp_data->shell.unmap(ec->comp_data->shell.surface); - } - else if (ec->internal || ec->comp_data->sub.data || - (ec == e_comp_wl->drag_client)) - { - ELOGF("COMP", "Try to unmap2. Hide window. internal:%d, sub:%p, drag:%d", - ec, ec->internal, ec->comp_data->sub.data, (ec == e_comp_wl->drag_client)); - ec->visible = EINA_FALSE; - evas_object_hide(ec->frame); - ec->comp_data->mapped = 0; - } + ELOGF("COMP", "Try to unmap2. Call shell.unmap.", ec); + ec->comp_data->shell.unmap(ec->comp_data->shell.surface); + } + else if (ec->internal || ec->comp_data->sub.data || + (ec == e_comp_wl->drag_client)) + { + ELOGF("COMP", "Try to unmap2. Hide window. internal:%d, sub:%p, drag:%d", + ec, ec->internal, ec->comp_data->sub.data, (ec == e_comp_wl->drag_client)); + ec->visible = EINA_FALSE; + evas_object_hide(ec->frame); + ec->comp_data->mapped = 0; } - - 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 + + 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 + { + if (!ec->comp_data->mapped) { - if (!ec->comp_data->mapped) + if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.map) && + (!ec->ignored)) { - if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.map) && - (!ec->ignored)) - { - ELOGF("COMP", "Try to map2. Call shell.map.", ec); - ec->comp_data->shell.map(ec->comp_data->shell.surface); - } - else if (ec->internal || e_comp_wl_subsurface_can_show(ec) || - (ec == e_comp_wl->drag_client)) - { - ELOGF("COMP", "Try to map2. Show window. internal:%d, drag:%d", - ec, ec->internal, (ec == e_comp_wl->drag_client)); - ec->visible = EINA_TRUE; - ec->ignored = 0; - evas_object_show(ec->frame); - ec->comp_data->mapped = 1; - } + ELOGF("COMP", "Try to map2. Call shell.map.", ec); + ec->comp_data->shell.map(ec->comp_data->shell.surface); + } + else if (ec->internal || e_comp_wl_subsurface_can_show(ec) || + (ec == e_comp_wl->drag_client)) + { + ELOGF("COMP", "Try to map2. Show window. internal:%d, drag:%d", + ec, ec->internal, (ec == e_comp_wl->drag_client)); + ec->visible = EINA_TRUE; + ec->ignored = 0; + evas_object_show(ec->frame); + ec->comp_data->mapped = 1; } - - if (ec->comp_data->sub.below_obj && !evas_object_visible_get(ec->comp_data->sub.below_obj) - && evas_object_visible_get(ec->frame)) - evas_object_show(ec->comp_data->sub.below_obj); } - } + if (ec->comp_data->sub.below_obj && !evas_object_visible_get(ec->comp_data->sub.below_obj) + && evas_object_visible_get(ec->frame)) + evas_object_show(ec->comp_data->sub.below_obj); + } ec->ignored = ignored; if (ec->is_cursor && ec->visible) diff --git a/src/bin/e_foreign_shell.c b/src/bin/e_foreign_shell.c index 68d46ee..aa4a886 100644 --- a/src/bin/e_foreign_shell.c +++ b/src/bin/e_foreign_shell.c @@ -70,8 +70,6 @@ static E_Exported_Shell *_e_exported_shell_find_by_surface(struct wl_resource *s static E_Exported_Shell *_e_exported_shell_find_by_handle(const char *handle); static void _e_exported_shell_surface_link(E_Exported_Shell *es, struct wl_resource *surface); static void _e_exported_shell_surface_unlink(E_Exported_Shell *es); -static void _e_exported_shell_foreign_link(E_Exported_Shell *es, E_Foreign_Shell *fs); -static void _e_exported_shell_foreign_unlink(E_Exported_Shell *es); static void _e_exported_shell_visible_set(E_Exported_Shell *es, Eina_Bool visible); static void _e_exported_shell_destination_set(E_Exported_Shell *es, int w, int h); static void _e_exported_shell_transform_set(E_Exported_Shell *es, enum wtz_exported_shell_transform transform); @@ -88,6 +86,9 @@ static void _e_foreign_shell_transform_set(E_Foreign_Shell *fs, enu static void _e_foreign_shell_transform_update(E_Foreign_Shell *fs); static void _e_foreign_shell_viewport_update(E_Foreign_Shell *fs); static void _e_foreign_shell_rotation_update(E_Foreign_Shell *fs); +static void _e_foreign_shell_place_under_exported(E_Foreign_Shell *fs); +static void _e_foreign_shell_exported_restack_handler_add(E_Foreign_Shell *fs); +static void _e_foreign_shell_exported_restack_handler_remove(E_Foreign_Shell *fs); EINTERN Eina_Bool e_foreign_shell_init(void) @@ -635,36 +636,6 @@ _e_exported_shell_transform_set(E_Exported_Shell *es, enum wtz_exported_shell_tr } static void -_e_exported_shell_foreign_link(E_Exported_Shell *es, E_Foreign_Shell *fs) -{ - E_Client *esc, *fsc; - - fsc = wl_resource_get_user_data(fs->surface); - esc = wl_resource_get_user_data(es->surface); - e_client_embedded_client_set(esc, fsc); - - es->foreign = fs; -} - -static void -_e_exported_shell_foreign_unlink(E_Exported_Shell *es) -{ - E_Client *esc; - - /* FIXME - * The E_Client associated with exported shell must get hidden before - * unsetting embedded client. Otherwise referencing count of E_Client - * wouldn't reach to zero permanently by animation triggered by - * e_comp_object. We need more general solution for it. */ - _e_exported_shell_visible_set(es, EINA_FALSE); - - esc = wl_resource_get_user_data(es->surface); - e_client_embedded_client_unset(esc); - - es->foreign = NULL; -} - -static void _e_foreign_shell_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) { wl_resource_destroy(resource); @@ -903,16 +874,69 @@ _e_foreign_shell_cb_exported_shell_destroy(struct wl_listener *listener, void *d } static void +_e_foreign_shell_place_under_exported(E_Foreign_Shell *fs) +{ + E_Client *fsc, *esc; + E_Layer layer; + + fsc = wl_resource_get_user_data(fs->surface); + esc = wl_resource_get_user_data(fs->exported->surface); + + layer = e_client_layer_get(esc); + e_client_layer_set(fsc, layer); + + evas_object_stack_below(fsc->frame, esc->frame); +} + +static void +_e_foreign_shell_cb_exported_object_restack(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + E_Foreign_Shell *fs; + + fs = data; + + _e_foreign_shell_place_under_exported(fs); +} + +static void +_e_foreign_shell_exported_restack_handler_add(E_Foreign_Shell *fs) +{ + E_Client *esc; + + esc = wl_resource_get_user_data(fs->exported->surface); + + evas_object_event_callback_add(esc->frame, + EVAS_CALLBACK_RESTACK, + _e_foreign_shell_cb_exported_object_restack, + fs); +} + +static void +_e_foreign_shell_exported_restack_handler_remove(E_Foreign_Shell *fs) +{ + E_Client *esc; + + esc = wl_resource_get_user_data(fs->exported->surface); + + evas_object_event_callback_del_full(esc->frame, + EVAS_CALLBACK_RESTACK, + _e_foreign_shell_cb_exported_object_restack, + fs); +} + +static void _e_foreign_shell_exported_link(E_Foreign_Shell *fs, E_Exported_Shell *es) { + fs->exported = es; + es->foreign = fs; + fs->shell_destroy_listener.notify = _e_foreign_shell_cb_exported_shell_destroy; wl_signal_add(&es->destroy_signal, &fs->shell_destroy_listener); - _e_exported_shell_foreign_link(es, fs); - - fs->exported = es; + _e_foreign_shell_place_under_exported(fs); + _e_foreign_shell_exported_restack_handler_add(fs); } static void @@ -920,8 +944,9 @@ _e_foreign_shell_exported_unlink(E_Foreign_Shell *fs) { wl_list_remove(&fs->shell_destroy_listener.link); - _e_exported_shell_foreign_unlink(fs->exported); + _e_foreign_shell_exported_restack_handler_remove(fs); + fs->exported->foreign = NULL; fs->exported = NULL; } -- 2.7.4