fix(cloud): isolate sidebar row hover targets
Problem
Hovering New Cloud Machine in the Cloud Machines sidebar could highlight the OpenCode row instead of the view under the pointer.
Fix
Cloud tree hover now asks AppKit which view owns the window-space pointer before assigning a row. The shared cmuxHitTest(windowPoint:) path supplies the superview-space coordinate required by both unflipped AppKit and flipped SwiftUI content hosts. Hover refresh also keeps NSWindow.mouseLocationOutsideOfEventStream in its native window coordinate space, so a moved window cannot remap the pointer to another row. Menu-pinned and native-drag hover ownership still take precedence, while selection and row action rendering remain unchanged.
Validation
python3 scripts/verify-local.py --affected origin/main --swift-changed— passed the affected localization-defaults, app-source wiring, test-wiring, and feature-flag checks.python3 scripts/verify-local.py --only swift-syntax --swift Sources/Cloud/CloudTreeNSOutlineView.swift cmuxTests/CloudTreeHeaderActionsTests.swift— passed../scripts/sync-test-wiring --checkandgit diff --check— passed.- Focused hosted run 37873929934 on
a8012ed2efd29ad134def4d3c3037deb5046b291passed all 11CloudTreeHeaderActionsTeststests, including flipped and unflipped overlapping-sibling ownership and the moved-window refresh regression. - Red-before evidence: focused run 37865127155 on
3aae873669b2d6f0f57f409bec3e6c9aaa344647failed the flipped-host cases before the hit-test coordinate repair; the same selector is green above on the repaired head. - The moved-window regression also failed all three refresh assertions at
cba9556f8a579752842f0cffc17de785ca6386bein run 37871570864. Both red runs and the final green run usescripts/run-e2e.sh cmuxTests/CloudTreeHeaderActionsTests --ref <sha> --no-video. - Exact-head tagged non-launching fleet build
ce5741e90058c9ecca9f78dcpassed oncmux10s-Mac-mini.localwith tagissue-18689-cloud-hover-docs, local backend mode, and artifact digestsha256:8a4c316d04225a07bdae6f1eabf54aa186538726a31b97acec74abab1ef401a7; workspace cleanup completed. HQ publication returned HTTP 502, so no HQ download link is available. - Final-head macOS compile admission passed. The first attempt of the broader changed-suite lane in run 37873859085 crashed during Xcode test enumeration (
IDELaunchServicesLauncher,childPID > 0) before tests ran; rerun attempt 2 passed. - No interactive app launch or UI capture was performed: this PR has no
dev-buildlabel, and the workflow's optional dogfood proof is therefore skipped.
Changelog
Fixed: Cloud sidebar hover stays with the row that owns the pointer.
Issues
Fixes https://github.com/manaflow-ai/cmux/issues/18689
Related: https://github.com/manaflow-ai/cmux/issues/16385
Issue lifecycle
- Pickup comment: https://github.com/manaflow-ai/cmux/issues/18689#issuecomment-6070748847
- Resolution comment: pending until the fix PR merges.
Impact map
- Source of truth:
CloudTreeNSOutlineViewowns one hover target and the AppKit window-space hit-test boundary;CloudTreeCellViewandCloudTreeCreateActionViewcontinue to render the existing shared row/action states. - Adjacent paths inspected: New Workspace, New Cloud Machine, My Devices/provider/account rows, row descendants, keyboard selection, menu pinning, and native drag lifting; no action routing or localized strings changed.
- Cross-surface effects: only transient pointer ownership and refresh coordinate conversion changed. Pressed/disabled states, light/dark colors, localization, selection, accessibility, and create actions remain on their existing paths.
- Regression coverage:
CloudTreeHeaderActionsTestsexercises sibling hit-target isolation in both host orientations plus refresh after a moved window origin; the exact hosted run executed all 11 cases. - Read-only correctness review of the repair found no concrete defects; the final follow-up adds only a regression-test doc comment.
- Residual limit: the test uses native AppKit event injection rather than a full interactive dogfood tour; the exact-head tagged app build passed without launch.
Mergeability
- Base SHA:
ce6be93cf232b381befbfcac8ff107f14fd40a02 - Head SHA:
a8012ed2efd29ad134def4d3c3037deb5046b291 - Conflict-only gate: pass (
merge-gate.sh --conflict-only)