Skip to content

Make sidebar empty area a window-drag region - #9212

Closed
kenifxyz wants to merge 16 commits into
manaflow-ai:mainfrom
kenifxyz:feature/sidebar-empty-area-window-drag
Closed

kenifxyz wants to merge 16 commits into
manaflow-ai:mainfrom
kenifxyz:feature/sidebar-empty-area-window-drag

Conversation

@kenifxyz

@kenifxyz kenifxyz commented Jul 30, 2026 •

Copy link
Copy Markdown

Summary

  • Make the empty space below the last workspace group a window-drag region, matching the titlebar strip above the sidebar and standard macOS background-drag.
  • Track the press synchronously from mouseDown with nextEvent(matching:) instead of an NSGestureRecognizer.
  • Repost the terminating mouse-up when a press never becomes a drag, so clicks, double-clicks, and context menus are unaffected.
  • Add four behavior tests covering drag, click, sub-threshold jitter, and a detached view.

Fixes #9203

Root cause

The empty region below the workspace list sits inside the sidebar's NSScrollView. NSScrollView reports mouseDownCanMoveWindow == false, so the scroll-view background swallowed the press and AppKit's background-drag never engaged. mouseDownCanMoveWindow is wired up in the titlebar accessory views, WindowDragHandleView, and MinimalModeSidebarControls, but never reached the left sidebar's list body — which is why #3119 could describe the non-minimal sidebar as draggable while this specific region was not.

The first attempt here used an NSGestureRecognizer and was wrong in a way worth recording: NSWindow.performDrag(with:) runs its own modal tracking loop and consumes the terminating mouse-up. A recognizer that calls it therefore never receives the event that would drive it back to .possible — it parks in a terminal state, reset() never runs, and it silently stops recognizing for the rest of the window's life. Manual testing showed exactly that: the drag worked, then stopped working permanently.

Design

SidebarEmptyAreaWindowDrag.perform(with:in:) runs a synchronous tracking loop from mouseDown, the same shape as SidebarDividerTrackingView in the same directory:

  • ≥4pt travel → performDrag, consume the event, return true.
  • mouse-up first → repost it with postEvent(_:atStart: true) and return false, so the caller falls through to normal handling. NSTableView's own mouseDown tracking loop blocks waiting for that mouse-up; swallowing it would hang the click.

Three call sites share the one path. The table view gates on row(at:) < 0 so rows keep their existing click handling; the clip view needs no gate because presses only reach it when they miss the table's frame entirely. Double-clicks bypass the drag path so doubleClickEmptyArea() still fires. Window-drag suppression is respected via the existing isWindowDragSuppressed / withTemporaryWindowMovableEnabled helpers, matching TitlebarAccessoryContainerView.

Testing

  • SidebarEmptyAreaWindowDragTests, 4/4 passing locally via scripts/test-unit.sh -only-testing:cmuxTests/SidebarEmptyAreaWindowDragTests: drag past threshold moves the window and restores isMovable; press without movement stays a click; sub-threshold jitter stays a click; a detached view is a no-op.
  • Manually verified on a tagged DEBUG build: the empty region below the last workspace group drags the window, and the recognizer wedge described above no longer reproduces. The recognizer-based first attempt reproduced that wedge consistently before the rewrite.
  • Local builds passed CMUX_SKIP_ZIG_BUILD=1 because Xcode 26.6 no longer bundles the Metal toolchain, so the Ghostty CLI helper phase cannot compile shaders.metal here. That phase is untouched by this change.

Heads-up: cmuxTests does not compile on current main

Two pre-existing breaks, both in files this PR does not touch, block the whole test target. I stubbed them locally to get a run and reverted before committing.

  • cmuxTests/WorkspaceRemoteConnectionTests.swift:24 — Fix stale SSH workspace connection status #9085 added beginReadinessDelivery() and finishReadinessDelivery(succeeded:) to ControlRemotePTYLifecycleCommitLease without updating ManualRemotePTYLifecycleCommitLease.
  • cmuxTests/AppDelegateEqualizeSplitsShortcutTests.swift:7894 — call is missing the now-required managedAgentResumeBinding argument.

CI on this PR will likely fail on both until they are fixed on main. Happy to fold the fixes in here if maintainers prefer, but I have kept them out to hold scope.

Demo Video

Not attached. The behavior is a pointer interaction covered by the four behavior tests plus manual verification on a tagged DEBUG build. Happy to record a clip if a reviewer would like one.

Checklist

  • I tested the change locally
  • I added or updated tests for behavior changes
  • I updated docs/changelog if needed (not needed: CHANGELOG.md is assembled per release by maintainers, and recent merged PRs do not touch it)
  • I requested bot reviews after my latest commit
  • All code review bot comments are resolved
  • All human review comments are resolved

Summary by CodeRabbit

  • New Features
    • Enable window dragging from the sidebar’s empty area with a single click-and-drag gesture, including space below the last row.
    • Support activating an inactive window when clicking in the empty sidebar area.
    • Preserve existing single-click and double-click behavior when no drag occurs.
  • Bug Fixes
    • Improved handling of cancellations and unavailable windows without disrupting normal interactions.
  • Tests
    • Added coverage for threshold-based drags, click-only behavior, cancellation, and inactive-window handling.

Note

Medium Risk
Touches low-level AppKit mouse tracking and performDrag on the main sidebar table/clip views; incorrect event handling could break row clicks or hang tracking, but behavior is gated to empty space and covered by tests.

Overview
Adds window dragging from empty space below the last workspace row in the native AppKit sidebar, aligned with titlebar and other background-drag regions (fixes #9203).

A new SidebarEmptyAreaWindowDragController runs a synchronous tracking loop from mouseDown (same pattern as SidebarDividerTrackingView), not an NSGestureRecognizer, because performDrag(with:) breaks recognizer state permanently. Movement past a 4pt threshold calls performDrag via existing withTemporaryWindowMovableEnabled / suppression helpers; otherwise the terminating mouse-up is reposted so clicks, double-clicks, and NSTableView tracking still work.

SidebarWorkspaceTableViewImpl and SidebarWorkspaceTableClipView hook single-click empty-area presses; double-clicks stay on the existing empty-area path. The clip view also acceptsFirstMouse for inactive windows. SwiftUI’s full-height empty hit target is documented as SwiftUI-only so native views own drags without stealing row presses.

Tests cover drag, click, jitter, cancellation, detached views, and first-mouse; plus a small test compile fix in AppDelegateEqualizeSplitsShortcutTests.

Reviewed by Cursor Bugbot for commit 14c454e. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026 •

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Single-clicks in sidebar empty areas now support threshold-based window dragging through an AppKit event handler. The sidebar delegates eligible presses to the handler. Tests cover dragging, click preservation, cancellation, movability restoration, and inactive-window handling.

Changes

Sidebar empty-area dragging

Layer / File(s) Summary
Drag contracts and controller
Sources/Sidebar/SidebarEmptyAreaWindowDragController.swift, Sources/Sidebar/SidebarEmptyAreaWindowDragOutcome.swift, Sources/Sidebar/SidebarEmptyAreaWindowDragTrackingEvent.swift
Adds event tracking, threshold-based dragging, cancellation handling, mouse-up replay, and temporary window movability.
Sidebar event integration
Sources/Sidebar/AppKitList/SidebarWorkspaceTableClipView.swift, Sources/Sidebar/AppKitList/SidebarWorkspaceTableViewImpl.swift, Sources/VerticalTabsSidebar+EmptyAreasAndFooter.swift, cmux.xcodeproj/project.pbxproj
Routes eligible empty-area presses to the controller and registers the new source files in the target. Existing double-click behavior remains unchanged.
Drag behavior validation
cmuxTests/TitlebarInteractiveControlTests.swift
Adds synthetic event tests for drags, pass-through clicks, cancellation, detached views, movability restoration, and inactive-window first-mouse handling.

Weak test reference fix

Layer / File(s) Summary
Weak reference declaration
cmuxTests/AppDelegateEqualizeSplitsShortcutTests.swift
Replaces an invalid weak constant declaration with a weak optional variable and assignment.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Possibly related issues

  • manaflow-ai/cmux-dev-artifacts#9438 — Concerns the SidebarEmptyAreaWindowDragTests suite added by this change.
  • manaflow-ai/cmux-dev-artifacts#9415 — References the new empty-area window-drag functionality and its tests.
  • manaflow-ai/cmux-dev-artifacts#9384 — References the new SidebarEmptyAreaWindowDragTests suite.
  • manaflow-ai/cmux-dev-artifacts#9460 — Concerns execution of the new empty-area window-drag tests.
  • manaflow-ai/cmux-dev-artifacts#9324 — References the new drag tests and the weak-variable test fix.

Possibly related PRs

Suggested reviewers: austinywang

Sequence Diagram(s)

sequenceDiagram
  participant SidebarWorkspaceTableView
  participant SidebarEmptyAreaWindowDragController
  participant NSWindow
  SidebarWorkspaceTableView->>SidebarEmptyAreaWindowDragController: handle single-click
  SidebarEmptyAreaWindowDragController->>NSWindow: track pointer events
  SidebarEmptyAreaWindowDragController->>NSWindow: performDrag(with:) after threshold
  SidebarEmptyAreaWindowDragController->>NSWindow: restore movability
Loading
🚥 Pre-merge checks | ✅ 23 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The AppDelegateEqualizeSplitsShortcutTests weak-reference fix is unrelated to the linked sidebar window-drag objective. Remove the unrelated AppDelegateEqualizeSplitsShortcutTests change or link it to a separate issue.
Docstring Coverage ⚠️ Warning Docstring coverage is 65.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (23 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The implementation directly addresses issue #9203 by enabling empty sidebar-area window dragging with threshold tracking and preserved click behavior.
Cmux Swift Actor Isolation ✅ Passed The production controller and both AppKit owners are explicitly @MainActor; added values stay synchronous and no new Sendable, async, service-protocol, or background UI access appears.
Cmux Swift Blocking Runtime ✅ Passed Production code uses AppKit-idiomatic synchronous event tracking via window.nextEvent() in .eventTracking mode (matching SidebarDividerTrackingView pattern), not blocking primitives; no semaphores,...
Cmux Browser Automation Off-Main ✅ Passed The PR changes only sidebar drag handling and tests; both rule-target files are unchanged, and the patch contains no browser/WebKit/socket automation changes.
Cmux Expensive Synchronous Load ✅ Passed The PR adds only AppKit event tracking and window-drag calls; the production diff contains no agent-history loader, filesystem scan, JSON/transcript parse, or synchronous agent-store access.
Cmux Cache Substitution Correctness ✅ Passed The PR diff only changes Swift AppKit mouse-event handling and tests; it contains no fresh-read replacement, cache, persistence, history, undo, or snapshot consumer.
Cmux No Hacky Sleeps ✅ Passed The PR changes Swift files plus Xcode project wiring; it adds no covered non-Swift runtime delay, sleep, timer, polling, or wall-clock wait.
Cmux Algorithmic Complexity ✅ Passed Changed production code has only a synchronous event-tracking loop; no scalable-collection scans, sorting/filtering, joins, or nested loops were introduced.
Cmux Swift Concurrency ✅ Passed The diff adds no Dispatch, Combine, completion-handler, or fire-and-forget Task pattern; tracking is synchronous AppKit nextEvent/performDrag, and the existing SwiftUI Task is unchanged.
Cmux Swift @Concurrent ✅ Passed The PR adds only synchronous @MainActor controller and mouseDown paths; the diff adds no async, nonisolated, or @concurrent work, so the rule has no violation.
Cmux Swift Package Boundaries ✅ Passed The diff adds AppKit-only sidebar event glue: NSWindow/NSView/NSEvent tracking, performDrag, and two native view call sites; it exposes no reusable domain or cross-surface logic.
Cmux Swiftpm Lockfiles ✅ Passed cmux.xcodeproj/project.pbxproj only adds Swift source references; no package references, Package.swift, Package.resolved, or .gitignore changed. Package-local lockfile obligations are not triggered.
Cmux Swift Logging ✅ Passed The cumulative PR diff adds no print, debugPrint, dump, NSLog, Logger, file-output, stdout, or stderr logging in production or test Swift code.
Cmux User-Facing Error Privacy ✅ Passed The PR-specific diff adds AppKit drag logic, enums, comments, tests, and project wiring; it adds no user-facing errors, alerts, command output, or sensitive diagnostic text.
Cmux Full Internationalization ✅ Passed The PR adds no user-facing production text or localization resources; production changes are event handling/comments, and test diagnostics are explicitly allowed by the rule.
Cmux Swiftui State Layout ✅ Passed The only SwiftUI diff adds comments in existing SidebarEmptyArea; no new state, GeometryReader, lazy-row store reference, or render-time mutation was introduced. New behavior is AppKit.
Cmux Architecture Rethink ✅ Passed The diff uses one immutable @MainActor controller path; synchronous nextEvent and mouse-up reposting are documented AppKit event handoff, with no new sleeps, polling, locks, observers, or mutable s...
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed The PR adds no standalone user-visible window or close shortcut; production code only drags the existing host window, and NSWindow fixtures are test-only. Auxiliary-window lint passes.
Cmux Source Artifacts ✅ Passed The full PR diff contains only Swift source, Swift tests, and Xcode project configuration; no logs, media, caches, temp directories, build output, or other artifact paths were added.
Cmux No Test Or Debug Seam In Production Source ✅ Passed Changed Sources files add no test/debug guards, seam-named members, visibility widening, or state accessors; the injected event source supports a production default and real callers.
Cmux No Ambient Global State ✅ Passed The new drag behavior is owned by an instance-based, constructable controller with an injected event source; added enums contain cases only, with no free functions, mutable globals, static namespac...
Title check ✅ Passed The title clearly and concisely describes the main change: enabling window dragging from the sidebar empty area.
Description check ✅ Passed The description covers the change, rationale, design, testing, checklist, and known limitations; the optional demo video is explicitly noted as unavailable.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@kenifxyz
kenifxyz marked this pull request as ready for review July 30, 2026 07:10
@kenifxyz

Copy link
Copy Markdown
Author

@codex review
@coderabbitai review
@greptile-apps review
@cubic-dev-ai review

@cubic-dev-ai

cubic-dev-ai Bot commented Jul 30, 2026

Copy link
Copy Markdown

@codex review
@coderabbitai review
@greptile-apps review
@cubic-dev-ai review

@kenifxyz I can't start this review because your workspace has reached its free monthly review limit. cubic has reviewed 241,631 of the 240,000 allowed lines of code this month. Reviews resume on 1 August 2026 (in 2 days). Paid plans include much higher monthly review limits. Upgrade now to resume reviews.

To help optimise your usage, you can tune cubic to get the most out of your usage limits:

Learn more →

@coderabbitai

coderabbitai Bot commented Jul 30, 2026 •

Copy link
Copy Markdown

@kenifxyz: I’ll review the changes in #9212.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 703341fe60

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/VerticalTabsSidebar+EmptyAreasAndFooter.swift
@kenifxyz

Copy link
Copy Markdown
Author

@codex review
@coderabbitai review
@greptile-apps review

@coderabbitai

coderabbitai Bot commented Jul 30, 2026 •

Copy link
Copy Markdown

@kenifxyz I’ll review the latest changes in #9212.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Sources/VerticalTabsSidebar+EmptyAreasAndFooter.swift (1)

103-107: 📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift

Remove the test-only event-pump seam from production code.

nextEvent is only used by the supplied tests to replace AppKit’s real event pump. Keep the production method tied to its real event source and move deterministic event-sequence testing behind a test-target helper or isolated state-machine test. As per path instructions, production Swift source must not add test-only or debug-only seams under Sources/**.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Sources/VerticalTabsSidebar`+EmptyAreasAndFooter.swift around lines 103 -
107, Remove the injectable nextEvent parameter from perform and bind the
event-pumping logic directly to AppKit’s production event source. Update callers
and tests accordingly, moving deterministic event-sequence control into a
test-target helper or isolated state-machine test without adding test-only seams
under Sources.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@Sources/VerticalTabsSidebar`+EmptyAreasAndFooter.swift:
- Around line 103-107: Remove the injectable nextEvent parameter from perform
and bind the event-pumping logic directly to AppKit’s production event source.
Update callers and tests accordingly, moving deterministic event-sequence
control into a test-target helper or isolated state-machine test without adding
test-only seams under Sources.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: bc9588f2-d7b3-4bc0-bd24-1f94b043567f

📥 Commits

Reviewing files that changed from the base of the PR and between 703341f and 251673a.

📒 Files selected for processing (1)
  • Sources/VerticalTabsSidebar+EmptyAreasAndFooter.swift

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: 251673abc5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@kenifxyz

Copy link
Copy Markdown
Author

@austinywang any chance i could get a review on this please? would really improve the quality of life of cmux!

@kenifxyz
kenifxyz force-pushed the feature/sidebar-empty-area-window-drag branch from 251673a to 1e95362 Compare August 5, 2026 03:36
@cursor

cursor Bot commented Aug 5, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cmuxTests/TitlebarInteractiveControlTests.swift`:
- Around line 324-340: The pressWithoutMovementIsNotADrag test should also
verify mouse-up replay, not just that dragging is suppressed. After
SidebarEmptyAreaWindowDrag.perform returns, dequeue the queued event and assert
it is the original mouse-up, and add equivalent coverage for movement below the
drag threshold to ensure both non-drag paths repost the terminating event.

In `@Sources/VerticalTabsSidebar`+EmptyAreasAndFooter.swift:
- Around line 561-613: Convert SidebarEmptyAreaWindowDrag from a static
namespace into a constructable `@MainActor` handler with immutable nextEvent and
drag-threshold dependencies. Move pumpTrackingEvent and perform to instance
methods, remove the static-only entry points, and update each AppKit boundary to
create or receive the handler and call its instance method while preserving
injectable event-pump behavior for tests.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f4365033-1961-4f10-8b6c-fdf9d2cdf47a

📥 Commits

Reviewing files that changed from the base of the PR and between 2f3d922 and 1e95362.

📒 Files selected for processing (4)
  • Sources/Sidebar/AppKitList/SidebarWorkspaceTableClipView.swift
  • Sources/Sidebar/AppKitList/SidebarWorkspaceTableViewImpl.swift
  • Sources/VerticalTabsSidebar+EmptyAreasAndFooter.swift
  • cmuxTests/TitlebarInteractiveControlTests.swift

Comment thread cmuxTests/TitlebarInteractiveControlTests.swift Outdated
Comment thread Sources/VerticalTabsSidebar+EmptyAreasAndFooter.swift Outdated
@austinywang

austinywang commented Aug 7, 2026 •

Copy link
Copy Markdown
Contributor

Maintainer follow-up is complete on the upstream branch, now at 7cf6ef4435b.

Review fixes:

  • 3c55681ad4 replaces the static namespace with a constructable, injected controller.
  • faca7e8f22 verifies mouse-up replay for both click paths.
  • 6a93e43cca separates ownership types and wires the Xcode target.
  • 9b3c51757a, 8d27e9457a, and 3055c56349 remove the pre-existing Xcode 26.1 test blocker, make replay precision AppKit-safe, and eliminate branch-introduced Swift warnings.
  • a5cea389853 keeps the unreachable SwiftUI bridge out of the full-height row background.
  • cafe5a5592d handles event cancellation and inactive-window first mouse.
  • 1004eb85f39 completes the one-major-type-per-file policy cleanup.
  • 7cf6ef4435b adds CodeRabbit's requested detached-view event-source assertion and documents the AppKit handoff invariant.

The latest focused workflow run 31148661946 completed successfully on the updated branch. On the same upstream tip, the canonical structured review reports no findings, the cmux architecture policy is clean, Xcode project normalization and all 652 test-file wiring checks pass, and the merge simulation against current origin/main is clean.

The latest review feedback is fully addressed:

  • CodeRabbit's detached-view assertion request is fixed in 7cf6ef4435b; its thread remains open only until the fix is present on the PR head.
  • Cursor's stale-event suggestion is rejected because Apple explicitly requires “The original mouse-down event” for NSWindow.performDrag(with:): https://developer.apple.com/documentation/appkit/nswindow/performdrag(with:). The tracked drag locations only decide when the threshold is crossed; 7cf6ef4435b records that invariant at the call site. The Cursor thread has a justification reply and is resolved.

This PR still points to kenifxyz/cmux@1004eb85f39, while the complete upstream branch is manaflow-ai/cmux@7cf6ef4435b. @kenifxyz, please fast-forward the fork branch once more so #9212 can contain the final review fix and rerun its checks. Under the origin-only push constraint, maintainers cannot make the upstream branch become the cross-repository PR head.

@austinywang

Copy link
Copy Markdown
Contributor

Final upstream tip manaflow-ai/cmux@1004eb85f39 is review-clean and its exact-head focused workflow is green: https://github.com/manaflow-ai/cmux/actions/runs/31144098678

@kenifxyz, please fast-forward kenifxyz/cmux:feature/sidebar-empty-area-window-drag to that tip so this cross-fork PR can run its required checks. Full maintainer evidence: #9212 (comment)

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cmuxTests/TitlebarInteractiveControlTests.swift`:
- Around line 403-409: Update the detached-view test around
SidebarEmptyAreaWindowDragController to count invocations of the injected
nextEvent closure, then assert that count remains zero alongside the existing
passThrough and performDrag assertions.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 68afc8f3-8159-4fd9-b3b5-e39db866c7c1

📥 Commits

Reviewing files that changed from the base of the PR and between 1e95362 and 1004eb8.

📒 Files selected for processing (9)
  • Sources/Sidebar/AppKitList/SidebarWorkspaceTableClipView.swift
  • Sources/Sidebar/AppKitList/SidebarWorkspaceTableViewImpl.swift
  • Sources/Sidebar/SidebarEmptyAreaWindowDragController.swift
  • Sources/Sidebar/SidebarEmptyAreaWindowDragOutcome.swift
  • Sources/Sidebar/SidebarEmptyAreaWindowDragTrackingEvent.swift
  • Sources/VerticalTabsSidebar+EmptyAreasAndFooter.swift
  • cmux.xcodeproj/project.pbxproj
  • cmuxTests/AppDelegateEqualizeSplitsShortcutTests.swift
  • cmuxTests/TitlebarInteractiveControlTests.swift

Comment thread cmuxTests/TitlebarInteractiveControlTests.swift

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 1004eb8. Configure here.

Comment thread Sources/Sidebar/SidebarEmptyAreaWindowDragController.swift
@austinywang

Copy link
Copy Markdown
Contributor

Final review follow-up is now manaflow-ai/cmux@7cf6ef4435b; its focused run is green and canonical review is clean: https://github.com/manaflow-ai/cmux/actions/runs/31148661946

@kenifxyz, please fast-forward the fork branch from 1004eb85f39 to 7cf6ef4435b so #9212 contains the last CodeRabbit test assertion. Full evidence: #9212 (comment)

@coderabbitai coderabbitai 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Sources/Sidebar/SidebarEmptyAreaWindowDragController.swift (1)

21-24: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Reject invalid drag thresholds.

dragThreshold accepts negative and non-finite values. A negative value starts dragging on the first tracked movement. A NaN value prevents any drag because distance >= dragThreshold is always false. Validate the threshold before storing it so the controller cannot represent an invalid drag policy.

As per coding guidelines, Swift changes must not leave invalid state representable.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Sources/Sidebar/SidebarEmptyAreaWindowDragController.swift` around lines 21 -
24, Validate dragThreshold in the initializer of
SidebarEmptyAreaWindowDragController before storing it, rejecting negative and
non-finite values so only valid finite non-negative thresholds can be
represented. Preserve the existing default and nextEvent behavior while ensuring
invalid input cannot initialize the controller.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@Sources/Sidebar/SidebarEmptyAreaWindowDragController.swift`:
- Around line 21-24: Validate dragThreshold in the initializer of
SidebarEmptyAreaWindowDragController before storing it, rejecting negative and
non-finite values so only valid finite non-negative thresholds can be
represented. Preserve the existing default and nextEvent behavior while ensuring
invalid input cannot initialize the controller.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a0001825-b7e2-4be1-ac21-cec2aff2f3d1

📥 Commits

Reviewing files that changed from the base of the PR and between 1004eb8 and 7cf6ef4.

📒 Files selected for processing (2)
  • Sources/Sidebar/SidebarEmptyAreaWindowDragController.swift
  • cmuxTests/TitlebarInteractiveControlTests.swift

@austinywang

Copy link
Copy Markdown
Contributor

Threshold-validation follow-up is complete on the upstream branch at f7ee18b9bfb.

This fixes CodeRabbit’s outside-diff threshold finding at the controller ownership boundary and adds a real red/green regression history.

@kenifxyz, please fast-forward kenifxyz/cmux:feature/sidebar-empty-area-window-drag from 7cf6ef4435b to f7ee18b9bfb so #9212 contains the completed follow-up. Under the origin-only push constraint, maintainers cannot update the cross-repository PR head directly.

@austinywang

Copy link
Copy Markdown
Contributor

Final upstream evidence for f7ee18b9bfbe8219b087cec05d4b06310ac8e0e6 is complete:

@kenifxyz, please fast-forward the fork PR branch to f7ee18b9bfb so these final commits and checks become the #9212 head. I will keep monitoring and close out the PR checks/reviews once synchronized.

@austinywang

Copy link
Copy Markdown
Contributor

@kenifxyz One-hour synchronization follow-up: #9212 still points to 7cf6ef4435b, while the complete reviewed tip is manaflow-ai/cmux@f7ee18b9bfb.

From a clone where origin is your fork, this fast-forwards the PR branch:

git fetch https://github.com/manaflow-ai/cmux.git feature/sidebar-empty-area-window-drag
git push origin FETCH_HEAD:feature/sidebar-empty-area-window-drag

The final tip has a green exact-head focused run, a clean canonical autoreview, a clean cmux policy gate, and a clean merge simulation against current main. I am monitoring and will close out required PR checks as soon as the head updates.

@kenifxyz

kenifxyz commented Aug 7, 2026

Copy link
Copy Markdown
Author

Synced to f7ee18b9bfb, then pushed one commit on top: 14c454e719 removes a test assertion that fails on macOS 26.

The branch is now one commit ahead of manaflow-ai/cmux:feature/sidebar-empty-area-window-drag, so please rebase onto it rather than force-pushing, or the fix will be dropped silently.

The bug: two tests failed on macOS 26 and no runner could see it

cmuxTests/SidebarEmptyAreaWindowDragTests was green on warp-macos-15-arm64-6x but red locally on macOS 26.3.1. At 7cf6ef4435b, pressWithoutMovementIsNotADrag and movementBelowThresholdStaysAClick both failed on the same line in expectReplayedMouseUp:

#expect(replayed.locationInWindow == original.locationInWindow)
replayed (40.0, -1008.0)  vs  original (40.0, 80.0)
replayed (41.0, -1007.0)  vs  original (41.0, 81.0)

x was preserved, y was off by exactly -1088 in both cases.

makeWindow() builds a 240x320 window and never orders it on screen or pins an origin, so AppKit cascades it and its screen origin.y becomes 1440 - (320 + 32) = 1088 on a 2560x1440 display. On the postEvent to nextEvent round trip AppKit reconstitutes the event and recomputes locationInWindow by subtracting that origin, treating the queued point as screen-absolute. x survives because origin.x is 0.

So the assertion tracked display geometry and AppKit's event-reconstitution behaviour, which differs across macOS majors, rather than replay itself. The headless macOS 15 runner does not reproduce it, which is why every exact-head check stayed green while the suite was red on real macOS 26 hardware.

To be clear, this was a test-fixture bug and not a product bug. The tests covering actual drag behaviour all passed, and the controller is fine.

14c454e719 drops the location comparison and records why in a comment so it does not get re-added. Replay is still established by the type, windowNumber, eventNumber, timestamp, clickCount and modifierFlags comparisons, which is what the original review asked for. All 7 tests now pass locally on macOS 26.3.1:

✔ movementBelowThresholdStaysAClick        ✔ pressWithoutMovementIsNotADrag
✔ dragPastThresholdMovesWindowAndRestoresMovability
✔ cancelledSequenceDoesNotFallThrough      ✔ nativeEmptyAreaOwnersAcceptFirstMouse
✔ viewWithoutWindowIsNotADrag              ✔ invalidThresholdsFailFast
** TEST SUCCEEDED **

Objection to c57c5d928a

precondition(
    dragThreshold.isFinite && dragThreshold >= 0,
    "Sidebar drag threshold must be finite and non-negative"
)

Both production call sites construct the controller with no arguments:

private let emptyAreaWindowDragController = SidebarEmptyAreaWindowDragController()

dragThreshold therefore always takes its default of 4, and nothing in the product ever passes a value. The only callers that vary it are the three assertions inside invalidThresholdsFailFast, which exist to trip this precondition. The validation guards a state that cannot be reached, and as a precondition it is a production crash path for an input that cannot occur. That cuts against the repo guidance to validate at boundaries and trust internal flow, and to avoid handling scenarios that cannot happen.

The cost is also measurable: invalidThresholdsFailFast takes 4.787s of the suite's 4.788s total, because processExitsWith spawns a subprocess per case. Three process launches to prove a hardcoded 4 is not NaN.

I would rather revert that commit and its tests, but it is your call since it closes a CodeRabbit finding. Flagging it rather than reverting unilaterally.

One process note

This PR reports maintainerCanModify = true, so "Allow edits by maintainers" is enabled and you can push directly to kenifxyz:feature/sidebar-empty-area-window-drag. The origin-only restriction looks like it sits in the automation rather than a GitHub permission. If this needs another round, pushing straight to the branch would avoid another fast-forward relay.

@kenifxyz

kenifxyz commented Aug 7, 2026

Copy link
Copy Markdown
Author

@kenifxyz One-hour synchronization follow-up: #9212 still points to 7cf6ef4435b, while the complete reviewed tip is manaflow-ai/cmux@f7ee18b9bfb.

From a clone where origin is your fork, this fast-forwards the PR branch:

git fetch https://github.com/manaflow-ai/cmux.git feature/sidebar-empty-area-window-drag
git push origin FETCH_HEAD:feature/sidebar-empty-area-window-drag

The final tip has a green exact-head focused run, a clean canonical autoreview, a clean cmux policy gate, and a clean merge simulation against current main. I am monitoring and will close out required PR checks as soon as the head updates.

done!

@kenifxyz

Copy link
Copy Markdown
Author

@austinywang branch is synced at 14c454e719 and confirmed 0 commits behind origin/main. Both open items from the comment above are resolved: the macOS 26 test fix is in, and the precondition objection is flagged for your call. Could you take a look and run the required checks when you get a chance?

@kenifxyz
kenifxyz force-pushed the feature/sidebar-empty-area-window-drag branch from 14c454e to 9570dd4 Compare August 13, 2026 08:18
@austinywang
austinywang force-pushed the feature/sidebar-empty-area-window-drag branch from 9570dd4 to f9ee034 Compare August 24, 2026 23:45
@greptile-apps

greptile-apps Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds native window dragging from otherwise empty sidebar space while preserving existing click behavior.

  • Introduces a synchronous AppKit event-tracking controller with a four-point drag threshold, mouse-up replay, cancellation handling, and temporary window-movability support.
  • Connects the behavior to empty regions owned by the sidebar table and clip view, including first-mouse handling for inactive windows.
  • Documents that the overlapping SwiftUI empty-area target must not participate in native hit testing.
  • Registers the new production files in the Xcode project and adds tests for dragging, clicks, jitter, cancellation, detached views, and first-mouse behavior.

Confidence Score: 5/5

The PR appears safe to merge, with no concrete changed-code failure identified.

The new behavior is limited to single presses in native sidebar regions classified as empty, preserves non-drag clicks by replaying the terminating mouse-up, bypasses row and double-click handling, and restores temporary window state after dragging.

Important Files Changed

Filename Overview
Sources/Sidebar/SidebarEmptyAreaWindowDragController.swift Adds the main-actor event-tracking loop that distinguishes clicks, cancellations, and threshold-crossing window drags.
Sources/Sidebar/AppKitList/SidebarWorkspaceTableViewImpl.swift Routes single presses outside table rows through the new drag controller while retaining row and double-click handling.
Sources/Sidebar/AppKitList/SidebarWorkspaceTableClipView.swift Makes empty viewport space accept first mouse and participate in window dragging.
Sources/VerticalTabsSidebar+EmptyAreasAndFooter.swift Clarifies ownership of native sidebar hit testing without changing SwiftUI behavior.
cmux.xcodeproj/project.pbxproj Registers the three new sidebar drag source files in the application target.
cmuxTests/TitlebarInteractiveControlTests.swift Adds focused coverage for drag thresholds, click replay, cancellation, detached views, and inactive-window input.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Single mouse-down in sidebar] --> B{Native hit target}
    B -->|Workspace row| C[Existing table handling]
    B -->|Empty table or clip area| D[Track drag and mouse-up events]
    D --> E{Travel at least 4 points?}
    E -->|Yes| F[Temporarily enable window movement]
    F --> G[Perform window drag]
    E -->|No, mouse-up| H[Repost mouse-up]
    H --> I[Continue normal mouse-down handling]
    D -->|Cancelled| J[Consume cancelled sequence]
Loading

Reviews (1): Last reviewed commit: "Merge current main and finalize sidebar ..." | Re-trigger Greptile

@austinywang

Copy link
Copy Markdown
Contributor

Maintainer closeout for synchronized PR head f9ee034:\n\n- Fast-forwarded the reviewed branch onto current main and updated the fork PR head with an exact --force-with-lease (observed old head 9570dd4).\n- Kept the drag threshold as the controller's private 4pt policy; removed the unreachable production precondition and process-exit tests.\n- Removed the macOS-window-geometry-sensitive locationInWindow replay assertion; event identity and replay behavior remain covered.\n- The unrelated AppDelegateEqualizeSplitsShortcutTests edit is no longer in the PR diff.\n\nVerification: current-base canonical autoreview clean (Codex 0.95), cmux policy clean, PBX test-wiring lint passed for 702 files, project normalization and diff checks passed, and all 7 GitHub PR checks are green.\n\nThe tagged reload was attempted twice but the host ran out of disk space during GhosttyKit/SwiftPM diagnostics (NoSpaceLeft); no app was launched or dogfood approval claimed. PR remains open and mergeable pending tagged dogfood and explicit merge approval.

@austinywang

Copy link
Copy Markdown
Contributor

Final gate after base 3084031: current-base autoreview and cmux policy are clean, all 7 PR checks are green, and GitHub reports the PR mergeable. The only remaining gate is runtime dogfood; the tagged build cannot complete on this host while disk-full SwiftPM/Metal diagnostics persist. No merge was performed.

@austinywang

Copy link
Copy Markdown
Contributor

Follow-up build attempt: using the preprovisioned cached GhosttyKit and disabled automatic package resolution reached cmux Swift compilation, but Xcode failed with NoSpaceLeft while writing index/object files. No source/compiler diagnostic was reported. The tagged DerivedData was removed afterward; no code or PR changes were made.

@kenifxyz
kenifxyz requested a review from austinywang August 31, 2026 06:01
@austinywang
austinywang force-pushed the feature/sidebar-empty-area-window-drag branch from f9ee034 to e43cf11 Compare September 1, 2026 10:38
@vercel

vercel Bot commented Sep 1, 2026

Copy link
Copy Markdown

@austinywang is attempting to deploy a commit to the Manaflow Team on Vercel.

A member of the Team first needs to authorize it.

kenifxyz and others added 16 commits September 1, 2026 03:51
The empty space below the last workspace group did not move the window
when dragged, though the titlebar strip above the sidebar did. macOS
users expect background-drag anywhere in a sidebar, and issue manaflow-ai#3119
records the non-minimal sidebar as already behaving that way.

Track the press synchronously from mouseDown with nextEvent(matching:),
the same shape as SidebarDividerTrackingView, rather than through an
NSGestureRecognizer. NSWindow.performDrag(with:) runs its own modal
tracking loop and consumes the terminating mouse-up, so a recognizer
that calls it never receives the event that would drive it back to
.possible: it parks in a terminal state, reset() never runs, and it
stops recognizing for the rest of the window's life.

A press that never travels 4pt is handed back intact - the mouse-up is
reposted before falling through, because NSTableView's own mouseDown
tracking loop blocks waiting for it. Double-clicks bypass the drag path
entirely so doubleClickEmptyArea() still fires, and the table view gates
on row(at:) < 0 so rows keep their existing click handling.

Fixes manaflow-ai#9203
The vertically expanding SidebarEmptyArea is mounted as a full-height
background behind the rows in workspaceScrollContent, where a SwiftUI
shield sized to the rows stops end-of-list interactions falling through.
That shield cannot block an AppKit view, so a representable there would
out-hit-test it and turn row presses into window drags.

The AppKit sidebar covers this region through the table and clip views,
so only the legacy SwiftUI sidebar loses empty-area window drag.
@austinywang
austinywang force-pushed the feature/sidebar-empty-area-window-drag branch from e43cf11 to 04d2929 Compare September 1, 2026 10:55
@austinywang

Copy link
Copy Markdown
Contributor

Top-level review disposition, re-checked against PR HEAD 04d29299a66ab0fa36452977d27074ad7b0da105:

Review Finding / ask Disposition Evidence
Codex review 4816331105 No major issues; thumbs-up review. already-fixed The reviewed drag path remains unchanged at current HEAD.
CodeRabbit review 4816626938 (outside diff) Remove the production-injected event-pump seam. fix SidebarEmptyAreaWindowDragController is a constructable @MainActor owner in its own file; the injected source is the deterministic test seam and the default is AppKit's real event pump.
CodeRabbit review 4860765055 Assert mouse-up replay and use an instance controller. fix Both click paths dequeue/repost and assert replay identity; both AppKit boundaries own controller instances.
CodeRabbit review 4879977817 Assert detached views do not call nextEvent. fix viewWithoutWindowIsNotADrag counts the injected calls and expects zero.
CodeRabbit review 4880139200 (outside diff) Reject invalid configurable thresholds. disagree The shipped policy is a private, fixed 4-point threshold; no production caller can supply an invalid value. The unreachable precondition/process-exit test was removed to avoid a production crash path and expensive fixture-only subprocesses.
Cursor review 4879987995 Pass the threshold-crossing dragged event to performDrag. disagree AppKit documents performDrag(with:) as requiring the original mouse-down event. The tracked point only gates handoff; the source comment records this invariant.
Greptile summary 5403037722 Safe implementation summary; no concrete finding. already-fixed Controller lifecycle, click preservation, cancellation, first-mouse handling, and Xcode wiring are present and covered.
Cubic notice 5127762040 Review unavailable due quota; no code ask. already-fixed No actionable finding was supplied.
Vercel comment 5492685937 Team authorization required for deployment. disagree This PR is macOS/AppKit-only and has no web preview; the authorization-gated Vercel contexts are not code-required checks.

The five inline threads are all resolved with replies. No review is CHANGES_REQUESTED; the current review decision is empty/non-blocking. This rebase retained the behavior and removed no requested coverage.

@austinywang

Copy link
Copy Markdown
Contributor

Final review audit (re-checked against PR HEAD)

HEAD is 04d29299a66ab0fa36452977d27074ad7b0da105. The five live review threads are all isResolved: true, and each has at least one visible reply. The table records every actionable review root and top-level review body; status, invocation, and rate-limit notices with no code ask are summarized below.

Thread IDs re-checked: PRRT_kwDORDHQWM6VBOxS, PRRT_kwDORDHQWM6WiJpI, PRRT_kwDORDHQWM6WiJpJ, PRRT_kwDORDHQWM6XLK2-, and PRRT_kwDORDHQWM6XLMdC.

Comment/review ID Author File:line Ask Disposition Commit SHA
3680777545 chatgpt-codex-connector[bot] Sources/VerticalTabsSidebar+EmptyAreasAndFooter.swift:629 Keep the native drag view out of the full-height row background. fix a8e3111b2453a001f84b42f098d0afce00a47cd2
4816331105 chatgpt-codex-connector[bot] — Codex found no major issues. already-fixed 04d29299a66ab0fa36452977d27074ad7b0da105
4816626938 coderabbitai[bot] Sources/VerticalTabsSidebar+EmptyAreasAndFooter.swift:103-107 Remove the injected event-pump seam from production code. disagree 04d29299a66ab0fa36452977d27074ad7b0da105
3717748139 coderabbitai[bot] cmuxTests/TitlebarInteractiveControlTests.swift:~324-340 Assert mouse-up replay on both non-drag paths. fix 7f0f9bfe456c422a6196243c7443064f346d9448
3717748141 coderabbitai[bot] Sources/VerticalTabsSidebar+EmptyAreasAndFooter.swift:~561-613 Replace the static namespace with a constructable handler. fix 23639bb42fe063e680e62f896611c65c2e9f7efe
4860765055 coderabbitai[bot] cmuxTests/TitlebarInteractiveControlTests.swift:324-340; Sources/VerticalTabsSidebar+EmptyAreasAndFooter.swift:561-613 Top-level summary of the replay and constructable-handler findings. fix 7f0f9bfe456c422a6196243c7443064f346d9448
3733453041 coderabbitai[bot] cmuxTests/TitlebarInteractiveControlTests.swift:414 Assert a detached view does not call nextEvent. fix 02ff8bad2eb334c267ff4e7faaa55006d23ff5
4879977817 coderabbitai[bot] cmuxTests/TitlebarInteractiveControlTests.swift:403-414 Top-level summary of the detached-view test gap. fix 02ff8bad2eb334c267ff4e7faaa55006d23ff5
3733462297 cursor[bot] Sources/Sidebar/SidebarEmptyAreaWindowDragController.swift:83 Pass the threshold-crossing event to performDrag. disagree 7ad21254b2ee3bf365b004fe0ae3175899da71ff
4879987995 cursor[bot] Sources/Sidebar/SidebarEmptyAreaWindowDragController.swift:83 Top-level Bugbot report of the stale-event concern. disagree 7ad21254b2ee3bf365b004fe0ae3175899da71ff
4880139200 coderabbitai[bot] Sources/Sidebar/SidebarEmptyAreaWindowDragController.swift:21-24 Reject negative and non-finite configurable thresholds. disagree c001376168ce7ceeddaac52c6e259c2cddc3ec81
5403037722 greptile-apps[bot] — Greptile supplied a positive summary and no concrete ask. already-fixed 04d29299a66ab0fa36452977d27074ad7b0da105
5127762040 cubic-dev-ai[bot] — Review unavailable because the monthly quota was exhausted; no code ask. already-fixed 04d29299a66ab0fa36452977d27074ad7b0da105
5492685937 vercel[bot] — Authorize the Manaflow Vercel deployment. disagree 04d29299a66ab0fa36452977d27074ad7b0da105

The seam disagreement is intentional: the controller's event source is a constructor-injected production dependency with AppKit as its default, which is the testable ownership boundary required by cmux architecture. The threshold disagreement is intentional: production callers cannot provide a threshold; the shipped policy is a private fixed 4-point value. The performDrag disagreement follows Apple's documented requirement that the argument be the original mouse-down event.

Current gates: GitHub reports MERGEABLE and no review is CHANGES_REQUESTED, but the review decision is still REVIEW_REQUIRED. The exact-HEAD hosted run 33564238605 passed and executed all six sidebar Swift Testing tests. The AWS compile produced the app/test bundle; test orchestration could not start because the headless SSH session lacked testmanagerd.control. The two Vercel status contexts are authorization failures for optional deployment previews; no required status checks are configured on main. There is no new actionable review activity after the last push; the newer CodeRabbit replies are rate-limit notices only. Because live UI end-to-end dogfood evidence and the required human review are still missing, this closeout does not merge the PR.

@teamleaderleo

Copy link
Copy Markdown
Collaborator

Thank you for this! The sidebar empty-area drag fix shipped in #12162 (commit 50ec919). You had this first, so closing this superseded PR :)

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.

Empty area below the workspace list in the sidebar isn't a window-drag region

3 participants