Repository navigation
Fix standard tab-bar new-tab click handling - #101
Conversation
When the drag zone returns mouseDownCanMoveWindow=true, AppKit's own window-drag tracking intercepts mouseUp on the first click. The second click of a quick double-click then arrives as clickCount=1 instead of clickCount=2, so the new-tab action never fires. Forcing the property to false keeps the standard mouseDown/mouseUp/mouseDown sequence intact while the custom mouseDragged -> window.performDrag flow still handles actual window drags. Same class of bug already documented on pane tab clicks (see NonDraggableHostingView / SplitArrangedContainerView comments). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThis PR modifies the tab bar drag zone's mouse event handling to prevent AppKit from interfering with click operations and to improve coordination between single-click, double-click, and window-drag behaviors. It restructures the Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
✨ Finishing Touches📝 Generate docstrings
🧪 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 new-tab click handling in the standard-mode tab bar by (1) hardcoding Confidence Score: 5/5Safe to merge; all findings are P2 and do not block the primary new-tab fix. The core logic is sound and well-commented. All changes are covered by new or updated unit tests. The one flagged concern (unfocused-pane standard-mode behavior) is a pre-existing edge case with no new regression introduced by this PR, making this a clarification/test-coverage note rather than a blocker. No files require special attention beyond the P2 clarification on TabBarView.swift. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[mouseDown event received] --> B{isMinimalMode?}
B -- No: standard mode --> C[clearPendingWindowDrag]
C --> D{clickCount == 1?}
D -- Yes --> E[call onDoubleClick new-tab]
E --> F{returned true?}
F -- Yes --> G[return — tab created]
F -- No --> H[super.mouseDown]
D -- No clickCount ≥ 2 --> I[return — deduplicated]
B -- Yes: minimal mode --> J{clickCount ≥ 2?}
J -- Yes --> K[clearPendingWindowDrag]
K --> L{onDoubleClick?}
L -- true --> M[return — tab created]
L -- false/nil --> N[performTitlebarDoubleClickAction]
J -- No --> O{isFocusedPane?}
O -- No --> P{onSingleClick?}
P -- true --> Q[clearPendingWindowDrag / return]
P -- false/nil --> R[pendingWindowDragEvent = event]
O -- Yes --> R
R --> S[mouseDragged: distance ≥ 4px?]
S -- Yes --> T[startWindowDrag via window.performDrag]
S -- No --> U[wait for more drag events]
Reviews (1): Last reviewed commit: "Fix standard tab-bar new-tab click handl..." | Re-trigger Greptile |
| if !isMinimalMode { | ||
| clearPendingWindowDrag() | ||
| if event.clickCount == 1 { | ||
| if onDoubleClick?() == true { | ||
| #if DEBUG | ||
| dlog("tab.bar.dragZone.singleClick action=newTab") | ||
| #endif | ||
| return | ||
| } | ||
| super.mouseDown(with: event) | ||
| return | ||
| } | ||
| // clickCount >= 2: same gesture as a click we already acted on. | ||
| #if DEBUG | ||
| dlog("tab.bar.dragZone.click skipped reason=dedupeStandardMode clickCount=\(event.clickCount)") | ||
| #endif | ||
| return |
There was a problem hiding this comment.
onSingleClick (focus-pane) bypassed in standard mode for unfocused panes
In standard mode the code immediately calls onDoubleClick (new-tab) on the first click regardless of isFocusedPane, skipping the onSingleClick → focusPaneFromTabBarChrome path that minimal mode uses. If a split layout has two panes in standard mode and the user clicks the empty trailing area of the unfocused pane, a tab is created in that pane without first focusing it. No test covers isMinimalMode = false, isFocusedPane = false, and no comment explains whether this is deliberate.
Publishes the bonsplit side of manaflow-ai/cmux issue 3049.\n\n- adds standard-mode tab-bar new-tab regression coverage\n- makes a click in the empty trailing tab-bar region request a new tab immediately\n- keeps follow-up double-click events from creating duplicate tabs\n\nThis PR is needed before the cmux parent repo can point at a clean bonsplit SHA on origin/main.
Summary by CodeRabbit
Bug Fixes
Tests
Summary by cubic
Fixes tab-bar new-tab click handling to remove flakiness and accidental duplicates. Single clicks in the trailing empty space now create a tab, and double-clicks behave correctly in both standard and minimal modes while preserving window drag.
dropZoneAfterTabs, keepingclickCountconsistent across boundary shifts.mouseDownCanMoveWindow; use custommouseDragged→window.performDragwith a small movement threshold to prevent AppKit from stealing mouseUp.Written for commit 68659a2. Summary will update on new commits.