-
Notifications
You must be signed in to change notification settings - Fork 920
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
Allow the user to register the application delegate on macOS and iOS #3758
Conversation
ae4da6c
to
33670a2
Compare
33670a2
to
5b45632
Compare
39b651e
to
4a53350
Compare
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'm starting to understand the MacOS backend quite a bit now, the cleanup you have done so far is pretty amazing.
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'm not that familiar with observers, but it looks ok-ish? I know that it works by appkit basically signalling you when something happens and you can register a lot of observers.
Also does it affect performance/input latency in any aspect or it's all the same because macOS is just giant message passing infra already and dispatching observer is not slower than dispatching regular methods?
); | ||
// TODO(madsmtm): Use `MainThreadBound` once that is possible in `static`s. | ||
thread_local! { | ||
static GLOBAL: OnceCell<Rc<AppState>> = const { OnceCell::new() }; |
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.
What's the reason to Rc
thread local global? I'd assume the main reason is that the user creates it in Rc
and shares the pointer with winit, thus it's correctly ref-counted.
And you're using global here just for simplicity?
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.
Rc
I haven't really decided how I want to pass the state around yet, so I just went with something that worked, and matched the semantics of what we were doing before (Retained<ApplicationDelegate>
is basically the same as Rc<AppState>
).
thread local
That was to avoid a bit of unsafe
until I've released a version of objc2-foundation
with a const
MainThreadBound::new
. But I've worked around it with a helper for now instead.
global
I think that the only piece of state that has to actually be global (in Winit) is the ApplicationHandler
, since we have to access that from our overwritten WinitApplication
when (hackily) dispatching device events. But if I find a different way to implement that, then I might be able to remove this final piece of global state in Winit's AppKit backend.
I looked into it: On AppKit, when calling On UIKit, the delegate method is called directly, while the notification is emitted immediately afterwards. I'd suspect the performance impact of this PR to be very minimal, as UIKit still creates the In any case, you don't need to be concerned with buffering of notifications or other such shenanigans, the notifications are emitted at (basically) the same time as the methods are called. |
@kchibisov Just to make sure you didn't miss it |
@Korne127 miss what? I approved the PR long time ago... |
Sorry if I'm wrong, to me it just looked like you were expected to give feedback to the new changes / address Mads' answer to your question. |
I've asked for feedback just to confirm my assumption, otherwise I'd request changes. |
This looks absolutely fantastic. This would solve a lot of the problems I've had with Winit on MacOS. Giving the application control of the AppDelegate is excellent on it's own. But I'm particular excited that this approach seems to open up the possibility of modular libraries that independently hook into apple system events! |
This is a breaking change, although unlikely to matter in practice, since the return value of `application:didFinishLaunchingWithOptions:` is seldom used by the system.
This allows the user to override the application delegate themselves, which opens several doors for customization that were previously closed.
7e17899
to
53f7c34
Compare
The holdup for this PR has not been Kirill at all, it's because I was on vacation ;) |
Woohoo! Awesome :D |
Register for event-loop lifecycle events using the
NSNotification
API instead of application delegates. This gives the user full control over the application delegate, which opens several doors for customization that were previously closed.In particular, this fixes #1751, closes #3713, fixes #2674, fixes #3499, fixes #3650 and fixes #2141, all by allowing the user to override
[NS|UI]ApplicationDelegate
themselves outside Winit.Also fixes #1281 by listening on notifications instead of using the application delegate.
Resolves part of the macOS side of #2120.
changelog
module if knowledge of this change could be valuable to users