- Main-process interact instances for the selected OFX effect card
(create on selection change, describe, destroy on deselect/close),
coexisting with the render-worker plugin instances per the OFX
multi-instance model.
- Program viewer composites the interact's overlay: draw into a GL
FBO via gl_bridge, read back, straight-alpha 'over' composite onto
the displayed frame; cached and only re-rendered on frame/time/
viewport/instance change or plugin redraw requests.
- Event forwarding: picture-area pointer maps through the contain-fit
letterbox inverse to OFX pen coordinates (pen_motion/down/up);
Keystroke to OFX key symbols (ASCII, navigation, F1-F35) for
key_down/up; a 50ms idle pump; global shortcut consumption keeps
precedence.
- e2e with the real test plugin: lifecycle marker assertions, pen/key
event records, and macOS GL overlay compositing verified (265 tests
green incl. gpui_widgets viewer suite).
- Right-clicking an unselected clip selects it first (C++ parity) —
this is what made Cut/Delete appear to do nothing.
- Cut/Copy/Paste clipboard: clipboard_copy/cut/paste on the engine,
clipboard clips keep footage/range/speed/track kind and stay linked
in the pasted group; paste lands at the playhead as one undo entry.
- Dropping a video-with-audio footage places the video clip plus a
linked audio clip at the same range in ONE 'Add Clip' undo entry.
- Add Video/Audio Track buttons in the timeline toolbar and the track
header context menu; new sequences start with 2 video + 2 audio
tracks (not an undoable edit).
- oaknode Graph::add_entry now reclaims the slot from the free list —
before, a detached-then-reattached node left its slot in the free
list, so node_count undercounted and the next add_node silently
clobbered the restored node. This was the user's 'undo, redo, undo,
redo and the result changed' bug; regression covered by cycle tests
(move/trim/delete/split/add-track/linked-placement all converge).
- crates/oakengine moved to crates/oakengine.bk (excluded from the
workspace): the frozen C-ABI cdylib had no in-workspace consumers
left after the direct-rlib migration (M14); git history is the
authoritative backup.
- oakcommon: remove the CHandle module (no remaining users); config
store and shared value types are unaffected.
- oakengine is now cdylib-only (no rlib/staticlib consumers anywhere;
cargo tree verified) — the plugin/external C ABI layer; README and
docs updated
- cd.yml drops the dylib embedding/re-sign steps (the app no longer
links it)
- test race root-caused and fixed for good: the global undo stack lock
is now a re-entrant mutex (parking_lot) shared by every test that
drives the stack, including the previously unlocked node/render
families; the render-manager serial-ordering bug (an earlier repro
test initialized the global manager before the not-initialized test)
is fixed with a shared SERIAL guard and a manager shutdown
- 5 consecutive parallel runs clean; serial 209/209
- real.rs rewritten over module Rust APIs (Arc<Mutex<Project>> +
NodeId; the addref handle dance and renderer boxes are gone);
AppEngine trait and all panels untouched
- new app assembly layers: graphops (project/timeline/edit
primitives), effectchain (chain composition with undo groups),
renderops (montage build + ticket render + ExportTask export),
library via oakstorage directly
- module-side safe API additions: oakundo global value-semantic
push/undo/redo + from_closures, oakstorage project_arc_of
- deleted: src/oakui/ffi.rs, src/oakui/host_syms.rs, the dylib link
config in build.rs (only the gpui IOSurface framework link remains)
- the binary carries zero liboakengine references (otool/nm verified);
101 app tests green incl. the real-render and full-res e2e tests
- behavior improvements for free: sequences land in the project graph
(the facade scratch-project deviation is gone), footage drops take
one undo record, effect remove/reorder undo restores edges
The 'host-provided' oakcore_audioparams_* runtime imports dated from
the deleted C++ host; the facade is their only caller. The dylib now
defines and exports the six symbols itself (repr(C) AudioParams mirror,
liboakcore-compatible semantics), -Wl,-undefined,dynamic_lookup is gone,
and the Windows DLL undefined-symbol blocker is removed by construction
(Windows CI/packaging stays off until a real toolchain verifies links).
D3: oakdb+pg:// fully wired (shared sea-orm entities, BIGSERIAL DDL,
connect-probe instead of pool retry on dead servers); Storage/Backend=pg
+ Storage/PgUrl config; 13 OAK_TEST_PG_URL-gated PG tests (verified
against a Docker postgres:16), always-on clean-error tests otherwise.
D4: DaVinci-style project manager — list with derived stats, create/
rename/duplicate/delete (confirm)/import/export (native dialogs,
ove/otio/fcpxml), shown at startup and from the file menu; facade
oakengine_library_* exports (list/create/delete/rename/duplicate/
import/export + project_load_library that binds write-through);
save/save-as menu becomes 'export project file', open splits into
from-library/from-file; status bar shows library write state; storage
activates on app start and flushes on exit; spawn_modal reentrancy
fixed (window-callback path) with a doc note.
Also: the P1 audio test's environment probe was lost in the ffi purge;
restored on cpal (the output device is cpal now).
oakstorage (new workspace member): URI dispatch, pluggable backends
(ove-xml built in, otio/fcpxml via oakotio, C-vtable foreign
registration), the M10 C API surface, version info codes, last-error
and alive accounting; round-trip tests per backend.
oaknode serializer: persists the full timeline — sequence track lists,
track block lists, block ranges/media_in/speed/flags, clip footage
references, footage filename+streams, folder children — through
<custom> behavior hooks with two-phase reference resolution; loads the
C++ <olive><project><layout> containers (golden: tests/
project_with_footage.ove); round-trip is field-by-field and
byte-idempotent.
- CI: push/PR to main only; ubuntu/macos-15-arm64/windows-ucrt64 matrix;
deps via tooling/install-deps.sh; project FFmpeg built once and cached
under .cache/ffmpeg keyed on the build script; rust-cache for target/
- CD: tag v* packages with cargo-packager — deb/AppImage/pacman on
Linux (rpm converted from the deb with fpm), NSIS on Windows, and a
DMG (Apple Silicon) whose .app embeds liboakengine.dylib via
install_name_tool; tag pushes publish a GitHub release with all
packages attached
- root Cargo.toml gains [package.metadata.packager]; the app icon is
generated from Oak_Icon.svg with rsvg-convert in CI
- root build.rs now also links the app on Linux (link-search + rpath +
--export-dynamic); Windows remains blocked on the DLL undefined-symbol
problem (oakcore_* host imports), documented in build.rs
- App no longer depends on the oakengine rlib: build.rs links the
built liboakengine.dylib (+rpath, -export_dynamic, IOSurface) and
src/oakui/ffi.rs declares the pure-C surface; RealEngine calls only
the frozen oakengine_* C ABI
- host_syms.rs provides the oakcore_*/fb_* host symbols the dylib
imports via dynamic lookup
- Fix Preferences dialog crash (spawn_modal reentrancy) with a
regression test
- Timeline toolbar and viewer transport render C++-era icons (16px
grid, dark/light themes) with localized tooltips
- i18n: complete en-US table, add untranslated-key detection test
- New dialogs module (preferences, export, progress)