Uh oh!
There was an error while loading. Please reload this page.
feat(desktop): add cross-platform window capture - #8103
Conversation
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
Included review availability: Your plan provides up to 10 included reviews per hour; 6 remain after this review. 📝 WalkthroughWalkthroughThe pull request adds desktop window capture across contracts, native capture, IPC, web chat, settings, persistence, provider serialization, packaging, and documentation. It supports platform-specific shortcuts, capture metadata, animations, and pending-capture recovery. ChangesWindow Capture Feature
Estimated code review effort: 5 (Critical) | ~120 minutes Merge Risk:🟠 High · up to Window capture now imports text and metadata from other applications, listens for global shortcuts, and drains captures into drafts. At the current head, captured text is not isolated from provider instructions, the default shortcut can fail on Windows/Linux, timed-out accessibility work can accumulate, and captures can target stale or different drafts; these create security, reliability, and data-integrity risks, so the PR is not merge-ready without fixes or explicit acceptance. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Description checkExplanation The description includes What Changed, Why, platform details, testing evidence, UI evidence through a demo, and a checklist. It is mostly complete, although it uses custom checklist items and does not retain the exact UI Changes heading.
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Reviewed the new Effect service (apps/desktop/src/windowCapture/DesktopWindowCapture.ts), its IPC methods, layer wiring, and contract additions. Module shape (namespace imports, Context.Service with inline interface, exported make/layer, dependencies acquired via yield*) follows the conventions; the Effect.runPromiseWith bridge for the Electron globalShortcut callback matches the existing desktop native-callback pattern. Two error-modeling issues below.
Posted via Macroscope — Effect Service Conventions
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
UI consistency review
Two findings, both in the new window-capture UI.
apps/web/src/index.cssintroduces a global rule keyed on the class trio.animate-in.fade-in.zoom-in-95, which does not exist as a utility in this project. The repo's established pattern (seeComposerStashBadge/prompt-stash-count-enter) is keyframes inindex.cssplus ananimate-[…]utility at the owner. As written, the unlayered global rule wins over Tailwind's layeredanimate-none, so the call-sitemotion-reduce:animate-noneis inert (reduced motion only works because of the duplicated media query),duration-200never affects the animation, and any future element combining those class names silently inherits this animation.WindowCaptureSettingsrecords a shortcut on aButtonwithout thedata-keybinding-captureopt-out that app-level shortcut handlers check, so global capture-phase handlers (e.g.sidebar.toggleinAppSidebarLayout) consume the keypress before the recorder sees it.
Details inline.
Posted via Macroscope — UI Consistency
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This PR adds a broad cross-platform capture workflow with native compositor integrations, permission and shortcut handling, persistent screenshots, accessibility data, and provider prompt changes. Its production and sensitive-data blast radius, plus new static-analysis overrides and product defaults, require human review. Not approved because:
Review your spending limits in Billing settings, or comment |
There was a problem hiding this comment.
Window capture UI review: one new finding on WindowCaptureOnboardingDialog (dialog body bypasses the DialogPanel contract). The three findings from the previous run (index.css.animate-in.fade-in.zoom-in-95 global override, the matching ChatComposer class string, and the missing data-keybinding-capture on the shortcut recorder) are unchanged in this head commit and are not re-posted.
Posted via Macroscope — UI Consistency
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
UI consistency review of the web-side window capture surfaces. Four findings, all on newly added lines; the three items flagged in the previous run (global .animate-in override, call-site animation ownership, and the missing data-keybinding-capture marker) are resolved in this revision.
Posted via Macroscope — UI Consistency
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
UI consistency review of the window-capture web surfaces. Two findings on the new settings page; the composer/timeline attachment cards, the onboarding dialog, the keyframe ownership, and the command palette action all follow the existing primitives and conventions.
Posted via Macroscope — UI Consistency
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Reviewed the web UI surface of this feature (composer/timeline capture cards, capture settings page, onboarding dialog, command palette entry, keyframe ownership). The earlier findings on the window-capture-card-enter keyframe ownership, data-keybinding-capture, DialogPanel composition, capability gating of the onboarding dialog, and the disabled state of the sound/flash/animation switches are all resolved. Two remaining items below.
Still open from earlier reviews (not re-posted): the shortcut recorder still preventDefault()s Tab so focus cannot leave the button, and WindowCaptureAttachmentDetails still anchors its title to text-foreground while rendering on bg-background/70 inside the text-message-foreground bubble.
Posted via Macroscope — UI Consistency
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
One consistency finding on the new window-capture web code. Previously flagged items (recorder Tab handling, data-keybinding-capture, disabled-state parity for the feedback switches, capability gating on the onboarding dialog, DialogPanel composition, and the named window-capture-card-enter keyframes) all look resolved at this head.
Posted via Macroscope — UI Consistency
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Reviewed the changed web UI surfaces (window-capture settings page, onboarding dialog, composer/timeline attachment cards, command palette entry, index.css keyframe). Earlier rounds' items (shared focus-event constant, DialogPanel composition, data-keybinding-capture, Tab handling, named keyframe animation, uniformly gated switches) all look resolved. Two remaining consistency points on the new settings page.
Posted via Macroscope — UI Consistency
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Two findings on the settings surface introduced/changed here. The composer and timeline capture cards, the extracted SettingsUnavailableGroup, the keyframe ownership, and the onboarding dialog composition all look consistent with the existing primitives now.
Posted via Macroscope — UI Consistency
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
One consistency finding on the new window-capture attachment card; everything else (settings layout group, dialog composition, keyframe ownership, palette action) matches the existing contracts.
Posted via Macroscope — UI Consistency
Uh oh!
There was an error while loading. Please reload this page.
When a capture and the T3 window sit on different displays, macOS runs one overlay per display. A failure on either surface rejected the shared flight promise, so landing resolved early and the overlay was destroyed mid-animation: the card froze half-scaled with no border or app details before disappearing. Settle each overlay's flight independently so one display failing no longer cuts the animation short on the others.
Acknowledging a capture tears down the desktop overlay, and the composer only revealed the attachment tile afterwards. The tile was therefore missing for every frame between the flight landing and its first paint, which reads as a blank gap on slower handoffs such as a capture from a second display. Wait for the landing, reveal the tile, then acknowledge.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Add opt-in capture setup, bundled GNOME installation, Niri shortcuts, and the native KDE capture helper with motion and accessibility support. Use direct portal shortcut registration and remove obsolete Electron migration, launch onboarding, shortcut-test state, and duplicate backend probing. Verified with 488 focused TypeScript tests, 11 native KDE tests, scoped lint/format checks, and desktop, web, and build-script typechecks.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
get-windows reports the active window in physical pixels, but xa11y reports UI Automation bounds in logical (DIP) coordinates. On any display above 100% scaling the exact-bounds match in findAccessibleWindow never succeeded, so Windows captures shipped without accessible text or element trees. Convert the active window bounds to DIP before the accessibility lookup, matching the region the screenshot already uses. Element coordinates keep mapping onto the physical screenshot because the image size is still derived from the captured PNG. Generated with Claude Fable 5.1 in Claude Code.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…d-accessibility fix(desktop): avoid window capture accessibility timeout
What Changed
Shift + Shiftby default on macOS and Windows. Wayland requires a key chord because its portal does not support modifier-pair shortcuts.Why
Users can add visual and text context from another app without leaving their T3 Code workflow or managing screenshot files. Native behavior stays in the desktop service, while the existing settings, IPC, draft, attachment, and provider paths carry the result.
Platform Details
Demo
CleanShot.2026-08-31.at.3.17.42.mp4
Testing on macOS
pnpm dev:desktop, then open Settings > Window Capture.pnpm(such as Terminal, iTerm, or Warp) in:If T3 Code is missing, use the + button to select
<repo>/apps/desktop/.electron-runtime/T3 Code (Dev).app.pnpm dev:desktopwith Ctrl+C, then run it again. If macOS offers Quit & Reopen, still restart the terminal command so the dev server and app start together.Verification
uiohook-napias a packaged runtime dependency with prebuilt macOS, Windows, and Linux binaries for the supported CPU architectures.Checklist
Generated by GPT-5.6-sol in T3 Code using the Codex harness.
Note
Add cross-platform window capture with native Linux, macOS, and Windows backends
DesktopWindowCapturecoordinator that manages pending captures, compositor-specific backends, accessibility extraction, transparent transition overlays, and PNG persistencescreencapture), and Windows (xa11y), with shortcut registration via D-Bus portals, compositor configs, and native modifier-pair pollingDesktopBridgemethods; captured accessibility metadata is compacted and appended to provider input as untrusted JSONcomposerDraftStore.addImagenow returns boolean and rejects duplicate image IDs;keybindingsevent-key resolution uses physical key codes for punctuation shortcuts; client settings writes are now serialized through a promise chain; window-capture IPC handlers validate sender identity against the current main window's web-contents IDMacroscope summarized 2fad302.
Summary by CodeRabbit