aboutsummaryrefslogtreecommitdiff
path: root/src/platform
diff options
context:
space:
mode:
authorJJ Liebig <jonathan.liebig@gmail.com>2026-09-03 15:30:04 +0200
committerGitHub <noreply@github.com>2026-09-03 15:30:04 +0200
commit0f8ad128b65869d683253753a477c0ccafca9bf2 (patch)
treed6861cd72edd361608b4c8be06e42450252307bf /src/platform
parent9a2a7af5402f2bc67ab24c8b4c14c6dd20a43bb2 (diff)
fix: read Windows clipboard images in WSL (#3572)
refs #3376
Diffstat (limited to 'src/platform')
-rw-r--r--src/platform/linux.rs43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/platform/linux.rs b/src/platform/linux.rs
index f3ba0429..8efe7357 100644
--- a/src/platform/linux.rs
+++ b/src/platform/linux.rs
@@ -478,6 +478,13 @@ pub fn open_url(url: &str) -> std::io::Result<Option<std::process::Child>> {
}
pub fn read_clipboard_image() -> Option<ClipboardImage> {
+ if running_inside_wsl() {
+ if let Some(image) = read_wsl_clipboard_image_with_command(|program| Command::new(program))
+ {
+ return Some(image);
+ }
+ }
+
for (mime, extension) in [
("image/png", "png"),
("image/jpeg", "jpg"),
@@ -508,6 +515,24 @@ pub fn read_clipboard_image() -> Option<ClipboardImage> {
None
}
+fn read_wsl_clipboard_image_with_command(
+ mut command: impl FnMut(&str) -> Command,
+) -> Option<ClipboardImage> {
+ let mut command = command("powershell.exe");
+ command.args([
+ "-NoProfile",
+ "-NonInteractive",
+ "-STA",
+ "-Command",
+ "$ErrorActionPreference='Stop'; Add-Type -AssemblyName System.Windows.Forms; Add-Type -AssemblyName System.Drawing; $image=[System.Windows.Forms.Clipboard]::GetImage(); if ($null -eq $image) { exit 1 }; $stream=[System.IO.MemoryStream]::new(); try { $image.Save($stream, [System.Drawing.Imaging.ImageFormat]::Png); [Console]::OpenStandardOutput().Write($stream.GetBuffer(), 0, [int]$stream.Length) } finally { $stream.Dispose(); $image.Dispose() }",
+ ]);
+ let bytes = read_clipboard_image_with_spawned_command(command)?;
+ bytes_match_image_signature("png", &bytes).then_some(ClipboardImage {
+ bytes,
+ extension: "png",
+ })
+}
+
fn read_validated_clipboard_image(
program: &str,
args: &[&str],
@@ -1495,6 +1520,24 @@ mod tests {
}
#[test]
+ fn read_wsl_clipboard_image_accepts_png_from_windows_command() {
+ assert_eq!(
+ read_wsl_clipboard_image_with_command(|program| {
+ assert_eq!(program, "powershell.exe");
+ let mut command = Command::new("sh");
+ command
+ .arg("-c")
+ .arg("printf '\\211PNG\\r\\n\\032\\nrest-of-image'");
+ command
+ }),
+ Some(ClipboardImage {
+ bytes: b"\x89PNG\r\n\x1a\nrest-of-image".to_vec(),
+ extension: "png",
+ })
+ );
+ }
+
+ #[test]
fn image_signatures_match_only_their_format() {
assert!(bytes_match_image_signature("png", b"\x89PNG\r\n\x1a\n..."));
assert!(bytes_match_image_signature(