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;