Skip to content

mod-role="input-control-port" silently fails for plugins using patch:writable parameters #161

Description

@bwanab

When writing a modgui skin for an LV2 plugin that exposes its parameters via patch:writable (the atom/patch protocol) rather than traditional lv2:ControlPort ports, using the documented mod-role="input-control-port" in icon.html causes knobs to render correctly but not respond to interaction. There is no error or warning — the knobs simply do nothing when dragged.

Root cause

In modgui.js, assignControlFunctionality populates self.controls from effect.ports.control.input:

self.controls = self.makePortIndexes(effect.ports.control.input)

For patch:writable plugins this list is empty (only internal ports like enabled and freeWheeling appear there, both with
pprop:notOnGUI). The binding code then looks up the knob's mod-port-symbol in self.controls, finds nothing, and silently skips the entire binding:

var port = self.controls[symbol]
if (port) {
// bind the knob — never reached for patch:writable plugins
}

Affected plugins

Any LV2 plugin built with JUCE uses patch:writable exclusively for all parameters. This includes the entire Surge XT effect suite and any other plugin exported via JUCE's LV2 support. The pattern is increasingly common.

Workaround

Use mod-role="input-parameter" with mod-parameter-uri set to the full parameter URI instead:

This is undocumented in the SDK and not mentioned anywhere in the modgui skin examples or wiki. A developer following the standard
examples will produce broken skins for this class of plugin with no indication of what went wrong.

Suggested fix

Either of these would resolve the issue:

  1. When input-control-port + mod-port-symbol finds no match in effect.ports.control.input, emit a console.warn identifying the
    unresolved symbol. This costs nothing and would immediately surface the problem.
  2. As a deeper fix, fall back to checking effect.parameters for a parameter whose URI ends with :symbol. If found, bind using the
    lv2PatchSet path. This would make input-control-port work transparently for both parameter types.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions