mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-08-24 16:11:43 +00:00
macos: preview images in the clipboard read confirmation dialog
This commit is contained in:
@@ -56,6 +56,7 @@ class ClipboardConfirmationController: NSWindowController {
|
||||
request: confirmation.kind,
|
||||
programName: confirmation.programName,
|
||||
canRemember: confirmation.canRemember,
|
||||
previewImage: confirmation.previewImage,
|
||||
delegate: delegate
|
||||
))
|
||||
}
|
||||
|
||||
@@ -39,6 +39,10 @@ struct ClipboardConfirmationView: View {
|
||||
/// grant, showing the remember toggle.
|
||||
var canRemember: Bool = false
|
||||
|
||||
/// An image decoded from the request contents, shown scaled in
|
||||
/// place of most of the text area when present.
|
||||
var previewImage: NSImage?
|
||||
|
||||
/// Optional delegate to get results. If this is nil, then this view will never close on its own.
|
||||
weak var delegate: ClipboardConfirmationViewDelegate?
|
||||
|
||||
@@ -62,9 +66,17 @@ struct ClipboardConfirmationView: View {
|
||||
.padding()
|
||||
}
|
||||
|
||||
TextEditor(text: .constant(contents))
|
||||
.focusable(false)
|
||||
.font(.system(.body, design: .monospaced))
|
||||
if let previewImage {
|
||||
Image(nsImage: previewImage)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
.padding(.horizontal)
|
||||
} else {
|
||||
TextEditor(text: .constant(contents))
|
||||
.focusable(false)
|
||||
.font(.system(.body, design: .monospaced))
|
||||
}
|
||||
|
||||
if canRemember {
|
||||
Toggle("Remember this choice for the session", isOn: $remember)
|
||||
|
||||
@@ -391,6 +391,13 @@ extension Ghostty {
|
||||
.flatMap { String(data: $0.data, encoding: .utf8) }
|
||||
?? reps.map { "\($0.mime) (\($0.data.count) bytes)" }.joined(separator: "\n")
|
||||
|
||||
// Decode an image representation so the dialog can preview
|
||||
// exactly what would be disclosed rather than a byte count.
|
||||
let previewImage: NSImage? = reps.lazy
|
||||
.filter { $0.mime.hasPrefix("image/") }
|
||||
.compactMap { NSImage(data: $0.data) }
|
||||
.first
|
||||
|
||||
// libghostty reaches this callback only when the request attempted
|
||||
// by readClipboard requires confirmation. Reads allowed by policy
|
||||
// complete immediately and never become pending Swift state.
|
||||
@@ -399,7 +406,8 @@ extension Ghostty {
|
||||
contents: display,
|
||||
kind: kind,
|
||||
programName: c.name.map { String(cString: $0) },
|
||||
canRemember: c.can_remember
|
||||
canRemember: c.can_remember,
|
||||
previewImage: previewImage
|
||||
) { surfaceView, confirmed, remember in
|
||||
guard let surface = surfaceView.surface else { return }
|
||||
if confirmed {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import AppKit
|
||||
import Foundation
|
||||
import GhosttyKit
|
||||
|
||||
@@ -81,6 +82,11 @@ extension Ghostty {
|
||||
/// grant, showing a remember option in the prompt.
|
||||
let canRemember: Bool
|
||||
|
||||
/// An image decoded from the request contents, previewed scaled
|
||||
/// in the dialog when the request carries an image
|
||||
/// representation.
|
||||
let previewImage: NSImage?
|
||||
|
||||
/// Called exactly once with whether the user confirmed the
|
||||
/// request and whether their decision should be remembered.
|
||||
private var completion: ((SurfaceView, Bool, Bool) -> Void)?
|
||||
@@ -91,6 +97,7 @@ extension Ghostty {
|
||||
kind: ClipboardRequest,
|
||||
programName: String? = nil,
|
||||
canRemember: Bool = false,
|
||||
previewImage: NSImage? = nil,
|
||||
completion: @escaping (SurfaceView, Bool, Bool) -> Void
|
||||
) {
|
||||
self.surface = surface
|
||||
@@ -98,6 +105,7 @@ extension Ghostty {
|
||||
self.kind = kind
|
||||
self.programName = programName
|
||||
self.canRemember = canRemember
|
||||
self.previewImage = previewImage
|
||||
self.completion = completion
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user