feat: overlay cols/rows sizing, anchor positioning, and canvas read-back#281
feat: overlay cols/rows sizing, anchor positioning, and canvas read-back#281umputun wants to merge 20 commits into
Conversation
…t canvas measurement)
Deploying agterm with
|
| Latest commit: |
8729b28
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://03d980f1.agterm.pages.dev |
| Branch Preview URL: | https://overlay-anchor-sizing.agterm.pages.dev |
umputun
left a comment
There was a problem hiding this comment.
found 4 blocking issues and 2 nits.
blocking
-
agterm/Control/ControlServer.swift:574readscanvasCols/canvasRowsfrom the currently hosted Ghostty surface. Dashboard and terminal zoom reparent that surface and can change its frame or font, while a control-opened overlay still targets the normal detail pane.treecan report dashboard-cell or zoom-layer dimensions instead of the overlay canvas. Keep the normal detail canvas measurement separately and use it for read-back; add dashboard and zoom regression cases. -
agtermCore/Sources/agtermCore/OverlayLayout.swift:144sums two complete split-surface widths and divides by one cell width. Both widths include terminal padding, but a hypothetical full-width overlay has only one padding allocation, so the extra padding can turn into one or more columns and violate the documented "never over-reports" contract. Subtract one primary-derived horizontal remainder before flooring and add a nonzero-padding boundary test. -
agtermUITests/ControlOverlaySplitUITests.swift:925waits only for requestedoverlayCols/overlayRowsafter a percent-to-cells resize. Those fields update synchronously, so the test can pass whileoverlayColsApplied/overlayRowsAppliedremain stale. Poll until the applied grid converges after resize and compare it with a newstty sizeobservation. -
agtermUITests/ControlOverlaySplitUITests.swift:783exercises canvas read-back only without a split. The visible-split and secondary-pane-maximized branches insessionCanvasGridhave no end-to-end coverage, and the unit tests cannot verify surface selection or live libghostty widths. Add UI cases for both branches and assert the reported canvas against an overlay realized from that grid.
nits
-
agtermCore/Sources/agtermCore/OverlayLayout.swift:14still saysOverlayAnchormaps to SwiftUIAlignment. The implementation now computes an origin inpanelRectand uses a constant top-leading container with padding. Update the comment. -
agtermCore/Sources/agtermCore/OverlayArgs.swift:6exportsOverlaySizeParse,OverlayAnchorParse,OverlayArgs.Command,parseSize, andparseAnchor, but production code uses only the public resolvers. Keep the intermediate parser surface internal or private; the tests already use@testable import.
|
after careful consideration, I decided to drop this experiment and won't merge it. the functionality has real but very narrow use cases. I wanted exact overlay sizing based on the actual terminal content size instead of a percentage. The implementation adds too much complexity for that benefit, especially around cell metrics, split and reparented layouts, state read-back, and UI testing. |
adds precise sizing and positioning to floating session overlays, driven over the control channel.
Sizing.
session overlay open/resizegain--cols N --rows Mto size an overlay to an exact terminal grid (from the surface cell metrics, with a px-to-point conversion for Retina), as an alternative to the uniform--size-percent. An oversized request clamps to the whole cells that fit.Positioning.
--anchor <pos>places a floating overlay at one of nine spots (top-leftthroughbottom-right, defaultcenter). Every floating overlay is inset by a uniform one-line-height safe-area margin on all four sides, so a full-width band is inset left/right the same as top/bottom.Read-back on
tree. The session node now reports the overlay's requested grid (overlayCols/overlayRows), the realized grid after clamping (overlayColsApplied/overlayRowsApplied), theoverlayAnchor, and the terminal content area (canvasCols/canvasRows) so a script can size an overlay as a fraction of the canvas. For a top band at 30% height: readcanvasCols/canvasRows, thenoverlay open <cmd> --cols $canvasCols --rows $((canvasRows*30/100)) --anchor top.Behavior change.
overlay open --size-percentnow errors on an out-of-range value instead of silently clamping, matchingresize.no new control commands (both capabilities ride the existing
session.overlay.open/resize), so the command count is unchanged, and overlay state stays live-only. The host-free sizing, anchor, and validation logic lives inagtermCore(OverlayLayout,OverlayArgs) with the app target as a thin adapter; the agent skill,site/commands.html,site/docs.html,README.md, and.claude/rules/control-api.mdare updated to match.covered by host-free unit tests and XCUITest e2e, including an in-overlay
stty sizegrid check and panel-frame margin assertions.