Skip to content

feat(desktop-gpui): resize a picked window to a ratio or size, and focus it to record it alone - #3454

Open
richiemcilroy wants to merge 19 commits into
feat/recording-window-onlyfrom
feat/gpui-window-arrange-focus
Open

richiemcilroy wants to merge 19 commits into
feat/recording-window-onlyfrom
feat/gpui-window-arrange-focus

Conversation

@richiemcilroy

@richiemcilroy richiemcilroy commented Oct 27, 2026 •

Copy link
Copy Markdown
Member

Stacked on #3452.

Problem

In the window picker, the picked window's size was plain text, and the only way to change the shape of what gets recorded was to resize the window by hand. A window recording also captured a region of the screen. #3452 adds the option to record the window by itself, but nothing in the app could turn it on.

Change

  • Size chip. The size readout becomes a chip. It shows the size the window will record at (pixels, so 1440 × 900 points reads 2880 × 1800 on a Retina display) and its ratio when it matches one. It opens a menu:
    • Ratios: 21:9, 16:9, 16:10, 4:3, 1:1 and 9:16. A ratio keeps the window's area and centre, grows a tiny window to at least 160 pt on its shorter side, and keeps it at least 16 pt inside the display's usable area (menu bar, Dock and taskbar excluded).
    • Sizes: 720p, 1080p, 1440p and 4K in recorded pixels, listed only when they fit.
    • The current ratio or size is ticked.
  • Focus toggle. Focus centres the window in the usable area, brings it to the front, and records it by itself. Turning it off puts the window back where the picker found it.
    • Focus lives in the picker's shared state, so every display's overlay shows the choice the recording will use.
    • Picking a window while Focus is on centres and raises it, as turning Focus on does.
    • In Instant mode with a camera, macOS and Windows keep recording the screen region, because the camera bubble reaches the video through the screen capture (feat(recording): capture a window by itself, on request, on macOS and Windows #3452). The Focus tooltip says so.
  • Window capture style setting. Focus is the same stored choice as a new Settings › General › Window capture style row: Screen region (the default, today's behaviour) or Focused window. The last choice is remembered. Recording reads it as it starts.
  • Moving the window. foreign_window does the platform work:
    • macOS: the Accessibility API (AXPosition/AXSize, matched to the window through _AXUIElementGetWindow), which Cap already holds the permission for.
    • Windows: SetWindowPos, adding back DWM's invisible resize borders and restoring a maximized window first. The maximized window's WINDOWPLACEMENT is saved, so putting it back maximizes it again with its old restore size.
    • X11: _NET_MOVERESIZE_WINDOW and _NET_ACTIVE_WINDOW.
    • Wayland: cannot move other apps' windows, so the chip stays read-only with a tooltip saying so and Focus is hidden. The same happens on macOS without Accessibility.
  • Off the UI thread, in order. Moves and restores run on one worker thread, in the order they were asked for, because SetWindowPos waits on the target app. So a cancel's restore always lands after a move the user started first. The highlight then animates to wherever the app actually put the window, since apps clamp to their own minimum sizes or cell grids. A move that finishes after the user has picked another window, or closed the picker, leaves the new choice alone.
  • The menu holds its window. Opening the size menu pins the window it acts on, so passing over another app on the way to a row cannot change the target.
  • Highlight tracking. The pinned window's bounds are now re-read on every picker poll. Before, the highlight stayed where the window was first picked.
  • Restoring. Dismissing the picker puts back every window it moved. Starting a recording keeps them where they were shaped.

The new overlay strings are literals, like the rest of the overlay on this base. #3423 localizes the overlay, and they move into its catalogue when this rebases onto it. The settings row and options are localized in all seven catalogues.

Test

  • Unit tests (window_arrange, and foreign_window's ordering of queued jobs):

    • ratio keeps area and centre;
    • every ratio near every edge stays on screen;
    • tiny windows grow;
    • exact sizes fit or are refused on 1x and 2x displays;
    • centring;
    • ratio detection.
  • i18n: the i18n surface tests pin the new keys, and cap-i18n-build passes.

  • Real app: Picker smoke (real app) now drives a real window on macOS, Windows and Linux X11 through the overlay's own menu and toggle. It picks the window it opened (TextEdit, Notepad or xterm) outright, so the runner's cursor position doesn't matter:

    1. chooses 16:9, then checks the actual frame is within 4% of 16:9 and inside the display;
    2. turns Focus on, then checks the window is centred;
    3. dismisses the picker, then checks the window is back within 6 pt of where it started.

    Screenshots of each step are uploaded.

RetriggerView in GreptileConfidence Score: 4/5

Wait to merge until recording waits for pending window moves.

Findings

  1. P1 Recording can use old bounds ▶
  2. P2 Some exits leave windows changed ▶
  3. P2 Smoke check misses broken cancellation ▶
Fix with agent prompt
### Issue 1
apps/desktop-gpui/src/app_windows.rs:2449-2452
Starting a recording does not wait for pending window moves. If the user chooses a size and starts while the target app is busy, the default `ScreenRegion` capture can read the old bounds before `SetWindowPos` finishes. The window then moves outside the fixed recording crop.

Wait for queued moves to finish before starting capture.

### Issue 2
apps/desktop-gpui/src/app_windows.rs:2173-2174
Window restoration only runs through `dismiss_target_overlays`, but other user actions close the picker directly. Choosing Open Cap from the tray calls `show_main_window`, which closes the overlays without restoring moved windows. The next picker opening clears `arranged`, losing the original positions.

Restore moved windows on non-recording close paths too.

### Issue 3
apps/desktop-gpui/src/picker_probe.rs:199-204
The smoke check turns Focus off before dismissing the picker. `set_focus(false)` already restores the original window, so `restored_ok` can pass even if dismissal restoration is completely broken.

Dismiss while the window is still moved, then check its original bounds. Test turning Focus off separately.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

Adds window size and ratio choices, a shared Focus toggle, platform window movement, and a saved capture-style setting.

  • The window picker offers ratios and pixel sizes for a picked window.
  • The Focus toggle centres a picked window and selects window-only capture.
  • The picker follows arranged windows and restores them when dismissed.

These issues remain in the inspected higher stack revisions, including #3456.

Reviews (6) · Last reviewed commit: "fix(desktop-gpui): colour the window siz..." · Reviewed by Greptile

@vercel

vercel Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
cap-status Ready Ready Preview Oct 27, 2026 9:46pm UTC

@richiemcilroy

Copy link
Copy Markdown
Member Author

hey @greptileai, please re-review the PR

Comment thread apps/desktop-gpui/src/target_overlay.rs
Comment thread apps/desktop-gpui/src/target_overlay.rs
Comment thread apps/desktop-gpui/src/target_overlay.rs
Comment thread apps/desktop-gpui/src/target_overlay.rs Outdated
Comment thread apps/desktop-gpui/src/foreign_window.rs
Comment thread apps/desktop-gpui/src/window_arrange.rs Outdated
# Conflicts:
#	apps/desktop-gpui/src/picker_probe.rs
… pin the size menu's window, ignore stale moves, restore maximized windows
# Conflicts:
#	apps/desktop-gpui/src/picker_probe.rs
@richiemcilroy

Copy link
Copy Markdown
Member Author

hey @greptileai, please re-review the PR

Comment thread apps/desktop-gpui/src/app_windows.rs
Comment thread apps/desktop-gpui/src/picker_probe.rs
@richiemcilroy

Copy link
Copy Markdown
Member Author

hey @greptileai, please re-review the PR

Comment thread apps/desktop-gpui/src/recording.rs
Comment thread apps/desktop-gpui/src/app_windows.rs Outdated
@richiemcilroy

Copy link
Copy Markdown
Member Author

hey @greptileai, please re-review the PR

@capy-ai capy-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capy found no issues.

Open in Capy

@capy-ai capy-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capy found no issues.

Open in Capy

@capy-ai capy-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capy found no issues.

Open in Capy

@capy-ai capy-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capy found no issues.

Open in Capy

@capy-ai capy-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capy found no issues.

Open in Capy

@capy-ai capy-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capy found no issues.

Open in Capy

@capy-ai capy-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capy found no issues.

Open in Capy

@capy-ai capy-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capy found no issues.

Open in Capy

This branch was successfully deployed

2 active deployments
Preview – cap-web — 06ab8c40 Deployed Oct 27, 2026 by vercel[bot]
Preview – cap-status — 06ab8c40 Deployed Oct 27, 2026 by vercel[bot]
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.

1 participant