Skip to content

Comments

feat: allow disabling menu on right click and add show_menu()#294

Open
felipecrs wants to merge 2 commits intotauri-apps:devfrom
felipecrs:dynamic-menu
Open

feat: allow disabling menu on right click and add show_menu()#294
felipecrs wants to merge 2 commits intotauri-apps:devfrom
felipecrs:dynamic-menu

Conversation

@felipecrs
Copy link

@felipecrs felipecrs commented Jan 25, 2026

This PR adds two features to this crate:

  1. Allows disabling showing the menu on right click (similar to how it can be done for left click)
  2. Adds a method for displaying the menu manually

Which, together, fixes #254: users can disable menu on right click, update the menu on a right click event, and then display the menu once done.

PS: Claude Sonnet 4.5 has been used to generate these changes, but the code has been reviewed and changed for consistency.

Demo

Windows:

3cqD6MA7NY.mp4

Mac:

AnyDeskMSI_hKs5iFcMu9.mp4
Code for the demo
// Example demonstrating how to prevent automatic menu opening on right-click
// and manually show the menu after updating it dynamically
//
// This example shows two approaches:
// 1. Using show_menu() to immediately display the menu after updating (demonstrated here)
// 2. Using set_show_menu_on_right_click(true) to re-enable automatic opening
//
// Approach 1 is simpler and provides better UX as the menu appears instantly
// after the update without requiring another click.

use tray_icon::{
    menu::{Menu, MenuItem},
    Icon, MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent,
};
use winit::event_loop::{ControlFlow, EventLoop};

fn main() {
    let event_loop = EventLoop::builder().build().unwrap();

    let icon = load_icon();

    // Create initial menu items
    let menu = Menu::new();
    let item1 = MenuItem::new("Item 1", true, None);
    let item2 = MenuItem::new("Item 2", true, None);
    menu.append(&item1).unwrap();
    menu.append(&item2).unwrap();

    // Build tray icon with menu_on_right_click disabled
    let tray_icon = TrayIconBuilder::new()
        .with_tooltip("Dynamic Menu Example")
        .with_icon(icon)
        .with_menu(Box::new(menu.clone()))
        .with_menu_on_right_click(false) // Disable automatic menu opening on right-click
        .build()
        .unwrap();

    println!("Tray icon created with menu_on_right_click = false");
    println!("Right-click the tray icon to see dynamic menu updates!");

    let mut counter = 2;

    #[allow(deprecated)]
    let _ = event_loop.run(move |_event, elwt| {
        elwt.set_control_flow(ControlFlow::Poll);

            // Listen for tray icon events
            if let Ok(event) = TrayIconEvent::receiver().try_recv() {
                // Check if it's a right-click down event
                if matches!(
                    event,
                    TrayIconEvent::Click {
                        button: MouseButton::Right,
                        button_state: MouseButtonState::Down,
                        ..
                    }
                ) {
                    println!("Right-click detected! Updating menu...");

                    // Update menu items dynamically
                    counter += 1;
                    
                    // Update the menu item texts
                    item1.set_text(format!("Updated Item {}", counter - 1));
                    item2.set_text(format!("Updated Item {}", counter));

                    println!("Menu updated - texts changed");

                    // Now manually show the menu after updating
                    tray_icon.show_menu();
                }

            // Note: We no longer need to handle MouseButtonState::Up
            // because we're manually showing the menu immediately after updating
            }
        });
}

fn load_icon() -> Icon {
    let (icon_rgba, icon_width, icon_height) = {
        let image = image::load_from_memory(include_bytes!("../examples/icon.png"))
            .expect("Failed to open icon path")
            .into_rgba8();
        let (width, height) = image.dimensions();
        let rgba = image.into_raw();
        (rgba, width, height)
    };
    Icon::from_rgba(icon_rgba, icon_width, icon_height).expect("Failed to open icon")
}

@felipecrs felipecrs changed the title feat: allow disabling menu on right click and manual menu display feat: allow disabling menu on right click and add show_menu Jan 25, 2026
@felipecrs felipecrs changed the title feat: allow disabling menu on right click and add show_menu feat: allow disabling menu on right click and add show_menu() Jan 25, 2026
@felipecrs
Copy link
Author

@amrbashir sorry for pinging you, but I think this PR is almost a no-brainer. Mind taking a look?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow to prevent automatic opening of menu on right click

1 participant