Skip to content

Commit

Permalink
macOS
Browse files Browse the repository at this point in the history
  • Loading branch information
amrbashir committed Dec 27, 2022
1 parent 8d7145c commit 2bead5f
Showing 1 changed file with 61 additions and 5 deletions.
66 changes: 61 additions & 5 deletions src/webview/wkwebview/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ pub(crate) struct InnerWebView {
// Note that if following functions signatures are changed in the future,
// all functions pointer declarations in objc callbacks below all need to get updated.
ipc_handler_ptr: *mut (Box<dyn Fn(&Window, String)>, Rc<Window>),
document_title_changed_handler: *mut (Box<dyn Fn(&Window, String)>, Rc<Window>),
navigation_decide_policy_ptr: *mut Box<dyn Fn(String, bool) -> bool>,
#[cfg(target_os = "macos")]
file_drop_ptr: *mut (Box<dyn Fn(&Window, FileDropEvent) -> bool>, Rc<Window>),
Expand Down Expand Up @@ -378,6 +379,56 @@ impl InnerWebView {
null_mut()
};

// Document title changed handler
let document_title_changed_handler = if let Some(ipc_handler) = attributes.ipc_handler {
let cls = ClassDecl::new("DocumentTitleChangedDelegate", class!(NSObject));
let cls = match cls {
Some(mut cls) => {
cls.add_ivar::<*mut c_void>("function");
cls.add_method(
sel!(observeValueForKeyPath),
observe_value_for_key_path as extern "C" fn(&Object, Sel, id, id, id, id),
);
extern "C" fn observe_value_for_key_path(
this: &Object,
_sel: Sel,
key_path: id,
_of_object: id,
change: id,
_context: id,
) {
let key = NSString(key_path);
if key.to_str() == "title" {
let function = this.get_ivar::<*mut c_void>("function");
if !function.is_null() {
let function =
&mut *(*function as *mut (Box<dyn for<'r> Fn(&'r Window, String)>, Rc<Window>));
let title: id = msg_send![change, valueForKey:NSString::new("title")];
let title = NSString(title).to_str().to_string();
(function.0)(&function.1, title);
}
}
}
cls.register()
}
None => class!(DocumentTitleChangedDelegate),
};

let handler: id = msg_send![cls, new];
let document_title_changed_handler = Box::into_raw(Box::new((ipc_handler, window.clone())));

(*handler).set_ivar(
"function",
document_title_changed_handler as *mut _ as *mut c_void,
);

let _: () = msg_send![webview, addObserver:handler forKeyPath:NSString::new("title") options:0x01 context:nil ];

document_title_changed_handler
} else {
null_mut()
};

// Navigation handler
extern "C" fn navigation_policy(this: &Object, _: Sel, _: id, action: id, handler: id) {
unsafe {
Expand Down Expand Up @@ -683,6 +734,7 @@ impl InnerWebView {
manager,
pending_scripts,
ipc_handler_ptr,
document_title_changed_handler,
navigation_decide_policy_ptr,
#[cfg(target_os = "macos")]
file_drop_ptr,
Expand Down Expand Up @@ -934,28 +986,32 @@ impl Drop for InnerWebView {
// We need to drop handler closures here
unsafe {
if !self.ipc_handler_ptr.is_null() {
let _ = Box::from_raw(self.ipc_handler_ptr);
drop(Box::from_raw(self.ipc_handler_ptr));

let ipc = NSString::new(IPC_MESSAGE_HANDLER_NAME);
let _: () = msg_send![self.manager, removeScriptMessageHandlerForName: ipc];
}

if !self.document_title_changed_handler.is_null() {
drop(Box::from_raw(self.document_title_changed_handler));
}

if !self.navigation_decide_policy_ptr.is_null() {
let _ = Box::from_raw(self.navigation_decide_policy_ptr);
drop(Box::from_raw(self.navigation_decide_policy_ptr));
}

#[cfg(target_os = "macos")]
if !self.file_drop_ptr.is_null() {
let _ = Box::from_raw(self.file_drop_ptr);
drop(Box::from_raw(self.file_drop_ptr));
}

if !self.download_delegate.is_null() {
let _ = self.download_delegate.drop_in_place();
drop(self.download_delegate.drop_in_place());
}

for ptr in self.protocol_ptrs.iter() {
if !ptr.is_null() {
let _ = Box::from_raw(*ptr);
drop(Box::from_raw(*ptr));
}
}

Expand Down

0 comments on commit 2bead5f

Please sign in to comment.