shell: wait for desktop-shell init before fade in
On Raspberry Pi, weston-desktop-shell is so slow to start, that the compositor has time to run the fade-in before the wallpaper is up. The user launching Weston sees the screen flipping to black, the fbcon fading in, and then the desktop popping up. To fix this, wait for the weston-desktop-shell to draw everything before starting the initial fade-in. A new request is added to the private desktop-shell protocol to signal it. If a desktop-shell client does not support the new request, the fade-in happens already at bind time. If weston-desktop-shell crashes, or does not send the 'desktop_ready' request in 15 seconds, the compositor will fade in anyway. This should avoid a blocked screen in case weston-desktop-shell malfunction. shell_fade_startup() does not directly start the fade-in but schedules an idle callback, so that the compositor can process all pending events before starting the fade clock. Otherwise (on RPi) we risk skipping part of the animation. Yes, it is a hack, that should have been done in window.c and weston-desktop-shell instead. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
This commit is contained in:
committed by
Kristian Høgsberg
parent
17bd884bff
commit
79346ab3a5
+105
-14
@@ -156,6 +156,7 @@ struct desktop_shell {
|
||||
struct weston_surface *surface;
|
||||
struct weston_surface_animation *animation;
|
||||
enum fade_type type;
|
||||
struct wl_event_source *startup_timer;
|
||||
} fade;
|
||||
|
||||
uint32_t binding_modifier;
|
||||
@@ -275,6 +276,9 @@ shell_surface_get_shell(struct shell_surface *shsurf);
|
||||
static void
|
||||
surface_rotate(struct shell_surface *surface, struct weston_seat *seat);
|
||||
|
||||
static void
|
||||
shell_fade_startup(struct desktop_shell *shell);
|
||||
|
||||
static bool
|
||||
shell_surface_is_top_fullscreen(struct shell_surface *shsurf)
|
||||
{
|
||||
@@ -2548,12 +2552,22 @@ desktop_shell_set_grab_surface(struct wl_client *client,
|
||||
shell->grab_surface = surface_resource->data;
|
||||
}
|
||||
|
||||
static void
|
||||
desktop_shell_desktop_ready(struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
struct desktop_shell *shell = resource->data;
|
||||
|
||||
shell_fade_startup(shell);
|
||||
}
|
||||
|
||||
static const struct desktop_shell_interface desktop_shell_implementation = {
|
||||
desktop_shell_set_background,
|
||||
desktop_shell_set_panel,
|
||||
desktop_shell_set_lock_surface,
|
||||
desktop_shell_unlock,
|
||||
desktop_shell_set_grab_surface
|
||||
desktop_shell_set_grab_surface,
|
||||
desktop_shell_desktop_ready
|
||||
};
|
||||
|
||||
static enum shell_surface_type
|
||||
@@ -3031,11 +3045,28 @@ shell_fade_done(struct weston_surface_animation *animation, void *data)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
shell_fade(struct desktop_shell *shell, enum fade_type type)
|
||||
static struct weston_surface *
|
||||
shell_fade_create_surface(struct desktop_shell *shell)
|
||||
{
|
||||
struct weston_compositor *compositor = shell->compositor;
|
||||
struct weston_surface *surface;
|
||||
|
||||
surface = weston_surface_create(compositor);
|
||||
if (!surface)
|
||||
return NULL;
|
||||
|
||||
weston_surface_configure(surface, 0, 0, 8192, 8192);
|
||||
weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1.0);
|
||||
wl_list_insert(&compositor->fade_layer.surface_list,
|
||||
&surface->layer_link);
|
||||
pixman_region32_init(&surface->input);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
static void
|
||||
shell_fade(struct desktop_shell *shell, enum fade_type type)
|
||||
{
|
||||
float tint;
|
||||
|
||||
switch (type) {
|
||||
@@ -3053,18 +3084,12 @@ shell_fade(struct desktop_shell *shell, enum fade_type type)
|
||||
shell->fade.type = type;
|
||||
|
||||
if (shell->fade.surface == NULL) {
|
||||
surface = weston_surface_create(compositor);
|
||||
if (!surface)
|
||||
shell->fade.surface = shell_fade_create_surface(shell);
|
||||
if (!shell->fade.surface)
|
||||
return;
|
||||
|
||||
weston_surface_configure(surface, 0, 0, 8192, 8192);
|
||||
weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1.0);
|
||||
surface->alpha = 1.0 - tint;
|
||||
wl_list_insert(&compositor->fade_layer.surface_list,
|
||||
&surface->layer_link);
|
||||
weston_surface_update_transform(surface);
|
||||
shell->fade.surface = surface;
|
||||
pixman_region32_init(&surface->input);
|
||||
shell->fade.surface->alpha = 1.0 - tint;
|
||||
weston_surface_update_transform(shell->fade.surface);
|
||||
}
|
||||
|
||||
if (shell->fade.animation)
|
||||
@@ -3077,6 +3102,67 @@ shell_fade(struct desktop_shell *shell, enum fade_type type)
|
||||
shell_fade_done, shell);
|
||||
}
|
||||
|
||||
static void
|
||||
do_shell_fade_startup(void *data)
|
||||
{
|
||||
struct desktop_shell *shell = data;
|
||||
|
||||
shell_fade(shell, FADE_IN);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_fade_startup(struct desktop_shell *shell)
|
||||
{
|
||||
struct wl_event_loop *loop;
|
||||
|
||||
if (!shell->fade.startup_timer)
|
||||
return;
|
||||
|
||||
wl_event_source_remove(shell->fade.startup_timer);
|
||||
shell->fade.startup_timer = NULL;
|
||||
|
||||
loop = wl_display_get_event_loop(shell->compositor->wl_display);
|
||||
wl_event_loop_add_idle(loop, do_shell_fade_startup, shell);
|
||||
}
|
||||
|
||||
static int
|
||||
fade_startup_timeout(void *data)
|
||||
{
|
||||
struct desktop_shell *shell = data;
|
||||
|
||||
shell_fade_startup(shell);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
shell_fade_init(struct desktop_shell *shell)
|
||||
{
|
||||
/* Make compositor output all black, and wait for the desktop-shell
|
||||
* client to signal it is ready, then fade in. The timer triggers a
|
||||
* fade-in, in case the desktop-shell client takes too long.
|
||||
*/
|
||||
|
||||
struct wl_event_loop *loop;
|
||||
|
||||
if (shell->fade.surface != NULL) {
|
||||
weston_log("%s: warning: fade surface already exists\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
shell->fade.surface = shell_fade_create_surface(shell);
|
||||
if (!shell->fade.surface)
|
||||
return;
|
||||
|
||||
weston_surface_update_transform(shell->fade.surface);
|
||||
weston_surface_damage(shell->fade.surface);
|
||||
|
||||
loop = wl_display_get_event_loop(shell->compositor->wl_display);
|
||||
shell->fade.startup_timer =
|
||||
wl_event_loop_add_timer(loop, fade_startup_timeout, shell);
|
||||
wl_event_source_timer_update(shell->fade.startup_timer, 15000);
|
||||
}
|
||||
|
||||
static void
|
||||
idle_handler(struct wl_listener *listener, void *data)
|
||||
{
|
||||
@@ -3444,6 +3530,7 @@ desktop_shell_sigchld(struct weston_process *process, int status)
|
||||
|
||||
weston_log("weston-desktop-shell died, respawning...\n");
|
||||
launch_desktop_shell_process(shell);
|
||||
shell_fade_startup(shell);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3497,6 +3584,10 @@ bind_desktop_shell(struct wl_client *client,
|
||||
if (client == shell->child.client) {
|
||||
resource->destroy = unbind_desktop_shell;
|
||||
shell->child.desktop_shell = resource;
|
||||
|
||||
if (version < 2)
|
||||
shell_fade_startup(shell);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4391,7 +4482,7 @@ module_init(struct weston_compositor *ec,
|
||||
|
||||
shell_add_bindings(ec, shell);
|
||||
|
||||
shell_fade(shell, FADE_IN);
|
||||
shell_fade_init(shell);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user