krz/orgstar

A native macOS editor for org-mode files. editor org-mode swift

Sources/Orgstar/DevelopmentHooks.swift

2fa201330f61c801f777baa3f2943d49d8758cda
orgstar/Sources/Orgstar/DevelopmentHooks.swift history · blame · raw

45 lines · 2877 bytes

 1import AppKit
 2
 3/// Switches for checking the app from scripts, read from the environment:
 4/// - `ORGSTAR_DATA_DIR`: where the index and roots live (see `WorkspaceModel.defaultDirectory`).
 5/// - `ORGSTAR_OPEN`: a file to select at launch.
 6/// - `ORGSTAR_ROOT`: a folder to add at launch.
 7/// - `ORGSTAR_WINDOW`: a window to open at launch (`agenda`, `settings`); the snapshot renders it.
 8/// - `ORGSTAR_COMMAND`: commands to run at launch, separated by commas (`app.import-emacs`); a
 9///   sheet or prompt they open is what the snapshot renders.
10/// - `ORGSTAR_ANSWERS`: answers to the prompts those commands ask, in order, separated by commas.
11/// - `ORGSTAR_URL`: an `org-protocol://` link to handle at launch, as if opened from a browser.
12/// - `ORGSTAR_APPEARANCE`: `dark` or `light`, instead of the system's.
13/// - `ORGSTAR_SNAPSHOT`: after `ORGSTAR_SNAPSHOT_DELAY` seconds (default 3), render the main
14///   window to this PNG path and quit. Rendering from inside the app needs no screen-recording
15///   permission.
16enum DevelopmentHooks {
17    static var fileToOpen: String? { ProcessInfo.processInfo.environment["ORGSTAR_OPEN"] }
18    static var rootToAdd: String? { ProcessInfo.processInfo.environment["ORGSTAR_ROOT"] }
19    static var windowToOpen: String? { ProcessInfo.processInfo.environment["ORGSTAR_WINDOW"] }
20    static var commandToRun: String? { ProcessInfo.processInfo.environment["ORGSTAR_COMMAND"] }
21    static var urlToOpen: String? { ProcessInfo.processInfo.environment["ORGSTAR_URL"] }
22    static var answers: [String] { ProcessInfo.processInfo.environment["ORGSTAR_ANSWERS"]?.split(separator: ",").map(String.init) ?? [] }
23
24    @MainActor
25    static func scheduleSnapshot() {
26        let environment = ProcessInfo.processInfo.environment
27        if let appearance = environment["ORGSTAR_APPEARANCE"] {
28            NSApp.appearance = NSAppearance(named: appearance == "dark" ? .darkAqua : .aqua)
29        }
30        guard let path = environment["ORGSTAR_SNAPSHOT"] else { return }
31        let delay = Double(environment["ORGSTAR_SNAPSHOT_DELAY"] ?? "") ?? 3
32        DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
33            let visible = NSApp.windows.filter(\.isVisible)
34            let chosen = windowToOpen.flatMap { id in visible.first { $0.identifier?.rawValue.lowercased().contains(id) == true } } ?? visible.first
35            let window = chosen?.attachedSheet ?? chosen
36            if let view = window?.contentView?.superview,
37               let bitmap = view.bitmapImageRepForCachingDisplay(in: view.bounds) {
38                view.cacheDisplay(in: view.bounds, to: bitmap)
39                try? bitmap.representation(using: .png, properties: [:])?.write(to: URL(fileURLWithPath: path))
40            }
41            if let chosen, let sheet = chosen.attachedSheet { chosen.endSheet(sheet) }
42            NSApp.terminate(nil)
43        }
44    }
45}