Skip to content

Floating widgets don't follow the desktop when the window is resized #913

Closed

Description

@juanlentino

What happens

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:

Image Image

Steps to reproduce

  1. Drag a few widgets out of the column and arrange them in a grid next to it.
  2. Make the window wider (or move the dock to a side edge, which narrows the area).
  3. 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.

Activity

  1. juanlentino commented on Oct 5, 2026

    @juanlentino
    ContributorAuthor

    Three related cases from running a six-card desktop, in case they belong with this work or a follow-up:

    1. 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.
    2. 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.
    3. 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.

  2. juanlentino commented on Oct 12, 2026

    @juanlentino
    ContributorAuthor

    One path still stores clamped positions after #914, at trunk 572ce21.

    Repro (Chromium, trunk 572ce21 built locally, WordPress 7.1):

    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.
    2. Resize the viewport to 1024 by 500. The reflow paints the card at top 132. Storage is unchanged (y 400, frame 768). This part works as Widgets: reflow floating cards when the desktop resizes #914 intends.
    3. 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.
    4. 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions