Skip to content

fix(panel): clamp panel window height to screen (#304) - #305

Open
LikeSundayLikeRain wants to merge 1 commit into
wxtsky:mainfrom
LikeSundayLikeRain:fix/304-card-invisible-macos26
Open

fix(panel): clamp panel window height to screen (#304)#305
LikeSundayLikeRain wants to merge 1 commit into
wxtsky:mainfrom
LikeSundayLikeRain:fix/304-card-invisible-macos26

Conversation

@LikeSundayLikeRain

Copy link
Copy Markdown

Fixes #304.

Symptom

The Ask-user-question / permission panel becomes invisible ~2s after it appears, on some displays. Moving the mouse over the panel area brings it back; moving away hides it again. Reproduces on the built-in display and one external monitor, but not another external display, across two different MacBook Pros.

Root cause

The island is a single borderless, non-opaque NSPanel whose height is sized up-front to fit the largest possible expanded session list:

let maxH = max(300, maxSessions * 90 + 60)   // maxVisibleSessions * 90 + 60

With a large maxVisibleSessions (e.g. 99) this makes the window 8970pt tall — a ~18k-pixel-tall backing store on a Retina display, for a window that is ~95% transparent and only ever draws content in its top ~200pt.

On macOS 26, the WindowServer drops compositing for a backing store that large once the surface goes idle (to reclaim GPU memory). Nothing in the app forces a repaint of the settled card, so it renders blank until a mouse event forces a recomposition — hence "invisible after ~2s, reappears on hover." It is display-dependent because a 1× (non-HiDPI) external monitor's smaller buffer stays under the purge threshold, which is why one external display was unaffected.

Fix

Clamp the panel window height to the screen's visible height. The content is top-anchored and the session list already scrolls internally (ThinScrollView caps at maxVisibleSessions * 90), so the window never needs to be taller than the screen.

Verification

Confirmed on macOS 26.6 with a release build, using the real hook path (a genuine AskUserQuestion over the hook socket), on a Retina display:

  • Instrumented the live window: while the card was blank it still reported isVisible=true, alpha=1.0, occlusionState.contains(.visible)=true, surface .questionCard — ruling out collapse / orderOut / alpha / occlusion-state. The frame was 8970pt tall.
  • Reducing the window height (via maxVisibleSessions) made the card stay visible with nothing else changed.
  • With this clamp and maxVisibleSessions=99, the card now stays visible for the full duration (previously it vanished after ~2s).

A large maxVisibleSessions made the borderless panel window thousands of
points tall (99 -> 8970pt). On macOS 26 the WindowServer drops compositing
for the huge idle backing store, so the approval/question card renders blank
until a mouse event forces a redraw -- looked like the card going invisible
~2s after appearing and reappearing on hover, on Retina/HiDPI displays only.

Clamp the window height to the screen's visible height; the content is
top-anchored and the session list scrolls internally, so the window never
needs to exceed the screen.
nguyenvanduocit pushed a commit to nguyenvanduocit/CodeIsland that referenced this pull request Aug 8, 2026
New finding: wxtsky/CodeIsland PR wxtsky#305 (open Aug 6) fixes panel going
invisible on HiDPI displays when panelSize height exceeds screen height,
triggering WindowServer GPU compositing bypass on macOS 26. Same bug
confirmed in our PanelWindowController.swift:121. Added T-081 (XS fix)
to kanban Todo.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WQBHS6nVFxhc4CSqq7twkZ
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.

Question and permission panel becomes invisible after around 2s on some screens

1 participant