diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 90013d85a..1f340b79a 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -835,10 +835,21 @@ vt_func(struct weston_compositor *compositor, int event) ec->prev_state = compositor->state; compositor->state = WESTON_COMPOSITOR_SLEEPING; + /* If we have a repaint scheduled (either from a + * pending pageflip or the idle handler), make sure we + * cancel that so we don't try to pageflip when we're + * vt switched away. The SLEEPING state will prevent + * further attemps at repainting. When we switch + * back, we schedule a repaint, which will process + * pending frame callbacks. */ + + wl_list_for_each(output, &ec->base.output_list, link) { + output->repaint_needed = 0; + drm_output_set_cursor(output, NULL); + } + wl_list_for_each(input, &compositor->input_device_list, link) evdev_remove_devices(input); - wl_list_for_each(output, &ec->base.output_list, link) - drm_output_set_cursor(output, NULL); if (drmDropMaster(ec->drm.fd) < 0) fprintf(stderr, "failed to drop master: %m\n"); diff --git a/src/compositor.c b/src/compositor.c index b6facd249..2e0a3f8e3 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -840,9 +840,8 @@ struct weston_frame_callback { }; static void -repaint(void *data, int msecs) +repaint(struct weston_output *output, int msecs) { - struct weston_output *output = data; struct weston_compositor *compositor = output->compositor; struct weston_animation *animation, *next; struct weston_frame_callback *cb, *cnext; @@ -865,7 +864,11 @@ repaint(void *data, int msecs) static void idle_repaint(void *data) { - repaint(data, weston_compositor_get_time()); + struct weston_output *output = data; + + /* An idle repaint may have been cancelled by vt switching away. */ + if (output->repaint_needed) + repaint(output, weston_compositor_get_time()); } WL_EXPORT void