Skip to content

Fix stale panel height when content shrinks#36

Merged
fredrivett merged 2 commits into
mainfrom
fredrivett/fix-stale-panel-height
Jul 13, 2026
Merged

Fix stale panel height when content shrinks#36
fredrivett merged 2 commits into
mainfrom
fredrivett/fix-stale-panel-height

Conversation

@fredrivett

@fredrivett fredrivett commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Problem

The reeve panel sometimes kept its old, too-tall height after its content got smaller — collapsing an environment, clearing the filter, hitting "Collapse all", or processes vanishing on a refresh would leave the list vertically centred inside an oversized window.

Root cause

The panel's height is driven by scrollContentHeight, measured by a GeometryReader in the scroll content's .background. Per the documented macOS 26 MenuBarExtra quirk, that GeometryReader only re-measures when its .id() changes. The id was tied only to inactiveExpanded, so height re-measured on the Inactive toggle but not for any other change that shrinks the content. Combined with the if h > 0 guard, scrollContentHeight stayed stuck at its old large value and never came back down.

Fix

Replace .id(inactiveExpanded) with .id(contentHeightSignature) — a composite hash of every piece of state that affects content height:

  • filterText, inactiveExpanded, showInactive
  • collapsedEnvironments and expandedInactiveEnvironments
  • per-environment path, active state, process count, and error presence

Any change that grows or shrinks the list now recreates the GeometryReader and forces a fresh measurement, so the window resizes to fit.

Also added a Fragility note to the quirk section in AGENTS.md (which CLAUDE.md symlinks to) so future state dimensions get folded into the signature.

Testing

  • swift build passes.
  • Manual: expand to a tall panel, then collapse an env / clear the filter — window now snaps down to the new content height instead of leaving centred content in an oversized window.

🤖 Generated with Claude Code


Summary by cubic

Fixes the panel keeping a too-tall height after content shrinks in the macOS 26 MenuBarExtra. The window now snaps to the correct size immediately, even when filters or refreshes change which rows are visible.

  • Bug Fixes
    • Replaced the GeometryReader .id(inactiveExpanded) with .id(contentHeightSignature) to force re-measure on any height change.
    • contentHeightSignature mirrors render logic: hashes filter text, inactive toggle/visibility, collapse/expand state, per-env path/active/error presence, filter match, and the visible process count.
    • Added a fragility note in AGENTS.md to keep the signature updated when new height-affecting state is introduced.

Written for commit 6247d4e. Summary will update on new commits.

Review in cubic

The MenuBarExtra window kept its old (too-tall) height after the
content shrank — collapsing an environment, clearing the filter, or
processes vanishing on refresh left the list vertically centred inside
an oversized window.

The panel height comes from a GeometryReader in the content's
.background, which on macOS 26 only re-measures when its .id() changes
(known quirk). That id was tied only to inactiveExpanded, so every other
height change went unmeasured and scrollContentHeight stayed stale.

Replace the id with contentHeightSignature, a composite hash of every
piece of state that affects content height (filter text, all
collapse/expand state, per-env process counts and error presence).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 2 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread Sources/Reeve/Views/ContentView.swift
contentHeightSignature hashed the raw per-env process count, but when a
filter is active the rendered rows come from filteredProcesses(for:) and
envNameMatches(_:). A refresh could change which processes match the
filter (by name/ports) or whether an env matches (by name/branch)
without changing the total count, leaving the signature — and the panel
height — stale.

Mirror the render logic instead: hash matchesName plus the actual
visible process count, which together also capture whether the env is
displayed at all.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@fredrivett

Copy link
Copy Markdown
Owner Author

Good catch — valid. The signature hashed the raw per-env process count, but under an active filter the rendered rows come from filteredProcesses(for:) and envNameMatches(_:), so a refresh could change which rows match without changing the total count and leave the height stale.

Fixed in 6247d4e by mirroring the render logic: the signature now hashes matchesName plus the actual visible process count (which together also capture whether the env is shown at all), rather than the raw count.

@fredrivett fredrivett merged commit e708818 into main Jul 13, 2026
2 checks passed
@fredrivett fredrivett deleted the fredrivett/fix-stale-panel-height branch July 13, 2026 08:34
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