桌面通知
桌面通知是小的、被动的弹出对话框,以异步方式通知用户特定事件。
Libnotify
libnotify 是 Desktop Notifications Specification 的桌面无关实现,它提供了 notify-send(1) 工具以及对 GTK 和 Qt 应用程序的支持。它已经被许多开源应用程序使用,例如 Evolution 和 Pidgin。
通知服务器
为了接收通过 libnotify 发送的通知,需要一个通知服务器。
内置
Cinnamon、Deepin、Enlightenment、GNOME 和 GNOME Flashback 使用它们自己的实现来显示通知,并且可能无法被替换,因为它们的通知服务器会在登录时自动启动,以通过 DBus 接收来自应用程序的通知。
在 KDE Plasma 上,如果您进入系统托盘的配置,可以在“系统服务”下通过将“通知”旁边的下拉菜单更改为“禁用”来禁用内置通知服务器。然后,您可以在“系统设置”菜单的“系统 / 自启动”下,通过添加新的自启动应用程序来添加您偏好的通知服务器。您需要注销并重新登录才能生效。
独立运行
在其他桌面环境中,需要手动安装通知服务器并使用例如 XDG Autostart 来启动它。
或者,通过将通知服务器设为 D-Bus 服务,可以在首次调用时自动启动通知服务器。大多数通知服务器已经在 /usr/share/dbus-1/services 下提供 dbus 服务。对于某些实现,例如 notification-daemon 包,需要在用户 D-Bus 服务目录($XDG_DATA_HOME/dbus-1/services)中手动创建一个。
org.freedesktop.Notifications.service
[D-BUS Service] Name=org.freedesktop.Notifications Exec=/usr/lib/notification-daemon-1.0/notification-daemon
每当应用程序通过向 org.freedesktop.Notifications 发送信号来发送通知时,D-Bus 就会激活 /usr/lib/notification-daemon-1.0/notification-daemon(如果尚未激活)。
您还可以选择以下实现之一
- Deadd Notification Center — 一个受 Dunst 启发的带通知中心的 notification-daemon。- 截至 2025 年 2 月不再积极开发
- fnott — 适用于 wlroots-based 合成器的键盘驱动且轻量级的 Wayland 通知守护程序。
- LXQt Notification Daemon — LXQt 的通知服务器。
- MATE Notification Daemon — MATE 的通知服务器。
- Notification Daemon — 原始的通知服务器。
- https://gitlab.gnome.org/Archive/notification-daemon || notification-daemon
- 您可以使用
/usr/lib/notification-daemon-1.0/notification-daemon手动运行它。
- Notify OSD — Unity 的通知服务器。
- statnot — 小巧轻量的通知守护程序,可以将通知输出到根窗口的标题、标准输出或 FIFO 管道,使其能很好地与平铺窗口管理器集成。
- swaync — 一个简单的基于 GTK 的 Sway 通知守护程序。
- twmn — 平铺窗口管理器的通知系统。
- UKUI Notification Daemon — UKUI 的通知服务器。
- wired — 使用 Rust 编写的,具有高度可定制布局块的轻量级通知守护程序。
- Xfce Notification Daemon — Xfce 的通知服务器。
- https://docs.xfce.org/apps/notifyd/start || xfce4-notifyd
- 您可以使用
/usr/lib/xfce4/notifyd/xfce4-notifyd手动运行它。 - 提示 要配置 xfce4-notifyd,请运行以下命令:
xfce4-notifyd-config。
技巧与提示
发送通知给另一位用户
systemd-run(1) 可用于进入另一位用户的会话并向他们发送通知,例如,从以 root 身份运行的后台脚本发送。
# systemd-run --machine=target_user@.host --user notify-send 'Hello world!' 'This is an example notification.'
另一种方法是使用 systembus-notify。以下命令将向所有在用户会话中运行 systembus-notify 的用户显示通知。
$ dbus-send --system / net.nuetzlich.SystemNotifications.Notify 'string:Hello world!' 'string:This is an example notification.'
ExecStart 命令的基础,来收到关于服务失败的通知。替换上一条通知
通知可以通过其 ID 来替换;如果新的通知请求指定了相同的 ID,它将始终替换旧通知。不幸的是,notify-send 不报告此 ID,因此需要使用替代工具来在 CLI 上完成此操作。一个有能力的 CLI 工具是 notify-send.py Python 脚本,它提供了 notify-send 语法,并具有额外的 ID 报告和替换功能。
然而,对于*某些*通知服务器(例如 Notify-OSD),您可以使用 notify-send 的 string:x-canonical-private-synchronous: 提示来实现相同的结果。
例如,要显示时间的通知
while true; do date=$(date) notify-send "$date" -h string:x-canonical-private-synchronous:my-notification sleep 1 done
包含按钮或监听通知的关闭/点击事件
使用 notify-send.py 脚本,可以使用操作来显示按钮或监听通知的默认操作(通常是用户单击它时)和关闭操作。当 action-icons 提示设置为 true 且通知守护程序支持此功能时,按钮将显示图标而不是文本。当发生相应事件时,脚本会将操作标识符或“close”打印到命令行。要监听默认操作(单击),必须使用操作标识符“default”。
带图标按钮的示例
notify-send.py "Buttons" "Do you like em?" --hint boolean:action-icons:true --action yes:face-cool no:face-sick
带有 D-Bus 服务的多个通知服务器
如独立运行部分所述,用户可以创建 D-Bus 服务,以便自动启动通知服务器。某些实现已包含 D-Bus 服务文件。然而,当安装了多个通知服务器,并且其中一些附带了服务文件时,这就会引发一个问题。例如,同时安装 dunst 和 mako 而不明确指定所需的服务器,D-Bus 就会为用户选择其中一个,而这个决定不受用户控制。为了避免这种情况,您可以创建一个 org.freedesktop.Notifications.service(参见#独立运行)并指向您想使用的服务,然后重新启动会话,来覆盖使用的服务。
故障排除
应用程序卡顿一分钟
如果应用程序在尝试显示通知时卡住,可能是因为通知服务通过 D-Bus 服务错误地声明了其可用性。
例如,假设用户最近安装了一个需要 plasma-workspace 的 KDE 组件,但用户仍在运行 XFCE。在这种情况下,KDE 通知程序将获得优先,但用户并未运行它。应用程序将等待服务而卡住,直到超时后才会回退到 xfce4-notifyd。
最明显的卡顿可能来自音量指示器的滚动调整。
如果您遇到这种情况,您应该有两个通知处理程序。
$ find /usr/share/dbus-1/services/ -name '*Notif*'
org.kde.plasma.Notifications.service org.xfce.xfce4-notifyd.Notifications.service
在这两者中,一个会在 1 分钟超时后定期失败,如 journal 中所见。
# journalctl -g notif
Jul 01 09:40:49 laptop dbus-daemon[866]: [session uid=1000 pid=866] Activating service name='org.freedesktop.Notifications' requested by ':1.193' (uid=1000 pid=5432 comm="/usr/lib/xfce4/panel/wrapper-2.0 /usr/lib/xfce4/pa") Jul 01 09:41:49 laptop plasma_waitforname[6093]: org.kde.knotifications: WaitForName: Service was not registered within timeout Jul 01 09:41:49 laptop dbus-daemon[866]: [session uid=1000 pid=866] Activated service 'org.freedesktop.Notifications' failed: Process org.freedesktop.Notifications exited with status 1
如 #Multiple notification servers with D-Bus services 中所述,选择您想使用的服务将解决此问题。
参见
- Libnotify 参考手册
- C 示例 (存档版本)
- Python 通知示例
- Python notify 示例 (法语文章)