From 0a6b6bc1af09ab3dcc2771998537e6d3c1b70aef Mon Sep 17 00:00:00 2001 From: Matt Sephton Date: Fri, 23 Aug 2024 16:35:52 +0100 Subject: [PATCH] improved document opening scenario handling --- Stapler.xcodeproj/project.pbxproj | 4 +- Stapler/StaplerApp.swift | 119 +++++++++++++++++++----------- 2 files changed, 79 insertions(+), 44 deletions(-) diff --git a/Stapler.xcodeproj/project.pbxproj b/Stapler.xcodeproj/project.pbxproj index 5257f42..b37d81c 100644 --- a/Stapler.xcodeproj/project.pbxproj +++ b/Stapler.xcodeproj/project.pbxproj @@ -273,7 +273,7 @@ CODE_SIGN_ENTITLEMENTS = Stapler/Stapler.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 240822; + CURRENT_PROJECT_VERSION = 240823; DEVELOPMENT_ASSET_PATHS = "\"Stapler/Preview Content\""; DEVELOPMENT_TEAM = Q3Z639YB49; ENABLE_HARDENED_RUNTIME = YES; @@ -305,7 +305,7 @@ CODE_SIGN_ENTITLEMENTS = Stapler/Stapler.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 240822; + CURRENT_PROJECT_VERSION = 240823; DEVELOPMENT_ASSET_PATHS = "\"Stapler/Preview Content\""; DEVELOPMENT_TEAM = Q3Z639YB49; ENABLE_HARDENED_RUNTIME = YES; diff --git a/Stapler/StaplerApp.swift b/Stapler/StaplerApp.swift index f242aae..ccd13b5 100644 --- a/Stapler/StaplerApp.swift +++ b/Stapler/StaplerApp.swift @@ -3,6 +3,15 @@ import UniformTypeIdentifiers import Quartz import os +// Define an enum for the different document opening scenarios +enum DocumentOpeningScenario { + case launchedWithDocument + case resumedBySystem + case openedThroughFileMenu + case unknown +} + +// Modify the AppDelegate to work with the new AppStateManager class AppDelegate: NSObject, NSApplicationDelegate { func setupDefaultCommandKeyDelay() { if UserDefaults.standard.object(forKey: "CommandKeyDelay") == nil { @@ -562,54 +571,80 @@ struct StaplerApp: App { } func handleDocumentOpening(_ url: URL) { - let currentEvent = NSApplication.shared.currentEvent - let isOpenedFromFinder = currentEvent != nil && currentEvent?.type == .appKitDefined && currentEvent?.subtype.rawValue == NSEvent.EventSubtype.applicationActivated.rawValue - - if isOpenedFromFinder { - // Delay the check for Command key to allow it to be released - DispatchQueue.main.asyncAfter(deadline: .now() + commandKeyDelay) { - let commandKeyPressed = NSEvent.modifierFlags.contains(.command) - - if !commandKeyPressed { - // Launch all items and close the document - DispatchQueue.main.async { - do { - // Start accessing the security-scoped resource - guard url.startAccessingSecurityScopedResource() else { - logger.error("Failed to access security-scoped resource") - return - } - defer { - url.stopAccessingSecurityScopedResource() - } - - let document = try StaplerDocument(contentsOf: url) - let viewModel = StaplerViewModel(document: document) - viewModel.launchAliases(at: IndexSet(integersIn: 0.. DocumentOpeningScenario { + let currentEvent = NSApplication.shared.currentEvent + let isOpenedFromFinder = currentEvent != nil && currentEvent?.type == .appKitDefined && currentEvent?.subtype.rawValue == NSEvent.EventSubtype.applicationActivated.rawValue + + if appStateManager.wasJustLaunched && isOpenedFromFinder { + return .launchedWithDocument + } else if NSApp.isActive { + return .openedThroughFileMenu + } else if ProcessInfo.processInfo.isOperatingSystemAtLeast(OperatingSystemVersion(majorVersion: 10, minorVersion: 15, patchVersion: 0)) { + // Check if the app was resumed by the system (macOS 10.15+) + return .resumedBySystem + } else { + return .unknown + } + } + + private func handleLaunchedWithDocument(_ url: URL) { + DispatchQueue.main.asyncAfter(deadline: .now() + commandKeyDelay) { + let commandKeyPressed = NSEvent.modifierFlags.contains(.command) + + if !commandKeyPressed { + do { + guard url.startAccessingSecurityScopedResource() else { + logger.error("Failed to access security-scoped resource") + return + } + defer { url.stopAccessingSecurityScopedResource() } + + let document = try StaplerDocument(contentsOf: url) + let viewModel = StaplerViewModel(document: document) + viewModel.launchAliases(at: IndexSet(integersIn: 0..