Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bug] CloseRequested:: prevent_close() is invalid #12334

Open
axzsd opened this issue Jan 10, 2025 · 5 comments
Open

[bug] CloseRequested:: prevent_close() is invalid #12334

axzsd opened this issue Jan 10, 2025 · 5 comments
Labels
status: needs triage This issue needs to triage, applied to new issues type: bug

Comments

@axzsd
Copy link

axzsd commented Jan 10, 2025

Describe the bug

I use tauri to listen for window close events. I capture the close request in main_window.on_window_event and use api.prevent_close(); Prevents the default shutdown behavior, but he closes the program anyway。

permissions

{
  "$schema": "../gen/schemas/desktop-schema.json",
  "identifier": "default",
  "description": "Capability for the main window",
  "windows": [
    "main"
  ],
  "permissions": [
    "core:default",
    "shell:allow-open",
    "fs:default",
    "clipboard-manager:default",
    "dialog:default",
    {
      "identifier": "http:default",
      "allow": [{ "url": "https://*.tauri.app" }],
      "deny": [{ "url": "https://private.tauri.app" }]
    },
    {
      "identifier": "fs:allow-exists",
      "allow": [
        {
          "path": "$APPDATA/*"
        }
      ]
    }
  ]
}

run

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    // 初始化日志
    sys_log::init_logger();
    log::info!("init system start");

    let current_dir = std::env::current_dir().expect("路径错误");
    let data_path = current_dir.join(DATA_PATH);
    if !data_path.exists() {
        let _ = std::fs::create_dir_all(&data_path).expect("创建数据文件夹失败");
    }
    // let data_path = data_path.as_path();

    #[allow(unused_mut)]
    let mut builder = tauri::Builder::default();

    #[allow(unused_mut)]
    let mut app = builder
        .plugin(tauri_plugin_dialog::init())
        .plugin(tauri_plugin_clipboard_manager::init())
        .plugin(tauri_plugin_shell::init())
        .invoke_handler(tauri::generate_handler![greet])
        .setup(move |app| {
            register_database(app, data_path.clone())?;
            // The shutdown request event is registered here
            close_dialog::dialog(app.handle());
            Ok(())
        })
        .build(tauri::generate_context!())
        .expect("error while building tauri application");

    log::info!("init system ready");
    app.run(|_app_handle, e| {
        match e {
            tauri::RunEvent::Ready => {
                log::info!("Application is ready.");
            },
            _ => {}
        }
    });
}

dialog

use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use tauri::{AppHandle, Manager, WindowEvent};
use tauri_plugin_dialog::{DialogExt, MessageDialogButtons, MessageDialogKind};

pub fn dialog(app: &AppHandle) {
    let main_window = Arc::new(app.get_webview_window("main").unwrap());
    let dialog_shown = Arc::new(AtomicBool::new(false));
    let dialog_shown_clone = dialog_shown.clone();

    let app = Arc::new(app.clone());
    let main_window_clone = main_window.clone();

    main_window.on_window_event(move |event| {
        if let WindowEvent::CloseRequested { api, .. } = event {
            if !dialog_shown_clone.load(Ordering::Relaxed) {
                log::info!("Confirm to exit the current program?");

                // 标记对话框已显示
                dialog_shown_clone.store(true, Ordering::Relaxed);
                // 阻止默认的关闭行为
                api.prevent_close();

                let app = app.clone();
                let main_window_clone = main_window_clone.clone();
                let dialog_shown_clone = dialog_shown.clone();

                // 使用 tokio 或 async-std 来处理异步任务
                tauri::async_runtime::block_on( async move {
                    handle_exit_dialog(app, main_window_clone, dialog_shown_clone).await
                });
            }
        }
    });
}

async fn handle_exit_dialog(
    app: Arc<AppHandle>,
    main_window: Arc<tauri::WebviewWindow>,
    dialog_shown: Arc<AtomicBool>,
) {
    log::info!("Wait for the user to choose whether to quit the program!");
    app.dialog()
        .message("确定退出吗??")
        .kind(MessageDialogKind::Info)
        .title("Information")
        .buttons(MessageDialogButtons::OkCancelCustom(
            format!("退出"),
            format!("取消"),
        ))
        .show(move |result| match result {
            true => {
                log::info!("Exit application");
                main_window
                    .close()
                    .unwrap_or_else(|e| log::error!("Failed to close window: {}", e));
            },
            false => {
                log::info!("Cancels exiting the current program");
                dialog_shown.store(false, Ordering::Relaxed);
            }
        });
}

Reproduction

No response

Expected behavior

I want a dialog box to pop up when I close the program and let the user confirm

Full tauri info output

[✔] Environment
    - OS: Mac OS 14.5.0 x86_64 (X64)
    ✔ Xcode Command Line Tools: installed
    ✔ rustc: 1.84.0 (9fc6b4312 2025-01-07)
    ✔ cargo: 1.84.0 (66221abde 2024-11-19)
    ✔ rustup: 1.27.1 (54dd3d00f 2024-04-24)
    ✔ Rust toolchain: stable-x86_64-apple-darwin (default)
    - node: 22.11.0
    - yarn: 1.22.22
    - npm: 10.9.0


[-] Packages
    - tauri 🦀: 2.2.0
    - tauri-build 🦀: 2.0.4
    - wry 🦀: 0.48.0
    - tao 🦀: 0.31.1
    - @tauri-apps/api : 2.2.0
    - @tauri-apps/cli : 2.2.2

[-] Plugins
    - tauri-plugin-shell 🦀: 2.2.0
    - @tauri-apps/plugin-shell : 2.2.0
    - tauri-plugin-fs 🦀: 2.2.0
    - @tauri-apps/plugin-fs : not installed!
    - tauri-plugin-dialog 🦀: 2.2.0
    - @tauri-apps/plugin-dialog : 2.2.0
    - tauri-plugin-http 🦀: 2.2.0
    - @tauri-apps/plugin-http : not installed!

[-] App
    - build-type: bundle
    - CSP: unset
    - frontendDist: ../dist
    - devUrl: http://localhost:1420/
    - framework: Vue.js
    - bundler: Vite

Stack trace

Can print out this log: 'Wait for the user to choose whether to quit the program! '

Additional context

[build-dependencies]
tauri-build = { version = "2", features = [] }

[dependencies]
tauri = { version = "2", features = [] }
tauri-plugin-shell = "2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
chrono = "0.4"
quick-xml = "0.37.2"
tempfile = "3.15.0"
thiserror = "2.0"
zip = "2"
walkdir = "2.5.0"
# tokio = {version = "1.43.0", features = ["full"] }
tauri-plugin-fs = "2"
tauri-plugin-clipboard-manager = "2.2.0"
tauri-plugin-dialog = "2"
tauri-plugin-http = "2"
sqlx = { version = "0.8", default-features = false, features = ["runtime-tokio-native-tls", "sqlite", "macros"] }
# rusqlite = {version = "0.32.1", features = ["bundled-sqlcipher"] }
urlencoding = "2.1"
log = "0.4"
log4rs = {version = "1.3", features = ["gzip"] }

[dev-dependencies]
tokio = {version = "1.43.0", features = ["full"] }
@axzsd axzsd added status: needs triage This issue needs to triage, applied to new issues type: bug labels Jan 10, 2025
@axzsd axzsd changed the title [bug] [bug] CloseRequested:: prevent_close() is invalid Jan 10, 2025
@FabianLars
Copy link
Member

How are you closing the window? By clicking the red X in the native traffic lights?

@axzsd
Copy link
Author

axzsd commented Jan 11, 2025

How are you closing the window? By clicking the red X in the native traffic lights?

yes,I'm clicking the x in the top left corner

@FabianLars
Copy link
Member

hmm, it still works for me as far as i can see. Can you try to repro it in a fresh create-tauri-app project maybe?

@axzsd
Copy link
Author

axzsd commented Jan 12, 2025

hmm, it still works for me as far as i can see. Can you try to repro it in a fresh create-tauri-app project maybe?

Ok, I'll try.

@axzsd
Copy link
Author

axzsd commented Jan 15, 2025

hmm, it still works for me as far as i can see. Can you try to repro it in a fresh create-tauri-app project maybe?

I'm very sorry that I have been busy recently. Maybe the test will be postponed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: needs triage This issue needs to triage, applied to new issues type: bug
Projects
None yet
Development

No branches or pull requests

2 participants