Expand description
§godot-ksni
A Godot 4 GDExtension that provides system tray icon functionality for Linux desktop environments using the StatusNotifierItem (SNI) specification via the ksni library.
§Overview
This library exposes a TrayIcon node that can be used in Godot projects to create system tray icons
with menus, tooltips, and custom icons. It supports standard menu items, checkboxes, radio buttons,
submenus, and separators.
§Usage
§Method 1: As a Standalone GDExtension
Use this method if you want to add godot-ksni as a separate GDExtension to your Godot project.
-
Add godot-ksni as a git submodule or clone to your project
git submodule add https://github.com/yuna0x0/godot-ksni.git git submodule update --init --recursive # Or clone directly git clone https://github.com/yuna0x0/godot-ksni.git -
Build the library with default features (includes
gdextensionfeature):cd godot-ksni # For debug build cargo build # For release build cargo build --release -
Assuming your project structure is like this:
. ├── godot │ ├── GodotKsni.gdextension │ ├── project.godot │ └── ... └── godot-ksni ├── Cargo.toml ├── src ├── target └── ... -
Create a
GodotKsni.gdextensionfile in your Godot project directory:[configuration] entry_symbol = "gdext_rust_init" compatibility_minimum = 4.5 reloadable = true [libraries] linux.debug.x86_64 = "res://../godot-ksni/target/debug/libgodot_ksni.so" linux.release.x86_64 = "res://../godot-ksni/target/release/libgodot_ksni.so" -
The
TrayIconnode will be available in your Godot project
§Method 2: As a Rust Dependency (for GDExtension developers)
Use this method if you’re building your own Rust GDExtension and want to include godot-ksni’s functionality within it.
-
Add godot-ksni as a dependency with default features disabled:
cargo add godot-ksni --no-default-featuresImportant: You must disable default features to prevent duplicate
gdext_rust_initsymbols. Thegdextensionfeature is only needed when building as a standalone library. -
In your
lib.rs, re-exportTrayIconto ensure it gets linked:ⓘuse godot::prelude::*; // Re-export TrayIcon so it's registered with Godot pub use godot_ksni::TrayIcon; struct MyExtension; #[gdextension] unsafe impl ExtensionLibrary for MyExtension {} -
The
TrayIconnode will be automatically registered when your extension loads
§Example
extends Node
var tray_icon: TrayIcon
func _ready():
tray_icon = TrayIcon.new()
add_child(tray_icon)
tray_icon.set_tray_id("my_app")
tray_icon.set_title("My Application")
tray_icon.set_icon_from_path("res://icon.svg")
tray_icon.add_menu_item("quit", "Quit", "application-exit", true, true)
tray_icon.menu_activated.connect(_on_menu_activated)
tray_icon.spawn_tray()
func _on_menu_activated(id: String):
if id == "quit":
get_tree().quit()Re-exports§
pub use godot::TrayIcon;pub use menu::MenuItemData;pub use menu::RadioItemData;pub use tray::KsniTray;pub use tray::TrayEvent;pub use tray::TrayState;