From 07d4db0c15392f2a48e7d90a6171c9fa3b3f84cb Mon Sep 17 00:00:00 2001 From: HuntedByTheIRS Date: Sun, 5 Jul 2026 21:43:47 -0400 Subject: [PATCH] fix(output): propagate scale changes to all surface types on output reconfiguration - Hook scale re-notification into updatemons() enabled-output loop - Covers: clients, XDG popups, layer surfaces, layer popups - Hook scale into commitlayersurfacenotify() runtime commit path - Remove __attribute__((unused)) from layersurface_update_scale - Add XWayland integer fallback documentation comments --- src/client.c | 4 ++++ src/peachwm.c | 40 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/client.c b/src/client.c index 3859eb0..488722b 100644 --- a/src/client.c +++ b/src/client.c @@ -353,6 +353,9 @@ client_set_fullscreen(Client *c, int fullscreen) void client_set_scale(struct wlr_surface *s, float scale) { + /* XWayland surfaces get ceilf(scale) integer buffer scale — X11 has + * no fractional scale protocol, so wlr_fractional_scale_v1_notify_scale + * is a no-op for them */ wlr_fractional_scale_v1_notify_scale(s, scale); wlr_surface_set_preferred_buffer_scale(s, (int32_t)ceilf(scale)); } @@ -436,6 +439,7 @@ client_update_scale(Client *c) if (fabsf(scale - c->current_scale) > 0.001f) { wlr_fractional_scale_v1_notify_scale(client_surface(c), (double)scale); + /* ceilf for XWayland integer buffer scale fallback — see client_set_scale */ wlr_surface_set_preferred_buffer_scale(client_surface(c), (int32_t)ceilf(scale)); c->current_scale = scale; } diff --git a/src/peachwm.c b/src/peachwm.c index a86a2f3..beb2755 100644 --- a/src/peachwm.c +++ b/src/peachwm.c @@ -909,7 +909,7 @@ static void closemon(Monitor *m) { // ── Compositor Lifecycle ──────────────────────────────────── -__attribute__((unused)) static void +static void layersurface_update_scale(LayerSurface *l) { struct wlr_surface_output *surface_output; @@ -965,6 +965,8 @@ static void commitlayersurfacenotify(struct wl_listener *listener, void *data) { return; l->mapped = layer_surface->surface->mapped; + layersurface_update_scale(l); + if (scene_layer != l->scene->node.parent) { wlr_scene_node_reparent(&l->scene->node, scene_layer); wl_list_remove(&l->link); @@ -4162,6 +4164,42 @@ static void updatemons(struct wl_listener *listener, void *data) { /* Calculate the effective monitor geometry to use for clients */ arrangelayers(m); + + /* Re-notify scale on all surfaces after output layout change */ + { + wl_list_for_each(c, &clients, link) { + if (c->mon != m) + continue; + client_update_scale(c); + if (!client_is_x11(c) && c->surface.xdg) { + struct wlr_xdg_popup *popup; + wl_list_for_each(popup, &c->surface.xdg->popups, link) + wlr_fractional_scale_v1_notify_scale( + popup->base->surface, (double)m->wlr_output->scale); + } + } + for (int i = 0; i < 4; i++) { + LayerSurface *l; + wl_list_for_each(l, &m->layers[i], link) { + layersurface_update_scale(l); + { + struct wlr_scene_node *popup_node; + wl_list_for_each(popup_node, &l->popups->children, link) { + if (popup_node->type != WLR_SCENE_NODE_BUFFER) + continue; + struct wlr_scene_buffer *sb = + wlr_scene_buffer_from_node(popup_node); + struct wlr_scene_surface *ss = + wlr_scene_surface_try_from_buffer(sb); + if (ss && ss->surface) + wlr_fractional_scale_v1_notify_scale( + ss->surface, (double)m->wlr_output->scale); + } + } + } + } + } + /* Don't move clients to the left output when plugging monitors */ arrange(m); /* make sure fullscreen clients have the right size */