VST3: two context-menu bridge fixes - #542
Merged
defiantnerd merged 2 commits intoSep 13, 2026
Merged
Conversation
clap_plugin_context_menu::populate documents target == nullptr as the global context, so a plugin that passes it is conforming. The wrapper dereferenced it unconditionally while deciding which menu to create, which takes the host down. Treat it as the global context, which is what it means. An unrecognised kind still creates no menu, as before.
defiantnerd
force-pushed
the
vst3-context-menu-fixes
branch
from
September 13, 2026 08:22
e7a35d1 to
72cf961
Compare
createParameter() publishes a parameter as `info->id & 0x7FFFFFFF`, but createContextMenu() was handed the raw clap_id. For any parameter whose id has the top bit set the host is asked for a menu for an id it never saw, so it cannot offer the parameter's own entries. The mask is not a convention: pluginterfaces/vst/vsttypes.h documents ParamID as "value in range [0, 0x7FFFFFFF]" and names the bound kMaxParamId. Every other clap_id -> ParamID conversion in the wrapper already applies it - param_clear, the queued editvalue, and the three in detail/vst3/process.cpp - so this call was the only one out of step.
defiantnerd
force-pushed
the
vst3-context-menu-fixes
branch
from
September 13, 2026 08:35
72cf961 to
f79bfa6
Compare
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.
Two independent correctness fixes on the VST3 context-menu bridge, one commit each. Found while implementing
clap.context-menuconsumption in a plugin — i.e. the plugin draws its own menu and merges the host's entries into it.1. A null target dereferences
clap/ext/context-menu.hcarries "If target is null, assume global context." on all five function pointers, and has since CLAP 1.1.4 — before context-menu support landed here.ClapAsVst3::context_menu_populatedereferenced it unconditionally while deciding which menu to create, taking the host down.Now treated as what it means. An unrecognised
kindstill creates no menu, as before. This was the only dereference oftargetin the tree:context_menu_performignores it (its action ids are the indices it handed out, so the target adds nothing),Plugin::context_menu_populateonly forwards the pointer, and the other four flavoursreturn falsewithout touching it.2. The context-menu parameter id is not masked
createParameter()publishes every parameter asinfo->id & 0x7FFFFFFF, butcreateContextMenu()was handed the rawclap_id. For a parameter whose id has the top bit set, the host is asked for a menu for an id it never saw, so it cannot offer that parameter's own entries.The mask is the SDK's own rule, not a local convention:
pluginterfaces/vst/vsttypes.hdocumentsParamIDas "value in range [0, 0x7FFFFFFF]" and nameskMaxParamId. Every otherclap_id→ParamIDconversion in the wrapper already applies it —param_clear, the queuededitvalue, and the three indetail/vst3/process.cpp— so this call was the only one out of step. It introduces no new collision: two ids differing only in bit 31 already collide in theparameterstable that this menu request now names.Verified against Cubase on macOS with a CLAP plugin consuming
clap_host_context_menuthrough the VST3 wrapper: host entries reach the plugin's menu with nested submenus and disabled items intact, and selecting one performs the host's action.That plugin avoids both paths above by construction — it never sends a null target and its only parameter id is below 2^31 — which is how they were found rather than hit.