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
This commit is contained in:
2026-07-05 21:43:47 -04:00
parent 7dfed7bd27
commit 07d4db0c15
2 changed files with 43 additions and 1 deletions
+4
View File
@@ -353,6 +353,9 @@ client_set_fullscreen(Client *c, int fullscreen)
void void
client_set_scale(struct wlr_surface *s, float scale) 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_fractional_scale_v1_notify_scale(s, scale);
wlr_surface_set_preferred_buffer_scale(s, (int32_t)ceilf(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) { if (fabsf(scale - c->current_scale) > 0.001f) {
wlr_fractional_scale_v1_notify_scale(client_surface(c), (double)scale); 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)); wlr_surface_set_preferred_buffer_scale(client_surface(c), (int32_t)ceilf(scale));
c->current_scale = scale; c->current_scale = scale;
} }
+39 -1
View File
@@ -909,7 +909,7 @@ static void closemon(Monitor *m) {
// ── Compositor Lifecycle ──────────────────────────────────── // ── Compositor Lifecycle ────────────────────────────────────
__attribute__((unused)) static void static void
layersurface_update_scale(LayerSurface *l) layersurface_update_scale(LayerSurface *l)
{ {
struct wlr_surface_output *surface_output; struct wlr_surface_output *surface_output;
@@ -965,6 +965,8 @@ static void commitlayersurfacenotify(struct wl_listener *listener, void *data) {
return; return;
l->mapped = layer_surface->surface->mapped; l->mapped = layer_surface->surface->mapped;
layersurface_update_scale(l);
if (scene_layer != l->scene->node.parent) { if (scene_layer != l->scene->node.parent) {
wlr_scene_node_reparent(&l->scene->node, scene_layer); wlr_scene_node_reparent(&l->scene->node, scene_layer);
wl_list_remove(&l->link); 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 */ /* Calculate the effective monitor geometry to use for clients */
arrangelayers(m); 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 */ /* Don't move clients to the left output when plugging monitors */
arrange(m); arrange(m);
/* make sure fullscreen clients have the right size */ /* make sure fullscreen clients have the right size */