在macOS上,使用gpui的 Rust应用程序,关闭主窗口时应用程序不会退出
我正在尝试用gpui构建一个Rust用户界面应用,但在关闭主窗口后应用程序不会退出。
macOS 12.7.6,内存16G
Xcode 14.2
rustover 2016.1.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"
构建并运行后,将显示一个窗口,点击窗口的关闭按钮,rustover的状态如下:

我也不知道这是为什么。
解决方案
尽管我个人也觉得这种行为颇让人困惑,但这其实是macOS上 GUI应用的标准做法。
也就是说,你在关闭主窗口后仍然可以手动退出程序:
use gpui::{
App, Application, Bounds, Context, SharedString, Window, WindowBounds, WindowOptions, div,
prelude::*, px, rgb, size,
};
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()
},
|window, cx| {
window.on_window_should_close(cx, |_window, _cx| {
println!("Main window is closing. Exiting app.");
std::process::exit(0);
});
cx.new(|_| HelloWorld {
text: "World".into(),
})
},
)
.unwrap();
});
}
不过我还是不建议这么做,因为Mac用户会对这种非标准行为感到困惑。
更好的替代方案
一个更常见的选项是支持类似 CMD + Q 的快捷键,它将关闭所有窗口并像下面这样终止进程:
use gpui::{
App, Application, Bounds, Context, KeyBinding, SharedString, Window, WindowBounds,
WindowOptions, actions, div, prelude::*, px, rgb, size,
};
actions!(HelloWorld, [Quit]);
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.bind_keys([KeyBinding::new("cmd-q", Quit, None)]);
cx.open_window(
WindowOptions {
window_bounds: Some(WindowBounds::Windowed(bounds)),
..Default::default()
},
|_, cx| {
cx.on_action(|_: &Quit, _cx| {
println!("Quit shortcut triggered");
std::process::exit(0);
});
cx.new(|_| HelloWorld {
text: "World".into(),
})
},
)
.unwrap();
});
}
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。