Mac平台基于GPUI的Rust应用关闭主窗口后无法退出问题
GPUI 0.2.2应用关闭主窗口后进程无法退出(macOS)
问题重现
使用GPUI 0.2.2开发Rust UI应用,在macOS 12.7.6环境下,点击主窗口关闭按钮后,窗口消失但应用进程仍在后台运行,无法自动退出。
环境信息:
- macOS 12.7.6,16GB内存
- Xcode 14.2
- Rust/Cargo 1.95.0
- GPUI 0.2.2
原实现代码:
use gpui::{ div, prelude::*, px, rgb, size, App, Application, Bounds, Context, SharedString, Window, WindowBounds, WindowOptions, }; struct HelloWorld { text: SharedString, } impl Render for HelloWorld { fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement { div() .flex() .flex_col() .gap_3() .bg(rgb(0x505050)) .size(px(500.0)) .justify_center() .items_center() .shadow_lg() .border_1() .border_color(rgb(0x0000ff)) .text_xl() .text_color(rgb(0xffffff)) .child(format!("Hello, {}!", &self.text)) .child( div() .flex() .gap_2() .child(div().size_8().bg(gpui::red())) .child(div().size_8().bg(gpui::green())) .child(div().size_8().bg(gpui::blue())) .child(div().size_8().bg(gpui::yellow())) .child(div().size_8().bg(gpui::black())) .child(div().size_8().bg(gpui::white())), ) } } fn main() { Application::new().run(|cx: &mut App| { let bounds = Bounds::centered(None, size(px(500.), px(500.0)), cx); cx.open_window( WindowOptions { window_bounds: Some(WindowBounds::Windowed(bounds)), ..Default::default() }, |_, cx| { cx.new(|_| HelloWorld { text: "World".into(), }) }, ) .unwrap(); }); }
Cargo.toml配置:
[package] name = "gpui_test" version = "0.1.0" edition = "2024" [dependencies] gpui = "0.2.2"
原因分析
GPUI框架的默认行为中,关闭单个窗口不会自动触发应用退出——因为框架支持多窗口场景,关闭某一个窗口不代表要终止整个应用进程。因此需要手动监听窗口关闭事件,显式触发退出逻辑。
解决方案
在窗口创建后,订阅窗口的WillClose事件,在事件触发时调用cx.quit()终止应用进程。
修改后的代码
首先补充导入WillClose事件:
use gpui::{ div, prelude::*, px, rgb, size, App, Application, Bounds, Context, SharedString, Window, WindowBounds, WindowOptions, WillClose, // 新增事件导入 };
然后修改main函数,添加事件监听:
fn main() { Application::new().run(|cx: &mut App| { let bounds = Bounds::centered(None, size(px(500.), px(500.0)), cx); let window = cx.open_window( WindowOptions { window_bounds: Some(WindowBounds::Windowed(bounds)), ..Default::default() }, |_, cx| { cx.new(|_| HelloWorld { text: "World".into(), }) }, ) .unwrap(); // 监听窗口关闭事件,触发时退出应用 cx.subscribe(&window, move |_event: &WillClose, cx| { cx.quit(); }); }); }
验证效果
修改代码后重新编译运行,点击窗口关闭按钮,窗口消失的同时应用进程会正常退出,不会在后台残留。
内容的提问来源于stack exchange,提问作者long
相关产品推荐
相关产品推荐

