「デスクトップ通知」の版間の差分
(→ヒントとテクニック: 同期) |
(TranslationStatus の時刻形式を合わせる) |
||
| (同じ利用者による、間の3版が非表示) | |||
| 1行目: | 1行目: | ||
[[Category:X サーバー]] |
[[Category:X サーバー]] |
||
[[Category:通知]] |
[[Category:通知]] |
||
| − | [[Category:開発]] |
||
[[Category:ソフトウェア一覧]] |
[[Category:ソフトウェア一覧]] |
||
[[en:Desktop notifications]] |
[[en:Desktop notifications]] |
||
| + | [[zh-hans:桌面通知程序]] |
||
| − | [[es:Desktop notifications]] |
||
| − | [[ru:Desktop notifications]] |
||
{{Related articles start}} |
{{Related articles start}} |
||
| − | {{Related|GTK |
+ | {{Related|GTK}} |
{{Related|Libcanberra}} |
{{Related|Libcanberra}} |
||
{{Related articles end}} |
{{Related articles end}} |
||
デスクトップ通知は、非同期に特定のイベントをユーザーに通知する小さくて控えめなポップアップダイアログです。 |
デスクトップ通知は、非同期に特定のイベントをユーザーに通知する小さくて控えめなポップアップダイアログです。 |
||
| − | ==Libnotify== |
+ | == Libnotify == |
| − | + | {{Pkg|libnotify}} は {{man|1|notify-send}} ユーティリティや [[GTK]] と [[Qt]] のアプリケーションのサポートを提供する [https://specifications.freedesktop.org/notification-spec/latest/ Desktop Notifications Specification] の実装で特定のデスクトップに依存していません。この実装はすでに [[Evolution]] や [[Pidgin]] といった多くのオープンソースアプリによって使用されています。 |
|
| + | {{Tip|利用可能なアイコンに関する概要は[https://specifications.freedesktop.org/icon-naming-spec/latest/ 仕様]にあります。}} |
||
| − | libnotify を使うには、[[#通知サーバー|通知サーバー]]をインストールする必要があります。 |
||
== 通知サーバー == |
== 通知サーバー == |
||
| + | [[#Libnotify|libnotify]] で送られた通知を受け取るには、通知サーバーが必要です。 |
||
| − | ===ビルトイン=== |
||
| − | 以下のデスクトップ環境では通知を表示するためにそれぞれ独自の実装を使っており、置き換えることができません。通知サーバーはログイン時に自動で起動し DBus によってアプリケーションからの通知を受け取ります。 |
||
| + | === ビルトイン === |
||
| − | * [[Cinnamon]] は通知サーバーを備えており、通知は画面の右上に表示されます。 |
||
| − | * [[Enlightenment]] は Notification 拡張を通して通知サーバーを提供しています。通知オプションは[[Enlightenment#通知|設定]]が可能です。 |
||
| − | * [[GNOME]] は通知サーバーを備えており、通知は画面の上部に表示されます。 |
||
| − | * [[KDE]] は通知サーバーを備えており、通知は画面の右下に表示されます。 |
||
| + | [[Cinnamon]]、[[Deepin]]、[[Enlightenment]]、[[GNOME]]、[[GNOME Flashback]] は独自の実装を用いて通知を表示します。これらの通知サーバーはアプリケーションからの通知を DBus 経由で受け取るためにログイン時に自動的に起動されるので、他の通知サーバーに置き換えることができない場合があります。 |
||
| − | また、[[Deepin]] および [[GNOME Flashback]] も同様に通知サーバーを備えています。 |
||
| + | [[KDE Plasma]] では、システムトレイの設定を開き、システムサービスの項目から Notifications の横にあるドロップダウンを Disabled に変更することで、ビルトインの通知サーバーを無効化することができます。その後システム設定メニューで System / Autostart のところに新しい自動起動アプリケーションを追加することで、所望の通知サーバーを追加することができます。変更を適用するには一旦ログアウトし、ログインし直す必要があります。 |
||
| − | ===スタンドアロン=== |
||
| − | 他のデスクトップ環境では、ウィンドウマネージャやデスクトップ環境の自動実行を使って通知サーバーを起動する必要があります。 |
||
| + | === スタンドアロン === |
||
| − | [[D-Bus]] で初めて呼ばれた時に通知サーバーを起動させるには、通知サーバー ({{Pkg|notification-daemon}} パッケージなど) をインストールした後、以下のように設定を {{ic|/usr/share/dbus-1/services}} (またはユーザー個別に起動したい場合 {{ic|$XDG_DATA_HOME/dbus-1/services}}) に追加します: |
||
| + | |||
| + | 他のデスクトップ環境では、通知サーバーは手動でインストールし、[[XDG Autostart]] などを使って起動する必要があります。 |
||
| + | |||
| + | あるいは、通知サーバーを [[D-Bus]] サービスにすることで、通知サーバーを初めて呼び出した時に自動的に起動させることもできます。ほとんどの通知サーバーにはすでに dbus サービスが {{ic|/usr/share/dbus-1/services}} に用意されています。{{Pkg|notification-daemon}} などの一部の実装では、ユーザー [[D-Bus]] サービスのディレクトリ ({{ic|$XDG_DATA_HOME/dbus-1/services}}) 内に手動でサービスを作る必要があります: |
||
{{hc|org.freedesktop.Notifications.service|2= |
{{hc|org.freedesktop.Notifications.service|2= |
||
| 40行目: | 37行目: | ||
Exec=/usr/lib/notification-daemon-1.0/notification-daemon |
Exec=/usr/lib/notification-daemon-1.0/notification-daemon |
||
}} |
}} |
||
| + | |||
| + | アプリケーションが通知を送ると (つまり {{ic|org.freedesktop.Notifications}} にシグナルを送ると)、{{ic|/usr/lib/notification-daemon-1.0/notification-daemon}} がまだアクティブ化されていない場合、D-Bus によってアクティブ化されます。 |
||
通知サーバーは以下から選ぶことができます: |
通知サーバーは以下から選ぶことができます: |
||
| − | * {{App| |
+ | * {{App|Deadd Notification Center|Dunst にインスパイヤされた、通知センターが付いた通知デーモン。[https://github.com/phuhl/linux_notification_center/issues/255 2025年2月から開発が滞っています。]|https://github.com/phuhl/linux_notification_center|{{AUR|deadd-notification-center}}}} |
| + | * {{App|[[Dunst]]|[[dwm]] などのミニマルなウィンドウマネージャにうってつけの Linux 用の最小通知デーモン。1.6 から Wayland サポートがあります。|https://dunst-project.org/|{{Pkg|dunst}}}} |
||
| − | * {{App|Deadd Notification Center|Dnust にインスパイヤされた、通知センターが付いた通知デーモン。|https://github.com/phuhl/linux_notification_center|{{AUR|deadd-notification-center}}}} |
||
| − | * {{App| |
+ | * {{App|fnott|wlroots ベースのコンポジタのための軽量な Wayland 向けの通知デーモン。キーボードによって操作可能。|https://codeberg.org/dnkl/fnott|{{Pkg|fnott}}}} |
| − | * {{App| |
+ | * {{App|LXQt Notification Daemon|[[LXQt]] の通知サーバー。|https://github.com/lxde/lxqt-notificationd|{{Pkg|lxqt-notificationd}}}} |
| − | * {{App| |
+ | * {{App|mako|[[Wayland]] 向けの軽量な通知サーバー。現時点では [[Sway]] と {{Pkg|river}} 上で動作します。|https://github.com/emersion/mako|{{Pkg|mako}}}} |
| − | * {{App|mako|[[Wayland]] 向けの軽量な通知サーバー。現時点では [[Sway]] と一緒に動作します。|https://github.com/emersion/mako|{{Pkg|mako}} {{AUR|mako-git}}}} |
||
* {{App|MATE Notification Daemon|[[MATE]] の通知サーバー。|https://github.com/mate-desktop/mate-notification-daemon/|{{Pkg|mate-notification-daemon}}}} |
* {{App|MATE Notification Daemon|[[MATE]] の通知サーバー。|https://github.com/mate-desktop/mate-notification-daemon/|{{Pkg|mate-notification-daemon}}}} |
||
| − | * {{App|Notification Daemon| |
+ | * {{App|Notification Daemon|オリジナルの通知サーバー。|https://gitlab.gnome.org/Archive/notification-daemon|{{Pkg|notification-daemon}}}} |
:{{ic|/usr/lib/notification-daemon-1.0/notification-daemon}} で手動で起動できます。 |
:{{ic|/usr/lib/notification-daemon-1.0/notification-daemon}} で手動で起動できます。 |
||
| − | * {{App|Notify OSD| |
+ | * {{App|Notify OSD|Unity の通知サーバー。|https://launchpad.net/notify-osd|{{Pkg|notify-osd}}}} |
* {{App|statnot|小さくて軽量な通知デーモン。ルートウィンドウのタイトルや標準出力、FIFO パイプなどに通知を出力できるので、タイル型ウィンドウマネージャと相性がとても良いです。|https://github.com/halhen/statnot|{{AUR|statnot}}}} |
* {{App|statnot|小さくて軽量な通知デーモン。ルートウィンドウのタイトルや標準出力、FIFO パイプなどに通知を出力できるので、タイル型ウィンドウマネージャと相性がとても良いです。|https://github.com/halhen/statnot|{{AUR|statnot}}}} |
||
| − | * {{App| |
+ | * {{App|swaync|[[Sway]] のためのシンプルな GTK ベースの通知デーモン。|https://github.com/ErikReider/SwayNotificationCenter|{{Pkg|swaync}}}} |
* {{App|twmn|タイル型ウィンドウマネージャ向けの通知システム。|https://github.com/sboli/twmn|{{AUR|twmn-git}}}} |
* {{App|twmn|タイル型ウィンドウマネージャ向けの通知システム。|https://github.com/sboli/twmn|{{AUR|twmn-git}}}} |
||
* {{App|wired|レイヤーブロックのカスタマイズ性が高い軽量な通知デーモン。Rust で書かれている。|https://github.com/Toqozz/wired-notify|{{AUR|wired}}}} |
* {{App|wired|レイヤーブロックのカスタマイズ性が高い軽量な通知デーモン。Rust で書かれている。|https://github.com/Toqozz/wired-notify|{{AUR|wired}}}} |
||
| − | * {{App|Xfce Notification Daemon|[[Xfce]] の通知サーバー。|https:// |
+ | * {{App|Xfce Notification Daemon|[[Xfce]] の通知サーバー。|https://docs.xfce.org/apps/notifyd/start|{{Pkg|xfce4-notifyd}}}} |
| + | :{{ic|/usr/lib/xfce4/notifyd/xfce4-notifyd}} で手動で起動できます。 |
||
:{{Tip|xfce4-notifyd を設定するには、ターミナルから次のコマンドを実行してください: {{ic|xfce4-notifyd-config}}。}} |
:{{Tip|xfce4-notifyd を設定するには、ターミナルから次のコマンドを実行してください: {{ic|xfce4-notifyd-config}}。}} |
||
| + | == ヒントとテクニック == |
||
| − | ==プログラミングでの使い方== |
||
| − | GObject-Introspection やバインディングを通して多くのプログラミング言語を使ったり、または bash を利用して簡単に libnotify でメッセージを表示することができます。 |
||
| + | === 他のユーザーに通知を送る === |
||
| − | 以下の例ではシンプルな "Hello world" の通知が表示されます。 |
||
| + | {{man|1|systemd-run}} を使うことで (例えば root として実行されたバックグラウンドのスクリプトなどから)、他のユーザーのセッションに入り、そのユーザーに通知を送ることができます: |
||
| − | ===Bash=== |
||
| + | # systemd-run --machine=''target_user''@.host --user notify-send 'Hello world!' 'This is an example notification.' |
||
| − | * 依存パッケージ: {{Pkg|libnotify}} |
||
| + | もう一つの方法は {{Pkg|systembus-notify}} です。以下のコマンドは、{{ic|systembus-notify}} をセッション内に実行しているすべてのユーザーに通知を表示します: |
||
| − | {{hc|hello_world.sh|2= |
||
| − | #!/bin/bash |
||
| − | notify-send 'Hello world!' 'This is an example notification.' --icon=dialog-information |
||
| − | }} |
||
| + | $ dbus-send --system / net.nuetzlich.SystemNotifications.Notify 'string:Hello world!' 'string:This is an example notification.' |
||
| − | {{Tip| |
||
| − | * 利用可能なアイコンは [https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html Icon Naming Specification] から参照できます。 |
||
| − | * root で実行するバックグラウンドスクリプトからデスクトップ通知を送信するには ({{ic|''X_user''}} と {{ic|''X_userid''}} は X を実行するユーザーおよびユーザー ID に置き換えてください): {{ic|1=# sudo -u ''X_user'' DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/''X_userid''/bus notify-send 'Hello world!' 'This is an example notification.'}}。}} |
||
| + | {{Tip|[[systemd#サービスの失敗を通知する]] で説明されているようにして、上記のコマンドを {{ic|ExecStart}} コマンドで実行することで、失敗したサービスを通知で知らせることもできます。}} |
||
| − | === Boo === |
||
| − | |||
| − | * 依存パッケージ: {{Pkg|notify-sharp-3}} ({{AUR|boo}}) |
||
| − | * ビルドするのに必要なパッケージ: {{AUR|boo}} |
||
| − | * ビルド: {{ic|booc hello_world.boo}} |
||
| − | * 実行: {{ic|mono hello_world.exe}} (または {{ic|booi hello_world.boo}}) |
||
| − | |||
| − | {{hc|hello_world.boo|2= |
||
| − | import Notifications from "notify-sharp" |
||
| − | Hello = Notification() |
||
| − | Hello.Summary = "Hello world!" |
||
| − | Hello.Body = "This is an example notification." |
||
| − | Hello.IconName = "dialog-information" |
||
| − | Hello.Show() |
||
| − | }} |
||
| − | |||
| − | === C === |
||
| − | |||
| − | * 依存パッケージ: {{Pkg|glib2}} |
||
| − | * ビルド: {{ic|gcc -o hello_world `pkg-config --cflags --libs gio-2.0` hello_world.c}} |
||
| − | |||
| − | {{hc|hello_world.c|2= |
||
| − | #include <gio/gio.h> |
||
| − | int main() { |
||
| − | GApplication *application = g_application_new ("hello.world", G_APPLICATION_FLAGS_NONE); |
||
| − | g_application_register (application, NULL, NULL); |
||
| − | GNotification *notification = g_notification_new ("Hello world!"); |
||
| − | g_notification_set_body (notification, "This is an example notification."); |
||
| − | GIcon *icon = g_themed_icon_new ("dialog-information"); |
||
| − | g_notification_set_icon (notification, icon); |
||
| − | g_application_send_notification (application, NULL, notification); |
||
| − | g_object_unref (icon); |
||
| − | g_object_unref (notification); |
||
| − | g_object_unref (application); |
||
| − | return 0; |
||
| − | } |
||
| − | }} |
||
| − | |||
| − | * 依存パッケージ: {{Pkg|libnotify}} |
||
| − | * ビルド: {{ic|gcc -o hello_world `pkg-config --cflags --libs libnotify` hello_world.c}} |
||
| − | |||
| − | {{hc|hello_world.c|2= |
||
| − | #include <libnotify/notify.h> |
||
| − | int main() { |
||
| − | notify_init ("Hello world!"); |
||
| − | NotifyNotification * Hello = notify_notification_new ("Hello world", "This is an example notification.", "dialog-information"); |
||
| − | notify_notification_show (Hello, NULL); |
||
| − | g_object_unref(G_OBJECT(Hello)); |
||
| − | notify_uninit(); |
||
| − | return 0; |
||
| − | } |
||
| − | }} |
||
| − | |||
| − | === C++ === |
||
| − | |||
| − | * 依存パッケージ: {{Pkg|glibmm}} |
||
| − | * ビルド: {{Ic|g++ -o hello_world `pkg-config --cflags --libs giomm-2.4` hello_world.cc}} |
||
| − | |||
| − | {{hc|hello_world.cc|2= |
||
| − | #include <giomm-2.4/giomm.h> |
||
| − | int main(int argc, char *argv[]) { |
||
| − | auto Application = Gio::Application::create("hello.world", Gio::APPLICATION_FLAGS_NONE); |
||
| − | Application->register_application(); |
||
| − | auto Notification = Gio::Notification::create("Hello world"); |
||
| − | Notification->set_body("This is an example notification."); |
||
| − | auto Icon = Gio::ThemedIcon::create("dialog-information"); |
||
| − | Notification->set_icon (Icon); |
||
| − | Application->send_notification(Notification); |
||
| − | return 0; |
||
| − | } |
||
| − | }} |
||
| − | |||
| − | * 依存パッケージ: {{AUR|libnotifymm}} |
||
| − | * ビルド: {{Ic|g++ -o hello_world `pkg-config --cflags --libs libnotifymm-1.0` hello_world.cc}} |
||
| − | |||
| − | {{hc|hello_world.cc|2= |
||
| − | #include <libnotifymm.h> |
||
| − | int main(int argc, char *argv[]) { |
||
| − | Notify::init("Hello world!"); |
||
| − | Notify::Notification Hello("Hello world", "This is an example notification.", "dialog-information"); |
||
| − | Hello.show(); |
||
| − | return 0; |
||
| − | } |
||
| − | }} |
||
| − | |||
| − | === C# === |
||
| − | |||
| − | * 依存パッケージ: {{Pkg|notify-sharp-3}} |
||
| − | * ビルド: {{ic|mcs -pkg:notify-sharp-3.0 hello_world.cs}} |
||
| − | * 実行: {{ic|mono hello_world.exe}} |
||
| − | |||
| − | {{hc|hello_world.cs|2= |
||
| − | using Notifications; |
||
| − | public class HelloWorld { |
||
| − | static void Main() { |
||
| − | var Hello = new Notification(); |
||
| − | Hello.Summary = "Hello world!"; |
||
| − | Hello.Body = "This is an example notification."; |
||
| − | Hello.IconName = "dialog-information"; |
||
| − | Hello.Show(); |
||
| − | } |
||
| − | } |
||
| − | }} |
||
| − | |||
| − | ===Crystal=== |
||
| − | |||
| − | * 依存パッケージ: [https://github.com/woodruffw/notify.cr woodruffw/notify.cr] (shards から) |
||
| − | * ビルドするのに必要なパッケージ: {{Pkg|crystal}} および {{Pkg|shards}} |
||
| − | |||
| − | {{hc|hello_world.cr|2= |
||
| − | require "notify" |
||
| − | notifier = Notify.new |
||
| − | notifier.notify "Hello", body: "<b>World!</b>" |
||
| − | }} |
||
| − | |||
| − | === F# === |
||
| − | |||
| − | * 依存パッケージ: {{Pkg|notify-sharp-3}} |
||
| − | * ビルドするのに必要なパッケージ: {{AUR|fsharp}} |
||
| − | * ビルド: {{ic|fsharpc -r:notify-sharp.dll -I:/usr/lib/mono/notify-sharp-3.0/ -I:/usr/lib/mono/gtk-sharp-3.0/ hello_world.fs}} |
||
| − | * 実行: {{ic|mono hello_world.exe}} |
||
| − | |||
| − | {{hc|hello_world.fs|2= |
||
| − | open Notifications |
||
| − | let Hello = new Notification() |
||
| − | Hello.Summary <- "Hello world!" |
||
| − | Hello.Body <- "This is an example notification." |
||
| − | Hello.IconName <- "dialog-information" |
||
| − | Hello.Show() |
||
| − | }} |
||
| − | |||
| − | === Genie === |
||
| − | |||
| − | * 依存パッケージ: {{Pkg|glib2}} |
||
| − | * ビルドするのに必要なパッケージ: {{Pkg|vala}} |
||
| − | * ビルド: {{ic|valac --pkg gio-2.0 hello_world.gs}} |
||
| − | |||
| − | {{hc|hello_world.gs|2= |
||
| − | uses |
||
| − | GLib |
||
| − | |||
| − | init |
||
| − | var Application = new GLib.Application ("hello.world", GLib.ApplicationFlags.FLAGS_NONE); |
||
| − | Application.register (); |
||
| − | var Notification = new GLib.Notification ("Hello world"); |
||
| − | Notification.set_body ("This is an example notification."); |
||
| − | var Icon = new GLib.ThemedIcon ("dialog-information"); |
||
| − | Notification.set_icon (Icon); |
||
| − | Application.send_notification (null, Notification); |
||
| − | }} |
||
| − | |||
| − | * 依存パッケージ: {{Pkg|libnotify}} |
||
| − | * ビルドするのに必要なパッケージ: {{Pkg|vala}} |
||
| − | * ビルド: {{ic|valac --pkg libnotify hello_world.gs}} |
||
| − | |||
| − | {{hc|hello_world.gs|2= |
||
| − | uses |
||
| − | Notify |
||
| − | |||
| − | init |
||
| − | Notify.init ("Hello world") |
||
| − | var Hello=new Notify.Notification ("Hello world!","This is an example notification.","dialog-information") |
||
| − | Hello.show () |
||
| − | }} |
||
| − | |||
| − | === Go === |
||
| − | |||
| − | * 依存パッケージ: {{Pkg|libnotify}} |
||
| − | * ビルドするのに必要なパッケージ: {{AUR|go-notify-git}} |
||
| − | * ビルド: {{ic|go build hello_world.go}} |
||
| − | * 実行: {{ic|go run hello_world.go}} |
||
| − | |||
| − | {{hc|hello_world.go|2= |
||
| − | package main |
||
| − | import ("github.com/mqu/go-notify") |
||
| − | |||
| − | func main() { |
||
| − | notify.Init("Hello world") |
||
| − | hello := notify.NotificationNew("Hello World!", "This is an example notification.","dialog-information") |
||
| − | hello.Show() |
||
| − | } |
||
| − | }} |
||
| − | |||
| − | === Groovy === |
||
| − | |||
| − | * 依存パッケージ: {{Pkg|groovy}}, {{AUR|java-gnome}} |
||
| − | * ビルド: {{ic|groovyc -cp /usr/share/java/gtk.jar HelloWorld.groovy && jar cfe HelloWorld.jar HelloWorld HelloWorld.class}} |
||
| − | * 実行: {{ic|java -cp /usr/share/groovy/embeddable/groovy-all.jar:/usr/share/java/gtk.jar:HelloWorld.jar HelloWorld}} (または {{ic|groovy -cp /usr/share/java/gtk.jar HelloWorld.groovy}}) |
||
| − | |||
| − | {{hc|HelloWorld.groovy|2= |
||
| − | import org.gnome.gtk.* |
||
| − | import org.gnome.notify.* |
||
| − | |||
| − | Gtk.init() |
||
| − | Notify.init("Hello world") |
||
| − | def Hello = new Notification("Hello world!", "This is an example notification.", "dialog-information") |
||
| − | Hello.show() |
||
| − | }} |
||
| − | |||
| − | === Haskell === |
||
| − | |||
| − | * ビルドするのに必要なパッケージ: {{Pkg|haskell-fdo-notify}} |
||
| − | * ビルド: {{ic|ghc hello_world}} |
||
| − | {{hc|hello_world.hs|2= |
||
| − | import DBus.Notify |
||
| − | main = do |
||
| − | client <- connectSession |
||
| − | let hello = blankNote { summary="Hello world!", |
||
| − | body=(Just $ Text "This is an example notification."), |
||
| − | appImage=(Just $ Icon "dialog-information") } |
||
| − | notification <- notify client hello |
||
| − | return 0 |
||
| − | }} |
||
| − | |||
| − | === IronPython === |
||
| − | |||
| − | * 依存パッケージ: {{Pkg|notify-sharp-3}}, {{AUR|ironpython}} |
||
| − | * 実行: {{ic|ipy hello_world.py}} |
||
| − | |||
| − | {{hc|hello_world.py|2= |
||
| − | import clr |
||
| − | clr.AddReference('notify-sharp') |
||
| − | import Notifications |
||
| − | Hello = Notifications.Notification() |
||
| − | Hello.Summary = "Hello world!" |
||
| − | Hello.Body = "This is an example notification." |
||
| − | Hello.IconName = "dialog-information" |
||
| − | Hello.Show() |
||
| − | }} |
||
| − | |||
| − | === Java === |
||
| − | |||
| − | * 依存パッケージ: {{AUR|java-gnome}} |
||
| − | * ビルドするのに必要なパッケージ: java-environment |
||
| − | * ビルド: {{ic|javac -cp /usr/share/java/gtk.jar HelloWorld.java && jar cfe HelloWorld.jar HelloWorld HelloWorld.class}} |
||
| − | * 実行: {{ic|java -cp /usr/share/java/gtk.jar:HelloWorld.jar HelloWorld}} |
||
| − | |||
| − | {{hc|HelloWorld.java|2= |
||
| − | import org.gnome.gtk.Gtk; |
||
| − | import org.gnome.notify.Notify; |
||
| − | import org.gnome.notify.Notification; |
||
| − | |||
| − | public class HelloWorld |
||
| − | { |
||
| − | public static void main(String[] args) { |
||
| − | Gtk.init(args); |
||
| − | Notify.init("Hello world"); |
||
| − | Notification Hello = new Notification("Hello world!", "This is an example notification.", "dialog-information"); |
||
| − | Hello.show(); |
||
| − | } |
||
| − | } |
||
| − | }} |
||
| − | |||
| − | === JavaScript === |
||
| − | |||
| − | * 依存パッケージ: {{Pkg|gjs}} |
||
| − | |||
| − | {{hc|hello_world.js|2= |
||
| − | #!/usr/bin/gjs |
||
| − | const Gio = imports.gi.Gio; |
||
| − | var Application = new Gio.Application ({application_id: "hello.world"}); |
||
| − | Application.register (null); |
||
| − | var Notification = new Gio.Notification (); |
||
| − | Notification.set_title ("Hello world"); |
||
| − | Notification.set_body ("This is an example notification."); |
||
| − | var Icon = new Gio.ThemedIcon ({name: "dialog-information"}); |
||
| − | Notification.set_icon (Icon); |
||
| − | Application.send_notification (null, Notification); |
||
| − | }} |
||
| − | |||
| − | * 依存パッケージ: {{Pkg|libnotify}}, {{Pkg|gjs}} |
||
| − | |||
| − | {{hc|hello_world.js|2= |
||
| − | #!/usr/bin/gjs |
||
| − | const Notify = imports.gi.Notify; |
||
| − | Notify.init ("Hello world"); |
||
| − | var Hello=new Notify.Notification ({summary: "Hello world!", |
||
| − | body: "This is an example notification.", |
||
| − | "icon-name": "dialog-information"}); |
||
| − | Hello.show (); |
||
| − | }} |
||
| − | |||
| − | === JRuby === |
||
| − | |||
| − | * 依存パッケージ: {{AUR|java-gnome}}, {{Pkg|jruby}} |
||
| − | * ビルド: {{ic|jrubyc hello_world.rb && jar cfe hello_world.jar hello_world hello_world.class}} |
||
| − | * 実行: {{ic|java -cp /opt/jruby/lib/jruby.jar:hello_world.jar hello_world}} または {{ic|jruby hello_world.rb}} |
||
| − | {{hc|hello_world.rb|2= |
||
| − | require '/usr/share/java/gtk.jar' |
||
| − | import Java::OrgGnomeGtk::Gtk |
||
| − | import Java::OrgGnomeNotify::Notify |
||
| − | import Java::OrgGnomeNotify::Notification |
||
| − | |||
| − | Gtk.init(nil) |
||
| − | Notify.init("Hello world") |
||
| − | Hello = Notification.new("Hello world!", "This is an example notification.", "dialog-information") |
||
| − | Hello.show |
||
| − | }} |
||
| − | |||
| − | === Jython === |
||
| − | |||
| − | * 依存パッケージ: {{AUR|java-gnome}}, {{Pkg|jython}} |
||
| − | * 実行: {{ic|1=jython -Dpython.path=/usr/share/java/gtk.jar hello_world.py}} |
||
| − | {{hc|hello_world.py|2= |
||
| − | from org.gnome.gtk import Gtk |
||
| − | from org.gnome.notify import Notify, Notification |
||
| − | Gtk.init(None) |
||
| − | Notify.init("Hello world") |
||
| − | Hello=Notification("Hello world!", "This is an example notification.", "dialog-information") |
||
| − | Hello.show() |
||
| − | }} |
||
| − | |||
| − | === Lua === |
||
| − | |||
| − | * 依存パッケージ: {{Pkg|lua-lgi}} |
||
| − | |||
| − | {{hc|hello_world.lua|2= |
||
| − | #!/usr/bin/lua |
||
| − | lgi = require 'lgi' |
||
| − | Gio = lgi.require('Gio') |
||
| − | Application = Gio.Application.new("hello.world",Gio.ApplicationFlags.FLAGS_NONE); |
||
| − | Application:register(); |
||
| − | Notification = Gio.Notification.new("Hello world"); |
||
| − | Notification:set_body("This is an example notification."); |
||
| − | Icon = Gio.ThemedIcon.new("dialog-information"); |
||
| − | Notification:set_icon(Icon); |
||
| − | Application:send_notification(nil, Notification); |
||
| − | }} |
||
| − | |||
| − | * 依存パッケージ: {{Pkg|libnotify}}, {{Pkg|lua-lgi}} |
||
| − | |||
| − | {{hc|hello_world.lua|2= |
||
| − | #!/usr/bin/lua |
||
| − | lgi = require 'lgi' |
||
| − | Notify = lgi.require('Notify') |
||
| − | Notify.init("Hello world") |
||
| − | Hello=Notify.Notification.new("Hello world","This is an example notification.","dialog-information") |
||
| − | Hello:show()</nowiki>}} |
||
| − | |||
| − | === Nemerle === |
||
| − | |||
| − | * 依存パッケージ: {{Pkg|notify-sharp-3}} |
||
| − | * ビルドするのに必要なパッケージ: {{AUR|nemerle}} |
||
| − | * ビルド: {{ic|ncc -pkg:notify-sharp-3.0 -out:hello_world.exe hello_world.n}} |
||
| − | * 実行: {{ic|mono hello_world.exe}} |
||
| − | |||
| − | {{hc|hello_world.n|2= |
||
| − | using Notifications; |
||
| − | public class HelloWorld { |
||
| − | static Main() : void { |
||
| − | def Hello = Notification(); |
||
| − | Hello.Summary = "Hello world!"; |
||
| − | Hello.Body = "This is an example notification."; |
||
| − | Hello.IconName = "dialog-information"; |
||
| − | Hello.Show(); |
||
| − | } |
||
| − | } |
||
| − | }} |
||
| − | |||
| − | === Pascal === |
||
| − | |||
| − | * 依存パッケージ: {{Pkg|libnotify}} |
||
| − | * ビルドするのに必要なパッケージ: {{Pkg|fpc}}, [https://github.com/ik5/libnotify-fpc libnotify バインディング] |
||
| − | * ビルド: {{ic|fpc hello_world}} |
||
| − | |||
| − | {{hc|hello_world.pas|2= |
||
| − | program hello_world; |
||
| − | uses libnotify; |
||
| − | var hello : PNotifyNotification; |
||
| − | begin |
||
| − | notify_init(argv[0]); |
||
| − | hello := notify_notification_new ('Hello world', 'This is an example notification.', 'dialog-information'); |
||
| − | notify_notification_show (hello, nil); |
||
| − | end. |
||
| − | }} |
||
| − | |||
| − | === Perl === |
||
| − | |||
| − | ==== libnotify を使用 ==== |
||
| − | |||
| − | * 依存パッケージ: {{Pkg|libnotify}}, {{Pkg|perl-glib-object-introspection}} |
||
| − | {{hc|hello_world.pl|2= |
||
| − | #!/usr/bin/perl |
||
| − | use Glib::Object::Introspection; |
||
| − | Glib::Object::Introspection->setup ( |
||
| − | basename => 'Notify', |
||
| − | version => '0.7', |
||
| − | package => 'Notify'); |
||
| − | Notify->init; |
||
| − | my $hello = Notify::Notification->new('Hello world!', |
||
| − | "This is an example notification.", |
||
| − | "dialog-information"); |
||
| − | $hello->show; |
||
| − | }} |
||
| − | |||
| − | ==== 直接 D-Bus 呼び出し ==== |
||
| − | |||
| − | * 依存関係: {{Pkg|perl-net-dbus}} |
||
| − | {{hc|hello_world.pl|2= |
||
| − | #!/usr/bin/perl |
||
| − | use Net::DBus; |
||
| − | my $bus = Net::DBus->session; |
||
| − | my $svc = $bus->get_service('org.freedesktop.Notifications'); |
||
| − | my $obj = $svc->get_object('/org/freedesktop/Notifications'); |
||
| − | my $id = $obj->Notify('myapp', 0, |
||
| − | 'dialog-information', |
||
| − | 'Hello world!', |
||
| − | 'This is an example notification.', |
||
| − | [], {}, 0); |
||
| − | }} |
||
| − | |||
| − | === Python === |
||
| − | |||
| − | * 依存パッケージ: {{Pkg|python-gobject}} (または Python 2 なら {{Pkg|python2-gobject}}) |
||
| − | |||
| − | {{hc|hello_world.py|2= |
||
| − | #!/usr/bin/python |
||
| − | import gi |
||
| − | gi.require_version('Gio', '2.0') |
||
| − | from gi.repository import Gio |
||
| − | Application=Gio.Application.new ("hello.world", Gio.ApplicationFlags.FLAGS_NONE); |
||
| − | Application.register () |
||
| − | Notification=Gio.Notification.new ("Hello world") |
||
| − | Notification.set_body ("This is an example notification.") |
||
| − | Icon=Gio.ThemedIcon.new ("dialog-information") |
||
| − | Notification.set_icon (Icon) |
||
| − | Application.send_notification (None, Notification) |
||
| − | }} |
||
| − | |||
| − | * 依存パッケージ: {{Pkg|libnotify}}, {{Pkg|python-gobject}} (または Python 2 なら {{Pkg|python2-gobject}}) |
||
| − | |||
| − | {{hc|hello_world.py|2= |
||
| − | #!/usr/bin/python |
||
| − | import gi |
||
| − | gi.require_version('Notify', '0.7') |
||
| − | from gi.repository import Notify |
||
| − | Notify.init ("Hello world") |
||
| − | Hello = Notify.Notification.new ("Hello world","This is an example notification.","dialog-information") |
||
| − | Hello.show () |
||
| − | }} |
||
| − | |||
| − | === Ruby === |
||
| − | |||
| − | *依存パッケージ: {{Pkg|libnotify}}, {{AUR|ruby-gir_ffi}} |
||
| − | |||
| − | {{hc|hello_world.rb|2= |
||
| − | #!/usr/bin/ruby |
||
| − | require 'gir_ffi' |
||
| − | GirFFI.setup :Notify |
||
| − | Notify.init("Hello world") |
||
| − | Hello = Notify::Notification.new("Hello world!", "This is an example notification.", "dialog-information") |
||
| − | Hello.show |
||
| − | }} |
||
| − | |||
| − | === Rust === |
||
| − | |||
| − | [https://crates.io/crates/notify-rust notify-rust] を使用。 |
||
| − | * ビルドするのに必要なパッケージ: {{Pkg|rust}} か {{Pkg|rustup}} ([[Rust]] を参照) |
||
| − | * ビルド: {{ic|cargo build}} |
||
| − | * 実行: {{ic|target/debug/hello_world}} または {{ic|cargo run}} |
||
| − | |||
| − | {{hc|Cargo.toml|2= |
||
| − | [package] |
||
| − | name = "hello_world" |
||
| − | version = "0.1.0" |
||
| − | |||
| − | [dependencies] |
||
| − | notify-rust = "^3" |
||
| − | }} |
||
| − | |||
| − | {{hc|src/main.rs|2= |
||
| − | extern crate notify_rust; |
||
| − | use notify_rust::Notification; |
||
| − | fn main(){ |
||
| − | Notification::new() |
||
| − | .summary("Hello world") |
||
| − | .body("This is an example notification.") |
||
| − | .icon("dialog-information") |
||
| − | .show().unwrap(); |
||
| − | } |
||
| − | }} |
||
| − | |||
| − | === Scala === |
||
| − | |||
| − | * 依存パッケージ: {{AUR|java-gnome}} (と {{Pkg|scala}}) |
||
| − | * ビルドするのに必要なパッケージ: {{Pkg|scala}} |
||
| − | * ビルド: {{ic|scalac -cp /usr/share/java/gtk.jar -d HelloWorld.jar HelloWorld.scala}} |
||
| − | * 実行: {{ic|java -cp /usr/share/java/gtk.jar:HelloWorld.jar HelloWorld}} (または {{ic|scala -cp /usr/share/java/gtk.jar HelloWorld.scala}}) |
||
| − | |||
| − | {{hc|HelloWorld.scala|2= |
||
| − | import org.gnome.gtk._ |
||
| − | import org.gnome.notify._ |
||
| − | |||
| − | object HelloWorld { |
||
| − | def main(args: Array[String]) { |
||
| − | Gtk.init(args) |
||
| − | Notify.init("Hello world") |
||
| − | var Hello = new Notification("Hello world!", "This is an example notification.", "dialog-information") |
||
| − | Hello.show() |
||
| − | } |
||
| − | } |
||
| − | }} |
||
| − | |||
| − | === Vala === |
||
| − | |||
| − | *依存パッケージ: {{Pkg|glib2}} |
||
| − | *ビルドするのに必要なパッケージ: {{Pkg|vala}} |
||
| − | *ビルド: {{ic|valac --pkg gio-2.0 hello_world.vala}} |
||
| − | |||
| − | {{hc|hello_world.vala|2= |
||
| − | using GLib; |
||
| − | public class HelloWorld { |
||
| − | static void main () { |
||
| − | var Application = new GLib.Application ("hello.world", GLib.ApplicationFlags.FLAGS_NONE); |
||
| − | Application.register (); |
||
| − | var Notification = new GLib.Notification ("Hello world"); |
||
| − | Notification.set_body ("This is an example notification."); |
||
| − | var Icon = new GLib.ThemedIcon ("dialog-information"); |
||
| − | Notification.set_icon (Icon); |
||
| − | Application.send_notification (null, Notification); |
||
| − | } |
||
| − | } |
||
| − | }} |
||
| − | |||
| − | *依存パッケージ: {{Pkg|libnotify}} |
||
| − | *ビルドするのに必要なパッケージ: {{Pkg|vala}} |
||
| − | *ビルド: {{ic|valac --pkg libnotify hello_world.vala}} |
||
| − | |||
| − | {{hc|hello_world.vala|2= |
||
| − | using Notify; |
||
| − | public class HelloWorld { |
||
| − | static void main () { |
||
| − | Notify.init ("Hello world"); |
||
| − | var Hello = new Notify.Notification("Hello world!", "This is an example notification.", "dialog-information"); |
||
| − | Hello.show (); |
||
| − | } |
||
| − | } |
||
| − | }} |
||
| − | |||
| − | === Visual Basic .NET === |
||
| − | |||
| − | * 依存パッケージ: {{Pkg|notify-sharp-3}} |
||
| − | * ビルドするのに必要なパッケージ: {{AUR|mono-basic}} |
||
| − | * ビルド: {{ic|vbnc -r:/usr/lib/mono/notify-sharp-3.0/notify-sharp.dll hello_world.vb}} |
||
| − | * 実行: {{ic|mono hello_world.exe}} |
||
| − | |||
| − | {{hc|hello_world.vb|2= |
||
| − | Imports Notifications |
||
| − | Public Class Hello |
||
| − | Public Shared Sub Main |
||
| − | Dim Hello As New Notification |
||
| − | Hello.Summary = "Hello world!" |
||
| − | Hello.Body = "This is an example notification." |
||
| − | Hello.IconName = "dialog-information" |
||
| − | Hello.Show |
||
| − | End Sub |
||
| − | End Class |
||
| − | }} |
||
| − | |||
| − | == ヒントとテクニック == |
||
=== 以前の通知を置き換える === |
=== 以前の通知を置き換える === |
||
| − | ID がわかっている場合は、通知を置き換えることができます。新しい通知リクエストで同じ ID が指定されている場合、常に古い通知が置き換えられます。(上記の libnotify バインディングはこれを自動的に処理します。) 残念ながら、notify-send はこの ID を報告しないため、CLI でこれを行うには代替ツールが必要です。有効な CLI ツールの 1 つは、[https://github.com/phuhl/notify-send.py |
+ | 通知 ID がわかっている場合は、その通知を置き換えることができます。新しい通知リクエストで同じ ID が指定されている場合、常に古い通知が置き換えられます。(上記の libnotify バインディングはこれを自動的に処理します。) 残念ながら、notify-send はこの ID を報告しないため、CLI でこれを行うには代替ツールが必要です。有効な CLI ツールの 1 つは、[https://github.com/phuhl/notify-send.py notify-send.py] Python スクリプトです。これは、追加の ID レポート機能と置換機能を備えた Notify-Send 構文を提供します。 |
ただし、''一部の'' 通知サーバー (Notify-OSD など) では、notify-send で {{ic|string:x-canonical-private-synchronous:}} ヒントを使用して同じ結果を得ることができます。 |
ただし、''一部の'' 通知サーバー (Notify-OSD など) では、notify-send で {{ic|string:x-canonical-private-synchronous:}} ヒントを使用して同じ結果を得ることができます。 |
||
| 654行目: | 88行目: | ||
}} |
}} |
||
| − | === ボタンを |
+ | === ボタンを追加する、通知の閉じる/クリックをリッスンする === |
| − | [https://github.com/phuhl/notify-send.py |
+ | [https://github.com/phuhl/notify-send.py notify-send.py] スクリプトを使用すると、アクションを使用してボタンを表示したり通知のデフォルトアクション (通常、ユーザーが通知をクリックした時に発生します) やクローズアクションをリッスンすることができます。''action-icons'' ヒントが true に設定されており、通知デーモンがこれをサポートしている場合、ボタンにはテキストの代わりにアイコンが表示されます。スクリプトは、対応するイベントが発生したときに、コマンドラインにアクション ID または "close" を出力します。デフォルトのアクション (クリック時) をリッスンするには、アクション識別子 "default" を使用する必要があります。 |
| − | ボタン |
+ | ボタンにアイコンを表示する例: |
{{bc|1= |
{{bc|1= |
||
notify-send.py "Buttons" "Do you like em?" --hint boolean:action-icons:true --action yes:face-cool no:face-sick |
notify-send.py "Buttons" "Do you like em?" --hint boolean:action-icons:true --action yes:face-cool no:face-sick |
||
}} |
}} |
||
| − | === D- |
+ | === D-Bus サービスが同梱されている通知サーバーが複数ある場合 === |
| − | [[ |
+ | [[#スタンドアロン|スタンドアロン]]章で説明した通り、ユーザーは D-Bus サービスを作成して通知サーバーを自動的に起動させることができます。しかし、一部の通知サーバーにはすでに D-Bus サービスファイルが同梱されています。複数の通知サーバーをインストールしていて、それらのうちどれかにサービスファイルが含まれている場合、問題が発生します。例えば、{{Pkg|dunst}} と {{Pkg|mako}} の両方をインストールして、使用するサーバーを明示的に指定しなかった場合、D-Bus はどちらか一方を勝手に選びます。そうならないようにするには、{{ic|org.freedesktop.Notifications.service}} ([[#スタンドアロン]] を参照) を作成して、使用したいサービスを指定することで、使用されるサービスをオーバーライドすることができます。ファイルの作成後は、セッションを再起動してください。 |
| − | |||
| − | === 失敗した Systemd サービスに関する通知 === |
||
| − | |||
| − | 失敗したサービスによる通知を受け取るには、ターゲットユーザーに {{Pkg|systembus-notify}} をインストールして実行し、[[systemd#サービスの失敗を通知する]] に示されている手順に従います。ただし、{{ic|failure-notification@}} は置き換えてください。これを使用したテンプレートユニット: |
||
| − | {{hc|/etc/systemd/system/failure-notification@.service|2= |
||
| − | [Unit] |
||
| − | Description=Send a notification about a failed systemd unit |
||
| − | After=Graphical.target |
||
| − | |||
| − | [Service] |
||
| − | Type=simple |
||
| − | ExecStart=/usr/bin/dbus-send --system / net.nuetzlich.SystemNotifications.Notify 'string:%i' 'string:Unit failed' |
||
| − | }} |
||
| − | |||
| − | 残念ながら、このソリューションは通知の緊急性やタイムアウトの設定をまだサポートしていません。[https://github.com/rfjakob/systembus-notify/issues/6 this issue] を参照してください。 |
||
== トラブルシューティング == |
== トラブルシューティング == |
||
| 686行目: | 105行目: | ||
=== アプリケーションがちょうど 1 分間ハングする === |
=== アプリケーションがちょうど 1 分間ハングする === |
||
| − | 通知を表示しようとし |
+ | アプリケーションが通知を表示しようとした際にハングしてしまう場合、通知サービスが自身の可用性を誤って D-Bus サービス経由で広告してしまっているのかもしれません。 |
たとえば、ユーザーが最近、{{Pkg|plasma-workspace}} を必要とする KDE コンポーネントをインストールしたが、まだ XFCE を実行しているとします。この場合、KDE 通知機能が優先されますが、ユーザーはそれを実行していません。アプリケーションはサービスの待機中にハングし、タイムアウト後に {{Pkg|xfce4-notifyd}} にフォールバックすることになります。 |
たとえば、ユーザーが最近、{{Pkg|plasma-workspace}} を必要とする KDE コンポーネントをインストールしたが、まだ XFCE を実行しているとします。この場合、KDE 通知機能が優先されますが、ユーザーはそれを実行していません。アプリケーションはサービスの待機中にハングし、タイムアウト後に {{Pkg|xfce4-notifyd}} にフォールバックすることになります。 |
||
| − | 最も |
+ | 最もわかりやすいハングは、通知インディケータの調整スクロールでしょう。 |
| − | この |
+ | このような場合、2つの通知ハンドラーが存在するはずです: |
{{hc|$ find /usr/share/dbus-1/services/ -name '*Notif*'| |
{{hc|$ find /usr/share/dbus-1/services/ -name '*Notif*'| |
||
| 699行目: | 118行目: | ||
}} |
}} |
||
| − | [[ |
+ | [[journal]] を見ると、これら2つのうちどちら一方が定期的に1分のタイムアウトで失敗しています: |
{{hc|# journalctl -g notif|2= |
{{hc|# journalctl -g notif|2= |
||
| − | [ press End to go to the end of the log ] |
||
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: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 plasma_waitforname[6093]: org.kde.knotifications: WaitForName: Service was not registered within timeout |
||
| 708行目: | 126行目: | ||
}} |
}} |
||
| − | [[ |
+ | [[#D-Bus サービスが同梱されている通知サーバーが複数ある場合]] で説明されているように、使いたいサービスを指定すれば、問題は解決します。 |
| + | |||
| + | == 参照 == |
||
| + | |||
| + | * [https://gnome.pages.gitlab.gnome.org/libnotify/ Libnotify リファレンスマニュアル] |
||
| + | * [https://web.archive.org/web/20160313162757/http://milky.manishsinha.net/2009/03/29/working-with-libnotify/ C サンプル] (アーカイブされたバージョン) |
||
| + | * [https://www.devdungeon.com/content/desktop-notifications-linux-python Python の通知サンプル] |
||
| + | * [https://hashbang.fr/tutoriel-notify.html Python の通知サンプル] (フランス語の記事) |
||
| + | {{TranslationStatus|Desktop notifications|2025-07-03|839792}} |
||
| − | ==参照== |
||
| − | *[https://developer-old.gnome.org/libnotify/ Libnotify リファレンスマニュアル] |
||
| − | *[https://web.archive.org/web/20160313162757/http://milky.manishsinha.net/2009/03/29/working-with-libnotify/ C サンプル] (アーカイブされたバージョン) |
||
| − | * [https://www.devdungeon.com/content/desktop-notifications-linux-python Python 通知サンプル] |
||
| − | *[http://hashbang.fr/tutoriel-notify.html Python サンプル] (フランス語の記事) |
||
2025年7月3日 (木) 17:41時点における最新版
関連記事
デスクトップ通知は、非同期に特定のイベントをユーザーに通知する小さくて控えめなポップアップダイアログです。
目次
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 の通知サンプル (フランス語の記事)