Allow the user to register the application delegate on macOS and iOS#3758
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
daxpedda
left a comment
There was a problem hiding this comment.
I'm starting to understand the MacOS backend quite a bit now, the cleanup you have done so far is pretty amazing.
kchibisov
left a comment
There was a problem hiding this comment.
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.
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.
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 |
iOS parts of rust-windowing#3758. This allows the user to override the application delegate themselves, which opens several doors for customization that were previously closed. To do this, we use notifications instead of a top-level application delegate. One effect of not providing an application delegate on iOS is that we no longer act as-if the application successfully open all URLs there. This is a breaking change, although unlikely to matter in practice, since the return value of `application:didFinishLaunchingWithOptions:` is seldom used by the system (and this is likely the preferred behaviour anyhow).
|
I backported the iOS parts of this to v0.30.10, the macOS parts are more extensive, and will have to wait until v0.31.0. CC @extrawurst, this should allow what we talked about on Discord with v0.30.10. |
iOS parts of rust-windowing#3758. This allows the user to override the application delegate themselves, which opens several doors for customization that were previously closed. To do this, we use notifications instead of a top-level application delegate. One effect of not providing an application delegate on iOS is that we no longer act as-if the application successfully open all URLs there. This is a breaking change, although unlikely to matter in practice, since the return value of `application:didFinishLaunchingWithOptions:` is seldom used by the system (and this is likely the preferred behaviour anyhow).
iOS parts of rust-windowing#3758. This allows the user to override the application delegate themselves, which opens several doors for customization that were previously closed. To do this, we use notifications instead of a top-level application delegate. One effect of not providing an application delegate on iOS is that we no longer act as-if the application successfully open all URLs there. This is a breaking change, although unlikely to matter in practice, since the return value of `application:didFinishLaunchingWithOptions:` is seldom used by the system (and this is likely the preferred behaviour anyhow).
iOS parts of #3758. This allows the user to override the application delegate themselves, which opens several doors for customization that were previously closed. To do this, we use notifications instead of a top-level application delegate. One effect of not providing an application delegate on iOS is that we no longer act as-if the application successfully open all URLs there. This is a breaking change, although unlikely to matter in practice, since the return value of `application:didFinishLaunchingWithOptions:` is seldom used by the system (and this is likely the preferred behaviour anyhow).
Is there any way I can help with macOS parts? |
|
Problem is that it depends on a bunch of other refactoring PRs I've done, and backporting those (correctly) is kind of a nightmare. I know how useful this feature would be to downstream projects, but I can't really justify that time usage, I think my time's better spent getting v0.31 out the door. Though I'd probably accept a PR that cherry-picked the required stuff against the |
Register for event-loop lifecycle events using the
NSNotificationAPI 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
NSApplicationDelegate/UIApplicationDelegatethemselves outside Winit.Also fixes #1281 by listening on notifications instead of using the application delegate.
Resolves part of the macOS side of #2120.
changelogmodule if knowledge of this change could be valuable to users