evas: Fix event area issue by bounding box 98/160398/1
authorjiin.moon <jiin.moon@samsung.com>
Wed, 15 Nov 2017 08:59:35 +0000 (17:59 +0900)
committerJIIN MOON <jiin.moon@samsung.com>
Thu, 16 Nov 2017 04:40:39 +0000 (04:40 +0000)
This patch fixes that mouse button does not working on smart object.
If the bounding box of smart object has wrong geometry,
it affects when the event area is deviced

This patch is a part of upstream commit
f6b3c31561276a6c7afc8fb56ae2e5363772782c.
(evas event handling3 - fix yet more corner cases for clipped objects)

addition:
evas event handling2 - fix incorrect object reporting
(25d77bc1d24d9fd539c681fa58db976c1ca65051)

evas event handling4- fix more corner cases where bounding is bad
(e57084d5c5b8b55a4823952ba43c61a15457e369)

Change-Id: I5e6578fd94d0bf2b9a852519ff79e516b5cc34e0
(cherry picked from commit a9ee7166f8affc18f88fcba6d7916d9ba3d503b8)

src/lib/evas/canvas/evas_clip.c
src/lib/evas/canvas/evas_events.c
src/lib/evas/canvas/evas_map.c
src/lib/evas/canvas/evas_object_main.c
src/lib/evas/canvas/evas_object_smart.c
src/lib/evas/include/evas_inline.x

index c47f2ac..eddae9d 100644 (file)
@@ -381,6 +381,8 @@ _evas_object_clip_set(Eo *eo_obj, Evas_Object_Protected_Data *obj, Evas_Object *
 
    evas_object_change(eo_clip, clip);
    evas_object_change(eo_obj, obj);
+   evas_object_update_bounding_box(eo_obj, obj);
+
    evas_object_clip_dirty(eo_obj, obj);
    evas_object_recalc_clippees(obj);
    if ((!obj->is_smart) &&
@@ -426,6 +428,8 @@ _evas_object_clip_unset(Eo *eo_obj, Evas_Object_Protected_Data *obj)
      }
    _evas_object_clip_unset_common(obj, EINA_FALSE);
    evas_object_change(eo_obj, obj);
+   evas_object_update_bounding_box(eo_obj, obj);
+
    evas_object_clip_dirty(eo_obj, obj);
    evas_object_recalc_clippees(obj);
    if ((!obj->is_smart) &&
index bd82b2c..6650654 100644 (file)
@@ -91,7 +91,6 @@ _evas_event_object_list_raw_in_get(Evas *eo_e, Eina_List *in,
              if (obj->is_smart)
                {
                   Evas_Coord_Rectangle bounding_box = { 0, 0, 0, 0};
-
                   evas_object_smart_bounding_box_update(eo_obj, obj);
                   evas_object_smart_bounding_box_get(eo_obj, &bounding_box, NULL);
                   c = bounding_box;
index bd6e914..bf8f6d3 100644 (file)
@@ -524,10 +524,11 @@ _evas_object_map_enable_set(Eo *eo_obj, Evas_Object_Protected_Data *obj, Eina_Bo
              if (!parents) break;
              parents->child_has_map = EINA_TRUE;
           }
+        evas_object_update_bounding_box(eo_obj, obj);
+
      }
    else
      {
-        if (_evas_object_map_parent_check(obj->smart.parent))
           evas_object_update_bounding_box(eo_obj, obj);
      }
 }
@@ -604,6 +605,7 @@ _evas_object_map_set(Eo *eo_obj, Evas_Object_Protected_Data *obj, const Evas_Map
 
              if (!obj->map->prev.map)
                {
+                  evas_object_update_bounding_box(eo_obj, obj);
                   evas_object_mapped_clip_across_mark(eo_obj, obj);
                   return;
                }
@@ -613,6 +615,7 @@ _evas_object_map_set(Eo *eo_obj, Evas_Object_Protected_Data *obj, const Evas_Map
              if (obj->map->cur.usemap)
                evas_object_mapped_clip_across_mark(eo_obj, obj);
           }
+        evas_object_update_bounding_box(eo_obj, obj);
         return;
      }
 
@@ -646,7 +649,7 @@ _evas_object_map_set(Eo *eo_obj, Evas_Object_Protected_Data *obj, const Evas_Map
         if (obj->map->cur.usemap)
           evas_object_mapped_clip_across_mark(eo_obj, obj);
      }
-
+   evas_object_update_bounding_box(eo_obj, obj);
    _evas_map_calc_map_geometry(eo_obj);
 }
 
index 926007a..003a38c 100644 (file)
@@ -1287,6 +1287,7 @@ _show(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
                }
           }
      }
+   evas_object_update_bounding_box(eo_obj, obj);
    evas_object_inform_call_show(eo_obj);
 }
 
@@ -1409,6 +1410,7 @@ _hide(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
         obj->mouse_in = 0;
  */
      }
+   evas_object_update_bounding_box(eo_obj, obj);
    evas_object_inform_call_hide(eo_obj);
 }
 
index 4fa0384..281623c 100644 (file)
@@ -1384,6 +1384,11 @@ evas_object_smart_need_bounding_box_update(Evas_Object *eo_obj)
    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);
 }
@@ -1394,10 +1399,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;
@@ -1406,69 +1413,65 @@ evas_object_smart_bounding_box_update(Evas_Object *eo_obj, Evas_Object_Protected
    evas_object_async_block(obj);
    os = eo_data_scope_get(eo_obj, MY_CLASS);
 
-   if (!os->update_boundingbox_needed) return;
-   os->update_boundingbox_needed = EINA_FALSE;
 
-   minx = obj->layer->evas->output.w;
-   miny = obj->layer->evas->output.h;
+   if (!os->update_boundingbox_needed)
+     return;
+
+   os->update_boundingbox_needed = EINA_FALSE;
 
    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);
+             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;
 
-             tx = s->cur.bounding_box.x;
-             ty = s->cur.bounding_box.y;
-             tw = s->cur.bounding_box.x + s->cur.bounding_box.w;
-             th = s->cur.bounding_box.y + s->cur.bounding_box.h;
           }
         else
           {
-             tx = o->cur->geometry.x;
-             ty = o->cur->geometry.y;
-             tw = o->cur->geometry.x + o->cur->geometry.w;
-             th = o->cur->geometry.y + o->cur->geometry.h;
-          }
-
-        if (tx < minx) minx = tx;
-        if (ty < miny) miny = ty;
-        if (tw > maxw) maxw = tw;
-        if (th > maxh) maxh = th;
-     }
+             tx1 = o->cur->geometry.x;
+             ty1 = o->cur->geometry.y;
+             tx2 = tx1 + o->cur->geometry.w;
+             ty2 = ty1 + o->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;
-     }
+          }
+        if (tx1 < minx) minx = tx1;
+        if (ty1 < miny) miny = ty1;
+        if (tx2 > maxx) maxx = tx2;
+        if (ty2 > maxy) maxy = ty2;
 
-   if (miny != os->cur.bounding_box.y)
-     {
-        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 (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;
+      }
+   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 (maxh != os->cur.bounding_box.y + os->cur.bounding_box.h)
-     {
-        os->cur.bounding_box.h = maxh - os->cur.bounding_box.y;
-     }
+   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);
+   evas_object_clip_recalc(obj);
+   if (obj->cur->clipper) evas_object_clip_recalc(obj->cur->clipper);
 }
 
 /* all nice and private */
index 5776b4d..d84b640 100644 (file)
@@ -289,10 +289,24 @@ evas_object_clip_recalc(Evas_Object_Protected_Data *obj)
      }
    else
      {
-        cx = obj->cur->geometry.x;
-        cy = obj->cur->geometry.y;
-        cw = obj->cur->geometry.w;
-        ch = obj->cur->geometry.h;
+        if (obj->is_smart)
+          {
+             Evas_Coord_Rectangle bounding_box;
+
+             evas_object_smart_bounding_box_update(eo_obj, obj);
+             evas_object_smart_bounding_box_get(eo_obj, &bounding_box, NULL);
+             cx = bounding_box.x;
+             cy = bounding_box.y;
+             cw = bounding_box.w;
+             ch = bounding_box.h;
+          }
+        else
+          {
+             cx = obj->cur->geometry.x;
+             cy = obj->cur->geometry.y;
+             cw = obj->cur->geometry.w;
+             ch = obj->cur->geometry.h;
+          }
      }
 
    if (obj->cur->color.a == 0 && obj->cur->render_op == EVAS_RENDER_BLEND)
@@ -305,7 +319,6 @@ evas_object_clip_recalc(Evas_Object_Protected_Data *obj)
    if (EVAS_OBJECT_DATA_VALID(clipper))
      {
         // this causes problems... hmmm ?????
-        if (clipper->cur->cache.clip.dirty)
           evas_object_clip_recalc(clipper);
 
         // I don't know why this test was here in the first place. As I have
@@ -331,6 +344,8 @@ evas_object_clip_recalc(Evas_Object_Protected_Data *obj)
                {
                   Evas_Object_Protected_Data *parent =
                         eo_data_scope_get(obj->smart.parent, EVAS_OBJECT_CLASS);
+
+                  evas_object_clip_recalc(parent);
                   if (parent->clip.mask)
                     {
                        if (parent->clip.mask != obj->clip.mask)