elm/evas: Fix disappearance of window icons with CSD

After a few patches trying to fix clipping of frame or
non-frame objects the icon finally ended up invisible. Even
if the elm_icon was marked as is_frame, its internal evas
object image would not have the flag set, thus it would be
clipped out.

Solution: Propagate the is_frame flag to all smart children,
not only when setting it but also when adding new members.
A hack with the API indicates that the frame edje is a very
special object that does not propagate the flag.

See also:
7ce79be1a1
0f6c33eff1
9c9c8809a7
ac5ca9281c
This commit is contained in:
Jean-Philippe Andre 2016-11-16 18:09:37 +09:00
parent ac5ca9281c
commit f50b0fed13
6 changed files with 52 additions and 17 deletions

View File

@ -3926,9 +3926,14 @@ _elm_win_frame_add(Efl_Ui_Win_Data *sd, const char *style)
return;
}
edje_object_part_swallow(sd->frame_obj, "elm.swallow.client", sd->edje);
/* Small hack: The special value 2 means this is the top frame object.
* We propagate to the children now (the edc group contents), but subsequent
* calls to smart_member_add will not propagate the flag further. Note that
* this little hack will fall apart if edje creates and destroys objects on
* the fly. */
efl_canvas_object_is_frame_object_set(sd->frame_obj, 2);
evas_object_is_frame_object_set(sd->frame_obj, EINA_TRUE);
edje_object_part_swallow(sd->frame_obj, "elm.swallow.client", sd->edje);
if (sd->icon)
evas_object_show(sd->icon);
@ -3952,8 +3957,8 @@ _elm_win_frame_add(Efl_Ui_Win_Data *sd, const char *style)
}
}
edje_object_part_swallow(sd->frame_obj, "elm.swallow.icon",
sd->icon);
edje_object_part_swallow(sd->frame_obj, "elm.swallow.icon", sd->icon);
efl_canvas_object_is_frame_object_set(sd->icon, EINA_TRUE);
evas_object_event_callback_add
(sd->frame_obj, EVAS_CALLBACK_MOVE, _elm_win_frame_obj_move, sd);
@ -5201,7 +5206,10 @@ _efl_ui_win_icon_object_set(Eo *obj, Efl_Ui_Win_Data *sd, Evas_Object *icon)
evas_object_event_callback_add(sd->icon, EVAS_CALLBACK_DEL,
_elm_win_on_icon_del, obj);
if (sd->frame_obj)
edje_object_part_swallow(sd->frame_obj, "elm.swallow.icon", sd->icon);
{
edje_object_part_swallow(sd->frame_obj, "elm.swallow.icon", sd->icon);
evas_object_is_frame_object_set(sd->icon, EINA_TRUE);
}
}
#ifdef HAVE_ELEMENTARY_X
_elm_win_xwin_update(sd);

View File

@ -273,13 +273,17 @@ abstract Efl.Canvas.Object (Efl.Object, Efl.Gfx, Efl.Gfx.Stack, Efl.Animator,
return: bool; [[$true if the seat was removed from the focus list or $false otherwise.]]
}
@property is_frame_object {
[[Property to identify if an object is a frame]]
set {
[[@since 1.2]]
}
get {
[[@since 1.2]]
}
[[If $true the object belongs to the window border decorations.
This will be $false by default, and should be $false for all objects
created by the application, unless swallowed in some very specific
parts of the window.
It is very unlikely that an application needs to call this manually,
as the window will handle this feature automatically.
@since 1.2
]]
values {
is_frame: bool; [[$true if the object is a frame, $false otherwise]]
}

View File

@ -2048,6 +2048,16 @@ _is_frame_flag_set(Evas_Object_Protected_Data *obj, Eina_Bool is_frame)
const Eina_Inlist *l;
Evas_Object_Protected_Data *child;
/* Small hack here:
* The main frame object (ie. the frame edje object itself) will set
* a value of 2 here (Eina_Bool is an unsigned char). That way we can
* safely propagate the frame flag inside smart_member_add. */
if (is_frame > 1)
{
obj->is_frame_top = EINA_TRUE;
is_frame = EINA_TRUE;
}
obj->is_frame = is_frame;
l = evas_object_smart_members_get_direct(obj->object);

View File

@ -283,6 +283,9 @@ _efl_canvas_group_group_member_add(Eo *smart_obj, Evas_Smart_Data *o, Evas_Objec
}
}
if (!smart->is_frame_top && (smart->is_frame != obj->is_frame))
efl_canvas_object_is_frame_object_set(eo_obj, smart->is_frame);
evas_object_change(eo_obj, obj);
evas_object_mapped_clip_across_mark(eo_obj, obj);
if (smart->smart.smart && smart->smart.smart->smart_class->member_add)

View File

@ -1346,6 +1346,7 @@ evas_render_mapped(Evas_Public_Data *evas, Evas_Object *eo_obj,
RD(0, ", ctx:%p, sfc:%p, offset:%i,%i, %s, use_mapped_ctx:%d, %s)\n", context, surface, off_x, off_y,
mapped ? "mapped" : "normal", use_mapped_ctx, do_async ? "async" : "sync");
RD(level, " obj: '%s' %s", obj->type, obj->is_smart ? "(smart) " : "");
if (obj->is_frame) RD(0, "(frame) ");
if (obj->name) RD(0, "'%s'\n", obj->name);
else RD(0, "\n");
if (obj->cur->clipper)
@ -1856,8 +1857,7 @@ evas_render_mapped(Evas_Public_Data *evas, Evas_Object *eo_obj,
(evas, ctx, off_x - evas->framespace.x, off_y - evas->framespace.y);
}
if (proxy_src_clip)
ENFN->context_clip_clip(ENDT, ctx, ecx, ecy, ecw, ech);
ENFN->context_clip_clip(ENDT, ctx, ecx, ecy, ecw, ech);
}
else
{
@ -2436,9 +2436,18 @@ evas_render_updates_internal_loop(Evas *eo_e, Evas_Public_Data *e,
if (!obj->is_smart)
{
RECTS_CLIP_TO_RECT(x, y, w, h,
obj->cur->cache.clip.x + off_x + fx,
obj->cur->cache.clip.y + off_y + fy,
int cfx, cfy;
if (!obj->is_frame)
{
cfx = obj->cur->cache.clip.x + off_x + fx;
cfy = obj->cur->cache.clip.y + off_y + fy;
}
else
{
cfx = obj->cur->cache.clip.x + off_x;
cfy = obj->cur->cache.clip.y + off_y;
}
RECTS_CLIP_TO_RECT(x, y, w, h, cfx, cfy,
obj->cur->cache.clip.w,
obj->cur->cache.clip.h);
}

View File

@ -1172,6 +1172,7 @@ struct _Evas_Object_Protected_Data
Eina_Bool del_ref : 1;
Eina_Bool is_frame : 1;
Eina_Bool is_frame_top : 1; // this is the frame edje
Eina_Bool child_has_map : 1;
Eina_Bool efl_del_called : 1;
Eina_Bool is_smart : 1;