Skip to content

fix(plugin): stop the editor aborting the host on Windows - #284

Merged
OpenSauce merged 4 commits into
mainfrom
fix/windows-editor-crash
Jul 27, 2026
Merged

fix(plugin): stop the editor aborting the host on Windows#284
OpenSauce merged 4 commits into
mainfrom
fix/windows-editor-crash

Conversation

@OpenSauce

@OpenSauce OpenSauce commented Jul 27, 2026

Copy link
Copy Markdown
Owner

Loading the VST3 in REAPER on Windows killed the DAW the moment the editor opened, with exception 0xc0000409 and Rustortion.vst3 as the faulting module.

That code is __fastfail(FATAL_APP_EXIT) -- Rust's abort(). nih-plug's log had the cause:

panicked at 'called `Option::unwrap()` on a `None` value':
iced_baseview/src/conversion.rs:781

The Win32 arm of convert_raw_window_handle tested hinstance.is_null() and then unwrapped NonZeroIsize::new(hinstance) inside the .then() closure -- which runs precisely when the pointer is null. baseview fills in only hwnd and leaves hinstance null on every window, so this fired on every editor open; the panic crossed the extern "C" wrapper boundary, became a non-unwinding panic, and aborted the host. Linux takes the Xlib arm, which is why neither CI nor local dev ever saw it.

Fixed upstream in the fork (OpenSauce/iced_baseview@f76ba2f1), which recovers the HINSTANCE from the window via GetWindowLongPtrW(GWLP_HINSTANCE) rather than passing the null through -- wgpu's Vulkan backend refuses a surface without one.

Dependency pin

The fork dep now points at the v0.1.0 tag rather than a bare rev on a topic branch:

iced_baseview = { git = "https://github.com/OpenSauce/iced_baseview.git", tag = "v0.1.0" }

v0.1.0 resolves to a0c8040d and contains the fix (f76ba2f1 merged via PR #1, plus a repository-metadata commit) -- verified with git merge-base --is-ancestor. A bare rev on a topic branch is not a released state and says nothing about what it holds; a tag does.

CLAUDE.md described this as an "unpinned git dep", which was already inaccurate and is now doubly so, so it is corrected in the same commit to name the tag and note that moving it means cutting a release on the fork first.

Testing

cargo check -p rustortion-plugin builds clean against the tag. The Windows crash itself still needs verifying on Windows -- neither CI nor Linux dev exercises the Win32 arm, which is how the bug survived in the first place.

OpenSauce and others added 4 commits July 27, 2026 14:53
Loading the VST3 in REAPER on Windows killed the DAW the moment the editor
opened, with exception 0xc0000409 and Rustortion.vst3 as the faulting module.

That code is `__fastfail(FATAL_APP_EXIT)` -- Rust's `abort()`. nih-plug's log
had the cause:

    panicked at 'called `Option::unwrap()` on a `None` value':
    iced_baseview/src/conversion.rs:781

The Win32 arm of `convert_raw_window_handle` tested `hinstance.is_null()` and
then unwrapped `NonZeroIsize::new(hinstance)` inside the `.then()` closure --
which runs precisely when the pointer *is* null. baseview fills in only `hwnd`
and leaves `hinstance` null on every window, so this fired on every editor open;
the panic crossed the extern "C" wrapper boundary, became a non-unwinding panic,
and aborted the host. Linux takes the Xlib arm, which is why neither CI nor
local dev ever saw it.

Fixed upstream in the fork (OpenSauce/iced_baseview@f76ba2f1), which recovers the
HINSTANCE from the window via `GetWindowLongPtrW(GWLP_HINSTANCE)` rather than
passing the null through -- wgpu's Vulkan backend refuses a surface without one.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
With the Windows abort out of the way the editor renders, but flickers while it
is open.

`IcedBaseviewSettings::default()` leaves `always_redraw` off, so iced redraws
only when it decides it has something new to show. baseview cannot request a
redraw when the window's visibility changes, so between the two the window can
end up presenting a swapchain buffer that nothing ever drew into -- stale on
Windows, blank on a reopened editor. Upstream's own doc comment describes the
default as the thing to work around, and `nih_plug_iced` hard-codes the opposite
(`nih_plug_iced/src/editor.rs:104`).

Cost is a redraw per baseview window update while the editor is open, which is
what every other iced-based plugin editor already pays.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
…ring"

This reverts commit b0b4b5d.

It did not fix the flicker, and it broke the dropdowns: `always_redraw` forces
`needs_update` true on every frame (iced_baseview application.rs:424), which
tears down and rebuilds the whole `UserInterface` continuously -- and a
`pick_list` dropdown is an overlay that has to survive across frames to stay
open and take a click.

The flicker turned out to follow the graphics backend, not the redraw rate:
forcing `WGPU_BACKEND=gl` removes it while the default DX12 path shows it.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
The dep pointed at a bare `rev` on a topic branch (`f76ba2f1`, on
`fix/win32-hinstance`), which is not a released state and says nothing about
what it contains. The fork now has a `v0.1.0` tag containing that fix — PR #1
merged, plus a metadata commit — so pin to the tag instead.

Resolves to a0c8040d, verified to contain f76ba2f1.

CLAUDE.md called this an "unpinned git dep", which was already wrong and is now
doubly so; corrected to name the tag and say that moving it means cutting a
release on the fork first.
@OpenSauce
OpenSauce marked this pull request as ready for review July 27, 2026 19:27
Copilot AI review requested due to automatic review settings July 27, 2026 19:27

Copilot AI left a comment

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.

Pull request overview

This PR addresses a Windows-only crash where opening the VST3 editor could abort the host (panic crossing an extern "C" boundary) by updating the iced_baseview fork dependency to a released tag that includes the Win32 HINSTANCE recovery fix.

Changes:

  • Pin iced_baseview in rustortion-plugin to the v0.1.0 git tag (instead of a bare rev).
  • Update Cargo.lock to reflect the tagged commit and resulting dependency resolution.
  • Correct CLAUDE.md to document the dependency as tag-pinned and clarify the upgrade procedure.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated no comments.

File Description
rustortion-plugin/Cargo.toml Switch iced_baseview dependency from a specific rev to the v0.1.0 tag.
Cargo.lock Lockfile updates reflecting the tagged iced_baseview commit and transitive dependency resolution changes.
CLAUDE.md Documentation update to accurately describe iced_baseview as pinned to v0.1.0 and note release/tag expectations.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@OpenSauce
OpenSauce merged commit aceddb7 into main Jul 27, 2026
11 checks passed
@OpenSauce
OpenSauce deleted the fix/windows-editor-crash branch July 27, 2026 19:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants