Handle URLs on macOS
This allows macOS apps to access the URL when they are opened "as a browser / url handler". This is adapted from Iced's fork of Winit and I believe it is the main things preventing Iced from using upstream Winit.
Fixes #2190
- [ ] Tested on all platforms changed
- [ ] Added an entry to the
changelogmodule if knowledge of this change could be valuable to users - [ ] Updated documentation to reflect any user-facing changes, including notes of platform-specific behavior
- [ ] Created or updated an example program if it would help users understand this functionality
- [ ] Updated feature matrix, if new features were added or implemented
@madsmtm Super excited to see https://github.com/rust-windowing/winit/pull/3758 merged. That looks like an absolutely fantastic solution for modular Winit on apple platforms. I'll have to implement it to be sure, but I reckon it will be possible for this to be implemented outside of Winit on top of #3758. And I reckon I can use some of the objc2 crates' functionality to really clean it up too. The one question I have is when/where I ought to run the code that registers the listener for the event that returns the url:
I could use my own AppDelegate and register it in applicationWillFinishLaunching like the current PR does. But I would really like to be able to wrap this up in a library, and my feeling is that the approach you've used in #3758 ought to enable that. But that perhaps the create_observer function ought to become public so it can be used in 3rd party libs as well as winit.
Regarding event registration ordering:
- I'm guessing I ought to put my code in Winit's "resume" event?
- Do you think I could register for the
kAEGetURLevent directly in "resume"? - Or do you think I would need to register for applicationWillFinishLaunching in "resume" and then register for
kAEGetURL?
perhaps the
create_observerfunction ought to become public so it can be used in 3rd party libs
It is quite a simple function, and will become even simpler in the future once block2 supports references in arguments. If you really feel you need it, just copy the definition.
Regarding event registration ordering:
- I'm guessing I ought to put my code in Winit's "resume" event?
- Do you think I could register for the
kAEGetURLevent directly in "resume"?- Or do you think I would need to register for applicationWillFinishLaunching in "resume" and then register for
kAEGetURL?
I don't know anything about the kAEGetURL event, and I'm unfamiliar with these kinds of lower-level events, but it seems probable that the registration needs to happen before the application has launched. You may be able to do it at the top of main (or possibly right after EventLoop::new), but otherwise, doing it in applicationWillFinishLaunching: could be done with something like:
let block = RcBlock::new(|notification: NonNull<NSNotification>| {
let notification = unsafe { notification.as_ref() };
// ... Register in here
});
let observer = unsafe {
center.addObserverForName_object_queue_usingBlock(
// `applicationWillFinishLaunching:`
Some(unsafe { NSApplicationWillFinishLaunchingNotification }),
None,
None,
&block,
)
}
// Keep `observer` around until the end of `main` (or leak it).
Not sure if you got the time to play around with this yet, but again, I'm fairly confident that https://github.com/rust-windowing/winit/pull/3758 will solve Iced's needs here.
Feel free to re-open or discuss further if that's not the case!
@madsmtm I haven't had time to play around with this yet, but I am also confident that https://github.com/rust-windowing/winit/pull/3758 allows this to be solved outside of Winit.
We probably ought to document the pattern described in https://github.com/rust-windowing/winit/issues/4260#issuecomment-2945457455 somewhere.