Effects & Presets kept its favourites in `UiState::effects_favorites`,
which nothing writes out (only the workspace layout is saved), so the
stars were gone the next time the app opened. They now live in the
settings (`Prefs::effects_favorites`, saved when a star is clicked) like
the recent fonts and presets, survive Reset All like them, and a
hand-edited list loses empty and repeated ids on load.
Create each atomic write through its own exclusively created temporary sibling and keep its open file handle until writing finishes. Concurrent writers publish complete files without truncating or following an existing temporary entry; failed writes or renames clean up their own staging file.
Keep the temporary basename bounded independently of the destination name so previously supported long project filenames still save. Retain the concurrent-writer and symlink regressions and add a 251-byte filename overwrite regression that checks exact bytes and staging cleanup.
Fixes#1233
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds Georgian (ქართული, code ka) to Settings > General > Language, with
Match System for ka / ka-GE / ka_GE.UTF-8 locales:
- i18n.rs: the menu catalog, the same 628 (command, English label) keys as
the other languages, plus the Undo/Redo entries, the workspace and 3D
view shortcut submenus, the Reveal labels on Windows and Linux and the
macOS Services items.
- i18n/ui.rs: GEORGIAN, every row of the Chinese panel catalogs (687), and
GEORGIAN_PANELS, 195 rows for text the panels send through tr() that no
catalog has yet (form dialogs, drop messages, screen-reader names,
context menus, Project and Timeline column headers). The tests hold
them to the same rules (unique, same placeholders, used by a converted
panel) and keep them from shadowing a Chinese row; prefs_live.rs joins
the converted files.
- i18n/effects.rs: Georgian names for all 307 effects and 21 categories;
the CC series and brand names stay in English.
- Properties > Text Animation: the Add Animator and Presets buttons grow
with their translated labels (English keeps 116 / 84 px).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YMTAbGNRxnMEzRvYnQGphF
Alt+1 after Alt+Shift+1 shows the red channel in grayscale instead of going back
to RGB (and the other way round). The same key again is still RGB.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
layer.sampling takes `toggle`: layers that all have the sampling already get the
other one. The Bilinear and Bicubic menu entries, which carry the keys, pass it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
F2 Deselect All, Cmd+Shift+T Effect Controls, Cmd+Alt+Left / Right Go to Start /
End, Cmd+Shift+/ Add to Render Queue.
Effect Controls is a menu entry with bound parameters, which could hold one key:
a menu line can now give further default keys after a comma
(F3, Cmd+Shift+T); the menus show the first. MenuEntry gains alt_shortcuts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Both were a single command taking the mode as a parameter, with no menu entry,
so nothing could carry a default key. Each mode is now its own command:
view.fastPreviews.off / adaptive / draft / fastDraft / wireframe (Cmd+Alt+1-5)
and view.channel.red / green / blue / alpha (Alt+1-4), redColorized /
greenColorized / blueColorized (Alt+Shift+1-3) and rgbStraight (Alt+Shift+4).
A channel's key again returns to RGB.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Renderer: no cover step for adjustment layers (#686); their buffer is the comp below.
Restores a single CPU step in split adjustment stacks.
- Effect Controls rename (#953): focus the name field the frame it exists. Focusing an id
not yet drawn left AccessKit with a focus outside its tree (a panic in the consumer).
The tests double-click at 60 fps, within egui's double-click time.
- i18n: Russian, French and German entries for Copy Frame to Clipboard and the extrusion
Front/Bevel/Side/Back Color submenus added by today's other PRs.
- Tests: "fr" is now a valid language; the marker dialog's comment is focused on open
(#922), so Enter-is-OK is tested with the focus elsewhere; the toolbar gradient tests
give the selected layer its paint kind, since the toolbar mirrors it (#732).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keep every entry in contributors/people.toml, and translate the new menu
item (Copy Frame to Clipboard) and the five gradient-editor strings into
Czech.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Czech for all 618 fixed menu entries and the 496 panel, tooltip and dialog
strings of the most complete catalog; settings accept and persist `cs`, Match
System recognises cs, cs-CZ and cs_CZ.UTF-8; native menu, Undo/Redo and
file-manager labels. Czech may lag the Chinese catalogs like Japanese and
Ukrainian (a missing row falls back to English); menu rows use "..." like
the other catalogs. AI-assisted, independently reviewed, not yet proofread
by a native speaker.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
As in After Effects, the Preset menu in Composition Settings / New Composition gets a Save
button (asks for the name in a Choose Name window; an existing name of yours is replaced) and a
Delete button for the selected preset of yours. Your presets keep frame size, pixel aspect and
frame rate, are listed above the built-in ones and live in the settings (`compPresets`), so they
survive restarts and Reset All. Commands: `comp.savePreset`, `comp.deletePreset`, `comp.presets`.
A hand-edited settings file loses only its invalid presets.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Previous / Next Frame also answer to Cmd+Left / Cmd+Right Arrow, and Back / Forward
10 Frames to Cmd+Shift+Left / Right, next to the Page keys (After Effects' second
default keys). A command spec can now list several default shortcuts
(`alt_shortcuts`, `cmd!(…, ["PageDown", "Cmd+ArrowRight"], …)`); menus and tooltips
keep showing the first.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Settings > Appearance > UI Scale offered only 75, 100, 125, 150, 175 and
200 %, so a size between 75 and 100 wasn't possible. It is now the shared
numeric field (Kind::Int(75, 200, "%")): type or drag any whole
percentage. The engine already stored the scale as a clamped integer and
the UI applies it with set_zoom_factor, so the range, the default, live
preview, Cancel and saved preferences are unchanged; the preset list
goes.
Numeric settings now apply a typed number once it is entered (Enter or
leaving the field), not at every keystroke: typing 85 used to apply the
partial 8, clamped to 75, and resize the whole interface before the 5.
Dragging still applies as it moves.
Tests: the UI Scale test types 85 a key at a time (nothing applies and
the field keeps the keyboard until Enter), Cancel, 50 and 300 clamp to
75 and 200, 90 with OK, and a new app with the saved preferences starts
at 90 %. The GPU Information transaction test types 125.
Settings > Previews > GPU Information was fixed text ("Compositing: CPU, N
threads... Display: egui on wgpu."): it never named a GPU, even while the GPU
compositor was running, so a card looked undetected. The System Report's GPU
line only said whether the compositor started.
sysinfo::gpu_summary builds the graphics lines from the session: the compositor's
adapter, or the reason compositing is on the CPU, and the adapter the window
itself got. The dialog uses it.
This does not explain why a particular card isn't used for compositing; that
needs the reporter's System Report (Help > System Report).
Tests: engine gpu_summary_names_the_adapter_or_says_why_there_is_none and UI
gpu_information_names_the_adapter_and_why_the_gpu_is_off (fails with the old
text). The six engine tests that fail on this Windows machine (relative footage
and render-queue paths) fail on main too.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Ported onto the current language plumbing next to Spanish (catalog codes,
Match System for pt-* locales, native menu Services label, docs, tests);
the language list and settings validation stay the shared LANGUAGES table.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QiAJeFttZp83Fh7YuzAR5f
Ported onto the current language plumbing next to Ukrainian (catalog
codes, Match System, native menu Services label, docs, tests), and the
stale Ease Presets row (a ScriptUI panel since #404) dropped.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QiAJeFttZp83Fh7YuzAR5f
Add a Spanish catalog for the menus (618 entries), the computed titles and the macOS Services label, and list Español in the Language preference. Match System now maps es, es-ES, es_MX and es-419 to it. Add llopjulen to contributors/people.toml.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HcDWLRR3UfieXAyFa9cq4p
Settings > Appearance > UI Scale (appearance.uiScale, 75-200 %, default 100)
scales the whole interface on top of the display's own scaling, live as it is
chosen; Cancel puts it back, OK saves it and a saved scale applies from the
first frame. The Settings dialog's choice rows show a number setting with
choices as its text. Automation id: settings.appearance.uiScale.
egui's own Ctrl+= / Ctrl+- / Ctrl+0 zoom is off now: Ctrl+0 (Window > Project)
also reset the zoom behind the app's back, and the scale is a setting.
Test: engine tests_settings ui_scale_is_a_percentage_from_75_to_200; ui_panels
ui_scale_setting_sizes_the_interface.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- New TRADITIONAL_CHINESE catalog: the same (command, English label) keys as JAPANESE and
SIMPLIFIED_CHINESE, one entry per fixed menu row (618 rows). The wording follows the
Traditional Chinese catalogs PhotoCraft, PdfCraft, VectorCraft and LightCraft already ship
(`檔案`, `開啟`, `儲存`, `圖層`, `遮色片`, `影格`, `預設集`, `快速鍵`, …).
- Match System maps a Traditional Chinese locale (`zh-TW`, `zh-HK`, `zh-Hant`, `zh_MO`) to
`zh-hant` instead of English, now that there is a catalog for it.
- `simplified()` and `traditional()` replace the Simplified-only `chinese()`; the macOS Services
item is 服务 in Simplified and 服務 in Traditional.
- `general.language` gains 繁體中文; `docs/preferences.md` documents the locale mapping.
- Tests: all three catalogs must cover the same fixed TREE entries; the shape check covers both
Chinese catalogs; label/undo/panel-title/submenu/native-menu behaviour in zh-hant with file and
layer names kept verbatim; the Traditional locale mapping; the preference round-trips.
- The i18n module now selects a catalog by language code instead of testing for Japanese:
`language(app)` returns the code, `lookup` is shared by every catalog, and the undo/redo
and workspace / 3D-view titles are formatted per language.
- New SIMPLIFIED_CHINESE catalog: the same (command, English label) keys as JAPANESE, one
entry per fixed menu row of the engine tree (618 rows).
- `general.language` gains 简体中文 (`zh-hans`). Match System maps a Simplified Chinese locale
(zh, zh-CN, zh_CN.UTF-8, zh-Hans-CN, zh-SG) to it and a Traditional one (zh-TW, zh-HK,
zh-Hant) to English, which has no catalog of its own yet.
- The macOS Services menu item is 服务 in Chinese.
- Tests: both catalogs must cover the same fixed TREE entries; `...`, brackets and spacing
keep the English shape; label/undo/panel-title/submenu/native-menu behaviour in zh-hans
with file and layer names kept verbatim; the locale mapping; the preference round-trips
through prefs.json.
get_project / render.backend reported "gpuAcceleration": true with
"active": "cpu" and no reason, which read as a broken GPU. The
headless MCP server only attaches the GPU compositor when started with
--gpu, which docs/agents.md didn't mention, and a failed --gpu said
only "no usable GPU adapter" (the adapter's error went to a log no
one sees). The session now keeps the host's reason there is no GPU
compositor (accel_note): the CLI's "headless: renders on the CPU
unless started with --gpu", or the desktop app's compositor setup or
retirement error. The status reports it as `why` whenever it renders
on the CPU (or that the project's renderer is Software Only). --gpu
failures include the adapter's error (Gpu::try_headless).
docs/agents.md documents `mcp --gpu`.
Test: render_backend_says_why_it_renders_on_the_cpu (engine).
Checked with effectcraft-cli mcp and mcp --gpu.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On some older Intel integrated GPUs (UHD 600, UHD with 2020 drivers)
the graphics driver crashes EffectCraft as its window's DirectX 12 or
Vulkan device is created (exit code 0xC0000005): the process
disappears with no message, and only WGPU_BACKEND=gl helped. A driver
crash can't be caught, so each launch now leaves a marker in the
settings folder until its window draws. A launch that finds the
previous one's marker switches the new Settings ▸ Startup & Repair ▸
Window Graphics (Automatic / OpenGL) to OpenGL and says so in the
status bar. A window that fails to open says the next launch will try
OpenGL. WGPU_BACKEND still wins; macOS has no OpenGL backend, so it
never switches there.
Tests: a_launch_that_never_drew_switches_the_next_to_opengl (app),
window_graphics_is_validated (engine). Checked end to end with a
leftover marker: the app opened on OpenGL with the notice and cleared
the marker.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The interface language was English unless Japanese was chosen in
Settings ▸ General ▸ Language. Language now has a Match System choice
(`general.language` = `system`), the new default: the operating
system's interface language where EffectCraft has a translation
(Japanese), else English, as After Effects installs in the system's
language. English and Japanese can still be chosen; a language chosen
before stays. The browser build stays in English with Match System,
since it has no Japanese font of its own.
The system language comes from sys-locale (MIT OR Apache-2.0, no
dependencies on the desktop platforms), on desktop builds only.
Tests: match_system_uses_the_system_language_where_there_is_a_catalog
(i18n), interface_language_is_validated_persisted_and_backward_compatible
(engine).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Use checked hex slices so prefs.set follows the existing invalid-colour fallback when a component splits a UTF-8 character. Cover invalid Unicode placements and valid mixed-case colours through the command.
Co-Authored-By: OpenAI Codex <noreply@openai.com>
Every 10 seconds the UI thread re-read the system's memory for the cache budgets, and on
Windows that starts PowerShell (`Get-CimInstance Win32_OperatingSystem`) and waits for it:
about a second, sometimes two, during which the whole app froze. The reading now runs on a
background thread (`sysinfo::MemoryWatch`); `Session::memory_tick` takes the last reading and
starts the next one, never waiting. Console programs started for it no longer open a console
window (`CREATE_NO_WINDOW`).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PRJ-7. `engine::autosave` with the session hooks the frontends call:
- Auto-save: every N minutes a dirty project is written to "EffectCraft Auto-Save" next to
it (or a custom folder; untitled projects use the custom folder or the config dir) as
"<name> auto-save N.ecproj", rotating through max versions (oldest overwritten, extra
slots dropped when the maximum shrinks). Optional save when the render queue starts.
- Atomic writes for projects, auto-saves and config files: temp file + fsync + rename; a
failed write removes the temp file and leaves the previous file intact.
- Crash recovery: a session.lock sentinel in the config dir records the open project and
its latest auto-save; a clean exit removes it. At launch a leftover sentinel offers the
latest auto-save in a Recover Project dialog (Settings > Startup can turn it off).
- File > Open Recent (stored in the settings) with Clear Recent Projects; Increment and
Save uses After Effects naming ("Intro 2.ecproj"); Revert reloads the saved file.
- Commands: file.autoSave, file.recoveryInfo, file.openRecent {index|path},
file.clearRecent.
- Tests: rotation, interval/dirty tick, simulated crash mid-write, unclean-exit detection
and recovery, Open Recent / Increment and Save / Revert.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keyboard shortcut presets in the engine (`engine::shortcuts`): every menu entry (including
ones with bound parameters), registry command and frontend command is bindable, scoped
application-wide or to a panel. "EffectCraft Default" is After Effects' layout and
read-only; editing it creates a custom preset that stores only its differences. Presets
are saved in the config store; the shortcut dispatcher and the menus read the active one.
- Commands: shortcuts.list, shortcuts.set {command, params?, keys}, shortcuts.reset,
shortcuts.preset {select|new|duplicate|delete|rename}, shortcuts.export/import (JSON),
shortcuts.conflicts.
- Edit > Keyboard Shortcuts: preset bar, modifier toggles (or held keys), an on-screen
keyboard coloured by scope (application-wide / panel-specific / both), key details,
a searchable list of every command, record-or-type assignment with conflict warnings,
reset to default; all widgets have automation ids.
- Tests: normalization, defaults conflict-free, conflict detection, custom preset creation
and persistence, preset lifecycle + export/import, dispatch uses the custom preset.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A real Settings model in the engine (`engine::prefs`): serde, versioned, dotted keys
(`general.undoLevels`, `labels.3.name`), migration of older layouts, unknown keys kept,
persisted through a `ConfigStore` trait (platform config dir on the desktop; MemoryConfig
for tests; the web app can back it with localStorage).
- After Effects 2026 pages (General … Scripting & Expressions) as a schema shared by the
dialog, `prefs.pages` and docs/preferences.md (rows not wired yet are listed there and
kept in step by a test).
- Commands: prefs.get, prefs.set {key, value | values}, prefs.reset {page?}, prefs.open
{page?}, prefs.pages.
- Wired settings: undo levels, path point size, tool tips, layers at comp start / CTI,
default spatial interpolation linear, Home screen on launch, new project template,
rendering progress in Info, adaptive resolution limit, cache when idle, fast previews,
theme + UI brightness, label names/colours everywhere (Label menu, timeline, project,
render queue, viewer), label colour for handles, grid colour/spacing/subdivisions, guide
colour, safe margins, still footage duration, sequence fps, audio output device and
output mapping, layer / footage / preview cache budgets, default 3D renderer.
- Settings dialog: AE's left page list + right content, OK / Cancel (restores) / Previous /
Next, every widget with an automation id.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>