Skip to content

feat(desktop-gpui): localize every GPUI surface and review all six translations - #3516

Merged
richiemcilroy merged 30 commits into
mainfrom
i18n/gpui-full-language-audit
Oct 28, 2026
Merged

richiemcilroy merged 30 commits into
mainfrom
i18n/gpui-full-language-audit

Conversation

@richiemcilroy

@richiemcilroy richiemcilroy commented Oct 28, 2026 •

Copy link
Copy Markdown
Member

Every GPUI surface now follows the chosen language, the six catalogs have had a native-level review, and the language picker ships in release builds.

This lands the open localization stack (#3422, #3423, #3428, #3434) merged with current main, plus an audit of everything added since and a review of every translated string.

Coverage

flowchart LR
  A[Settings window + pages<br/>#3424, merged] --> M
  B[Editor sidebar, panels, colour, audio, crop<br/>from #3422] --> M
  C[Screenshot editor, overlays, dialogs<br/>from #3423] --> M
  D[Editor shell, export, clips, timeline, tabs<br/>from #3428] --> M
  E[Picker in release, Info.plist languages,<br/>update/quit dialogs, from #3434] --> M
  F[Audit of strings added to main since] --> M
  M[this PR]
Loading

Strings main added after that stack was written, now localized:

  • Recording picker (target_overlay.rs): window size, Focus mode card and its hints, area ratio / reset / fill hints, countdown and mode picker hints.
  • Export: the Turbo export toggle and its warning (editor_export.rs:2295).
  • Clip menu: the transition section, its None / Crossfade / Fade chips and length chips (editor_window.rs).
  • Editor loading timeline: its "Timeline" and "Clip" labels (editor_timeline.rs).
  • Camera preview: the Light / Heavy / Cutout blur label (store.rs:63).

Errors shown to the user

Recording and upload errors stay English where they are created, because they are logged, matched to classify failures (instant_cleanup::classify_start_failure, the Linux visible-window fallback) and saved in upload state. i18n::messages::localize translates them where they are shown: the main window error card, the recording controls, and the upload status in the library and Settings → Recordings.

// "Stop task failed: Recording startup cancelled; local files preserved. Capture cleanup is unconfirmed. Use Ctrl+Shift+F9 to retry Stop."
// ja →
// "停止タスクが失敗しました:録画の開始がキャンセルされました。ローカルファイルは保持されています。キャプチャの後処理を確認できません。Ctrl+Shift+F9で停止をやり直してください。"
  • Exact messages and prefix{inner}suffix wrappers, nested a few deep. Engine text it doesn't know passes through unchanged.
  • English output is byte-identical: each table entry is pinned to its catalog English, and a test fails if the code stops writing a message the table knows.
  • The copy button copies what is shown.

Numbers

i18n::decimal writes 1,5 GB in French, Spanish and German for the numbers inside translated sentences: export size and time estimates, free storage, 3D shot lengths and transition lengths. Other languages and English are unchanged.

Translation review

Every key in zh-CN, ja, fr, es, de and hi was reviewed against the English context, the source and Apple's own localized wording. About 590 strings changed. Most of the changes are about consistency:

  • One term per concept:
    • zh-CN: 复制, 转写, 点击, and 分段 for segments.
    • ja: 動画, 音声, アスペクト比, and no spaces around Latin text.
    • fr: offre for plan, plus the straight apostrophe.
    • es: preajuste, toma, vídeo.
    • de: Vorlage, Speichern, Systemaudio, and no space before ….
    • hi: कुंजी for key, plus रीस्टार्ट vs फिर से शुरू.
  • macOS menu wording: matches each language's AppKit, e.g. de "Benutzte Dokumente", fr "Réglages…", es "Usar pantalla completa", ja Window menu ウインドウ.
  • Real mistranslations fixed:
    • zh-CN 3D lens: 焦距 → 视角.
    • de In/Out edges read as On/Off.
    • fr « Sans système » → « Sans-serif système ».
    • ja transparent MOV description.
    • es automation names starting in lowercase.

locales/GLOSSARY.md records these choices, the error rule and the decimal rule.

Fitting the longer languages

  • Disabled clip menu rows keep their own label whole and wrap the reason beside it onto a second line (editor_window.rs, clip_menu_row). English already cut "Split at playhead" short, and Japanese and German lost the label entirely.
  • The device pills in the recording picker use Apple's compact Oui/Non and Sí/No in French and Spanish, so the device name isn't squeezed to "Aucune…".
  • The caption and keyboard font menus show translated names. The project still saves the English value.

Release

  • The Language section always shows. System follows the macOS language in release builds.
  • CFBundleLocalizations plus InfoPlist.strings in each language mean the permission prompts use the system language.

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge, with the earlier non-blocking clip-menu text clipping still outstanding.

Findings

  1. P2 Merge reasons get cut off ▶
Fix with agent prompt
### Issue 1
apps/desktop-gpui/src/editor_window.rs:1868-1869
Disabled merge rows now keep the full label on one line and give the reason only the leftover width. In the 300px menu, German labels such as “Mit vorherigem Clip zusammenführen” leave too little room for the reason, which is cut off after two short lines. Users cannot read why merging is blocked or what would enable it.

This is non-blocking, but putting the reason below the label or widening these rows would keep it readable.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

---

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

Summary

Extends GPUI translations across the editor, screenshot tools, recording picker, and dialogs.

  • The seven language catalogs use reviewed translations and consistent terms.
  • The recording, settings, and editor screens use translated labels and controls.
  • Release builds offer language selection and localized macOS permission prompts.

Reviews (4) · Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." · Reviewed by Greptile

…ur correction, audio library and crop dialog
# Conflicts:
#	apps/desktop-gpui/src/editor_window.rs
#	apps/desktop-gpui/src/target_overlay.rs
…, clip transitions, camera blur labels, recording errors and decimals
@richiemcilroy

Copy link
Copy Markdown
Member Author

@greptileai review

@vercel

vercel Bot commented Oct 28, 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 28, 2026 3:04pm UTC

Comment thread apps/desktop-gpui/src/menus.rs Outdated
Some(error) => format!("Quit canceled: {error}. Cap will stay open so you can finish or recover the recording."),
None if action == QuitAction::TimedOut => "Quit canceled because recording shutdown is still pending. Cap will stay open. Use Stop once available, then try Quit again.".into(),
None => "Quit canceled because recording shutdown could not be confirmed. Cap will stay open. Use Stop, then try Quit again.".into(),
Some(error) => tr::dialog::quit::canceled(error),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Quit errors stay partly English

When quitting fails, tr::dialog::quit::canceled(error) embeds the raw English recording error in the translated dialog. Japanese users can still see “Stop task failed.” even though it has a translation. The mixed-language message also replaces session.error, and localize cannot recognize the translated wrapper later.

Localize the inner error before building the dialog.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop-gpui/src/menus.rs
Line: 776

Comment:
**Quit errors stay partly English**

When quitting fails, `tr::dialog::quit::canceled(error)` embeds the raw English recording error in the translated dialog. Japanese users can still see “Stop task failed.” even though it has a translation. The mixed-language message also replaces `session.error`, and `localize` cannot recognize the translated wrapper later.

Localize the inner error before building the dialog.

---

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

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in the latest push.

Comment thread apps/desktop-gpui/src/editor_tabs.rs Outdated
// Catalogues
// ---------------------------------------------------------------------------

/// A catalogue label, read in the current language each time it is drawn.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 New comments repeat the code

The new comment above Label only describes the type and how it is used. AGENTS.md requires comments to explain non-obvious context and explicitly bans comments that narrate code or restate types.

Remove this comment and the new descriptive catalog section comments, such as the one in en.toml. This repository requirement must be satisfied before merging.

Context Used: AGENTS.md (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop-gpui/src/editor_tabs.rs
Line: 51

Comment:
**New comments repeat the code**

The new comment above `Label` only describes the type and how it is used. `AGENTS.md` requires comments to explain non-obvious context and explicitly bans comments that narrate code or restate types.

Remove this comment and the new descriptive catalog section comments, such as the one in `en.toml`. This repository requirement must be satisfied before merging.

**Context Used:** AGENTS.md ([source](https://github.com/capsoftware/cap/blob/main/AGENTS.md))

---

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

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in the latest push.

@richiemcilroy

Copy link
Copy Markdown
Member Author

@greptileai review

Comment on lines +1868 to +1869
.when(hinted, |label| label.flex_none())
.when(!hinted, |label| label.flex_1().min_w_0())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Merge reasons get cut off

Disabled merge rows now keep the full label on one line and give the reason only the leftover width. In the 300px menu, German labels such as “Mit vorherigem Clip zusammenführen” leave too little room for the reason, which is cut off after two short lines. Users cannot read why merging is blocked or what would enable it.

This is non-blocking, but putting the reason below the label or widening these rows would keep it readable.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop-gpui/src/editor_window.rs
Line: 1868-1869

Comment:
**Merge reasons get cut off**

Disabled merge rows now keep the full label on one line and give the reason only the leftover width. In the 300px menu, German labels such as “Mit vorherigem Clip zusammenführen” leave too little room for the reason, which is cut off after two short lines. Users cannot read why merging is blocked or what would enable it.

This is non-blocking, but putting the reason below the label or widening these rows would keep it readable.

---

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

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@richiemcilroy
richiemcilroy marked this pull request as ready for review October 28, 2026 14:33

@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 2 other findings in Capy.

Open in Capy

# Conflicts:
#	apps/desktop-gpui/src/target_overlay.rs
@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.

View 2 other findings in Capy.

Open in Capy

This branch was successfully deployed

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

1 participant