Add support for experimental add-on filters#1813
Conversation
This includes a new selection dialog and generated UIs The --experimental option is required to expose the selection --experimental is ony available when Shotcut is compiles for debug
| bool FilterController::ensureAddOnTempDir() | ||
| { | ||
| if (!m_addOnTempDir.isValid()) { | ||
| m_addOnTempDir = QTemporaryDir(QDir::tempPath() + "/shotcut-addon-XXXXXX"); |
There was a problem hiding this comment.
A new Temporary directory is created for every Shotcut instance. If someone opens/closes Shotcut a lot, they can accumulate. But this handles the case of regenerating the UI for software updates or multiple versions installed at the same time. It also makes development easy since I don't have to delete the generated files every time I make a change to the code.
| QmlMetadata *meta = m_attachedModel.getMetadata(m_currentFilterIndex); | ||
| QmlFilter *filter = nullptr; | ||
| if (meta) { | ||
| if (meta->objectName().startsWith(QStringLiteral("addOn.")) && !ensureAddOnFilterQml(meta)) { |
There was a problem hiding this comment.
The UI QML for an add-on filter is only generated when absolutely needed - when a user has selected an add-on filter in the UI. If present, the cached version is used. Else, it is generated. So, in many cases, the temporary directory will never be created if the user opens shotcut, but never uses an add-on filter.
| Shotcut.Button { | ||
| id: addOnMenuButton | ||
|
|
||
| visible: enableAddOns |
There was a problem hiding this comment.
This button only appears when --experimental is passed to Shotcut.
| QCommandLineOption gpuOption("gpu", | ||
| QCoreApplication::translate("main", "Use GPU processing.")); | ||
| parser.addOption(gpuOption); | ||
| #ifdef QT_DEBUG |
There was a problem hiding this comment.
The --experimental option is only available when Shotcut is compiled for debug.
| if (experimental) | ||
| ::qputenv("MLT_REPOSITORY_DENY", "libmltqt:libmltglaxnimate"); | ||
| else | ||
| ::qputenv("MLT_REPOSITORY_DENY", "libmltqt:libmltglaxnimate:libmltopenfx"); |
There was a problem hiding this comment.
The experimental option also enables openfx to be loaded at startup.
| return settings.value("filter/addOnServices").toStringList(); | ||
| } | ||
|
|
||
| void ShotcutSettings::setAddOnFilterServices(const QStringList &services) |
There was a problem hiding this comment.
When the user selects add-on services in the dialog, they are saved in the settings so they can be reloaded very time shotcut starts (only with --experimental)
There was a problem hiding this comment.
Pull request overview
Adds an experimental add-on filter workflow (debug builds only) that lets users opt-in to exposing arbitrary MLT filter services in Shotcut’s filter menu, with auto-generated parameter UIs and a metadata/help viewer.
Changes:
- Add
--experimental(debug-only) flag and wire it into MLT repository deny-list behavior (e.g., OpenFX availability). - Add add-on filter management UI: hamburger menu entry in the filter menu + a new “Manage Add-on Filters” dialog backed by a new
AddOnServiceModelpersisted via settings. - Generate and cache QML UIs for enabled add-on filter services on demand, plus a non-modal metadata/help viewer.
Reviewed changes
Copilot reviewed 25 out of 25 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| src/settings.h | Adds settings API for persisted add-on filter service list. |
| src/settings.cpp | Implements persisted add-on filter service list getters/setters. |
| src/qmltypes/qmlutilities.cpp | Registers new QML type used for the add-on menu popup. |
| src/qmltypes/qmlfiltermenu.h | Declares C++ QML-facing menu helper for add-on actions. |
| src/qmltypes/qmlfiltermenu.cpp | Implements popup menu that opens the add-on manager dialog. |
| src/qmltypes/qmlapplication.h | Exposes showAddOnFiltersDialog() to QML/C++ menu helper. |
| src/qmltypes/qmlapplication.cpp | Implements dialog launch for add-on filter management. |
| src/qml/views/filter/filterview.qml | Plumbs generated-UI help signal up to the dock for display. |
| src/qml/views/filter/FilterMenu.qml | Adds the experimental hamburger menu button. |
| src/models/addonservicemodel.h | New model for enumerating MLT filter services and enabled selections. |
| src/models/addonservicemodel.cpp | Implements MLT filter discovery + persistence of enabled add-ons. |
| src/mltcontroller.cpp | Adjusts MLT_REPOSITORY_DENY based on experimental flag. |
| src/mainwindow.cpp | Threads add-on service model into FiltersDock construction. |
| src/main.cpp | Adds debug-only --experimental option and sets app property. |
| src/docks/filtersdock.h | Adds support for showing non-modal add-on metadata help dialog. |
| src/docks/filtersdock.cpp | Wires QML signal to a QTextBrowser help dialog; sets enableAddOns context property. |
| src/dialogs/addonfiltersdialog.h | Declares add-on filter management dialog. |
| src/dialogs/addonfiltersdialog.cpp | Implements searchable, checkable list of all MLT filter services. |
| src/controllers/filtercontroller.h | Adds add-on UI generation/caching members and add-on metadata loading hooks. |
| src/controllers/filtercontroller.cpp | Implements add-on metadata insertion/removal and on-demand generated UI caching. |
| src/controllers/addonqmlgenerator.h | Declares generator for add-on filter parameter UI QML. |
| src/controllers/addonqmlgenerator.cpp | Generates parameter UI QML + metadata help text for add-on services. |
| src/controllers/addonmetadataparser.h | Declares parser to normalize MLT metadata into descriptors. |
| src/controllers/addonmetadataparser.cpp | Implements metadata parsing into generator-friendly descriptors. |
| src/CMakeLists.txt | Adds new sources (model, dialogs, generator, parser, QML type helper) to build. |
Comments suppressed due to low confidence (1)
src/docks/filtersdock.cpp:53
- The
addOnServiceModelparameter is not used in this constructor, which can trigger unused-parameter warnings (and it’s unclear why it is being threaded throughMainWindow). Either use it (e.g., expose it to QML via a context property) or remove it from the constructor signature/call sites; if it must remain, mark it withQ_UNUSED(addOnServiceModel)to make the intent explicit.
FiltersDock::FiltersDock(MetadataModel *metadataModel,
AddOnServiceModel *addOnServiceModel,
AttachedFiltersModel *attachedModel,
MotionTrackerModel *motionTrackerModel,
SubtitlesModel *subtitlesModel,
QWidget *parent)
Include all the metadata fields
a4657e5 to
a4e539d
Compare
|
Thank you; it is nice to have. The first filter I tried |
I found that the avformat module was incorrect about metadata and pushed a change. Now, it does not crash. |
I am on the fence about this. On the one hand, it would reduce redundancy. On the other hand, filters can be exposed/represented in many ways. Maybe we are exposing a service through our curated UI, but not exposing some of the parameters or doing it in a limited way. It might be good if the experimenter can work with the raw filter even if we have exposed it through our supported filters. As a reference, the following services are used in multiple Shotcut filters:
As a variation on this comment, for each add-on filter, I could add a note somewhere to indicate which supported filters are using that MLT filter. Perhaps as a column in the manager dialog. Or maybe a tool tip in the generated UI. |
OK I see your point. |
Use LineEditClear Replace hamburger menu with "configure" button
This includes a new selection dialog and generated UIs
The --experimental option is required to expose the selection
--experimental is only available when Shotcut is compiled for debug
When --experimental is enabled, the filter selection menu adds a hamburger menu before the search bar with a single action called "Manage Add-on Filters"

This action opens a new Add-on Filter selection dialog which lists ALL available filters in MLT:

The user can select and de-select MLT filters to be added to the main filter selection as Add-on Filters. After the dialog is closed, the main filter selection is updated with the selected (or de-selected) filters

When the user selects an Add-on filter that has been added to a clip, the UI for that add-on is auto-generated and cached in a temporary folder.

The help button (?) opens a non-modal dialog with a detailed view of all the properties for that add-on filter

I find this feature useful for exploring filters - especially the host of OpenFx filters. This has also exposed some opportunities for improving metadata for some MLT filters - which I will submit in different PRs.
Review comments are welcome.
I recommend that we wait until after the April release before we consider merging this.