Repository navigation
Fix #3708: redraw cmux window on focus regain even when cursor is over the sidebar resize handle - #3879
Conversation
The sidebar/main resize handle repro depends on a main window key-regain path that currently restores focus state without requiring a content redraw. This regression test builds a registered cmux main window with a split divider under the pointer and asserts that the root content view is invalidated after resign/become-key notifications. Constraint: Do not run local tests or bare xcodebuild for this branch Confidence: high Scope-risk: narrow Directive: Keep this as a behavior-level AppKit lifecycle test; do not replace it with a source-shape assertion Tested: Not run locally by request Not-tested: Local XCTest execution; CI is expected to show this test failing before the fix
A cursor hover over the sidebar/main divider should not decide whether a key-regain redraw occurs. The main window lifecycle handler now treats content invalidation as an app-level invariant for registered cmux windows before restoring subview focus state. Constraint: Fix must avoid resize-handle-specific timing glue and must not use local bare xcodebuild Rejected: Patch WindowTerminalHostView mouse tracking | redraw on focus regain belongs to the window lifecycle owner, not the current cursor owner Confidence: medium Scope-risk: narrow Directive: Keep key-regain redraw ownership in the main-window lifecycle path; do not move it into divider tracking handlers Tested: git diff --check Not-tested: Local XCTest/build by request; CI will verify
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryThis PR fixes a focus-regain redraw regression where the pointer being over the
Confidence Score: 5/5Safe to merge — the change is localized to the key-regain path and adds a regression test; the tree-walk invalidation is unconditional and isolated behind MainWindowKeyRegainRefresh. The tree-walk display invalidation is correct and self-contained. The only gap is that invalidateCursorRects(for: contentView) does not recurse into subviews, so NSSplitView cursor areas are not reset — but this does not affect display correctness and does not regress existing behavior. The regression test uses only local view-frame coordinates and is reliable in headless CI. No files require special attention; the production change is small and the test is straightforward. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[NSWindow.didBecomeKeyNotification] --> B[handleCmuxWindowBecameKey]
B --> C[contextForMainTerminalWindow]
C --> D[setActiveMainWindow]
D --> E[publishCmuxWindowLifecycle]
E --> F{context != nil?}
F -- No --> G[Done]
F -- Yes --> H[MainWindowKeyRegainRefresh.refresh]
H --> I[invalidateContentDisplayTree]
I --> J[invalidateDisplayTree recursive walk]
J --> K[view.needsDisplay = true / view.layer?.setNeedsDisplay]
K --> L{more subviews?}
L -- Yes, not hidden --> J
L -- No --> M[window.invalidateCursorRects for contentView]
M --> N[keyboardFocusCoordinator.restoreTargetAfterWindowBecameKey]
N --> G
Reviews (2): Last reviewed commit: "Clarify key-regain refresh ownership" | Re-trigger Greptile |
Review feedback correctly pointed out that the redraw invariant should be named as one post-focus contract instead of appearing as an orphaned pre-walk next to focus restoration. This keeps the app-window lifecycle as the single owner while calling the keyboard focus coordinator only after redraw invalidation is established. Constraint: Continue avoiding local tests and bare xcodebuild on this branch Rejected: Move redraw ownership into divider tracking | the bug must be impossible regardless of current cursor owner Confidence: medium Scope-risk: narrow Tested: git diff --check Not-tested: Local XCTest/build by request; CI will verify
Fixes #3708.\n\n## Summary\n- Add a regression test for key-regain invalidation while the pointer is over the sidebar/main split divider.\n- Move redraw responsibility to the main-window key lifecycle path so divider cursor tracking cannot suppress content invalidation.\n\n## Testing\n- Not run locally by request; CI will verify the failing-test/fix two-commit sequence.
Note
Medium Risk
Moderate risk: changes main-window key focus handling to aggressively invalidate the entire view tree, which could impact redraw performance or introduce new focus/hover side effects on macOS UI components.
Overview
Fixes a focus-regain redraw bug by moving main-window refresh responsibilities into the
didBecomeKeylifecycle path.On key regain, the app now recursively invalidates the window’s content view hierarchy (and cursor rects) before restoring keyboard focus, ensuring the UI redraws even when cursor tracking (e.g., over the sidebar split divider) would otherwise suppress updates.
Adds a regression test (
MainWindowFocusRedrawTests) that simulates a sidebar/mainNSSplitViewdivider scenario and asserts the root content view is invalidated after resigning and regaining key focus.Reviewed by Cursor Bugbot for commit b1bf2b1. Bugbot is set up for automated code reviews on this repo. Configure here.