From 7bc567adf59b651fa8a8fce7441e9b8091b265e0 Mon Sep 17 00:00:00 2001 From: Michael Suchacz <203725896+ibetitsmike@users.noreply.github.com> Date: Wed, 13 Aug 2025 10:04:26 +0200 Subject: [PATCH 1/2] chore: add MainActor when mutating vpn state (#225) --- Coder-Desktop/Coder-Desktop/VPN/VPNService.swift | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Coder-Desktop/Coder-Desktop/VPN/VPNService.swift b/Coder-Desktop/Coder-Desktop/VPN/VPNService.swift index de8fa86..9da39d5 100644 --- a/Coder-Desktop/Coder-Desktop/VPN/VPNService.swift +++ b/Coder-Desktop/Coder-Desktop/VPN/VPNService.swift @@ -185,10 +185,12 @@ extension CoderVPNService { // Any -> Disconnected: Update UI w/ error if present case (_, .disconnected): connection.fetchLastDisconnectError { err in - self.tunnelState = if let err { - .failed(.internalError(err.localizedDescription)) - } else { - .disabled + Task { @MainActor in + self.tunnelState = if let err { + .failed(.internalError(err.localizedDescription)) + } else { + .disabled + } } } // Connecting -> Connecting: no-op From 0776807f9a001249d181f66ee6e60807032d9e34 Mon Sep 17 00:00:00 2001 From: Ethan <39577870+ethanndickson@users.noreply.github.com> Date: Wed, 13 Aug 2025 18:22:48 +1000 Subject: [PATCH 2/2] feat: dynamically show app in dock & cmd+tab (#224) --- .../Coder-Desktop/Coder_DesktopApp.swift | 3 +++ Coder-Desktop/Coder-Desktop/Views/Util.swift | 23 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/Coder-Desktop/Coder-Desktop/Coder_DesktopApp.swift b/Coder-Desktop/Coder-Desktop/Coder_DesktopApp.swift index d3deab2..eab01ea 100644 --- a/Coder-Desktop/Coder-Desktop/Coder_DesktopApp.swift +++ b/Coder-Desktop/Coder-Desktop/Coder_DesktopApp.swift @@ -20,6 +20,7 @@ struct DesktopApp: App { Window("Sign In", id: Windows.login.rawValue) { LoginForm() .environmentObject(appDelegate.state) + .showDockIconWhenOpen() }.handlesExternalEvents(matching: Set()) // Don't handle deep links .windowResizability(.contentSize) SwiftUI.Settings { @@ -27,6 +28,7 @@ struct DesktopApp: App { .environmentObject(appDelegate.vpn) .environmentObject(appDelegate.state) .environmentObject(appDelegate.autoUpdater) + .showDockIconWhenOpen() } .windowResizability(.contentSize) Window("Coder File Sync", id: Windows.fileSync.rawValue) { @@ -34,6 +36,7 @@ struct DesktopApp: App { .environmentObject(appDelegate.state) .environmentObject(appDelegate.fileSyncDaemon) .environmentObject(appDelegate.vpn) + .showDockIconWhenOpen() }.handlesExternalEvents(matching: Set()) // Don't handle deep links } } diff --git a/Coder-Desktop/Coder-Desktop/Views/Util.swift b/Coder-Desktop/Coder-Desktop/Views/Util.swift index 69981a2..10d0747 100644 --- a/Coder-Desktop/Coder-Desktop/Views/Util.swift +++ b/Coder-Desktop/Coder-Desktop/Views/Util.swift @@ -44,3 +44,26 @@ public extension View { } } } + +@MainActor +private struct ActivationPolicyModifier: ViewModifier { + func body(content: Content) -> some View { + content + // This lets us show and hide the app from the dock and cmd+tab + // when a window is open. + .onAppear { + NSApp.setActivationPolicy(.regular) + } + .onDisappear { + if NSApp.windows.filter { $0.level != .statusBar && $0.isVisible }.count <= 1 { + NSApp.setActivationPolicy(.accessory) + } + } + } +} + +public extension View { + func showDockIconWhenOpen() -> some View { + modifier(ActivationPolicyModifier()) + } +}