Skip to content
Merged
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
7 changes: 7 additions & 0 deletions .changes/feat-dock-visibility-on-macos.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
tauri: patch:feat
tauri-runtime: patch:feat
tauri-runtime-wry: patch:feat
---

MacOS: Add `set_dock_visibility` method to support setting the visibility of the application in the dock.
6 changes: 6 additions & 0 deletions .changes/setDockVisibility.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@tauri-apps/api": minor:feat
---

Added `app.setDockVisibility` for macOS.

14 changes: 14 additions & 0 deletions crates/tauri-runtime-wry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1363,6 +1363,8 @@ pub enum Message<T: 'static> {
Task(Box<dyn FnOnce() + Send>),
#[cfg(target_os = "macos")]
SetActivationPolicy(ActivationPolicy),
#[cfg(target_os = "macos")]
SetDockVisibility(bool),
RequestExit(i32),
Application(ApplicationMessage),
Window(WindowId, WindowMessage),
Expand Down Expand Up @@ -2435,6 +2437,11 @@ impl<T: UserEvent> RuntimeHandle<T> for WryHandle<T> {
)
}

#[cfg(target_os = "macos")]
fn set_dock_visibility(&self, visible: bool) -> Result<()> {
send_user_message(&self.context, Message::SetDockVisibility(visible))
}

fn request_exit(&self, code: i32) -> Result<()> {
// NOTE: request_exit cannot use the `send_user_message` function because it accesses the event loop callback
self
Expand Down Expand Up @@ -2844,6 +2851,11 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
.set_activation_policy(tao_activation_policy(activation_policy));
}

#[cfg(target_os = "macos")]
fn set_dock_visibility(&mut self, visible: bool) {
self.event_loop.set_dock_visibility(visible);
}

#[cfg(target_os = "macos")]
fn show(&self) {
self.event_loop.show_application();
Expand Down Expand Up @@ -3018,6 +3030,8 @@ fn handle_user_message<T: UserEvent>(
Message::SetActivationPolicy(activation_policy) => {
event_loop.set_activation_policy_at_runtime(tao_activation_policy(activation_policy))
}
#[cfg(target_os = "macos")]
Message::SetDockVisibility(visible) => event_loop.set_dock_visibility(visible),
Message::RequestExit(_code) => panic!("cannot handle RequestExit on the main thread"),
Message::Application(application_message) => match application_message {
#[cfg(target_os = "macos")]
Expand Down
12 changes: 12 additions & 0 deletions crates/tauri-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,12 @@ pub trait RuntimeHandle<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'st
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
fn set_activation_policy(&self, activation_policy: ActivationPolicy) -> Result<()>;

/// Sets the dock visibility for the application.
///
#[cfg(target_os = "macos")]
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
fn set_dock_visibility(&self, visible: bool) -> Result<()>;

/// Requests an exit of the event loop.
fn request_exit(&self, code: i32) -> Result<()>;

Expand Down Expand Up @@ -431,6 +437,12 @@ pub trait Runtime<T: UserEvent>: Debug + Sized + 'static {
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
fn set_activation_policy(&mut self, activation_policy: ActivationPolicy);

/// Sets the dock visibility for the application.
///
#[cfg(target_os = "macos")]
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
fn set_dock_visibility(&mut self, visible: bool);

/// Shows the application, but does not automatically focus it.
#[cfg(target_os = "macos")]
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
Expand Down
1 change: 1 addition & 0 deletions crates/tauri/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ const PLUGINS: &[(&str, &[(&str, bool)])] = &[
("remove_data_store", false),
("default_window_icon", false),
("set_app_theme", false),
("set_dock_visibility", false),
],
),
(
Expand Down
26 changes: 26 additions & 0 deletions crates/tauri/permissions/app/autogenerated/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,32 @@ Denies the set_app_theme command without any pre-configured scope.
<tr>
<td>

`core:app:allow-set-dock-visibility`

</td>
<td>

Enables the set_dock_visibility command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`core:app:deny-set-dock-visibility`

</td>
<td>

Denies the set_dock_visibility command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`core:app:allow-tauri-version`

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

Large diffs are not rendered by default.

41 changes: 41 additions & 0 deletions crates/tauri/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,26 @@ impl<R: Runtime> AppHandle<R> {
.set_activation_policy(activation_policy)
.map_err(Into::into)
}

/// Sets the dock visibility for the application.
///
/// # Examples
/// ```,no_run
/// tauri::Builder::default()
/// .setup(move |app| {
/// #[cfg(target_os = "macos")]
/// app.handle().set_dock_visibility(false);
/// Ok(())
/// });
/// ```
#[cfg(target_os = "macos")]
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
pub fn set_dock_visibility(&self, visible: bool) -> crate::Result<()> {
self
.runtime_handle
.set_dock_visibility(visible)
.map_err(Into::into)
}
}

impl<R: Runtime> Manager<R> for AppHandle<R> {
Expand Down Expand Up @@ -1130,6 +1150,27 @@ impl<R: Runtime> App<R> {
}
}

/// Sets the dock visibility for the application.
///
/// # Examples
/// ```,no_run
/// tauri::Builder::default()
/// .setup(move |app| {
/// #[cfg(target_os = "macos")]
/// app.set_dock_visibility(false);
/// Ok(())
/// });
/// ```
#[cfg(target_os = "macos")]
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
pub fn set_dock_visibility(&mut self, visible: bool) {
if let Some(runtime) = self.runtime.as_mut() {
runtime.set_dock_visibility(visible);
} else {
let _ = self.app_handle().set_dock_visibility(visible);
}
}

/// Change the device event filter mode.
///
/// Since the DeviceEvent capture can lead to high CPU usage for unfocused windows, [`tao`]
Expand Down
28 changes: 28 additions & 0 deletions crates/tauri/src/app/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,33 @@ pub async fn set_app_theme<R: Runtime>(app: AppHandle<R>, theme: Option<Theme>)
app.set_theme(theme);
}

#[command(root = "crate")]
pub async fn set_dock_visibility<R: Runtime>(
app: AppHandle<R>,
visible: bool,
) -> crate::Result<()> {
#[cfg(target_os = "macos")]
{
let mut focused_window = None;
for window in app.manager.windows().into_values() {
if window.is_focused().unwrap_or_default() {
focused_window.replace(window);
break;
}
}

app.set_dock_visibility(visible)?;

// retain focus
if let Some(focused_window) = focused_window {
let _ = focused_window.set_focus();
}
}
#[cfg(not(target_os = "macos"))]
let (_app, _visible) = (app, visible);
Ok(())
}

pub fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::new("app")
.invoke_handler(crate::generate_handler![
Expand All @@ -97,6 +124,7 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
remove_data_store,
default_window_icon,
set_app_theme,
set_dock_visibility,
])
.build()
}
10 changes: 10 additions & 0 deletions crates/tauri/src/test/mock_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,12 @@ impl<T: UserEvent> RuntimeHandle<T> for MockRuntimeHandle {
Ok(())
}

#[cfg(target_os = "macos")]
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
fn set_dock_visibility(&self, visible: bool) -> Result<()> {
Ok(())
}

fn request_exit(&self, code: i32) -> Result<()> {
unimplemented!()
}
Expand Down Expand Up @@ -1209,6 +1215,10 @@ impl<T: UserEvent> Runtime<T> for MockRuntime {
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
fn set_activation_policy(&mut self, activation_policy: tauri_runtime::ActivationPolicy) {}

#[cfg(target_os = "macos")]
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
fn set_dock_visibility(&mut self, visible: bool) {}

#[cfg(target_os = "macos")]
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
fn show(&self) {}
Expand Down
1 change: 1 addition & 0 deletions examples/api/src-tauri/capabilities/run-app.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"core:app:allow-app-hide",
"core:app:allow-app-show",
"core:app:allow-set-app-theme",
"core:app:allow-set-dock-visibility",
"core:window:allow-set-theme",
"core:window:allow-center",
"core:window:allow-request-user-attention",
Expand Down
11 changes: 9 additions & 2 deletions examples/api/src/views/App.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<script>
import { show, hide, setTheme } from '@tauri-apps/api/app'
import { show, hide, setTheme, setDockVisibility } from '@tauri-apps/api/app'

export let onMessage
/** @type {import('@tauri-apps/api/window').Theme | 'auto'} */
let theme = 'auto'
let dockVisible = true

function showApp() {
hideApp()
Expand Down Expand Up @@ -37,6 +38,11 @@
}
setTheme(theme === 'auto' ? null : theme)
}

async function toggleDockVisibility() {
await setDockVisibility(!dockVisible)
dockVisible = !dockVisible
}
</script>

<div>
Expand All @@ -47,5 +53,6 @@
on:click={showApp}>Show</button
>
<button class="btn" id="hide" on:click={hideApp}>Hide</button>
<button class="btn" id="hide" on:click={switchTheme}>Switch Theme ({theme})</button>
<button class="btn" id="switch-theme" on:click={switchTheme}>Switch Theme ({theme})</button>
<button class="btn" id="toggle-dock-visibility" on:click={toggleDockVisibility}>Toggle dock visibility</button>
</div>
13 changes: 12 additions & 1 deletion packages/api/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,16 @@ async function setTheme(theme?: Theme | null): Promise<void> {
return invoke('plugin:app|set_app_theme', { theme })
}

/**
* Sets the dock visibility for the application on macOS.
*
* @param visible whether the dock should be visible or not
* @since 2.5.0
*/
async function setDockVisibility(visible: boolean): Promise<void> {
return invoke('plugin:app|set_dock_visibility', { visible })
}

export {
getName,
getVersion,
Expand All @@ -206,5 +216,6 @@ export {
defaultWindowIcon,
setTheme,
fetchDataStoreIdentifiers,
removeDataStore
removeDataStore,
setDockVisibility
}