You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Floating widgets don't follow the desktop when the window is resized #913
Floating (liberated) widgets store a fixed left/top offset in desktop-mode-widgets-geometry. When the browser or PWA window gets wider, the docked widget column slides right with the edge, but floating cards arranged beside it stay where they were. A gap opens between widgets the user placed together.
Before / after widening the PWA window:
Steps to reproduce
Drag a few widgets out of the column and arrange them in a grid next to it.
Make the window wider (or move the dock to a side edge, which narrows the area).
The column moves and the grid doesn't.
Expected
The arrangement stays where the user put it relative to the desktop. A group parked next to the right-hand column follows the right edge, a group on the left stays put, and a centered group stays centered.
Current behavior in code
WidgetLayer.reclampFloating() (src/widgets/layer.ts) only pulls cards back inside the work area when it shrinks. Nothing repositions them when it grows, and a session opened at a different size doesn't adjust either.
Three related cases from running a six-card desktop, in case they belong with this work or a follow-up:
Content that outgrows the saved height. A card whose content changes (a status card listing failing checks, a provenance card listing documents being processed) grows past the height the user saved. The frame then scrolls the card, which hides the controls at its bottom. A widget could opt in to growing its height to fit its content, up to a cap. The reflow here would then move the cards below it down instead of letting them overlap.
A new defaultHeight never reaches a saved layout. When a plugin release changes a card's default height, any saved rect keeps the old one. Storing the default a size was saved against would let a card the user never resized adopt the new default, while a size the user set stays theirs.
A removed widget leaves a hole. When a plugin retires a widget id, its slot stays empty in the arrangement. The grouping in reflow.ts could close the gap a missing group member leaves.
Happy to split these into their own issues, or to extend #914 with (3), which is the smallest.
One path still stores clamped positions after #914, at trunk 572ce21.
Repro (Chromium, trunk 572ce21 built locally, WordPress 7.1):
Float the Note Pad widget at x 120, y 400, 300 by 240, with the desktop at 1024 by 768. The stored geometry is {"x":120,"y":400,"width":300,"height":240} and the stored frame is 1024 by 768.
Resize the viewport to 1024 by 300, where the card no longer fits above the dock. The card is painted at top 0. Storage now holds y: 0 and frame 1024 by 300.
Resize back to 1024 by 768. The card stays at top 20, and storage holds y: 20 with frame 1024 by 768. A reload keeps it at 20. The original y 400 is gone.
Where it happens:reclampFloating() (src/widgets/layer.ts:869-886) runs on every work-area change (subscribed at :769). When a card no longer fits, it clamps the card and calls persistGeometry(id, next) (:883). That runs commitLayout() (:931-942), which saves the clamped geometry as the user's arrangement and the current host size as the layout frame. Later reflows start from that layout. The work area changes on a browser resize (src/work-area/index.ts:441) as well as when the dock moves. The docblock (:864-868) describes the persist as intended, so the next load starts from the corrected spot.
reflowToHost() already avoids this: it clamps only what is painted, under the comment "Clamp what is painted, not what is stored, as a mount does: a grid that meets the edge must come back when the window widens" (:914-920). Only the work-area path still writes the clamp to storage.
Activity
juanlentino commentedon Oct 5, 2026
Three related cases from running a six-card desktop, in case they belong with this work or a follow-up:
defaultHeightnever reaches a saved layout. When a plugin release changes a card's default height, any saved rect keeps the old one. Storing the default a size was saved against would let a card the user never resized adopt the new default, while a size the user set stays theirs.reflow.tscould close the gap a missing group member leaves.Happy to split these into their own issues, or to extend #914 with (3), which is the smallest.
juanlentino commentedon Oct 12, 2026
One path still stores clamped positions after #914, at trunk 572ce21.
Repro (Chromium, trunk 572ce21 built locally, WordPress 7.1):
{"x":120,"y":400,"width":300,"height":240}and the stored frame is1024 by 768.y: 0and frame1024 by 300.y: 20with frame1024 by 768. A reload keeps it at 20. The original y 400 is gone.Where it happens:
reclampFloating()(src/widgets/layer.ts:869-886) runs on every work-area change (subscribed at:769). When a card no longer fits, it clamps the card and callspersistGeometry(id, next)(:883). That runscommitLayout()(:931-942), which saves the clamped geometry as the user's arrangement and the current host size as the layout frame. Later reflows start from that layout. The work area changes on a browser resize (src/work-area/index.ts:441) as well as when the dock moves. The docblock (:864-868) describes the persist as intended, so the next load starts from the corrected spot.reflowToHost()already avoids this: it clamps only what is painted, under the comment "Clamp what is painted, not what is stored, as a mount does: a grid that meets the edge must come back when the window widens" (:914-920). Only the work-area path still writes the clamp to storage.