Notification
Notification 是一个 toast 通知系统,用于向用户显示短暂消息。通知会出现在窗口右上角,并可在超时后自动消失。它支持多种类型、标题、自定义内容和操作按钮,适合状态反馈、确认信息和异步操作提示。
#导入
use gpui_kit::component::{
notification::{Notification, NotificationType},
WindowExt
};
#用法
#通知的渲染位置
窗口的 Root 会自动挂载并渲染通知层。使用 gpui_kit::open_window 打开窗口,或将应用视图包裹在 Root::new 中即可,无需在视图中手动渲染浮层。
#基础通知
window.push_notification("This is a notification.", cx);
Notification::new()
.message("Your changes have been saved.")
#通知类型
window.push_notification(
(NotificationType::Info, "File saved successfully."),
cx,
);
window.push_notification(
(NotificationType::Success, "Payment processed successfully."),
cx,
);
window.push_notification(
(NotificationType::Warning, "Network connection is unstable."),
cx,
);
window.push_notification(
(NotificationType::Error, "Failed to save file. Please try again."),
cx,
);
#带标题
Notification::new()
.title("Update Available")
.message("A new version of the application is ready to install.")
.with_type(NotificationType::Info)
#自动隐藏
Notification::new()
.message("This notification stays until manually closed.")
.autohide(false)
Notification::new()
.message("This will disappear automatically.")
.autohide(true)
指针悬停在通知上或某条通知获得键盘焦点时倒计时暂停,指针移开或焦点离开后继续。窗口未激活时倒计时照常进行,不能错过的消息应关闭自动隐藏或使用系统通知投递。
#通知位置
通知默认出现在窗口右上角。可以为所有通知设置全局默认值,也可以为单条通知覆盖。每个位置分别维护自己的堆叠。
use gpui_kit::Anchor;
// 全局默认值(默认:`Anchor::TopRight`)
Theme::update(cx, |theme| theme.notification.placement = Anchor::BottomRight);
// 单条通知覆盖
Notification::info("Download complete.")
.placement(Anchor::BottomLeft)
支持的值有 Anchor::TopLeft、Anchor::TopCenter、Anchor::TopRight、Anchor::LeftCenter、Anchor::RightCenter、Anchor::BottomLeft、Anchor::BottomCenter 和 Anchor::BottomRight。
#操作按钮
Notification::new()
.title("Connection Lost")
.message("Unable to connect to server.")
.with_type(NotificationType::Error)
.autohide(false)
.action(|_, cx| {
Button::new("retry")
.primary()
.label("Retry")
.on_click(cx.listener(|this, _, window, cx| {
println!("Retrying connection...");
this.dismiss(window, cx);
}))
})
#可点击通知
Notification::new()
.message("Click to view details")
.on_click(cx.listener(|_, _, _, cx| {
println!("Notification clicked");
cx.notify();
}))
#自定义内容
use gpui_kit::component::text::markdown;
let markdown_content = r#"
## Custom Notification
- **Feature**: New dashboard available
- **Status**: Ready to use
- [Learn more](https://example.com)
"#;
Notification::new()
.content(|_, window, cx| {
markdown(markdown_content).into_any_element()
})
#唯一通知 ID
如果你要手动管理通知,例如长任务状态或持久警告,可以为通知分配唯一 ID。
struct UpdateNotification;
Notification::new()
.id::<UpdateNotification>()
.message("System update available")
.autohide(false)
struct TaskNotification;
Notification::warning("Task failed to complete")
.id1::<TaskNotification>("task-123")
.title("Task Failed")
后续可以通过:
window.remove_notification::<UpdateNotification>(cx);
来移除对应通知。
#系统通知
通知也可以投递到操作系统的通知中心。使用 NotificationDelivery 选择通知的去向:应用内 toast(InApp,默认)、系统通知中心(System)、或两者都发(InAppAndSystem)。
use gpui_kit::component::notification::{Notification, NotificationDelivery};
// 单条通知覆盖;`.system()` 和 `.in_app_and_system()` 是
// `.delivery(NotificationDelivery::...)` 的简写。
Notification::info("Your download is ready.")
.title("Download complete")
.system()
// 或为所有通知设置全局默认值
Theme::update(cx, |theme| {
theme.notification.delivery = NotificationDelivery::InAppAndSystem
});
通知的标题和消息分别成为系统通知的标题和正文;两者都缺失时不会投递。用相同的 .id::<T>() 再次推送会替换之前的系统通知,window.remove_notification::<T>(cx) / window.clear_notifications(cx) 会将其撤回。toast 自动隐藏时,系统通知会保留在通知中心。
点击系统通知会激活应用及其窗口、关闭对应的应用内 toast(如有)、并以默认的 ClickEvent 触发 on_click。NotificationDelivery::System 模式下没有 toast,因此 on_close 不会被调用。
gpui_kit::component::init 会注册应用级的 on_system_notification_response 处理器,之后请勿再自行注册——gpui 只保留一个。应用通过 cx.show_system_notification 直接发送的系统通知不受影响。
平台要求:
| 平台 | 要求 | 撤回 |
|---|---|---|
| macOS | 必须从可信位置(如 /Applications)的打包 .app 运行;cargo run 裸跑时静默禁用。首次投递会触发系统授权弹窗,拒绝后系统会记住该选择,后续投递静默失败 | 支持 |
| Windows | 启动早期调用 cx.set_app_identity(identifier, name) | 支持 |
| Linux | 需要 XDG 通知守护进程 | 不支持(自然过期) |
#示例
#表单校验失败
Notification::error("Please correct the following errors before submitting.")
.title("Validation Failed")
.autohide(false)
#文件上传进度
struct UploadNotification;
window.push_notification(
Notification::info("Uploading file...")
.id::<UploadNotification>()
.title("File Upload")
.autohide(false),
cx,
);