Skip to content

fix: paste clipboard images on WSL when WSLg only offers BMP#1962

Open
nothankyouzzz wants to merge 1 commit into
MoonshotAI:mainfrom
nothankyouzzz:fix/wsl-clipboard-bmp
Open

fix: paste clipboard images on WSL when WSLg only offers BMP#1962
nothankyouzzz wants to merge 1 commit into
MoonshotAI:mainfrom
nothankyouzzz:fix/wsl-clipboard-bmp

Conversation

@nothankyouzzz

Copy link
Copy Markdown

Closes #1961

Problem

On WSL with WSLg, pasting an image (e.g. a Win+Shift+S screenshot) into the TUI with Ctrl-V silently does nothing. Two compounding causes:

  1. WSLg only bridges Windows clipboard images as image/bmp. selectPreferredImageMimeType() fell back to accepting any image/* type, so readClipboardImageViaWlPaste() successfully returned BMP bytes. Because that read "succeeded", readClipboardMedia() never reached the WSL PowerShell fallback — and the BMP was then dropped by isSupportedImageMimeType() (the pipeline only decodes png/jpeg/webp/gif). Verified by shim-logging the actual subprocess calls on Ctrl-V: wl-paste --type image/bmp is requested, wslpath/powershell.exe never run.
  2. The PowerShell fallback's temp-path hand-off was broken on a stock WSL setup. It passed the path via KIMI_WSL_CLIPBOARD_IMAGE_PATH, but WSL only forwards env vars listed in WSLENV to Win32 processes, so the variable arrived empty, $img.Save($null) threw (non-terminating), and the fallback silently returned null.

Fix

  • selectPreferredImageMimeType() no longer accepts undecodable image/* types. A BMP-only clipboard now yields null at the wl-paste/xclip stage, letting the WSL PowerShell fallback produce a real PNG attachment.
  • readClipboardImageViaPowerShell() embeds the temp path (single-quote escaped) directly in the script text instead of relying on an env var crossing the WSL boundary.
  • Linux clipboard helpers now take the injected runCommand (same pattern as the macOS path), making the fallback chain testable.

Tests

Added two cases to clipboard-image.test.ts:

  • WSL + WSLg offering only image/bmp → falls through to the PowerShell fallback, returns a PNG, never reads the BMP payload, and the script carries the embedded temp path.
  • Plain Wayland (non-WSL) with a BMP-only clipboard → returns null (unchanged behavior, no PowerShell call).

pnpm vitest run apps/kimi-code/test/utils/clipboard/ — 25/25 pass; pnpm run typecheck (apps/kimi-code) clean; pnpm oxlint on touched files clean.

Also verified the exact PowerShell round-trip manually on Windows 11 + WSL2 (Ubuntu 24.04, WSLg 1.0.73.2, WezTerm).

WSLg bridges Windows clipboard images into the Wayland clipboard as
image/bmp only. selectPreferredImageMimeType() accepted any image/*
type, so the BMP payload was read successfully but dropped downstream
(png/jpeg/webp/gif only), and the WSL PowerShell fallback never ran.

- Only select MIME types the image pipeline can decode, so a BMP-only
  clipboard falls through to the PowerShell fallback on WSL.
- Embed the temp path in the PowerShell script text instead of an env
  var: WSL only forwards env vars listed in WSLENV, so the hand-off
  silently arrived empty without user-side config.
- Thread the injected runCommand through the Linux clipboard helpers
  (matching the macOS path) so the fallback chain is testable.

Closes MoonshotAI#1961
@changeset-bot

changeset-bot Bot commented Jul 20, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 9428618

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

nothankyouzzz added a commit to nothankyouzzz/wezterm-config that referenced this pull request Jul 20, 2026
WSLg bridges Windows clipboard images as image/bmp only, which Kimi
cannot decode; the successful BMP read also short-circuits Kimi's WSL
PowerShell fallback, and that fallback loses its temp-path env var at
the WSL boundary unless it is listed in WSLENV. Ship a wl-paste shim
plus a kimi() wrapper and WSLENV entry, all marked temporary until
MoonshotAI/kimi-code#1962 lands.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

WSL (WSLg): pasting an image does nothing — wl-paste selects undecodable image/bmp and short-circuits the PowerShell fallback

1 participant