tauri-apps / tauri

Build smaller, faster, and more secure desktop applications with a web frontend.
https://tauri.app
Apache License 2.0
81.16k stars 2.42k forks source link

[bug] WebviewWindow freezes/loads infinite on creation inside js if tauri-plugin-devtools are inside Cargo.toml #10256

Closed thettler closed 1 week ago

thettler commented 1 month ago

Describe the bug

i try to create a new WebviewWindow from JS Code but every time it just loads infinite and i need to force quit the Program.

I figured out that it has something to do with the tauri-plugin-devtools. If i remove it from the Cargo.toml it works.

Cargo.toml

[package]
name = "app"
version = "0.1.0"
description = "A Tauri App"
authors = ["you"]
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[build-dependencies]
tauri-build = { version = "2.0.0-beta.18", features = [] }

[dependencies]
tauri = { version = "2.0.0-beta", features = ["devtools"] }
tauri-plugin-devtools = "2.0.0-beta" # <- Removing this makes it work.
serde = { version = "1", features = ["derive"] }
serde_json = "1"

main.rs

// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

fn main() {
    let builder = tauri::Builder::default();

    builder
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
    import {WebviewWindow} from "@tauri-apps/api/webviewWindow"

    function openWindow() {
        const pileWindow = new WebviewWindow('my-label', {
            url: 'https://github.com/tauri-apps/tauri'
        });

        pileWindow.once('tauri://created', function () {
            console.log('Success');
        });
        pileWindow.once('tauri://error', function (e) {
            console.log(e);
        });
    }

Reproduction

Repo

Expected behavior

No response

Full tauri info output

[✔] Environment
    - OS: Mac OS 14.5.0 X64
    ✔ Xcode Command Line Tools: installed
    ✔ rustc: 1.78.0 (9b00956e5 2024-04-29)
    ✔ cargo: 1.78.0 (54d8815d0 2024-03-26)
    ✔ rustup: 1.27.1 (54dd3d00f 2024-04-24)
    ✔ Rust toolchain: stable-aarch64-apple-darwin (default)
    - node: 21.7.3
    - npm: 10.5.0

[-] Packages
    - tauri [RUST]: 2.0.0-beta.23
    - tauri-build [RUST]: 2.0.0-beta.18
    - wry [RUST]: 0.41.0
    - tao [RUST]: 0.28.1
    - tauri-cli [RUST]: 1.5.4
    - @tauri-apps/api [NPM]: 2.0.0-beta.14
    - @tauri-apps/cli [NPM]: 2.0.0-beta.21

[-] App
    - build-type: bundle
    - CSP: unset
    - frontendDist: ../build
    - devUrl: http://localhost:5173/
    - framework: Svelte
    - bundler: Vite

Stack trace

No response

Additional context

https://discord.com/channels/616186924390023171/1260259980435521686

Lurrobert commented 1 month ago

same this sucks. thank you for figuring out it was tauri-plugin-devtools | devtools

it fixed it for me

JonasKruckenberg commented 1 month ago

This is possibly one of the wildest bugs I have seen to date. Just declaring (not even using) causes a different crate to malfunction, just wild. Thanks for reporting!

I have only today started investigating and I can already tell this is probably gonna be a longer process 😅 but it's promising a great writeup! Will keep this issue updated as I make progress on debugging this.

Edit 1: I don't have a windows VM handy, but this appears to be affecting macOS only

Edit 2: We have tracked down the issue. It is a pretty classic deadlock in the webviews_lock method that comes down to essentially a race condition: When the window is created a we eval a script on the window that sets a few imported global properties. At the same time the underlying graphics toolkit is setting up the window and generating events corresponding to that. Usually, the evaling script step is fast enough that the lock is released before the first native window event is generated, however it seems with the tracing feature enabled (which in-turn is used by the devtools plugin) this step takes just a bit too long and the native event is generated, caught by our handler which attempts to acquire another lock which then deadlocks.

JonasKruckenberg commented 1 month ago

@thettler while we are working on a proper fix for this, here is a simple workaround:

function openWindow() {
    const pileWindow = new WebviewWindow('my-label', {
        url: 'https://github.com/tauri-apps/tauri',
+       visible: false // initially hide the window
    });

    pileWindow.once('tauri://created', function () {
        console.log('Success');
+       pileWindow.show(); // only show it after creation
    });
    pileWindow.once('tauri://error', function (e) {
        console.log(e);
    });
}