codetether_agent/tui/
clipboard.rs1use base64::Engine;
7use std::io::Cursor;
8
9use crate::session::ImageAttachment;
10
11fn is_ssh_or_headless() -> bool {
13 std::env::var("SSH_CONNECTION").is_ok()
14 || std::env::var("SSH_TTY").is_ok()
15 || (std::env::var("TERM")
16 .ok()
17 .map_or(false, |t| t.starts_with("xterm"))
18 && std::env::var("DISPLAY").is_err()
19 && std::env::var("WAYLAND_DISPLAY").is_err())
20}
21
22pub fn get_clipboard_image() -> Option<ImageAttachment> {
25 if is_ssh_or_headless() {
26 return None;
27 }
28
29 let mut clipboard = arboard::Clipboard::new().ok()?;
30 let img_data = clipboard.get_image().ok()?;
31
32 let width = img_data.width;
33 let height = img_data.height;
34 let raw_bytes = img_data.bytes.into_owned();
35
36 let buf: image::ImageBuffer<image::Rgba<u8>, Vec<u8>> =
37 image::ImageBuffer::from_raw(width as u32, height as u32, raw_bytes)?;
38
39 let mut png_bytes = Vec::new();
40 buf.write_to(&mut Cursor::new(&mut png_bytes), image::ImageFormat::Png)
41 .ok()?;
42
43 let b64 = base64::engine::general_purpose::STANDARD.encode(&png_bytes);
44 Some(ImageAttachment {
45 data_url: format!("data:image/png;base64,{b64}"),
46 mime_type: Some("image/png".to_string()),
47 })
48}