feat(desktop): capture any window with a global shortcut - #8103
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 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
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
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This PR introduces a substantial cross-platform window-capture workflow spanning native permissions, global shortcuts, filesystem persistence, IPC, contracts, and chat attachment state. Its broad runtime and user-facing impact warrants human review beyond the supplied minor UI consistency comment. You can add or adjust custom eligibility rules. Learn more. |
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
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
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
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
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
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
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
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
| className="h-full w-full cursor-zoom-in" | ||
| className={ | ||
| image.source?.kind === "window-capture" | ||
| ? "h-full w-24 shrink-0 cursor-zoom-in overflow-hidden border-r border-border/70" |
There was a problem hiding this comment.
The capture card shell is composed inline on both surfaces and the thumbnail widths diverge: w-24 here versus w-28 in MessagesTimeline's user row, even though both cards are h-20 and share WindowCaptureAttachmentDetails. Since the image is object-cover, the same capture crops to a different aspect in the composer than in the sent message. The sibling wide attachment cards (ComposerPreviewAnnotationCards and UserMessagePreviewAnnotationCard) deliberately keep the same size-14 thumbnail across those two surfaces for this reason. Suggest settling on one width for both call sites (or extracting the card shell next to the shared details component).
| ? "h-full w-24 shrink-0 cursor-zoom-in overflow-hidden border-r border-border/70" | |
| ? "h-full w-28 shrink-0 cursor-zoom-in overflow-hidden border-r border-border/70" |
Posted via Macroscope — UI Consistency
What Changed
Why
Users can add visual context from another app without leaving their current T3 Code workflow or managing screenshot files by hand. The implementation keeps native behavior in one desktop service and reuses the existing settings, IPC, draft, attachment, and timeline paths.
The diff is larger than a typical contribution because the complete cross-platform workflow includes the native boundary, durable handoff, settings, feedback, and every user entry point. It remains scoped to window capture.
UI Changes
This is a new surface, so there is no prior equivalent UI.
First-run onboarding
Window Capture settings
Setup flow
t3-window-capture-settings.mp4
Verification
Checklist
Generated by GPT-5.6-sol in T3 Code using the Codex harness.
Note
Add global window capture shortcut to desktop app
DesktopWindowCaptureservice that registers a global shortcut, hides the app window, captures the active window using platform-specific methods (macOSscreencaptureCLI, Linux Wayland portal or X11, Windowsget-windows), and saves PNG and JSON metadata to disk.captureWindow,listPendingWindowCaptures,readWindowCapture,acknowledgeWindowCapture).WindowCaptureCoordinatorto drain pending captures, compress them, attach them to the current or new draft thread, and display them in the chat composer with source metadata (app icon, name, window title)./settings/window-captureroute to toggle the feature, record shortcuts, configure feedback (sound, flash, animations), and trigger immediate captures, plus an onboarding dialog for first-time users.ClientSettingsfields (windowCaptureEnabled, etc.) default to disabled;ChatImageAttachmentandUploadChatImageAttachmentschemas gain an optionalsourcefield that must be preserved by the orchestrator and normalizer.Macroscope summarized 68fb035.