1871 Commits
Author SHA1 Message Date
redonion23andClaude Opus 5.5 b2cf845624 Scripting: key calls fetch only the key they need, so removeKey stays fast (#814)
Every key call (removeKey, keyTime, keyValue, setInterpolationTypeAtKey…)
looked its key up through `__keys()`, which serialised the whole key list,
eases and tangents included, on each call. Removing keys one by one was
therefore quadratic: about 100 ms per removeKey on a 2,000-key property.
The `keys` query now takes an optional `index` and returns just that key
with the count; `__key` uses it. removeKey on 2,000 keys drops from
103.7 ms to 0.4 ms (release, Windows 11 aarch64).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 01:35:49 +02:00
Kristian MyramandClaude Haiku 5.5 be99fecfdc #1010: recover a static Orientation's Y angle without losing precision near gimbal lock
uniform_parent_pose took the Y angle from asin, which loses precision within about 1e-6 degrees of
+-90. The Y angle now comes from atan2 on cos(Y), as the X and Z angles already do. The gimbal
branch and the principal-range output are unchanged.

A new test parents a static Orientation with Y 1e-6 degrees off gimbal lock under a uniform
parent. Its largest corner displacement was 3.3e-8 px before this change and 1.5e-14 px after.

Co-Authored-By: Claude Haiku 5.5 <[email protected]>
2026-10-13 01:33:51 +02:00
tylerjenningsw bfb7507565 Timeline: a Quick Offset of layer bars ends on release off screen (#1012)
The layer bar Quick Offset was followed and ended in its row's code, and
rows out of view aren't drawn. Released with its row scrolled away, it
stayed active: the next drag of that bar, even a plain one, ran as a
Quick Offset from the old origin, into the old undo step.

Like the key drag, it now follows the pointer below the rows and ends
when the button is released, wherever the bar's row is.

Test: a_quick_offset_released_off_screen_ends (release with the row
scrolled away; a plain drag after it moves both layers together as its
own undo step; fails before).
2026-10-12 18:49:51 -04:00
tylerjenningsw e1c9c33fb1 Keyframes: a refused key drag step doesn't count towards the drag (#1012)
keys.quickOffset and keys.move stored the drag's new total before the
edit ran. When the edit refused the step (keys.quickOffset with a key
landing past the end of time), the project stayed as it was but the
total kept the refused delta, and with incremental steps (merge without
fromStart) the next step moved by it too.

The drag state is now stored only after the edit applies.

Test: a_refused_step_does_not_count_towards_the_drag (+1 s, a refused
step, -1 s: the keys end where they started; fails before: the last key
ends near the end of time).
2026-10-12 18:49:48 -04:00
tylerjenningsw f72b8993ef Keyframes: moving keys keeps subframe spacing (#1012)
keys.move and the nudges snapped each key's destination to the nearest
frame, so moving keys a Quick Offset had staggered onto subframes put
them back on frames: four keys at 0, 1/3, 2/3 and 1 frame, moved one
frame, came out at 1, 1, 2 and 2. Layer bars kept theirs, because
layer.timing snaps the move, not the times.

The move is now rounded to whole frames and every key translated by it.
layer_shift turns a comp-time move into a layer-time move through the
layer's start and stretch (reversed too) without a round trip through
comp time; keys.quickOffset uses it as well.

Test: moving_staggered_keys_keeps_their_subframe_spacing (Quick Offset,
then keys.move and keys.nudgeForward; fails before: 1/3 frame lands on
a frame).
2026-10-12 18:49:34 -04:00
fabian-coandClaude Opus 5.5 41f7736959 macOS: open the window on Intel Metal by skipping indirect-call validation
wgpu validates indirect draw and dispatch arguments with a compute shader it
compiles when the device is created. Metal on an Intel Iris Pro (MacBookPro11,3,
macOS 12.7.6) fails to compile it ("Compiler encountered an internal error" in
MTLCompilerService), the device is lost, and the window never opens.

EffectCraft draws and dispatches nothing indirectly, so leave the check out of the
instance flags. WGPU_VALIDATION_INDIRECT_CALL=1 turns it back on. VectorCraft
does the same (storytold/vectorcraft#651).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 17:45:45 -05:00
redonion23andClaude Opus 5.5 a69c7d7cd2 Timeline: Reset keeps an animated property's keyframes and keys the default (#1078)
prop.reset cleared every keyframe before setting the default value. As in
After Effects (and as effect.reset already does for effect parameters), an
animated property now keeps its keyframes and gets the default as a key at
the current time; a static property just takes the default. The expression
is still removed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 23:52:44 +02:00
tylerjenningsw e2d50ec926 Timeline: Shift ranges and key boxes stagger in comp order (#1012)
In After Effects a marquee selection staggers in the comp's layer order,
not in the direction the box was drawn. A Shift-click range of layer
bars and a box of keys already come out top layer first; this test makes
both with the pointer (the range from the bottom layer up, the box from
the bottom right to the top left) and checks the Quick Offset that
follows: the top layer stays and the bottom one moves the whole delta.
2026-10-12 17:45:30 -04:00
storybored379andOpenAI Codex 5d9bab268d M6.7: reject Roto Brush span edits past trimmed strokes
Validate saved stroke frames against the current layer limits before clamping a span edit. Keep project and undo state intact when trimming has left strokes outside the layer.

Co-Authored-By: OpenAI Codex <[email protected]>
2026-10-12 14:40:10 -07:00
Marco Arnulfo d85601f8eb UI: a Simplified Chinese interface picks a face with the simplified hanzi (fixes #1141)
The Chinese UI fallback was chosen by probing 文, which Japanese faces
cover too. Fallback takes a face already loaded first, so after the
English interface had loaded a Japanese face for kana, switching to
Simplified Chinese reused it, and the simplified-only hanzi (选, 删,
层, 设, 页 ...) drew as boxes. A Simplified Chinese interface now probes
页, as wordcraft does for its interface font (storytold/wordcraft#248).
2026-10-12 23:38:13 +02:00
tylerjenningsw 94b4d0ca34 Timeline: Quick Offset layers and keyframes in selection order (#1012)
Ctrl/Cmd+Alt dragging a selected layer bar or a selected key now runs a
Quick Offset (layer.quickOffset / keys.quickOffset with fromStart, one
undo step). The mode is chosen when the drag starts and needs at least
two unlocked layers; the last selected layer moves by whole frames with
the pointer. A readout by the pointer shows the Total Offset and the
offset Per Layer, translated.

A plain drag still moves the selection together, Alt alone still scales
a key group in time (it now leaves Ctrl/Cmd+Alt to Quick Offset), and
Ctrl/Cmd+Alt+click still toggles Hold. The key drag's readout is drawn
by a shared drag_tip. Keys also register timeline.keyAt.<uid>.<ticks>,
exact where keys on subframes can share a frame.

Tests (ui_quick_offset): staggering layer bars in selection order and
keys per layer, one undo each; plain drags and Alt scaling unchanged; the
readout while dragging.
2026-10-12 17:37:34 -04:00
tylerjenningsw 28e9e5229e Quick Offset: layer.quickOffset and keys.quickOffset commands (#1012)
After Effects 25.4's Quick Offset staggers selected layers, or each
layer's selected keyframes, in the order they were selected: the first
stays, the last moves by the drag and the ones between by equal steps,
landing on subframes.

layer.quickOffset {delta, layers?} moves each layer's start, in and out
point by total * i / (n - 1), worked out once in ticks with integer
arithmetic, so 1 frame over 4 layers gives 0, 1/3, 2/3 and 1 frame
exactly. keys.quickOffset {delta} does the same per layer for the
selected keys, the layers in the order their first key was selected;
every selected key of a layer, across its properties, moves by that
layer's comp-time offset through its start and stretch (reversed too),
keeping values, interpolation, easing and labels. Locked layers are
skipped and at least two layers are needed. With merge and fromStart,
delta is the whole drag and each step starts again from before it, so
the drag is one undo step and a key passed over survives. A delta or a
destination out of the range of times is an error, not a clamped move.

Docs: agents.md; architecture.md notes Quick Offset as the exception to
times snapping to frames.
2026-10-12 17:37:31 -04:00
tylerjenningsw 7643f803e0 Keyframes: moving keys keeps the selection order
keys.move (and nudging) rebuilt the key selection in layer and property
order, so the order the keys were selected in was lost after a move. A
Quick Offset that follows staggers layers in that order (#1012).

The move now goes through move_key_refs, which maps each selected key to
its new time and returns the selection in its original order, with the
same collisions (a key landing on another replaces it), roving retiming
and locked-layer handling as before. key_gesture is the drag-step logic
(start again from the keys and project as they were before the drag)
split out of shift_keys so other key drags can share it.

Test: moving_keys_keeps_the_selection_order (fails before: the keys come
back sorted by layer).
2026-10-12 17:37:29 -04:00
FredApps b4e7f8615f Timeline: the Video-off notice takes the frames/fps line instead of overlapping it (#1118) 2026-10-12 23:30:14 +02:00
vangel76andClaude Sonnet 5.5 4a08f8fdf4 PSD: a memory budget for one decode and a capped smart-object bake (#1138)
The 2^28 pixel limit applied per image; one composite or layer decode kept
the ZIP output, a Vec<f32> per channel and the result alive together, and the
bake size came from the file's quad. A decode now charges every buffer
against a byte budget (4 GiB, 1 GiB on 32-bit), checks its whole expected peak
before allocating, writes channels straight into the result and returns an
error when over budget. Bakes are at most 4x the document across and 2^24
pixels.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-12 23:06:55 +02:00
Egon 5000 4101cef8b4 UI: add an Effects submenu to the layer context menu
The layer context menu gains an Effects submenu between Blending Mode and Arrange, mirroring the After Effects layer menu: the effect registry grouped by category (sorted), synced with the Effect menu; picking one applies it to the selected layers.
2026-10-12 23:03:39 +02:00
vangel76andClaude Sonnet 5.5 35c5ff5fa1 PSD: avoid redundant plane copies, per-pixel mask tests and repeated quad solves (#1136)
Raw channels are borrowed, ZIP planes are un-predicted in place in the inflated buffer,
the 32-bit un-predictor uses one scratch row, the layer mask tests the rect per row
instead of per pixel (and skips a constant factor of 1.0), and a placed-layer bake
solves the quad once and hoists per-triangle invariants. Output is bit-identical;
tests compare against the replaced implementations and count the avoided work.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-12 23:03:35 +02:00
vangel76andClaude Sonnet 5.5 6259bf0b57 #1132: a damaged PSD layer section keeps the merged image instead of failing the document
Psd::parse drops the layers, records Psd::warnings and keeps the header and
merged image; the importer then imports the flattened image as one layer and
reports 'Layers could not be read'. Header damage and a missing merged image
stay hard errors.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-12 23:00:40 +02:00
vangel76andClaude Sonnet 5.5 cf22417c1a PSD: share the duplicated decode, placed-transform and writer helpers (#1133)
One decode_plane for raw/RLE/ZIP (decode_channel and composite), placed::eight and
quad_from for the SoLd/PlLd transforms, the writer's big-endian and UTF-16 helpers
from descriptor.rs, one delimiter const in engine_data.rs, and the dead binding in
write.rs. No behaviour change; adds ZIP and RLE composite tests.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-12 22:58:31 +02:00
vangel76andClaude Sonnet 5.5 130bcb2385 PSD: drop non-finite values from descriptors, EngineData and 32-bit samples; no panic in Warp::apply or Rect::new (#1130)
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-12 22:57:27 +02:00
vangel76andClaude Sonnet 5.5 4f9a04fcf5 PSD import: bound group nesting at 64 so thousands of nested groups cannot overflow the stack (#1128)
Psd::tree flattens groups nested deeper than MAX_GROUP_DEPTH into their depth-64 parent, keeping every layer, so the importer recursion and the tree's Drop/Clone/PartialEq are bounded. The import result reports how many groups were flattened.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-12 22:56:56 +02:00
pravdomilandClaude Opus 5.5 a3e2271e94 Viewer eyedropper: stay armed until there is a frame to sample
A colour pick clicked in the Composition panel before the viewer had a frame
(still rendering on a background thread, or a readback pending) sampled nothing
but was used up, leaving the colour unchanged. The click now leaves the
eyedropper armed, as the text colour eyedropper already does.

timeline_colour_eyedropper_samples_the_comp clicked without waiting for the
frame and hit this in about one run in four; it now waits for the frame.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 22:52:38 +02:00
FredApps 463a4a5221 Preview: say so in the viewer and Timeline when Video is off (#1118) 2026-10-12 22:25:40 +02:00
Kristian MyramandClaude Haiku 5.5 e6dd37e62c contributors: add my own people.toml entry
Credit myself by the display name I chose, nanox333. The name shows in the About window once
contributors.json marks the entry as verified.

Co-Authored-By: Claude Haiku 5.5 <[email protected]>
2026-10-12 22:25:12 +02:00
Kristian MyramandClaude Haiku 5.5 b845562f4c #759: read the include test's file name on Windows
On Windows $.fileName is the full path with backslashes, so split('/') returned the whole path
and includes_are_inlined_relative_to_the_script failed. The test now takes the last part after a
backslash and then after a slash, with plain string splits: a regex split did not split the path
in the script engine.

Co-Authored-By: Claude Haiku 5.5 <[email protected]>
2026-10-12 22:24:38 +02:00
Marco Arnulfo a179714108 Scripting: Google Earth Studio camera scripts key the camera (fixes #1077)
CameraLayer gets the transform and camera-options shortcuts (position, xRotation, zoom...) that AVLayer already had, and Convert Expression to Keyframes run without a property converts the selected ones, as app.executeCommand does it.
2026-10-12 22:02:59 +02:00
pravdomilandClaude Opus 5.5 5789c1c7d8 Scroll bars: a handle you can see [skip ci]
The handle was filled with the colour of its own track (both the field
background), so it only showed while hovered or dragged. It now takes the text
colour, in every scroll area.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 21:49:05 +02:00
pravdomilandClaude Opus 5.5 00afd27dca Keyboard Shortcuts: Enter is OK [skip ci]
Enter closes the editor like its OK button, also while the search field has
focus. It stays with the shortcut recorder (Enter can be recorded), the preset
rename field and an open preset menu.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 21:42:40 +02:00
pravdomilandClaude Opus 5.5 e91b19f2a5 Floating panels: no widget ID clash when dragged past the window edge [skip ci]
The floating group's title strip used the same id as its Area's own
background widget, and the Area was shifted back into the window while
the group's rect kept moving, so the two no longer overlapped and egui
painted "Double use of widget ID" over the panel. The strip has its own
id and the group is drawn where its rect says.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 21:39:27 +02:00
vangel76andClaude Sonnet 5.5 19e4fc7c60 docs: re-audit gaps.md and parity docs against main (2026-10-12)
Open-issue count, crash list, closed-issue references, localization
catalog counts, export formats and #include status checked against
upstream/main 470ea7a3. Rows 7, 14 and 21 of gaps.md untouched (pending
in PRs #1102, #792, #1098).

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-12 21:36:26 +02:00
pravdomilandClaude Opus 5.5 07fe9cb1dc Keyboard Shortcuts: keep the OK button in view [skip ci]
The editor's content was a little taller than its dialog, so the outer scroll
area clipped the OK button and its scrollbar covered the right edge. The dialog
now has no outer scroll area: the command list takes whatever height is left,
so the button row always fits, in small windows too.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 21:34:56 +02:00
Marco Arnulfo 8e21e5dbc1 Tracker: a track point can be grabbed when zoomed out (fixes #1067)
The attach point's 12 px grab area sat on top of the feature region and is tested first. Zoomed out, a default feature region is smaller than that on screen, so every press inside it moved the attach point instead of the point. Inside the feature region the attach point now grabs only the region's inner half.
2026-10-12 21:22:01 +02:00
dotCooCoo 91e46af99c Text: fallback tries a script's usual families before faces loaded earlier
fallback_for tried every face that was already loaded before the usual
families of the character's script. Which faces are loaded depends on
every earlier lookup. On macOS, /Library/Fonts/Arial Unicode.ttf makes
Arial Unicode MS the first face in the scan, and it covers every script
that has usual families except Sinhala. The variable font search loads
it, and so does a fallback for a character that it covers and the
bundled faces and the usual families lack, such as the Simplified
Chinese 们. After that, Hebrew, Arabic, Indic, Thai and CJK text in a
Latin family fell back to Arial Unicode MS instead of Tahoma, Kohinoor
Devanagari, Tamil Sangam MN, Hiragino Sans or Apple SD Gothic Neo. In
the effectcraft-text unit tests,
other_scripts_fall_back_to_a_plain_system_family and
cjk_falls_back_to_a_system_family failed in 7 of 100 runs on a Mac, and
in 24 of 100 while other builds were running, depending on which faces
the other tests had loaded.

The usual families now come right after the bundled faces. family_faces
lists the installed faces of the script's families in the order they
are tried, each in the preferred face's style. The list is cached per
script and preferred face, and adding faces or changing the CJK locale
clears it. Faces that are already loaded come next, then the per-block
cache of the search over every installed font, then the search itself,
as before. A search result made for another character of the block (an
Armenian character next to Hebrew, Lao next to Thai, or a character
that no face covers) is no longer used for a character that a usual
family covers.

tests/script_fallback.rs runs in a test binary of its own. It records
the fallback for eight characters of those scripts, looks up U+0590,
Armenian and Lao and runs the variable font search, and checks that the
eight get the same faces again. It also checks that U+08A4, which on
macOS only faces outside the Arabic list cover, keeps its face after a
lookup of U+0870, which no face covers.
2026-10-12 12:14:33 -07:00
vangel76andClaude Sonnet 5.5 51371939ad Gap 7: Backgrounds animation presets (#1096)
Problem: the built-in animation preset library had no Backgrounds category
(gap 7: 31 presets against After Effects' 621).

Fix: 23 original Backgrounds presets in crates/engine/presets/backgrounds.json,
built from our own generator, noise, colour and stylize effects: Soft Gradient
Drift, Aurora Veil, Slow Fog, Cloud Bank, Dark Smoke, Ember Haze, Magma Flow,
Ice Flow, Pastel Plasma, Cell Drift, Crystal Facets, Hex Mosaic, Mirrored Silk,
Water Caustics, Blueprint Grid, Checker Scroll, Scrolling Stripes, Pulse Rings,
Bokeh Drift, Spotlight Floor, Dawn Sky, Sweeping Light, Grainy Wash.

The preset format gains `expr` (an expression per property, so backgrounds keep
moving for the whole layer) and point parameters written as fractions of the
layer size. Effects & Presets lists them under * Animation Presets > Backgrounds.
Tests: catalogue uniqueness and categories, apply/undo/redo of every preset
(engine), render of every preset with the expression engine: finite,
non-flat, deterministic, moving (host), panel listing and apply (ui-egui).
Sidecar, ATTRIBUTION.md, gaps.md row 7 and effects-parity.md updated.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-12 21:13:05 +02:00
pravdomilandClaude Opus 5.5 97514ef198 Fix #978: keep form choices and buttons inside the dialog
Undoes the 800 px Project Settings width from #980: the form is back at the
shared 480 px.

A form's choice popup keeps its 240 px column and ends a long choice (a GPU
adapter's name) in an ellipsis instead of widening the grid past the dialog.
Only the fields scroll, and only vertically; OK and Cancel sit under the
scroll area, so they stay in view.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 21:11:01 +02:00
pravdomilandClaude Opus 5.5 af28bc4ddb Shortcuts: C cycles the camera tools
tool.camera cycles Orbit, Pan and Dolly.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 21:09:49 +02:00
pravdomilandClaude Opus 5.5 81521d9b06 Shortcuts: switch, cycle and close panels
window.toggleCompTimeline (\) switches between the Composition viewer
and the Timeline. window.previousPanel / nextPanel (Alt+Shift+, / .)
step through the tabs of the focused panel's frame. window.closeAll
(Cmd+Shift+W) closes every open composition when a viewer or the
Timeline is active, otherwise the focused panel.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 21:08:43 +02:00
vangel76andClaude Sonnet 5.5 f11792827e Gap 21: percentage guides and effect colour labels (#1095)
Guides can store a percent of the comp so they follow comp-size changes
(View > Add Percentage Guide, Convert Guides to Percentage / Pixels); an
effect instance has an optional colour label (effect.setLabel, Effect Controls
header bar and Label menu). Both are serde-defaulted, so old projects load.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-12 21:07:36 +02:00
pravdomilandClaude Opus 5.5 00799d8c77 Shortcuts: fit up to 100 %, step through open comps
view.fitUpTo100 (Alt+/) fits the viewer without magnifying past 100 %.
view.previousItem / view.nextItem (Shift+, / Shift+.) activate the
previous / next open composition, wrapping.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 21:06:24 +02:00
pravdomilandClaude Opus 5.5 f7b366197d Shortcuts: scroll the Timeline, Parent column
timeline.scrollToTime (D) centres the current time in the time graph,
timeline.scrollToLayer (X) puts the topmost selected layer at the top;
both are done when the Timeline is next drawn. timeline.parentColumn
(Shift+F4) shows or hides the Parent column.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 21:04:50 +02:00
pravdomilandClaude Opus 5.5 bf53ae6094 Shortcuts: layer selection, timing, masks and Casts Shadows
- layer.extendSelectionNext / Previous (Cmd+Shift+Down / Up).
- layer.moveInToStart / moveOutToEnd (Alt+Home / End).
- layer.moveEarlier / moveLater (Alt+PageUp / PageDown) and
  layer.moveEarlier10 / moveLater10 (with Shift). Alt+PageUp / PageDown
  used to slip the source one frame; layer.slipBack / slipForward keep
  working but have no default key.
- layer.stretchInToTime / stretchOutToTime (Cmd+Shift+, / Cmd+Alt+,):
  layer.timeStretch takes to: in|out.
- layer.mask.selectNext / selectPrevious (Alt+` / Alt+Shift+`).
- layer.castsShadows (Alt+Shift+C) for the selected 3D layers.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 21:02:49 +02:00
pravdomilandClaude Opus 5.5 c6a87a2798 Marker dialog: Cmd+Enter is OK, also from the Comment field [skip ci]
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 21:00:49 +02:00
pravdomilandClaude Opus 5.5 cf912d5049 Shortcuts: deselect keyframes and properties
keys.deselectAll (Shift+F2, Cmd+Alt+Shift+A) clears the selected
keyframes, properties and groups and leaves the layers selected.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 20:59:48 +02:00
pravdomilandClaude Opus 5.5 d444eceb90 Shortcuts: work area from the selection, most recent comp
comp.workAreaToSelection (Cmd+Alt+B) spans the selected layers, or the
whole composition with none selected. comp.activateRecent (Shift+Esc)
goes back to the composition that was active most recently within the
active one's nesting hierarchy; EditorState keeps recent_comps for it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 20:57:21 +02:00
pravdomilandClaude Opus 5.5 a644bb07c9 Shortcuts: go to the work area ends and to In / Out points
time.workAreaStart / time.workAreaEnd (Shift+Home / End) and
time.previousInOut / time.nextInOut (Cmd+Alt+Shift+Left / Right): the In
and Out points of the selected layers, of every layer with none selected.
time.go takes nextInOut and prevInOut.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 20:53:49 +02:00
Moein Saharkhiz a27f9f54b9 #1063: render carriage-return text as separate paragraphs 2026-10-12 14:47:58 -04:00
vangel76andClaude Sonnet 5.5 3840d227ff #1081: Orient Along Path keeps the last heading at and after the end of the path
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-12 20:44:44 +02:00
vangel76andClaude Sonnet 5.5 8703f52d12 #1042: path vertices win over the bounding-box handles in the viewer
A vertex under or beside a box handle lost the press to the handle (the handle reaches 9 points, the vertex 6), the resize cursor showed over it, and the handles were painted over the vertex markers. Vertex reach now matches the handle's wherever one is in range, the cursor stays a pointer, and markers are drawn last.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-12 20:31:48 +02:00
vangel76andClaude Sonnet 5.5 8e5605d0e6 #1070: a fresh import or opened project reads footage files again
The media layer keys decoded frames by path, and nothing dropped them when a
new project (or a new import) named a file that another app had overwritten
since, so a same-size overwrite showed the old pixels. Importing footage and
replacing the project now make the media layer and the layer cache let go of
the files involved.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-12 20:22:48 +02:00
Elias b00c7f582a ui: centre Reset / About... on the effect header row in Effect Controls
The buttons were offset 2pt below the 22pt header's centre, so their text sat
below the effect name's baseline.

(cherry picked from commit acacef9f42e992c535397a55ae03bb3f3684a5e0)

(cherry picked from commit dc9ff1b5aad75c4f4233d89ed33813844e980487)
(cherry picked from commit 1e599b6e1d2e3402a10477ccccd1fd52724dc95c)

(cherry picked from commit 7deda99fabe57bb40c6ea9f02f18c6c79d19d792)
2026-10-12 19:22:18 +01:00