diff options
Diffstat (limited to '')
26 files changed, 201 insertions, 16 deletions
diff --git a/WireGuard/WireGuard/UI/macOS/AppDelegate.swift b/WireGuard/WireGuard/UI/macOS/AppDelegate.swift index a08f9dc..3f08987 100644 --- a/WireGuard/WireGuard/UI/macOS/AppDelegate.swift +++ b/WireGuard/WireGuard/UI/macOS/AppDelegate.swift @@ -6,7 +6,8 @@ import Cocoa @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { - var statusItem: NSStatusItem? + var statusItemController: StatusItemController? + var currentTunnelStatusObserver: AnyObject? func applicationDidFinishLaunching(_ aNotification: Notification) { Logger.configureGlobal(withFilePath: FileManager.appLogFileURL?.path) @@ -19,21 +20,19 @@ class AppDelegate: NSObject, NSApplicationDelegate { } let tunnelsManager: TunnelsManager = result.value! + let statusItemController = StatusItemController() + let statusMenu = StatusMenu(tunnelsManager: tunnelsManager) - self.statusItem = createStatusBarItem(with: statusMenu) + + statusItemController.statusItem.menu = statusMenu + statusItemController.currentTunnel = statusMenu.currentTunnel + self.currentTunnelStatusObserver = statusMenu.observe(\.currentTunnel) { statusMenu, _ in + statusItemController.currentTunnel = statusMenu.currentTunnel + } + self.statusItemController = statusItemController tunnelsManager.tunnelsListDelegate = statusMenu tunnelsManager.activationDelegate = statusMenu } } } - -func createStatusBarItem(with statusMenu: StatusMenu) -> NSStatusItem { - let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength) - if let statusBarImage = NSImage(named: "WireGuardMacStatusBarIcon") { - statusBarImage.isTemplate = true - statusItem.button?.image = statusBarImage - } - statusItem.menu = statusMenu - return statusItem -} diff --git a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/WireGuardMacStatusBarIcon.imageset/Contents.json b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIcon.imageset/Contents.json index 2adee86..c878d79 100644 --- a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/WireGuardMacStatusBarIcon.imageset/Contents.json +++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIcon.imageset/Contents.json @@ -2,22 +2,25 @@ "images" : [ { "idiom" : "universal", - "filename" : "WireGuardMacStatusBarIcon@1x.png", + "filename" : "StatusBarIcon@1x.png", "scale" : "1x" }, { "idiom" : "universal", - "filename" : "WireGuardMacStatusBarIcon@2x.png", + "filename" : "StatusBarIcon@2x.png", "scale" : "2x" }, { "idiom" : "universal", - "filename" : "WireGuardMacStatusBarIcon@3x.png", + "filename" : "StatusBarIcon@3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" } }
\ No newline at end of file diff --git a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIcon.imageset/StatusBarIcon@1x.png b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIcon.imageset/StatusBarIcon@1x.png Binary files differnew file mode 100644 index 0000000..c0a43e7 --- /dev/null +++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIcon.imageset/StatusBarIcon@1x.png diff --git a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIcon.imageset/StatusBarIcon@2x.png b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIcon.imageset/StatusBarIcon@2x.png Binary files differnew file mode 100644 index 0000000..2057c31 --- /dev/null +++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIcon.imageset/StatusBarIcon@2x.png diff --git a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIcon.imageset/StatusBarIcon@3x.png b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIcon.imageset/StatusBarIcon@3x.png Binary files differnew file mode 100644 index 0000000..60cc363 --- /dev/null +++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIcon.imageset/StatusBarIcon@3x.png diff --git a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDimmed.imageset/Contents.json b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDimmed.imageset/Contents.json new file mode 100644 index 0000000..aeb8a8e --- /dev/null +++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDimmed.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "StatusBarIconDimmed@1x.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "StatusBarIconDimmed@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "StatusBarIconDimmed@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +}
\ No newline at end of file diff --git a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDimmed.imageset/StatusBarIconDimmed@1x.png b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDimmed.imageset/StatusBarIconDimmed@1x.png Binary files differnew file mode 100644 index 0000000..fb9d8f7 --- /dev/null +++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDimmed.imageset/StatusBarIconDimmed@1x.png diff --git a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDimmed.imageset/StatusBarIconDimmed@2x.png b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDimmed.imageset/StatusBarIconDimmed@2x.png Binary files differnew file mode 100644 index 0000000..2f4e613 --- /dev/null +++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDimmed.imageset/StatusBarIconDimmed@2x.png diff --git a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDimmed.imageset/StatusBarIconDimmed@3x.png b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDimmed.imageset/StatusBarIconDimmed@3x.png Binary files differnew file mode 100644 index 0000000..cc5ead9 --- /dev/null +++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDimmed.imageset/StatusBarIconDimmed@3x.png diff --git a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot1.imageset/Contents.json b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot1.imageset/Contents.json new file mode 100644 index 0000000..0024a60 --- /dev/null +++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot1.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "StatusBarIconDot1@1x.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "StatusBarIconDot1@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "StatusBarIconDot1@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +}
\ No newline at end of file diff --git a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot1.imageset/StatusBarIconDot1@1x.png b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot1.imageset/StatusBarIconDot1@1x.png Binary files differnew file mode 100644 index 0000000..bbbe0c3 --- /dev/null +++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot1.imageset/StatusBarIconDot1@1x.png diff --git a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot1.imageset/StatusBarIconDot1@2x.png b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot1.imageset/StatusBarIconDot1@2x.png Binary files differnew file mode 100644 index 0000000..01b5eb3 --- /dev/null +++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot1.imageset/StatusBarIconDot1@2x.png diff --git a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot1.imageset/StatusBarIconDot1@3x.png b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot1.imageset/StatusBarIconDot1@3x.png Binary files differnew file mode 100644 index 0000000..76afa15 --- /dev/null +++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot1.imageset/StatusBarIconDot1@3x.png diff --git a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot2.imageset/Contents.json b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot2.imageset/Contents.json new file mode 100644 index 0000000..8b61c0e --- /dev/null +++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot2.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "StatusBarIconDot2@1x.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "StatusBarIconDot2@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "StatusBarIconDot2@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +}
\ No newline at end of file diff --git a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot2.imageset/StatusBarIconDot2@1x.png b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot2.imageset/StatusBarIconDot2@1x.png Binary files differnew file mode 100644 index 0000000..a16143f --- /dev/null +++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot2.imageset/StatusBarIconDot2@1x.png diff --git a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot2.imageset/StatusBarIconDot2@2x.png b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot2.imageset/StatusBarIconDot2@2x.png Binary files differnew file mode 100644 index 0000000..ce00482 --- /dev/null +++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot2.imageset/StatusBarIconDot2@2x.png diff --git a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot2.imageset/StatusBarIconDot2@3x.png b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot2.imageset/StatusBarIconDot2@3x.png Binary files differnew file mode 100644 index 0000000..82640f7 --- /dev/null +++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot2.imageset/StatusBarIconDot2@3x.png diff --git a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot3.imageset/Contents.json b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot3.imageset/Contents.json new file mode 100644 index 0000000..96da519 --- /dev/null +++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot3.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "StatusBarIconDot3@1x.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "StatusBarIconDot3@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "StatusBarIconDot3@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +}
\ No newline at end of file diff --git a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot3.imageset/StatusBarIconDot3@1x.png b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot3.imageset/StatusBarIconDot3@1x.png Binary files differnew file mode 100644 index 0000000..80e221b --- /dev/null +++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot3.imageset/StatusBarIconDot3@1x.png diff --git a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot3.imageset/StatusBarIconDot3@2x.png b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot3.imageset/StatusBarIconDot3@2x.png Binary files differnew file mode 100644 index 0000000..663f92b --- /dev/null +++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot3.imageset/StatusBarIconDot3@2x.png diff --git a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot3.imageset/StatusBarIconDot3@3x.png b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot3.imageset/StatusBarIconDot3@3x.png Binary files differnew file mode 100644 index 0000000..10e43d9 --- /dev/null +++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot3.imageset/StatusBarIconDot3@3x.png diff --git a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/WireGuardMacStatusBarIcon.imageset/WireGuardMacStatusBarIcon@1x.png b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/WireGuardMacStatusBarIcon.imageset/WireGuardMacStatusBarIcon@1x.png Binary files differdeleted file mode 100644 index 1a7d77c..0000000 --- a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/WireGuardMacStatusBarIcon.imageset/WireGuardMacStatusBarIcon@1x.png +++ /dev/null diff --git a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/WireGuardMacStatusBarIcon.imageset/WireGuardMacStatusBarIcon@2x.png b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/WireGuardMacStatusBarIcon.imageset/WireGuardMacStatusBarIcon@2x.png Binary files differdeleted file mode 100644 index 66c49c1..0000000 --- a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/WireGuardMacStatusBarIcon.imageset/WireGuardMacStatusBarIcon@2x.png +++ /dev/null diff --git a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/WireGuardMacStatusBarIcon.imageset/WireGuardMacStatusBarIcon@3x.png b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/WireGuardMacStatusBarIcon.imageset/WireGuardMacStatusBarIcon@3x.png Binary files differdeleted file mode 100644 index e1bcc35..0000000 --- a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/WireGuardMacStatusBarIcon.imageset/WireGuardMacStatusBarIcon@3x.png +++ /dev/null diff --git a/WireGuard/WireGuard/UI/macOS/StatusItemController.swift b/WireGuard/WireGuard/UI/macOS/StatusItemController.swift new file mode 100644 index 0000000..2568c15 --- /dev/null +++ b/WireGuard/WireGuard/UI/macOS/StatusItemController.swift @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: MIT +// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. + +import Cocoa + +class StatusItemController { + var currentTunnel: TunnelContainer? { + didSet { + updateStatusItemImage() + } + } + + let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength) + private let statusBarImageWhenActive = NSImage(named: "StatusBarIcon")! + private let statusBarImageWhenInactive = NSImage(named: "StatusBarIconDimmed")! + + private let animationImages = [ + NSImage(named: "StatusBarIconDot1")!, + NSImage(named: "StatusBarIconDot2")!, + NSImage(named: "StatusBarIconDot3")! + ] + private var animationImageIndex: Int = 0 + private var animationTimer: Timer? + + init() { + updateStatusItemImage() + } + + func updateStatusItemImage() { + guard let currentTunnel = currentTunnel else { + stopActivatingAnimation() + statusItem.button?.image = statusBarImageWhenInactive + return + } + switch currentTunnel.status { + case .inactive: + stopActivatingAnimation() + statusItem.button?.image = statusBarImageWhenInactive + case .active: + stopActivatingAnimation() + statusItem.button?.image = statusBarImageWhenActive + case .activating, .waiting, .reasserting, .restarting: + startActivatingAnimation() + case .deactivating: + break + } + } + + func startActivatingAnimation() { + guard animationTimer == nil else { return } + let timer = Timer(timeInterval: 0.3, repeats: true) { [weak self] _ in + guard let self = self else { return } + self.statusItem.button?.image = self.animationImages[self.animationImageIndex] + self.animationImageIndex = (self.animationImageIndex + 1) % self.animationImages.count + } + RunLoop.main.add(timer, forMode: .default) + animationTimer = timer + } + + func stopActivatingAnimation() { + guard let timer = self.animationTimer else { return } + timer.invalidate() + animationTimer = nil + animationImageIndex = 0 + } +} diff --git a/WireGuard/WireGuard/UI/macOS/StatusMenu.swift b/WireGuard/WireGuard/UI/macOS/StatusMenu.swift index 78e71ba..a2f02d8 100644 --- a/WireGuard/WireGuard/UI/macOS/StatusMenu.swift +++ b/WireGuard/WireGuard/UI/macOS/StatusMenu.swift @@ -13,6 +13,8 @@ class StatusMenu: NSMenu { var firstTunnelMenuItemIndex = 0 var numberOfTunnelMenuItems = 0 + @objc dynamic var currentTunnel: TunnelContainer? + var manageTunnelsRootVC: ManageTunnelsRootViewController? lazy var manageTunnelsWindow: NSWindow = { manageTunnelsRootVC = ManageTunnelsRootViewController(tunnelsManager: tunnelsManager) @@ -30,7 +32,11 @@ class StatusMenu: NSMenu { addStatusMenuItems() addItem(NSMenuItem.separator()) for index in 0 ..< tunnelsManager.numberOfTunnels() { - let isUpdated = updateStatusMenuItems(with: tunnelsManager.tunnel(at: index), ignoreInactive: true) + let tunnel = tunnelsManager.tunnel(at: index) + if tunnel.status != .inactive { + currentTunnel = tunnel + } + let isUpdated = updateStatusMenuItems(with: tunnel, ignoreInactive: true) if isUpdated { break } @@ -176,6 +182,13 @@ extension StatusMenu { updateTunnelMenuItem(menuItem) let statusObservationToken = tunnel.observe(\.status) { [weak self] tunnel, _ in updateTunnelMenuItem(menuItem) + if tunnel.status == .deactivating || tunnel.status == .inactive { + if self?.currentTunnel == tunnel { + self?.currentTunnel = self?.tunnelsManager.waitingTunnel() + } + } else { + self?.currentTunnel = tunnel + } self?.updateStatusMenuItems(with: tunnel, ignoreInactive: false) } tunnelStatusObservers.insert(statusObservationToken, at: tunnelIndex) |