Skip to content

fix: refresh macOS cursor monitor after display changes - #1739

Draft
dudemeister23 wants to merge 1 commit into
cjpais:mainfrom
dudemeister23:codex/fix-cursor-monitor-overlay
Draft

fix: refresh macOS cursor monitor after display changes#1739
dudemeister23 wants to merge 1 commit into
cjpais:mainfrom
dudemeister23:codex/fix-cursor-monitor-overlay

Conversation

@dudemeister23

Copy link
Copy Markdown

Before Submitting This PR

Please confirm you have done the following:

  • I have searched existing issues and pull requests, including closed ones, to ensure this is not a duplicate
  • I have read CONTRIBUTING.md

If this is a feature or change that was previously closed/rejected:

Not applicable. This is a bug fix following the merged multi-monitor overlay changes.

Human Written Description

Fix for permanent UI location on fallback main monitor after monitors are disconnected and reconnected.

Regular reconnection is a common workflow for laptop owners, and this avoids inconsistent behavior between starting the app and using it after reconnection.

Related Issues/Discussions

Follow-up to #175 and #969.

Related reports: #811 and Discussion #655.

Community Feedback

Multi-monitor overlay behavior has previously been reported and confirmed in #811 and Discussion #655. This PR addresses the remaining macOS behavior after disconnecting or reconnecting displays.

Testing

  • Added three unit tests covering Retina cursor conversion, invalid scale factors, and negative-origin monitor matching.
  • Focused overlay tests passed: 3 passed.
  • Full Rust library test suite passed: 131 passed.
  • cargo fmt --manifest-path src-tauri/Cargo.toml -- --check passed.
  • cargo clippy --manifest-path src-tauri/Cargo.toml --lib --tests completed successfully, with only existing warnings in unrelated files.
  • Built a production macOS app bundle, signed it locally, installed it, and launched it successfully.
  • Manually verified overlay placement on the cursor's monitor before disconnecting an external display, while disconnected, and after reconnecting it.
  • Debug logs confirmed successful overlay positioning with no cursor lookup, monitor enumeration, or primary-monitor fallback warnings.

Screenshots/Videos (if applicable)

Not included. The behavior was verified through a live monitor disconnect and reconnect cycle plus debug logs.

AI Assistance

  • No AI was used in this PR
  • AI was used (please describe below)

If AI was used:

  • Tools used: OpenAI Codex
  • How extensively: Codex helped diagnose the root cause, implement the focused patch and tests, and run validation. I manually reproduced the issue, validated the fix through monitor disconnect and reconnect testing, and made the final decisions on scope and behavior.

@cjpais

cjpais commented Jul 21, 2026

Copy link
Copy Markdown
Owner

@dudemeister23 can you write explicit before and after expectations, it's not exactly clear to me what the problem this is solving is. just looking so I can reproduce it with my external monitor and validate the fix after I can reproduce the bug itself

@dudemeister23

Copy link
Copy Markdown
Author

@cjpais Hi! The sequence for me is it works fine when I start the app while the MacBook is connected to external monitors. Then, obviously, it still works fine when I disconnect the monitors because the laptop then only has the one screen that it needs to anchor to. But then, once I reconnect to the external monitor setup, the anchor is always the main monitor that is selected in that setup, as that is the fallback. And that's the diagnosis 5.6 Sol gave me when inspecting the state as I described the issue. See if you can reproduce this on your end. There may, of course, be many confounding factors. One monitor is attached via USB C, the other via HDMI. One is in vertical orientation and one is in horizontal orientation. And I'm running the Dev Beta 3 of macOS 27. So, if you can't reproduce this issue, it could, of course, be any number of those circumstances. Thanks for looking into it.

@cjpais

cjpais commented Jul 22, 2026

Copy link
Copy Markdown
Owner

At least I'm not able to replicate this with my external monitor, just wondering if you only experience this with all 3 monitors in use? or just two (built in and external I assume)? and if you are able to replicate with two please let me know how I can set my Mac in the same way

@dudemeister23

dudemeister23 commented Jul 23, 2026

Copy link
Copy Markdown
Author

@cjpais It definitely makes sense to try and reproduce this yourself. What I can say is that I am experiencing it on my setup on an M1 with two external monitors. And as I mentioned, there may be many confounding factors. I also cannot trigger it reliably in the sense of connecting and reconnecting those monitors. It will often work immediately after. But for example, this morning after reconnecting for a long time, the issue surfaced again.

The diagnosis that 5.6 Sol gave is illustrative in regards to that, and that's exactly what this fix constitutes. I'm giving you below its two sentence version of its description of the issue it found in the code.

On macOS, Handy obtains the cursor position from a long-lived Enigo instance that caches CGDisplay::main() when it is created, so after the display topology changes its Y-axis conversion can continue using stale main-display geometry. The resulting cursor coordinates no longer match Tauri’s freshly enumerated monitor bounds, causing get_monitor_with_cursor() to fall through to the primary-monitor fallback; this patch uses a fresh Tauri cursor query for each overlay placement so cursor and monitor data come from the same current display state.

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.

2 participants