fix(clipboard): hardened WSL PowerShell fallback for headless environments

- Raised PowerShell timeout to 8s and swallowed reap errors to prevent unhandled throws on WSL interop.
- Fixed fallback logic so arboard is skipped when no display server is present on headless WSL.
- Added test coverage for the headless WSL short-circuit path.
This commit is contained in:
can1357
2026-05-25 14:05:48 +02:00
parent 79f6bf4f76
commit 81cec1c38b
2 changed files with 30 additions and 5 deletions
@@ -97,9 +97,10 @@ describe("readImageFromClipboard on WSL", () => {
expect(nativeSpy).not.toHaveBeenCalled();
});
it("falls back to the native bridge when PowerShell returns no payload", async () => {
it("falls back to the native bridge when PowerShell returns no payload and a display is present", async () => {
setPlatform("linux");
process.env.WSL_INTEROP = "/run/WSL/1_interop";
process.env.WAYLAND_DISPLAY = "wayland-0";
spyPowershell([], "");
const nativeSpy = vi.spyOn(native, "readImageFromClipboard").mockResolvedValue(null);
@@ -110,9 +111,10 @@ describe("readImageFromClipboard on WSL", () => {
expect(nativeSpy).toHaveBeenCalledTimes(1);
});
it("falls back to the native bridge when PowerShell exits non-zero", async () => {
it("falls back to the native bridge when PowerShell exits non-zero (with display)", async () => {
setPlatform("linux");
process.env.WSL_DISTRO_NAME = "Ubuntu";
process.env.DISPLAY = ":0";
spyPowershell([], "noise", 1);
const nativeSpy = vi.spyOn(native, "readImageFromClipboard").mockResolvedValue(null);
@@ -120,6 +122,18 @@ describe("readImageFromClipboard on WSL", () => {
await readImageFromClipboard();
expect(nativeSpy).toHaveBeenCalledTimes(1);
});
it("returns null without invoking arboard on headless WSL when PowerShell yields nothing", async () => {
setPlatform("linux");
process.env.WSL_DISTRO_NAME = "Ubuntu";
// No DISPLAY / WAYLAND_DISPLAY — arboard would reject, so we must short-circuit.
spyPowershell([], "");
const nativeSpy = vi.spyOn(native, "readImageFromClipboard");
expect(await readImageFromClipboard()).toBeNull();
expect(nativeSpy).not.toHaveBeenCalled();
});
});
describe("readImageFromClipboard dispatch", () => {