Skip to content

Avalonia/.NET 10 Port: Consolidated Windows/macOS/Linux support#508

Draft
tzarc wants to merge 19 commits into
qmk:masterfrom
tzarc:avalonia-net10-port
Draft

Avalonia/.NET 10 Port: Consolidated Windows/macOS/Linux support#508
tzarc wants to merge 19 commits into
qmk:masterfrom
tzarc:avalonia-net10-port

Conversation

@tzarc

@tzarc tzarc commented May 4, 2026

Copy link
Copy Markdown
Member

Description

Replaces the Windows WinForms and macOS Swift applications with a single Avalonia/.NET 10 codebase targeting Linux (x64, arm64), macOS (universal), and Windows (x64).

Raising for visibility. This is a very considerable PR, given the complete rewrite.

Non-maintainers: Don't expect merge any time soon.

Prebuilt binaries can be found on my fork's releases: https://github.com/tzarc/qmk_toolbox/releases/tag/beta-xplat

Dark Light
image image

Removed:

  • windows/ WinForms C# application
  • macos/ Swift/Xcode application

New application structure (src/):

  • QmkToolbox.Core: platform-agnostic bootloader detection, flash/reset/EEPROM operations, USB device model, and service interfaces
  • QmkToolbox.Desktop: Avalonia UI with MVVM (CommunityToolkit.Mvvm), HID console, key tester, settings, and platform service implementations
  • QmkToolbox.Tests: xUnit test suite covering bootloader factory, flash commands, USB device parsing, settings serialisation, and resource layout

Flash tool changes:

  • Binaries sourced from qmk_flashutils releases and bundled per-platform under resources/flashutils/{linux-x64,linux-arm64,osx,win-x64}/
  • Added picotool (RP2040/RP2350) and wb32-dfu-updater_cli (WB32) — not present in the old platform-specific bundles
  • Per-platform flashutils_release_* manifest files used for version-gated extraction; stale installs are wiped and re-extracted on version change

HID / hidapi:

  • libhidapi bundled per-platform under resources/hidapi/ from qmk_hidapi releases; loaded at runtime via NativeLibrary rather than P/Invoke paths
  • HidConsoleDevice and HidApiListener replace the platform-specific HID listeners in the old Windows/macOS codebases

Platform services:

  • Linux: udev rules (50-qmk.rules) and qmk_id helper sourced from qmk_udev releases and extracted to /etc/udev/rules.d at runtime via UdevInstaller
  • Windows: driver installation preserved via embedded qmk_driver_installer
  • macOS/Linux USB hotplug via Usb.Events (wraps IOKit/udev per-platform)
  • Windows USB hotplug rewritten to directly register for device notifications, bypassing WMI (Usb.Events supports Windows, but still uses WMI and is slow)
  • Serial port resolution via DesktopSerialPortService (Registry lookup on Windows, /dev/serial/by-id on Linux, /dev/cu.* nodes on macOS)

Build and release:

  • scripts/fetch-tools.sh downloads qmk_flashutils, qmk_hidapi, qmk_driver_installer, and qmk_udev from their respective GitHub releases into resources/
  • scripts/publish-all.sh produces self-contained per-platform binaries
  • scripts/make-app.sh / make-pkg-macos.sh / make-installer-win.sh package platform-specific installers
  • GitHub Actions CI matrix builds all four targets and uploads artifacts
  • Husky pre-commit hook enforces dotnet-format

Types of Changes

  • Core
  • Bugfix
  • New feature
  • Enhancement/optimization
  • Documentation

Replaces the Windows WinForms and macOS Swift applications with a single
Avalonia/.NET 10 codebase targeting Linux (x64, arm64), macOS (universal),
and Windows (x64).

Removed:
- windows/ WinForms C# application
- macos/ Swift/Xcode application

New application structure (src/):
- QmkToolbox.Core: platform-agnostic bootloader detection, flash/reset/EEPROM
  operations, USB device model, and service interfaces
- QmkToolbox.Desktop: Avalonia UI with MVVM (CommunityToolkit.Mvvm), HID
  console, key tester, settings, and platform service implementations
- QmkToolbox.Tests: xUnit test suite covering bootloader factory, flash
  commands, USB device parsing, settings serialisation, and resource layout

Flash tool changes:
- Binaries sourced from qmk_flashutils releases and bundled per-platform
  under resources/flashutils/{linux-x64,linux-arm64,osx,win-x64}/
- Added picotool (RP2040/RP2350) and wb32-dfu-updater_cli (WB32) — not
  present in the old platform-specific bundles
- Per-platform flashutils_release_* manifest files used for version-gated
  extraction; stale installs are wiped and re-extracted on version change

HID / hidapi:
- libhidapi bundled per-platform under resources/hidapi/ from qmk_hidapi
  releases; loaded at runtime via NativeLibrary rather than P/Invoke paths
- HidConsoleDevice and HidApiListener replace the platform-specific HID
  listeners in the old Windows/macOS codebases

Platform services:
- Linux: udev rules (50-qmk.rules) and qmk_id helper sourced from qmk_udev
  releases and extracted to /etc/udev/rules.d at runtime via UdevInstaller
- Windows: driver installation preserved via embedded qmk_driver_installer
- USB hotplug via Usb.Events (wraps IOKit/udev/WMI per-platform)
- Serial port resolution via DesktopSerialPortService (WMI on Windows,
  /dev/serial/by-id on Linux, IORegistryExplorer on macOS)

Build and release:
- scripts/fetch-tools.sh downloads qmk_flashutils, qmk_hidapi, qmk_driver_installer,
  and qmk_udev from their respective GitHub releases into resources/
- scripts/publish-all.sh produces self-contained per-platform binaries
- scripts/make-app.sh / make-pkg-macos.sh / make-installer-win.sh package
  platform-specific installers
- GitHub Actions CI matrix builds all four targets and uploads artifacts
- Husky pre-commit hook enforces dotnet-format

Known limitation:
- Trimming disabled pending compatibility issues with Avalonia and
  System.Management (WMI) under NativeAOT/trimmed runtimes
@tzarc

tzarc commented May 4, 2026

Copy link
Copy Markdown
Member Author

GHA workflows are currently set up so they produce binaries on my own fork, will pivot those to main QMK GitHub org closer to merge time.

tzarc added 5 commits May 4, 2026 20:49
…orms.

- Eliminates the use of WMI on Windows by directly querying the device tree for USB events.
- Ensures that trimming is effective on all platforms, reducing the application size and improving performance.
@tzarc tzarc changed the title Port QMK Toolbox to Avalonia/.NET 10 with cross-platform support Avalonia/.NET 10 Port: Consolidated Windows/macOS/Linux support May 5, 2026
@tzarc tzarc force-pushed the avalonia-net10-port branch from 0664511 to 8b76f19 Compare May 6, 2026 02:24
@tzarc tzarc added the linux label May 27, 2026
@NickBrisebois

NickBrisebois commented May 30, 2026

Copy link
Copy Markdown

Thank you for this! I was really surprised there wasn't already official Linux support for Toolbox when I started setting up QMK on my new keyboard today

edit: Successfully flashed my QMMK Pro with it using a firmware compiled on config.qmk.fm 😄 (Linux kernel 7.0.10-1-cachyos w/ KDE 6.6.5 on Wayland)

@tzarc tzarc force-pushed the avalonia-net10-port branch from e68d435 to 19e6dd1 Compare June 10, 2026 23:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Linux version please Arm binaries for dfu-programmer etc.

2 participants