Adopt shared qmlcomponents module; multi-backend video input - #67
Open
jcelerier wants to merge 3 commits into
Open
Adopt shared qmlcomponents module; multi-backend video input#67jcelerier wants to merge 3 commits into
jcelerier wants to merge 3 commits into
Conversation
- Add qmlcomponents as a submodule at qml/ca/qc/sat/qmlcomponents and pull
submodules in the build workflow.
- Replace the duplicated DarkStyle/LightStyle, Custom* controls, AboutDialog,
AppMenuBar and LogView with the shared module; appStyle.* -> Theme.*, drop
the injected appStyle/DarkStyle-LightStyle and drive Theme.dark from the OS
colour scheme instead.
- RunView: replace the Camera/Video-file toggle with InputSourceSelector and
own the Score lifecycle in the host. A single 'Input' device occupies the
alpha1 live lane (Camera/NDI/Spout/Syphon) and is routed to the Video Mapper
'in' port; the video file keeps the alpha2 lane. Sync backends reuse the
enumerated DeviceSettings, async backends use {Path:name}. restartIfRunning
and the model selection behaviour are preserved.
- environment: document LIVEPOSE_ADVANCED_IO (off) to reveal NDI/Spout/Syphon.
The shared AboutDialog now takes a partnerLogos data list instead of fixed SAT/ossia image properties; pass the SAT + ossia footer logos that way.
jcelerier
force-pushed
the
claude/qmlcomponents-adoption-nfnz0k
branch
from
June 18, 2026 15:38
44ec22a to
527b272
Compare
The Camera backend is declared enumerate: "sync", so reenumerate() set
enumerate = true and read enumerator.devices in the same tick. That holds
on desktop: setting the property runs score's reprocess() directly
(QMetaObject::invokeMethod defaults to AutoConnection), and the V4L2 and
AVFoundation enumerators call back from inside it, so the list is already
full when it is read.
It cannot hold in a browser. There, enumerating cameras means
navigator.mediaDevices.enumerateDevices(), which hands out neither ids nor
labels until camera permission has been granted -- so score's wasm
enumerator asks for permission and rescans on a timer. The prompt is raised
by that very call, and by the time the user accepts, the combo has been
built from an empty list and nothing ever reads it again: the devices
property has no NOTIFY. The cameras never appear.
Connect deviceAdded/deviceRemoved before enabling enumeration and drop the
one-shot read. Inline backends deliver through the same signal during the
assignment, so desktop behaviour is unchanged, while sources that arrive
later now show up on their own. This also handles the wasm camera's
anonymous-then-named transition: the enumerator removes the placeholder and
re-adds the device once its label is known.
Two consequences of building the list from the signal:
- deviceRemoved carries only the name, while a camera's label needs its
category too (one category per device, one name per mode), so sourceLabels
maps one to the other.
- the saved source can no longer be restored synchronously at startup;
pendingSourceRestore defers it to whenever the device turns up.
The descriptor's enumerate field stays as it is: it also selects the
settings shape (snapshot vs {Path: name}), which is a separate axis from
discovery timing -- a wasm camera is discovered asynchronously yet still
needs its enumerated DeviceSettings.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019oPj1zRcxSQX7FNni7EHM6
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.
Adopts the shared
ca.qc.sat.qmlcomponentsmodule (submodule atqml/ca/qc/sat/qmlcomponents) and generalises the input path to multiple backends.What moved
DarkStyle/LightStyle,CustomButton/ComboBox/Label/TextField/Switch,AboutDialog,AppMenuBarandLogView; the app now imports them from the module.appStyle.*→Theme.*; the injectedappStylecontext property and theDarkStyle/LightStyleinstances are gone —Theme.darkis driven from the OS colour scheme instead.qml/livepose/qmldirnow only registers the app-specificRunView.RunView.qml): the Camera/Video-file two-button toggle is replaced by the sharedInputSourceSelector. The widget is pure presentation; this view owns everyScore.*call. A singleInputdevice occupies the existingalpha1live lane (Camera/NDI/Spout/Syphon) and is routed to the current Video Mapperinport; the video file keeps thealpha2lane. Sync backends (Camera/Syphon) reuse the enumeratedDeviceSettings; async backends (NDI/Spout) use{Path:name}.restartIfRunning()and the model-selection / camera behaviour are preserved.LIVEPOSE_ADVANCED_IO(documented, off, inenvironment) reveals NDI/Spout/Syphon, platform-filtered by the widget.actions/checkoutnow usessubmodules: recursive.Notes
.gitmodulesURL points athttps://github.com/sat-mtl/qmlcomponents.git, gitlink pinned tomain.Inputon launch as the camera path did) and the last video path. Restoring a non-default backend into the selector's combo on launch is a minor follow-up (the selector is intentionally stateless); host-side state is restored regardless.LogView"Test Log" button (a dev affordance) was dropped with the move to the sharedLogView.qmllint -I qml(Score.*/Score.UI/Util are host-provided and do not resolve locally, as expected) and the module'sqmltestrunnersuite (17/17).Generated by Claude Code