diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index ce1c286b..f126393a 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -4866,14 +4866,25 @@ shell_output_changed_move_layer(struct desktop_shell *shell, } static void -handle_output_destroy(struct wl_listener *listener, void *data) +shell_output_destroy(struct shell_output *shell_output) { - struct shell_output *shell_output = - container_of(listener, struct shell_output, destroy_listener); struct desktop_shell *shell = shell_output->shell; shell_for_each_layer(shell, shell_output_changed_move_layer, NULL); + if (shell_output->fade.animation) { + weston_view_animation_destroy(shell_output->fade.animation); + shell_output->fade.animation = NULL; + } + + if (shell_output->fade.view) { + /* destroys the view as well */ + weston_surface_destroy(shell_output->fade.view->surface); + } + + if (shell_output->fade.startup_timer) + wl_event_source_remove(shell_output->fade.startup_timer); + if (shell_output->panel_surface) wl_list_remove(&shell_output->panel_surface_listener.link); if (shell_output->background_surface) @@ -4883,6 +4894,15 @@ handle_output_destroy(struct wl_listener *listener, void *data) free(shell_output); } +static void +handle_output_destroy(struct wl_listener *listener, void *data) +{ + struct shell_output *shell_output = + container_of(listener, struct shell_output, destroy_listener); + + shell_output_destroy(shell_output); +} + static void shell_resize_surface_to_output(struct desktop_shell *shell, struct weston_surface *surface, @@ -5014,11 +5034,8 @@ shell_destroy(struct wl_listener *listener, void *data) text_backend_destroy(shell->text_backend); input_panel_destroy(shell); - wl_list_for_each_safe(shell_output, tmp, &shell->output_list, link) { - wl_list_remove(&shell_output->destroy_listener.link); - wl_list_remove(&shell_output->link); - free(shell_output); - } + wl_list_for_each_safe(shell_output, tmp, &shell->output_list, link) + shell_output_destroy(shell_output); wl_list_remove(&shell->output_create_listener.link); wl_list_remove(&shell->output_move_listener.link);