aboutsummaryrefslogtreecommitdiffstats
path: root/WireGuard
diff options
context:
space:
mode:
authorRoopesh Chander <roop@roopc.net>2019-01-16 01:00:42 +0530
committerRoopesh Chander <roop@roopc.net>2019-01-16 01:26:10 +0530
commite29cf19fddc6878f7e24c442f83d6ff0d23fa6b8 (patch)
tree6b7a098cd40dda417d1827af5245669bc883fa88 /WireGuard
parentmacOS: Add About dialog (diff)
downloadwireguard-apple-e29cf19fddc6878f7e24c442f83d6ff0d23fa6b8.tar.xz
wireguard-apple-e29cf19fddc6878f7e24c442f83d6ff0d23fa6b8.zip
macOS: Different status bar icon looks for different states
- Looks dimmed when no tunnel is active - Looks normal when a tunnel is active - Animates when a tunnel is activating Signed-off-by: Roopesh Chander <roop@roopc.net>
Diffstat (limited to 'WireGuard')
-rw-r--r--WireGuard/WireGuard.xcodeproj/project.pbxproj4
-rw-r--r--WireGuard/WireGuard/Tunnel/TunnelsManager.swift4
-rw-r--r--WireGuard/WireGuard/UI/macOS/AppDelegate.swift23
-rw-r--r--WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIcon.imageset/Contents.json (renamed from WireGuard/WireGuard/UI/macOS/Assets.xcassets/WireGuardMacStatusBarIcon.imageset/Contents.json)9
-rw-r--r--WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIcon.imageset/StatusBarIcon@1x.pngbin0 -> 978 bytes
-rw-r--r--WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIcon.imageset/StatusBarIcon@2x.pngbin0 -> 1722 bytes
-rw-r--r--WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIcon.imageset/StatusBarIcon@3x.pngbin0 -> 1975 bytes
-rw-r--r--WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDimmed.imageset/Contents.json26
-rw-r--r--WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDimmed.imageset/StatusBarIconDimmed@1x.pngbin0 -> 881 bytes
-rw-r--r--WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDimmed.imageset/StatusBarIconDimmed@2x.pngbin0 -> 1390 bytes
-rw-r--r--WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDimmed.imageset/StatusBarIconDimmed@3x.pngbin0 -> 1581 bytes
-rw-r--r--WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot1.imageset/Contents.json26
-rw-r--r--WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot1.imageset/StatusBarIconDot1@1x.pngbin0 -> 953 bytes
-rw-r--r--WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot1.imageset/StatusBarIconDot1@2x.pngbin0 -> 1570 bytes
-rw-r--r--WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot1.imageset/StatusBarIconDot1@3x.pngbin0 -> 1744 bytes
-rw-r--r--WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot2.imageset/Contents.json26
-rw-r--r--WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot2.imageset/StatusBarIconDot2@1x.pngbin0 -> 942 bytes
-rw-r--r--WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot2.imageset/StatusBarIconDot2@2x.pngbin0 -> 1502 bytes
-rw-r--r--WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot2.imageset/StatusBarIconDot2@3x.pngbin0 -> 1676 bytes
-rw-r--r--WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot3.imageset/Contents.json26
-rw-r--r--WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot3.imageset/StatusBarIconDot3@1x.pngbin0 -> 958 bytes
-rw-r--r--WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot3.imageset/StatusBarIconDot3@2x.pngbin0 -> 1521 bytes
-rw-r--r--WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot3.imageset/StatusBarIconDot3@3x.pngbin0 -> 1677 bytes
-rw-r--r--WireGuard/WireGuard/UI/macOS/Assets.xcassets/WireGuardMacStatusBarIcon.imageset/WireGuardMacStatusBarIcon@1x.pngbin990 -> 0 bytes
-rw-r--r--WireGuard/WireGuard/UI/macOS/Assets.xcassets/WireGuardMacStatusBarIcon.imageset/WireGuardMacStatusBarIcon@2x.pngbin1714 -> 0 bytes
-rw-r--r--WireGuard/WireGuard/UI/macOS/Assets.xcassets/WireGuardMacStatusBarIcon.imageset/WireGuardMacStatusBarIcon@3x.pngbin1956 -> 0 bytes
-rw-r--r--WireGuard/WireGuard/UI/macOS/StatusItemController.swift66
-rw-r--r--WireGuard/WireGuard/UI/macOS/StatusMenu.swift15
28 files changed, 209 insertions, 16 deletions
diff --git a/WireGuard/WireGuard.xcodeproj/project.pbxproj b/WireGuard/WireGuard.xcodeproj/project.pbxproj
index a5119b65..b6b1c32b 100644
--- a/WireGuard/WireGuard.xcodeproj/project.pbxproj
+++ b/WireGuard/WireGuard.xcodeproj/project.pbxproj
@@ -54,6 +54,7 @@
6F7774EF21722D97006A79B3 /* TunnelsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F7774EE21722D97006A79B3 /* TunnelsManager.swift */; };
6F7774F321774263006A79B3 /* TunnelEditTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F7774F221774263006A79B3 /* TunnelEditTableViewController.swift */; };
6F7F7E5F21C7D74B00527607 /* TunnelErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F7F7E5E21C7D74B00527607 /* TunnelErrors.swift */; };
+ 6F89E17A21EDEB0E00C97BB9 /* StatusItemController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F89E17921EDEB0E00C97BB9 /* StatusItemController.swift */; };
6F919EC3218A2AE90023B400 /* ErrorPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F919EC2218A2AE90023B400 /* ErrorPresenter.swift */; };
6F919ED9218C65C50023B400 /* wireguard_doc_logo_22x29.png in Resources */ = {isa = PBXBuildFile; fileRef = 6F919ED5218C65C50023B400 /* wireguard_doc_logo_22x29.png */; };
6F919EDA218C65C50023B400 /* wireguard_doc_logo_44x58.png in Resources */ = {isa = PBXBuildFile; fileRef = 6F919ED6218C65C50023B400 /* wireguard_doc_logo_44x58.png */; };
@@ -263,6 +264,7 @@
6F7774EE21722D97006A79B3 /* TunnelsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelsManager.swift; sourceTree = "<group>"; };
6F7774F221774263006A79B3 /* TunnelEditTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelEditTableViewController.swift; sourceTree = "<group>"; };
6F7F7E5E21C7D74B00527607 /* TunnelErrors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelErrors.swift; sourceTree = "<group>"; };
+ 6F89E17921EDEB0E00C97BB9 /* StatusItemController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusItemController.swift; sourceTree = "<group>"; };
6F919EC2218A2AE90023B400 /* ErrorPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorPresenter.swift; sourceTree = "<group>"; };
6F919ED5218C65C50023B400 /* wireguard_doc_logo_22x29.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = wireguard_doc_logo_22x29.png; sourceTree = "<group>"; };
6F919ED6218C65C50023B400 /* wireguard_doc_logo_44x58.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = wireguard_doc_logo_44x58.png; sourceTree = "<group>"; };
@@ -512,6 +514,7 @@
6FBA104421D7EA750051C35F /* ViewController */,
6FBA101321D613F30051C35F /* Application.swift */,
6FB1BD5F21D2607A00A991BF /* AppDelegate.swift */,
+ 6F89E17921EDEB0E00C97BB9 /* StatusItemController.swift */,
6FBA101621D655340051C35F /* StatusMenu.swift */,
6FBA104121D6BC210051C35F /* ErrorPresenter.swift */,
6FCD99AE21E0EA1700BA4C82 /* ImportPanelPresenter.swift */,
@@ -1111,6 +1114,7 @@
6FB1BDBC21D50F0200A991BF /* ringlogger.c in Sources */,
6FB1BDBD21D50F0200A991BF /* ringlogger.h in Sources */,
6FBA103F21D6B6FF0051C35F /* TunnelImporter.swift in Sources */,
+ 6F89E17A21EDEB0E00C97BB9 /* StatusItemController.swift in Sources */,
6F4DD16B21DA558800690EAE /* TunnelListRow.swift in Sources */,
5F52D0BF21E3788900283CEA /* NSColor+Hex.swift in Sources */,
6FB1BDBE21D50F0200A991BF /* Logger.swift in Sources */,
diff --git a/WireGuard/WireGuard/Tunnel/TunnelsManager.swift b/WireGuard/WireGuard/Tunnel/TunnelsManager.swift
index 4476c4a0..1b3cc50f 100644
--- a/WireGuard/WireGuard/Tunnel/TunnelsManager.swift
+++ b/WireGuard/WireGuard/Tunnel/TunnelsManager.swift
@@ -222,6 +222,10 @@ class TunnelsManager {
return tunnels.first { $0.name == tunnelName }
}
+ func waitingTunnel() -> TunnelContainer? {
+ return tunnels.first { $0.status == .waiting }
+ }
+
func startActivation(of tunnel: TunnelContainer) {
guard tunnels.contains(tunnel) else { return } // Ensure it's not deleted
guard tunnel.status == .inactive else {
diff --git a/WireGuard/WireGuard/UI/macOS/AppDelegate.swift b/WireGuard/WireGuard/UI/macOS/AppDelegate.swift
index a08f9dc0..3f089875 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 2adee869..c878d79c 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
new file mode 100644
index 00000000..c0a43e77
--- /dev/null
+++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIcon.imageset/StatusBarIcon@1x.png
Binary files differ
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
new file mode 100644
index 00000000..2057c317
--- /dev/null
+++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIcon.imageset/StatusBarIcon@2x.png
Binary files differ
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
new file mode 100644
index 00000000..60cc363a
--- /dev/null
+++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIcon.imageset/StatusBarIcon@3x.png
Binary files differ
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 00000000..aeb8a8ef
--- /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
new file mode 100644
index 00000000..fb9d8f79
--- /dev/null
+++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDimmed.imageset/StatusBarIconDimmed@1x.png
Binary files differ
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
new file mode 100644
index 00000000..2f4e6135
--- /dev/null
+++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDimmed.imageset/StatusBarIconDimmed@2x.png
Binary files differ
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
new file mode 100644
index 00000000..cc5ead92
--- /dev/null
+++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDimmed.imageset/StatusBarIconDimmed@3x.png
Binary files differ
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 00000000..0024a601
--- /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
new file mode 100644
index 00000000..bbbe0c3f
--- /dev/null
+++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot1.imageset/StatusBarIconDot1@1x.png
Binary files differ
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
new file mode 100644
index 00000000..01b5eb37
--- /dev/null
+++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot1.imageset/StatusBarIconDot1@2x.png
Binary files differ
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
new file mode 100644
index 00000000..76afa156
--- /dev/null
+++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot1.imageset/StatusBarIconDot1@3x.png
Binary files differ
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 00000000..8b61c0e8
--- /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
new file mode 100644
index 00000000..a16143f0
--- /dev/null
+++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot2.imageset/StatusBarIconDot2@1x.png
Binary files differ
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
new file mode 100644
index 00000000..ce00482b
--- /dev/null
+++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot2.imageset/StatusBarIconDot2@2x.png
Binary files differ
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
new file mode 100644
index 00000000..82640f7e
--- /dev/null
+++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot2.imageset/StatusBarIconDot2@3x.png
Binary files differ
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 00000000..96da519d
--- /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
new file mode 100644
index 00000000..80e221be
--- /dev/null
+++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot3.imageset/StatusBarIconDot3@1x.png
Binary files differ
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
new file mode 100644
index 00000000..663f92bf
--- /dev/null
+++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot3.imageset/StatusBarIconDot3@2x.png
Binary files differ
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
new file mode 100644
index 00000000..10e43d99
--- /dev/null
+++ b/WireGuard/WireGuard/UI/macOS/Assets.xcassets/StatusBarIconDot3.imageset/StatusBarIconDot3@3x.png
Binary files differ
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
deleted file mode 100644
index 1a7d77cb..00000000
--- a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/WireGuardMacStatusBarIcon.imageset/WireGuardMacStatusBarIcon@1x.png
+++ /dev/null
Binary files differ
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
deleted file mode 100644
index 66c49c10..00000000
--- a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/WireGuardMacStatusBarIcon.imageset/WireGuardMacStatusBarIcon@2x.png
+++ /dev/null
Binary files differ
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
deleted file mode 100644
index e1bcc351..00000000
--- a/WireGuard/WireGuard/UI/macOS/Assets.xcassets/WireGuardMacStatusBarIcon.imageset/WireGuardMacStatusBarIcon@3x.png
+++ /dev/null
Binary files differ
diff --git a/WireGuard/WireGuard/UI/macOS/StatusItemController.swift b/WireGuard/WireGuard/UI/macOS/StatusItemController.swift
new file mode 100644
index 00000000..2568c153
--- /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 78e71ba7..a2f02d8c 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)