diff --git a/crates/gpui/src/platform/mac/platform.rs b/crates/gpui/src/platform/mac/platform.rs index 244350169caffef10ea2740a30e36772506e6145..4e0ee9f2c5773c014aa84ff0e69efb83cf5c54a7 100644 --- a/crates/gpui/src/platform/mac/platform.rs +++ b/crates/gpui/src/platform/mac/platform.rs @@ -1124,7 +1124,32 @@ impl Platform for MacPlatform { } } - // If it wasn't a string, try the various supported image types. + // Next, check for URL flavors (including file URLs). Some tools only provide a URL + // with no plain text entry. + { + // Try the modern UTType identifiers first. + let file_url_type: id = ns_string("public.file-url"); + let url_type: id = ns_string("public.url"); + + let url_data = if msg_send![types, containsObject: file_url_type] { + pasteboard.dataForType(file_url_type) + } else if msg_send![types, containsObject: url_type] { + pasteboard.dataForType(url_type) + } else { + nil + }; + + if url_data != nil && !url_data.bytes().is_null() { + let bytes = slice::from_raw_parts( + url_data.bytes() as *mut u8, + url_data.length() as usize, + ); + + return Some(self.read_string_from_clipboard(&state, bytes)); + } + } + + // If it wasn't a string or URL, try the various supported image types. for format in ImageFormat::iter() { if let Some(item) = try_clipboard_image(pasteboard, format) { return Some(item); @@ -1132,7 +1157,7 @@ impl Platform for MacPlatform { } } - // If it wasn't a string or a supported image type, give up. + // If it wasn't a string, URL, or a supported image type, give up. None } @@ -1707,6 +1732,40 @@ mod tests { ); } + #[test] + fn test_file_url_reads_as_url_string() { + let platform = build_platform(); + + // Create a file URL for an arbitrary test path and write it to the pasteboard. + // This path does not need to exist; we only validate URL→path conversion. + let mock_path = "/tmp/zed-clipboard-file-url-test"; + unsafe { + // Build an NSURL from the file path + let url: id = msg_send![class!(NSURL), fileURLWithPath: ns_string(mock_path)]; + let abs: id = msg_send![url, absoluteString]; + + // Encode the URL string as UTF-8 bytes + let len: usize = msg_send![abs, lengthOfBytesUsingEncoding: NSUTF8StringEncoding]; + let bytes_ptr = abs.UTF8String() as *const u8; + let data = NSData::dataWithBytes_length_(nil, bytes_ptr as *const c_void, len as u64); + + // Write as public.file-url to the unique pasteboard + let file_url_type: id = ns_string("public.file-url"); + platform + .0 + .lock() + .pasteboard + .setData_forType(data, file_url_type); + } + + // Ensure the clipboard read returns the URL string, not a converted path + let expected_url = format!("file://{}", mock_path); + assert_eq!( + platform.read_from_clipboard(), + Some(ClipboardItem::new_string(expected_url)) + ); + } + fn build_platform() -> MacPlatform { let platform = MacPlatform::new(false); platform.0.lock().pasteboard = unsafe { NSPasteboard::pasteboardWithUniqueName(nil) };