From 335746527d2cc6cdc497aa304a51f88a343e76f5 Mon Sep 17 00:00:00 2001 From: "jiin.moon" Date: Mon, 10 Apr 2017 20:21:57 +0900 Subject: [PATCH] edje: Add workaround for misuses of clip_set Author: Jean-Philippe Andre AuthorDate: Mon Apr 10 16:01:28 2017 +0900 Commit: Jean-Philippe Andre CommitDate: Mon Apr 10 16:14:45 2017 +0900 edje: Add workaround for misuses of clip_set An unfortunately very common misuse of clip is as follows: - Layout A is created (edje object / elm_layout) - Object B is swallowed inside A - Clipper C is set to clip B This is a invalid usage, as layout A takes control over the clip property of B (just like it does for geometry, visibility, color...). Since 75ec3a7338c9c2406d4 edje_recalc resets the clip at every calc loop, as it can change between states. In the past, edje_recalc did not reset the clip so anyone could (wrongly) swallow an object and then change its clip from C to modify its color, mask it, blend it, etc... Even though this was not proper use of the API, this is not very clearly documented, and since it worked, it has been (ab)used a lot already. The result now is that a clipper set from C will become visible as an opaque white rectangle covering the entire UI. Booh. This patch is a workaround that should have no impact on well written applications. As a bonus this avoids an extra call to clip_set() from edje. @fix Change-Id: I30f18a34a1812afa54b980222a51c9988374d805 --- src/lib/edje/edje_calc.c | 40 ++++++++++++++++++++++++++-------------- src/lib/edje/edje_load.c | 5 ++++- src/lib/edje/edje_private.h | 1 + 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/lib/edje/edje_calc.c b/src/lib/edje/edje_calc.c index 2dcc176..e62daef 100644 --- a/src/lib/edje/edje_calc.c +++ b/src/lib/edje/edje_calc.c @@ -4826,7 +4826,10 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta if (ep->param1.description->rel2.id_y >= 0) rp1[Rel2Y] = ed->table_parts[ep->param1.description->rel2.id_y]; if (ep->param1.description->clip_to_id >= 0) - clip1 = ed->table_parts[ep->param1.description->clip_to_id % ed->table_parts_size]; + { + clip1 = ed->table_parts[ep->param1.description->clip_to_id % ed->table_parts_size]; + ed->has_state_clip = EINA_TRUE; + } } if (ep->param2) { @@ -4839,7 +4842,10 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta if (ep->param2->description->rel2.id_y >= 0) rp2[Rel2Y] = ed->table_parts[ep->param2->description->rel2.id_y]; if (ep->param2->description->clip_to_id >= 0) - clip2 = ed->table_parts[ep->param2->description->clip_to_id % ed->table_parts_size]; + { + clip2 = ed->table_parts[ep->param2->description->clip_to_id % ed->table_parts_size]; + ed->has_state_clip = EINA_TRUE; + } } if (flags & FLAG_X) @@ -5557,12 +5563,15 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta _edje_entry_real_part_configure(ed, ep); /* handle clip overrides */ - if (pf->clip_to && pf->clip_to->object) - evas_object_clip_set(ep->object, pf->clip_to->object); - else if (ep->part->clip_to_id >= 0) - evas_object_clip_set(ep->object, ed->table_parts[ep->part->clip_to_id % ed->table_parts_size]->object); - else - evas_object_clip_set(ep->object, ed->base->clipper); + if (ed->has_state_clip) + { + if (pf->clip_to && pf->clip_to->object) + evas_object_clip_set(ep->object, pf->clip_to->object); + else if (ep->part->clip_to_id >= 0) + evas_object_clip_set(ep->object, ed->table_parts[ep->part->clip_to_id % ed->table_parts_size]->object); + else + evas_object_clip_set(ep->object, ed->base->clipper); + } break; case EDJE_PART_TYPE_TEXT: @@ -5835,12 +5844,15 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta (ep->typedata.swallow)) && (ep->typedata.swallow->swallowed_object)) { - if (pf->clip_to && pf->clip_to->object) - evas_object_clip_set(ep->typedata.swallow->swallowed_object, pf->clip_to->object); - else if (ep->part->clip_to_id >= 0) - evas_object_clip_set(ep->typedata.swallow->swallowed_object, ed->table_parts[ep->part->clip_to_id % ed->table_parts_size]->object); - else - evas_object_clip_set(ep->typedata.swallow->swallowed_object, ed->base->clipper); + if (ed->has_state_clip) + { + if (pf->clip_to && pf->clip_to->object) + evas_object_clip_set(ep->typedata.swallow->swallowed_object, pf->clip_to->object); + else if (ep->part->clip_to_id >= 0) + evas_object_clip_set(ep->typedata.swallow->swallowed_object, ed->table_parts[ep->part->clip_to_id % ed->table_parts_size]->object); + else + evas_object_clip_set(ep->typedata.swallow->swallowed_object, ed->base->clipper); + } if (pf->visible) { diff --git a/src/lib/edje/edje_load.c b/src/lib/edje/edje_load.c index 0def4c1..10f6a35 100644 --- a/src/lib/edje/edje_load.c +++ b/src/lib/edje/edje_load.c @@ -929,7 +929,10 @@ _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const ch } if (rp->param1.description && (rp->param1.description->clip_to_id >= 0)) - clip_to = ed->table_parts[rp->param1.description->clip_to_id % ed->table_parts_size]; + { + clip_to = ed->table_parts[rp->param1.description->clip_to_id % ed->table_parts_size]; + ed->has_state_clip = EINA_TRUE; + } else if (rp->part->clip_to_id >= 0) clip_to = ed->table_parts[rp->part->clip_to_id % ed->table_parts_size]; if (clip_to && clip_to->object && rp->object) diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h index 2fafeeb..dc93926 100644 --- a/src/lib/edje/edje_private.h +++ b/src/lib/edje/edje_private.h @@ -1760,6 +1760,7 @@ struct _Edje Eina_Bool update_hints : 1; Eina_Bool recalc_hints : 1; Eina_Bool need_map_update : 1; + Eina_Bool has_state_clip : 1; }; struct _Edje_Calc_Params_Map -- 2.7.4