Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changes/changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'tauri': 'patch:feat'
---

Add macos support for setting the icon and icon template state in the same step of the main thread, to prevent flickering.
1 change: 1 addition & 0 deletions crates/tauri/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ const PLUGINS: &[(&str, &[(&str, bool)])] = &[
("set_visible", true),
("set_temp_dir_path", true),
("set_icon_as_template", true),
("set_icon_with_as_template", true),
("set_show_menu_on_left_click", true),
],
),
Expand Down
27 changes: 27 additions & 0 deletions crates/tauri/permissions/tray/autogenerated/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Default permissions for the plugin, which enables all commands.
- `allow-set-visible`
- `allow-set-temp-dir-path`
- `allow-set-icon-as-template`
- `allow-set-icon-with-as-template`
- `allow-set-show-menu-on-left-click`

## Permission Table
Expand Down Expand Up @@ -158,6 +159,32 @@ Denies the set_icon_as_template command without any pre-configured scope.
<tr>
<td>

`core:tray:allow-set-icon-with-as-template`

</td>
<td>

Enables the set_icon_with_as_template command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`core:tray:deny-set-icon-with-as-template`

</td>
<td>

Denies the set_icon_with_as_template command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`core:tray:allow-set-menu`

</td>
Expand Down
2 changes: 1 addition & 1 deletion crates/tauri/scripts/bundle.global.js

Large diffs are not rendered by default.

32 changes: 32 additions & 0 deletions crates/tauri/src/tray/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,38 @@ impl<R: Runtime> TrayIcon<R> {
Ok(())
}

/// Sets the tray icon and template status atomically. **macOS only**.
///
/// On macOS, calling `set_icon` followed by `set_icon_as_template` causes a visible
/// flicker as the icon is rendered twice. This method sets both atomically to prevent that.
///
/// ## Platform-specific:
///
/// - **Linux / Windows:** Falls back to calling `set_icon`.
pub fn set_icon_with_as_template(
&self,
icon: Option<Image<'_>>,
#[allow(unused)] is_template: bool,
) -> crate::Result<()> {
#[cfg(target_os = "macos")]
{
let tray_icon = match icon {
Some(i) => Some(i.try_into()?),
None => None,
};
run_item_main_thread!(self, |self_: Self| {
self_
.inner
.set_icon_with_as_template(tray_icon, is_template)
})??;
}
#[cfg(not(target_os = "macos"))]
{
self.set_icon(icon)?;
}
Ok(())
}

/// Disable or enable showing the tray menu on left click.
///
///
Expand Down
19 changes: 19 additions & 0 deletions crates/tauri/src/tray/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,24 @@ fn set_icon_as_template<R: Runtime>(
tray.set_icon_as_template(as_template)
}

#[command(root = "crate")]
fn set_icon_with_as_template<R: Runtime>(
app: AppHandle<R>,
webview: Webview<R>,
rid: ResourceId,
icon: Option<JsImage>,
as_template: bool,
) -> crate::Result<()> {
let resources_table = app.resources_table();
let tray = resources_table.get::<TrayIcon<R>>(rid)?;
let webview_resources_table = webview.resources_table();
let icon = match icon {
Some(i) => Some(i.into_img(&webview_resources_table)?.as_ref().clone()),
None => None,
};
tray.set_icon_with_as_template(icon, as_template)
}

#[command(root = "crate")]
fn set_show_menu_on_left_click<R: Runtime>(
app: AppHandle<R>,
Expand All @@ -228,6 +246,7 @@ pub(crate) fn init<R: Runtime>() -> TauriPlugin<R> {
set_visible,
set_temp_dir_path,
set_icon_as_template,
set_icon_with_as_template,
set_show_menu_on_left_click,
])
.build()
Expand Down
25 changes: 25 additions & 0 deletions packages/api/src/tray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,31 @@ export class TrayIcon extends Resource {
})
}

/**
* Sets a new tray icon and template status atomically. **macOS only**.
*
* Note that you may need the `image-ico` or `image-png` Cargo features to use this API.
* To enable it, change your Cargo.toml file:
* ```toml
* [dependencies]
* tauri = { version = "...", features = ["...", "image-png"] }
* ```
*/
async setIconWithAsTemplate(
icon: string | Image | Uint8Array | ArrayBuffer | number[] | null,
asTemplate: boolean
): Promise<void> {
let trayIcon = null
if (icon) {
trayIcon = transformImage(icon)
}
return invoke('plugin:tray|set_icon_with_as_template', {
rid: this.rid,
icon: trayIcon,
asTemplate
})
}

/**
* Disable or enable showing the tray menu on left click.
*
Expand Down
Loading