feat(api/tray): add TrayIcon.setShowMenuOnLeftClick method (#11726)

This commit is contained in:
Amr Bashir 2024-11-21 14:50:41 +02:00 committed by GitHub
parent 7a9b920c3e
commit fc30b20bea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 203 additions and 74 deletions

View File

@ -0,0 +1,6 @@
---
"@tauri-apps/api": "minor:feat"
---
Add `TrayIcon.setShowMenuOnLeftClick` method and deprecate `TrayIcon.setMenuOnLeftClick` to match the Rust API.

View File

@ -0,0 +1,6 @@
---
"@tauri-apps/api": "minor:feat"
---
Add `TrayIconOptions.showMenuOnLeftClick` field and deprecate `TrayIconOptions.menuOnLeftClick` to match the Rust API.

View File

@ -0,0 +1,6 @@
---
"tauri": "minor:feat"
---
Add `TrayIconBuilder::show_menu_on_left_click` method and deprecate `TrayIconBuilder::menu_on_left_click` for consistent naming and clarity.

View File

@ -0,0 +1,6 @@
---
"@tauri-apps/api": "minor:enhance"
---
Add support for `TrayIconOptions.menuOnLeftClick` option and `TrayIcon.setMenuOnLeftClick` on Windows.

View File

@ -1,6 +1,6 @@
---
"tauri": patch:bug
"tauri": "minor:enhance"
---
Support for `set_show_menu_on_left_click` was implemented on Windows too. So it
should not be macOS anymore. [tauri-apps/tray-icon#199](https://github.com/tauri-apps/tray-icon/pull/199)
Add support for `TrayIconBuilder::menu_on_left_click` and `TrayIcon::set_show_menu_on_left_click` on Windows.

View File

@ -1624,7 +1624,13 @@
"type": "boolean"
},
"menuOnLeftClick": {
"description": "A Boolean value that determines whether the menu should appear when the tray icon receives a left click on macOS.",
"description": "A Boolean value that determines whether the menu should appear when the tray icon receives a left click.\n\n ## Platform-specific:\n\n - **Linux**: Unsupported.",
"default": true,
"deprecated": true,
"type": "boolean"
},
"showMenuOnLeftClick": {
"description": "A Boolean value that determines whether the menu should appear when the tray icon receives a left click.\n\n ## Platform-specific:\n\n - **Linux**: Unsupported.",
"default": true,
"type": "boolean"
},

View File

@ -1624,7 +1624,13 @@
"type": "boolean"
},
"menuOnLeftClick": {
"description": "A Boolean value that determines whether the menu should appear when the tray icon receives a left click on macOS.",
"description": "A Boolean value that determines whether the menu should appear when the tray icon receives a left click.\n\n ## Platform-specific:\n\n - **Linux**: Unsupported.",
"default": true,
"deprecated": true,
"type": "boolean"
},
"showMenuOnLeftClick": {
"description": "A Boolean value that determines whether the menu should appear when the tray icon receives a left click.\n\n ## Platform-specific:\n\n - **Linux**: Unsupported.",
"default": true,
"type": "boolean"
},

View File

@ -2431,9 +2431,21 @@ pub struct TrayIconConfig {
/// A Boolean value that determines whether the image represents a [template](https://developer.apple.com/documentation/appkit/nsimage/1520017-template?language=objc) image on macOS.
#[serde(default, alias = "icon-as-template")]
pub icon_as_template: bool,
/// A Boolean value that determines whether the menu should appear when the tray icon receives a left click on macOS.
/// A Boolean value that determines whether the menu should appear when the tray icon receives a left click.
///
/// ## Platform-specific:
///
/// - **Linux**: Unsupported.
#[serde(default = "default_true", alias = "menu-on-left-click")]
#[deprecated(since = "2.2.0", note = "Use `show_menu_on_left_click` instead.")]
pub menu_on_left_click: bool,
/// A Boolean value that determines whether the menu should appear when the tray icon receives a left click.
///
/// ## Platform-specific:
///
/// - **Linux**: Unsupported.
#[serde(default = "default_true", alias = "show-menu-on-left-click")]
pub show_menu_on_left_click: bool,
/// Title for MacOS tray
pub title: Option<String>,
/// Tray icon tooltip on Windows and macOS
@ -3351,7 +3363,9 @@ mod build {
fn to_tokens(&self, tokens: &mut TokenStream) {
let id = opt_str_lit(self.id.as_ref());
let icon_as_template = self.icon_as_template;
#[allow(deprecated)]
let menu_on_left_click = self.menu_on_left_click;
let show_menu_on_left_click = self.show_menu_on_left_click;
let icon_path = path_buf_lit(&self.icon_path);
let title = opt_str_lit(self.title.as_ref());
let tooltip = opt_str_lit(self.tooltip.as_ref());
@ -3362,6 +3376,7 @@ mod build {
icon_path,
icon_as_template,
menu_on_left_click,
show_menu_on_left_click,
title,
tooltip
);

File diff suppressed because one or more lines are too long

View File

@ -2042,10 +2042,12 @@ tauri::Builder::default()
{
let config = app.config();
if let Some(tray_config) = &config.app.tray_icon {
#[allow(deprecated)]
let mut tray =
TrayIconBuilder::with_id(tray_config.id.clone().unwrap_or_else(|| "main".into()))
.icon_as_template(tray_config.icon_as_template)
.menu_on_left_click(tray_config.menu_on_left_click);
.menu_on_left_click(tray_config.menu_on_left_click)
.show_menu_on_left_click(tray_config.show_menu_on_left_click);
if let Some(icon) = &app.manager.tray.icon {
tray = tray.icon(icon.clone());
}

View File

@ -119,9 +119,9 @@ impl<R: Runtime> CheckMenuItem<R> {
/// Set this menu item accelerator.
pub fn set_accelerator<S: AsRef<str>>(&self, accelerator: Option<S>) -> crate::Result<()> {
let accel = accelerator.and_then(|s| s.as_ref().parse().ok());
run_item_main_thread!(self, |self_: Self| (*self_.0)
.as_ref()
.set_accelerator(accel))?
run_item_main_thread!(self, |self_: Self| {
(*self_.0).as_ref().set_accelerator(accel)
})?
.map_err(Into::into)
}

View File

@ -206,9 +206,9 @@ impl<R: Runtime> IconMenuItem<R> {
/// Set this menu item accelerator.
pub fn set_accelerator<S: AsRef<str>>(&self, accelerator: Option<S>) -> crate::Result<()> {
let accel = accelerator.and_then(|s| s.as_ref().parse().ok());
run_item_main_thread!(self, |self_: Self| (*self_.0)
.as_ref()
.set_accelerator(accel))?
run_item_main_thread!(self, |self_: Self| {
(*self_.0).as_ref().set_accelerator(accel)
})?
.map_err(Into::into)
}
@ -228,9 +228,9 @@ impl<R: Runtime> IconMenuItem<R> {
/// - **Windows / Linux**: Unsupported.
pub fn set_native_icon(&self, _icon: Option<NativeIcon>) -> crate::Result<()> {
#[cfg(target_os = "macos")]
return run_item_main_thread!(self, |self_: Self| (*self_.0)
.as_ref()
.set_native_icon(_icon.map(Into::into)));
return run_item_main_thread!(self, |self_: Self| {
(*self_.0).as_ref().set_native_icon(_icon.map(Into::into))
});
#[allow(unreachable_code)]
Ok(())
}

View File

@ -271,9 +271,9 @@ impl<R: Runtime> Menu<R> {
/// [`Submenu`]: super::Submenu
pub fn append(&self, item: &dyn IsMenuItem<R>) -> crate::Result<()> {
let kind = item.kind();
run_item_main_thread!(self, |self_: Self| (*self_.0)
.as_ref()
.append(kind.inner().inner_muda()))?
run_item_main_thread!(self, |self_: Self| {
(*self_.0).as_ref().append(kind.inner().inner_muda())
})?
.map_err(Into::into)
}
@ -301,9 +301,9 @@ impl<R: Runtime> Menu<R> {
/// [`Submenu`]: super::Submenu
pub fn prepend(&self, item: &dyn IsMenuItem<R>) -> crate::Result<()> {
let kind = item.kind();
run_item_main_thread!(self, |self_: Self| (*self_.0)
.as_ref()
.prepend(kind.inner().inner_muda()))?
run_item_main_thread!(self, |self_: Self| {
(*self_.0).as_ref().prepend(kind.inner().inner_muda())
})?
.map_err(Into::into)
}
@ -351,18 +351,20 @@ impl<R: Runtime> Menu<R> {
/// Remove a menu item from this menu.
pub fn remove(&self, item: &dyn IsMenuItem<R>) -> crate::Result<()> {
let kind = item.kind();
run_item_main_thread!(self, |self_: Self| (*self_.0)
.as_ref()
.remove(kind.inner().inner_muda()))?
run_item_main_thread!(self, |self_: Self| {
(*self_.0).as_ref().remove(kind.inner().inner_muda())
})?
.map_err(Into::into)
}
/// Remove the menu item at the specified position from this menu and returns it.
pub fn remove_at(&self, position: usize) -> crate::Result<Option<MenuItemKind<R>>> {
run_item_main_thread!(self, |self_: Self| (*self_.0)
.as_ref()
.remove_at(position)
.map(|i| MenuItemKind::from_muda(self_.0.app_handle.clone(), i)))
run_item_main_thread!(self, |self_: Self| {
(*self_.0)
.as_ref()
.remove_at(position)
.map(|i| MenuItemKind::from_muda(self_.0.app_handle.clone(), i))
})
}
/// Retrieves the menu item matching the given identifier.
@ -380,12 +382,14 @@ impl<R: Runtime> Menu<R> {
/// Returns a list of menu items that has been added to this menu.
pub fn items(&self) -> crate::Result<Vec<MenuItemKind<R>>> {
run_item_main_thread!(self, |self_: Self| (*self_.0)
.as_ref()
.items()
.into_iter()
.map(|i| MenuItemKind::from_muda(self_.0.app_handle.clone(), i))
.collect::<Vec<_>>())
run_item_main_thread!(self, |self_: Self| {
(*self_.0)
.as_ref()
.items()
.into_iter()
.map(|i| MenuItemKind::from_muda(self_.0.app_handle.clone(), i))
.collect::<Vec<_>>()
})
}
/// Set this menu as the application menu.

View File

@ -117,9 +117,9 @@ impl<R: Runtime> MenuItem<R> {
/// Set this menu item accelerator.
pub fn set_accelerator<S: AsRef<str>>(&self, accelerator: Option<S>) -> crate::Result<()> {
let accel = accelerator.and_then(|s| s.as_ref().parse().ok());
run_item_main_thread!(self, |self_: Self| (*self_.0)
.as_ref()
.set_accelerator(accel))?
run_item_main_thread!(self, |self_: Self| {
(*self_.0).as_ref().set_accelerator(accel)
})?
.map_err(Into::into)
}
}

View File

@ -173,9 +173,9 @@ impl<R: Runtime> Submenu<R> {
/// Add a menu item to the end of this submenu.
pub fn append(&self, item: &dyn IsMenuItem<R>) -> crate::Result<()> {
let kind = item.kind();
run_item_main_thread!(self, |self_: Self| (*self_.0)
.as_ref()
.append(kind.inner().inner_muda()))?
run_item_main_thread!(self, |self_: Self| {
(*self_.0).as_ref().append(kind.inner().inner_muda())
})?
.map_err(Into::into)
}
@ -225,18 +225,20 @@ impl<R: Runtime> Submenu<R> {
/// Remove a menu item from this submenu.
pub fn remove(&self, item: &dyn IsMenuItem<R>) -> crate::Result<()> {
let kind = item.kind();
run_item_main_thread!(self, |self_: Self| (*self_.0)
.as_ref()
.remove(kind.inner().inner_muda()))?
run_item_main_thread!(self, |self_: Self| {
(*self_.0).as_ref().remove(kind.inner().inner_muda())
})?
.map_err(Into::into)
}
/// Remove the menu item at the specified position from this submenu and returns it.
pub fn remove_at(&self, position: usize) -> crate::Result<Option<MenuItemKind<R>>> {
run_item_main_thread!(self, |self_: Self| (*self_.0)
.as_ref()
.remove_at(position)
.map(|i| MenuItemKind::from_muda(self_.0.app_handle.clone(), i)))
run_item_main_thread!(self, |self_: Self| {
(*self_.0)
.as_ref()
.remove_at(position)
.map(|i| MenuItemKind::from_muda(self_.0.app_handle.clone(), i))
})
}
/// Retrieves the menu item matching the given identifier.
@ -293,9 +295,9 @@ impl<R: Runtime> Submenu<R> {
/// certain other items to the menu.
#[cfg(target_os = "macos")]
pub fn set_as_windows_menu_for_nsapp(&self) -> crate::Result<()> {
run_item_main_thread!(self, |self_: Self| (*self_.0)
.as_ref()
.set_as_windows_menu_for_nsapp())?;
run_item_main_thread!(self, |self_: Self| {
(*self_.0).as_ref().set_as_windows_menu_for_nsapp()
})?;
Ok(())
}
@ -307,9 +309,9 @@ impl<R: Runtime> Submenu<R> {
/// which has a title matching the localized word "Help".
#[cfg(target_os = "macos")]
pub fn set_as_help_menu_for_nsapp(&self) -> crate::Result<()> {
run_item_main_thread!(self, |self_: Self| (*self_.0)
.as_ref()
.set_as_help_menu_for_nsapp())?;
run_item_main_thread!(self, |self_: Self| {
(*self_.0).as_ref().set_as_help_menu_for_nsapp()
})?;
Ok(())
}
}

View File

@ -307,12 +307,30 @@ impl<R: Runtime> TrayIconBuilder<R> {
self
}
/// Whether to show the tray menu on left click or not, default is `true`. **macOS & Windows only**.
/// Whether to show the tray menu on left click or not, default is `true`.
///
/// ## Platform-specific:
///
/// - **Linux:** Unsupported.
#[deprecated(
since = "2.2.0",
note = "Use `TrayIconBuiler::show_menu_on_left_click` instead."
)]
pub fn menu_on_left_click(mut self, enable: bool) -> Self {
self.inner = self.inner.with_menu_on_left_click(enable);
self
}
/// Whether to show the tray menu on left click or not, default is `true`.
///
/// ## Platform-specific:
///
/// - **Linux:** Unsupported.
pub fn show_menu_on_left_click(mut self, enable: bool) -> Self {
self.inner = self.inner.with_menu_on_left_click(enable);
self
}
/// Set a handler for menu events.
///
/// Note that this handler is called for any menu event,
@ -493,9 +511,9 @@ impl<R: Runtime> TrayIcon<R> {
///
/// - **Linux**: once a menu is set it cannot be removed so `None` has no effect
pub fn set_menu<M: ContextMenu + 'static>(&self, menu: Option<M>) -> crate::Result<()> {
run_item_main_thread!(self, |self_: Self| self_
.inner
.set_menu(menu.map(|m| m.inner_context_owned())))
run_item_main_thread!(self, |self_: Self| {
self_.inner.set_menu(menu.map(|m| m.inner_context_owned()))
})
}
/// Sets the tooltip for this tray icon.
@ -543,18 +561,23 @@ impl<R: Runtime> TrayIcon<R> {
/// Sets the current icon as a [template](https://developer.apple.com/documentation/appkit/nsimage/1520017-template?language=objc). **macOS only**.
pub fn set_icon_as_template(&self, #[allow(unused)] is_template: bool) -> crate::Result<()> {
#[cfg(target_os = "macos")]
run_item_main_thread!(self, |self_: Self| self_
.inner
.set_icon_as_template(is_template))?;
run_item_main_thread!(self, |self_: Self| {
self_.inner.set_icon_as_template(is_template)
})?;
Ok(())
}
/// Disable or enable showing the tray menu on left click. **macOS & Windows only**.
/// Disable or enable showing the tray menu on left click.
///
///
/// ## Platform-specific:
///
/// - **Linux**: Unsupported.
pub fn set_show_menu_on_left_click(&self, #[allow(unused)] enable: bool) -> crate::Result<()> {
#[cfg(any(target_os = "macos", target_os = "windows"))]
run_item_main_thread!(self, |self_: Self| self_
.inner
.set_show_menu_on_left_click(enable))?;
#[cfg(any(target_os = "macos", windows))]
run_item_main_thread!(self, |self_: Self| {
self_.inner.set_show_menu_on_left_click(enable)
})?;
Ok(())
}
@ -564,12 +587,12 @@ impl<R: Runtime> TrayIcon<R> {
///
/// - **Linux**: Unsupported, always returns `None`.
pub fn rect(&self) -> crate::Result<Option<crate::Rect>> {
run_item_main_thread!(self, |self_: Self| self_.inner.rect().map(|rect| {
Rect {
run_item_main_thread!(self, |self_: Self| {
self_.inner.rect().map(|rect| Rect {
position: rect.position.into(),
size: rect.size.into(),
}
}))
})
})
}
}

View File

@ -30,6 +30,7 @@ struct TrayIconOptions {
temp_dir_path: Option<PathBuf>,
icon_as_template: Option<bool>,
menu_on_left_click: Option<bool>,
show_menu_on_left_click: Option<bool>,
}
#[command(root = "crate")]
@ -78,9 +79,13 @@ fn new<R: Runtime>(
if let Some(icon_as_template) = options.icon_as_template {
builder = builder.icon_as_template(icon_as_template);
}
#[allow(deprecated)]
if let Some(menu_on_left_click) = options.menu_on_left_click {
builder = builder.menu_on_left_click(menu_on_left_click);
}
if let Some(show_menu_on_left_click) = options.show_menu_on_left_click {
builder = builder.show_menu_on_left_click(show_menu_on_left_click);
}
let tray = builder.build(&webview)?;
let id = tray.id().as_ref().to_string();

View File

@ -48,7 +48,7 @@ pub fn create_tray<R: Runtime>(app: &tauri::AppHandle<R>) -> tauri::Result<()> {
.tooltip("Tauri")
.icon(app.default_window_icon().unwrap().clone())
.menu(&menu1)
.menu_on_left_click(false)
.show_menu_on_left_click(false)
.on_menu_event(move |app, event| match event.id.as_ref() {
"quit" => {
app.exit(0);

View File

@ -113,8 +113,26 @@ export interface TrayIconOptions {
* Use the icon as a [template](https://developer.apple.com/documentation/appkit/nsimage/1520017-template?language=objc). **macOS only**.
*/
iconAsTemplate?: boolean
/** Whether to show the tray menu on left click or not, default is `true`. **macOS & Windows only**. */
/**
* Whether to show the tray menu on left click or not, default is `true`.
*
* #### Platform-specific:
*
* - **Linux**: Unsupported.
*
* @deprecated use {@linkcode TrayIconOptions.showMenuOnLeftClick} instead.
*/
menuOnLeftClick?: boolean
/**
* Whether to show the tray menu on left click or not, default is `true`.
*
* #### Platform-specific:
*
* - **Linux**: Unsupported.
*
* @since 2.2.0
*/
showMenuOnLeftClick?: boolean
/** A handler for an event on the tray icon. */
action?: (event: TrayIconEvent) => void
}
@ -278,13 +296,37 @@ export class TrayIcon extends Resource {
})
}
/** Disable or enable showing the tray menu on left click. **macOS & Windows only**. */
/**
* Disable or enable showing the tray menu on left click.
*
* #### Platform-specific:
*
* - **Linux**: Unsupported.
*
* @deprecated use {@linkcode TrayIcon.setShowMenuOnLeftClick} instead.
*/
async setMenuOnLeftClick(onLeft: boolean): Promise<void> {
return invoke('plugin:tray|set_show_menu_on_left_click', {
rid: this.rid,
onLeft
})
}
/**
* Disable or enable showing the tray menu on left click.
*
* #### Platform-specific:
*
* - **Linux**: Unsupported.
*
* @since 2.2.0
*/
async setShowMenuOnLeftClick(onLeft: boolean): Promise<void> {
return invoke('plugin:tray|set_show_menu_on_left_click', {
rid: this.rid,
onLeft
})
}
}
function mapEvent(e: RustTrayIconEvent): TrayIconEvent {