| Crates.io | godot-ksni |
| lib.rs | godot-ksni |
| version | 0.1.2 |
| created_at | 2025-11-12 20:11:52.604122+00 |
| updated_at | 2025-11-13 23:10:49.962582+00 |
| description | A Godot GDExtension wrapper for ksni (StatusNotifierItem/AppIndicator) |
| homepage | |
| repository | https://github.com/yuna0x0/godot-ksni |
| max_upload_size | |
| id | 1929891 |
| size | 104,818 |
A Godot 4 GDExtension that provides system tray icon functionality for Linux desktop environments using the StatusNotifierItem specification.
godot-ksni wraps the iovxw/ksni Rust library to bring native system tray support to Godot 4 projects on Linux. It exposes a TrayIcon node that can be used to create tray icons with menus, checkboxes, radio buttons, submenus, and custom icons.
This library currently supports Linux desktop environments that implement the StatusNotifierItem specification, including:
Use this method if you want to add godot-ksni as a separate GDExtension to your Godot 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
gdextension feature):cd godot-ksni
# Debug build
cargo build
# Release build
cargo build --release
.
├── godot
│ ├── GodotKsni.gdextension
│ ├── project.godot
│ └── ...
└── godot-ksni
├── Cargo.toml
├── src
├── target
└── ...
GodotKsni.gdextension file in your Godot project directory (e.g., godot/GodotKsni.gdextension) with the following content:[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"
TrayIcon node will be available in your Godot project.Use this method if you're building your own Rust GDExtension and want to include godot-ksni's functionality within it.
cargo add godot-ksni --no-default-features
Important: You must disable default features with --no-default-features to prevent duplicate gdext_rust_init symbols. The gdextension feature (enabled by default) is only needed when building godot-ksni as its own standalone GDExtension (Method 1).
lib.rs, re-export the TrayIcon to 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 {}
TrayIcon node will be automatically registered when your extension loads.extends Node
var tray_icon: TrayIcon
func _ready():
# Create the TrayIcon node
tray_icon = TrayIcon.new()
add_child(tray_icon)
# Configure the tray
tray_icon.set_tray_id("my_application")
tray_icon.set_title("My Application")
tray_icon.set_icon_from_path("res://icon.svg")
tray_icon.set_tooltip("My App", "Running in background", "")
# Build menu
tray_icon.add_menu_item("show", "Show Window", "", true, true)
tray_icon.add_separator()
tray_icon.add_menu_item("quit", "Quit", "application-exit", true, true)
# Connect signals
tray_icon.menu_activated.connect(_on_menu_activated)
# Spawn the tray icon
if tray_icon.spawn_tray():
print("Tray icon created successfully")
func _on_menu_activated(id: String):
match id:
"show":
get_window().visible = true
"quit":
get_tree().quit()
# Method 1: System icon (simplest, but limited selection)
tray_icon.set_icon_name("application-x-executable")
# Method 2: From resource path (recommended for custom icons)
if tray_icon.set_icon_from_path("res://icon.svg"):
print("Icon loaded")
# Method 3: From texture resource
var texture = load("res://icon.svg")
if texture:
tray_icon.set_icon_from_texture(texture)
# Method 4: From image (for image manipulation)
var texture = load("res://icon.svg")
if texture:
var image = texture.get_image()
tray_icon.set_icon_from_image(image)
func build_menu():
tray_icon.clear_menu()
# Standard items
tray_icon.add_menu_item("open", "Open", "", true, true)
tray_icon.add_separator()
# Checkmark
tray_icon.add_checkmark_item("autostart", "Start on Boot", "", false, true, true)
tray_icon.add_separator()
# Radio group
tray_icon.add_radio_group("theme", 0)
tray_icon.add_radio_option("theme", "light", "Light", "", true, true)
tray_icon.add_radio_option("theme", "dark", "Dark", "", true, true)
tray_icon.add_separator()
# Submenu
tray_icon.begin_submenu("Settings", "preferences-system", true, true)
tray_icon.add_submenu_item("Settings", "prefs", "Preferences", "", true, true)
tray_icon.add_submenu_checkmark("Settings", "notify", "Notifications", "", true, true, true)
tray_icon.add_separator()
tray_icon.add_menu_item("quit", "Quit", "application-exit", true, true)
The examples/ directory contains the following examples:
tray_example.gd - Example demonstrating all features (menu items, checkmarks, radio groups, submenus)res:// for Godot resources)This project is licensed under the MIT License. See the LICENSE file for details.