Skip to content

fix: replace anchor system with simple screen-bottom growth detection#74

Merged
quiet-node merged 7 commits intomainfrom
simplify-window-growth
Apr 10, 2026
Merged

fix: replace anchor system with simple screen-bottom growth detection#74
quiet-node merged 7 commits intomainfrom
simplify-window-growth

Conversation

@quiet-node
Copy link
Copy Markdown
Owner

Summary

  • Remove the complex WindowAnchor coordinate system (precalculated bottom pin, max-height clamping, isPreExpandedRef locking, outerContainerRef minHeight CSS hacks) and replace with a single check: if windowY + MAX_CHAT_WINDOW_HEIGHT > screenBottomY, grow upward; otherwise grow downward
  • Rust backend now sends window_x, window_y, and screen_bottom_y in the visibility payload instead of a WindowAnchor struct
  • Smooth upward growth via buffered window commits: grow the native window in coarse steps with an 80px buffer so content fills smoothly via justify-end with fewer native resize calls

Test plan

  • Activate Thuki near the top of the screen: window should grow downward smoothly
  • Activate Thuki near the bottom of the screen: window should grow upward with bottom pinned
  • Stream a long response in upward mode: window should not jitter/bounce
  • Drag the window during an upward-growth session: should switch to downward growth
  • Start a new conversation via the + button: window should shrink back to ask-bar size
  • Verify bun run test:coverage shows 100% coverage
  • Verify bun run validate-build passes with zero warnings

🤖 Generated with Claude Code

quiet-node and others added 6 commits April 10, 2026 14:46
…ction

Remove the complex WindowAnchor coordinate system (precalculated bottom
pin, max-height clamping, pre-expansion on generate, isPreExpandedRef
locking, outerContainerRef minHeight CSS hacks) and replace with a
single check: if windowY + MAX_CHAT_WINDOW_HEIGHT > screenBottomY, grow
upward; otherwise grow downward.

The Rust backend now sends window_x, window_y, and screen_bottom_y in
the visibility payload instead of a WindowAnchor struct. The frontend
decides growth direction at show time and pins the window bottom for
upward sessions. Net deletion of ~240 lines.

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
During streaming with upward growth, the ResizeObserver was calling
set_window_frame on every content height change, causing the window
to visually bounce as the Y position oscillated with each token.

Replace the per-event native resize with a buffered commit strategy:
when streaming, grow the native window in coarse steps (targetHeight
+ 80px buffer). The extra space lands in the transparent region above
the morphing container where it is invisible to the user. Content then
fills smoothly via justify-end with zero native resize calls until it
catches up to the committed height. When not streaming, exact height
is committed as before.

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
@quiet-node quiet-node force-pushed the simplify-window-growth branch from 7fcce48 to e628248 Compare April 10, 2026 19:47
- Add Math.max(0, ...) clamp to prevent the window from going above
  the screen top during upward growth on small displays
- Add missing setGrowsUpward(false) in requestHideOverlay so the React
  state stays in sync with the ref during exit animations
- Remove hasMorphedUpwardRef (declared and written but never read)
- Fix window_x doc comment to reflect its use as a positional anchor

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
@quiet-node quiet-node changed the title Replace anchor system with simple screen-bottom growth detection fix: replace anchor system with simple screen-bottom growth detection Apr 10, 2026
@quiet-node quiet-node merged commit d59119d into main Apr 10, 2026
3 checks passed
@quiet-node quiet-node deleted the simplify-window-growth branch April 10, 2026 20:37
quiet-node added a commit that referenced this pull request Apr 10, 2026
…#74)

* refactor: replace anchor system with simple screen-bottom growth detection

Remove the complex WindowAnchor coordinate system (precalculated bottom
pin, max-height clamping, pre-expansion on generate, isPreExpandedRef
locking, outerContainerRef minHeight CSS hacks) and replace with a
single check: if windowY + MAX_CHAT_WINDOW_HEIGHT > screenBottomY, grow
upward; otherwise grow downward.

The Rust backend now sends window_x, window_y, and screen_bottom_y in
the visibility payload instead of a WindowAnchor struct. The frontend
decides growth direction at show time and pins the window bottom for
upward sessions. Net deletion of ~240 lines.

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

* fix: eliminate upward-growth jitter with buffered window commits

During streaming with upward growth, the ResizeObserver was calling
set_window_frame on every content height change, causing the window
to visually bounce as the Y position oscillated with each token.

Replace the per-event native resize with a buffered commit strategy:
when streaming, grow the native window in coarse steps (targetHeight
+ 80px buffer). The extra space lands in the transparent region above
the morphing container where it is invisible to the user. Content then
fills smoothly via justify-end with zero native resize calls until it
catches up to the committed height. When not streaming, exact height
is committed as before.

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

* fix: App window height morph smoothly in both directions

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

* fix: Always morph upward and lock height state via React

* fix: refine upward growth buffering and test coverage

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

* chore: remove stray debug scripts from worktree

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

* fix: clamp upward growth Y, sync growsUpward state, remove dead ref

- Add Math.max(0, ...) clamp to prevent the window from going above
  the screen top during upward growth on small displays
- Add missing setGrowsUpward(false) in requestHideOverlay so the React
  state stays in sync with the ref during exit animations
- Remove hasMorphedUpwardRef (declared and written but never read)
- Fix window_x doc comment to reflect its use as a positional anchor

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

---------

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
quiet-node added a commit that referenced this pull request Apr 10, 2026
…#74)

* refactor: replace anchor system with simple screen-bottom growth detection

Remove the complex WindowAnchor coordinate system (precalculated bottom
pin, max-height clamping, pre-expansion on generate, isPreExpandedRef
locking, outerContainerRef minHeight CSS hacks) and replace with a
single check: if windowY + MAX_CHAT_WINDOW_HEIGHT > screenBottomY, grow
upward; otherwise grow downward.

The Rust backend now sends window_x, window_y, and screen_bottom_y in
the visibility payload instead of a WindowAnchor struct. The frontend
decides growth direction at show time and pins the window bottom for
upward sessions. Net deletion of ~240 lines.

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

* fix: eliminate upward-growth jitter with buffered window commits

During streaming with upward growth, the ResizeObserver was calling
set_window_frame on every content height change, causing the window
to visually bounce as the Y position oscillated with each token.

Replace the per-event native resize with a buffered commit strategy:
when streaming, grow the native window in coarse steps (targetHeight
+ 80px buffer). The extra space lands in the transparent region above
the morphing container where it is invisible to the user. Content then
fills smoothly via justify-end with zero native resize calls until it
catches up to the committed height. When not streaming, exact height
is committed as before.

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

* fix: App window height morph smoothly in both directions

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

* fix: Always morph upward and lock height state via React

* fix: refine upward growth buffering and test coverage

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

* chore: remove stray debug scripts from worktree

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

* fix: clamp upward growth Y, sync growsUpward state, remove dead ref

- Add Math.max(0, ...) clamp to prevent the window from going above
  the screen top during upward growth on small displays
- Add missing setGrowsUpward(false) in requestHideOverlay so the React
  state stays in sync with the ref during exit animations
- Remove hasMorphedUpwardRef (declared and written but never read)
- Fix window_x doc comment to reflect its use as a positional anchor

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

---------

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
quiet-node added a commit that referenced this pull request Apr 11, 2026
…#74)

* refactor: replace anchor system with simple screen-bottom growth detection

Remove the complex WindowAnchor coordinate system (precalculated bottom
pin, max-height clamping, pre-expansion on generate, isPreExpandedRef
locking, outerContainerRef minHeight CSS hacks) and replace with a
single check: if windowY + MAX_CHAT_WINDOW_HEIGHT > screenBottomY, grow
upward; otherwise grow downward.

The Rust backend now sends window_x, window_y, and screen_bottom_y in
the visibility payload instead of a WindowAnchor struct. The frontend
decides growth direction at show time and pins the window bottom for
upward sessions. Net deletion of ~240 lines.

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

* fix: eliminate upward-growth jitter with buffered window commits

During streaming with upward growth, the ResizeObserver was calling
set_window_frame on every content height change, causing the window
to visually bounce as the Y position oscillated with each token.

Replace the per-event native resize with a buffered commit strategy:
when streaming, grow the native window in coarse steps (targetHeight
+ 80px buffer). The extra space lands in the transparent region above
the morphing container where it is invisible to the user. Content then
fills smoothly via justify-end with zero native resize calls until it
catches up to the committed height. When not streaming, exact height
is committed as before.

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

* fix: App window height morph smoothly in both directions

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

* fix: Always morph upward and lock height state via React

* fix: refine upward growth buffering and test coverage

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

* chore: remove stray debug scripts from worktree

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

* fix: clamp upward growth Y, sync growsUpward state, remove dead ref

- Add Math.max(0, ...) clamp to prevent the window from going above
  the screen top during upward growth on small displays
- Add missing setGrowsUpward(false) in requestHideOverlay so the React
  state stays in sync with the ref during exit animations
- Remove hasMorphedUpwardRef (declared and written but never read)
- Fix window_x doc comment to reflect its use as a positional anchor

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>

---------

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
This was referenced Apr 11, 2026
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