Skip to content

macOS: add dynamic accepts_first_mouse callback#4488

Open
tilladam wants to merge 4 commits intorust-windowing:masterfrom
tilladam:dynamic-accepts-first-mouse
Open

macOS: add dynamic accepts_first_mouse callback#4488
tilladam wants to merge 4 commits intorust-windowing:masterfrom
tilladam:dynamic-accepts-first-mouse

Conversation

@tilladam
Copy link

Summary

  • Add ApplicationHandlerExtMacOS::accepts_first_mouse callback that receives the window ID and click position (PhysicalPosition<f64>), enabling per-click decisions about whether to accept first mouse on inactive windows.
  • Add EventHandler::handle_with_result for synchronous, re-entrant-safe handler dispatch that returns Option<R>. Refactor existing handle on top of it to eliminate duplication.
  • When the handler is unavailable (not set or re-entrant), the static accepts_first_mouse value from WindowAttributes is used as a fallback.

Motivated by slint-ui/slint#10451 — applications need per-click decisions to follow the macOS convention of accepting first mouse for low-risk actions (selection, scrolling) but rejecting it for buttons and destructive actions.

Implementation notes

  • acceptsFirstMouse: must return bool synchronously, so the handler is called via handle_with_result which returns None on re-entrancy instead of panicking.
  • The NSEvent parameter is Option<&NSEvent> per Apple's API contract (can be nil); nil falls back to the static default.
  • Coordinates use the same conversion as existing mouse event handlers (convertPoint_fromView + scale factor), with isFlipped providing top-left origin.

Test plan

  • cargo build -p winit-core / winit-appkit / winit — compiles
  • cargo test -p winit-core — passes
  • cargo test -p winit-common --features event-handler — 5 new tests pass:
    • handle_with_result returns value (normal path)
    • handle_with_result returns None when handler not set
    • handle_with_result returns None on re-entrancy via handle
    • handle_with_result returns None on re-entrancy via itself
    • handle still panics on re-entrancy (regression test)
  • cargo clippy -p winit-appkit — no warnings
  • cargo +nightly fmt -- --check — clean

@tilladam tilladam requested a review from madsmtm as a code owner February 15, 2026 21:27
Add an `accepts_first_mouse` callback to `ApplicationHandlerExtMacOS`
that receives the window ID and click position, enabling per-click
decisions about whether to accept first mouse on inactive windows.

This is needed for applications that want to follow the macOS convention
of accepting first mouse for low-risk actions (selection, scrolling) but
rejecting it for buttons and destructive actions.

The implementation dispatches synchronously via a new
`EventHandler::handle_with_result` method. When the handler is
unavailable (not set or re-entrant), the static `accepts_first_mouse`
value from `WindowAttributes` is used as a fallback.
@tilladam tilladam force-pushed the dynamic-accepts-first-mouse branch from 9e4e2f6 to 91b3567 Compare February 15, 2026 21:30
@madsmtm madsmtm added S - enhancement Wouldn't this be the coolest? DS - appkit Affects the AppKit/macOS backend labels Mar 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

DS - appkit Affects the AppKit/macOS backend S - enhancement Wouldn't this be the coolest?

Development

Successfully merging this pull request may close these issues.

2 participants