clipboard-rs

repository·master·Indexed 41 days ago

https://github.com/churchtao/clipboard-rs

A cross-platform Rust library for interacting with system-level clipboards on Windows, macOS, and Linux. Version 0.3.5 supports reading and writing plain text, HTML, RTF, images, and file lists. It includes a ClipboardWatcher for monitoring clipboard changes and the RustImage trait for image processing and manipulation.

Tokens
4K
Snippets
14
Records
15
Agent score
50%

What's inside clipboard-rs

  1. Read and process images from the clipboard

    master

    Use ctx.get_image() to retrieve clipboard images. The returned image type (likely RustImage) provides methods like save_to_path and thumbnail for processing.

    use clipboard_rs::{common::RustImage, Clipboard, ClipboardContext};
    
    const TMP_PATH: &str = "/tmp/";
    
    fn main() {
    	let ctx = ClipboardContext::new().unwrap();
    	let img = ctx.get_image();
    
    	match img {
    		Ok(img) => {
    			img.save_to_path(format!("{}test.png", TMP_PATH).as_str())
    				.unwrap();
    
    			let resize_img = img.thumbnail(300, 300).unwrap();
    
    			resize_img
    				.save_to_path(format!("{}test_thumbnail.png", TMP_PATH).as_str())
    				.unwrap();
    		}
    		Err(err) => {
    			println!("err={}", err);
    		}
    	}
    }
  2. Perform simple text, HTML, and RTF read/write operations

    master

    You can use ClipboardContext to check for available formats and retrieve common content types like plain text, HTML, or Rich Text (RTF). Use ctx.has(ContentFormat) to check for existence before retrieving.

    use clipboard_rs::{Clipboard, ClipboardContext, ContentFormat};
    
    fn main() {
    	nlet ctx = ClipboardContext::new().unwrap();
    	let types = ctx.available_formats().unwrap();
    	println!("{:?}", types);
    
    	let has_rtf = ctx.has(ContentFormat::Rtf);
    	println!("has_rtf={}", has_rtf);
    
    	let rtf = ctx.get_rich_text().unwrap_or("".to_string());
    	println!("rtf={}", rtf);
    
    	let has_html = ctx.has(ContentFormat::Html);
    	println!("has_html={}", has_html);
    
    	let html = ctx.get_html().unwrap_or("".to_string());
    
    	let content = ctx.get_text().unwrap_or("".to_string());
    	println!("txt={}", content);
    }
  3. Monitor clipboard changes with ClipboardWatcher

    master

    To react to clipboard changes, implement the ClipboardHandler trait for your manager struct and use ClipboardWatcherContext to start watching. You can obtain a shutdown channel to stop the watcher programmatically.

    use clipboard_rs::{
    	Clipboard,
    	ClipboardContext,
    	ClipboardHandler,
    	ClipboardWatcher,
    	ClipboardWatcherContext,
    };
    use std::{thread, time::Duration};
    
    struct Manager {
    	ctx: ClipboardContext,
    }
    
    impl Manager {
    	pub fn new() -> Self {
    		let ctx = ClipboardContext::new().unwrap();
    		Manager { ctx }
    	}
    }
    
    impl ClipboardHandler for Manager {
    	fn on_clipboard_change(&mut self) {
    		println!(
    			"on_clipboard_change, txt = {}",
    			self.ctx.get_text().unwrap()
    		);
    	}
    }
    
    fn main() {
    	let manager = Manager::new();
    	let mut watcher = ClipboardWatcherContext::new().unwrap();
    
    	// Add handler and get shutdown channel
    	let watcher_shutdown = watcher.add_handler(manager).get_shutdown_channel();
    
    	thread::spawn(move || {
    		thread::sleep(Duration::from_secs(5));
    		println!("stop watch!");
    		watcher_shutdown.stop();
    	});
    
    	println!("start watch!");
    	watcher.start_watch();
    }
  4. Read arbitrary clipboard types using identifiers

    master

    If a specific helper method doesn't exist, you can retrieve raw data for any supported type using ctx.get_buffer(type_identifier). This returns a byte buffer which you can then convert (e.g., to a UTF-8 string).

    use clipboard_rs::{Clipboard, ClipboardContext};
    
    fn main() {
        let ctx = ClipboardContext::new().unwrap();
        let types = ctx.available_formats().unwrap();
        println!("{:?}", types);
    
        // Use a specific type identifier like "public.html"
        let buffer = ctx.get_buffer("public.html").unwrap();
    
        let string = String::from_utf8(buffer).unwrap();
        println!("{}", string);
    }
  5. Configure X11 read timeout for large data

    master

    On Linux (X11), reading large data (like high-resolution images) might fail due to the default 500ms timeout. You can increase this timeout using ClipboardContext::new_with_options and providing ClipboardContextX11Options.

    #[cfg(unix)]
    fn setup_clipboard() -> ClipboardContext {
    	// Set read_timeout to None or a specific duration to prevent interruption
    	ClipboardContext::new_with_options(ClipboardContextX11Options { read_timeout: None }).unwrap()
    }
    
    #[cfg(not(unix))]
    fn setup_clipboard(ctx: &mut ClipboardContext) -> ClipboardContext {
    	ClipboardContext::new().unwrap()
    }
  6. Supported clipboard formats and platform compatibility

    master

    The library supports various data formats across different operating systems. Note that Android support is currently under development (🚧).

    TypeWindowsmacOSLinux (X11)iOS (Beta)Android
    Plain Text✅✅✅✅🚧
    HTML✅✅✅✅🚧
    RTF✅✅✅✅🚧
    ImagesPNG/DIBV5PNG/TIFFPNGPNG🚧
    File Lists✅✅✅❌🚧
    Custom Types✅✅✅✅🚧
    Change Monitoring✅✅✅✅🚧
  7. Use RustImageBuffer for encoded image data

    master

    A RustImageBuffer is a wrapper around a Vec<u8> containing encoded image data (e.g., a complete PNG or JPEG file). It is the return type for all conversion methods in the RustImage trait.

    Use get_bytes() to access the raw encoded byte slice or save_to_path(path) to write the buffer directly to a file.

    #[cfg(feature = "image")]
    impl RustImageBuffer {
        pub fn get_bytes(&self) -> &[u8] {
            &self.0
        }
    
        pub fn save_to_path(&self, path: &str) -> Result<()> {
            std::fs::write(path, &self.0)?;
            Ok(())
        }
    }
  8. Process and manipulate images with the RustImage trait

    master

    If the image feature is enabled, you can use the RustImage trait to perform advanced image operations on clipboard image data. This trait works with the RustImageData struct.

    Key capabilities:

    • Creation: Load images from paths (from_path), byte slices (from_bytes), or DynamicImage objects (from_dynamic_image).
    • Resizing: Create a scaled-down version that preserves aspect ratio (thumbnail) or resize exactly to dimensions (resize).
    • Encoding/Conversion: Convert images to specific formats like JPEG (to_jpeg), PNG (to_png), or BMP (to_bitmap, Windows only) which return a RustImageBuffer.
    • Persistence: Save the image directly to a file (save_to_path).
    • Access: Get the underlying DynamicImage or convert to Rgba8 format.
    use clipboard_rs::RustImage;
    
    // Example: Loading and resizing an image
    let img = RustImageData::from_path("input.png")?;
    let small_img = img.thumbnail(100, 100)?;
    
    // Example: Converting to PNG bytes
    let png_buffer = small_img.to_png()?;
    let bytes = png_buffer.get_bytes();
    
    // Example: Saving to disk
    small_img.save_to_path("output.png")?;
  9. Handle clipboard changes with ClipboardHandler

    master

    To react to clipboard updates, implement the ClipboardHandler trait. This is typically used in conjunction with a listener loop or event system provided by the library to trigger logic whenever the clipboard content changes.

    pub trait ClipboardHandler {
    	fn on_clipboard_change(&mut self);
    }
  10. Represent clipboard content with ClipboardContent

    master

    The ClipboardContent enum represents the various types of data that can be stored in the clipboard. It supports text, RTF, HTML, images (requires image feature), file paths, and generic 'other' data.

    By implementing the ContentData trait, you can interact with any ClipboardContent variant using a unified interface to retrieve its format, raw bytes, or string representation.

    use clipboard_rs::ClipboardContent;
    
    // Example of matching on content
    match content {
        ClipboardContent::Text(t) => println!("Text: {}", t),
        ClipboardContent::Image(img) => println!("Image data available"),
        _ => println!("Other content type"),
    }
    
    // Using ContentData methods
    let format = content.get_format();
    let bytes = content.as_bytes();
    let text_result = content.as_str();
  11. Use the Clipboard trait to read and write content

    master

    The Clipboard trait provides the core interface for interacting with the system clipboard. It supports reading various data formats (plain text, rich text, HTML, images, and files) and writing them back to the clipboard.

    Key Capabilities:

    • Reading: Use get_text(), get_rich_text(), get_html(), get_image() (requires image feature), or get_buffer(format: &str) for raw byte access.
    • Writing: Use set_text(), set_rich_text(), set_html(), set_image() (requires image feature), or set_buffer(format: &str, buffer: Vec<u8>).
    • Metadata: Check available formats with available_formats() or check for a specific format with has(format: ContentFormat).
    • Management: Clear the clipboard using clear() or set multiple contents at once using set(contents: &[ClipboardContent]).
    // Example: Reading and writing text
    fn handle_clipboard(clipboard: &impl Clipboard) -> Result<()> {
        // Read text
        let text = clipboard.get_text()?;
        println!("Clipboard contains: {}", text);
    
        // Write text
        clipboard.set_text("Hello from clipboard-rs!".to_string())?;
        Ok(())
    }