antognolli pushed a commit to branch master.

commit e937f1f5a385b44f37d943c34cdc06871483714e
Author: Rafael Antognolli <[email protected]>
Date:   Thu Apr 18 16:10:53 2013 -0300

    evas/wayland: Unclip objects from the framespace after rendering.
    
    These objects should be clipped only during rendering, since keeping
    them clipped after that allows for unexpected behavior on the
    application side. For instance, an application could check if objects
    have clippers before doing something to them, assuming that some objects
    should have no clipper, but under wayland, after the first render
    iteration, there will be no objects without a clipper.
    
    This commit fixes this behavior by unclipping objects that had no
    clipper prior to the render iteration.
    
    Additionally, it fixes a bug where a maximized/fullscreen window could
    have not all of its content rendered immediately. This was occuring
    because some objects could be clipped to the framespace clipper, but
    considered invisible in the beginning of the render phase, where they
    are evaluated. They were considered invisible because the framespace
    clipper object was not resized at that phase yet, and thus these objects
    were being clipped out from the viewport.
---
 src/lib/evas/canvas/evas_main.c     |   2 +
 src/lib/evas/canvas/evas_render.c   | 176 ++++++++++++++++++++----------------
 src/lib/evas/include/evas_private.h |   1 +
 3 files changed, 103 insertions(+), 76 deletions(-)

diff --git a/src/lib/evas/canvas/evas_main.c b/src/lib/evas/canvas/evas_main.c
index beebbb3..79babed 100644
--- a/src/lib/evas/canvas/evas_main.c
+++ b/src/lib/evas/canvas/evas_main.c
@@ -164,6 +164,7 @@ _constructor(Eo *eo_obj, void *class_data, va_list *list 
EINA_UNUSED)
    EVAS_ARRAY_SET(e, obscuring_objects);
    EVAS_ARRAY_SET(e, temporary_objects);
    EVAS_ARRAY_SET(e, calculate_objects);
+   EVAS_ARRAY_SET(e, clipped_objects);
    EVAS_ARRAY_SET(e, clip_changes);
    EVAS_ARRAY_SET(e, scie_unref_queue);
    EVAS_ARRAY_SET(e, image_unref_queue);
@@ -276,6 +277,7 @@ _destructor(Eo *eo_e, void *_pd, va_list *list EINA_UNUSED)
    eina_array_flush(&e->obscuring_objects);
    eina_array_flush(&e->temporary_objects);
    eina_array_flush(&e->calculate_objects);
+   eina_array_flush(&e->clipped_objects);
    eina_array_flush(&e->clip_changes);
    eina_array_flush(&e->scie_unref_queue);
    eina_array_flush(&e->image_unref_queue);
diff --git a/src/lib/evas/canvas/evas_render.c 
b/src/lib/evas/canvas/evas_render.c
index ecdad31..23c081d 100644
--- a/src/lib/evas/canvas/evas_render.c
+++ b/src/lib/evas/canvas/evas_render.c
@@ -1431,6 +1431,103 @@ _drop_image_cache_ref(const void *container 
EINA_UNUSED, void *data, void *fdata
    return EINA_TRUE;
 }
 
+static void
+_framespace_clipper_add(Evas *eo_e, Evas_Public_Data *e)
+{
+   Eina_Rectangle clip_rect;
+   unsigned int i;
+   Evas_Object *eo_obj;
+   Evas_Object_Protected_Data *obj;
+
+   if (strncmp(e->engine.module->definition->name, "wayland", 7))
+     return;
+
+   /* see if the master clip has been added yet, if not, then create */
+   if (!e->framespace.clip)
+     {
+        e->framespace.clip = evas_object_rectangle_add(eo_e);
+        evas_object_color_set(e->framespace.clip, 255, 255, 255, 255);
+        evas_object_move(e->framespace.clip,
+                         e->framespace.x, e->framespace.y);
+        evas_object_resize(e->framespace.clip,
+                           e->viewport.w - e->framespace.w,
+                           e->viewport.h - e->framespace.h);
+     }
+   else
+     {
+        /* master clip is already present. check for size changes in the
+         * viewport, and update master clip size if needed */
+        if ((e->viewport.changed) || (e->output.changed) ||
+            (e->framespace.changed))
+          {
+             evas_object_move(e->framespace.clip,
+                              e->framespace.x, e->framespace.y);
+             evas_object_resize(e->framespace.clip,
+                                e->viewport.w - e->framespace.w,
+                                e->viewport.h - e->framespace.h);
+          }
+     }
+
+   Evas_Object_Protected_Data *framespace_clip =
+      eo_data_get(e->framespace.clip, EVAS_OBJ_CLASS);
+
+   EINA_RECTANGLE_SET(&clip_rect,
+                      framespace_clip->cur->geometry.x,
+                      framespace_clip->cur->geometry.y,
+                      framespace_clip->cur->geometry.w,
+                      framespace_clip->cur->geometry.h);
+
+   evas_object_show(e->framespace.clip);
+   /* With the master clip all setup, we need to loop the objects on this
+    * canvas and determine if the object is in the viewport space. If it
+    * is in the viewport space (and not in framespace), then we need to
+    * clip the object to the master clip so that it does not draw on top
+    * of the frame (eg: elm 3d test) */
+   for (i = 0; i < e->render_objects.count; ++i)
+     {
+        Eina_Rectangle obj_rect;
+        Evas_Object *pclip;
+
+        obj = eina_array_data_get(&e->render_objects, i);
+        if (obj->is_frame) continue;
+
+        if (obj->delete_me) continue;
+
+        eo_obj = obj->object;
+
+        /* skip clipping if the object is itself the
+         * framespace clip */
+        if (eo_obj == framespace_clip->object) continue;
+
+        EINA_RECTANGLE_SET(&obj_rect,
+                           obj->cur->geometry.x, obj->cur->geometry.y,
+                           obj->cur->geometry.w, obj->cur->geometry.h);
+
+        /* if the object does not intersect our clip rect, ignore it */
+        if (!eina_rectangles_intersect(&clip_rect, &obj_rect))
+          continue;
+
+        if (!(pclip = evas_object_clip_get(eo_obj)))
+          {
+             /* clip this object so it does not draw on the window frame */
+             evas_object_clip_set(eo_obj, framespace_clip->object);
+             eina_array_push(&e->clipped_objects, eo_obj);
+          }
+     }
+}
+
+static void
+_framespace_clipper_del(Evas_Public_Data *e)
+{
+   Evas_Object *eo_obj;
+
+   while ((eo_obj = eina_array_pop(&e->clipped_objects)))
+     evas_object_clip_unset(eo_obj);
+
+   if (e->framespace.clip)
+     evas_object_hide(e->framespace.clip);
+}
+
 static Eina_Bool
 evas_render_updates_internal(Evas *eo_e,
                              unsigned char make_updates,
@@ -1574,82 +1671,7 @@ evas_render_updates_internal(Evas *eo_e,
     * NB: This is for the wayland engine(s). If we do not do this, then 
     * objects will draw outside the viewport and potentially onto the frame 
     * itself */
-   if (!strncmp(e->engine.module->definition->name, "wayland", 7))
-     {
-        Eina_Rectangle clip_rect;
-
-        /* see if the master clip has been added yet, if not, then create */
-        if (!e->framespace.clip)
-          {
-             e->framespace.clip = evas_object_rectangle_add(eo_e);
-             evas_object_color_set(e->framespace.clip, 255, 255, 255, 255);
-             evas_object_move(e->framespace.clip,
-                              e->framespace.x, e->framespace.y);
-             evas_object_resize(e->framespace.clip,
-                                e->viewport.w - e->framespace.w,
-                                e->viewport.h - e->framespace.h);
-             evas_object_show(e->framespace.clip);
-          }
-        else
-          {
-             /* master clip is already present. check for size changes in the 
-              * viewport, and update master clip size if needed */
-             if ((e->viewport.changed) || (e->output.changed) ||
-                 (e->framespace.changed))
-               {
-                  evas_object_move(e->framespace.clip,
-                                   e->framespace.x, e->framespace.y);
-                  evas_object_resize(e->framespace.clip,
-                                     e->viewport.w - e->framespace.w,
-                                     e->viewport.h - e->framespace.h);
-               }
-          }
-
-        Evas_Object_Protected_Data *framespace_clip =
-          eo_data_get(e->framespace.clip, EVAS_OBJ_CLASS);
-
-        EINA_RECTANGLE_SET(&clip_rect,
-                           framespace_clip->cur->geometry.x,
-                           framespace_clip->cur->geometry.y,
-                           framespace_clip->cur->geometry.w,
-                           framespace_clip->cur->geometry.h)
-
-        /* With the master clip all setup, we need to loop the objects on this 
-         * canvas and determine if the object is in the viewport space. If it 
-         * is in the viewport space (and not in framespace), then we need to 
-         * clip the object to the master clip so that it does not draw on top 
-         * of the frame (eg: elm 3d test) */
-        for (i = 0; i < e->render_objects.count; ++i)
-          {
-             Eina_Rectangle obj_rect;
-             Evas_Object *pclip;
-
-             obj = eina_array_data_get(&e->render_objects, i);
-             if (obj->is_frame) continue;
-
-             if (obj->delete_me) continue;
-
-             eo_obj = obj->object;
-
-             /* skip clipping if the object is itself the 
-              * framespace clip */
-             if (eo_obj == framespace_clip->object) continue;
-
-             EINA_RECTANGLE_SET(&obj_rect,
-                                obj->cur->geometry.x, obj->cur->geometry.y,
-                                obj->cur->geometry.w, obj->cur->geometry.h);
-
-             /* if the object does not intersect our clip rect, ignore it */
-             if (!eina_rectangles_intersect(&clip_rect, &obj_rect))
-               continue;
-
-             if (!(pclip = evas_object_clip_get(eo_obj)))
-               {
-                  /* clip this object so it does not draw on the window frame 
*/
-                  evas_object_clip_set(eo_obj, framespace_clip->object);
-               }
-          }
-     }
+   _framespace_clipper_add(eo_e, e);
 
    if (redraw_all)
      {
@@ -1938,6 +1960,8 @@ evas_render_updates_internal(Evas *eo_e,
         e->invalidate = EINA_TRUE;
      }
 
+   _framespace_clipper_del(e);
+
    evas_module_clean();
 
    if (!do_async)
diff --git a/src/lib/evas/include/evas_private.h 
b/src/lib/evas/include/evas_private.h
index 9defa26..fcf8128 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -388,6 +388,7 @@ struct _Evas_Public_Data
    Eina_Array     obscuring_objects;
    Eina_Array     temporary_objects;
    Eina_Array     calculate_objects;
+   Eina_Array     clipped_objects; // to the framespace clipper
    Eina_Array     clip_changes;
    Eina_Array     scie_unref_queue;
    Eina_Array     image_unref_queue;

-- 

------------------------------------------------------------------------------
Precog is a next-generation analytics platform capable of advanced
analytics on semi-structured data. The platform includes APIs for building
apps and a phenomenal toolset for data science. Developers can use
our toolset for easy data analysis & visualization. Get a free account!
http://www2.precog.com/precogplatform/slashdotnewsletter

Reply via email to