Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Implement Badging API #11661

Open
wants to merge 13 commits into
base: dev
Choose a base branch
from
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
11 changes: 11 additions & 0 deletions .changes/overlay.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"tauri": minor:feat
"tauri-runtime-wry": minor:feat
"tauri-runtime": minor:feat
'@tauri-apps/api': minor:feat
---

Add badging APIs:
- `Window/WebviewWindow::set_badge_count` for Linux, macOS and IOS.
- `Window/WebviewWindow::set_overlay_icon` for Windows Only.
- `Window/WebviewWindow::set_badge_label`for macOS Only.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/tauri-runtime-wry/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ wry = { version = "0.47", default-features = false, features = [
"os-webview",
"linux-body",
] }
tao = { version = "0.30.6", default-features = false, features = ["rwh_06"] }
tao = { version = "0.30.8", default-features = false, features = ["rwh_06"] }
tauri-runtime = { version = "2.2.0", path = "../tauri-runtime" }
tauri-utils = { version = "2.1.0", path = "../tauri-utils" }
raw-window-handle = "0.6"
Expand Down
58 changes: 57 additions & 1 deletion crates/tauri-runtime-wry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ use wry::{
)))]
use wry::{WebViewBuilderExtUnix, WebViewExtUnix};

#[cfg(target_os = "ios")]
pub use tao::platform::ios::WindowExtIOS;
#[cfg(target_os = "macos")]
pub use tao::platform::macos::{
ActivationPolicy as TaoActivationPolicy, EventLoopExtMacOS, WindowExtMacOS,
Expand Down Expand Up @@ -1263,6 +1265,9 @@ pub enum WindowMessage {
SetCursorIcon(CursorIcon),
SetCursorPosition(Position),
SetIgnoreCursorEvents(bool),
SetBadgeCount(Option<i64>, Option<String>),
SetBadgeLabel(Option<String>),
SetOverlayIcon(Option<TaoIcon>),
SetProgressBar(ProgressBarState),
SetTitleBarStyle(tauri_utils::TitleBarStyle),
SetTheme(Option<Theme>),
Expand Down Expand Up @@ -2125,6 +2130,32 @@ impl<T: UserEvent> WindowDispatch<T> for WryWindowDispatcher<T> {
)
}

fn set_badge_count(&self, count: Option<i64>, desktop_filename: Option<String>) -> Result<()> {
send_user_message(
&self.context,
Message::Window(
self.window_id,
WindowMessage::SetBadgeCount(count, desktop_filename),
),
)
}

fn set_badge_label(&self, label: Option<String>) -> Result<()> {
send_user_message(
&self.context,
Message::Window(self.window_id, WindowMessage::SetBadgeLabel(label)),
)
}

fn set_overlay_icon(&self, icon: Option<Icon>) -> Result<()> {
let icon: Result<Option<TaoIcon>> = icon.map_or(Ok(None), |x| Ok(Some(TaoIcon::try_from(x)?)));

send_user_message(
&self.context,
Message::Window(self.window_id, WindowMessage::SetOverlayIcon(icon?)),
)
}

fn set_progress_bar(&self, progress_state: ProgressBarState) -> Result<()> {
send_user_message(
&self.context,
Expand Down Expand Up @@ -3096,6 +3127,32 @@ fn handle_user_message<T: UserEvent>(
WindowMessage::RequestRedraw => {
window.request_redraw();
}
WindowMessage::SetBadgeCount(_count, _desktop_filename) => {
#[cfg(target_os = "ios")]
window.set_badge_count(
_count.map_or(0, |x| x.clamp(i32::MIN as i64, i32::MAX as i64) as i32),
amrbashir marked this conversation as resolved.
Show resolved Hide resolved
);

#[cfg(target_os = "macos")]
window.set_badge_label(_count.map(|x| x.to_string()));

#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
))]
window.set_badge_count(_count, _desktop_filename);
}
WindowMessage::SetBadgeLabel(_label) => {
#[cfg(target_os = "macos")]
window.set_badge_label(_label);
}
WindowMessage::SetOverlayIcon(_icon) => {
#[cfg(windows)]
window.set_overlay_icon(_icon.map(|x| x.0).as_ref());
}
WindowMessage::SetProgressBar(progress_state) => {
window.set_progress_bar(ProgressBarStateWrapper::from(progress_state).0);
}
Expand Down Expand Up @@ -3431,7 +3488,6 @@ fn handle_user_message<T: UserEvent>(
}
#[cfg(target_os = "ios")]
{
use tao::platform::ios::WindowExtIOS;
use wry::WebViewExtIOS;

f(Webview {
Expand Down
20 changes: 20 additions & 0 deletions crates/tauri-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,26 @@ pub trait WindowDispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 's
/// Starts resize-dragging the window.
fn start_resize_dragging(&self, direction: ResizeDirection) -> Result<()>;

/// Sets the badge count on the taskbar
/// The badge count appears as a whole for the application
/// Setting the count to `0``will remove the badge
///
/// ## Platform-specific
/// - **Windows:** Unsupported, use [`WindowDispatch::set_overlay_icon`] instead.
/// - **Android:** Unsupported.
/// - **iOS:** iOS expects i32, if the value is larger than i32::MAX, it will be clamped to i32::MAX.
fn set_badge_count(&self, count: Option<i64>, desktop_filename: Option<String>) -> Result<()>;

/// Sets the badge count on the taskbar (macOS only)
/// Setting the label to None will remove the badge
fn set_badge_label(&self, label: Option<String>) -> Result<()>;

/// Sets the overlay icon on the taskbar (Windows only)
/// Setting the icon to None will remove the overlay icon
///
/// The overlay icon can be unique for each window.
fn set_overlay_icon(&self, icon: Option<Icon>) -> Result<()>;

/// Sets the taskbar progress state.
///
/// ## Platform-specific
Expand Down
3 changes: 3 additions & 0 deletions crates/tauri/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ const PLUGINS: &[(&str, &[(&str, bool)])] = &[
("start_dragging", false),
("start_resize_dragging", false),
("set_progress_bar", false),
("set_badge_count", false),
("set_overlay_icon", false),
("set_badge_label", false),
("set_icon", false),
("set_title_bar_style", false),
("set_theme", false),
Expand Down
78 changes: 78 additions & 0 deletions crates/tauri/permissions/window/autogenerated/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -898,6 +898,58 @@ Denies the set_always_on_top command without any pre-configured scope.
<tr>
<td>

`core:window:allow-set-badge-count`

</td>
<td>

Enables the set_badge_count command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`core:window:deny-set-badge-count`

</td>
<td>

Denies the set_badge_count command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`core:window:allow-set-badge-label`

</td>
<td>

Enables the set_badge_label command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`core:window:deny-set-badge-label`

</td>
<td>

Denies the set_badge_label command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`core:window:allow-set-closable`

</td>
Expand Down Expand Up @@ -1340,6 +1392,32 @@ Denies the set_minimizable command without any pre-configured scope.
<tr>
<td>

`core:window:allow-set-overlay-icon`

</td>
<td>

Enables the set_overlay_icon command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`core:window:deny-set-overlay-icon`

</td>
<td>

Denies the set_overlay_icon command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`core:window:allow-set-position`

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

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions crates/tauri/src/test/mock_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -977,6 +977,18 @@ impl<T: UserEvent> WindowDispatch<T> for MockWindowDispatcher {
Ok(())
}

fn set_badge_count(&self, count: Option<i64>, desktop_filename: Option<String>) -> Result<()> {
Ok(())
}

fn set_badge_label(&self, label: Option<String>) -> Result<()> {
Ok(())
}

fn set_overlay_icon(&self, icon: Option<Icon<'_>>) -> Result<()> {
Ok(())
}

fn set_title_bar_style(&self, style: tauri_utils::TitleBarStyle) -> Result<()> {
Ok(())
}
Expand Down
29 changes: 29 additions & 0 deletions crates/tauri/src/webview/webview_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1716,6 +1716,35 @@ impl<R: Runtime> WebviewWindow<R> {
self.window.start_dragging()
}

/// Sets the overlay icon on the taskbar **Windows only**
/// Setting the icon to None will remove the overlay icon
///
/// The overlay icon can be unique for each window.
#[cfg(target_os = "windows")]
#[cfg_attr(docsrs, doc(cfg(target_os = "windows")))]
pub fn set_overlay_icon(&self, icon: Option<Image<'_>>) -> crate::Result<()> {
ahqsoftwares marked this conversation as resolved.
Show resolved Hide resolved
self.window.set_overlay_icon(icon)
}

/// Sets the taskbar badge count
/// Setting the count to `0``will remove the badge
///
/// ## Platform-specific
/// - **Windows:** Unsupported, use [`WebviewWindow::set_overlay_icon`] instead.
/// - **iOS:** iOS expects i32, the value will be clamped to i32::MIN, i32::MAX.
/// - **Android:** Unsupported.
pub fn set_badge_count(&self, count: Option<i64>) -> crate::Result<()> {
self.window.set_badge_count(count)
}

/// Sets the taskbar badge label **macOS only**
/// Setting the label to `0``will remove the badge
#[cfg(target_os = "macos")]
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
pub fn set_badge_label(&self, label: Option<String>) -> crate::Result<()> {
ahqsoftwares marked this conversation as resolved.
Show resolved Hide resolved
self.window.set_badge_label(label)
}

/// Sets the taskbar progress state.
///
/// ## Platform-specific
Expand Down
41 changes: 41 additions & 0 deletions crates/tauri/src/window/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2014,6 +2014,47 @@ tauri::Builder::default()
.map_err(Into::into)
}

/// Sets the overlay icon on the taskbar **Windows only**
/// Setting the icon to None will remove the overlay icon
///
/// The overlay icon can be unique for each window.
#[cfg(target_os = "windows")]
#[cfg_attr(docsrs, doc(cfg(target_os = "windows")))]
pub fn set_overlay_icon(&self, icon: Option<Image<'_>>) -> crate::Result<()> {
self
.window
.dispatcher
.set_overlay_icon(icon.map(|x| x.into()))
.map_err(Into::into)
}

/// Sets the taskbar badge count
/// Setting the count to `0``will remove the badge
///
/// ## Platform-specific
/// - **Windows:** Unsupported, use [`Window::set_overlay_icon`] instead.
/// - **iOS:** iOS expects i32, the value will be clamped to i32::MIN, i32::MAX.
/// - **Android:** Unsupported.
#[cfg(target_os = "macos")]
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
Comment on lines +2038 to +2039
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be on set_badge_label, right?

pub fn set_badge_count(&self, count: Option<i64>) -> crate::Result<()> {
self
.window
.dispatcher
.set_badge_count(count, Some(format!("{}.desktop", self.package_info().name)))
.map_err(Into::into)
}

/// Sets the taskbar badge label **macOS only**
/// Setting the label to `0``will remove the badge
pub fn set_badge_label(&self, label: Option<String>) -> crate::Result<()> {
self
.window
.dispatcher
.set_badge_label(label)
.map_err(Into::into)
}

/// Sets the taskbar progress state.
///
/// ## Platform-specific
Expand Down
Loading
Loading