summaryrefslogtreecommitdiff
path: root/macos/Sources
diff options
context:
space:
mode:
authorMitchell Hashimoto <m@mitchellh.com>2025-09-19 11:44:37 -0700
committerMitchell Hashimoto <m@mitchellh.com>2025-09-19 11:44:46 -0700
commitd27bc69f2e1b59703afa28b1576ca69d9ff173e6 (patch)
tree6df7779897dfbee2610f229d18e0cbc278e9dd8b /macos/Sources
parent1b6cda2b1046b80df7fa33bb5f4b9dea8863445a (diff)
macos: correct SurfaceView supported send/receive types for services
Fixes #8785 This is the callback AppKit sends when it wants to know if our application can handle sending and receiving certain types of data. The prior implementaiton was incorrect and would erroneously claim support over combinations that we couldn't handle (at least, at the SurfaceView layer). This corrects the implementation. The services we expect still show up and the error in 8785 goes away.
Diffstat (limited to 'macos/Sources')
-rw-r--r--macos/Sources/Ghostty/SurfaceView_AppKit.swift45
1 files changed, 33 insertions, 12 deletions
diff --git a/macos/Sources/Ghostty/SurfaceView_AppKit.swift b/macos/Sources/Ghostty/SurfaceView_AppKit.swift
index 03c113209..22784d164 100644
--- a/macos/Sources/Ghostty/SurfaceView_AppKit.swift
+++ b/macos/Sources/Ghostty/SurfaceView_AppKit.swift
@@ -1815,18 +1815,39 @@ extension Ghostty.SurfaceView: NSServicesMenuRequestor {
forSendType sendType: NSPasteboard.PasteboardType?,
returnType: NSPasteboard.PasteboardType?
) -> Any? {
- // Types that we accept sent to us
- let accepted: [NSPasteboard.PasteboardType] = [.string, .init("public.utf8-plain-text")]
-
- // We can always receive the accepted types
- if (returnType == nil || accepted.contains(returnType!)) {
- return self
- }
-
- // If we have a selection we can send the accepted types too
- if ((self.surface != nil && ghostty_surface_has_selection(self.surface)) &&
- (sendType == nil || accepted.contains(sendType!))
- ) {
+ // This function confused me a bit so I'm going to add my own commentary on
+ // how this works. macOS sends this callback with the given send/return types and
+ // we must return the responder capable of handling the COMBINATION of those send
+ // and return types (or super up if we can't handle it).
+ //
+ // The "COMBINATION" bit is key: we might get sent a string (we can handle that)
+ // but get requested an image (we can't handle that at the time of writing this),
+ // so we must bubble up.
+
+ // Types we can receive
+ let receivable: [NSPasteboard.PasteboardType] = [.string, .init("public.utf8-plain-text")]
+
+ // Types that we can send. Currently the same as receivable but I'm separating
+ // this out so we can modify this in the future.
+ let sendable: [NSPasteboard.PasteboardType] = receivable
+
+ // The sendable types that require a selection (currently all)
+ let sendableRequiresSelection = sendable
+
+ // If we expect no data to be sent/received we can obviously handle it (that's
+ // the nil check), otherwise it must conform to the types we support on both sides.
+ if (returnType == nil || receivable.contains(returnType!)) &&
+ (sendType == nil || sendable.contains(sendType!)) {
+ // If we're expected to send back a type that requires selection, then
+ // verify that we have a selection. We do this within this block because
+ // validateRequestor is called a LOT and we want to prevent unnecessary
+ // performance hits because `ghostty_surface_has_selection` isn't free.
+ if let sendType, sendableRequiresSelection.contains(sendType) {
+ if surface == nil || !ghostty_surface_has_selection(surface) {
+ return super.validRequestor(forSendType: sendType, returnType: returnType)
+ }
+ }
+
return self
}