From 063a882dc7bb39fbda9ab8cd124a0f30e076e22b Mon Sep 17 00:00:00 2001 From: MoD Date: Sat, 2 Mar 2013 23:43:57 +0000 Subject: [PATCH] toytoolkit: avoid redrawing a window between maximize and configure Resolve a bad frame visible when maximizing toytoolkit programs with the the maximize button in decorations. Windows now use wl_display.sync requests to wait for a maximize to finish before drawing again, following suggestions from http://lists.freedesktop.org/archives/wayland-devel/2013-February/007650.html --- clients/window.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/clients/window.c b/clients/window.c index e3e8eb59..d9c4e435 100644 --- a/clients/window.c +++ b/clients/window.c @@ -224,6 +224,7 @@ struct window { int resizing; int fullscreen_method; + int configure_requests; window_key_handler_t key_handler; window_keyboard_focus_handler_t keyboard_focus_handler; @@ -3376,6 +3377,8 @@ void window_schedule_redraw(struct window *window) { window->redraw_needed = 1; + if (window->configure_requests) + return; if (!window->redraw_scheduled) { window->redraw_task.run = idle_redraw; display_defer(window->display, &window->redraw_task); @@ -3389,6 +3392,41 @@ window_is_fullscreen(struct window *window) return window->type == TYPE_FULLSCREEN; } +static void +configure_request_completed(void *data, struct wl_callback *callback, uint32_t time) +{ + struct window *window = data; + + wl_callback_destroy(callback); + window->configure_requests--; + + if (!window->configure_requests) + window_schedule_redraw(window); +} + +static struct wl_callback_listener configure_request_listener = { + configure_request_completed, +}; + +static void +window_defer_redraw_until_configure(struct window* window) +{ + struct wl_callback *callback; + + if (window->redraw_scheduled) { + wl_list_remove(&window->redraw_task.link); + window->redraw_scheduled = 0; + } + if (window->frame_cb) { + wl_callback_destroy(window->frame_cb); + window->frame_cb = 0; + } + + callback = wl_display_sync(window->display->display); + wl_callback_add_listener(callback, &configure_request_listener, window); + window->configure_requests++; +} + void window_set_fullscreen(struct window *window, int fullscreen) { @@ -3407,6 +3445,7 @@ window_set_fullscreen(struct window *window, int fullscreen) wl_shell_surface_set_fullscreen(window->shell_surface, window->fullscreen_method, 0, NULL); + window_defer_redraw_until_configure (window); } else { if (window->saved_type == TYPE_MAXIMIZED) { window_set_maximized(window, 1); @@ -3447,9 +3486,11 @@ window_set_maximized(struct window *window, int maximized) window->saved_allocation = window->main_surface->allocation; wl_shell_surface_set_maximized(window->shell_surface, NULL); window->type = TYPE_MAXIMIZED; + window_defer_redraw_until_configure(window); } else if (window->type == TYPE_FULLSCREEN) { wl_shell_surface_set_maximized(window->shell_surface, NULL); window->type = TYPE_MAXIMIZED; + window_defer_redraw_until_configure(window); } else { wl_shell_surface_set_toplevel(window->shell_surface); window->type = TYPE_TOPLEVEL; @@ -3658,6 +3699,7 @@ window_create_internal(struct display *display, window->type = type; window->fullscreen_method = WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT; + window->configure_requests = 0; if (display->argb_device) #ifdef HAVE_CAIRO_EGL