From f95ee3e8715bccca4048cb8cfdbb3072f84939cd Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Oct 2023 09:52:04 +1100 Subject: [PATCH] Fix incorrect window decoration size with Wayland & libdecor on startup When fractional scaling was used with libdecor the window decorations would not match the window size on startup, drawing small and on top of Blender's window. While there are still glitches with fractional-scaling & libdecor (which doesn't support fractional scaling), see #109194 this at least resolves one of the worst issues. --- intern/ghost/intern/GHOST_WindowWayland.cc | 29 +++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/intern/ghost/intern/GHOST_WindowWayland.cc b/intern/ghost/intern/GHOST_WindowWayland.cc index b7315a9b399..7027e976de0 100644 --- a/intern/ghost/intern/GHOST_WindowWayland.cc +++ b/intern/ghost/intern/GHOST_WindowWayland.cc @@ -50,6 +50,18 @@ /* Logging, use `ghost.wl.*` prefix. */ #include "CLG_log.h" +/** + * NOTE(@ideasman42): Workaround a bug with fractional scaling with LIBDECOR. + * When fractional scaling is used the GHOST window uses a buffer-scale of 1 + * with the actual scale compensated for by a #wp_viewport. + * + * This causes various glitches between the GHOST window and LIBDECOR. + * While this hack doesn't resolve all of them it does fix the problem where a new windows + * decorations don't match the window, sometimes causing a delayed decrease in the windows size. + * See #109194 for related issues. + */ +#define USE_LIBDECOR_FRACTIONAL_SCALE_HACK + static const xdg_activation_token_v1_listener *xdg_activation_listener_get(); static constexpr size_t base_dpi = 96; @@ -493,6 +505,20 @@ static bool gwl_window_viewport_set(GWL_Window *win, else { wl_surface_commit(win->wl.surface); } + +#if defined(WITH_GHOST_WAYLAND_LIBDECOR) && defined(USE_LIBDECOR_FRACTIONAL_SCALE_HACK) + /* NOTE(@ideasman42): it's important this only runs when enabling the viewport + * since there is a bug with LIBDECOR not supporting the switch from non-fractional + * to fractional scaled surfaces. */ + if (use_libdecor) { + WGL_LibDecor_Window &decor = *win->libdecor; + libdecor_state *state = libdecor_state_new( + gwl_window_fractional_from_viewport_round(win->frame, win->frame.size[0]), + gwl_window_fractional_from_viewport_round(win->frame, win->frame.size[1])); + libdecor_frame_commit(decor.frame, state, nullptr); + libdecor_state_free(state); + } +#endif } return true; @@ -1367,7 +1393,8 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system, * is detected and enabled. Unfortunately, it doesn't seem possible to receive the * #wp_fractional_scale_v1_listener::preferred_scale information before the window is created * So leave the buffer scaled up because there is no *guarantee* the fractional scaling support - * will run which could result in an incorrect buffer scale. */ + * will run which could result in an incorrect buffer scale. + * Leaving the buffer scale is necessary for #USE_LIBDECOR_FRACTIONAL_SCALE_HACK to work too. */ window_->frame.buffer_scale = outputs_uniform_scale_or_default( system_->outputs_get(), 1, nullptr); window_->frame_pending.buffer_scale = window_->frame.buffer_scale;