diff options
author | Martin Minarik <minarik11@student.fiit.stuba.sk> | 2013-01-24 16:48:03 +0100 |
---|---|---|
committer | David Herrmann <dh.herrmann@googlemail.com> | 2013-01-24 20:13:09 +0100 |
commit | e0f798071c786e4b2e622d18d1cd1ab0dba585ae (patch) | |
tree | c41a3d7fffda454cf47a2ab9ba5f291406db849b /src | |
parent | 0f206cc5b58685c4b4cb9e17374f6265b56cc038 (diff) |
wlt: toolkit: fix resize window stuck in need_resize=true
The problem is that:
wnd->w_frame contains a number
and
wnd->need_frame=true
Therefore schedule_frame() doesn't schedule the callback.
But deleting these checks causes flicker. Further redesign
of the frame sheduling was necessary.
4. frame_callback()
3. do_frame()
3. idle_frame()
2. schedule_frame()
1. wlt_window_set_size()
Please, observe the need_resize variable.
-------------------------------------------------------------------------------
BAD (window stuck on resize):
$3 = {ref = 1, list = {next = 0x659c70, prev = 0x659c70},
buffer_attached = true, skip_damage = false, need_resize = true,
w_frame = 0x70d9b0, widget_list = {next = 0x686cb0, prev = 0x6b54d0}}
OK (window not stuck on resize):
$3 = {ref = 1, list = {next = 0x240cc70, prev = 0x240cc70},
buffer_attached = true, skip_damage = false, need_resize = false,
w_frame = 0x241bb10, widget_list = {next = 0x2439cb0, prev = 0x2468560}}
-----------------------------------------------------------------------------------
This is the basic idea:
-> time ->
frame callbacks() * * * * * *
wnd->idle_pending ------ --------- --------- -------- ---------------------
wnd->need_frame --- --- --- --- --- ------ ---
schedule_frame() * * * * * * * **
idle_frame() * * * * * * * *
This design follows similiar design in weston/clients/window.c
Kmscon Weston
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
wlt_window_do_redraw() ~~~ shm_surface_swap()
do_frame() ~~~~~~~~~~~~~~~ window_attach_surface()
wnd->idle_pending ~~~~~~~~ window->redraw_scheduled
frame_callback() ~~~~~~~~ frame_callback()
do_frame() ~~~~~~~~~~~~~~ idle_redraw()
wlt_window_set_size()
wlt_window_schedule_redraw()
schedule_frame() ~~~~~~~~ window_schedule_redraw()
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/wlt_toolkit.c | 34 |
1 files changed, 14 insertions, 20 deletions
diff --git a/src/wlt_toolkit.c b/src/wlt_toolkit.c index 41f6d0c..0aa0a97 100644 --- a/src/wlt_toolkit.c +++ b/src/wlt_toolkit.c @@ -126,7 +126,6 @@ struct wlt_window { bool buffer_attached; bool skip_damage; bool need_resize; - bool need_redraw; bool need_frame; bool idle_pending; unsigned int new_width; @@ -1305,7 +1304,7 @@ static void wlt_window_do_redraw(struct wlt_window *wnd, } static int resize_window(struct wlt_window *wnd, unsigned int width, - unsigned int height, bool force_redraw) + unsigned int height) { struct shl_dlist *iter; struct wlt_widget *widget; @@ -1351,8 +1350,7 @@ static int resize_window(struct wlt_window *wnd, unsigned int width, if (width == wnd->buffer.width && height == wnd->buffer.height) { - if (force_redraw) - wlt_window_do_redraw(wnd, width, height); + wlt_window_do_redraw(wnd, width, height); return 0; } @@ -1420,26 +1418,18 @@ static const struct wl_callback_listener frame_callback_listener = { static void do_frame(struct wlt_window *wnd) { - bool force; - - wnd->idle_pending = false; ev_eloop_unregister_idle_cb(wnd->disp->eloop, idle_frame, wnd, EV_NORMAL); if (wnd->need_resize) { - force = wnd->need_redraw; wnd->need_frame = true; wnd->need_resize = false; - wnd->need_redraw = false; wnd->w_frame = wl_surface_frame(wnd->w_surface); wl_callback_add_listener(wnd->w_frame, &frame_callback_listener, wnd); - resize_window(wnd, wnd->new_width, wnd->new_height, force); - } - - if (wnd->need_redraw) { + resize_window(wnd, wnd->new_width, wnd->new_height); + } else { wnd->need_frame = true; - wnd->need_redraw = false; wnd->w_frame = wl_surface_frame(wnd->w_surface); wl_callback_add_listener(wnd->w_frame, &frame_callback_listener, wnd); @@ -1448,6 +1438,8 @@ static void do_frame(struct wlt_window *wnd) } } +static void schedule_frame(struct wlt_window *wnd); + static void frame_callback(void *data, struct wl_callback *w_callback, uint32_t time) { @@ -1455,9 +1447,10 @@ static void frame_callback(void *data, struct wl_callback *w_callback, wl_callback_destroy(w_callback); wnd->w_frame = NULL; - wnd->need_frame = false; - do_frame(wnd); + wnd->idle_pending = false; + if (wnd->need_frame) + schedule_frame(wnd); } static void idle_frame(struct ev_eloop *eloop, void *unused, void *data) @@ -1496,10 +1489,12 @@ static void schedule_frame(struct wlt_window *wnd) { int ret; - if (!wnd || wnd->w_frame) + if (!wnd) return; - if (wnd->need_frame || wnd->idle_pending) + wnd->need_frame = true; + + if (wnd->idle_pending) return; ret = ev_eloop_register_idle_cb(wnd->disp->eloop, idle_frame, wnd, @@ -1592,7 +1587,7 @@ int wlt_display_create_window(struct wlt_display *disp, &shell_surface_listener, wnd); wl_shell_surface_set_toplevel(wnd->w_shell_surface); - ret = resize_window(wnd, width, height, true); + ret = resize_window(wnd, width, height); if (ret) goto err_shell_surface; @@ -1677,7 +1672,6 @@ void wlt_window_schedule_redraw(struct wlt_window *wnd) if (!wnd) return; - wnd->need_redraw = true; schedule_frame(wnd); } |