Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,7 @@ fastlane/test_output

# Editor bundle build (scripts/editor-bundle)
node_modules/

# Local design tooling
.superpowers/
.worktrees/
2 changes: 1 addition & 1 deletion Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<key>CFBundleTypeName</key>
<string>Markdown Document</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<string>Editor</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSItemContentTypes</key>
Expand Down
55 changes: 23 additions & 32 deletions md-preview/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,12 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
private weak var darkAppearanceMenuItem: NSMenuItem?
private weak var normalContentWidthMenuItem: NSMenuItem?
private weak var fullContentWidthMenuItem: NSMenuItem?
private var isOpeningDocumentFromPrompt = false
private var isPromptingForDocument = false
private var isDocumentPromptScheduled = false
private var documentPromptScheduleGeneration = 0
private var isUntitledDocumentScheduled = false
private var untitledDocumentScheduleGeneration = 0
private var didReceiveOpenURLsDuringLaunch = false
private var hasFinishedLaunching = false
private var pendingOpenURLCount = 0
private weak var activeOpenPanel: NSOpenPanel?
private var isTerminationSaveInProgress = false
private var pendingTerminationSaveCount = 0
private var terminationSaveFailed = false
Expand All @@ -140,7 +138,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
installZoomMenuItemIcons()
hasFinishedLaunching = true
if !didReceiveOpenURLsDuringLaunch {
scheduleDocumentPrompt(requiresNoDocuments: true)
scheduleUntitledDocument(requiresNoDocuments: true)
}
}

Expand All @@ -149,13 +147,13 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
}

func applicationOpenUntitledFile(_ sender: NSApplication) -> Bool {
scheduleDocumentPrompt(requiresNoDocuments: true)
scheduleUntitledDocument(requiresNoDocuments: true)
return true
}

func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
if !flag {
scheduleDocumentPrompt(requiresNoDocuments: true)
scheduleUntitledDocument(requiresNoDocuments: true)
return false
}
return true
Expand All @@ -165,7 +163,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
if !hasFinishedLaunching {
didReceiveOpenURLsDuringLaunch = true
}
cancelScheduledDocumentPrompt()
cancelScheduledUntitledDocument()

for url in urls {
if url.isExistingDirectory {
Expand All @@ -182,7 +180,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
guard let self else { return }
self.pendingOpenURLCount -= 1
if error != nil, self.pendingOpenURLCount == 0 {
self.scheduleDocumentPrompt(requiresNoDocuments: true)
self.scheduleUntitledDocument(requiresNoDocuments: true)
}
}
}
Expand Down Expand Up @@ -340,47 +338,40 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
defer { isPromptingForDocument = false }

let panel = makeOpenPanel()
activeOpenPanel = panel
defer { activeOpenPanel = nil }
guard panel.runModal() == .OK, let url = panel.url else { return }
if url.isExistingDirectory {
openFolder(url)
return
}

isOpeningDocumentFromPrompt = true
NSDocumentController.shared.openDocument(withContentsOf: url,
display: true) { [weak self] _, _, error in
self?.isOpeningDocumentFromPrompt = false
display: true) { _, _, error in
guard let error else { return }
NSAlert(error: error).runModal()
}
}

private func scheduleDocumentPrompt(requiresNoDocuments: Bool = false) {
guard !isPromptingForDocument,
!isDocumentPromptScheduled else { return }

isDocumentPromptScheduled = true
documentPromptScheduleGeneration += 1
let scheduleGeneration = documentPromptScheduleGeneration
private func scheduleUntitledDocument(requiresNoDocuments: Bool = false) {
guard !isUntitledDocumentScheduled else { return }
isUntitledDocumentScheduled = true
untitledDocumentScheduleGeneration += 1
let generation = untitledDocumentScheduleGeneration
DispatchQueue.main.async { [weak self] in
guard let self else { return }
guard self.documentPromptScheduleGeneration == scheduleGeneration else { return }
self.isDocumentPromptScheduled = false
guard let self,
self.untitledDocumentScheduleGeneration == generation else { return }
self.isUntitledDocumentScheduled = false
guard !requiresNoDocuments || NSDocumentController.shared.documents.isEmpty else { return }
guard !self.isPromptingForDocument else { return }
guard self.pendingOpenURLCount == 0 else { return }
NSApp.activate(ignoringOtherApps: true)
self.promptForDocument()
NSDocumentController.shared.newDocument(nil)
}
}

private func cancelScheduledDocumentPrompt() {
// Dismiss a prompt that already made it past the generation check and
// is sitting in runModal() when the open event arrives.
activeOpenPanel?.cancel(nil)
guard isDocumentPromptScheduled else { return }
documentPromptScheduleGeneration += 1
isDocumentPromptScheduled = false
private func cancelScheduledUntitledDocument() {
guard isUntitledDocumentScheduled else { return }
untitledDocumentScheduleGeneration += 1
isUntitledDocumentScheduled = false
}

private func openFolder(_ url: URL) {
Expand Down
Loading
Loading