>(&self, path: Option) {
+ #[cfg(target_os = "linux")]
+ self.tray.borrow_mut().set_temp_dir_path(path);
+ #[cfg(not(target_os = "linux"))]
+ let _ = path;
+ }
+
+ /// Set 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, is_template: bool) {
+ #[cfg(target_os = "macos")]
+ self.tray.borrow_mut().set_icon_as_template(is_template);
+ #[cfg(not(target_os = "macos"))]
+ let _ = is_template;
+ }
+
+ pub fn set_icon_with_as_template(&self, icon: Option, is_template: bool) -> Result<()> {
+ #[cfg(target_os = "macos")]
+ return self
+ .tray
+ .borrow_mut()
+ .set_icon_with_as_template(icon, is_template);
+ #[cfg(not(target_os = "macos"))]
+ {
+ let _ = icon;
+ let _ = is_template;
+ Ok(())
+ }
+ }
+
+ /// Disable or enable showing the tray menu on left click.
+ ///
+ /// ## Platform-specific:
+ ///
+ /// - **Linux:** Unsupported.
+ pub fn set_show_menu_on_left_click(&self, enable: bool) {
+ #[cfg(any(target_os = "macos", target_os = "windows"))]
+ self.tray.borrow_mut().set_show_menu_on_left_click(enable);
+ #[cfg(not(any(target_os = "macos", target_os = "windows")))]
+ let _ = enable;
+ }
+
+ /// Get tray icon rect.
+ ///
+ /// ## Platform-specific:
+ ///
+ /// - **Linux**: Unsupported.
+ pub fn rect(&self) -> Option {
+ self.tray.borrow().rect()
+ }
+
+ /// Get the tray icon's underlying [window handle](windows_sys::Win32::Foundation::HWND) **Windows only**.
+ ///
+ /// This window handle is valid as long as the tray icon.
+ #[cfg(windows)]
+ pub fn window_handle(&self) -> windows_sys::Win32::Foundation::HWND {
+ self.tray.borrow().hwnd()
+ }
+
+ /// Get the tray icon's underlying [NSStatusItem](objc2_app_kit::NSStatusItem) **macOS only**.
+ ///
+ /// Returns `None` if the status item is not available.
+ #[cfg(target_os = "macos")]
+ pub fn ns_status_item(&self) -> Option> {
+ self.tray.borrow().ns_status_item().cloned()
+ }
+
+ /// Get the tray icon's underlying [AppIndicator](libappindicator::AppIndicator) **Linux only**.
+ ///
+ /// # Safety
+ ///
+ /// The returned pointer is valid as long as the `TrayIcon` is.
+ #[cfg(all(unix, not(target_os = "macos")))]
+ pub unsafe fn app_indicator(&self) -> *const libappindicator::AppIndicator {
+ self.tray.borrow().app_indicator() as *const _
+ }
+}
+
+/// Describes a tray icon event.
+///
+/// ## Platform-specific:
+///
+/// - **Linux**: Unsupported. The event is not emmited even though the icon is shown
+/// and will still show a context menu on right click.
+#[derive(Debug, Clone)]
+#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
+#[cfg_attr(feature = "serde", serde(tag = "type"))]
+#[non_exhaustive]
+pub enum TrayIconEvent {
+ /// A click happened on the tray icon.
+ #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
+ Click {
+ /// Id of the tray icon which triggered this event.
+ id: TrayIconId,
+ /// Physical Position of this event.
+ position: dpi::PhysicalPosition,
+ /// Position and size of the tray icon.
+ rect: Rect,
+ /// Mouse button that triggered this event.
+ button: MouseButton,
+ /// Mouse button state when this event was triggered.
+ button_state: MouseButtonState,
+ },
+ /// A double click happened on the tray icon. **Windows Only**
+ DoubleClick {
+ /// Id of the tray icon which triggered this event.
+ id: TrayIconId,
+ /// Physical Position of this event.
+ position: dpi::PhysicalPosition,
+ /// Position and size of the tray icon.
+ rect: Rect,
+ /// Mouse button that triggered this event.
+ button: MouseButton,
+ },
+ /// The mouse entered the tray icon region.
+ Enter {
+ /// Id of the tray icon which triggered this event.
+ id: TrayIconId,
+ /// Physical Position of this event.
+ position: dpi::PhysicalPosition,
+ /// Position and size of the tray icon.
+ rect: Rect,
+ },
+ /// The mouse moved over the tray icon region.
+ Move {
+ /// Id of the tray icon which triggered this event.
+ id: TrayIconId,
+ /// Physical Position of this event.
+ position: dpi::PhysicalPosition,
+ /// Position and size of the tray icon.
+ rect: Rect,
+ },
+ /// The mouse left the tray icon region.
+ Leave {
+ /// Id of the tray icon which triggered this event.
+ id: TrayIconId,
+ /// Physical Position of this event.
+ position: dpi::PhysicalPosition,
+ /// Position and size of the tray icon.
+ rect: Rect,
+ },
+}
+
+/// Describes the mouse button state.
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
+#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
+#[derive(Default)]
+pub enum MouseButtonState {
+ #[default]
+ Up,
+ Down,
+}
+
+/// Describes which mouse button triggered the event..
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
+#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
+#[derive(Default)]
+pub enum MouseButton {
+ #[default]
+ Left,
+ Right,
+ Middle,
+}
+
+/// Describes a rectangle including position (x - y axis) and size.
+#[derive(Debug, PartialEq, Clone, Copy)]
+#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
+pub struct Rect {
+ pub size: dpi::PhysicalSize,
+ pub position: dpi::PhysicalPosition,
+}
+
+impl Default for Rect {
+ fn default() -> Self {
+ Self {
+ size: dpi::PhysicalSize::new(0, 0),
+ position: dpi::PhysicalPosition::new(0., 0.),
+ }
+ }
+}
+
+/// A reciever that could be used to listen to tray events.
+pub type TrayIconEventReceiver = Receiver;
+type TrayIconEventHandler = Box;
+
+static TRAY_CHANNEL: Lazy<(Sender, TrayIconEventReceiver)> = Lazy::new(unbounded);
+static TRAY_EVENT_HANDLER: OnceCell