デスクトップ通知
関連記事
デスクトップ通知は、非同期に特定のイベントをユーザーに通知する小さくて控えめなポップアップダイアログです。
目次
Libnotify
libnotify は notify-send(1) ユーティリティや GTK と Qt のアプリケーションのサポートを提供する Desktop Notifications Specification の実装で特定のデスクトップに依存していません。この実装はすでに Evolution や Pidgin といった多くのオープンソースアプリによって使用されています。
通知サーバー
libnotify で送られた通知を受け取るには、通知サーバーが必要です。
ビルトイン
Cinnamon、Deepin、Enlightenment、GNOME、GNOME Flashback は独自の実装を用いて通知を表示します。これらの通知サーバーはアプリケーションからの通知を DBus 経由で受け取るためにログイン時に自動的に起動されるので、他の通知サーバーに置き換えることができない場合があります。
KDE Plasma では、システムトレイの設定を開き、システムサービスの項目から Notifications の横にあるドロップダウンを Disabled に変更することで、ビルトインの通知サーバーを無効化することができます。その後システム設定メニューで System / Autostart のところに新しい自動起動アプリケーションを追加することで、所望の通知サーバーを追加することができます。変更を適用するには一旦ログアウトし、ログインし直す必要があります。
スタンドアロン
他のデスクトップ環境では、通知サーバーは手動でインストールし、XDG Autostart などを使って起動する必要があります。
あるいは、通知サーバーを D-Bus サービスにすることで、通知サーバーを初めて呼び出した時に自動的に起動させることもできます。ほとんどの通知サーバーにはすでに dbus サービスが /usr/share/dbus-1/services
に用意されています。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 にインスパイヤされた、通知センターが付いた通知デーモン。2025年2月から開発が滞っています。
- fnott — wlroots ベースのコンポジタのための軽量な 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 — Sway のためのシンプルな GTK ベースの通知デーモン。
- twmn — タイル型ウィンドウマネージャ向けの通知システム。
- wired — レイヤーブロックのカスタマイズ性が高い軽量な通知デーモン。Rust で書かれている。
- Xfce Notification Daemon — Xfce の通知サーバー。
- https://docs.xfce.org/apps/notifyd/start || xfce4-notifyd
/usr/lib/xfce4/notifyd/xfce4-notifyd
で手動で起動できます。
ヒントとテクニック
他のユーザーに通知を送る
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.'
以前の通知を置き換える
通知 ID がわかっている場合は、その通知を置き換えることができます。新しい通知リクエストで同じ ID が指定されている場合、常に古い通知が置き換えられます。(上記の libnotify バインディングはこれを自動的に処理します。) 残念ながら、notify-send はこの ID を報告しないため、CLI でこれを行うには代替ツールが必要です。有効な CLI ツールの 1 つは、notify-send.py Python スクリプトです。これは、追加の ID レポート機能と置換機能を備えた Notify-Send 構文を提供します。
ただし、一部の 通知サーバー (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 に設定されており、通知デーモンがこれをサポートしている場合、ボタンにはテキストの代わりにアイコンが表示されます。スクリプトは、対応するイベントが発生したときに、コマンドラインにアクション ID または "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
(#スタンドアロン を参照) を作成して、使用したいサービスを指定することで、使用されるサービスをオーバーライドすることができます。ファイルの作成後は、セッションを再起動してください。
トラブルシューティング
アプリケーションがちょうど 1 分間ハングする
アプリケーションが通知を表示しようとした際にハングしてしまう場合、通知サービスが自身の可用性を誤って D-Bus サービス経由で広告してしまっているのかもしれません。
たとえば、ユーザーが最近、plasma-workspace を必要とする KDE コンポーネントをインストールしたが、まだ XFCE を実行しているとします。この場合、KDE 通知機能が優先されますが、ユーザーはそれを実行していません。アプリケーションはサービスの待機中にハングし、タイムアウト後に xfce4-notifyd にフォールバックすることになります。
最もわかりやすいハングは、通知インディケータの調整スクロールでしょう。
このような場合、2つの通知ハンドラーが存在するはずです:
$ find /usr/share/dbus-1/services/ -name '*Notif*'
org.kde.plasma.Notifications.service org.xfce.xfce4-notifyd.Notifications.service
journal を見ると、これら2つのうちどちら一方が定期的に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 サービスが同梱されている通知サーバーが複数ある場合 で説明されているように、使いたいサービスを指定すれば、問題は解決します。
参照
- Libnotify リファレンスマニュアル
- C サンプル (アーカイブされたバージョン)
- Python の通知サンプル
- Python の通知サンプル (フランス語の記事)