桌面通知

出自 ArchWiki
(重定向自 通知)

桌面通知是以异步方式通知用户特定事件的小型被动弹出对话框。

Libnotify

libnotify 是桌面通知规范的一个独立于桌面的实现,它提供了 notify-send(1) 实用程序,并支持 GTKQt 应用程序。许多开源应用程序,如 EvolutionPidgin 已经在使用它。

提示: 可在规范中找到可用图标的概述。

通知服务器

为了接收通过 libnotify 发送的通知,需要一个通知服务器。

内置

CinnamonDeepinEnlightenmentGNOMEGNOME FlashbackKDE Plasma 使用它们自己的实现来显示通知,并且无法替换。它们的通知服务器在登录时自动启动,以通过 DBus 接收来自应用程序的通知。

独立

在其他桌面环境中,需要手动安装和启动通知服务器,例如使用 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 发送信号来发送通知时,如果 /usr/lib/notification-daemon-1.0/notification-daemon 尚未激活,D-Bus 将会激活它。

您还可以选择以下实现之一

  • Deadd Notification Center — 一个受 Dunst 启发的带有通知中心的 notification-daemon。
https://github.com/phuhl/linux_notification_center || deadd-notification-centerAUR
  • Dunst — 适用于 Linux 的极简主义通知守护程序,旨在完美融入像 dwm 这样的极简主义窗口管理器。自 1.6 版本起包含 Wayland 支持。
https://dunst-project.org/ || dunst
  • fnott — 键盘驱动且轻量级的 Wayland 通知守护程序,适用于基于 wlroots 的合成器。
https://codeberg.org/dnkl/fnott || fnott
  • LXQt Notification Daemon — 用于 LXQt 的通知服务器。
https://github.com/lxde/lxqt-notificationd || lxqt-notificationd
  • mako — 一个轻量级的 Wayland 通知守护程序;目前在 Swayriver 上工作。
https://github.com/emersion/mako || mako
  • MATE Notification Daemon — 用于 MATE 的通知服务器。
https://github.com/mate-desktop/mate-notification-daemon/ || mate-notification-daemon
  • Notification Daemon — 原始的通知服务器。
https://gitlab.gnome.org/Archive/notification-daemon || notification-daemon
您可以使用 /usr/lib/notification-daemon-1.0/notification-daemon 手动运行它。
  • Notify OSD — 用于 Unity 的通知服务器。
https://launchpad.net/notify-osd || notify-osd
  • statnot — 小型、轻量级的通知守护程序,可以将通知输出到根窗口的标题、stdout 或 FIFO 管道,使其与平铺窗口管理器很好地集成。
https://github.com/halhen/statnot || statnotAUR
  • swaync — 一个基于 GTK 的简单 Sway 通知守护程序。
https://github.com/ErikReider/SwayNotificationCenter || swaync
  • twmn — 用于平铺窗口管理器的通知系统。
https://github.com/sboli/twmn || twmn-gitAUR
  • wired — 轻量级通知守护程序,具有高度可定制的布局块,用 Rust 编写。
https://github.com/Toqozz/wired-notify || wiredAUR
  • 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.'
提示: 您可以按照 Systemd#通知服务失败 中的说明,并使用上述命令之一作为 ExecStart 命令的基础,来获取有关服务失败的通知。

替换之前的通知

如果已知通知的 ID,则可以替换通知;如果新的通知请求指定了相同的 ID,它将始终替换旧的通知。不幸的是,notify-send 不报告此 ID,因此需要在 CLI 上使用其他工具来执行此操作。一个有能力的 CLI 工具是 notify-send.py python 脚本,它提供了 notify-send 语法,并具有额外的 ID 报告和替换功能。

但是,对于某些通知服务器(例如 Notify-OSD),您可以将 string:x-canonical-private-synchronous: 提示与 notify-send 一起使用以达到相同的效果。

例如,要获取显示时间的通知

while true; do
  date=$(date)
  notify-send "$date" -h string:x-canonical-private-synchronous:my-notification
  sleep 1
done

包含按钮或监听通知的关闭/点击事件

使用 notify-send.py 脚本,可以使用 actions 来显示按钮或监听通知的 default-action(通常是用户点击时)和 close-action。当 action-icons 提示设置为 true 且通知守护程序支持此功能时,按钮将显示图标而不是文本。当相应的事件发生时,脚本会将 action 标识符或 "close" 打印到命令行。要监听默认操作(点击),必须使用 action 标识符 "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 服务文件。但是,当安装了多个通知服务器,并且其中一些服务器带有服务文件时,这会导致问题。例如,在没有明确指定所需的服务器的情况下同时安装 dunstmako,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 分钟超时后失败,如 日志 中所示

# 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

选择您想要使用的服务,如 #使用_D-Bus_服务的多个通知服务器 中所述,将解决此问题。

参见