Skip to content

Commit 7738c55

Browse files
committed
Wayland: Fix incorrect window size calculation when transitioning from fullscreen to non-fullscreen with client side decorations
Fixes #8826
1 parent c16e2aa commit 7738c55

File tree

4 files changed

+16
-7
lines changed

4 files changed

+16
-7
lines changed

docs/changelog.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ Detailed list of changes
112112
- A new :opt:`cursor_trail_color` setting to independently control the color of
113113
cursor trails (:pull:`8830`)
114114

115+
- Wayland: Fix incorrect window size calculation when transitioning from
116+
fullscreen to non-fullscreen with client side decorations (:iss:`8826`)
117+
115118
0.42.2 [2025-07-16]
116119
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
117120

glfw/wl_client_side_decorations.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,11 @@ window_is_csd_capable(_GLFWwindow *window) {
570570
return window->decorated && !decs.serverSide && window->wl.xdg.toplevel;
571571
}
572572

573+
bool
574+
csd_should_window_be_decorated(_GLFWwindow *window) {
575+
return window_is_csd_capable(window) && window->monitor == NULL && (window->wl.current.toplevel_states & TOPLEVEL_STATE_FULLSCREEN) == 0;
576+
}
577+
573578
static bool
574579
ensure_csd_resources(_GLFWwindow *window) {
575580
if (!window_is_csd_capable(window)) return false;
@@ -653,18 +658,18 @@ csd_change_title(_GLFWwindow *window) {
653658

654659
void
655660
csd_set_window_geometry(_GLFWwindow *window, int32_t *width, int32_t *height) {
656-
bool has_csd = window_is_csd_capable(window) && decs.titlebar.surface && !(window->wl.current.toplevel_states & TOPLEVEL_STATE_FULLSCREEN);
661+
const bool include_space_for_csd = csd_should_window_be_decorated(window);
657662
bool size_specified_by_compositor = *width > 0 && *height > 0;
658663
if (!size_specified_by_compositor) {
659664
*width = window->wl.user_requested_content_size.width;
660665
*height = window->wl.user_requested_content_size.height;
661666
if (window->wl.xdg.top_level_bounds.width > 0) *width = MIN(*width, window->wl.xdg.top_level_bounds.width);
662667
if (window->wl.xdg.top_level_bounds.height > 0) *height = MIN(*height, window->wl.xdg.top_level_bounds.height);
663-
if (has_csd) *height += decs.metrics.visible_titlebar_height;
668+
if (include_space_for_csd) *height += decs.metrics.visible_titlebar_height;
664669
}
665670
decs.geometry.x = 0; decs.geometry.y = 0;
666671
decs.geometry.width = *width; decs.geometry.height = *height;
667-
if (has_csd) {
672+
if (include_space_for_csd) {
668673
decs.geometry.y = -decs.metrics.visible_titlebar_height;
669674
*height -= decs.metrics.visible_titlebar_height;
670675
}

glfw/wl_client_side_decorations.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ void csd_free_all_resources(_GLFWwindow *window);
1313
bool csd_change_title(_GLFWwindow *window);
1414
void csd_set_window_geometry(_GLFWwindow *window, int32_t *width, int32_t *height);
1515
bool csd_set_titlebar_color(_GLFWwindow *window, uint32_t color, bool use_system_color);
16+
bool csd_should_window_be_decorated(_GLFWwindow *window);
1617
void csd_set_visible(_GLFWwindow *window, bool visible);
1718
void csd_handle_pointer_event(_GLFWwindow *window, int button, int state, struct wl_surface* surface);

glfw/wl_window.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ apply_scale_changes(_GLFWwindow *window, bool resize_framebuffer, bool update_cs
424424
double scale = _glfwWaylandWindowScale(window);
425425
if (resize_framebuffer) resizeFramebuffer(window);
426426
_glfwInputWindowContentScale(window, (float)scale, (float)scale);
427-
if (update_csd) csd_set_visible(window, true); // resize the csd iff the window currently has CSD
427+
if (update_csd) csd_set_visible(window, csd_should_window_be_decorated(window)); // resize the csd iff the window currently has CSD
428428
int buffer_scale = window->wl.fractional_scale ? 1 : (int)scale;
429429
wl_surface_set_buffer_scale(window->wl.surface, buffer_scale);
430430
}
@@ -824,7 +824,7 @@ apply_xdg_configure_changes(_GLFWwindow *window) {
824824
int width = window->wl.pending.width, height = window->wl.pending.height;
825825
csd_set_window_geometry(window, &width, &height);
826826
bool resized = dispatchChangesAfterConfigure(window, width, height);
827-
csd_set_visible(window, !(window->wl.decorations.serverSide || window->monitor || window->wl.current.toplevel_states & TOPLEVEL_STATE_FULLSCREEN));
827+
csd_set_visible(window, csd_should_window_be_decorated(window));
828828
debug("Final window %llu content size: %dx%d resized: %d\n", window->id, width, height, resized);
829829
}
830830

@@ -967,7 +967,7 @@ setXdgDecorations(_GLFWwindow* window)
967967
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);
968968
} else {
969969
window->wl.decorations.serverSide = false;
970-
csd_set_visible(window, window->decorated);
970+
csd_set_visible(window, csd_should_window_be_decorated(window));
971971
}
972972
}
973973

@@ -1632,7 +1632,7 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
16321632
csd_set_window_geometry(window, &w, &h);
16331633
window->wl.width = w; window->wl.height = h;
16341634
resizeFramebuffer(window);
1635-
csd_set_visible(window, true); // resizes the csd iff the window currently has csd
1635+
csd_set_visible(window, csd_should_window_be_decorated(window)); // resizes the csd iff the window currently has csd
16361636
commit_window_surface_if_safe(window);
16371637
inform_compositor_of_window_geometry(window, "SetWindowSize");
16381638
}

0 commit comments

Comments
 (0)