nspasteboard/
nspasteboard.rs

1//! Read from the global pasteboard, and write a new string into it.
2//!
3//! Works on macOS 10.7+
4#![deny(unsafe_op_in_unsafe_fn)]
5
6use objc2::rc::Retained;
7use objc2::runtime::ProtocolObject;
8use objc2::ClassType;
9use objc2_app_kit::{NSPasteboard, NSPasteboardTypeString};
10use objc2_foundation::{NSArray, NSString};
11
12/// Simplest implementation
13pub fn get_text_1(pasteboard: &NSPasteboard) -> Option<Retained<NSString>> {
14    unsafe { pasteboard.stringForType(NSPasteboardTypeString) }
15}
16
17/// More complex implementation using `readObjectsForClasses:options:`,
18/// intended to show how some patterns might require more work.
19pub fn get_text_2(pasteboard: &NSPasteboard) -> Option<Retained<NSString>> {
20    let class_array = NSArray::from_slice(&[NSString::class()]);
21    let objects = unsafe { pasteboard.readObjectsForClasses_options(&class_array, None) };
22
23    let obj = objects?.firstObject()?;
24    // We now have to convert the object into an NSString, which we know it to
25    // be since that's what we told `readObjectsForClasses:options:` we wanted.
26    Some(obj.downcast::<NSString>().unwrap())
27}
28
29pub fn set_text(pasteboard: &NSPasteboard, text: &NSString) {
30    let _ = unsafe { pasteboard.clearContents() };
31    let obj = ProtocolObject::from_ref(text);
32    let objects = NSArray::from_slice(&[obj]);
33    let res = unsafe { pasteboard.writeObjects(&objects) };
34    if !res {
35        panic!("Failed writing to pasteboard");
36    }
37}
38
39fn main() {
40    let pasteboard = unsafe { NSPasteboard::generalPasteboard() };
41    let impl_1 = get_text_1(&pasteboard);
42    let impl_2 = get_text_2(&pasteboard);
43    println!("Pasteboard text from implementation 1 was: {impl_1:?}");
44    println!("Pasteboard text from implementation 2 was: {impl_2:?}");
45    assert_eq!(impl_1, impl_2);
46
47    let s = NSString::from_str("Hello, world!");
48    set_text(&pasteboard, &s);
49    println!("Now the pasteboard text should be: {s:?}");
50    assert_eq!(Some(s), get_text_1(&pasteboard));
51}