Skip to content

feat(desktop-gpui): localize the screenshot editor, overlays and dialogs - #3423

Merged
richiemcilroy merged 87 commits into
mainfrom
i18n/dialogs-and-screenshot-editor
Oct 28, 2026
Merged

richiemcilroy merged 87 commits into
mainfrom
i18n/dialogs-and-screenshot-editor

Conversation

@richiemcilroy

@richiemcilroy richiemcilroy commented Oct 26, 2026 •

Copy link
Copy Markdown
Member

Localizes the GPUI surfaces outside settings and the editor so they follow the UI language once the language picker ships in release builds.

What changed

278 new catalog keys, each in en.toml and in all six translations (zh-CN, ja, fr, es, de, hi), under screenshot_editor.*, overlay.*, dialog.*, permission.*, diagnostics.*, transcription.*, upload.*, import.* and auth.*. No existing key was renamed; existing main.*, common.* and settings.* keys are reused where the English already matched (device pills, countdown options, mode headers, delete confirmations).

Converted surfaces:

  • Screenshot editor: header tooltips, aspect ratio and corner style menus, background tabs, style popovers, annotation tools and config bar, layers panel, crop dialog, toasts, share progress, load and export errors.
  • Target overlay: device menus and pills, countdown and mode menus, Camera Only panel, area hints and size warnings, start button and its mode line.
  • Mode selection window.
  • macOS permission onboarding (checklist, per-permission cards, hints, status captions) and the drag-into-list guide, with whole sentences per System Settings pane.
  • Dialogs: recording deletion alerts, no-microphone prompt from a shortcut start, file dialog failures and filter names, clipboard errors, import progress and errors, sign-in failure, low-storage notices, capture-flow errors shown in the main window (window or area gone, devices changed, cleanup incomplete, Linux camera overlay checks, Wayland stop-shortcut hints).
  • Diagnostics: sync test stage labels (rewritten as whole messages per mode instead of splicing " studio" into a sentence), the Both segment, run errors and log upload errors.
  • Transcription model download status and the caption error messages.
  • Upload status labels in the library.
  • Teleprompter placeholder, notice and toggles. The placeholder is now set on render so it follows a live language switch.

Layout: labels that can grow in translation now truncate (background tabs, onboarding checklist rows, the overlay start label, teleprompter toggles). English renders the same.

Deliberately left in English

  • Errors that other code matches on: upload and auth errors (the upload queue classifies failures by "sign in" and "session has expired"), recording start errors (classify_start_failure), "access is unavailable" (camera window), cleanup errors checked by visible_fallback_allowed, the controls' disk-space errors, the diagnostics cancel sentinel, IMPORT_CANCELLED, and the caption error inputs.
  • Persisted text: the upload queue's last_error, the instant cleanup crash message, default project names ("Imported Video", "Screenshot").
  • Technical detail inside {error}, logs, ids (element ids built from labels now use separate English ids), window titles, key names.
  • installer.rs errors, which reach the user through updates.rs; that file is being rewritten in Update app and tray menus for macOS #2987 and is left for after it merges.

How English was proven unchanged

src/i18n/dialogs_surface_tests.rs asserts every plain key against the literal it replaced, counts the keys so a new one cannot skip the check, and formats every parameterized message against the format! it replaced. The diagnostics stage labels are compared against a copy of the old function for every stage and mode. tests.rs gets one filter line so its own key count ignores these prefixes.

CI

All CI jobs pass on the branch (run 40381205689): GPUI build and tests on macOS arm64, macOS x86_64, Windows and Linux, Format (Cargo), Format and Lint (Biome), Typecheck. The new tests ran on all four GPUI targets.

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge; no new actionable issue was established.

Summary

The PR expands localization across screenshot editing, capture overlays, permissions, dialogs, settings, and background-task messages.

  • Cap’s GPUI screens and messages follow the selected UI language.
  • The tray and app menus offer more ways to open files and choose capture modes.
  • Update settings let users choose when Cap downloads updates.
  • Linux camera capture reuses frame data instead of copying it.
  • The GPUI app updates its native macOS bindings and platform support.

Previous threads:

  • The mode-card heading and accessibility label now use display_name(), addressing the earlier English-only labels.
  • richiemcilroy accepted the direct display-capture behavior as intentional because the tray row matches its advertised shortcut.
  • richiemcilroy acknowledged the busy-download menu issue, stated that it came from main, and reported its fix in feat(desktop-gpui): enable the language picker in release builds #3434.

Validation was based on source inspection. No build, runtime test, or native UI capture was performed.

Reviews (4) · Last reviewed commit: "Merge dialogs i18n" · Reviewed by Greptile

ItsEeleeya and others added 30 commits October 17, 2026 04:50
Move the Cap menu onto AppKit: the model in `menus.rs` gains Check for
Update, Preferences…, Help destinations, Open File… and Import Media…, and
`platform.rs` patches the standard items after gpui installs the bar —
About becomes `orderFrontStandardAboutPanel:` (the gpui action and its
panel plumbing are gone), autoenables is off so the model owns the enabled
state, and the File menu gets the NSDocumentController-backed Open Recent
list fed by `add_recent_document` on every editor open.

Check for Update resolves to three states (check / download / restart)
and is now rewritten in the live `NSMenuItem` by row position rather than
reinstalling the menu bar, so an open menu survives a status change; the
version and the macOS download percentage ride an `NSMenuItemBadge` on
macOS 14+, and the other platforms only rebuild when the state changes.

Bumps the app to objc2 0.6.5 / objc2-app-kit 0.3.2 / block2 0.6 and
migrates the native code to those bindings.
Give the tray its own AppKit menu: a mode picker (the current mode as a
section header with the mode icons on macOS 14+, the ✓-ticked Recording
Mode submenu on older macOS and on Windows), record/take-screenshot rows,
Previous ▸ with cover-cropped thumbnails, Import Media…, Settings and
Upload Logs, plus the version and the SF Symbols for each row.

The Previous thumbnails reuse the Recents thumbnail cache for JPEG
sources instead of decoding full-resolution originals, which is what the
warm-scan tests cover, and the header follows the palette's highlighted
row in italic.
Fix the tray row's Settings glyph (`gear`, not `gearshape`) and the macOS
26 window symbol, document the File menu (Open File…, Import Media…, Open
Recent), the Help destinations and the live update row.
# Conflicts:
#	.github/workflows/ci.yml
#	apps/chrome-extension/src/offscreen/recorder.test.ts
#	apps/desktop-gpui/kernels/Cargo.toml
#	apps/desktop-gpui/kernels/src/thumbnail.rs
#	apps/desktop-gpui/src/app_windows.rs
#	apps/desktop-gpui/src/camera_blur_portable.rs
#	apps/desktop-gpui/src/controls_window.rs
#	apps/desktop-gpui/src/editor_edits.rs
#	apps/desktop-gpui/src/editor_window.rs
#	apps/desktop-gpui/src/library.rs
#	apps/desktop-gpui/src/main.rs
#	apps/desktop-gpui/src/main_window.rs
#	apps/desktop-gpui/src/menus.rs
#	apps/desktop-gpui/src/mode_select_window.rs
#	apps/desktop-gpui/src/platform.rs
#	apps/desktop-gpui/src/settings_window.rs
#	apps/desktop-gpui/src/target_thumbnails.rs
#	apps/desktop-gpui/src/tray.rs
#	apps/media-server/src/__tests__/lib/media-routes-real-world.integration.test.ts
#	apps/media-server/src/__tests__/lib/recording-verification.integration.test.ts
#	apps/media-server/src/__tests__/lib/storage-upload.test.ts
#	apps/media-server/src/__tests__/routes/lifecycle.test.ts
#	apps/media-server/src/lib/media-video.ts
#	apps/media-server/src/lib/recording-packet-proof.ts
#	apps/media-server/src/lib/recording-timing.ts
#	apps/media-server/src/routes/video.ts
#	apps/mobile/app/(tabs)/upload.tsx
#	apps/mobile/src/screens/dashboard-upload-visibility.test.tsx
#	apps/web/__tests__/unit/add-folder-videos.test.ts
#	apps/web/__tests__/unit/analytics-chart-dates.test.ts
#	apps/web/__tests__/unit/desktop-recording-source.test.ts
#	apps/web/__tests__/unit/finalize-desktop-recording.test.ts
#	apps/web/__tests__/unit/folder-access.test.ts
#	apps/web/__tests__/unit/loom-import-start.test.ts
#	apps/web/__tests__/unit/media-processing-workflows.test.ts
#	apps/web/__tests__/unit/media-server-progress.test.ts
#	apps/web/__tests__/unit/mobile-email-session.test.ts
#	apps/web/__tests__/unit/notification-read-state.test.ts
#	apps/web/__tests__/unit/s3-bucket-connections.test.ts
#	apps/web/__tests__/unit/segment-playlist-route.test.ts
#	apps/web/__tests__/unit/video-pipeline-recovery.test.ts
#	apps/web/__tests__/unit/video-processing-recovery.test.ts
#	apps/web/actions/folders/folder-access.ts
#	apps/web/actions/loom.ts
#	apps/web/actions/notifications/mark-as-read.ts
#	apps/web/actions/spaces/get-space-videos.ts
#	apps/web/app/(org)/dashboard/analytics/components/ChartArea.tsx
#	apps/web/app/s/[videoId]/_components/utils/parse-transcript-vtt.ts
#	apps/web/lib/desktop-recording-source-checkpoint.ts
#	apps/web/lib/desktop-recording-source.ts
#	apps/web/lib/loom-import-start.ts
#	apps/web/lib/loom-import-upload.ts
#	apps/web/lib/loom-media-dispatch.ts
#	apps/web/lib/video-pipeline-recovery.ts
#	apps/web/lib/video-processing-recovery.ts
#	apps/web/workflows/finalize-desktop-recording.ts
#	apps/web/workflows/import-loom-video.ts
#	crates/enc-ffmpeg/src/mux/ogg.rs
#	crates/enc-ffmpeg/src/video/h264.rs
#	crates/enc-ffmpeg/src/video/h264_packet.rs
#	crates/enc-ffmpeg/src/video/packed_yuv.rs
#	crates/project/src/caption_timing/projection_tests.rs
#	crates/project/src/configuration.rs
#	crates/project/src/configuration/style_resolution_tests.rs
#	crates/recording/src/instant_recording/linux_camera.rs
#	crates/recording/src/screenshot.rs
#	crates/rendering/src/frame_pipeline.rs
#	crates/rendering/src/lib.rs
#	crates/scap-targets/src/platform/linux.rs
#	packages/database/types/metadata.ts
#	packages/sdk-recorder/__tests__/recorder-options.test.ts
#	packages/sdk-recorder/src/index.ts
#	packages/web-backend/src/S3Buckets/S3ConnectionPool.ts
#	scripts/prepare-gpui-dependency.sh
#	scripts/prepare-gpui-dependency.test.mjs

@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.

View 3 other findings in Capy.

Open in Capy

Comment thread apps/desktop-gpui/src/mode_select_window.rs
@vercel

vercel Bot commented Oct 26, 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 26, 2026 8:40pm UTC

@richiemcilroy

Copy link
Copy Markdown
Member Author

@greptileai review

@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

@richiemcilroy

Copy link
Copy Markdown
Member Author

@greptileai review

Comment thread apps/desktop-gpui/src/tray.rs
Comment thread apps/desktop-gpui/src/menus.rs
@richiemcilroy

Copy link
Copy Markdown
Member Author

@greptileai review

This branch was successfully deployed

2 active deployments
Preview – cap-web — 1352727c Deployed Oct 26, 2026 by vercel[bot]
Preview – cap-status — 1352727c Deployed Oct 26, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants