GithubHelp home page GithubHelp logo

tauri-apps / tray-icon Goto Github PK

View Code? Open in Web Editor NEW
170.0 13.0 24.0 244 KB

Tray icons for Desktop Applications.

License: Apache License 2.0

Rust 100.00%
rust system-tray tray tray-app tray-application tray-icon tray-menu windowing gui

tray-icon's Introduction

tray-icon lets you create tray icons for desktop applications.

Platforms supported:

  • Windows
  • macOS
  • Linux (gtk Only)

Platform-specific notes:

  • On Windows and Linux, an event loop must be running on the thread, on Windows, a win32 event loop and on Linux, a gtk event loop. It doesn't need to be the main thread but you have to create the tray icon on the same thread as the event loop.
  • On macOS, an event loop must be running on the main thread so you also need to create the tray icon on the main thread.

Cargo Features

  • common-controls-v6: Use TaskDialogIndirect API from ComCtl32.dll v6 on Windows for showing the predefined About menu item dialog.
  • libxdo: Enables linking to libxdo which is used for the predfined Copy, Cut, Paste and SelectAll menu item, see https://github.com/tauri-apps/muda#cargo-features
  • serde: Enables de/serializing derives.

Dependencies (Linux Only)

On Linux, gtk, libxdo is used to make the predfined Copy, Cut, Paste and SelectAll menu items work and libappindicator or libayatnat-appindicator are used to create the tray icon, so make sure to install them on your system.

Arch Linux / Manjaro:

pacman -S gtk3 xdotool libappindicator-gtk3 #or libayatana-appindicator

Debian / Ubuntu:

sudo apt install libgtk-3-dev libxdo-dev libappindicator3-dev #or libayatana-appindicator3-dev

Examples

Create a tray icon without a menu.

use tray_icon::TrayIconBuilder;

let tray_icon = TrayIconBuilder::new()
    .with_tooltip("system-tray - tray icon library!")
    .with_icon(icon)
    .build()
    .unwrap();

Create a tray icon with a menu.

use tray_icon::{TrayIconBuilder, menu::Menu};

let tray_menu = Menu::new();
let tray_icon = TrayIconBuilder::new()
    .with_menu(Box::new(tray_menu))
    .with_tooltip("system-tray - tray icon library!")
    .with_icon(icon)
    .build()
    .unwrap();

Processing tray events

You can use TrayIconEvent::receiver to get a reference to the TrayIconEventReceiver which you can use to listen to events when a click happens on the tray icon

use tray_icon::TrayIconEvent;

if let Ok(event) = TrayIconEvent::receiver().try_recv() {
    println!("{:?}", event);
}

You can also listen for the menu events using MenuEvent::receiver to get events for the tray context menu.

use tray_icon::{TrayIconEvent, menu::{MenuEvent}};

if let Ok(event) = TrayIconEvent::receiver().try_recv() {
    println!("tray event: {:?}", event);
}

if let Ok(event) = MenuEvent::receiver().try_recv() {
    println!("menu event: {:?}", event);
}

License

Apache-2.0/MIT

tray-icon's People

Contributors

amrbashir avatar dklassic avatar ericchu94 avatar experimentalcyborg avatar fabianlars avatar github-actions[bot] avatar htngr avatar kandrelczyk avatar kuvaus avatar legend-master avatar lucasfernog avatar mokurin000 avatar pauldgillis avatar pewsheen avatar pronebird avatar renovate[bot] avatar rustdesk avatar t-oster avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tray-icon's Issues

Unable to run example directly from terminal, works from IDE (RustRover)

I'm a newbie to Rust, so I probably did something stupid and should have done differently.

I have cloned the project and wanted to run:

/Users/kino/.cargo/bin/cargo run --color=always --package tray-icon --example tao

If I run this through IDE (RustRover), I'm able to run it properly, and the tray icon shows as expected.

When I do the same from the terminal, I receive bus error. I was able to track down that the problem is

TrayIconBuilder::new()
. It does not matter what example I try to run. The bus error is always received when the try icon itself tries to build.

/Users/kino/.cargo/bin/cargo run --color=always --package tray-icon --example tao
    Finished dev [unoptimized + debuginfo] target(s) in 0.14s
     Running `target/debug/examples/tao`
[1]    34852 bus error  /Users/kino/.cargo/bin/cargo run --color=always --package tray-icon --example
./target/debug/examples/tao
[1]    35415 bus error  ./target/debug/examples/tao

Cargo/rust is installed with rustup

cargo --version
cargo 1.77.2 (e52e36006 2024-03-26)

rustc --version
rustc 1.77.2 (25ef9e3d8 2024-04-09)

rustup --version
rustup 1.27.0 (2024-03-08)
info: This is the version for the rustup toolchain manager, not the rustc compiler.
info: The currently active `rustc` version is `rustc 1.77.2 (25ef9e3d8 2024-04-09)`

edit: I'm using MacOS 14.4.1 with M1 cpu aarch64-apple-darwin toolchain default

Program crash after closing tray-icon menu without clicking any options

As the title says, when you right-click on a tray-icon the menu pops up as normal, but if you close the menu by clicking anywhere else the program simply crashes, giving the "STATUS_ACCESS_VIOLATION" error.
This was made on windows 10 pro 19045.3930.
This is my code stating the tray icon, menu and menu item:

let my_menu: Menu = Menu::new();

let _ = my_menu.append(&PredefinedMenuItem::quit(Some("Terminar")));

let _tray_icon: TrayIcon = TrayIconBuilder::new()
    .with_tooltip("Anti-AFK")
    .with_icon(icono)
    .with_menu(Box::new(my_menu))
    .build()
    .unwrap();

Can we just show text(without icon) in menubar?

https://github.com/matryer/xbar, image below is how xbar shows.
image

I am building an app using tauri-app, I just want to show text.

I've tried to set an empty png as icon(1px transparent), but throw error about not visible

thread 'main' panicked at 'error while running tauri application: Runtime(InvalidIcon(ByteCountNotDivisibleBy4 { byte_count: 5 }))', src/main.rs:39:10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

So can we support pure text or support empty png 🤔?

The icon is not update a second time because of icon cache

Hi,
I have the issue, that if I change the icon of a tray-icon with the set_icon method, the change only updates the icon the first time.

My guess is that you generate a temp file here

let icon_path = parent_path.join(format!("tray-icon-{}.png", id));
which resolves to tray-icon-1.png every time (because of the ID 1 of the tray-icon stays the same) and GTK is not updating the icon, because it is cached somehow.

The file itself is deleted and updated correctly, but since the name stays the same, at least in my Environment (ArchLinux+Cinnamon), the icon in the tray stays the same.

I would suggest adding a hash-value of the icon-path or similar so that different icons get mapped to different temp-files.

Error from simple example: "assertion 'GDK_IS_SCREEN (screen)' failed"

Output:

(process:70403): Gtk-CRITICAL **: 08:18:12.185: gtk_icon_theme_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed

(process:70403): GLib-GObject-WARNING **: 08:18:12.187: invalid (NULL) pointer instance

(process:70403): GLib-GObject-CRITICAL **: 08:18:12.187: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed

system info

(removed)


A minimal example can be found here

I'm suspecting there's some dependency I need that isn't specified? I've added a PKGBUILD to the repo to demonstrate that I'm depending on xdo, is there something else I need?

tray icon menu renders under taskbar

Opening and closing windows 11 tray quick settings then opening menu on own tray app renders the menu under the taskbar. Not able to close it unless right clicking on it then left clicking off it.
image

MacOS Sonoma displaying more than one icon

Using MacOS Sonoma (14.0) the icon will display twice on a single monitor. Once the actual tray icon is clicked and/or the current application loses focus it disappears.

image

Does this work on KDE?

When I run a test app on KDE (Kubuntu) I don't get any tray icon but my log gets:

(process:56879): Gtk-CRITICAL **: 14:39:36.342: gtk_icon_theme_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed

(process:56879): GLib-GObject-WARNING **: 14:39:36.342: invalid (NULL) pointer instance

(process:56879): GLib-GObject-CRITICAL **: 14:39:36.342: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed

Fluctuating width of the System tray

Is your feature request related to a problem? Please describe.

I am creating a timer application system tray for macOS.
I use set_title() to display the time remaining.

Because the width of each number is different, the width of the System tray changes each time it is dynamically updated. The position of the System tray to the left of the timer is also affected by all of this.

Describe the solution you'd like

I don't understand how far the OS can go in terms of potential. However, if I were to mention just a few things that immediately come to mind,

  • Allow monospace fonts to be specified
  • Fixed widths for the System tray itself

Can you think of anything else?

I looked for articles like this one.
https://developer.apple.com/forums/thread/21474

Describe alternatives you've considered

None in particular

Would you want to assign yourself to implement this feature?

  • Yes
  • No

Additional context

Fluctuating.width.mov

egui example doesn't work, crashes on start on macOS

Assertion failed: (CGAtomicGet(&is_initialized)), function CGSConnectionByID, file CGSConnection.mm, line 422.

After looking what might have caused the error, it seems that the NSApp needs to be initialized first
servo/core-foundation-rs#176

Indeed, moving tray creation inside the run_native function fixes the crash

    eframe::run_native(
        "My egui App",
        options,
        Box::new(|_cc| {
            // moved inside the lambda
            let _tray_icon = TrayIconBuilder::new().with_icon(icon).build().unwrap();

            Box::<MyApp>::default()
        }),
    )

BUT there is no icon in sight! Note that other examples worked just fine (winit + tao)

Tao example don't show menu on click

On Fedora 39, using the tao example, the tray icon appear but when clicking on it the menu does not show
A warning appear in the console:
LIBDBUSMENU-GLIB-WARNING **: 04:30:27.277: About to Show called on an item wihtout submenus. We're ignoring it.

`mouse-leave` and `mouse-enter` events

SystemTrayEvent contains MenuItemClick LeftClick RightClick RightClick event,but hover event is not contain.I think this should also be a commonly used event.

macOS: Incorrect tray icon size

Hi,

I have played a bit with the new tray API on 13.1 which was migrated from Rectangle to tauri::Rect. I found that it's basically broken, see the click event dump:

TrayIconEvent {
  id: TrayIconId("main"), 
  position: PhysicalPosition { x: 1237.8192138671875, y: 11.752716064453125 }, 
  icon_rect: Rect { position: Physical(PhysicalPosition { x: 2450, y: 48 }), 
  size: Physical(PhysicalSize { width: 2450, height: 2052 }) 
}

The value for tray size is extremely large and it makes no sense.

Help with linker (cc)

Hello, I don't think it's a library problem (if this type of issue for help isn't allowed, I delete it), but I would like some help.

I tried to reproduce the example "egui", but found some errors, so I did a minimal example: 

fn main() {
    let path = "/home/<your-path-to-folder>/src/icon.png";
    let icon = load_icon(std::path::Path::new(path));

    let tray_icon = TrayIconBuilder::new()
        .with_tooltip("system-tray - tray icon library!")
        .with_icon(icon)
        .build()
        .unwrap();
}

However, when i run cargo build i got this error:

"-Wl,-Bdynamic" "-lxdo" "-ldl" "-lgtk-3" "-lgdk-3" "-lpangocairo-1.0" "-lpango-1.0" "-lharfbuzz" "-latk-1.0" "-lcairo-gobject" "-lcairo" "-lgdk_pixbuf-2.0" "-lgio-2.0" "-lgobject-2.0" "-lglib-2.0" "-latk-1.0" "-lgobject-2.0" "-lglib-2.0" "-lgdk-3" "-lpangocairo-1.0" "-lpango-1.0" "-lharfbuzz" "-lgdk_pixbuf-2.0" "-lcairo-gobject" "-lcairo" "-lgobject-2.0" "-lglib-2.0" "-lpango-1.0" "-lgobject-2.0" "-lglib-2.0" "-lharfbuzz" "-lgdk_pixbuf-2.0" "-lgobject-2.0" "-lglib-2.0" "-lcairo-gobject" "-lcairo" "-lgobject-2.0" "-lglib-2.0" "-lgobject-2.0" "-lgio-2.0" "-lgobject-2.0" "-lglib-2.0" "-lgobject-2.0" "-lglib-2.0" "-lgobject-2.0" "-lglib-2.0" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/home/ademar/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "/home/ademar/Projetos/bosta/target/debug/deps/bosta-454ed0ac8f88c5a2" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs"
  = note: /usr/bin/ld: cannot find -lxdo: No such file or directory
          collect2: error: ld returned 1 exit status

I installed a lot of dependencies (gtk, libc-dev, gcc-multilib and anothers) trying to solve this problem, but with no success.

I tried run the command cc with all the flags and got an error too:

/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/Scrt1.o: in function `_start':
(.text+0x1b): undefined reference to `main'
collect2: error: ld returned 1 exit status

OS: Pop OS 22.04 (Cosmic)

Sorry for the poor English.

Clarification on dependencies

Are the specified dependencies for development purposes only?

Arch Linux / Manjaro:
pacman -S gtk3 libappindicator-gtk3 #or libayatana-appindicator
Debian / Ubuntu:
sudo apt install libgtk-3-dev libappindicator3-dev #or libayatana-appindicator3-dev

"assertion 'GTK_IS_WINDOW (window)' failed" when clicking on the egui example on Linux

I'm getting the following error whenever I click on the tray icon if it includes a with_menu builder section.

(legion-kb-rgb:1553719): Gtk-CRITICAL **: 19:05:37.050: gtk_window_set_accept_focus: assertion 'GTK_IS_WINDOW (window)' failed
zsh: segmentation fault (core dumped)  nix run . -L --

Current test code is here which is a slightly changed version of the egui example, which exhibits the same behavior.

Using GNOME 44.3 with the extension "Tray Icons: Reloaded" to be able to display them. (May has something to do with it? Every other app works fine though.)

Cant run tray_icon with iced-rs

This is the error that i get every single time :


"` to apply 2 suggestions)
    Finished dev [unoptimized + debuginfo] target(s) in 0.13s
     Running `target/debug/wall-garden`

(process:740): Gtk-CRITICAL **: 20:46:21.575: gtk_icon_theme_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed

(process:740): GLib-GObject-CRITICAL **: 20:46:21.576: invalid (NULL) pointer instance

(process:740): GLib-GObject-CRITICAL **: 20:46:21.576: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed
thread 'main' panicked at 'GTK has not been initialized. Call `gtk::init` first.', /home/melnibone/.cargo/registry/src/index.crates.io-6f17d22bba15001f/gtk-0.16.2/src/auto/menu.rs:40:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

and here is part of the code responsible for loading and preparing tray

  let path = "/home/melnibone/sandbox/rust/wall-garden/wall-garden/src/icon.png";
    let icon = load_icon(std::path::Path::new(path));
    let tray_menu = Menu::new();

    let quit_i = MenuItem::new("Quit", true, None);
    tray_menu.append_items(&[
        &MenuItem::new("show", true, None),
        &PredefinedMenuItem::separator(),
        &quit_i,
    ]);
    let tray_icon = TrayIconBuilder::new()
        .with_menu(Box::new(tray_menu))
        .with_tooltip("welcome")
        .with_icon(icon)
        .build();

    if let Err(error) = tray_icon {
        match error {
            tray_icon::Error::OsError(err) => std::process::exit(err.raw_os_error().unwrap_or(-1)),

            _ => std::process::exit(-1),
        }
    }

Tray click events on linux not firing

  • LeftClick
  • RightClick
  • DoubleClick

Are not triggered on linux.

I have found out that this is due to a limit in libappindicator used on linux.

Is it possible to switch to another lib or to submit a feature request to the maintainers of libappindicator?
I can not find it.

It is not clear how to use it

So, I copy/paste code from the Examples:

use tray_icon::TrayIconBuilder;

let tray_icon = TrayIconBuilder::new()
    .with_tooltip("system-tray - tray icon library!")
    .with_icon(icon)
    .build()
    .unwrap();

And, unsuprisingly, I got

unresolved import `tray_icon`
use of undeclared crate or module `tray_icon`

cannot find value `icon` in this scope
not found in this scope

What am I missing? I do not see any extra steps in the readme.

Then, I hoped to get answer in example folder, but ... there are multiple files - 1) I do not understand why there are many of them and what is the difference; 2) I copied code snippets and none of them worked for me, again, something is missing.

RUSTSEC-2022-0048: xml-rs is Unmaintained

xml-rs is Unmaintained

Details
Status unmaintained
Package xml-rs
Version 0.8.4
URL https://github.com/netvl/xml-rs/issues
Date 2022-01-26

xml-rs is a XML parser has open issues around parsing including integer
overflows / panics that may or may not be an issue with untrusted data.

Together with these open issues with Unmaintained status xml-rs
may or may not be suited to parse untrusted data.

Alternatives

See advisory page for additional details.

`Icon::from_resource` does not support icon without a ordinal id

I used windows-exe-info to link my executable with icon,
But in the icon0.rc it generated there is no ordinal id but a string name

image

I tried to pass 1033, 0, 1...13, but neither works
I believe We should support both ordinal ID and string ID

According to a document posted in 1992 for windows1:

The items marked `Name or Ordinal' are the same format used throughout the resource file (most notably in each resource header) to store a name or an ordinal ID.

Footnotes

  1. https://archive.org/details/RESFMT_ZIP

feat: query the tray icon rect without waiting for an event

The system tray is created for macOS.
Clicking on the system tray opens a window at the bottom of it.
The coordinates of the window are set using tauri-plugin-positioner.

The application can also display windows with global shortcut keys.
I was able to implement the shortcut key display, but I am having trouble setting the coordinates.
If I do nothing, the window will be centered on the display, so when I execute window.move_window(Position::TrayCenter);, it crashes.

When the user clicks on the system tray on the menu bar, a system tray event is fired at that point, so tauri-plugin-positioner can calculate where it should appear.
However, it is possible that a user may use a shortcut key without ever clicking on the system tray after launching an application. At that time, the system tray event has not yet occurred, so tauri-plugin-positioner cannot calculate where the window should be displayed. That's why I think that executing window.move_window(Position::TrayCenter); in the display handler will cause a crash.

Do you have any ideas that could solve this?
Also, fundamentally, do you think Tauri itself needs to be improved so that it can calculate the display coordinates when the system tray is activated?

Consider renaming the project to system-tray for consistency with other tauri crates

My OCD couldn't help but notice that this was the only project that used an underscore in both the repo and crate name. 🤣 I believe that all other tauri libraries (and most of the Rust ecosystem) prefers dashes, so thought I'd raise this since it may be a good time to adjust the name before the crate is released. 😄

Cheers
Fotis

Listening events for tray icons

Listening events for tray icons, such as mouse entry/leave, etc. And return to the position of the mouse and the position of the system tray.
Similar to the "mouse-leave" and "mouse-enter" events in electronjs.
Is there any way to achieve similar functionality in the v1 version?

Support template icon on macOS

macOS can set a mask for template icon.

Qt support the following usage.

QIcon icon(":/darwin/tray_icon.png");
icon.setIsMask(true);

Please support this feature.

using gtk4?

tray-icon is currently using gtk3. Would it be possible to bump to gtk4?

How to use MenuItem on Linux?

I'm trying to interact with a CheckMenuItem on the event loop in Linux, and I can't figure out how because of the following requirements:

  • the tray icon must be built on the GTK thread
  • the menu items must be passed in when the tray icon is built, therefore they must also be on the GTK thread
  • the GTK thread and the event loop must be different threads, as calling gtk:main() takes over the GTK thread forever
  • neither TrayIcon nor MenuItem are Send, so I can't move them between the GTK thread and the event loop thread.

I'm sure I'm missing something, but it looks impossible for the event loop to interact with MenuItems on Linux. If the examples could be updated to show how this is supposed to be done I'd appreciate it!

winit example doesn't work on linux

Running `target/debug/examples/winit`

(process:982485): Gtk-CRITICAL **: 14:17:22.383: gtk_icon_theme_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed

(process:982485): GLib-GObject-WARNING **: 14:17:22.384: invalid (NULL) pointer instance

(process:982485): GLib-GObject-CRITICAL **: 14:17:22.384: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed
thread 'main' panicked at 'GTK has not been initialized. Call `gtk::init` first.', /home/bsteinbrink/.cargo/registry/src/index.crates.io-6f17d22bba15001f/gtk-0.16.2/src/auto/menu.rs:40:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Running on Ubuntu 22.10

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.