From c0d49ffdf7e03953fa20cf9bf0a9515446dadfd9 Mon Sep 17 00:00:00 2001 From: Akshar Patel Date: Tue, 13 Oct 2026 22:26:26 -0400 Subject: [PATCH] perf(desktop): stop decoding snapshots twice for accessibility --- .../src/snapShot/DesktopSnapShot.test.ts | 27 ++++++++++++++----- apps/desktop/src/snapShot/DesktopSnapShot.ts | 9 ++++--- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/apps/desktop/src/snapShot/DesktopSnapShot.test.ts b/apps/desktop/src/snapShot/DesktopSnapShot.test.ts index 39a7dddf5de7..9e1895beb4a0 100644 --- a/apps/desktop/src/snapShot/DesktopSnapShot.test.ts +++ b/apps/desktop/src/snapShot/DesktopSnapShot.test.ts @@ -1049,9 +1049,15 @@ it.effect("matches Windows accessibility windows on a scaled display", () => { ); }); -it.effect.each(["gnome", "niri", "kde", "hyprland"] as const)( - "persists %s text without inventing AT-SPI screen coordinates", - (backend) => { +it.effect.each([ + { backend: "gnome", screenshot: "PNG" }, + { backend: "niri", screenshot: "PNG" }, + { backend: "kde", screenshot: "PNG" }, + { backend: "hyprland", screenshot: "PNG" }, + { backend: "gnome", screenshot: "invalid" }, +] as const)( + "persists $backend accessibility text with a $screenshot screenshot", + ({ backend, screenshot }) => { vi.stubEnv("XDG_SESSION_TYPE", "wayland"); flashWindows.length = 0; const window = { @@ -1068,7 +1074,16 @@ it.effect.each(["gnome", "niri", "kde", "hyprland"] as const)( ...(backend === "niri" ? { accessibilityBoundsReliable: false } : {}), ...(backend === "kde" ? { clientBounds: { x: 479, y: 371, width: 700, height: 520 } } : {}), }; - linuxCaptureMock.mockResolvedValueOnce({ png: Buffer.from([1, 2, 3]), window }); + // The captured pixels differ from the compositor's logical window bounds. + const imageSize = screenshot === "PNG" ? { width: 1400, height: 1040 } : window.bounds; + const png = + screenshot === "PNG" + ? Buffer.from( + "iVBORw0KGgoAAAANSUhEUgAABXgAAAQQAQAAAABwoA4ZAAAAyElEQVR4nO3BMQEAAADCoPVPbQwfoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHgYyx4AAepc/c0AAAAASUVORK5CYII=", + "base64", + ) + : Buffer.from([1, 2, 3]); + linuxCaptureMock.mockResolvedValueOnce({ png, window }); activeWindowMock.mockClear(); getSourcesMock.mockClear(); accessibilityByPidMock.mockReset().mockResolvedValue({ @@ -1108,7 +1123,7 @@ it.effect.each(["gnome", "niri", "kde", "hyprland"] as const)( assert.deepInclude(saved.source.accessibility, { format: "element-tree", coordinateSpace: "captured-image", - imageSize: { width: 700, height: window.bounds.height }, + imageSize: { width: imageSize.width, height: imageSize.height }, truncated: false, }); assert.deepInclude( @@ -1118,7 +1133,7 @@ it.effect.each(["gnome", "niri", "kde", "hyprland"] as const)( { role: "window", name: "Editor", - bounds: { x: 0, y: 0, width: 700, height: window.bounds.height }, + bounds: { x: 0, y: 0, width: imageSize.width, height: imageSize.height }, state: { active: true }, }, ); diff --git a/apps/desktop/src/snapShot/DesktopSnapShot.ts b/apps/desktop/src/snapShot/DesktopSnapShot.ts index 164c97b4f22f..1703666ea828 100644 --- a/apps/desktop/src/snapShot/DesktopSnapShot.ts +++ b/apps/desktop/src/snapShot/DesktopSnapShot.ts @@ -90,6 +90,7 @@ import { snapShotShortcutSystemConflict, } from "./snapShot.ts"; import * as HostProcess from "@t3tools/shared/HostProcess"; +import { readImageDimensions } from "@t3tools/shared/imageDimensions"; const MAX_CAPTURE_WIDTH = 2_560; const MAX_CAPTURE_HEIGHT = 1_600; @@ -418,10 +419,10 @@ async function requestMacSnapShotPermissions( } function snapShotImageSize(png: Buffer, fallback: Electron.Rectangle): Electron.Size { - try { - const size = Electron.nativeImage.createFromBuffer(png).getSize(); - if (size.width > 0 && size.height > 0) return size; - } catch {} + // Capture backends already validate or encode the PNG. Reading its header + // avoids decoding every pixel again just to size accessibility coordinates. + const size = readImageDimensions(png); + if (size) return size; return { width: Math.max(1, Math.round(fallback.width)), height: Math.max(1, Math.round(fallback.height)),