Wayland: Fix incorrect window size calculation when transitioning from fullscreen to non-fullscreen with client side decorations
Fixes #8826
This commit is contained in:
parent
c16e2aad05
commit
7738c55c4b
4 changed files with 16 additions and 7 deletions
|
|
@ -112,6 +112,9 @@ Detailed list of changes
|
|||
- A new :opt:`cursor_trail_color` setting to independently control the color of
|
||||
cursor trails (:pull:`8830`)
|
||||
|
||||
- Wayland: Fix incorrect window size calculation when transitioning from
|
||||
fullscreen to non-fullscreen with client side decorations (:iss:`8826`)
|
||||
|
||||
0.42.2 [2025-07-16]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
|||
11
glfw/wl_client_side_decorations.c
vendored
11
glfw/wl_client_side_decorations.c
vendored
|
|
@ -570,6 +570,11 @@ window_is_csd_capable(_GLFWwindow *window) {
|
|||
return window->decorated && !decs.serverSide && window->wl.xdg.toplevel;
|
||||
}
|
||||
|
||||
bool
|
||||
csd_should_window_be_decorated(_GLFWwindow *window) {
|
||||
return window_is_csd_capable(window) && window->monitor == NULL && (window->wl.current.toplevel_states & TOPLEVEL_STATE_FULLSCREEN) == 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
ensure_csd_resources(_GLFWwindow *window) {
|
||||
if (!window_is_csd_capable(window)) return false;
|
||||
|
|
@ -653,18 +658,18 @@ csd_change_title(_GLFWwindow *window) {
|
|||
|
||||
void
|
||||
csd_set_window_geometry(_GLFWwindow *window, int32_t *width, int32_t *height) {
|
||||
bool has_csd = window_is_csd_capable(window) && decs.titlebar.surface && !(window->wl.current.toplevel_states & TOPLEVEL_STATE_FULLSCREEN);
|
||||
const bool include_space_for_csd = csd_should_window_be_decorated(window);
|
||||
bool size_specified_by_compositor = *width > 0 && *height > 0;
|
||||
if (!size_specified_by_compositor) {
|
||||
*width = window->wl.user_requested_content_size.width;
|
||||
*height = window->wl.user_requested_content_size.height;
|
||||
if (window->wl.xdg.top_level_bounds.width > 0) *width = MIN(*width, window->wl.xdg.top_level_bounds.width);
|
||||
if (window->wl.xdg.top_level_bounds.height > 0) *height = MIN(*height, window->wl.xdg.top_level_bounds.height);
|
||||
if (has_csd) *height += decs.metrics.visible_titlebar_height;
|
||||
if (include_space_for_csd) *height += decs.metrics.visible_titlebar_height;
|
||||
}
|
||||
decs.geometry.x = 0; decs.geometry.y = 0;
|
||||
decs.geometry.width = *width; decs.geometry.height = *height;
|
||||
if (has_csd) {
|
||||
if (include_space_for_csd) {
|
||||
decs.geometry.y = -decs.metrics.visible_titlebar_height;
|
||||
*height -= decs.metrics.visible_titlebar_height;
|
||||
}
|
||||
|
|
|
|||
1
glfw/wl_client_side_decorations.h
vendored
1
glfw/wl_client_side_decorations.h
vendored
|
|
@ -13,5 +13,6 @@ void csd_free_all_resources(_GLFWwindow *window);
|
|||
bool csd_change_title(_GLFWwindow *window);
|
||||
void csd_set_window_geometry(_GLFWwindow *window, int32_t *width, int32_t *height);
|
||||
bool csd_set_titlebar_color(_GLFWwindow *window, uint32_t color, bool use_system_color);
|
||||
bool csd_should_window_be_decorated(_GLFWwindow *window);
|
||||
void csd_set_visible(_GLFWwindow *window, bool visible);
|
||||
void csd_handle_pointer_event(_GLFWwindow *window, int button, int state, struct wl_surface* surface);
|
||||
|
|
|
|||
8
glfw/wl_window.c
vendored
8
glfw/wl_window.c
vendored
|
|
@ -424,7 +424,7 @@ apply_scale_changes(_GLFWwindow *window, bool resize_framebuffer, bool update_cs
|
|||
double scale = _glfwWaylandWindowScale(window);
|
||||
if (resize_framebuffer) resizeFramebuffer(window);
|
||||
_glfwInputWindowContentScale(window, (float)scale, (float)scale);
|
||||
if (update_csd) csd_set_visible(window, true); // resize the csd iff the window currently has CSD
|
||||
if (update_csd) csd_set_visible(window, csd_should_window_be_decorated(window)); // resize the csd iff the window currently has CSD
|
||||
int buffer_scale = window->wl.fractional_scale ? 1 : (int)scale;
|
||||
wl_surface_set_buffer_scale(window->wl.surface, buffer_scale);
|
||||
}
|
||||
|
|
@ -824,7 +824,7 @@ apply_xdg_configure_changes(_GLFWwindow *window) {
|
|||
int width = window->wl.pending.width, height = window->wl.pending.height;
|
||||
csd_set_window_geometry(window, &width, &height);
|
||||
bool resized = dispatchChangesAfterConfigure(window, width, height);
|
||||
csd_set_visible(window, !(window->wl.decorations.serverSide || window->monitor || window->wl.current.toplevel_states & TOPLEVEL_STATE_FULLSCREEN));
|
||||
csd_set_visible(window, csd_should_window_be_decorated(window));
|
||||
debug("Final window %llu content size: %dx%d resized: %d\n", window->id, width, height, resized);
|
||||
}
|
||||
|
||||
|
|
@ -967,7 +967,7 @@ setXdgDecorations(_GLFWwindow* window)
|
|||
zxdg_toplevel_decoration_v1_set_mode(window->wl.xdg.decoration, window->decorated ? ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE: ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE);
|
||||
} else {
|
||||
window->wl.decorations.serverSide = false;
|
||||
csd_set_visible(window, window->decorated);
|
||||
csd_set_visible(window, csd_should_window_be_decorated(window));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1632,7 +1632,7 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
|
|||
csd_set_window_geometry(window, &w, &h);
|
||||
window->wl.width = w; window->wl.height = h;
|
||||
resizeFramebuffer(window);
|
||||
csd_set_visible(window, true); // resizes the csd iff the window currently has csd
|
||||
csd_set_visible(window, csd_should_window_be_decorated(window)); // resizes the csd iff the window currently has csd
|
||||
commit_window_surface_if_safe(window);
|
||||
inform_compositor_of_window_geometry(window, "SetWindowSize");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue