From 2f6175e6f00d123537eee64855cf5de769f86533 Mon Sep 17 00:00:00 2001 From: xiaogd Date: Tue, 19 Apr 2022 13:25:48 +0800 Subject: [PATCH] Fix issue #3 and #4 --- Doll.xcodeproj/project.pbxproj | 4 +++ Doll/AppDelegate.swift | 12 +++++++ Doll/ContentView.swift | 6 ++-- Doll/Source/MonitorEngine.swift | 34 +++++++++++++------ Doll/Utils/NSEventExtensions.swift | 9 +++++ Doll/Views/StatusBarController.swift | 11 ++++-- .../Sources/Monitor/MonitorService.swift | 1 - 7 files changed, 58 insertions(+), 19 deletions(-) create mode 100644 Doll/Utils/NSEventExtensions.swift diff --git a/Doll.xcodeproj/project.pbxproj b/Doll.xcodeproj/project.pbxproj index a311e51..944b77f 100644 --- a/Doll.xcodeproj/project.pbxproj +++ b/Doll.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 3A05F079FD8ED95600C00E09 /* NSEventExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A05FE1708B1B3E267E75950 /* NSEventExtensions.swift */; }; 3A05F0D44C56AF54405AF0C8 /* README.md in Sources */ = {isa = PBXBuildFile; fileRef = 3A05F569906D4FC793ED3B11 /* README.md */; }; 3A05F16312AEFBD25670304B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3A05FE513B0F76D50EE9A90B /* Assets.xcassets */; }; 3A05F319D3B6EACC3882AF88 /* UserDefaultSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A05F135761A1F95B691AC9F /* UserDefaultSettings.swift */; }; @@ -34,6 +35,7 @@ 3A05F569906D4FC793ED3B11 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = Doll/README.md; sourceTree = ""; }; 3A05F6A27D4869EB06B6E98D /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 3A05F88D951B0284A8B90FF0 /* Doll.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Doll.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 3A05FE1708B1B3E267E75950 /* NSEventExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSEventExtensions.swift; sourceTree = ""; }; 3A05FE513B0F76D50EE9A90B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 3A05FF26C7DEDD4C5CBF1E98 /* Doll.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Doll.entitlements; sourceTree = ""; }; 89CB806427A311400065CA70 /* MonitorCore */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = MonitorCore; sourceTree = ""; }; @@ -120,6 +122,7 @@ children = ( 89CB807527A312F10065CA70 /* ViewExtensions.swift */, 3A05F135761A1F95B691AC9F /* UserDefaultSettings.swift */, + 3A05FE1708B1B3E267E75950 /* NSEventExtensions.swift */, ); path = Utils; sourceTree = ""; @@ -251,6 +254,7 @@ 3A05F319D3B6EACC3882AF88 /* UserDefaultSettings.swift in Sources */, 3A05FBC07A5CF3CCC2701FBC /* AppSettings.swift in Sources */, 3A05F0D44C56AF54405AF0C8 /* README.md in Sources */, + 3A05F079FD8ED95600C00E09 /* NSEventExtensions.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Doll/AppDelegate.swift b/Doll/AppDelegate.swift index a3773af..a50d7fa 100644 --- a/Doll/AppDelegate.swift +++ b/Doll/AppDelegate.swift @@ -2,10 +2,22 @@ import SwiftUI @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { + var appActivated = false + func applicationDidFinishLaunching(_ aNotification: Notification) { MonitorEngine.setup() } + func applicationWillBecomeActive(_ notification: Notification) { + // https://github.com/xiaogdgenuine/Doll/issues/4 + // Create new instance if the app relaunch again from Spotlight or manually open by user + if appActivated { + MonitorEngine.createNewInstanceIfNecessary() + } + + appActivated = true + } + func applicationWillTerminate(_ aNotification: Notification) { // Insert code here to tear down your application } diff --git a/Doll/ContentView.swift b/Doll/ContentView.swift index f9d7f8b..e03089c 100644 --- a/Doll/ContentView.swift +++ b/Doll/ContentView.swift @@ -102,10 +102,8 @@ struct ContentView: View { } } HStack { - if let _ = statusBar.monitoredApp { - Button("Stop monitor") { - statusBar.destroy() - } + Button("Stop monitor") { + statusBar.destroy() } Spacer() diff --git a/Doll/Source/MonitorEngine.swift b/Doll/Source/MonitorEngine.swift index 33573cb..9dc3113 100644 --- a/Doll/Source/MonitorEngine.swift +++ b/Doll/Source/MonitorEngine.swift @@ -21,7 +21,7 @@ class MonitorEngine { } if monitoredApps.count == 0 { - return firstTimeSetup() + return createNewInstance() } monitoredApps.forEach { app in @@ -29,7 +29,7 @@ class MonitorEngine { statusBar.monitorApp(app: app) } } else { - firstTimeSetup() + createNewInstance() } } @@ -64,20 +64,23 @@ class MonitorEngine { saveSelectedApps() if statusBars.count == 0 { - firstTimeSetup() + createNewInstance() } } - private static func saveSelectedApps() { - let data = statusBars.compactMap { - $0.monitoredApp?.bundleId - } - .joined(separator: ",") - UserDefaults.standard.set(data, forKey: SETTING_MONITORED_APP_IDS) - UserDefaults.standard.synchronize() + static func createNewInstanceIfNecessary() { + if let unAssignedMonitor = (statusBars.first { + $0.monitoredApp == nil + }) { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { + unAssignedMonitor.showPopover() + } + } else { + createNewInstance() + } } - private static func firstTimeSetup() { + static func createNewInstance() { let newStatusBar = createNewStatusBar() DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { @@ -85,6 +88,15 @@ class MonitorEngine { } } + private static func saveSelectedApps() { + let data = statusBars.compactMap { + $0.monitoredApp?.bundleId + } + .joined(separator: ",") + UserDefaults.standard.set(data, forKey: SETTING_MONITORED_APP_IDS) + UserDefaults.standard.synchronize() + } + private static func createNewStatusBar() -> StatusBarController { let popover = NSPopover() popover.contentSize = NSSize(width: 600, height: 500) diff --git a/Doll/Utils/NSEventExtensions.swift b/Doll/Utils/NSEventExtensions.swift new file mode 100644 index 0000000..df5c1ec --- /dev/null +++ b/Doll/Utils/NSEventExtensions.swift @@ -0,0 +1,9 @@ +import AppKit + +extension NSEvent { + var isRightClick: Bool { + let rightClick = (self.type == .rightMouseUp) + let controlClick = self.modifierFlags.contains(.control) + return rightClick || controlClick + } +} \ No newline at end of file diff --git a/Doll/Views/StatusBarController.swift b/Doll/Views/StatusBarController.swift index 206eda3..78206b9 100644 --- a/Doll/Views/StatusBarController.swift +++ b/Doll/Views/StatusBarController.swift @@ -18,6 +18,7 @@ class StatusBarController { statusItem = statusBar.statusItem(withLength: iconSize) if let statusBarButton = statusItem.button { + statusBarButton.sendAction(on: [.leftMouseUp, .rightMouseUp]) statusBarButton.image = defaultIcon statusBarButton.image?.size = NSSize(width: iconSize, height: iconSize) statusBarButton.image?.isTemplate = false @@ -38,8 +39,9 @@ class StatusBarController { let noAppSelected = statusItem.button?.image == defaultIcon let isOptionKeyHolding = NSEvent.modifierFlags.contains(.option) + let isRightClick = NSApp.currentEvent?.isRightClick == true - if noAppSelected || isOptionKeyHolding { + if noAppSelected || isOptionKeyHolding || isRightClick { if (mainPopover.isShown) { hidePopover() } else { @@ -65,8 +67,11 @@ class StatusBarController { guard let appFullPath = NSWorkspace.shared.urlForApplication(withBundleIdentifier: app.bundleId)?.absoluteURL.path else { return } + guard let targetBundle = Bundle(path: appFullPath), - let appName = targetBundle.object(forInfoDictionaryKey: kCFBundleNameKey as String) as? String else { + let appName = ( + targetBundle.object(forInfoDictionaryKey: "CFBundleDisplayName") ?? + targetBundle.object(forInfoDictionaryKey: kCFBundleNameKey as String)) as? String else { return } @@ -130,8 +135,8 @@ class StatusBarController { if let monitoredApp = monitoredApp { MonitorService.unObserve(appName: monitoredApp.appName) MonitorEngine.unMonitor(app: monitoredApp) - statusBar.removeStatusItem(statusItem) } + statusBar.removeStatusItem(statusItem) } private func createNotificationPopover(newText: String) -> NSPopover { diff --git a/MonitorCore/Sources/Monitor/MonitorService.swift b/MonitorCore/Sources/Monitor/MonitorService.swift index 5d7e0eb..05da6ca 100644 --- a/MonitorCore/Sources/Monitor/MonitorService.swift +++ b/MonitorCore/Sources/Monitor/MonitorService.swift @@ -45,7 +45,6 @@ public struct MonitorService { public static func unObserve(appName: String) { observedAppInfos.removeValue(forKey: appName) - print(observedAppInfos.count) } public static func openMonitoredApp(appName: String) {