collective

Browse / github.com/storytold/craft-launcher / patch

macOS: Add optional Dock hiding when running in background is enabled.

macOS: Add optional Dock hiding when running in background is enabled. This PR adds a macOS setting to hide the ArtCraft Launcher icon from the Dock while it runs in the background. The setting is selectable only when `Keep running in the tray when the window is closed` is enabled; the Dock icon reappears when the window is shown.

Status
open
Score
0.00
Adopters
0 other operators
Author
alextorma (imported from pull request #368, open)
Base
1579aa8c02acc5483f901109292b18c22d750559
Size
+74 −1 in 14 files
Review
pending
Shared
2026-10-28
Id
0a8d36415929412c883ee083

How it went

No other operator has reported using it yet.

Diff

raw · apps/artcraft-launcher/src/main.rs apps/artcraft-launcher/src/spaces.rs crates/ui-egui/src/dialogs.rs crates/ui-egui/src/i18n/cs.tsv crates/ui-egui/src/i18n/de.tsv crates/ui-egui/src/i18n/es.tsv crates/ui-egui/src/i18n/fr.tsv crates/ui-egui/src/i18n/hu.tsv crates/ui-egui/src/i18n/ja.tsv crates/ui-egui/src/i18n/pl.tsv crates/ui-egui/src/i18n/pt-BR.tsv crates/ui-egui/src/i18n/ru.tsv crates/ui-egui/src/i18n/zh-CN.tsv crates/ui-egui/src/settings.rs

diff --git a/apps/artcraft-launcher/src/main.rs b/apps/artcraft-launcher/src/main.rs--- a/apps/artcraft-launcher/src/main.rs+++ b/apps/artcraft-launcher/src/main.rs@@ -624,6 +624,13 @@ impl<'a> Shell<'a> {         let window_hides = window_can_hide(cc.display_handle().ok().map(|d| d.as_raw()));         // Started hidden at login but there's no tray to come back from: show the window.         let visible = !hidden || launcher.tray.is_none();+        #[cfg(target_os = "macos")]+        spaces::set_dock_visibility(+            visible,+            launcher.ui.settings.hide_from_dock_when_hidden,+            launcher.tray.is_some(),+            launcher.ui.settings.close_to_tray,+        );         let mut shell = Self { launcher, window_hides, visible: true, quitting: false, applied_follow: None };         if !visible {             shell.put_away(&cc.egui_ctx);@@ -639,6 +646,12 @@ impl<'a> Shell<'a> {         // user to its own (macOS; the setting doesn't exist elsewhere).         #[cfg(target_os = "macos")]         {+            spaces::set_dock_visibility(+                true,+                self.launcher.ui.settings.hide_from_dock_when_hidden,+                self.launcher.tray.is_some(),+                self.launcher.ui.settings.close_to_tray,+            );             let on = self.launcher.ui.settings.show_on_current_desktop;             spaces::follow_current_desktop(on);             self.applied_follow = Some(on);@@ -657,6 +670,13 @@ impl<'a> Shell<'a> {     fn put_away(&mut self, ctx: &egui::Context) {         if self.window_hides {             self.visible = false;+            #[cfg(target_os = "macos")]+            spaces::set_dock_visibility(+                false,+                self.launcher.ui.settings.hide_from_dock_when_hidden,+                self.launcher.tray.is_some(),+                self.launcher.ui.settings.close_to_tray,+            );             ctx.send_viewport_cmd(egui::ViewportCommand::Visible(false));         } else {             self.launcher.closed_to_tray = true;@@ -744,6 +764,23 @@ mod tests {         assert_eq!(claim_notification_identity(), first);     } +    #[cfg(target_os = "macos")]+    #[test]+    fn dock_icon_hides_only_when_hidden_opted_in_and_tray_mode_is_enabled() {+        use objc2_app_kit::NSApplicationActivationPolicy;++        assert_eq!(spaces::activation_policy(true, true, true, true), NSApplicationActivationPolicy::Regular);+        assert_eq!(spaces::activation_policy(false, false, true, true), NSApplicationActivationPolicy::Regular);+        assert_eq!(spaces::activation_policy(false, true, false, true), NSApplicationActivationPolicy::Regular);+        assert_eq!(spaces::activation_policy(false, true, true, false), NSApplicationActivationPolicy::Regular);+        assert_eq!(spaces::activation_policy(false, true, true, true), NSApplicationActivationPolicy::Accessory);+    }++    #[test]+    fn hiding_from_the_dock_is_disabled_by_default() {+        assert!(!Settings::default().hide_from_dock_when_hidden);+    }+     /// What the tests can see of a [`Quiet`] backend, and its clock.     #[derive(Default)]     struct Seen {diff --git a/apps/artcraft-launcher/src/spaces.rs b/apps/artcraft-launcher/src/spaces.rs--- a/apps/artcraft-launcher/src/spaces.rs+++ b/apps/artcraft-launcher/src/spaces.rs@@ -6,7 +6,27 @@ //! show a hidden window on the current desktop anyway, so this module only exists on macOS.  use objc2::MainThreadMarker;-use objc2_app_kit::{NSApplication, NSWindowCollectionBehavior};+use objc2_app_kit::{NSApplication, NSApplicationActivationPolicy, NSWindowCollectionBehavior};++pub(super) fn activation_policy(+    window_visible: bool,+    hide_when_hidden: bool,+    tray_visible: bool,+    keep_in_tray: bool,+) -> NSApplicationActivationPolicy {+    if !window_visible && hide_when_hidden && tray_visible && keep_in_tray {+        NSApplicationActivationPolicy::Accessory+    } else {+        NSApplicationActivationPolicy::Regular+    }+}++/// Applies the Dock visibility preference. Must run on the main thread.+pub fn set_dock_visibility(window_visible: bool, hide_when_hidden: bool, tray_visible: bool, keep_in_tray: bool) {+    let Some(mtm) = MainThreadMarker::new() else { return };+    let app = NSApplication::sharedApplication(mtm);+    app.setActivationPolicy(activation_policy(window_visible, hide_when_hidden, tray_visible, keep_in_tray));+}  /// Makes the launcher's windows follow the current desktop when shown (`true`), or stay on their /// own desktop and switch to it (`false`, macOS's default). Must run on the main thread, as thediff --git a/crates/ui-egui/src/dialogs.rs b/crates/ui-egui/src/dialogs.rs--- a/crates/ui-egui/src/dialogs.rs+++ b/crates/ui-egui/src/dialogs.rs@@ -326,6 +326,9 @@ impl LauncherUi {             if host.has_desktops() {                 ui.checkbox(&mut self.settings.show_on_current_desktop, tl!("Show the window on the current desktop"))                     .on_hover_text(tl!("When on, opening the launcher from the menu bar brings its window to the desktop you're on. When off, macOS switches you to the desktop the window was on."));+                ui.add_enabled_ui(host.has_tray() && self.settings.close_to_tray, |ui| {+                    ui.checkbox(&mut self.settings.hide_from_dock_when_hidden, tl!("Hide ArtCraft Launcher from the Dock while in the background"));+                });             }             if let Some(mut on) = host.login_item()                 && ui.checkbox(&mut on, tl!("Start ArtCraft Launcher when I log in")).changed()diff --git a/crates/ui-egui/src/i18n/cs.tsv b/crates/ui-egui/src/i18n/cs.tsv--- a/crates/ui-egui/src/i18n/cs.tsv+++ b/crates/ui-egui/src/i18n/cs.tsv@@ -81,6 +81,7 @@ 	Updates always use the format an app was installed with.	Aktualizace vždy použijí formát, ve kterém byla aplikace nainstalována. 	Running in the background	Běh na pozadí 	Keep running in the tray when the window is closed	Po zavření okna ponechat spuštěné v oznamovací oblasti+	Hide ArtCraft Launcher from the Dock while in the background	Skrýt ArtCraft Launcher v Docku při běhu na pozadí 	Show the window on the current desktop	Zobrazit okno na aktuální ploše 	Start ArtCraft Launcher when I log in	Spouštět ArtCraft Launcher po přihlášení 	Community	Komunitadiff --git a/crates/ui-egui/src/i18n/de.tsv b/crates/ui-egui/src/i18n/de.tsv--- a/crates/ui-egui/src/i18n/de.tsv+++ b/crates/ui-egui/src/i18n/de.tsv@@ -94,6 +94,7 @@ 	Updates always use the format an app was installed with.	Updates verwenden immer das Format, mit dem eine App installiert wurde. 	Running in the background	Im Hintergrund ausführen 	Keep running in the tray when the window is closed	Beim Schließen des Fensters im Infobereich weiterlaufen+	Hide ArtCraft Launcher from the Dock while in the background	ArtCraft Launcher im Hintergrund aus dem Dock ausblenden 	Show the window on the current desktop	Fenster auf dem aktuellen Schreibtisch zeigen 	Start ArtCraft Launcher when I log in	ArtCraft Launcher bei der Anmeldung starten 	Community	Communitydiff --git a/crates/ui-egui/src/i18n/es.tsv b/crates/ui-egui/src/i18n/es.tsv--- a/crates/ui-egui/src/i18n/es.tsv+++ b/crates/ui-egui/src/i18n/es.tsv@@ -94,6 +94,7 @@ 	Updates always use the format an app was installed with.	Las actualizaciones siempre usan el formato con el que se instaló cada aplicación. 	Running in the background	En segundo plano 	Keep running in the tray when the window is closed	Seguir abierto en la bandeja del sistema al cerrar la ventana+	Hide ArtCraft Launcher from the Dock while in the background	Ocultar ArtCraft Launcher del Dock en segundo plano 	Show the window on the current desktop	Mostrar la ventana en el escritorio actual 	Start ArtCraft Launcher when I log in	Abrir ArtCraft Launcher al iniciar sesión 	Community	Comunidaddiff --git a/crates/ui-egui/src/i18n/fr.tsv b/crates/ui-egui/src/i18n/fr.tsv--- a/crates/ui-egui/src/i18n/fr.tsv+++ b/crates/ui-egui/src/i18n/fr.tsv@@ -92,6 +92,7 @@ 	Updates always use the format an app was installed with.	Les mises à jour utilisent toujours le format avec lequel l'application a été installée. 	Running in the background	Exécution en arrière-plan 	Keep running in the tray when the window is closed	Rester actif dans la zone de notification à la fermeture de la fenêtre+	Hide ArtCraft Launcher from the Dock while in the background	Masquer ArtCraft Launcher du Dock en arrière-plan 	Show the window on the current desktop	Afficher la fenêtre sur le bureau actuel 	Start ArtCraft Launcher when I log in	Lancer ArtCraft Launcher à l'ouverture de session 	Community	Communautédiff --git a/crates/ui-egui/src/i18n/hu.tsv b/crates/ui-egui/src/i18n/hu.tsv--- a/crates/ui-egui/src/i18n/hu.tsv+++ b/crates/ui-egui/src/i18n/hu.tsv@@ -94,6 +94,7 @@ 	Updates always use the format an app was installed with.	A frissítések mindig az eredeti telepítés csomagformátumát használják. 	Running in the background	Futtatás a háttérben 	Keep running in the tray when the window is closed	Az ablak bezárásakor kerüljön a tálcára+	Hide ArtCraft Launcher from the Dock while in the background	ArtCraft Launcher elrejtése a Dockból a háttérben 	Show the window on the current desktop	Ablak megjelenítése az aktuális asztalon 	Start ArtCraft Launcher when I log in	ArtCraft Launcher indítása bejelentkezéskor 	Community	Közösségdiff --git a/crates/ui-egui/src/i18n/ja.tsv b/crates/ui-egui/src/i18n/ja.tsv--- a/crates/ui-egui/src/i18n/ja.tsv+++ b/crates/ui-egui/src/i18n/ja.tsv@@ -96,6 +96,7 @@ 	Updates always use the format an app was installed with.	更新は常に、アプリをインストールしたときの形式で行われます。 	Running in the background	バックグラウンドで実行 	Keep running in the tray when the window is closed	ウィンドウを閉じてもトレイで実行し続ける+	Hide ArtCraft Launcher from the Dock while in the background	バックグラウンド実行中はArtCraft LauncherをDockに表示しない 	Show the window on the current desktop	現在のデスクトップにウィンドウを表示 	Start ArtCraft Launcher when I log in	ログイン時に ArtCraft Launcher を起動 	Community	コミュニティdiff --git a/crates/ui-egui/src/i18n/pl.tsv b/crates/ui-egui/src/i18n/pl.tsv--- a/crates/ui-egui/src/i18n/pl.tsv+++ b/crates/ui-egui/src/i18n/pl.tsv@@ -95,6 +95,7 @@ 	Updates always use the format an app was installed with.	Aktualizacje zawsze używają formatu, w jakim pierwotnie zainstalowano aplikację. 	Running in the background	Działanie w tle 	Keep running in the tray when the window is closed	Po zamknięciu okna działaj w zasobniku systemowym+	Hide ArtCraft Launcher from the Dock while in the background	Ukrywaj ArtCraft Launcher w Docku podczas działania w tle 	Show the window on the current desktop	Pokaż okno na bieżącym pulpicie 	Start ArtCraft Launcher when I log in	Uruchom ArtCraft Launcher po zalogowaniu 	Community	Społecznośćdiff --git a/crates/ui-egui/src/i18n/pt-BR.tsv b/crates/ui-egui/src/i18n/pt-BR.tsv--- a/crates/ui-egui/src/i18n/pt-BR.tsv+++ b/crates/ui-egui/src/i18n/pt-BR.tsv@@ -82,6 +82,7 @@ 	Updates always use the format an app was installed with.	As atualizações sempre usam o formato com o qual o aplicativo foi instalado. 	Running in the background	Execução em segundo plano 	Keep running in the tray when the window is closed	Continuar na bandeja do sistema ao fechar a janela+	Hide ArtCraft Launcher from the Dock while in the background	Ocultar o ArtCraft Launcher do Dock em segundo plano 	Show the window on the current desktop	Mostrar a janela na área de trabalho atual 	Start ArtCraft Launcher when I log in	Iniciar o ArtCraft Launcher ao fazer login 	Community	Comunidadediff --git a/crates/ui-egui/src/i18n/ru.tsv b/crates/ui-egui/src/i18n/ru.tsv--- a/crates/ui-egui/src/i18n/ru.tsv+++ b/crates/ui-egui/src/i18n/ru.tsv@@ -92,6 +92,7 @@ 	Updates always use the format an app was installed with.	Обновления всегда используют формат, с которым приложение было установлено. 	Running in the background	Работа в фоне 	Keep running in the tray when the window is closed	Оставаться в трее при закрытии окна+	Hide ArtCraft Launcher from the Dock while in the background	Скрывать ArtCraft Launcher из Dock при работе в фоне 	Show the window on the current desktop	Показывать окно на текущем рабочем столе 	Start ArtCraft Launcher when I log in	Запускать ArtCraft Launcher при входе в систему 	Community	Сообществоdiff --git a/crates/ui-egui/src/i18n/zh-CN.tsv b/crates/ui-egui/src/i18n/zh-CN.tsv--- a/crates/ui-egui/src/i18n/zh-CN.tsv+++ b/crates/ui-egui/src/i18n/zh-CN.tsv@@ -76,6 +76,7 @@ 	Updates always use the format an app was installed with.	更新时始终使用应用原来的安装格式。 	Running in the background	后台运行 	Keep running in the tray when the window is closed	关闭窗口后继续在系统托盘中运行+	Hide ArtCraft Launcher from the Dock while in the background	在后台运行时从 Dock 中隐藏 ArtCraft Launcher 	Show the window on the current desktop	在当前桌面显示窗口 	Start ArtCraft Launcher when I log in	登录时启动 ArtCraft Launcher 	Community	社区diff --git a/crates/ui-egui/src/settings.rs b/crates/ui-egui/src/settings.rs--- a/crates/ui-egui/src/settings.rs+++ b/crates/ui-egui/src/settings.rs@@ -97,6 +97,8 @@ pub struct Settings {     /// macOS: showing the window brings it to the current desktop (Space) instead of switching to     /// the desktop it was on.     pub show_on_current_desktop: bool,+    /// macOS: hide the Dock icon while the launcher is running without a visible window.+    pub hide_from_dock_when_hidden: bool,     pub check_every: CheckEvery,     /// Automatically download and install updates when found.     #[serde(default)]@@ -177,6 +179,7 @@ impl Default for Settings {             language: "auto".to_string(),             close_to_tray: true,             show_on_current_desktop: true,+            hide_from_dock_when_hidden: false,             check_every: CheckEvery::Hour,             auto_update: false,             notify: true,