tauri icon indicating copy to clipboard operation
tauri copied to clipboard

[bug] Panic and can't open TaoWindow on macOS

Open petamoriken opened this issue 8 months ago • 14 comments

Describe the bug

Not sure of the exact cause, but maybe update crates related to Tauri caused it to crash on macOS 13.3.0. ~~macOS 15.4.1 has been confirmed to work correctly.~~

unexpected NULL returned from -[NSKVONotifying_TaoWindow screen]
Full Crash Report
OS Version: macOS 13.3.0 (22E252)
Report Version: 104


Application Specific Information:
unexpected NULL returned from -[NSKVONotifying_TaoWindow screen]

Thread 0 Crashed:
0   std                             0x1019f0dc0         std::sys::backtrace::__rust_end_short_backtrace
1   <unknown>                       0x1019f1d14         _rust_begin_unwind
2   core                            0x101a50698         core::panicking::panic_fmt
3   objc2                           0x101a3d810         objc2::__macro_helpers::retain_semantics::none_fail
4   tao                             0x101199768         tao::platform_impl::platform::window::UnownedWindow::current_monitor_inner
5   tauri_runtime_wry               0x1011928c0         tauri_runtime_wry::handle_user_message
6   tauri_runtime_wry               0x10118c428         tauri_runtime_wry::make_event_handler::{{closure}}
7   tao                             0x1011c198c         tao::platform_impl::platform::app_state::EventLoopHandler<T>::handle_user_events
8   tao                             0x10175103c         tao::platform_impl::platform::app_state::AppState::cleared
9   tao                             0x101753b10         tao::platform_impl::platform::observer::control_flow_end_handler
10  <unknown>                       0x18df45ac4         <unknown>
11  <unknown>                       0x18df459b0         <unknown>
12  <unknown>                       0x18df450e4         <unknown>
13  <unknown>                       0x18df4458c         <unknown>
14  <unknown>                       0x197779df4         <unknown>
15  <unknown>                       0x197779c30         <unknown>
16  <unknown>                       0x197779988         <unknown>
17  <unknown>                       0x191163f58         <unknown>
18  <unknown>                       0x1911630f4         <unknown>
19  <unknown>                       0x191157558         <unknown>
20  tao                             0x1011973e4         tao::platform_impl::platform::event_loop::EventLoop<T>::run
21  tauri                           0x1011b2fb0         tauri::app::Builder<T>::run
22  app_name                        0x1012c5ca0         app_name::run
23  std                             0x100f584e8         std::sys::backtrace::__rust_begin_short_backtrace
24  std                             0x100f584d0         std::rt::lang_start::{{closure}}
25  std                             0x1019e6210         std::rt::lang_start_internal
26  <unknown>                       0x100f58544         _main



EOF

Reproduction

No response

Expected behavior

The window displays without crashing.

Full tauri info output

[✔] Environment
    - OS: Mac OS 14.5.0 arm64 (X64)
    ✔ Xcode Command Line Tools: installed
    ✔ rustc: 1.85.1 (4eb161250 2025-03-15)
    ✔ cargo: 1.85.1 (d73d2caf9 2024-12-31)
    ✔ rustup: 1.28.2 (e4f3ad6f8 2025-04-28)
    ✔ Rust toolchain: 1.85.1-aarch64-apple-darwin (overridden by '/Users/vagrant/git/rust-toolchain.toml')
    - node: 20.18.1
    - pnpm: 10.11.0
    - yarn: 1.22.22
    - npm: 10.8.2
    - deno: deno 2.3.1

[-] Packages
    - tauri 🦀: 2.5.1
    - tauri-build 🦀: 2.2.0
    - wry 🦀: 0.51.2
    - tao 🦀: 0.33.0

[-] Plugins
    - tauri-plugin-localhost 🦀: 2.2.0
    - tauri-plugin-single-instance 🦀: 2.2.3
    - tauri-plugin-dialog 🦀: 2.2.1
    - tauri-plugin-updater 🦀: 2.7.1
    - tauri-plugin-os 🦀: 2.2.1
    - tauri-plugin-shell 🦀: 2.2.1
    - tauri-plugin-process 🦀: 2.2.1
    - tauri-plugin-notification 🦀: 2.2.2
    - tauri-plugin-autostart 🦀: 2.3.0
    - tauri-plugin-fs 🦀: 2.2.1

[-] App
    - build-type: bundle
    - CSP: unset
    - frontendDist: ../dist
    - devUrl: http://localhost:1420/

Stack trace


Additional context

No response

petamoriken avatar May 15 '25 06:05 petamoriken

Thanks for the report. Can you provide a bit of code so we actually see what you're doing that triggers this?

FabianLars avatar May 15 '25 10:05 FabianLars

Although I can't provide minimal reproduction, the main function running in the production app is roughly as follows. I hope this will be helpful.

Rust code
#[command]
#[specta::specta]
async fn start_log_in_server(window: Window) -> Result<u16, String> {
    oauth::start_oauth_client_server(window)
}

#[command]
#[specta::specta]
async fn get_auth_state() -> String {
    oauth::generate_state()
}

#[command]
#[specta::specta]
async fn get_code_challenge() -> String {
    oauth::generate_code_challenge()
}

pub fn run() {
    let sentry_client = sentry::init((
        dotenv!("SENTRY_DSN_URL"),
        sentry::ClientOptions {
            release: Some(git_version::git_version!(args = ["--tags"]).into()),
            auto_session_tracking: true,
            ..Default::default()
        },
    ));

    let _guard = minidump::init(&sentry_client);

    let builder = Builder::<tauri::Wry>::new()
        .commands(collect_commands![
            start_log_in_server,
            get_auth_state,
            get_code_challenge,
        ])
        .typ::<AuthenticationResponse>();

    tauri::Builder::default()
        .plugin(tauri_plugin_sentry::init_with_no_injection(&sentry_client))
        .plugin(tauri_plugin_os::init())
        .plugin(tauri_plugin_dialog::init())
        .plugin(tauri_plugin_updater::Builder::new().build())
        .plugin(tauri_plugin_process::init())
        .plugin(tauri_plugin_notification::init())
        .plugin(tauri_plugin_shell::init())
        .plugin(tauri_plugin_oauth::init())
        .plugin(tauri_plugin_single_instance::init(|app, _argv, _cwd| {
            let _ = app
                .get_webview_window("main")
                .expect("no main window")
                .set_focus();
        }))
        .plugin(tauri_plugin_autostart::init(
            tauri_plugin_autostart::MacosLauncher::LaunchAgent,
            None,
        ))
        .invoke_handler(builder.invoke_handler())
        .setup(move |app| {
            builder.mount_events(app);

            {
                use tauri_plugin_autostart::MacosLauncher;
                use tauri_plugin_autostart::ManagerExt;

                let _ = app.handle().plugin(tauri_plugin_autostart::init(
                    MacosLauncher::LaunchAgent,
                    None,
                ));

                // Get the autostart manager
                let autostart_manager = app.autolaunch();
                // Enable autostart
                let enabled = autostart_manager.is_enabled().unwrap();
                if !enabled {
                    let _ = autostart_manager.enable();
                }
            }

            // Login
            let runtime = tokio::runtime::Runtime::new().unwrap();
            runtime.block_on(async {
                let client = Client::new();
                let manager = TokenManager::new();
                if let Ok(token) = manager.get_google_access_token().await {
                    let oidc_user_info_base_url = dotenv!("OIDC_USER_INFO_BASE_URL");

                    let user_response = client
                        .get(format!("{}{}", oidc_user_info_base_url, "/userinfo"))
                        .bearer_auth(token)
                        .send()
                        .await;
                    let user_response_text = user_response.unwrap().text().await.unwrap();
                    let user_info = serde_json::from_str::<model::UserInfo>(&user_response_text)
                        .expect("Failed to parse JSON response user info");

                    app.manage(std::sync::Arc::new(tokio::sync::Mutex::new(
                        types::AppState {
                            login_user: user_info,
                        },
                    )));
                } else {
                    app.manage(std::sync::Arc::new(tokio::sync::Mutex::new(
                        types::AppState::default(),
                    )));
                }
            });
            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

petamoriken avatar May 15 '25 15:05 petamoriken

thanks.

i guess this is impossible to tell if it crashes but do you think it's possible that tauri tries to create the window off-screen? Or maybe your main window is off-screen at that time?

Or is either window displayed, or going to be displayed, as fullscreen?

Asking because of https://developer.apple.com/documentation/appkit/nswindow/screen?language=objc

The value of this property is the screen where most of the window is on; it is nil when the window is offscreen.

I sure hope that this is the only case where it can return null and we don't hit some undocumented behavior or os bug 🙃

FabianLars avatar May 15 '25 16:05 FabianLars

I tried to get cursor_position and ns_window in the setup handler with no problem:

println!(
    "Cursor Position: {:#?}",
    app.cursor_position()
);
println!(
    "WebView: {:#?}",
    app.get_webview_window("main")
        .expect("no main window")
        .ns_window()
);

Apparently it works with Tauri 2.1.1, but not with 2.2.5.

It works:

[-] Packages
    - tauri 🦀: 2.1.1, (outdated, latest: 2.5.1)
    - tauri-build 🦀: 2.0.3, (outdated, latest: 2.2.0)
    - wry 🦀: 0.47.2, (outdated, latest: 0.51.2)
    - tao 🦀: 0.30.8, (outdated, latest: 0.33.0)

Does not work:

[-] Packages
    - tauri 🦀: 2.2.5, (outdated, latest: 2.5.1)
    - tauri-build 🦀: 2.2.0
    - wry 🦀: 0.50.5, (outdated, latest: 0.51.2)
    - tao 🦀: 0.32.8, (outdated, latest: 0.33.0)

petamoriken avatar May 19 '25 05:05 petamoriken

@FabianLars Maybe this issue is that the return value of ns_window has changed from cocoa::base::id to Retained<NSWindow> due to https://github.com/tauri-apps/wry/pull/1316, which causes panic in case of nil.

https://github.com/tauri-apps/wry/blob/5e6b0e689e38068c817ed1beb87af60b0fcbe0e2/src/lib.rs#L2248-L2250

petamoriken avatar May 21 '25 03:05 petamoriken

I changed the title of this issue because the crash was also encountered in macOS 15.4.1 in a few cases.

petamoriken avatar May 21 '25 03:05 petamoriken

Maybe this issue is that the return value of ns_window has changed from cocoa::base::id to Retained<NSWindow> due to https://github.com/tauri-apps/wry/pull/1316, which causes panic in case of nil.

Was thinking about a different line than you linked but the idea of this is why i asked those questions.

FabianLars avatar May 21 '25 06:05 FabianLars

Can you try again after adding this to your Cargo.toml file?

[patch.crates-io]
tao = { git = "https://github.com/tauri-apps/tao", branch = "fix/macos-screen-panic" }

(may require a cargo update call - please check if it throws a warning like "patch for tao not used in graph"

FabianLars avatar May 21 '25 12:05 FabianLars

@FabianLars I built using the branch you provided and it did not crash. Please proceed with that.

Thank you kindly!

petamoriken avatar May 23 '25 02:05 petamoriken

Thanks for testing. Will open a PR when I'm home.

FabianLars avatar May 23 '25 07:05 FabianLars

Any progress on this issue?

petamoriken avatar Jun 04 '25 01:06 petamoriken

i forgot to open the pr...

FabianLars avatar Jun 04 '25 10:06 FabianLars

Hey @FabianLars we have a decent number of users running into this and it has finally bubbled to our attention. Do you see any issues with that merging and when it might make its way into a tauri release?

AustinCase avatar Jun 16 '25 19:06 AustinCase

Do you see any issues with that merging

I don't think i'm in a position to be a judge of that. Otherwise this would be that one Obama medal meme.

As those changes are close to what's being used in winit and because i'm currently the only macos maintainer (without being a macos maintainer) i'll probably abuse my permissions and merge it without a review end of this week.

Since it's not a patch release (due to other queued changes) it may take a while to land in a tauri release (2.6.0).

FabianLars avatar Jun 16 '25 19:06 FabianLars