дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 19:25:54 +02:00
fix(agents): attach pasted clipboard images on Linux (#2336)
WebKitGTK hands the composer an empty clipboardData when the clipboard holds only an image, as after a GNOME screenshot, and refuses navigator.clipboard.read(). Ctrl+V then attached nothing. A paste that carries no data now reads the image through the GTK clipboard with the new clipboard_image command. Co-authored-by: NealimeKenna <[email protected]>
Цей коміт міститься в:
1 джерело
ff2eb95b01
коміт
e44a3af310
7 files changed
+79
-6
No files matched your search
@@ -31,6 +31,39 @@ pub async fn clipboard_set_file_list(app: AppHandle, paths: Vec<PathBuf>) -> Ide
|
||||
with_clipboard(app, move || Ok(ide_clipboard::set_files(&paths))).await
|
||||
}
|
||||
|
||||
/// The clipboard's image as a PNG data URL, for a paste whose event carried no
|
||||
/// files: WebKitGTK leaves `clipboardData` empty for a raw image (a screenshot).
|
||||
/// None when the clipboard holds no image, and always on other platforms.
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn clipboard_image(app: AppHandle) -> IdeResult<Option<String>> {
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
use base64::Engine;
|
||||
let (tx, rx) = tokio::sync::oneshot::channel();
|
||||
app.run_on_main_thread(move || {
|
||||
let sender = std::cell::Cell::new(Some(tx));
|
||||
gtk::Clipboard::get(>k::gdk::SELECTION_CLIPBOARD).request_image(move |_, pixbuf| {
|
||||
let png = pixbuf.and_then(|image| image.save_to_bufferv("png", &[]).ok());
|
||||
if let Some(sender) = sender.take() {
|
||||
let _ = sender.send(png);
|
||||
}
|
||||
});
|
||||
})
|
||||
.map_err(|error| {
|
||||
ide_core::IdeError::internal(format!("Cannot dispatch clipboard access to the main thread: {error}"))
|
||||
})?;
|
||||
let png = rx.await.ok().flatten();
|
||||
Ok(png
|
||||
.map(|bytes| format!("data:image/png;base64,{}", base64::engine::general_purpose::STANDARD.encode(bytes))))
|
||||
}
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
{
|
||||
let _ = app;
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
/// AppKit and WebKit share the general pasteboard, so a worker-side mutex cannot
|
||||
/// protect its type cache. Await the main thread without blocking a command thread.
|
||||
async fn with_clipboard<T: Send + 'static>(
|
||||
|
||||
@@ -166,6 +166,7 @@ pub fn builder() -> tauri_specta::Builder<tauri::Wry> {
|
||||
fs::fs_read_text,
|
||||
clipboard::clipboard_file_list,
|
||||
clipboard::clipboard_has_files,
|
||||
clipboard::clipboard_image,
|
||||
clipboard::clipboard_set_file_list,
|
||||
fonts::system_font_families,
|
||||
doc::doc_open,
|
||||
|
||||
Reference in new issue
Заблокувати користувача