CLAP: support host-driven GUI resizing (Editor::set_size + ViziaState::new_resizable)#273
Open
chrisredekop wants to merge 2 commits into
Open
CLAP: support host-driven GUI resizing (Editor::set_size + ViziaState::new_resizable)#273chrisredekop wants to merge 2 commits into
chrisredekop wants to merge 2 commits into
Conversation
Some CLAP hosts resize plugin windows host-side: the user drags the hosts window frame and the host negotiates through adjust_size() / set_size() (FL Studio works exclusively this way). The wrapper previously rejected every proposal, which made plugin windows completely rigid there, and can_resize was hardcoded to false so plugin-initiated request_resize() calls were ignored too. - Editor gains set_size(width, height) (logical pixels, same units as size()) with a default implementation that rejects the resize, so existing editors keep their fixed-size behavior. - ext_gui_can_resize returns true, ext_gui_adjust_size echoes the hosts proposal, and ext_gui_set_size forwards it to the editor, falling back to the old only-the-current-size check for editors that do not implement set_size.
ViziaState::new_resizable(size_fn, on_host_resize) opts an editor into host-driven resizing: Editor::set_size converts the proposal into size_fn units, the apps callback updates (and may clamp) whatever state size_fn reads, and an ApplyHostResize message is emitted through vizias event proxy so the embedded window is resized on the GUI thread. The proxy is used rather than the idle callback because vizia_baseview only runs on_idle on input events, and a host frame drag generates none (the idle path stays as a fallback). The GeometryChanged that follows a host-driven resize skips the request_resize renegotiation via a one-shot flag: the host already approved that size, and hosts that refuse plugin-initiated requests would otherwise revert their own resize. Note for Windows: the embedded window relayout additionally needs a baseview rev that includes the current masters Win32 resize handling. The rev currently pinned by nih-plug (2c1b1a7) pre-writes the new size into its bookkeeping, which makes the WM_SIZE following SetWindowPos look like a no-op and swallows the Resized event; baseview master has this fixed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Some CLAP hosts resize plugin windows host-side: the user drags the host's window frame and the host negotiates through
adjust_size()/set_size(). FL Studio works exclusively this way. The CLAP wrapper previously rejected every proposal (and hardcodedcan_resize -> false), which makes nih-plug plugin windows completely rigid there.This PR adds opt-in support for that model, addressing the "TODO: Implement Host->Plugin GUI resizing" in the CLAP wrapper:
Editor::set_size(width, height)(logical pixels, same units assize()), default implementation rejects — existing editors keep their exact fixed-size behavior.ext_gui_can_resizereturnstrue,ext_gui_adjust_sizeechoes the host's proposal,ext_gui_set_sizeforwards toEditor::set_sizeand falls back to the old only-the-current-size comparison when the editor does not implement it.nih_plug_vizia:ViziaState::new_resizable(size_fn, on_host_resize)opts an editor in. The callback updates (and may clamp) whatever statesize_fnreads; the new size is applied to the embedded window on the GUI thread via anApplyHostResizemessage through vizia's event proxy. The proxy is used becausevizia_baseviewonly runs the idle callback on input events — and a host frame drag generates none. TheGeometryChangedthat follows skips therequest_resizerenegotiation through a one-shot flag, since hosts that refuse plugin-initiated requests (FL) would otherwise revert their own resize.Existing
ViziaState::new/new_with_default_scale_factoreditors are unaffected (on_host_resize: None→set_sizerejects, legacy behavior).Verified
Tested in FL Studio 2025 (Windows 11, 125 % DPI): dragging FL's frame grip resizes window and content live and smoothly; plugin-side clamping works; sizes persist via the plugin's own
#[persist]state.clap-validator0.3.2 passes (in-process).Heads-up for Windows
The embedded window relayout additionally needs a baseview rev that includes current master's Win32 resize handling. The rev pinned today (
2c1b1a7) pre-writes the new size intowindow_info, so theWM_SIZEthat followsSetWindowPoscompares equal and theResizedevent is swallowed — the HWND resizes but vizia never relays out. baseview master has this fixed (send_resizedrefactor), so a baseview pin bump makes this work end-to-end; we currently carry a one-line baseview patch alongside this branch.Happy to adjust naming/placement —
set_sizemirroringsize()units felt most consistent, but an explicit physical/logical split would work too.