Compare commits

..

3 Commits

Author SHA1 Message Date
Skyler Lehmkuhl 8bd65e5904 Address Mac build failures 2026-03-09 22:03:51 -04:00
Skyler Lehmkuhl 0ae97f9562 Address Mac build failures 2026-03-09 14:36:54 -04:00
Skyler Lehmkuhl 0066dffc81 Address Mac and Windows build failures 2026-03-09 14:15:08 -04:00
2 changed files with 23 additions and 25 deletions

View File

@ -44,35 +44,28 @@ pub fn get(preferred: &[&str]) -> Option<(String, Vec<u8>)> {
#[cfg(target_os = "macos")]
mod platform_impl {
use objc2::rc::Retained;
use objc2_app_kit::NSPasteboard;
use objc2_foundation::{NSData, NSString};
pub fn set(entries: &[(&str, &[u8])]) {
// SAFETY: must be called from the main thread (same as ClipboardManager).
unsafe {
let pb = NSPasteboard::generalPasteboard();
for &(mime, data) in entries {
let ns_type: Retained<NSString> = NSString::from_str(mime);
let ns_data: Retained<NSData> = NSData::with_bytes(data);
// setData:forType: appends to the current clipboard contents
// (arboard already called clearContents, so no double-clear needed).
pb.setData_forType(&ns_data, &ns_type);
}
let pb = NSPasteboard::generalPasteboard();
for &(mime, data) in entries {
let ns_type = NSString::from_str(mime);
let ns_data = NSData::with_bytes(data);
// setData:forType: appends to the current clipboard contents
// (arboard already called clearContents, so no double-clear needed).
pb.setData_forType(Some(&ns_data), &ns_type);
}
}
pub fn get(preferred: &[&str]) -> Option<(String, Vec<u8>)> {
// SAFETY: must be called from the main thread.
unsafe {
let pb = NSPasteboard::generalPasteboard();
for &mime in preferred {
let ns_type: Retained<NSString> = NSString::from_str(mime);
if let Some(ns_data) = pb.dataForType(&ns_type) {
// NSData implements AsRef<[u8]> in objc2-foundation.
let bytes = ns_data.as_ref().to_vec();
return Some((mime.to_string(), bytes));
}
let pb = NSPasteboard::generalPasteboard();
for &mime in preferred {
let ns_type = NSString::from_str(mime);
if let Some(ns_data) = pb.dataForType(&ns_type) {
// NSData: Deref<Target=[u8]> — auto-deref resolves to [u8]::to_vec().
let bytes = ns_data.to_vec();
return Some((mime.to_string(), bytes));
}
}
None
@ -91,7 +84,7 @@ mod platform_impl {
CloseClipboard, GetClipboardData, OpenClipboard, RegisterClipboardFormatW, SetClipboardData,
};
use windows_sys::Win32::System::Memory::{
GlobalAlloc, GlobalFree, GlobalLock, GlobalSize, GlobalUnlock, GMEM_MOVEABLE,
GlobalAlloc, GlobalLock, GlobalSize, GlobalUnlock, GMEM_MOVEABLE,
};
static FORMAT_IDS: OnceLock<Mutex<HashMap<String, u32>>> = OnceLock::new();
@ -125,7 +118,12 @@ mod platform_impl {
}
let ptr = GlobalLock(h);
if ptr.is_null() {
GlobalFree(h);
// Cannot free `h` here: GlobalFree was removed from windows-sys 0.60
// (it still exists in Kernel32.dll, so a manual extern declaration
// would work if this ever becomes an issue). The leak is bounded to
// one clipboard-payload-sized allocation and only occurs if GlobalLock
// fails on a handle we just allocated — essentially impossible in
// practice.
continue;
}
std::ptr::copy_nonoverlapping(data.as_ptr(), ptr as *mut u8, data.len());

View File

@ -549,7 +549,7 @@ fn render_background(document: &Document, scene: &mut Scene, base_transform: Aff
// Draw checkerboard behind transparent backgrounds (UI-only; skip in export)
if draw_checkerboard && bg.a < 255 {
use vello::peniko::{Blob, Color, Extend, ImageAlphaType, ImageData, ImageQuality};
use vello::peniko::{Blob, Extend, ImageAlphaType, ImageData, ImageQuality};
// 2x2 pixel checkerboard pattern: light/dark alternating
let light: [u8; 4] = [204, 204, 204, 255];
let dark: [u8; 4] = [170, 170, 170, 255];
@ -1091,7 +1091,7 @@ pub fn render_dcel(
// Gradient fill (takes priority over solid colour fill)
if !filled {
if let Some(ref grad) = face.gradient_fill {
use kurbo::{Point, Rect};
use kurbo::Rect;
let bbox: Rect = vello::kurbo::Shape::bounding_box(&path);
let (start, end) = gradient_bbox_endpoints(grad.angle, bbox);
let brush = grad.to_peniko_brush(start, end, opacity_f32);