Skip to content

Commit 33d0b3f

Browse files
feat: add WebviewBuilder::on_new_window and WebviewBuilder::on_document_title_changed (#13876)
* add "new window" and "document title changed" webview handler * take document title changed handler * update example, add missing api, change files * allow creating tauri window for the window.open call * set size and position, fix linux, example * enhance document title change * fix windows deadlock * wry 0.53 * update wry --------- Co-authored-by: Lucas Nogueira <[email protected]>
1 parent f123267 commit 33d0b3f

File tree

12 files changed

+653
-22
lines changed

12 files changed

+653
-22
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"tauri": minor:feat
3+
"tauri-runtime": minor:feat
4+
"tauri-runtime-wry": minor:feat
5+
---
6+
7+
Added `WebviewBuilder::on_document_title_changed` and `WebviewWindowBuilder::on_document_title_changed`.

.changes/on_new_window.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"tauri": minor:feat
3+
"tauri-runtime": minor:feat
4+
"tauri-runtime-wry": minor:feat
5+
---
6+
7+
Added `WebviewBuilder::on_new_window` and `WebviewWindowBuilder::on_new_window`.

Cargo.lock

Lines changed: 10 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/tauri-runtime-wry/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ rustc-args = ["--cfg", "docsrs"]
1717
rustdoc-args = ["--cfg", "docsrs"]
1818

1919
[dependencies]
20-
wry = { version = "0.52", default-features = false, features = [
20+
wry = { version = "0.53.1", default-features = false, features = [
2121
"drag-drop",
2222
"protocol",
2323
"os-webview",

crates/tauri-runtime-wry/src/lib.rs

Lines changed: 103 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
use self::monitor::MonitorExt;
1616
use http::Request;
17+
#[cfg(target_os = "macos")]
18+
use objc2::ClassType;
1719
use raw_window_handle::{DisplayHandle, HasDisplayHandle, HasWindowHandle};
1820

1921
use tauri_runtime::{
@@ -43,6 +45,8 @@ use webview2_com::{ContainsFullScreenElementChangedEventHandler, FocusChangedEve
4345
use windows::Win32::Foundation::HWND;
4446
#[cfg(target_os = "ios")]
4547
use wry::WebViewBuilderExtIos;
48+
#[cfg(target_os = "macos")]
49+
use wry::WebViewBuilderExtMacos;
4650
#[cfg(windows)]
4751
use wry::WebViewBuilderExtWindows;
4852
#[cfg(target_vendor = "apple")]
@@ -3777,6 +3781,7 @@ fn handle_user_message<T: UserEvent>(
37773781
{
37783782
f(Webview {
37793783
controller: webview.controller(),
3784+
environment: webview.environment(),
37803785
});
37813786
}
37823787
#[cfg(target_os = "android")]
@@ -3822,9 +3827,13 @@ fn handle_user_message<T: UserEvent>(
38223827
}
38233828
}
38243829
Message::CreateWindow(window_id, handler) => match handler(event_loop) {
3825-
Ok(webview) => {
3826-
windows.0.borrow_mut().insert(window_id, webview);
3827-
}
3830+
// wait for borrow_mut to be available - on Windows we might poll for the window to be inserted
3831+
Ok(webview) => loop {
3832+
if let Ok(mut windows) = windows.0.try_borrow_mut() {
3833+
windows.insert(window_id, webview);
3834+
break;
3835+
}
3836+
},
38283837
Err(e) => {
38293838
log::error!("{e}");
38303839
}
@@ -4510,6 +4519,11 @@ You may have it installed on another user account, but it is not available for t
45104519
.with_clipboard(webview_attributes.clipboard)
45114520
.with_hotkeys_zoom(webview_attributes.zoom_hotkeys_enabled);
45124521

4522+
#[cfg(target_os = "macos")]
4523+
if let Some(webview_configuration) = webview_attributes.webview_configuration {
4524+
webview_builder = webview_builder.with_webview_configuration(webview_configuration);
4525+
}
4526+
45134527
#[cfg(any(target_os = "windows", target_os = "android"))]
45144528
{
45154529
webview_builder = webview_builder.with_https_scheme(webview_attributes.use_https_scheme);
@@ -4583,6 +4597,75 @@ You may have it installed on another user account, but it is not available for t
45834597
});
45844598
}
45854599

4600+
if let Some(new_window_handler) = pending.new_window_handler {
4601+
#[cfg(desktop)]
4602+
let context = context.clone();
4603+
webview_builder = webview_builder.with_new_window_req_handler(move |url, features| {
4604+
url
4605+
.parse()
4606+
.map(|url| {
4607+
let response = new_window_handler(
4608+
url,
4609+
tauri_runtime::webview::NewWindowFeatures::new(
4610+
features.size,
4611+
features.position,
4612+
tauri_runtime::webview::NewWindowOpener {
4613+
#[cfg(desktop)]
4614+
webview: features.opener.webview,
4615+
#[cfg(windows)]
4616+
environment: features.opener.environment,
4617+
#[cfg(target_os = "macos")]
4618+
target_configuration: features.opener.target_configuration,
4619+
},
4620+
),
4621+
);
4622+
match response {
4623+
tauri_runtime::webview::NewWindowResponse::Allow => wry::NewWindowResponse::Allow,
4624+
#[cfg(desktop)]
4625+
tauri_runtime::webview::NewWindowResponse::Create { window_id } => {
4626+
let windows = &context.main_thread.windows.0;
4627+
let webview = loop {
4628+
if let Some(webview) = windows.try_borrow().ok().and_then(|windows| {
4629+
windows
4630+
.get(&window_id)
4631+
.map(|window| window.webviews.first().unwrap().clone())
4632+
}) {
4633+
break webview;
4634+
} else {
4635+
// on Windows the window is created async so we should wait for it to be available
4636+
std::thread::sleep(std::time::Duration::from_millis(50));
4637+
continue;
4638+
};
4639+
};
4640+
4641+
#[cfg(desktop)]
4642+
wry::NewWindowResponse::Create {
4643+
#[cfg(target_os = "macos")]
4644+
webview: wry::WebViewExtMacOS::webview(&*webview).as_super().into(),
4645+
#[cfg(any(
4646+
target_os = "linux",
4647+
target_os = "dragonfly",
4648+
target_os = "freebsd",
4649+
target_os = "netbsd",
4650+
target_os = "openbsd",
4651+
))]
4652+
webview: webview.webview(),
4653+
#[cfg(windows)]
4654+
webview: webview.webview(),
4655+
}
4656+
}
4657+
tauri_runtime::webview::NewWindowResponse::Deny => wry::NewWindowResponse::Deny,
4658+
}
4659+
})
4660+
.unwrap_or(wry::NewWindowResponse::Deny)
4661+
});
4662+
}
4663+
4664+
if let Some(document_title_changed_handler) = pending.document_title_changed_handler {
4665+
webview_builder =
4666+
webview_builder.with_document_title_changed_handler(document_title_changed_handler)
4667+
}
4668+
45864669
let webview_bounds = if let Some(bounds) = webview_attributes.bounds {
45874670
let bounds: RectWrapper = bounds.into();
45884671
let bounds = bounds.0;
@@ -4672,6 +4755,10 @@ You may have it installed on another user account, but it is not available for t
46724755
webview_builder = webview_builder.with_additional_browser_args(&additional_browser_args);
46734756
}
46744757

4758+
if let Some(environment) = webview_attributes.environment {
4759+
webview_builder = webview_builder.with_environment(environment);
4760+
}
4761+
46754762
webview_builder = webview_builder.with_theme(match window.theme() {
46764763
TaoTheme::Dark => wry::Theme::Dark,
46774764
TaoTheme::Light => wry::Theme::Light,
@@ -4699,6 +4786,19 @@ You may have it installed on another user account, but it is not available for t
46994786
}
47004787
}
47014788

4789+
#[cfg(any(
4790+
target_os = "linux",
4791+
target_os = "dragonfly",
4792+
target_os = "freebsd",
4793+
target_os = "netbsd",
4794+
target_os = "openbsd"
4795+
))]
4796+
{
4797+
if let Some(related_view) = webview_attributes.related_view {
4798+
webview_builder = webview_builder.with_related_view(related_view);
4799+
}
4800+
}
4801+
47024802
#[cfg(any(target_os = "macos", target_os = "ios"))]
47034803
{
47044804
if let Some(data_store_identifier) = &webview_attributes.data_store_identifier {

crates/tauri-runtime-wry/src/webview.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,12 @@ mod imp {
2929

3030
#[cfg(windows)]
3131
mod imp {
32-
use webview2_com::Microsoft::Web::WebView2::Win32::ICoreWebView2Controller;
32+
use webview2_com::Microsoft::Web::WebView2::Win32::{
33+
ICoreWebView2Controller, ICoreWebView2Environment,
34+
};
3335
pub struct Webview {
3436
pub controller: ICoreWebView2Controller,
37+
pub environment: ICoreWebView2Environment,
3538
}
3639
}
3740

crates/tauri-runtime/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,12 @@ cookie = "0.18"
4141
version = "0.61"
4242
features = ["Win32_Foundation", "Win32_System_WinRT"]
4343

44+
[target."cfg(windows)".dependencies]
45+
webview2-com = "0.38"
46+
4447
[target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
4548
gtk = { version = "0.18", features = ["v3_24"] }
49+
webkit2gtk = { version = "=2.0", features = ["v2_40"] }
4650

4751
[target."cfg(target_os = \"android\")".dependencies]
4852
jni = "0.21"
@@ -56,6 +60,8 @@ objc2-ui-kit = { version = "0.3.0", default-features = false, features = [
5660

5761
[target."cfg(target_os = \"macos\")".dependencies]
5862
url = "2"
63+
objc2 = "0.6"
64+
objc2-web-kit = { version = "0.3", features = ["objc2-app-kit", "WKWebView"] }
5965

6066
[features]
6167
devtools = []

0 commit comments

Comments
 (0)