Support NAME on WebViewDelegate trait impls

This commit is contained in:
Ryan McGrath 2022-10-12 15:42:16 -04:00
parent 2525cbfee4
commit 4d1e0ddb9d
No known key found for this signature in database
GPG key ID: DA6CBD9233593DEA
4 changed files with 18 additions and 4 deletions

View file

@ -91,7 +91,9 @@ impl Dispatcher for BasicApp {
#[derive(Default)]
pub struct WebViewInstance;
impl WebViewDelegate for WebViewInstance {}
impl WebViewDelegate for WebViewInstance {
const NAME: &'static str = "BrowserWebViewDelegate";
}
struct AppWindow {
toolbar: Toolbar<BrowserToolbar>,

View file

@ -185,8 +185,8 @@ pub fn register_webview_class() -> *const Class {
/// Registers an `NSViewController` that we effectively turn into a `WebViewController`. Acts as
/// both a subclass of `NSViewController` and a delegate of the held `WKWebView` (for the various
/// varieties of delegates needed there).
pub fn register_webview_delegate_class<T: WebViewDelegate>() -> *const Class {
load_or_register_class("NSObject", "RSTWebViewDelegate", |decl| unsafe {
pub fn register_webview_delegate_class<T: WebViewDelegate>(instance: &T) -> *const Class {
load_or_register_class("NSObject", instance.subclass_name(), |decl| unsafe {
decl.add_ivar::<usize>(WEBVIEW_DELEGATE_PTR);
// WKNavigationDelegate

View file

@ -230,10 +230,11 @@ where
/// Initializes a new WebView with a given `WebViewDelegate`. This enables you to respond to events
/// and customize the view as a module, similar to class-based systems.
pub fn with(config: WebViewConfig, delegate: T) -> WebView<T> {
let delegate_class = register_webview_delegate_class(&delegate);
let mut delegate = Box::new(delegate);
let objc_delegate = unsafe {
let objc_delegate: id = msg_send![register_webview_delegate_class::<T>(), new];
let objc_delegate: id = msg_send![delegate_class, new];
let ptr: *const T = &*delegate;
(&mut *objc_delegate).set_ivar(WEBVIEW_DELEGATE_PTR, ptr as usize);
ShareId::from_ptr(objc_delegate)

View file

@ -8,6 +8,17 @@ use crate::webview::WebView;
/// You can implement this on structs to handle callbacks from the underlying `WKWebView`.
pub trait WebViewDelegate {
/// Used to cache subclass creations on the Objective-C side.
/// You can just set this to be the name of your delegate type. This
/// value *must* be unique per-type.
const NAME: &'static str;
/// You should rarely (read: probably never) need to implement this yourself.
/// It simply acts as a getter for the associated `NAME` const on this trait.
fn subclass_name(&self) -> &'static str {
Self::NAME
}
/// Called when the View is ready to work with. You're passed a `ViewHandle` - this is safe to
/// store and use repeatedly, but it's not thread safe - any UI calls must be made from the
/// main thread!