SIGN IN SIGN UP

Fix viewport blanking after large programmatic scroll (setFrameSize re-entrance) (#110)

## Summary

Cmd-End → Cmd-Home on a document taller than one viewport leaves the
editor blank except for the first wrapped fragment. Viewport layout is
correct; rendering is clipped because `contentView` and
`contentViewportView` end up pinned to ~one-line tall while the textView
itself is at full document height.

## Root cause

When `relocateViewport(to: docStart)` calls `setFrameSize(width,
lineHeight)` from a scrolled-down position, AppKit must synchronously
retract the clip view to fit the new bounds. That fires `prepareContent`
from inside `super.setFrameSize`, which calls
`updateContentSizeIfNeeded` and re-enters `setFrameSize` with the full
document height. The recursive call correctly resizes `contentView`.
When control returns to the outer call, `newSize` is still the original
(small) value, and `contentView.frame.size = newSize` stomps the
recursive call's result.

End state: textView at full height, `contentView` and
`contentViewportView` at one-line height, fragment views past line 1
clipped.

## Repro

Open a multi-screen word-wrapped document, Cmd-End, then Cmd-Home. The
editor renders only the first wrapped fragment of paragraph 1. Resizing
the window or toggling word-wrap restores rendering because both go
through a fresh non-re-entrant `setFrameSize`.

Verified in the bundled \`TextEdit.SwiftUI\` example with a ~24KB
document; reverting the change reproduces the blanking.

## Fix

After \`super.setFrameSize\`, read \`frame.size\` (which reflects any
recursive resize) rather than the stale \`newSize\` parameter. When no
re-entrance occurred, \`frame.size == newSize\`, so the common path is
unchanged.
I
Ilia Sazonov committed
a534d12b48cca9b8fc6f99d0eb4cc827f128042f
Parent: c36bf60
Committed by GitHub <noreply@github.com> on 4/28/2026, 8:22:57 PM