「デスクトップ通知」の版間の差分
Kusanaginoturugi (トーク | 投稿記録) (→Tips and tricks: タイトルのみ飜訳) |
(TranslationStatus の時刻形式を合わせる) |
||
| (4人の利用者による、間の9版が非表示) | |||
| 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(); |
||
| − | } |
||
| − | } |
||
| − | }} |
||
| − | |||
| − | === Cobra === |
||
| − | |||
| − | * 依存パッケージ: {{Pkg|notify-sharp-3}} |
||
| − | * ビルドするのに必要なパッケージ: {{AUR|cobra}} |
||
| − | * ビルド: {{ic|cobra -c hello_world}} |
||
| − | * 実行: {{ic|mono hello_world.exe}} |
||
| − | |||
| − | {{hc|hello_world.cobra|<nowiki>@args -pkg:notify-sharp-3.0 |
||
| − | use Notifications |
||
| − | class HelloWorld |
||
| − | def main |
||
| − | hello = Notification() |
||
| − | hello.summary = "Hello world!" |
||
| − | hello.body = "This is an example notification." |
||
| − | hello.iconName = "dialog-information" |
||
| − | hello.show</nowiki>}} |
||
| − | |||
| − | ===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 notify-send.py] Python スクリプトです。これは、追加の ID レポート機能と置換機能を備えた Notify-Send 構文を提供します。 |
||
| − | Notifications can be replaced if their ID is known; if a new notification request specifies the same ID, it will always replace the old notification. (The libnotify bindings shown above handle this automatically.) Unfortunately notify-send does not report this ID, so alternative tools are required to do this on CLI. One capable CLI-tool is the [https://github.com/phuhl/notify-send.py notify-send.py] python script, which provides notify-send syntax with additional ID-reporting and replacing capabilities. |
||
| − | + | ただし、''一部の'' 通知サーバー (Notify-OSD など) では、notify-send で {{ic|string:x-canonical-private-synchronous:}} ヒントを使用して同じ結果を得ることができます。 |
|
| + | たとえば、時間を表示する通知を取得するには: |
||
| − | For example, to get a notification displaying time: |
||
{{bc|1= |
{{bc|1= |
||
while true; do |
while true; do |
||
| 671行目: | 88行目: | ||
}} |
}} |
||
| − | === ボタンを |
+ | === ボタンを追加する、通知の閉じる/クリックをリッスンする === |
| + | [https://github.com/phuhl/notify-send.py notify-send.py] スクリプトを使用すると、アクションを使用してボタンを表示したり通知のデフォルトアクション (通常、ユーザーが通知をクリックした時に発生します) やクローズアクションをリッスンすることができます。''action-icons'' ヒントが true に設定されており、通知デーモンがこれをサポートしている場合、ボタンにはテキストの代わりにアイコンが表示されます。スクリプトは、対応するイベントが発生したときに、コマンドラインにアクション ID または "close" を出力します。デフォルトのアクション (クリック時) をリッスンするには、アクション識別子 "default" を使用する必要があります。 |
||
| − | With the [https://github.com/phuhl/notify-send.py notify-send.py] script, actions can be used to display buttons or to listen for the default-action of the notification (usually, when the user clicks on it) and the close-action. When the ''action-icons'' hint is set to true and the notification daemon supports this, the buttons will display icons instead of text. The script prints the action identifier or "close" to the command line when the corresponding event has occured. To listen for the default action (on-click), one has to use the action-identfier "default". |
||
| + | ボタンにアイコンを表示する例: |
||
| − | Example with icons on buttons: |
||
{{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}} ([[#スタンドアロン]] を参照) を作成して、使用したいサービスを指定することで、使用されるサービスをオーバーライドすることができます。ファイルの作成後は、セッションを再起動してください。 |
||
| − | As described in the section [[#Standalone|Standalone]], users can create a D-Bus service so that a notification server can be launched automatically. Some implementations already include the D-Bus service files. However, this causes a problem when multiple notification servers are installed and when some of them come with the service files. For example, installing both {{Pkg|dunst}} and {{Pkg|mako}} without explicitly specifying the desired server, D-Bus then chooses one for the users, and the decision is out of users' control. To avoid the situation, you can override the service used by creating the symbolic link {{ic|$XDG_DATA_DIR/dbus-1/services/org.freedesktop.Notifications.service}} pointing to the service you want to use, and then restart the session. |
||
| + | == トラブルシューティング == |
||
| − | == Troubleshooting == |
||
| + | === アプリケーションがちょうど 1 分間ハングする === |
||
| − | === Applications hanging for exactly one minute === |
||
| + | アプリケーションが通知を表示しようとした際にハングしてしまう場合、通知サービスが自身の可用性を誤って D-Bus サービス経由で広告してしまっているのかもしれません。 |
||
| − | If applications hang when attempting to show notifications, it might be because of a notification service falsely advertising its availability through the D-Bus service. |
||
| + | たとえば、ユーザーが最近、{{Pkg|plasma-workspace}} を必要とする KDE コンポーネントをインストールしたが、まだ XFCE を実行しているとします。この場合、KDE 通知機能が優先されますが、ユーザーはそれを実行していません。アプリケーションはサービスの待機中にハングし、タイムアウト後に {{Pkg|xfce4-notifyd}} にフォールバックすることになります。 |
||
| − | For instance, suppose a user recently installed a KDE component that requires {{Pkg|plasma-workspace}}, but the user is still running XFCE. In this case, the KDE notifier will be prioritized, but the user is not running it. The application will hang while waiting for the service, and only after a timeout will it fall back to {{Pkg|xfce4-notifyd}}. |
||
| + | 最もわかりやすいハングは、通知インディケータの調整スクロールでしょう。 |
||
| − | The most noticeable hanging might come from the volume indicator scroll adjustment. |
||
| + | このような場合、2つの通知ハンドラーが存在するはずです: |
||
| − | If you are in this situation, you should have two notification handlers: |
||
{{hc|$ find /usr/share/dbus-1/services/ -name '*Notif*'| |
{{hc|$ find /usr/share/dbus-1/services/ -name '*Notif*'| |
||
| 701行目: | 118行目: | ||
}} |
}} |
||
| + | [[journal]] を見ると、これら2つのうちどちら一方が定期的に1分のタイムアウトで失敗しています: |
||
| − | Of those two, one fails regularly after a 1-minute timeout, as seen in the [[journal]]: |
||
{{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 |
||
| 710行目: | 126行目: | ||
}} |
}} |
||
| + | [[#D-Bus サービスが同梱されている通知サーバーが複数ある場合]] で説明されているように、使いたいサービスを指定すれば、問題は解決します。 |
||
| − | Choosing the service you want to use as described in [[#Multiple notification servers with D-Bus services]] will fix the problem. |
||
| + | |||
| + | == 参照 == |
||
| + | |||
| + | * [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.gnome.org/libnotify/ Libnotify リファレンスマニュアル] |
||
| − | *[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 の通知サンプル (フランス語の記事)