Add edit parameter to URL scheme for capture-then-edit workflow

snippingtool://region?edit=true now captures a region screenshot and
immediately opens the editor. Works with all modes: fullscreen, window,
region. Without ?edit=true, behavior is unchanged.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-01 17:51:44 +02:00
co-authored by Claude Opus 4.6
parent f6e90047a8
commit 59b3f8d2a1
+29 -14
View File
@@ -105,34 +105,44 @@ final class AppCoordinator: ObservableObject {
func handle(url: URL) { func handle(url: URL) {
guard url.scheme?.caseInsensitiveCompare("snippingtool") == .orderedSame else { return } guard url.scheme?.caseInsensitiveCompare("snippingtool") == .orderedSame else { return }
let modeString = url.host?.lowercased() let components = URLComponents(url: url, resolvingAgainstBaseURL: false)
?? URLComponents(url: url, resolvingAgainstBaseURL: false)? let queryItems = components?.queryItems ?? []
.queryItems?
.first(where: { $0.name.caseInsensitiveCompare("mode") == .orderedSame })?
.value?
.lowercased()
let modeString = url.host?.lowercased()
?? queryItems.first(where: { $0.name.caseInsensitiveCompare("mode") == .orderedSame })?
.value?.lowercased()
let wantsEditor = queryItems.first(where: { $0.name.caseInsensitiveCompare("edit") == .orderedSame })?
.value?.lowercased() ?? "false"
let openEditor = ["true", "1", "yes"].contains(wantsEditor)
let mode: CaptureMode?
switch modeString { switch modeString {
case "fullscreen", "full", "full-screen", "screen": case "fullscreen", "full", "full-screen", "screen":
capture(mode: .fullScreen) mode = .fullScreen
case "window": case "window":
capture(mode: .window) mode = .window
case "region", "area", "selection": case "region", "area", "selection":
capture(mode: .region) mode = .region
default: default:
mode = nil
NSLog("SnippingTool: unrecognized URL trigger \(url.absoluteString)") NSLog("SnippingTool: unrecognized URL trigger \(url.absoluteString)")
} }
if let mode {
capture(mode: mode, openEditor: openEditor)
}
} }
// MARK: - Capture // MARK: - Capture
func capture(mode: CaptureMode) { func capture(mode: CaptureMode, openEditor: Bool = false) {
let saves = outputAction.savesToFile let saves = outputAction.savesToFile
let copies = outputAction.copiesToClipboard let copies = outputAction.copiesToClipboard
let ext = imageFormat.fileExtension let ext = imageFormat.fileExtension
let targetURL: URL let targetURL: URL
if saves { if saves || openEditor {
try? FileManager.default.createDirectory(at: saveFolder, withIntermediateDirectories: true) try? FileManager.default.createDirectory(at: saveFolder, withIntermediateDirectories: true)
targetURL = saveFolder.appendingPathComponent(Self.filename(ext: ext)) targetURL = saveFolder.appendingPathComponent(Self.filename(ext: ext))
} else { } else {
@@ -148,7 +158,7 @@ final class AppCoordinator: ObservableObject {
process.arguments = arguments process.arguments = arguments
process.terminationHandler = { [weak self] _ in process.terminationHandler = { [weak self] _ in
DispatchQueue.main.async { DispatchQueue.main.async {
self?.handleCaptured(at: targetURL, saves: saves, copies: copies) self?.handleCaptured(at: targetURL, saves: saves, copies: copies, openEditor: openEditor)
} }
} }
@@ -159,10 +169,15 @@ final class AppCoordinator: ObservableObject {
} }
} }
private func handleCaptured(at url: URL, saves: Bool, copies: Bool) { private func handleCaptured(at url: URL, saves: Bool, copies: Bool, openEditor: Bool = false) {
guard FileManager.default.fileExists(atPath: url.path) else { return } guard FileManager.default.fileExists(atPath: url.path) else { return }
lastCapturedURL = saves ? url : nil lastCapturedURL = url
if openEditor, let image = NSImage(contentsOf: url) {
self.openEditor(image: image, sourceURL: url)
return
}
if copies, let image = NSImage(contentsOf: url) { if copies, let image = NSImage(contentsOf: url) {
let pasteboard = NSPasteboard.general let pasteboard = NSPasteboard.general