Skip to content

Fix cursor overlay invisible on secondary monitors#48

Open
Catafal wants to merge 1 commit intofarzaa:mainfrom
Catafal:fix/multi-monitor-overlay-frame
Open

Fix cursor overlay invisible on secondary monitors#48
Catafal wants to merge 1 commit intofarzaa:mainfrom
Catafal:fix/multi-monitor-overlay-frame

Conversation

@Catafal
Copy link
Copy Markdown

@Catafal Catafal commented Apr 10, 2026

Feature

Fix multi-monitor cursor overlay rendering (resolves #24)

Summary

  • The blue cursor companion was invisible on any monitor that is not the primary display
  • Root cause: NSHostingView.frame uses window-local coordinates (always origin 0,0), but was being assigned screen.frame which has a non-zero origin for secondary monitors (e.g. {x:1920, y:0})
  • For a secondary monitor at x=1920, this placed the hosting view 1920pt to the right inside the window — completely off-screen

Changes

leanring-buddy/OverlayWindow.swift — one line in OverlayWindowManager.showOverlay():

// Before (broken for secondary monitors):
hostingView.frame = screen.frame

// After (correct — window-local coordinates):
hostingView.frame = CGRect(origin: .zero, size: screen.frame.size)

The NSPanel window itself is already positioned correctly at screen.frame.origin via OverlayWindow.init — only the content view frame needed fixing.

Why only the primary monitor worked before

Primary monitor has screen.frame.origin = (0,0), so screen.frame accidentally produced the correct window-local rect. Every secondary monitor has a non-zero origin and was broken.

Testing

  • GIVEN two monitors connected, WHEN ctrl+option pressed with mouse on secondary display, THEN cursor appears on that display ✓
  • GIVEN Claude responds with [POINT:x,y:label:screen2], THEN cursor animates to correct position on secondary display ✓
  • GIVEN only primary monitor, THEN behavior unchanged (origin 0,0 produces identical rect) ✓

Review Notes

All downstream coordinate math (convertScreenPointToSwiftUICoordinates, isCursorOnThisScreen, startNavigatingToElement) was already correct and required no changes. Verified by tracing the full coordinate pipeline across 3 independent passes.

Closes #24

NSView.frame uses window-local coordinates, not global screen coordinates.
For secondary monitors with non-zero origins (e.g. {1920,0}), setting
hostingView.frame = screen.frame displaced the SwiftUI content 1920pt
outside the window bounds, making the overlay invisible.

The window itself is correctly positioned via NSPanel.setFrame(screen.frame)
in OverlayWindow.init. Only the content view frame needs fixing.

Fixes farzaa#24

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

not working on multiple monitors

1 participant