StatusNotifierItem (SNI)

#linux #protocol #gui

Linuxデスクトップでトレイアイコン(インジケータ)を出すためのD-Busベースの規格。KDE発で、X11のウィンドウ埋め込みに依存する旧来のfreedesktop System Tray Protocol(XEmbed方式)の置き換えとして提案された。D-Bus越しに「モデル」を渡すだけなので、Waylandでも動くのが最大の違い。全体の位置づけはシステムトレイ / インジケータを参照。

3つの役者

sequenceDiagram participant App as アプリ = Item participant W as Watcher participant Host as パネル = Host Host->>W: RegisterStatusNotifierHost App->>App: org.kde.StatusNotifierItem-PID-ID を取得 App->>W: RegisterStatusNotifierItem W-->>Host: StatusNotifierItemRegistered シグナル Host->>App: プロパティ IconName / ToolTip / Menu を読む Host->>App: Activate / SecondaryActivate / Scroll
  • StatusNotifierItem — アプリ側。D-Bus上にorg.kde.StatusNotifierItemインターフェイスを公開し、org.kde.StatusNotifierItem-<PID>-<連番>というwell-knownな名前を持つ。
  • StatusNotifierWatcher — 仲介役。サービス名org.kde.StatusNotifierWatcher、オブジェクトパス/StatusNotifierWatcher。ItemとHostの両方から登録を受け付ける。
  • StatusNotifierHost — 表示側(パネル/シェル)。Watcherに登録し、Item一覧を受け取って描画する。

Watcherのインターフェイスは小さい。

種別 名前
メソッド RegisterStatusNotifierItem(service) / RegisterStatusNotifierHost(service)
プロパティ RegisteredStatusNotifierItems / IsStatusNotifierHostRegistered / ProtocolVersion
シグナル StatusNotifierItemRegistered / ...Unregistered / StatusNotifierHostRegistered / ...Unregistered

Itemが公開するもの

プロパティが本体で、Hostがこれを読んで自由に描画する(モデル/ビュー分離)。

プロパティ 用途
Category / Id / Title 分類と識別
Status Passive / Active / NeedsAttention
IconName / IconPixmap アイコン。テーマ内の名前か、生のピクセルデータ
IconThemePath 自前のアイコンを置いたディレクトリ
OverlayIconName / OverlayIconPixmap 重ねる小さなバッジ
AttentionIconName / AttentionIconPixmap / AttentionMovieName 注意喚起時の表示
ToolTip ツールチップ
Menu メニューのオブジェクトパス
ItemIsMenu クリックしたら即メニューを出すか
WindowId 関連付けるウィンドウ(不要なら0)

メソッドは4つ。

  • Activate(x, y) — 主クリック
  • SecondaryActivate(x, y) — 中クリック相当
  • Scroll(delta, orientation) — ホイール
  • ContextMenu(x, y) — アプリが自前で描いたメニューを出す(実装しないライブラリもある)

メニューそのものはこの規格に含まれない。 Menuプロパティが指すのはcom.canonical.dbusmenuという別インターフェイスのオブジェクトで、Ubuntu(Canonical)由来のDBusMenu規格に丸投げされている。

名前がorg.kde.のまま

freedesktopのwikiに仕様が置かれているにもかかわらず、実装が実際に使うインターフェイス名はorg.freedesktop.StatusNotifierItemではなくorg.kde.StatusNotifierItem。freedesktopへの提案は2009年に出されたが正式な標準として批准されておらず、KDEの名前空間のまま普及した。仕様文書と実装で型が食い違っている箇所すらある(WindowIdは仕様上u32だが実装はi32)。

落とし穴

Hostがいないと、登録に成功しても何も表示されない。 WatcherへのRegisterStatusNotifierItemが通っても、表示側が誰も登録していなければアイコンは出ない。デスクトップ環境の初期化が終わる前にアプリを起動すると起きる。ksniはこれをWontShowという専用のエラーで区別しており、仕様はこの場合「旧来のFreedesktop System tray仕様にフォールバックすべき」としている。

ItemIsMenuを効かせるにはActivateでエラーを返す必要がある。 「クリックで即メニュー」を実現するItemIsMenuプロパティは、実装によっては見てもらえない。GNOMEのappindicator拡張とKDE Plasma 6.4未満は、ActivateがUnknownMethodエラーを返したときに初めてメニュー表示にフォールバックする。ksniはこの互換ハックをコード内で明示的にやっている。Plasma 6.4以降はItemIsMenuがtrueならActivateを呼ばなくなったので、このハックを残したままでも問題ない。

アイコンをピクセルで渡せても通らないことがある。 IconPixmapがあるので理屈上は生データを渡せるが、libappindicatorのような中間層は名前かファイルパスしか受け付けない。そのためtray-iconは一時ディレクトリにPNGを書き出してIconThemePath経由で渡す、という回り道をしている。

出典

作成日時: 2026-09-06 23:14 / 更新日時: 2026-09-06 23:14