Fix glitch resizing windows with LIBDECOR on Wayland

The window contents and the window boarders were noticeably out of sync
when resizing the window quickly.

Resolve by keeping the current size as-is, rely on deferred handling
of the pending window size to apply the new size along with the contents.
This commit is contained in:
Campbell Barton 2023-10-06 17:25:10 +11:00
parent b9d300380f
commit e1dac0b122
1 changed files with 26 additions and 12 deletions

View File

@ -1084,6 +1084,11 @@ static void libdecor_frame_handle_configure(libdecor_frame *frame,
# ifdef USE_EVENT_BACKGROUND_THREAD
std::lock_guard lock_frame_guard{static_cast<GWL_Window *>(data)->frame_pending_mutex};
const bool is_main_thread = [data] {
GWL_Window *win = static_cast<GWL_Window *>(data);
const GHOST_SystemWayland *system = win->ghost_system;
return system->main_thread_id == std::this_thread::get_id();
}();
# endif
GWL_WindowFrame *frame_pending = &static_cast<GWL_Window *>(data)->frame_pending;
@ -1109,6 +1114,17 @@ static void libdecor_frame_handle_configure(libdecor_frame *frame,
frame_pending->size[0] = size_next[0] * scale;
frame_pending->size[1] = size_next[1] * scale;
}
# ifdef USE_EVENT_BACKGROUND_THREAD
/* NOTE(@ideasman42): when running from the event handling thread,
* don't apply the new window size back to LIBDECOR, otherwise the window content
* (which uses a deferred update) and the window get noticeably out of sync.
* Rely on the new `frame_pending->size` to resize the window later. */
if (is_main_thread == false) {
size_next[0] = win->frame.size[0] / scale;
size_next[1] = win->frame.size[1] / scale;
}
# endif
}
/* Set the state. */
@ -1121,22 +1137,10 @@ static void libdecor_frame_handle_configure(libdecor_frame *frame,
}
}
/* Commit the changes. */
{
GWL_Window *win = static_cast<GWL_Window *>(data);
WGL_LibDecor_Window &decor = *win->libdecor;
libdecor_state *state = libdecor_state_new(UNPACK2(size_next));
libdecor_frame_commit(frame, state, configuration);
libdecor_state_free(state);
decor.initial_configure_seen = true;
}
/* Apply the changes. */
{
GWL_Window *win = static_cast<GWL_Window *>(data);
# ifdef USE_EVENT_BACKGROUND_THREAD
const GHOST_SystemWayland *system = win->ghost_system;
const bool is_main_thread = system->main_thread_id == std::this_thread::get_id();
if (!is_main_thread) {
gwl_window_pending_actions_tag(win, PENDING_WINDOW_FRAME_CONFIGURE);
}
@ -1146,6 +1150,16 @@ static void libdecor_frame_handle_configure(libdecor_frame *frame,
gwl_window_frame_update_from_pending_no_lock(win);
}
}
/* Commit the changes. */
{
GWL_Window *win = static_cast<GWL_Window *>(data);
WGL_LibDecor_Window &decor = *win->libdecor;
libdecor_state *state = libdecor_state_new(UNPACK2(size_next));
libdecor_frame_commit(frame, state, configuration);
libdecor_state_free(state);
decor.initial_configure_seen = true;
}
}
static void libdecor_frame_handle_close(libdecor_frame * /*frame*/, void *data)