mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-01-31 00:35:19 +01:00
feat: add set_dock_visibility method (#13185)
* feat: add `set_dock_visibility` method Signed-off-by: The1111mp <The1111mp@outlook.com> * add api * retain focus * fmt * make SetDockVisibility message conditional (macos only) * lint --------- Signed-off-by: The1111mp <The1111mp@outlook.com> Co-authored-by: Lucas Nogueira <lucas@tauri.app>
This commit is contained in:
7
.changes/feat-dock-visibility-on-macos.md
Normal file
7
.changes/feat-dock-visibility-on-macos.md
Normal file
@@ -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/setDockVisibility.md
Normal file
6
.changes/setDockVisibility.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@tauri-apps/api": minor:feat
|
||||
---
|
||||
|
||||
Added `app.setDockVisibility` for macOS.
|
||||
|
||||
@@ -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),
|
||||
@@ -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
|
||||
@@ -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();
|
||||
@@ -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")]
|
||||
|
||||
@@ -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<()>;
|
||||
|
||||
@@ -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")))]
|
||||
|
||||
@@ -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),
|
||||
],
|
||||
),
|
||||
(
|
||||
|
||||
@@ -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>
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -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> {
|
||||
@@ -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`]
|
||||
|
||||
@@ -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![
|
||||
@@ -97,6 +124,7 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
|
||||
remove_data_store,
|
||||
default_window_icon,
|
||||
set_app_theme,
|
||||
set_dock_visibility,
|
||||
])
|
||||
.build()
|
||||
}
|
||||
|
||||
@@ -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!()
|
||||
}
|
||||
@@ -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) {}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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()
|
||||
@@ -37,6 +38,11 @@
|
||||
}
|
||||
setTheme(theme === 'auto' ? null : theme)
|
||||
}
|
||||
|
||||
async function toggleDockVisibility() {
|
||||
await setDockVisibility(!dockVisible)
|
||||
dockVisible = !dockVisible
|
||||
}
|
||||
</script>
|
||||
|
||||
<div>
|
||||
@@ -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>
|
||||
|
||||
@@ -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,
|
||||
@@ -206,5 +216,6 @@ export {
|
||||
defaultWindowIcon,
|
||||
setTheme,
|
||||
fetchDataStoreIdentifiers,
|
||||
removeDataStore
|
||||
removeDataStore,
|
||||
setDockVisibility
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user