Skip to content

Commit

Permalink
improved document opening scenario handling
Browse files Browse the repository at this point in the history
  • Loading branch information
gingerbeardman committed Aug 23, 2024
1 parent feaa002 commit 0a6b6bc
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 44 deletions.
4 changes: 2 additions & 2 deletions Stapler.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
119 changes: 77 additions & 42 deletions Stapler/StaplerApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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..<document.aliases.count))

// Close the document
if let windowController = NSDocumentController.shared.document(for: url)?.windowControllers.first {
windowController.close()
}

// If this was the only document and the app was just launched, quit the app
if appStateManager.wasJustLaunched && !appStateManager.hasActiveDocument {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
NSApp.terminate(nil)
}
}
} catch {
logger.error("Error handling document opening: \(error.localizedDescription)")
}
}
}
}
let scenario = determineOpeningScenario()

switch scenario {
case .launchedWithDocument:
logger.info("Document Opening Scenario: launchedWithDocument")
handleLaunchedWithDocument(url)
case .resumedBySystem:
logger.info("Document Opening Scenario: resumedBySystem")
// Handle resumed by system scenario
break
case .openedThroughFileMenu:
logger.info("Document Opening Scenario: openedThroughFileMenu")
// Handle opened through file menu scenario
break
case .unknown:
logger.info("Document Opening Scenario: unknown")
// Handle unknown scenarios
break
}

// Reset the wasJustLaunched flag
appStateManager.wasJustLaunched = false
}

private func determineOpeningScenario() -> 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..<document.aliases.count))

// Close the document
if let windowController = NSDocumentController.shared.document(for: url)?.windowControllers.first {
windowController.close()
}

// If this was the only document and the app was just launched, quit the app
if NSDocumentController.shared.documents.count == 1 {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
NSApp.terminate(nil)
}
}
} catch {
logger.error("Error handling document opening: \(error.localizedDescription)")
}
}
}
}

var body: some Scene {
DocumentGroup(newDocument: StaplerDocument()) { file in
ContentView(document: file.$document, hasSelection: $hasSelection)
Expand Down

0 comments on commit 0a6b6bc

Please sign in to comment.