Skip to content
/ ksni Public
forked from iovxw/ksni

A Rust implementation of the KDE/freedesktop StatusNotifierItem specification

License

Notifications You must be signed in to change notification settings

RenDiego/ksni

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

182 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ksni

Build Status Crates Documentation MSRV

A Rust implementation of the KDE/freedesktop StatusNotifierItem specification

Example

use ksni::TrayMethods; // provides the spawn method

#[derive(Debug)]
struct MyTray {
    selected_option: usize,
    checked: bool,
}

impl ksni::Tray for MyTray {
    fn id(&self) -> String {
        env!("CARGO_PKG_NAME").into()
    }
    fn icon_name(&self) -> String {
        "help-about".into()
    }
    fn title(&self) -> String {
        if self.checked { "CHECKED!" } else { "MyTray" }.into()
    }
    fn menu(&self) -> Vec<ksni::MenuItem<Self>> {
        use ksni::menu::*;
        vec![
            SubMenu {
                label: "a".into(),
                submenu: vec![
                    SubMenu {
                        label: "a1".into(),
                        submenu: vec![
                            StandardItem {
                                label: "a1.1".into(),
                                ..Default::default()
                            }
                            .into(),
                            StandardItem {
                                label: "a1.2".into(),
                                ..Default::default()
                            }
                            .into(),
                        ],
                        ..Default::default()
                    }
                    .into(),
                    StandardItem {
                        label: "a2".into(),
                        ..Default::default()
                    }
                    .into(),
                ],
                ..Default::default()
            }
            .into(),
            MenuItem::Separator,
            RadioGroup {
                selected: self.selected_option,
                select: Box::new(|this: &mut Self, current| {
                    this.selected_option = current;
                }),
                options: vec![
                    RadioItem {
                        label: "Option 0".into(),
                        ..Default::default()
                    },
                    RadioItem {
                        label: "Option 1".into(),
                        ..Default::default()
                    },
                    RadioItem {
                        label: "Option 2".into(),
                        ..Default::default()
                    },
                ],
                ..Default::default()
            }
            .into(),
            CheckmarkItem {
                label: "Checkable".into(),
                checked: self.checked,
                activate: Box::new(|this: &mut Self| this.checked = !this.checked),
                ..Default::default()
            }
            .into(),
            StandardItem {
                label: "Exit".into(),
                icon_name: "application-exit".into(),
                activate: Box::new(|_| std::process::exit(0)),
                ..Default::default()
            }
            .into(),
        ]
    }
}

#[tokio::main(flavor = "current_thread")]
async fn main() {
    let tray = MyTray {
        selected_option: 0,
        checked: false,
    };
    let handle = tray.spawn().await.unwrap();

    tokio::time::sleep(std::time::Duration::from_secs(5)).await;
    // We can modify the tray
    handle.update(|tray: &mut MyTray| tray.checked = true).await;
    // Run forever
    std::future::pending().await
}

Will create a system tray like this:

screenshot_of_example_in_gnome.png

(In GNOME with AppIndicator extension)

Async Runtime

ksni uses Tokio by default, but can be runtime-agnostic by disabling the "tokio" feature and enabling the "async-io" feature

[dependencies]
ksni = { version = "0.3", default-features = false, features = ["async-io"] }

Blocking API

Enable the "blocking" feature in Cargo.toml to get a non-async API

[dependencies]
ksni = { version = "0.3", features = ["blocking"] }

Todo

  • org.kde.StatusNotifierItem
  • com.canonical.dbusmenu
  • org.freedesktop.DBus.Introspectable
  • org.freedesktop.DBus.Properties
  • radio item
  • documents
  • async diwic/dbus-rs#166 edit: zbus now
  • mutable menu items

License

This is free and unencumbered software released into the public domain.

Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means.

About

A Rust implementation of the KDE/freedesktop StatusNotifierItem specification

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Rust 100.0%