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>
This commit is contained in:
parent
0f206cc5b5
commit
e0f798071c
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user