macOS: add WindowEvent::PointerButton::is_macos_activation_click

Apps 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. Motivated by slint-ui/slint#10451.

Always return `true` from `acceptsFirstMouse:`, and tag the resulting
`PointerButton` events with `is_macos_activation_click: true` (on both
the activating left press and its matching release) so the app can
short-circuit the whole gesture with a single check:

    WindowEvent::PointerButton { is_macos_activation_click: true, .. } => return,

Replaces an earlier callback-based design (`accepts_first_mouse` on
`ApplicationHandlerExtMacOS`) that mapped more closely to AppKit but
didn't fit winit's event-driven model and required re-entrancy handling.

Also removes `WindowAttributesMacOS::with_accepts_first_mouse`, which is
now redundant — apps that want to reject activation clicks check the
flag on the per-event instead.
This commit is contained in:
Till Adam
2026-06-18 22:39:35 +02:00
committed by Simon Hausmann
parent 92b643c3f1
commit 6a8a334426
15 changed files with 95 additions and 21 deletions

View File

@@ -329,6 +329,25 @@ pub enum WindowEvent {
primary: bool,
button: ButtonSource,
/// Whether this event is part of the click that activated an otherwise inactive window.
///
/// On macOS, AppKit normally consumes the click that brings a window forward without
/// delivering it as a regular mouse event (controlled by [`acceptsFirstMouse:`]). Winit
/// always delivers it, but tags both the activating press *and* its matching release
/// with this flag so applications can short-circuit the whole gesture with a single
/// check — e.g. ignore activation clicks for destructive or button-like targets while
/// accepting them for low-risk actions (selection, scrolling).
///
/// ## Platform-specific
///
/// - **Only available on macOS.** Always `false` on every other platform.
/// - Only ever `true` for the left mouse button. Intervening drag motion (delivered as
/// [`WindowEvent::PointerMoved`]) is not tagged; applications that care about drags
/// during the activation gesture must track that state themselves.
///
/// [`acceptsFirstMouse:`]: https://developer.apple.com/documentation/appkit/nsview/acceptsfirstmouse(_:)
is_macos_activation_click: bool,
},
/// Multi-finger hold gesture on the touchpad or touchscreen without movement.
@@ -1689,6 +1708,7 @@ mod tests {
state: event::ElementState::Pressed,
position: (0, 0).into(),
button: event::ButtonSource::Unknown(0),
is_macos_activation_click: false,
});
with_window_event(PointerButton {
device_id: None,
@@ -1699,6 +1719,7 @@ mod tests {
finger_id: fid,
force: Some(event::Force::Normalized(0.0)),
},
is_macos_activation_click: false,
});
with_window_event(PinchGesture {
device_id: None,