fix: capture screenshot for app intents views as NSImage

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.
pull/8180/head
Alexander Lais 2025-08-08 16:53:11 +02:00
parent a0eb4285b2
commit 1f378e6775
No known key found for this signature in database
1 changed files with 6 additions and 4 deletions

View File

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