fix: capture screenshot for app intents views as NSImage (#8180)

SwiftUI's ImageRenderer must not be called outside the main thread.

The `@MainActor` annotation is only relevant for our own code, not
for calls from frameworks. The machinations around Shortcuts end up
calling the displayRepresentation method outside the main thread.

By capturing the screenshot as NSImage, all data is retained and can
be processed outside the main thread.

Thread in Discord:
https://discord.com/channels/1005603569187160125/1403384231694172372
This commit is contained in:
Mitchell Hashimoto
2025-08-08 10:25:56 -07:00
committed by GitHub

View File

@@ -14,7 +14,7 @@ struct TerminalEntity: AppEntity {
@Property(title: "Kind")
var kind: Kind
var screenshot: Image?
var screenshot: NSImage?
static var typeDisplayRepresentation: TypeDisplayRepresentation {
TypeDisplayRepresentation(name: "Terminal")
@@ -24,8 +24,7 @@ struct TerminalEntity: AppEntity {
var displayRepresentation: DisplayRepresentation {
var rep = DisplayRepresentation(title: "\(title)")
if let screenshot,
let nsImage = ImageRenderer(content: screenshot).nsImage,
let data = nsImage.tiffRepresentation {
let data = screenshot.tiffRepresentation {
rep.image = .init(data: data)
}
@@ -45,11 +44,14 @@ struct TerminalEntity: AppEntity {
static var defaultQuery = TerminalQuery()
@MainActor
init(_ view: Ghostty.SurfaceView) {
self.id = view.uuid
self.title = view.title
self.workingDirectory = view.pwd
self.screenshot = view.screenshot()
if let nsImage = ImageRenderer(content: view.screenshot()).nsImage {
self.screenshot = nsImage
}
// Determine the kind based on the window controller type
if view.window?.windowController is QuickTerminalController {