Linux/Ubuntu port + Qt6 migration + Windows build/installer & UX enhancements#81
Linux/Ubuntu port + Qt6 migration + Windows build/installer & UX enhancements#81fnsangiul wants to merge 9 commits into
Conversation
…X enhancements" This reverts commit 492cf4b.
Step-by-step apt-based build for the ubuntu-port branch: deps, configure, run, expected first-failure points, and the V4L2 hardware-control caveat. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…counter) On Linux the kernel uvcvideo driver caches UVC control reads and only re-queries the device on a write. The Miniscope streams data back to the host by overloading UVC Processing-Unit controls (frame counter on CONTRAST, BNO quaternion on SATURATION/HUE/GAIN/BRIGHTNESS, ext-trigger on GAMMA), so the OpenCV/V4L2 backend read stale/frozen values: BNO never updated and the lost-frame counter ran away negative. Windows DirectShow re-reads fresh each time, which is why this only affected Linux. Add VideoStreamLibUVC, which talks to the device directly over libuvc/libusb (detaching uvcvideo while open) and issues a fresh UVC GET_CUR on every read, bypassing the cache. It handles YUYV 608x608 streaming, all control writes (LED/gain/EWL/framerate) via the same I2C-over-UVC packing as before, and the BNO/frame-counter/ext-trigger reads. Continuous BNO refresh on the DAQ is enabled with a SATURATION=0x0001 start command sent at stream start (the app otherwise gates this on the Record button; on Linux it must be live during Run). - Extract VideoStreamBase abstract interface; VideoStreamOCV implements it. - VideoDevice selects the backend in its constructor: Linux + Miniscope + a live deviceID -> libuvc; everything else (webcams, Windows, video playback) stays on OpenCV. Windows/OpenCV path is untouched. - CMake finds and links libuvc + libusb-1.0 and defines HAVE_LIBUVC on Linux; falls back to OpenCV with a warning if libuvc is absent. - Lower the CMake Qt floor 6.5 -> 6.4 (satisfied by any newer Qt). - Rewrite BUILD_LINUX.md to document the conda + libuvc build and the backend. Verified on Miniscope V4-BNO hardware (Ubuntu 24.04, conda Qt 6.11): live video, BNO roll/pitch/yaw tracks motion with the orientation logo, sane frame counter, and LED/gain/EWL controls all physically respond. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
- NewQuickView: add a cross-platform resizeEvent that snaps height to the locked width:height ratio on X11/Wayland/macOS. The ratio lock was already wired (setLockedAspectRatio) but only enforced on Windows via WM_SIZING. - backend.cpp scanVideoDevices(): add a Linux/V4L2 branch (was Windows-only). Enumerates /dev/videoN from /sys/class/video4linux, reads each node's name, and marks capture vs metadata nodes via VIDIOC_QUERYCAP so users can tell which deviceID to use. - VideoStreamLibUVC: close the device when the stream loop ends so uvc_close re-attaches the kernel uvcvideo driver and /dev/videoN returns after a session (previously the worker-thread object's destructor didn't run on shutdown, leaving the Miniscope's video nodes detached). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
USE_PYTHON=OFF previously failed to compile: PyObject members and a couple of NumPy/Python uses (import_array1, getColors) were not #ifdef-guarded. Guard them so the behaviour tracker (embedded Python / DeepLabCut-Live) becomes truly opt-in. With USE_PYTHON=OFF the binary links no Python at all — useful for a lean Linux AppImage. To re-enable DLC later, configure with -DUSE_PYTHON=ON; all the Python-dependent code lives in the guarded sections. Also add packaging/99-miniscope.rules: a udev rule granting USB access to the Cypress FX3 Miniscope DAQ (04b4:00f9) for headless / non-desktop sessions where the logind ACL isn't applied. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Add a portable Linux AppImage build and a first-run experience that lets the user choose where their configs and recordings live. App (cross-platform, env-driven; unset = previous behavior, so Windows is unaffected): - New-config default dataDirectory honors $MINISCOPE_DATA_DIR (backend.cpp). - backend.defaultUserConfigFolderUrl() exposes $MINISCOPE_USERCONFIG_DIR; the config open/save dialogs default to it (main.qml). Packaging (packaging/): - build-appimage.sh: builds USE_PYTHON=OFF against the conda env and bundles it with linuxdeploy + the Qt plugin into a single AppImage. Pulls in the transitive deps linuxdeploy drops (OpenCV's libcblas, libusb) and the xcb platform plugin; version comes from main.cpp. - AppRun.wrapper: on first run, asks (zenity) for the user-config and data folders (defaults under ~/Documents/Miniscope; falls back if zenity is absent/cancelled), persists the choice, seeds the example configs into the chosen folder, exports MINISCOPE_USERCONFIG_DIR/MINISCOPE_DATA_DIR, and runs from a private working dir holding deviceConfigs + Scripts. Re-prompt by deleting ~/.config/MiniscopeDAQ/paths.conf. - miniscope-daq.desktop: AppImage launcher entry. CI: .github/workflows/release-linux.yml mirrors the Windows workflow (conda + libuvc, tag-triggered release via action-gh-release; manual run uploads the AppImage as an artifact). .gitignore: scope build-* to directories (was hiding packaging/build-appimage.sh) and ignore dist/. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Remove the branches: ubuntu-port trigger before merging. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
The Linux workflow now triggers only on v* tags and manual dispatch, matching the Windows workflow. (The branch trigger was only to validate CI from the feature branch; it's served its purpose.) Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
sneakers-the-rat
left a comment
There was a problem hiding this comment.
seems good to me, we already talked about PR structure and the standards for maintenance work on deprecated projects in person.
the two things that i think would be worth doing beyond what's already done here are
- a mild restructuring of the workflows so that they feed into a single release
- declaring all the deps in cmake so that we don't need OS-specific copy/pastes
other than that, i basically will just take your word about the code changes - that they work, and also by bringing us back to a place where we can reliably compile the code, we can at least work on any bugs that might pop up again.
There was a problem hiding this comment.
as we discussed - putting these in a single workflow, two jobs, and then a third that combines the artifacts and makes a single release, would probably be one change worth making just for the sake of making "one release with the windows and linux binaries" rather than "two releases, one with windows, one with linux"
| ; A stable AppId ties every version to the same uninstall entry, so a new | ||
| ; release upgrades the previous install in place instead of stacking copies. | ||
| ; Never change this GUID once shipped. | ||
| AppId={{B7E6B2D4-3F8A-4C21-9E5D-2A1F6C9B4E70} |
There was a problem hiding this comment.
double {{ here, is that intentional?
There was a problem hiding this comment.
directory structure - might as well have one top-level directory for packaging artifacts/config and then split out for linux/windows.
/packaging/windows/MiniscopeDAQ.iss
/packaging/linux/99-miniscope.rules
...
| CFG_DIR="$HOME/.config/MiniscopeDAQ" | ||
| SETTINGS="$CFG_DIR/paths.conf" | ||
| mkdir -p "$CFG_DIR" | ||
|
|
There was a problem hiding this comment.
this is set outside the main application, is there an analogous concept for windows? or why configure that in a launcher rather than in the application?
| # Square 256x256 icon from the logo (linuxdeploy requires a standard square size). | ||
| ffmpeg -y -loglevel error -i "$REPO/source/img/MiniscopeLogo.png" \ | ||
| -vf "scale=256:256:force_original_aspect_ratio=decrease,pad=256:256:(ow-iw)/2:(oh-ih)/2:color=#00000000,format=rgba" \ | ||
| "$APPDIR/usr/share/icons/hicolor/256x256/apps/miniscope-daq.png" |
There was a problem hiding this comment.
might as well just version this statically
| // Qt6: removed cloned-QMouseEvent members; the drag logic that used them is | ||
| // disabled (commented out) in tracedisplay.cpp. |
There was a problem hiding this comment.
LLMs love to leave comments explaining that stuff no longer exists - we can just remove things, having a comment that explains that something is no longer here only serves to be confusing.
| // Qt6: removed unused 'import QtQuick.Controls.Styles 1.4' (module removed in Qt6; | ||
| // nothing in this file used a Controls-1 *Style type). |
There was a problem hiding this comment.
| // Qt6: removed unused 'import QtQuick.Controls.Styles 1.4' (module removed in Qt6; | |
| // nothing in this file used a Controls-1 *Style type). |
There was a problem hiding this comment.
i'm basically just gonna take your word on this and the below two files - haven't taken the time to read them, i imagine there may be some problems from having multiple backends patched together, but if it works it works.
There was a problem hiding this comment.
same as comment above - if we can avoid needing to do this by declaring the deps explicitly in cmake, that would b great
| - numpy=2.4 | ||
| - cmake | ||
| - ninja | ||
| - "libblas=*=*openblas" # force OpenBLAS, never MKL (see note above) |
There was a problem hiding this comment.
man what is even this specifier syntax
Summary
This PR brings the Miniscope DAQ software to Linux/Ubuntu on top of the existing Qt5 → Qt6 migration and reproducible Windows build/installer work. It targets the
qt6-portintegration branch so it can be reviewed without landing directly onmaster.The work breaks into two layers:
1. Qt6 migration, Windows build & UX (carried over from #80)
videodisplay,tracedisplay,behaviortracker); GLSL shader fixes; QML startup hardening.environment.ymlconda spec pinning the toolchain.tools/deploy.py+tools/launcher.cppportable folder, Inno Setup per-user installer, and a GitHub Actions release workflow.2. Linux / Ubuntu port (new in this PR)
videostreamlibuvc.*,videostreambase.h) for Miniscopes on Linux — live BNO and frame counter working.packaging/build-appimage.sh,AppRun.wrapper,.desktop) and a Linux release GitHub Actions workflow (.github/workflows/release-linux.yml).packaging/99-miniscope.rules) for non-root Miniscope access; guardedUSE_PYTHON=OFFbuild.BUILD_LINUX.mdbuild checklist and README Linux (AppImage) install instructions.Notes for review
qt6-portintegration branch, notmaster.