From 8b62e2043a721f4b6e6e409280f5acbde73e8dfa Mon Sep 17 00:00:00 2001 From: Neil Roberts Date: Mon, 30 Sep 2013 13:14:47 +0100 Subject: [PATCH] Set new state before emitting wake signal in weston_compsitor_wake The wake handler set up by the shell will try to unlock the screen which works by setting up an animation which fades in the display. The animation is started by first scheduling a repaint. Subsequent repaints are scheduled whenever the previous frame is finished. However in the case of the wake up signal the state is still WESTON_COMPOSITOR_SLEEPING when the animation is started. weston_output_schedule_repaint() ignores attempts to schedule a repaint if the compositor is sleeping which means the animation never gets run and will never complete. The animation gets unstuck and continues if anything else schedules a repaint after the state has been changed so the bug only gets hit in certain conditions. The first wake up creates the lock surface which causes a redraw when the first buffer is attached so the first wake up is always ok. A redraw can be triggered in the subsequent wake ups just by moving the mouse. A good way to trigger the bug is to try to wake up the compositor by pressing the shift key. If you let the compositor go back to sleep after waking it up without unlocking it, the second press of the shift key will not cause a redraw so the animation will not run and it won't fade in. https://bugs.freedesktop.org/show_bug.cgi?id=69719 --- src/compositor.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/compositor.c b/src/compositor.c index 0fa66131..376ddfd8 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -2542,7 +2542,14 @@ weston_compositor_dpms(struct weston_compositor *compositor, WL_EXPORT void weston_compositor_wake(struct weston_compositor *compositor) { - switch (compositor->state) { + uint32_t old_state = compositor->state; + + /* The state needs to be changed before emitting the wake + * signal because that may try to schedule a repaint which + * will not work if the compositor is still sleeping */ + compositor->state = WESTON_COMPOSITOR_ACTIVE; + + switch (old_state) { case WESTON_COMPOSITOR_SLEEPING: weston_compositor_dpms(compositor, WESTON_DPMS_ON); /* fall through */ @@ -2551,7 +2558,6 @@ weston_compositor_wake(struct weston_compositor *compositor) wl_signal_emit(&compositor->wake_signal, compositor); /* fall through */ default: - compositor->state = WESTON_COMPOSITOR_ACTIVE; wl_event_source_timer_update(compositor->idle_source, compositor->idle_time * 1000); }