tauri-apps / wry

Cross-platform WebView library in Rust for Tauri.
Apache License 2.0
3.56k stars 266 forks source link

IPC broken when sharing context between WebViews on Linux #1308

Closed ollpu closed 1 month ago

ollpu commented 3 months ago

Describe the bug If I spawn multiple WebViews with a shared WebContext, IPC callbacks (from JS to Rust) are routed incorrectly. It is as if each window sent the same event separately.

Steps To Reproduce

Apply the following changes to examples/multiwindow.rs. It makes the windows use a shared WebContext.

Diff

```diff diff --git a/examples/multiwindow.rs b/examples/multiwindow.rs index 1a95c09..5b50a2a 100644 --- a/examples/multiwindow.rs +++ b/examples/multiwindow.rs @@ -8,7 +8,7 @@ use tao::{ event_loop::{ControlFlow, EventLoopBuilder, EventLoopProxy, EventLoopWindowTarget}, window::{Window, WindowBuilder, WindowId}, }; -use wry::{http::Request, WebView, WebViewBuilder}; +use wry::{http::Request, WebContext, WebView, WebViewBuilder}; enum UserEvent { CloseWindow(WindowId), @@ -20,11 +20,13 @@ fn main() -> wry::Result<()> { let event_loop = EventLoopBuilder::::with_user_event().build(); let mut webviews = HashMap::new(); let proxy = event_loop.create_proxy(); + let mut web_context = WebContext::new(None); let new_window = create_new_window( format!("Window {}", webviews.len() + 1), &event_loop, proxy.clone(), + &mut web_context, ); webviews.insert(new_window.0.id(), (new_window.0, new_window.1)); @@ -47,6 +49,7 @@ fn main() -> wry::Result<()> { format!("Window {}", webviews.len() + 1), event_loop, proxy.clone(), + &mut web_context, ); webviews.insert(new_window.0.id(), (new_window.0, new_window.1)); } @@ -69,6 +72,7 @@ fn create_new_window( title: String, event_loop: &EventLoopWindowTarget, proxy: EventLoopProxy, + web_context: &mut WebContext, ) -> (Window, WebView) { let window = WindowBuilder::new() .with_title(title) @@ -114,6 +118,7 @@ fn create_new_window( }; let webview = builder + .with_web_context(web_context) .with_html( r#" ```

Full example

Then:

Expected behavior As with the original example,

Screenshots image

Platform and Versions: OS: Ubuntu 22.04.4 Rustc: rustc 1.77.2 (25ef9e3d8 2024-04-09)

Additional context I primarily want to share the WebContext between WebViews so that the BroadcastChannel API would work. It seems that on Linux / WebKitGTK, it doesn't work if the views are in separate contexts. (Same with live localStorage changes, etc.)

In Tauri the WebViews are currently always set up with separate contexts, unless TAURI_AUTOMATION=true (Tauri v1) or TAURI_WEBVIEW_AUTOMATION=true (Tauri v2) is set, in which case this bug is exhibited.

ollpu commented 3 months ago

I dug around a bit, and it seems like the underlying cause is that all of the WebViews share their UserContentManager, and the IPC callback is tied to that. It might make sense to use separate UserContentManagers for each view. Otherwise the IPC messages need to be discriminated in some other way (but then the signals would be unnecessarily fired multiple times for each event).

Edit: Init scripts are also shared within the UserContentManager, so I think they should be separate.