Repository navigation
mac: the caret sits on the same line as the words - #303
Merged
Merged
Conversation
Tyler, with a screenshot: "see how the cursor isn't lined up with the preview
text?"
`#ta{...font:var(--read)/22px...}` — the lab's composer is a 22 pt LINE BOX, and
nothing in this app set one. Two things followed. Typed lines sat at the reading
font's natural 18 pt rather than 22. And the caret is drawn to the line
fragment, so it was an 18 pt bar at the top of the box while the placeholder — a
SwiftUI Text centred in a 22 pt frame — drew its glyphs 2 pt lower.
Measured with a compiled probe rather than reasoned about, because reasoning
from a bad grep is what produced the --shRaised mistake earlier today:
no paragraph style : 18 pt fragment, ink at y 0.5, caret 18 pt
22 pt line box : 22 pt fragment, ink at y 4.5, caret 22 pt
placeholder centred in 22 pt : ink at y 6
placeholder topped in 22 pt : ink at y 4
So the editor gets the lab's line box and the placeholder is top-aligned: both
land at ~4, and the caret finally spans the line its text sits on.
Three more, found while looking:
- `fieldHeight` measured the draft at systemFont(12.5) — line height 15 — while
the editor renders system 15 in a 22 pt box. Every wrapped line was measured
7 pt short, so the field grew less than the text it had to hold.
- `#cLive{padding:8px 10px 4px;font:var(--read)/22px}`: the live dictation line
shares the editor's font and insets in the lab, because this text becomes that
text. It was 12.5 with 6/8 padding, so the words changed size and jumped the
instant transcription landed — the one moment you are watching them.
- `ComposerView.lineHeight` inside a `View` extension resolves to SwiftUI's own
`lineHeight(_:)` modifier, not the struct's constant. The value is passed in
now; the compiler found this one.
The dictation line's cyan is left alone: the lab uses `--text` there (and
`--text3` while transcribing), which is a state-colour decision, not a
measurement.
Gated: bun test 2315/0, tsc clean, swift test 138/0, Mac and iOS both build (CI
builds neither). Eleven mutations, eleven killed — including one that survived
the first pass, because asserting `storage.addAttribute(` existed still passed
with its branch inverted to `length < 0`. The guard now pins the condition.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SfEX6bfwCGXtThk1JRNmsE
stupart
added a commit
that referenced
this pull request
Sep 17, 2026
Tyler, twice: "the cursor in the text input box still isn't lined up with the preview text." #303 was my fix and it was wrong. It reasoned from a probe of a SIMPLIFIED case and shipped `minimumLineHeight = maximumLineHeight = 22`. CSS splits a line box's extra leading half above and half below the text; AppKit puts ALL of it above the baseline. So a 22 pt line box pushed the first line DOWN and grew the caret with it, while the placeholder — top-aligned, untouched — stayed where it was. That made the gap different, not smaller. Measured against a real NSTextView, rendered and read back pixel by pixel: no paragraph style caret 18 pt, text ink at 4 pt min/max 22 caret 22 pt, text ink at 8 pt <- what #303 shipped lineSpacing 4 caret 18 pt, text ink at 4 pt The placeholder draws its ink at 4 pt. The middle row was off by exactly 4. So: `ConchType.readingLineSpacing` — the same 4 pt the transcript already uses, so the composer and the messages it answers cannot drift apart. `#ta{font:var(--read)/22px}` is 15 pt of type plus 4 pt of leading, and 22 still bounds the field at one line and at eight (`max-height:calc(22px*8+12px)`). Two hypotheses were tested and discarded first. A harness hosting a real SwiftUI TextEditor showed the paragraph style SURVIVES every update (22/22 before and after a keystroke), so "SwiftUI clobbers it" was wrong and the introspector running once was not the bug. The lesson, which cost three attempts: a probe of a simplified case is not a measurement of the thing itself. The first probe measured a SwiftUI Text in a frame and an NSLayoutManager in isolation. Neither was the composer. Verified: bun test 2345/0, tsc clean, swift test 138/0, the Mac app builds. Five mutations, five killed — including one that re-ships #303's exact mistake, so it cannot come back quietly. Claude-Session: https://claude.ai/code/session_01SfEX6bfwCGXtThk1JRNmsE Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The caret
#ta{...font:var(--read)/22px...}is a 22 pt line box, and nothing in the app set one. The caret is drawn to the line fragment, so it was an 18 pt bar at the top of the box while the placeholder — a SwiftUITextcentred in a 22 pt frame — drew its glyphs 2 pt lower.Measured with a compiled probe, not reasoned about:
One change fixes three things: the caret's alignment, the placeholder's alignment, and typed multi-line spacing (18 pt → the lab's 22).
Three more, found on the way
fieldHeightgrowthsystemFont(12.5), line height 15#cLive)readingBody+ the editor's own insets — words no longer change size and jump when transcription landsComposerView.lineHeightin aViewextensionlineHeight(_:)modifierThe dictation line's cyan is left alone — the lab uses
--textthere and--text3while transcribing, which is a state-colour decision for you, like the send button.Gate:
bun test2315/0 ·tscclean ·swift test138/0 · Mac + iOS both build · 11 mutations, 11 killed.One of those eleven survived the first pass: asserting
storage.addAttribute(existed still passed with its branch inverted tolength < 0— the call was there, it just could never run. The guard pins the condition now.🤖 Generated with Claude Code
https://claude.ai/code/session_01SfEX6bfwCGXtThk1JRNmsE