feat(macro): add copy action button in macro editor - #386
Open
adaviscourt wants to merge 26 commits into
Open
Conversation
Replaces the fbs build/runtime layer, which pinned the project to Python 3.6 / PyQt5 5.9 / PyInstaller 3.4 and forced fork-based deps. Runtime - New `src/main/python/app_context.py` provides `VialContext` (QApplication setup + resource resolution via `sys._MEIPASS` when frozen, source tree otherwise) and `is_frozen()`. - `main.py` and `macro/macro_recorder_linux.py` drop `fbs_runtime` imports. Dependencies - PyQt5 5.9.2 -> 5.15.x (drops sip pin, sip6 bundled) - PyInstaller 3.4 -> 6.x - simpleeval pinned commit -> PyPI release - cython-hidapi vial fork -> PyPI hidapi - Dropped fbs, future, sip, altgraph, macholib, pefile - Adds `pyproject.toml` with project metadata and build/test extras - `test-requirements.txt` rewritten to layer on top of requirements Packaging - `vial-mac.spec`, `vial-win.spec`, `vial-linux.spec` replace the fbs build settings JSON. Bundles resources from `src/main/resources/base/` at the archive root. - `misc/Vial.desktop` replaces fbs-generated desktop file. - Linux Dockerfile bumped to Ubuntu 22.04 + Python 3.10, swaps pkg2appimage chain for appimagetool. Builder script runs PyInstaller and assembles AppDir directly. Verified locally on macOS: `pyinstaller vial-mac.spec` produces a working `Vial.app` that launches and enumerates a Vial keyboard via PyPI hidapi. Linux/Windows build chains untested in this commit. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- mac: drop manual python.pkg install, use setup-python@v5 with Python 3.10. Replace `fbs freeze` + `hdiutil` with `pyinstaller vial-mac.spec` + `create-dmg`. Bump MACOSX_DEPLOYMENT_TARGET to 10.13 (PyInstaller 6 minimum). Pin runner to macos-13 for x86_64 build. - win: bump Python 3.6 -> 3.10, setup-python@v4 -> v5. Replace `fbs freeze`/`fbs installer` with `pyinstaller vial-win.spec` + direct `makensis` invocation against existing Installer.nsi (copies dist\Vial into src\installer\Vial so the NSI's relative paths still resolve). - linux: workflow unchanged; new Dockerfile and builder script from previous commit drive the Python/PyInstaller bump. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Removes files no longer referenced after the PyInstaller migration:
- src/build/settings/{base,mac,linux}.json (fbs config)
- util/setup_python36.sh (Python 3.6 source build for old Docker)
- misc/Vial.yml (pkg2appimage recipe; replaced by appimagetool flow)
Updates README with current Python 3.10+ requirement, plain
`python main.py` dev command, and PyInstaller spec invocations.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The button relied on the third-party ShellExecAsUser NSIS plugin DLL, which fbs used to bundle automatically. Without that plugin the button silently no-ops. Removing the finish-page launch (and its LaunchLink function) keeps the installer working without committing a binary plugin to the repo. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- pyproject.toml: requires-python = >=3.13. Add [tool.uv] package = false (we run from source, don't install vial-gui as a package). - .python-version: 3.6.0 -> 3.13. - uv.lock: new — pins all transitives for reproducible installs. - README: document `uv sync` / `uv run` as the primary dev path, retain the plain-pip path as a fallback. - CI mac/win jobs: drop setup-python, use astral-sh/setup-uv@v5 with cache. Replace `pip install` with `uv sync --extra build --frozen` and `pyinstaller` with `uv run pyinstaller`. - Linux Dockerfile: drop apt python3.10 install, install uv via the official script. Builder script swaps pip+venv for `uv sync`. uv resolves and installs in seconds vs. pip's minutes for the PyQt5 + pyobjc dependency tail; the lockfile makes builds reproducible across the Linux/mac/Windows CI legs. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
`multiprocessing.RLock()` in AutorefreshThread caused an infinite process cascade in PyInstaller-frozen builds on macOS: multiprocessing lazily spawns a `resource_tracker` subprocess on first primitive creation, which (under the spawn start method, without `freeze_support()`) re-execs the frozen binary; that boots a new QApplication and AutorefreshThread, which creates another RLock, which spawns another tracker, and so on. AutorefreshThread is a QThread — single-process — so the lock only needs to coordinate threads, not processes. Switching to `threading.RLock` removes the multiprocessing import entirely. Also call `multiprocessing.freeze_support()` early in the frozen entry point as defense-in-depth against any future multiprocessing usage (PyInstaller best practice). Pre-existing bug exposed by the Python 3.13 / PyInstaller 6 upgrade. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add tool.uv.required-environments so uv lock resolves PyQt5 wheels for Windows (pyqt5-qt5 5.15.18 had no win_amd64 wheel). - Rewrite test.yml for uv toolchain; the prior version called the deleted util/setup_python36.sh. - Add hidraw as a Linux-only test extra (test_gui.py imports it). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The PyPI hidraw 0.1 package has a circular import on Python 3.13, but the test suite only needs hidraw to exist as a module so it can monkeypatch hid.enumerate / hid.device. Stub it via a top-level test conftest instead of installing the broken package. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
PyQt5 5.15.18 no longer implicitly converts float to int in QPoint constructors. bbox[0].x()/.y() return floats (QPointF), so wrap in int() to match QPoint(int, int) signature. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
macos-13 free-tier runners are slow to assign; arm64 runners are plentiful. Building both produces separate vial-mac-x86_64.dmg and vial-mac-arm64.dmg artifacts so PR CI is no longer gated on the single Intel runner. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Apple Silicon-only artifact. Intel users can run from source (uv sync && uv run) or build locally; not worth the macos-13 runner queue wait for the shrinking Intel user base. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Tag push (v*) triggers build + release. Release job downloads the build artifacts, renames them to Vial-<tag>.* and attaches them to a GitHub Release. Targets a 'release' environment so required reviewers can gate the upload. Setup step: configure repo Settings -> Environments -> 'release' with required reviewers = adaviscourt. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Rename main.yml -> build.yml. build.yml exposes workflow_call so release.yml can invoke it on tag push. Keeps build logic in one place while separating CI and release triggers/concerns. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
test.yml exposes workflow_call. release.yml now chains test -> build -> release so a tagged release can't publish with red tests. CI path (push/PR) still runs test.yml and build.yml in parallel for fast feedback. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds a verify-version job that fails the release pipeline if the pushed tag doesn't match the version in pyproject.toml. Catches forgotten version bumps before tests/build burn runner minutes. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Remove fbs, modernize Python toolchain (PyInstaller + uv + Python 3.13)
Generate Icon.icns from existing PNG sources and wire it into vial-mac.spec so the macOS .app and DMG show the Vial icon instead of the default PyInstaller floppy/Python placeholder. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
build(macos): bundle app icon in .app
Limit the push trigger to the main branch so feature branches with an open PR don't run build/test twice (once for push, once for the pull_request synchronize event). PRs still get a full run on every new commit via the pull_request trigger. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Tests already mock hidapi via conftest and use no platform-specific paths, so they run unchanged on mac and Windows runners. Adding both catches PyQt5 wheel breakage and Python install regressions on the platforms we ship. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
prepare() patched hidraw directly, which only matches the platform import on linux (hidproxy aliases hidraw -> hid there). On macOS and Windows hidproxy imports real hidapi as hid, so the mock_enumerate / MockDevice patches landed on an unrelated module and device discovery failed. Going through hidproxy.hid gives a single patch site that covers every platform. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
RegisterClass uses a fixed class name (VIAL_DEVICE_DETECTION) and the registration persists for the process lifetime. In tests that build multiple MainWindow instances, the second registration raises ERROR_CLASS_ALREADY_EXISTS (1410). Swallow that specific error since CreateWindowEx only needs the class to exist by name. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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.
When I am creating a macro that does a sequential down/up to simulate a multi-key press, it would be nice to just copy the
downaction and switch the input toup.Code written with assistance from Claude Code (Sonnet 4.6)