dioxus icon indicating copy to clipboard operation
dioxus copied to clipboard

use_tray_menu_event_handler no longer works

Open Abrahamh08 opened this issue 6 months ago • 1 comments

I modified the multiwindow with tray example:

//! Multiwindow with tray icon example
//!
//! This example shows how to implement a simple multiwindow application and tray icon using dioxus.
//! This works by spawning a new window when the user clicks a button. We have to build a new virtualdom which has its
//! own context, root elements, etc.
//!
//! This is useful for apps that incorporate settings panels or persistent windows like Raycast.

use dioxus::{
    desktop::{
        tao::event::Event,
        trayicon::{
            menu::{Menu, MenuItem}, Icon, TrayIcon, TrayIconBuilder
        },
        use_tray_menu_event_handler, use_wry_event_handler, WindowEvent,
        window, WindowCloseBehaviour,
    },
    prelude::*,
};

fn main() {
    dioxus::launch(app);
}

fn app() -> Element {
    use_hook(|| {
        // Set the close behavior for the main window
        // This will hide the window instead of closing it when the user clicks the close button
        window().set_close_behavior(WindowCloseBehaviour::WindowHides);

        let menu = Menu::new();

        let quit_item = MenuItem::with_id("quit", "Quit", true, None);
        let _ = menu.append_items(&[&quit_item]).unwrap();

        // Building the tray icon itself
        let builder = TrayIconBuilder::new()
            .with_menu(Box::new(menu))
            .with_menu_on_left_click(false);

        // Providing the context to the dioxus app
        // Basically we just did the exact same thing as the default `init_tray_icon` function would do
        // https://github.com/DioxusLabs/dioxus/blob/a729968ee47b066e6d55dd9e0f8c2a1f1aef79e0/packages/desktop/src/trayicon.rs#L31
        // We do it manually to have more control over the tray icon
        provide_context(builder.build().expect("tray icon builder failed"))
    });

    use_tray_menu_event_handler(move |event| {
        dioxus::logger::tracing::info!("Tray event happened: {:?}", event);
        // Potentially there is a better way to do this.
        // The `0` is the id of the menu item
        match event.id.0.as_str() {
            "quit" => {
                std::process::exit(0);
            }
            _ => {}
        }
    });

    rsx! {
        button {
            onclick: move |_| {
                window().new_window(VirtualDom::new(popup), Default::default());
            },
            "New Window"
        }
    }
}

fn popup() -> Element {
    rsx! {
        div { "This is a popup window!" }
    }
}

I tested on both main and 0.7.0-alpha.3. In my use_tray_menu_event_handler closure, I don't get prints nor does my Quit button do anything. This worked in 0.6

Windows 11

Abrahamh08 avatar Jul 31 '25 20:07 Abrahamh08

Dioxus uses the same muda version as tray-icon since https://github.com/DioxusLabs/dioxus/pull/3533 (v0.7.0-alpha.0), so only the first call to MenuEvent::set_event_handler sets it (it's a OnceCell).

The one with the MudaMenuEvent happens to be the first, so this is the event that is sent every time, not TrayMenuEvent.

https://github.com/DioxusLabs/dioxus/blob/da72b63b6f01d217dc26b3212845702f6f955ee9/packages/desktop/src/app.rs#L90-L96

Use use_muda_event_handler instead and it will work.

Aziks0 avatar Dec 19 '25 07:12 Aziks0