Skip to content

Commit

Permalink
Remove &Window parameter from Custom Protocol handlers (#361)
Browse files Browse the repository at this point in the history
* support multiple WebViews in a single WebContext

* wait for load-change::finished

* add doc_cfg for errors

* update os specific cfgs

* cargo +nightly fmt

* Revert "update os specific cfgs"

This reverts commit a1f1776.

* Revert "add doc_cfg for errors"

This reverts commit efe7b02.

* remove updated cfg values

* updated documentation

* change web_context refs to mut

* update changelog

* clippy

* clippy for win/macos

* update system tray example to track tao dev changes

* remove Window from custom protocol handlers

* add changefile

* blind fix macOS

Co-authored-by: Ngo Iok Ui <wusyong9104@gmail.com>
  • Loading branch information
chippers and Ngo Iok Ui authored Jul 29, 2021
1 parent 15f7698 commit 0e2574c
Show file tree
Hide file tree
Showing 11 changed files with 33 additions and 58 deletions.
5 changes: 5 additions & 0 deletions .changes/custom-protocol-remove-window-parameter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wry": patch
---

Custom Protocol handlers no longer take a `&Window` parameter.
2 changes: 1 addition & 1 deletion bench/tests/src/cpu_intensive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ fn main() -> wry::Result<()> {
};
let webview = WebViewBuilder::new(window)
.unwrap()
.with_custom_protocol("wry.bench".into(), move |_, requested_asset_path| {
.with_custom_protocol("wry.bench".into(), move |requested_asset_path| {
let requested_asset_path = requested_asset_path.replace("wry.bench://", "");
match requested_asset_path.as_str() {
"/index.css" => Ok((include_bytes!("static/index.css").to_vec(), "text/css".into())),
Expand Down
2 changes: 1 addition & 1 deletion bench/tests/src/custom_protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ fn main() -> wry::Result<()> {
let webview = WebViewBuilder::new(window)
.unwrap()
.with_rpc_handler(handler)
.with_custom_protocol("wry.bench".into(), move |_, _| {
.with_custom_protocol("wry.bench".into(), move |_uri| {
let index_html = r#"
<!DOCTYPE html>
<html lang="en">
Expand Down
2 changes: 1 addition & 1 deletion examples/custom_protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ fn main() -> wry::Result<()> {

let _webview = WebViewBuilder::new(window)
.unwrap()
.with_custom_protocol("wry".into(), move |_, requested_asset_path| {
.with_custom_protocol("wry".into(), move |requested_asset_path| {
// Remove url scheme
let path = requested_asset_path.replace("wry://", "");
// Read the file content from file path
Expand Down
2 changes: 1 addition & 1 deletion examples/system_tray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ fn main() -> wry::Result<()> {

let webview = WebViewBuilder::new(window)
.unwrap()
.with_custom_protocol("wry.dev".into(), move |_, _| {
.with_custom_protocol("wry.dev".into(), move |_uri| {
Ok((index_html.as_bytes().into(), "text/html".into()))
})
.with_url("wry.dev://")
Expand Down
2 changes: 1 addition & 1 deletion examples/system_tray_no_menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ fn main() -> wry::Result<()> {

let webview = WebViewBuilder::new(window)
.unwrap()
.with_custom_protocol("wry.dev".into(), move |_, _| {
.with_custom_protocol("wry.dev".into(), move |_uri| {
Ok((index_html.as_bytes().into(), "text/html".into()))
})
.with_url("wry.dev://")
Expand Down
13 changes: 5 additions & 8 deletions src/webview/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,9 @@ pub struct WebViewAttributes {
/// Register custom file loading protocols with pairs of scheme uri string and a handling
/// closure.
///
/// The closure takes the `Window` and a url string slice as parameters, and returns a tuple of a
/// vector of bytes which is the content and a mimetype string of the content.
pub custom_protocols: Vec<(
String,
Box<dyn Fn(&Window, &str) -> Result<(Vec<u8>, String)>>,
)>,
/// The closure takes a url string slice, and returns a two item tuple of a vector of
/// bytes which is the content and a mimetype string of the content.
pub custom_protocols: Vec<(String, Box<dyn Fn(&str) -> Result<(Vec<u8>, String)>>)>,
/// Set the RPC handler to Communicate between the host Rust code and Javascript on webview.
///
/// The communication is done via [JSON-RPC](https://www.jsonrpc.org). Users can use this to register an incoming
Expand Down Expand Up @@ -149,12 +146,12 @@ impl<'a> WebViewBuilder<'a> {
/// Register custom file loading protocols with pairs of scheme uri string and a handling
/// closure.
///
/// The closure takes the `Window` and a url string slice as parameters, and returns a tuple of a
/// The closure takes a url string slice, and returns a two item tuple of a
/// vector of bytes which is the content and a mimetype string of the content.
#[cfg(feature = "protocol")]
pub fn with_custom_protocol<F>(mut self, name: String, handler: F) -> Self
where
F: Fn(&Window, &str) -> Result<(Vec<u8>, String)> + 'static,
F: Fn(&str) -> Result<(Vec<u8>, String)> + 'static,
{
self
.webview
Expand Down
47 changes: 13 additions & 34 deletions src/webview/web_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ use self::unix::WebContextImpl;
pub mod unix {
//! Unix platform extensions for [`WebContext`](super::WebContext).
use crate::{application::window::Window, Error};
use crate::Error;
use glib::FileError;
use std::{
collections::{HashSet, VecDeque},
Expand Down Expand Up @@ -211,27 +211,17 @@ pub mod unix {
/// When duplicate schemes are registered, the duplicate handler will still be submitted and the
/// `Err(Error::DuplicateCustomProtocol)` will be returned. It is safe to ignore if you are
/// relying on the platform's implementation to properly handle duplicated scheme handlers.
fn register_uri_scheme<F>(
&mut self,
name: &str,
handler: F,
window: Rc<Window>,
) -> crate::Result<()>
fn register_uri_scheme<F>(&mut self, name: &str, handler: F) -> crate::Result<()>
where
F: Fn(&Window, &str) -> crate::Result<(Vec<u8>, String)> + 'static;
F: Fn(&str) -> crate::Result<(Vec<u8>, String)> + 'static;

/// Register a custom protocol to the web context, only if it is not a duplicate scheme.
///
/// If a duplicate scheme has been passed, its handler will **NOT** be registered and the
/// function will return `Err(Error::DuplicateCustomProtocol)`.
fn try_register_uri_scheme<F>(
&mut self,
name: &str,
handler: F,
window: Rc<Window>,
) -> crate::Result<()>
fn try_register_uri_scheme<F>(&mut self, name: &str, handler: F) -> crate::Result<()>
where
F: Fn(&Window, &str) -> crate::Result<(Vec<u8>, String)> + 'static;
F: Fn(&str) -> crate::Result<(Vec<u8>, String)> + 'static;

/// Add a [`WebView`] to the queue waiting to be opened.
///
Expand All @@ -258,34 +248,24 @@ pub mod unix {
&self.os.manager
}

fn register_uri_scheme<F>(
&mut self,
name: &str,
handler: F,
window: Rc<Window>,
) -> crate::Result<()>
fn register_uri_scheme<F>(&mut self, name: &str, handler: F) -> crate::Result<()>
where
F: Fn(&Window, &str) -> crate::Result<(Vec<u8>, String)> + 'static,
F: Fn(&str) -> crate::Result<(Vec<u8>, String)> + 'static,
{
actually_register_uri_scheme(self, name, handler, window)?;
actually_register_uri_scheme(self, name, handler)?;
if self.os.registered_protocols.insert(name.to_string()) {
Ok(())
} else {
Err(Error::DuplicateCustomProtocol(name.to_string()))
}
}

fn try_register_uri_scheme<F>(
&mut self,
name: &str,
handler: F,
window: Rc<Window>,
) -> crate::Result<()>
fn try_register_uri_scheme<F>(&mut self, name: &str, handler: F) -> crate::Result<()>
where
F: Fn(&Window, &str) -> crate::Result<(Vec<u8>, String)> + 'static,
F: Fn(&str) -> crate::Result<(Vec<u8>, String)> + 'static,
{
if self.os.registered_protocols.insert(name.to_string()) {
actually_register_uri_scheme(self, name, handler, window)
actually_register_uri_scheme(self, name, handler)
} else {
Err(Error::DuplicateCustomProtocol(name.to_string()))
}
Expand All @@ -308,10 +288,9 @@ pub mod unix {
context: &mut super::WebContext,
name: &str,
handler: F,
window: Rc<Window>,
) -> crate::Result<()>
where
F: Fn(&Window, &str) -> crate::Result<(Vec<u8>, String)> + 'static,
F: Fn(&str) -> crate::Result<(Vec<u8>, String)> + 'static,
{
let context = &context.os.context;
context
Expand All @@ -323,7 +302,7 @@ pub mod unix {
if let Some(uri) = request.get_uri() {
let uri = uri.as_str();

match handler(&window, uri) {
match handler(uri) {
Ok((buffer, mime)) => {
let input = gio::MemoryInputStream::from_bytes(&glib::Bytes::from(&buffer));
request.finish(&input, buffer.len() as i64, Some(&mime))
Expand Down
5 changes: 2 additions & 3 deletions src/webview/webkitgtk/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ impl InnerWebView {

// File drop handling
if let Some(file_drop_handler) = attributes.file_drop_handler {
file_drop::connect_drag_event(webview.clone(), window_rc.clone(), file_drop_handler);
file_drop::connect_drag_event(webview.clone(), window_rc, file_drop_handler);
}

if window.get_visible() {
Expand All @@ -193,8 +193,7 @@ impl InnerWebView {
}

for (name, handler) in attributes.custom_protocols {
let w = window_rc.clone();
if let Err(e) = web_context.register_uri_scheme(&name, handler, w) {
if let Err(e) = web_context.register_uri_scheme(&name, handler) {
if let Error::DuplicateCustomProtocol(_) = e {
// Swallow duplicate scheme errors to preserve current behavior.
// FIXME: we should log this error in the future
Expand Down
3 changes: 1 addition & 2 deletions src/webview/webview2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,6 @@ impl InnerWebView {

let custom_protocols = attributes.custom_protocols;
let env_clone = env_.clone();
let window_ = window.clone();
w.add_web_resource_requested(move |_, args| {
let uri = args.get_request()?.get_uri()?;
// Undo the protocol workaround when giving path to resolver
Expand All @@ -209,7 +208,7 @@ impl InnerWebView {
.iter()
.find(|(name, _)| name == &scheme)
.unwrap()
.1)(&window_, &path)
.1)(&path)
{
Ok((content, mime)) => {
let stream = webview2::Stream::from_bytes(&content);
Expand Down
8 changes: 2 additions & 6 deletions src/webview/wkwebview/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,7 @@ pub struct InnerWebView {
),
#[cfg(target_os = "macos")]
file_drop_ptr: *mut (Box<dyn Fn(&Window, FileDropEvent) -> bool>, Rc<Window>),
protocol_ptrs: Vec<*mut (
Box<dyn Fn(&Window, &str) -> Result<(Vec<u8>, String)>>,
Rc<Window>,
)>,
protocol_ptrs: Vec<*mut Box<dyn Fn(&str) -> Result<(Vec<u8>, String)>>>,
}

impl InnerWebView {
Expand Down Expand Up @@ -163,8 +160,7 @@ impl InnerWebView {
None => Class::get(&scheme_name).expect("Failed to get the class definition"),
};
let handler: id = msg_send![cls, new];
let w = window.clone();
let function = Box::into_raw(Box::new((function, w)));
let function = Box::into_raw(Box::new(function));
protocol_ptrs.push(function);

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

0 comments on commit 0e2574c

Please sign in to comment.