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::TopLeftAnchor::TopCenterAnchor::TopRightAnchor::LeftCenterAnchor::RightCenterAnchor::BottomLeftAnchor::BottomCenterAnchor::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_clickNotificationDelivery::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,
);