-
Notifications
You must be signed in to change notification settings - Fork 1.2k
macOS: add dynamic accepts_first_mouse callback #4488
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
9b0b42b
959c126
6cf8480
7ea93ef
2cb9dce
aca5bc0
955851a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| use dpi::PhysicalPosition; | ||
|
|
||
| use crate::application::ApplicationHandler; | ||
| use crate::event_loop::ActiveEventLoop; | ||
| use crate::window::WindowId; | ||
|
|
@@ -49,4 +51,36 @@ pub trait ApplicationHandlerExtMacOS: ApplicationHandler { | |
| let _ = window_id; | ||
| let _ = action; | ||
| } | ||
|
|
||
| /// Called when the user clicks on an inactive window to determine whether the click should | ||
| /// also be processed as a normal mouse event. | ||
| /// | ||
| /// This corresponds to the [`acceptsFirstMouse:`] method on `NSView`, which receives the | ||
| /// triggering mouse event. Winit extracts the click position from that event and passes it | ||
| /// here so that the application can make per-click decisions, e.g. accept first mouse for | ||
| /// low-risk actions (selection, scrolling) but reject it for buttons or destructive actions. | ||
| /// | ||
| /// The default implementation returns `true`. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, but that'd mean that by returning
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point — I've clarified the docs in 6cf8480 to make the precedence explicit: when I've also added guidance in 2cb9dce on when to use one vs the other: use the static setting when a per-window value is sufficient, use the dynamic callback when you need to decide based on click position. |
||
| /// | ||
| /// Use `WindowAttributesMacOS::with_accepts_first_mouse` if a static, per-window value is | ||
| /// sufficient. Implement this method instead when you need to decide dynamically based on | ||
| /// *where* in the window the click landed (e.g. accept for the canvas area but reject for | ||
| /// toolbar buttons). | ||
| /// | ||
| /// When [`ApplicationHandler::macos_handler`] returns `Some`, this method takes precedence | ||
| /// over the static `WindowAttributesMacOS::with_accepts_first_mouse` setting. The static | ||
| /// value is only used as a fallback when this method cannot be called synchronously (e.g. | ||
| /// the handler is already borrowed due to re-entrancy). | ||
| /// | ||
| /// [`acceptsFirstMouse:`]: https://developer.apple.com/documentation/appkit/nsview/acceptsfirstmouse(_:) | ||
| #[doc(alias = "acceptsFirstMouse:")] | ||
| fn accepts_first_mouse( | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you add usage to the Or maybe just document when, as a user, you'd want to implement this vs.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in 2cb9dce — added |
||
| &mut self, | ||
| event_loop: &dyn ActiveEventLoop, | ||
| window_id: WindowId, | ||
| position: PhysicalPosition<f64>, | ||
| ) -> bool { | ||
| let _ = (event_loop, window_id, position); | ||
| true | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's the right approach to the problem, but boy do I not like the fallback behavior when we're re-entrant, I wish we could do something different - but I don't see a good solution, AppKit is hella re-entrant and that's hard to avoid. Spitballing, maybe making ApplicationHandlerExtMacOS take
&self, and dofn macos_handler(&self) -> Option<Box<dyn macos::ApplicationHandlerExtMacOS>>instead? That would push the re-entrancy to the user.Anyhow, not something we need to fix in this PR, such changes can be made later when we better understand the requirements.