Skip to content

feat(desktop/garmin-express): add Garmin Express via Wine#1615

Open
fredclausen wants to merge 1 commit into
mainfrom
add-garmin-express
Open

feat(desktop/garmin-express): add Garmin Express via Wine#1615
fredclausen wants to merge 1 commit into
mainfrom
add-garmin-express

Conversation

@fredclausen

Copy link
Copy Markdown
Member

Summary

  • Adds a new `desktop.garmin-express` module under `features/desktop/garmin-express/` that runs the Windows Garmin Express app in a dedicated Wine prefix, so map and firmware updates work for Garmin devices (e.g. Edge 840) on NixOS.
  • Wired into `features/desktop/default.nix` and gated behind `desktop.enable_extra` (matches the pattern used by `ledger` / `trezor`).

Why

Garmin doesn't ship a Linux client. Native alternatives (manually copying `.img` files, Garmin Connect mobile) work for some cases but not for paid/preloaded TopoActive maps tied to Express. A reproducible Nix-managed Wine wrapper avoids the alternative of running a full Windows VM for one app.

How it works

The module:

  • Pins the Garmin Express installer with `fetchurl` (sha256). Note: Garmin's URL is unversioned; the hash will need refreshing when they rotate the binary.
  • Provides a `garmin-express` shell wrapper that, on first launch:
    1. Initialises a dedicated Wine prefix at `$XDG_DATA_HOME/wineprefixes/garmin-express`.
    2. Installs `corefonts` and `dotnet48` via `winetricks` (Express requires .NET Framework 4.x).
    3. Runs the Garmin Express installer interactively.
    4. Writes a `.garmin-express-installed` marker so subsequent launches skip setup.
  • Launches `express.exe` (32-bit, under `Program Files (x86)`) with `--disable-gpu --disable-gpu-compositing` to work around CefSharp.Wpf rendering as a black window under XWayland.
  • Adds a `.desktop` entry for app launchers.
  • Adds a udev rule for Garmin USB vendor `091e` and enables `gvfs` for MTP support.
  • Pulls in `wineWow64Packages.stable`, `winetricks`, `jmtpfs`, `libmtp`.

Caveats

  • Reproducibility limits: the Wine prefix is mutable state on disk; only the installer hash and Wine version are Nix-pinned. `winetricks` also downloads .NET from Microsoft at runtime (cached in `~/.cache/winetricks`). This is the unavoidable trade-off for a closed-source vendor app.
  • First-run is slow: ~10-20 minutes to install .NET 4.8 + Garmin Express. Subsequent launches are instant.
  • GPU-accel disabled: required to avoid the black-window issue with CefSharp.Wpf under XWayland. Verified working on Hyprland.

Test plan

  • Module evaluates (`nix-instantiate --parse`).
  • Built successfully on `fredhub`.
  • First-run setup completes (.NET 4.8 + Express installer).
  • App launches and renders the UI with `--disable-gpu`.
  • Edge 840 detected and map update flow tested end-to-end (next step on real hardware).

Copilot AI review requested due to automatic review settings May 10, 2026 08:58

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an optional NixOS desktop module to install and run Garmin Express (Windows) under Wine with a dedicated per-user Wine prefix, integrated into the existing desktop.enable_extra feature-gating.

Changes:

  • Introduces desktop.garmin-express module with a garmin-express wrapper that bootstraps a Wine prefix, installs prerequisites via winetricks, runs the pinned Garmin installer, and then launches Express with GPU disabled.
  • Adds a .desktop entry and installs required MTP/Wine-related packages for configured users.
  • Wires the module into features/desktop/default.nix and enables it when desktop.enable_extra is set.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
features/desktop/garmin-express/default.nix New module that pins the installer, provides the Wine/winetricks bootstrap wrapper, and configures udev + packages needed for Garmin Express/MTP.
features/desktop/default.nix Imports the new module and enables it behind desktop.enable_extra.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +97 to +99
# Allow user-level access to Garmin USB devices (vendor 0x091e).
services.udev.extraRules = ''
SUBSYSTEM=="usb", ATTRS{idVendor}=="091e", MODE="0666", GROUP="users"
Adds a desktop.garmin-express module that wraps the Windows Garmin Express
installer in a Wine prefix so Garmin device map/firmware updates work on
NixOS. Enabled with desktop.enable_extra alongside other vendor apps.

Wrapper handles first-run setup (wineboot, .NET 4.8 via winetricks, then
the pinned Garmin installer) and launches express.exe with --disable-gpu
to work around CefSharp.Wpf rendering as a black window under XWayland.

Also disables winemenubuilder via WINEDLLOVERRIDES so Wine does not
auto-export a duplicate .desktop entry into ~/.local/share/applications.
@fredclausen fredclausen force-pushed the add-garmin-express branch from fd52809 to 5def8c6 Compare May 12, 2026 20:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants