From 9cf602840d0c49d882d84b6cfedfd44274f1c966 Mon Sep 17 00:00:00 2001 From: Marius Vlad Date: Mon, 14 Feb 2022 22:57:08 +0200 Subject: [PATCH] desktop-shell: Create a distinct view for the fade-out close anim Creates a distinct view, separated from the one created by libweston-desktop, in order to avoid a potential ownership fight with libweston-desktop upon destroying the view. Upon weston_desktop_surface destruction, libweston-desktop inflicts damage on the view it creates, so we need the view to be alive at that time. This wasn't such an issue before because we had different destruction paths but with commit 'desktop-shell: Do not leave views in layers upon shell destruction' all of the destruction paths now land in the same spot + handle compositor tear down. Note as we still use the same weston_surface we'll keep the previous construct where we were taking a reference to keep it alive. The original view is destroyed when releasing the ownership, while for the view created in this patch we handle the destruction directly upon compositor tear down. Signed-off-by: Marius Vlad --- desktop-shell/shell.c | 57 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index 9957e016..377611ff 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -102,6 +102,7 @@ struct shell_surface { struct weston_desktop_surface *desktop_surface; struct weston_view *view; struct weston_surface *wsurface_anim_fade; + struct weston_view *wview_anim_fade; int32_t last_width, last_height; struct desktop_shell *shell; @@ -195,6 +196,10 @@ struct shell_seat { }; +static struct weston_view * +shell_fade_create_fade_out_view(struct shell_surface *shsurf, + struct weston_surface *surface); + static struct desktop_shell * shell_surface_get_shell(struct shell_surface *shsurf); @@ -2229,8 +2234,8 @@ fade_out_done(struct weston_view_animation *animation, void *data) loop = wl_display_get_event_loop(shsurf->shell->compositor->wl_display); - if (weston_view_is_mapped(shsurf->view)) { - weston_view_unmap(shsurf->view); + if (weston_view_is_mapped(shsurf->wview_anim_fade)) { + weston_view_unmap(shsurf->wview_anim_fade); wl_event_loop_add_idle(loop, fade_out_done_idle_cb, shsurf); } } @@ -2349,8 +2354,25 @@ desktop_surface_removed(struct weston_desktop_surface *desktop_surface, pixman_region32_init(&surface->pending.input); pixman_region32_fini(&surface->input); pixman_region32_init(&surface->input); - weston_fade_run(shsurf->view, 1.0, 0.0, 300.0, + + /* its location might have changed, but also might've + * migrated to a different output, so re-compute this + * as the animation requires having the same output as + * the view */ + weston_view_set_output(shsurf->wview_anim_fade, + shsurf->view->output); + weston_view_set_position(shsurf->wview_anim_fade, + shsurf->view->geometry.x, + shsurf->view->geometry.y); + + weston_layer_entry_insert(&shsurf->view->layer_link, + &shsurf->wview_anim_fade->layer_link); + + /* unmap the "original" view */ + weston_view_unmap(shsurf->view); + weston_fade_run(shsurf->wview_anim_fade, 1.0, 0.0, 300.0, fade_out_done, shsurf); + return; } } @@ -2476,9 +2498,13 @@ desktop_surface_committed(struct weston_desktop_surface *desktop_surface, surface->is_mapped = true; /* as we need to survive the weston_surface destruction we'll * need to take another reference */ - if (shsurf->shell->win_close_animation_type == ANIMATION_FADE) + if (shsurf->shell->win_close_animation_type == ANIMATION_FADE) { shsurf->wsurface_anim_fade = weston_surface_ref(surface); + shsurf->wview_anim_fade = + shell_fade_create_fade_out_view(shsurf, surface); + } + return; } @@ -3901,6 +3927,29 @@ shell_fade_create_view_for_output(struct desktop_shell *shell, return curtain; } +static struct weston_view * +shell_fade_create_fade_out_view(struct shell_surface *shsurf, + struct weston_surface *surface) +{ + struct weston_view *view; + struct weston_output *woutput; + + view = weston_view_create(surface); + if (!view) + return NULL; + + woutput = get_focused_output(surface->compositor); + /* set the initial position and output just in case we happen to not + * move it around and just destroy it */ + weston_view_set_output(view, woutput); + weston_view_set_position(view, + shsurf->view->geometry.x, + shsurf->view->geometry.y); + view->is_mapped = true; + + return view; +} + static void shell_fade(struct desktop_shell *shell, enum fade_type type) {