forked from enlightenment/efl
evas event handling3 - fix yet more corner cases for clipped objects
this is a continuation fix from25d77bc1d2
and9f0fd66ab8
this fixes yet more corner cases after the above 2 fixes. our clip cache tracking code seems to be broken somewhere and not updating - at least when events are processed so i did ti the slightly slower way and recursed through clippers to figure it out in this path. it all works now it seems but it's got a small speed hit. better be right than a little faster. @fix
This commit is contained in:
parent
0fc151cddc
commit
f6b3c31561
|
@ -143,6 +143,34 @@ _efl_event_desc_get(Evas_Callback_Type type)
|
|||
# define D(...) do { } while (0)
|
||||
#endif
|
||||
|
||||
#ifdef DDD_DO
|
||||
static void
|
||||
walk_clippers_print(int spaces, Evas_Object_Protected_Data *obj)
|
||||
{
|
||||
int i;
|
||||
spaces++;
|
||||
DDD("<<< CLIP %p c[%6i %6i %6ix%6i] c[%6i %6i %6ix%6i]\n",
|
||||
obj->object,
|
||||
obj->cur->geometry.x, obj->cur->geometry.y,
|
||||
obj->cur->geometry.w, obj->cur->geometry.h,
|
||||
obj->cur->cache.clip.x, obj->cur->cache.clip.y,
|
||||
obj->cur->cache.clip.w, obj->cur->cache.clip.h
|
||||
);
|
||||
if (obj->cur->clipper) walk_clippers_print(spaces, obj->cur->clipper);
|
||||
spaces--;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
clip_calc(Evas_Object_Protected_Data *obj, Evas_Coord_Rectangle *c)
|
||||
{
|
||||
if (!obj) return;
|
||||
RECTS_CLIP_TO_RECT(c->x, c->y, c->w, c->h,
|
||||
obj->cur->geometry.x, obj->cur->geometry.y,
|
||||
obj->cur->geometry.w, obj->cur->geometry.h);
|
||||
clip_calc(obj->cur->clipper, c);
|
||||
}
|
||||
|
||||
static Eina_List *
|
||||
_evas_event_object_list_raw_in_get(Evas *eo_e, Eina_List *in,
|
||||
const Eina_Inlist *list, Evas_Object *stop,
|
||||
|
@ -150,6 +178,7 @@ _evas_event_object_list_raw_in_get(Evas *eo_e, Eina_List *in,
|
|||
{
|
||||
Evas_Object *eo_obj;
|
||||
Evas_Object_Protected_Data *obj = NULL;
|
||||
Evas_Coord_Rectangle c;
|
||||
int inside;
|
||||
|
||||
#ifdef DDD_DO
|
||||
|
@ -171,37 +200,107 @@ _evas_event_object_list_raw_in_get(Evas *eo_e, Eina_List *in,
|
|||
*no_rep = 1;
|
||||
#ifdef DDD_DO
|
||||
spaces--;
|
||||
#endif
|
||||
DDD("***** NO REP - STOP *****\n");
|
||||
#endif
|
||||
return in;
|
||||
}
|
||||
|
||||
evas_object_clip_recalc(obj);
|
||||
if ((!RECTS_INTERSECT(x, y, 1, 1,
|
||||
obj->cur->cache.clip.x,
|
||||
obj->cur->cache.clip.y,
|
||||
obj->cur->cache.clip.w,
|
||||
obj->cur->cache.clip.h)))
|
||||
if (!obj->cur->visible) continue;
|
||||
// XXX: this below DYNAMICALLY calculates the current clip rect
|
||||
// by walking clippers to each parent clipper until there are
|
||||
// no more of them. this is a necessary hack because cache.clip
|
||||
// cooreds are broken. somewhere along the way in the past few years
|
||||
// someone has forgotten to flag them as dirty and update them
|
||||
// so a clicp recalce caqn work... somewhere. maybe a prexy or map fix
|
||||
// or an optimization. finding this is really hard, so i'm going
|
||||
// for plan b and doing this on the fly. it's only for event or
|
||||
// callback handling so its a small percentage of the time, but
|
||||
// it's better that we get this right
|
||||
if (obj->is_smart)
|
||||
{
|
||||
DDD("___ %p g[%6i %6i %6ix%6i] c[%6i %6i %6ix%6i] %s\n",
|
||||
obj->object,
|
||||
obj->cur->geometry.x, obj->cur->geometry.y,
|
||||
obj->cur->geometry.w, obj->cur->geometry.h,
|
||||
obj->cur->cache.clip.x, obj->cur->cache.clip.y,
|
||||
obj->cur->cache.clip.w, obj->cur->cache.clip.h,
|
||||
obj->type);
|
||||
continue;
|
||||
Evas_Coord_Rectangle bounding_box = { 0, 0, 0, 0 };
|
||||
|
||||
evas_object_smart_bounding_box_update(eo_obj, obj);
|
||||
evas_object_smart_bounding_box_get(obj->object, &bounding_box, NULL);
|
||||
c = bounding_box;
|
||||
}
|
||||
else
|
||||
{
|
||||
DDD("OBJ %p g[%6i %6i %6ix%6i] c[%6i %6i %6ix%6i] %s\n",
|
||||
obj->object,
|
||||
obj->cur->geometry.x, obj->cur->geometry.y,
|
||||
obj->cur->geometry.w, obj->cur->geometry.h,
|
||||
obj->cur->cache.clip.x, obj->cur->cache.clip.y,
|
||||
obj->cur->cache.clip.w, obj->cur->cache.clip.h,
|
||||
obj->type);
|
||||
if (obj->clip.clipees) continue;
|
||||
c = obj->cur->geometry;
|
||||
}
|
||||
clip_calc(obj->cur->clipper, &c);
|
||||
// only worry about objects that intersect INCLUDING clippint
|
||||
if ((!RECTS_INTERSECT(x, y, 1, 1, c.x, c.y, c.w, c.h)))
|
||||
{
|
||||
#ifdef DDD_DO
|
||||
if (obj->is_smart)
|
||||
{
|
||||
Evas_Coord_Rectangle bounding_box = { 0, 0, 0, 0 };
|
||||
|
||||
evas_object_smart_bounding_box_get(obj->object, &bounding_box, NULL);
|
||||
DDD("___ %p g[%6i %6i %6ix%6i] c[%6i %6i %6ix%6i] b[%6i %6i %6ix%6i] %s\n",
|
||||
obj->object,
|
||||
obj->cur->geometry.x, obj->cur->geometry.y,
|
||||
obj->cur->geometry.w, obj->cur->geometry.h,
|
||||
obj->cur->cache.clip.x, obj->cur->cache.clip.y,
|
||||
obj->cur->cache.clip.w, obj->cur->cache.clip.h,
|
||||
bounding_box.x, bounding_box.y,
|
||||
bounding_box.w, bounding_box.h,
|
||||
obj->type);
|
||||
}
|
||||
else
|
||||
{
|
||||
DDD("___ %p g[%6i %6i %6ix%6i] c[%6i %6i %6ix%6i] %s\n",
|
||||
obj->object,
|
||||
obj->cur->geometry.x, obj->cur->geometry.y,
|
||||
obj->cur->geometry.w, obj->cur->geometry.h,
|
||||
obj->cur->cache.clip.x, obj->cur->cache.clip.y,
|
||||
obj->cur->cache.clip.w, obj->cur->cache.clip.h,
|
||||
obj->type);
|
||||
}
|
||||
if (!strcmp(obj->type, "e_layout"))
|
||||
{
|
||||
if (obj->cur->clipper)
|
||||
walk_clippers_print(spaces, obj->cur->clipper);
|
||||
}
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
#ifdef DDD_DO
|
||||
else
|
||||
{
|
||||
if (obj->is_smart)
|
||||
{
|
||||
Evas_Coord_Rectangle bounding_box = { 0, 0, 0, 0 };
|
||||
|
||||
evas_object_smart_bounding_box_get(obj->object, &bounding_box, NULL);
|
||||
DDD("OBJ %p g[%6i %6i %6ix%6i] c[%6i %6i %6ix%6i] b[%6i %6i %6ix%6i] %s\n",
|
||||
obj->object,
|
||||
obj->cur->geometry.x, obj->cur->geometry.y,
|
||||
obj->cur->geometry.w, obj->cur->geometry.h,
|
||||
obj->cur->cache.clip.x, obj->cur->cache.clip.y,
|
||||
obj->cur->cache.clip.w, obj->cur->cache.clip.h,
|
||||
bounding_box.x, bounding_box.y,
|
||||
bounding_box.w, bounding_box.h,
|
||||
obj->type);
|
||||
}
|
||||
else
|
||||
{
|
||||
DDD("OBJ %p g[%6i %6i %6ix%6i] c[%6i %6i %6ix%6i] %s\n",
|
||||
obj->object,
|
||||
obj->cur->geometry.x, obj->cur->geometry.y,
|
||||
obj->cur->geometry.w, obj->cur->geometry.h,
|
||||
obj->cur->cache.clip.x, obj->cur->cache.clip.y,
|
||||
obj->cur->cache.clip.w, obj->cur->cache.clip.h,
|
||||
obj->type);
|
||||
}
|
||||
// if (!strcmp(obj->type, "e_layout"))
|
||||
{
|
||||
if (obj->cur->clipper)
|
||||
walk_clippers_print(spaces, obj->cur->clipper);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!source)
|
||||
{
|
||||
|
@ -275,8 +374,8 @@ _evas_event_object_list_raw_in_get(Evas *eo_e, Eina_List *in,
|
|||
*no_rep = 1;
|
||||
#ifdef DDD_DO
|
||||
spaces--;
|
||||
#endif
|
||||
DDD("***** NO REP1 *****\n");
|
||||
#endif
|
||||
return in;
|
||||
}
|
||||
}
|
||||
|
@ -315,8 +414,8 @@ _evas_event_object_list_raw_in_get(Evas *eo_e, Eina_List *in,
|
|||
*no_rep = 1;
|
||||
#ifdef DDD_DO
|
||||
spaces--;
|
||||
#endif
|
||||
DDD("***** NO REP2 *****\n");
|
||||
#endif
|
||||
return in;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1371,6 +1371,11 @@ evas_object_smart_need_bounding_box_update(Evas_Object *eo_obj, Evas_Smart_Data
|
|||
evas_object_async_block(obj);
|
||||
if (o->update_boundingbox_needed) return;
|
||||
o->update_boundingbox_needed = EINA_TRUE;
|
||||
EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
|
||||
{
|
||||
state_write->cache.clip.dirty = EINA_TRUE;
|
||||
}
|
||||
EINA_COW_STATE_WRITE_END(obj, state_write, cur);
|
||||
|
||||
if (obj->smart.parent)
|
||||
evas_object_smart_need_bounding_box_update(obj->smart.parent,
|
||||
|
@ -1384,10 +1389,12 @@ evas_object_smart_bounding_box_update(Evas_Object *eo_obj, Evas_Object_Protected
|
|||
Evas_Smart_Data *os;
|
||||
Eina_Inlist *list;
|
||||
Evas_Object_Protected_Data *o;
|
||||
Evas_Coord minx;
|
||||
Evas_Coord miny;
|
||||
Evas_Coord maxw = 0;
|
||||
Evas_Coord maxh = 0;
|
||||
Evas_Coord minx = 0x7fffffff;
|
||||
Evas_Coord miny = 0x7fffffff;
|
||||
Evas_Coord maxx = 0x80000000;
|
||||
Evas_Coord maxy = 0x80000000;
|
||||
Evas_Coord tx1, ty1, tx2, ty2;
|
||||
Eina_Bool none = EINA_TRUE;
|
||||
|
||||
MAGIC_CHECK(eo_obj, Evas_Object, MAGIC_OBJ);
|
||||
return;
|
||||
|
@ -1398,70 +1405,60 @@ evas_object_smart_bounding_box_update(Evas_Object *eo_obj, Evas_Object_Protected
|
|||
|
||||
if (!os->update_boundingbox_needed) return;
|
||||
os->update_boundingbox_needed = EINA_FALSE;
|
||||
evas_object_clip_dirty(eo_obj, obj);
|
||||
if (obj->cur->clipper) evas_object_clip_recalc(obj->cur->clipper);
|
||||
|
||||
minx = obj->layer->evas->output.w;
|
||||
miny = obj->layer->evas->output.h;
|
||||
|
||||
list = os->contained;
|
||||
EINA_INLIST_FOREACH(list, o)
|
||||
{
|
||||
Evas_Coord tx;
|
||||
Evas_Coord ty;
|
||||
Evas_Coord tw;
|
||||
Evas_Coord th;
|
||||
|
||||
if (o == obj) continue ;
|
||||
if (o->clip.clipees || o->is_static_clip) continue ;
|
||||
if (!o->cur->visible) continue;
|
||||
|
||||
none = EINA_FALSE;
|
||||
|
||||
if (o->is_smart)
|
||||
{
|
||||
Evas_Smart_Data *s = eo_data_scope_get(o->object, MY_CLASS);
|
||||
|
||||
evas_object_smart_bounding_box_update(o->object, o);
|
||||
|
||||
tx = s->cur.bounding_box.x;
|
||||
ty = s->cur.bounding_box.y;
|
||||
tw = tx + s->cur.bounding_box.w;
|
||||
th = ty + s->cur.bounding_box.h;
|
||||
tx1 = s->cur.bounding_box.x;
|
||||
ty1 = s->cur.bounding_box.y;
|
||||
tx2 = tx1 + s->cur.bounding_box.w;
|
||||
ty2 = ty1 + s->cur.bounding_box.h;
|
||||
}
|
||||
else
|
||||
{
|
||||
tx = o->cur->geometry.x;
|
||||
ty = o->cur->geometry.y;
|
||||
tw = tx + o->cur->geometry.w;
|
||||
th = ty + o->cur->geometry.h;
|
||||
tx1 = o->cur->geometry.x;
|
||||
ty1 = o->cur->geometry.y;
|
||||
tx2 = tx1 + o->cur->geometry.w;
|
||||
ty2 = ty1 + o->cur->geometry.h;
|
||||
}
|
||||
|
||||
if (tx < minx) minx = tx;
|
||||
if (ty < miny) miny = ty;
|
||||
if (tw > maxw) maxw = tw;
|
||||
if (th > maxh) maxh = th;
|
||||
if (tx1 < minx) minx = tx1;
|
||||
if (ty1 < miny) miny = ty1;
|
||||
if (tx2 > maxx) maxx = tx2;
|
||||
if (ty2 > maxy) maxy = ty2;
|
||||
}
|
||||
if (none)
|
||||
{
|
||||
minx = obj->cur->geometry.x;
|
||||
miny = obj->cur->geometry.y;
|
||||
maxx = obj->cur->geometry.x + obj->cur->geometry.w;
|
||||
maxy = obj->cur->geometry.y + obj->cur->geometry.h;
|
||||
}
|
||||
|
||||
if (minx != os->cur.bounding_box.x)
|
||||
{
|
||||
os->cur.bounding_box.w += os->cur.bounding_box.x - minx;
|
||||
os->cur.bounding_box.x = minx;
|
||||
}
|
||||
os->cur.bounding_box.x = minx;
|
||||
os->cur.bounding_box.y = miny;
|
||||
os->cur.bounding_box.w = maxx - minx;
|
||||
os->cur.bounding_box.h = maxy - miny;
|
||||
|
||||
if (miny != os->cur.bounding_box.y)
|
||||
EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
|
||||
{
|
||||
os->cur.bounding_box.h += os->cur.bounding_box.y - miny;
|
||||
os->cur.bounding_box.y = miny;
|
||||
}
|
||||
|
||||
if (maxw != os->cur.bounding_box.x + os->cur.bounding_box.w)
|
||||
{
|
||||
os->cur.bounding_box.w = maxw - os->cur.bounding_box.x;
|
||||
}
|
||||
|
||||
if (maxh != os->cur.bounding_box.y + os->cur.bounding_box.h)
|
||||
{
|
||||
os->cur.bounding_box.h = maxh - os->cur.bounding_box.y;
|
||||
state_write->cache.clip.dirty = EINA_TRUE;
|
||||
}
|
||||
EINA_COW_STATE_WRITE_END(obj, state_write, cur);
|
||||
evas_object_clip_recalc(obj);
|
||||
if (obj->cur->clipper) evas_object_clip_recalc(obj->cur->clipper);
|
||||
}
|
||||
|
||||
/* all nice and private */
|
||||
|
|
|
@ -309,8 +309,7 @@ evas_object_clip_recalc(Evas_Object_Protected_Data *obj)
|
|||
if (clipper)
|
||||
{
|
||||
// this causes problems... hmmm ?????
|
||||
if (clipper->cur->cache.clip.dirty)
|
||||
evas_object_clip_recalc(clipper);
|
||||
evas_object_clip_recalc(clipper);
|
||||
|
||||
// I don't know why this test was here in the first place. As I have
|
||||
// no issue showing up due to this, I keep it and move color out of it.
|
||||
|
|
Loading…
Reference in New Issue