Skip to content

layout: a place's corner is a small bubble peeking past its curve - #578

Merged
foxnne merged 2 commits into
mainfrom
layout/corner-bubble
Oct 18, 2026
Merged

foxnne merged 2 commits into
mainfrom
layout/corner-bubble

Conversation

@foxnne

@foxnne foxnne commented Oct 18, 2026

Copy link
Copy Markdown
Collaborator

Part of fizzyedit/plans#27 (the corner). Follows #555.

What changes

The corner #555 put on every filled place looked wrong on main (seen by the user): "doesn't look like a bubble filling the top right corner, it's got sharp edges, doesn't cover the corner area, and has a weird single corner cut".

The cause: cornerButton runs inside the place's content clip, the card inset by its padding (8 pt). The resting piece and its morph into the button were drawn under that clip, so their top and right 8 pt were cut off. The piece sat inset from the card's edge, and its outer curve, the card's own, never showed. The ring beside it already drew under the card's rect (clipSet(rs.r)) for the same reason. #555's screenshot showed the cut, and it was misread as the shape.

The corner is now what the user asked for after seeing the options: a small round bubble that "moves behind/under the region's rounded corner, peeking out".

  • The bubble: 16 pt round, its centre halfway round the card's top-right curve, so half lies over the card and half peeks past the curve.
  • Square cards: with no curve, its centre is the corner point itself.
  • Clipping: it is drawn, and morphed into the button, under the card's rect outset by half the bubble, not the content clip. It is kept whole inside the window, for a card that runs to the window's edge.
  • Hover: the pointer target is the bubble plus 8 pt round it (CornerPiece.hit). The finger's target is unchanged: 44 pt, centred on the card's outer corner.
  • Glyph: centred in the bubble, smaller.
  • Why not a flush piece: a shape with the card's top and right edges can't be small. Its outer corner has to match the card's radius (24 pt), and a glass corner is held to half its side, so it would be at least 48 pt across.

Prototype by the session working on the history transport (it measured the clip), taken over, checked and finished here.

SDK impact

  • None
  • Core-only or additive: reaches plugins at the next SDK release
  • Fingerprint moved: recorded in sdk/src/version.zig, sdk_version untouched, PR labelled sdk
  • SDK release: bumps sdk_version, lists the sdk PRs since the last sdk-v* tag

Verified

  • macOS:
    • Gates: scripts/check-fmt.sh, zig build, zig build check-web all pass. zig build test: 107/107 steps. zig build test-integration: 54/54 steps, 605/605 tests.
    • On screen (sandbox fizzy, --profile, captured):
      • default rounding: the bubble on the main view's and the panel's curve, peeking out;
      • corner_roundness = 0: the bubble whole, centred on the square corner at the window's edge;
      • hovered, by the prototype's author: the bubble turning into the button.
    • Explorer: the explorer has no card of its own, so its bubble sits on the place's corner over the window's chrome. It marks the place, but reads more detached than on a card.
    • Not seen: a tap on a touchscreen.
    • Unchanged by this PR, not re-checked: the empty-place path (hatch and button), which this doesn't touch (resting is false there); and the 44 pt touch target.
  • Windows:
  • Linux:
  • Web: check-web only

Follow-ups

🤖 Generated with Claude Code

#555's corner piece was drawn under the place's content clip, the card inset by
its padding: its top and right were cut off, so it read as an inset square with
one odd corner. The corner is now a 16 pt round bubble centred halfway round the
card's top-right curve, half over the card and half past it, drawn and morphed
under the card's own rect (outset by half the bubble), kept inside the window.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@foxnne
foxnne merged commit a7e67ff into main Oct 18, 2026
11 checks passed
@foxnne
foxnne deleted the layout/corner-bubble branch October 18, 2026 22:11
foxnne added a commit that referenced this pull request Oct 19, 2026
)

Part of fizzyedit/plans#29 (the liquid edge, step 2 in the comment that
revised it).

## What changes

Glass can belong to a place and merge with that place's edge. This is
the primitive behind controls that come out of a viewport's edge,
metaball-like, without crossing it.

- **`LiquidField.edge`**: a place's outline, its rect and corner radii
(rounded or square). The outside of the place is one more shape in the
field. A shape near the outline runs into it through the field's smooth
minimum, so it joins the edge by a neck. The outline then cuts the
glass's coverage, so none of it crosses.
- **No rim along the cut.** The lens, the rim and the light are worked
out from the joined shape, not the cut one, so where the glass meets the
edge it reads as carrying on past it.
- **Never drawn on its own.** The edge's surface starts 1px outside the
outline (`EDGE_GAP`), so nothing shows along the edge, only the necks
where shapes come near it.
- **Computed only near the shapes.** Each quad is still only its group's
shapes, grown by half the merge width (as far as a neck can reach) and
clipped to the place, so no draw covers the whole place.
- **No new uniforms.** The edge takes the program's last shape slot,
flagged 2 where a shape's round flag goes. Plugins packing with an older
`LiquidField` never set it. A field with an edge holds one shape fewer.
- **`glassBubbles(..., .{ .edge = ... })`** passes it on. Without the
glass program, the bubbles are cut to the edge's rect.
- **`LiquidField.sample`**, the CPU mirror, does the same, line for line
with the HLSL.

The compiled forms (SPIR-V, DXIL, Metal, GLSL) come from CI's `Shaders`
job and are committed in a second commit here.

## SDK impact

- [ ] None
- [x] Core-only or additive: reaches plugins at the next SDK release
- [ ] Fingerprint moved: recorded in `sdk/src/version.zig`,
`sdk_version` untouched, PR labelled `sdk`
- [ ] SDK release: bumps `sdk_version`, lists the `sdk` PRs since the
last `sdk-v*` tag

## Verified

- [x] macOS:
- `zig build`, `zig build check-web`, `zig build test-sdk-version` all
pass.
  - `zig build test`: 109/109 steps.
- `zig build test-integration`: 78/78 steps, 609/609 tests, including a
new test against `LiquidField.sample`: a drop near the edge joins it by
a neck; there's no glass along the edge away from it; a drop pushed past
the edge is cut there, round a curved corner too; and a field with an
edge holds one shape fewer.
  - Not yet seen on screen: needs the compiled shaders, next commit.
- [ ] Windows:
- [ ] Linux:
- [ ] Web: `check-web` only

## Follow-ups

- The arrange corner on it: the next PR, stacked on this one and #578.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant