mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-10-26 18:12:23 +03:00
feat(api/tray): add TrayIcon.getById/removeById
(#9155)
* feat(api/tray): add `TrayIcon.getById/removeById` closes #9135 * generate * add permissions --------- Co-authored-by: Lucas Nogueira <lucas@tauri.app>
This commit is contained in:
parent
e227fe02f9
commit
acdd76833d
5
.changes/api-tray-by-id.md
Normal file
5
.changes/api-tray-by-id.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'@tauri-apps/api': 'patch:feat'
|
||||||
|
---
|
||||||
|
|
||||||
|
Add `TrayIcon.getById` and `TrayIcon.removeById` static methods.
|
5
.changes/core-app-tray-remove-tray-apis-removed.md
Normal file
5
.changes/core-app-tray-remove-tray-apis-removed.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'tauri': 'patch:breaking'
|
||||||
|
---
|
||||||
|
|
||||||
|
Removed `App/AppHandle::tray` and `App/AppHandle::remove_tray`, use `App/AppHandle::tray_by_id` and `App/AppHandle::remove_tray_by_id` instead. If these APIs were used to access tray icon configured in `tauri.conf.json`, you can use `App/AppHandle::tray_by_id` with ID `main` or the configured value.
|
@ -180,6 +180,8 @@ const PLUGINS: &[(&str, &[(&str, bool)])] = &[
|
|||||||
"tray",
|
"tray",
|
||||||
&[
|
&[
|
||||||
("new", false),
|
("new", false),
|
||||||
|
("get_by_id", false),
|
||||||
|
("remove_by_id", false),
|
||||||
("set_icon", false),
|
("set_icon", false),
|
||||||
("set_menu", false),
|
("set_menu", false),
|
||||||
("set_tooltip", false),
|
("set_tooltip", false),
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
| Permission | Description |
|
| Permission | Description |
|
||||||
|------|-----|
|
|------|-----|
|
||||||
|
|`allow-get-by-id`|Enables the get_by_id command without any pre-configured scope.|
|
||||||
|
|`deny-get-by-id`|Denies the get_by_id command without any pre-configured scope.|
|
||||||
|`allow-new`|Enables the new command without any pre-configured scope.|
|
|`allow-new`|Enables the new command without any pre-configured scope.|
|
||||||
|`deny-new`|Denies the new command without any pre-configured scope.|
|
|`deny-new`|Denies the new command without any pre-configured scope.|
|
||||||
|
|`allow-remove-by-id`|Enables the remove_by_id command without any pre-configured scope.|
|
||||||
|
|`deny-remove-by-id`|Denies the remove_by_id command without any pre-configured scope.|
|
||||||
|`allow-set-icon`|Enables the set_icon command without any pre-configured scope.|
|
|`allow-set-icon`|Enables the set_icon command without any pre-configured scope.|
|
||||||
|`deny-set-icon`|Denies the set_icon command without any pre-configured scope.|
|
|`deny-set-icon`|Denies the set_icon command without any pre-configured scope.|
|
||||||
|`allow-set-icon-as-template`|Enables the set_icon_as_template command without any pre-configured scope.|
|
|`allow-set-icon-as-template`|Enables the set_icon_as_template command without any pre-configured scope.|
|
||||||
|
File diff suppressed because one or more lines are too long
@ -509,13 +509,7 @@ macro_rules! shared_app_impl {
|
|||||||
&self,
|
&self,
|
||||||
handler: F,
|
handler: F,
|
||||||
) {
|
) {
|
||||||
self
|
self.manager.menu.on_menu_event(handler)
|
||||||
.manager
|
|
||||||
.menu
|
|
||||||
.global_event_listeners
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.push(Box::new(handler));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Registers a global tray icon menu event listener.
|
/// Registers a global tray icon menu event listener.
|
||||||
@ -525,35 +519,7 @@ macro_rules! shared_app_impl {
|
|||||||
&self,
|
&self,
|
||||||
handler: F,
|
handler: F,
|
||||||
) {
|
) {
|
||||||
self
|
self.manager.tray.on_tray_icon_event(handler)
|
||||||
.manager
|
|
||||||
.tray
|
|
||||||
.global_event_listeners
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.push(Box::new(handler));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets the first tray icon registered,
|
|
||||||
/// usually the one configured in the Tauri configuration file.
|
|
||||||
#[cfg(all(desktop, feature = "tray-icon"))]
|
|
||||||
#[cfg_attr(docsrs, doc(cfg(all(desktop, feature = "tray-icon"))))]
|
|
||||||
pub fn tray(&self) -> Option<TrayIcon<R>> {
|
|
||||||
self.manager.tray.icons.lock().unwrap().first().cloned()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Removes the first tray icon registered, usually the one configured in
|
|
||||||
/// tauri config file, from tauri's internal state and returns it.
|
|
||||||
///
|
|
||||||
/// Note that dropping the returned icon, will cause the tray icon to disappear.
|
|
||||||
#[cfg(all(desktop, feature = "tray-icon"))]
|
|
||||||
#[cfg_attr(docsrs, doc(cfg(all(desktop, feature = "tray-icon"))))]
|
|
||||||
pub fn remove_tray(&self) -> Option<TrayIcon<R>> {
|
|
||||||
let mut icons = self.manager.tray.icons.lock().unwrap();
|
|
||||||
if !icons.is_empty() {
|
|
||||||
return Some(icons.swap_remove(0));
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a tray icon using the provided id.
|
/// Gets a tray icon using the provided id.
|
||||||
@ -564,20 +530,13 @@ macro_rules! shared_app_impl {
|
|||||||
I: ?Sized,
|
I: ?Sized,
|
||||||
TrayIconId: PartialEq<&'a I>,
|
TrayIconId: PartialEq<&'a I>,
|
||||||
{
|
{
|
||||||
self
|
self.manager.tray.tray_by_id(id)
|
||||||
.manager
|
|
||||||
.tray
|
|
||||||
.icons
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.iter()
|
|
||||||
.find(|t| t.id() == &id)
|
|
||||||
.cloned()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes a tray icon using the provided id from tauri's internal state and returns it.
|
/// Removes a tray icon using the provided id from tauri's internal state and returns it.
|
||||||
///
|
///
|
||||||
/// Note that dropping the returned icon, will cause the tray icon to disappear.
|
/// Note that dropping the returned icon, may cause the tray icon to disappear
|
||||||
|
/// if it wasn't cloned somewhere else or referenced by JS.
|
||||||
#[cfg(all(desktop, feature = "tray-icon"))]
|
#[cfg(all(desktop, feature = "tray-icon"))]
|
||||||
#[cfg_attr(docsrs, doc(cfg(all(desktop, feature = "tray-icon"))))]
|
#[cfg_attr(docsrs, doc(cfg(all(desktop, feature = "tray-icon"))))]
|
||||||
pub fn remove_tray_by_id<'a, I>(&self, id: &'a I) -> Option<TrayIcon<R>>
|
pub fn remove_tray_by_id<'a, I>(&self, id: &'a I) -> Option<TrayIcon<R>>
|
||||||
@ -585,12 +544,7 @@ macro_rules! shared_app_impl {
|
|||||||
I: ?Sized,
|
I: ?Sized,
|
||||||
TrayIconId: PartialEq<&'a I>,
|
TrayIconId: PartialEq<&'a I>,
|
||||||
{
|
{
|
||||||
let mut icons = self.manager.tray.icons.lock().unwrap();
|
self.manager.tray.remove_tray_by_id(id)
|
||||||
let idx = icons.iter().position(|t| t.id() == &id);
|
|
||||||
if let Some(idx) = idx {
|
|
||||||
return Some(icons.swap_remove(idx));
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the app's configuration, defined on the `tauri.conf.json` file.
|
/// Gets the app's configuration, defined on the `tauri.conf.json` file.
|
||||||
|
@ -8,7 +8,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
menu::{Menu, MenuId},
|
menu::{Menu, MenuEvent, MenuId},
|
||||||
AppHandle, Runtime, Window,
|
AppHandle, Runtime, Window,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -87,4 +87,12 @@ impl<R: Runtime> MenuManager<R> {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn on_menu_event<F: Fn(&AppHandle<R>, MenuEvent) + Send + Sync + 'static>(&self, handler: F) {
|
||||||
|
self
|
||||||
|
.global_event_listeners
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.push(Box::new(handler));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ use std::{collections::HashMap, fmt, sync::Mutex};
|
|||||||
use crate::{
|
use crate::{
|
||||||
app::GlobalTrayIconEventListener,
|
app::GlobalTrayIconEventListener,
|
||||||
image::Image,
|
image::Image,
|
||||||
tray::{TrayIcon, TrayIconId},
|
tray::{TrayIcon, TrayIconEvent, TrayIconId},
|
||||||
AppHandle, Runtime,
|
AppHandle, Runtime,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -28,3 +28,43 @@ impl<R: Runtime> fmt::Debug for TrayManager<R> {
|
|||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<R: Runtime> TrayManager<R> {
|
||||||
|
pub fn on_tray_icon_event<F: Fn(&AppHandle<R>, TrayIconEvent) + Send + Sync + 'static>(
|
||||||
|
&self,
|
||||||
|
handler: F,
|
||||||
|
) {
|
||||||
|
self
|
||||||
|
.global_event_listeners
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.push(Box::new(handler));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tray_by_id<'a, I>(&self, id: &'a I) -> Option<TrayIcon<R>>
|
||||||
|
where
|
||||||
|
I: ?Sized,
|
||||||
|
TrayIconId: PartialEq<&'a I>,
|
||||||
|
{
|
||||||
|
self
|
||||||
|
.icons
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.iter()
|
||||||
|
.find(|t| t.id() == &id)
|
||||||
|
.cloned()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_tray_by_id<'a, I>(&self, id: &'a I) -> Option<TrayIcon<R>>
|
||||||
|
where
|
||||||
|
I: ?Sized,
|
||||||
|
TrayIconId: PartialEq<&'a I>,
|
||||||
|
{
|
||||||
|
let mut icons = self.icons.lock().unwrap();
|
||||||
|
let idx = icons.iter().position(|t| t.id() == &id);
|
||||||
|
if let Some(idx) = idx {
|
||||||
|
return Some(icons.swap_remove(idx));
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -89,6 +89,25 @@ fn new<R: Runtime>(
|
|||||||
Ok((rid, id))
|
Ok((rid, id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[command(root = "crate")]
|
||||||
|
fn get_by_id<R: Runtime>(app: AppHandle<R>, id: &str) -> crate::Result<Option<ResourceId>> {
|
||||||
|
let tray = app.tray_by_id(id);
|
||||||
|
let maybe_rid = tray.map(|tray| {
|
||||||
|
let mut resources_table = app.resources_table();
|
||||||
|
resources_table.add(tray)
|
||||||
|
});
|
||||||
|
Ok(maybe_rid)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[command(root = "crate")]
|
||||||
|
fn remove_by_id<R: Runtime>(app: AppHandle<R>, id: &str) -> crate::Result<()> {
|
||||||
|
app
|
||||||
|
.remove_tray_by_id(id)
|
||||||
|
.ok_or_else(|| anyhow::anyhow!("Can't find a tray associated with this id: {id}"))
|
||||||
|
.map(|_| ())
|
||||||
|
.map_err(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
#[command(root = "crate")]
|
#[command(root = "crate")]
|
||||||
fn set_icon<R: Runtime>(
|
fn set_icon<R: Runtime>(
|
||||||
app: AppHandle<R>,
|
app: AppHandle<R>,
|
||||||
@ -196,6 +215,8 @@ pub(crate) fn init<R: Runtime>() -> TauriPlugin<R> {
|
|||||||
Builder::new("tray")
|
Builder::new("tray")
|
||||||
.invoke_handler(crate::generate_handler![
|
.invoke_handler(crate::generate_handler![
|
||||||
new,
|
new,
|
||||||
|
get_by_id,
|
||||||
|
remove_by_id,
|
||||||
set_icon,
|
set_icon,
|
||||||
set_menu,
|
set_menu,
|
||||||
set_tooltip,
|
set_tooltip,
|
||||||
|
@ -119,6 +119,23 @@ export class TrayIcon extends Resource {
|
|||||||
this.id = id
|
this.id = id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Gets a tray icon using the provided id. */
|
||||||
|
static async getById(id: string): Promise<TrayIcon | null> {
|
||||||
|
return invoke<number>('plugin:tray|get_by_id', { id }).then((rid) =>
|
||||||
|
rid ? new TrayIcon(rid, id) : null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a tray icon using the provided id from tauri's internal state.
|
||||||
|
*
|
||||||
|
* Note that this may cause the tray icon to disappear
|
||||||
|
* if it wasn't cloned somewhere else or referenced by JS.
|
||||||
|
*/
|
||||||
|
static async removeById(id: string): Promise<void> {
|
||||||
|
return invoke('plugin:tray|remove_by_id', { id })
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@linkcode TrayIcon}
|
* Creates a new {@linkcode TrayIcon}
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user