i18n: test_lock() and lang_test_lock() used to be TWO different static
mutexes, so the i18n tests and the ~30 app/actions/dialogs tests that
mutate the language global never excluded each other. Windows thread
scheduling exposed the race: tr_falls_back_to_english_then_the_key got
the English value because another test flipped the language mid-assert.
Both entry points now lock the same mutex.
oak_test_plugin.c: on Windows the plugin DLL has its own CRT
environment block, so getenv() never sees what the host's
std::env::set_var set via SetEnvironmentVariableW — the interact
lifecycle test's marker file stayed empty ("lifecycle actions
missing: []"). Read the marker path through GetEnvironmentVariableA
on _WIN32.
- gl_bridge: macOS CGL offscreen context (process-wide singleton,
serialized GlGuard), real GL output textures/FBOs, glReadPixels
readback with vertical flip and format conversion; use_opengl now
really engages for OpenGLRenderSupported plugins (verified with real
GL rendering: C smoke 11/11, unit tests, GL e2e).
- OfxColor: color params get a swatch button plus a real picker popup
(RGBA sliders, live preview, hex input, undoable commit) replacing
the four spinboxes.
- Push buttons route kOfxActionInstanceChanged (UserEdited) per the
OFX contract; test plugin asserts the callback.
- Worker-side plugin progress flows to the main-process progress
dialog over the NDJSON control channel, with cancel propagation.
- OFX Interact host: NewInteract/Describe lifecycle, Draw/Pen/Key/Idle
action surface with proper in-args, DrawSuite v1 host implementation
sharing the gl_bridge context; interact test plugin verifies the
event stream and real GL drawing.