add a 'mapped' field to weston_surface so that it is initialized
to 0 on surface creation, and to 1 when the surface output is set.
One can manually increase it to make the surface remain visible
after an attach with a NULL buffer, so that it can animate it and
call weston_surface_unmap at the end. weston_surface_unmap decreases
the value of mapped and if it reaches 0 it actually unmaps the surface.
Instead of setting surface->output directly it is now preferable to
set a surface's output via the new function weston_surface_set_output,
which checks if it was mapped before, and if not it increases the
mapped value.
---
 src/compositor.c | 24 +++++++++++++++++++++---
 src/compositor.h |  5 +++++
 src/shell.c      | 14 +++++++-------
 3 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index 8da348a..cae74e1 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -299,6 +299,7 @@ weston_surface_create(struct weston_compositor *compositor)
        surface->pending.buffer_transform = surface->buffer_transform;
        surface->pending.buffer_scale = surface->buffer_scale;
        surface->output = NULL;
+       surface->mapped = 0;
        surface->plane = &compositor->primary_plane;
        surface->pending.newly_attached = 0;
 
@@ -567,7 +568,7 @@ weston_surface_assign_output(struct weston_surface *es)
        }
        pixman_region32_fini(&region);
 
-       es->output = new_output;
+       weston_surface_set_output(es, new_output);
        weston_surface_update_output_mask(es, mask);
 }
 
@@ -885,6 +886,16 @@ weston_surface_set_transform_parent(struct weston_surface 
*surface,
        weston_surface_geometry_dirty(surface);
 }
 
+WL_EXPORT void
+weston_surface_set_output(struct weston_surface *surface,
+                                                 struct weston_output *output)
+{
+       if (!weston_surface_is_mapped(surface))
+               ++surface->mapped;
+
+       surface->output = output;
+}
+
 WL_EXPORT int
 weston_surface_is_mapped(struct weston_surface *surface)
 {
@@ -976,7 +987,11 @@ weston_surface_unmap(struct weston_surface *surface)
 {
        struct weston_seat *seat;
 
+       if (--surface->mapped > 0)
+               return;
+
        weston_surface_damage_below(surface);
+       surface->mapped = 0;
        surface->output = NULL;
        wl_list_remove(&surface->layer_link);
 
@@ -1137,9 +1152,11 @@ weston_surface_attach(struct weston_surface *surface,
        if (!buffer) {
                if (weston_surface_is_mapped(surface))
                        weston_surface_unmap(surface);
+       } else {
+               // Keep the old buffer around, so that it can be used to do
+               // unmap animations by the shell
+               surface->compositor->renderer->attach(surface, buffer);
        }
-
-       surface->compositor->renderer->attach(surface, buffer);
 }
 
 WL_EXPORT void
@@ -2008,6 +2025,7 @@ subsurface_configure(struct weston_surface *surface, 
int32_t dx, int32_t dy,
                assert(!wl_list_empty(&compositor->output_list));
                surface->output = container_of(compositor->output_list.next,
                                               struct weston_output, link);
+               ++surface->mapped;
        }
 }
 
diff --git a/src/compositor.h b/src/compositor.h
index 6db3c61..891db0e 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -710,6 +710,7 @@ struct weston_surface {
        float alpha;                     /* part of geometry, see below */
        struct weston_plane *plane;
        int32_t ref_count;
+       int32_t mapped;
 
        void *renderer_state;
 
@@ -851,6 +852,10 @@ weston_surface_buffer_width(struct weston_surface 
*surface);
 int32_t
 weston_surface_buffer_height(struct weston_surface *surface);
 
+void
+weston_surface_set_output(struct weston_surface *surface,
+                                                 struct weston_output *output);
+
 WL_EXPORT void
 weston_surface_to_buffer_float(struct weston_surface *surface,
                               float x, float y, float *bx, float *by);
diff --git a/src/shell.c b/src/shell.c
index 8f2be78..88685d0 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -1790,7 +1790,7 @@ shell_configure_fullscreen(struct shell_surface *shsurf)
        wl_list_remove(&shsurf->fullscreen.black_surface->layer_link);
        wl_list_insert(&surface->layer_link,
                       &shsurf->fullscreen.black_surface->layer_link);
-       shsurf->fullscreen.black_surface->output = output;
+       weston_surface_set_output(shsurf->fullscreen.black_surface, output);
 
        surface_subsurfaces_boundingbox(surface, &surf_x, &surf_y,
                                        &surf_width, &surf_height);
@@ -2149,7 +2149,7 @@ shell_map_popup(struct shell_surface *shsurf)
        struct weston_surface *es = shsurf->surface;
        struct weston_surface *parent = shsurf->parent;
 
-       es->output = parent->output;
+       weston_surface_set_output(es, parent->output);
 
        weston_surface_set_transform_parent(es, parent);
        weston_surface_set_position(es, shsurf->popup.x, shsurf->popup.y);
@@ -2453,7 +2453,7 @@ desktop_shell_set_background(struct wl_client *client,
 
        surface->configure = background_configure;
        surface->configure_private = shell;
-       surface->output = wl_resource_get_user_data(output_resource);
+       weston_surface_set_output(surface, 
wl_resource_get_user_data(output_resource));
        desktop_shell_send_configure(resource, 0,
                                     surface_resource,
                                     surface->output->width,
@@ -2487,7 +2487,7 @@ desktop_shell_set_panel(struct wl_client *client,
 
        surface->configure = panel_configure;
        surface->configure_private = shell;
-       surface->output = wl_resource_get_user_data(output_resource);
+       weston_surface_set_output(surface, 
wl_resource_get_user_data(output_resource));
        desktop_shell_send_configure(resource, 0,
                                     surface_resource,
                                     surface->output->width,
@@ -3434,7 +3434,7 @@ map(struct desktop_shell *shell, struct weston_surface 
*surface,
        if (surface_type != SHELL_SURFACE_NONE) {
                weston_surface_update_transform(surface);
                if (surface_type == SHELL_SURFACE_MAXIMIZED)
-                       surface->output = shsurf->output;
+                       weston_surface_set_output(surface, shsurf->output);
        }
 
        switch (surface_type) {
@@ -3509,7 +3509,7 @@ configure(struct desktop_shell *shell, struct 
weston_surface *surface,
                weston_surface_update_transform(surface);
 
                if (surface_type == SHELL_SURFACE_MAXIMIZED)
-                       surface->output = shsurf->output;
+                       weston_surface_set_output(surface, shsurf->output);
        }
 }
 
@@ -3685,7 +3685,7 @@ screensaver_set_surface(struct wl_client *client,
 
        surface->configure = screensaver_configure;
        surface->configure_private = shell;
-       surface->output = output;
+       weston_surface_set_output(surface, output);
 }
 
 static const struct screensaver_interface screensaver_implementation = {
-- 
1.8.3.4

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to