godot_ksni/
lib.rs

1//! # godot-ksni
2//!
3//! A Godot 4 GDExtension that provides system tray icon functionality for Linux desktop environments
4//! using the StatusNotifierItem (SNI) specification via the [ksni](https://crates.io/crates/ksni) library.
5//!
6//! ## Overview
7//!
8//! This library exposes a `TrayIcon` node that can be used in Godot projects to create system tray icons
9//! with menus, tooltips, and custom icons. It supports standard menu items, checkboxes, radio buttons,
10//! submenus, and separators.
11//!
12//! ## Usage
13//!
14//! ### Method 1: As a Standalone GDExtension
15//!
16//! Use this method if you want to add godot-ksni as a separate GDExtension to your Godot project.
17//!
18//! 1. Add godot-ksni as a git submodule or clone to your project
19//!    ```bash
20//!    git submodule add https://github.com/yuna0x0/godot-ksni.git
21//!    git submodule update --init --recursive
22//!
23//!    # Or clone directly
24//!    git clone https://github.com/yuna0x0/godot-ksni.git
25//!    ```
26//!
27//! 2. Build the library with default features (includes `gdextension` feature):
28//!    ```bash
29//!    cd godot-ksni
30//!
31//!    # For debug build
32//!    cargo build
33//!
34//!    # For release build
35//!    cargo build --release
36//!    ```
37//!
38//! 3. Assuming your project structure is like this:
39//!    ```text
40//!    .
41//!    ├── godot
42//!    │   ├── GodotKsni.gdextension
43//!    │   ├── project.godot
44//!    │   └── ...
45//!    └── godot-ksni
46//!        ├── Cargo.toml
47//!        ├── src
48//!        ├── target
49//!        └── ...
50//!    ```
51//!
52//! 4. Create a `GodotKsni.gdextension` file in your Godot project directory:
53//!    ```gdextension
54//!    [configuration]
55//!    entry_symbol = "gdext_rust_init"
56//!    compatibility_minimum = 4.5
57//!    reloadable = true
58//!
59//!    [libraries]
60//!    linux.debug.x86_64 = "res://../godot-ksni/target/debug/libgodot_ksni.so"
61//!    linux.release.x86_64 = "res://../godot-ksni/target/release/libgodot_ksni.so"
62//!    ```
63//!
64//! 5. The `TrayIcon` node will be available in your Godot project
65//!
66//! ### Method 2: As a Rust Dependency (for GDExtension developers)
67//!
68//! Use this method if you're building your own Rust GDExtension and want to include
69//! godot-ksni's functionality within it.
70//!
71//! 1. Add godot-ksni as a dependency with default features disabled:
72//!    ```bash
73//!    cargo add godot-ksni --no-default-features
74//!    ```
75//!
76//!    **Important**: You must disable default features to prevent duplicate `gdext_rust_init`
77//!    symbols. The `gdextension` feature is only needed when building as a standalone library.
78//!
79//! 2. In your `lib.rs`, re-export `TrayIcon` to ensure it gets linked:
80//!    ```rust,ignore
81//!    use godot::prelude::*;
82//!
83//!    // Re-export TrayIcon so it's registered with Godot
84//!    pub use godot_ksni::TrayIcon;
85//!
86//!    struct MyExtension;
87//!
88//!    #[gdextension]
89//!    unsafe impl ExtensionLibrary for MyExtension {}
90//!    ```
91//!
92//! 3. The `TrayIcon` node will be automatically registered when your extension loads
93//!
94//! ## Example
95//!
96//! ```gdscript
97//! extends Node
98//!
99//! var tray_icon: TrayIcon
100//!
101//! func _ready():
102//!     tray_icon = TrayIcon.new()
103//!     add_child(tray_icon)
104//!
105//!     tray_icon.set_tray_id("my_app")
106//!     tray_icon.set_title("My Application")
107//!     tray_icon.set_icon_from_path("res://icon.svg")
108//!
109//!     tray_icon.add_menu_item("quit", "Quit", "application-exit", true, true)
110//!
111//!     tray_icon.menu_activated.connect(_on_menu_activated)
112//!     tray_icon.spawn_tray()
113//!
114//! func _on_menu_activated(id: String):
115//!     if id == "quit":
116//!         get_tree().quit()
117//! ```
118
119// Module declarations
120pub mod godot;
121pub mod menu;
122pub mod tray;
123
124// Public re-exports
125pub use godot::TrayIcon;
126pub use menu::{MenuItemData, RadioItemData};
127pub use tray::{KsniTray, TrayEvent, TrayState};
128
129// Conditional GDExtension entry point
130#[cfg(feature = "gdextension")]
131mod gdextension {
132    use godot::prelude::*;
133
134    struct GodotKsniExtension;
135
136    #[gdextension]
137    unsafe impl ExtensionLibrary for GodotKsniExtension {}
138}