You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bevy(Wasm)环境下exit_on_all_closed不生效,如何处理浏览器标签页关闭?

Bevy Wasm环境下处理浏览器窗口/标签页关闭的解决方案

在原生环境中,Bevy的exit_on_all_closed参数可以在窗口关闭时触发应用退出,但这一逻辑不适用于WebAssembly(Wasm)环境——因为浏览器的窗口生命周期由JS引擎管理,Bevy原生的窗口关闭检测逻辑无法感知浏览器标签页/窗口的关闭事件。

解决方案:监听浏览器原生事件触发Bevy退出

我们可以通过web_sys crate监听浏览器的beforeunload或unload事件,在事件触发时向Bevy发送AppExit事件,实现应用的优雅退出。

步骤1:添加依赖

在Cargo.toml中添加web-sys依赖:

[dependencies]
bevy = "0.12" # 请匹配你的Bevy版本
web-sys = { version = "0.3", features = ["Window", "EventTarget", "BeforeUnloadEvent"] }

步骤2:编写事件监听系统

创建一个启动系统,注册浏览器的关闭事件监听,并在事件触发时发送Bevy的AppExit事件:

use bevy::app::AppExit;
use bevy::prelude::*;
use std::rc::Rc;
use web_sys::{window, BeforeUnloadEvent};

fn listen_for_browser_shutdown(mut exit_events: EventWriter<AppExit>) {
    let window = window().expect("浏览器环境不可用");
    
    // 创建闭包处理beforeunload事件
    let exit_events = Rc::new(exit_events);
    let closure = Closure::wrap(Box::new(move |_event: BeforeUnloadEvent| {
        // 发送AppExit事件触发Bevy退出
        exit_events.send(AppExit);
    }) as Box<dyn FnMut(_)>);

    // 注册事件监听器
    window.add_event_listener_with_callback(
        "beforeunload",
        closure.as_ref().unchecked_ref()
    ).expect("无法注册浏览器关闭事件监听器");

    // 防止闭包被GC回收
    closure.forget();
}

步骤3:将系统添加到Bevy应用

在main函数中注册上述启动系统:

fn main() {
    App::new()
        .add_plugins(DefaultPlugins.set(WindowPlugin {
            window: WindowDescriptor {
                title: "Extreme".to_string(),
                ..default()
            },
            add_primary_window: true,
            exit_on_all_closed: true,
            close_when_requested: true,
        }))
        .add_startup_system(listen_for_browser_shutdown)
        .run()
}

关键说明

  • beforeunload事件会在用户关闭标签页/窗口、刷新页面或导航离开时触发,适合用于执行资源清理、数据保存等退出前逻辑;
  • 如果不需要处理前置逻辑,仅需确保Bevy退出,也可以使用unload事件,但它的触发时机更晚,可能无法完成所有清理操作;
  • 即使不手动触发AppExit,浏览器关闭时也会直接终止Wasm实例,但手动监听事件可以实现优雅退出,避免资源泄漏或数据丢失。

内容的提问来源于stack exchange,提问作者tangoti84

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 06:45:35