How it works
- Windows: Raw Input for the HID digitizer usage page
0x0D/ touchpad0x05, parsed withHidP_*, so it keeps working while other windows have focus. AWH_MOUSE_LLhook hides edge clicks and freezes the pointer.SendInputsends keys. Brightness goes through WMI on a background thread. The settings window, tray icon and on-screen display are plain Win32 with per-monitor DPI awareness. - Linux: the touchpad is read from
/dev/input/event*(evdev multitouch protocol B). Keys, media keys and the zoom wheel are sent through virtualuinputdevices. A tiny local web server serves the settings page. - Shared: the settings, the touchpad geometry and the whole gesture engine are the same code on both systems.
No network access, no telemetry. Margin only reads the touchpad and writes your settings and a small log file.
#Build and test
cargo build --release # target/release/margin (margin.exe on Windows)
cargo test # unit tests: settings, geometry, shortcuts, the gesture engine, the evdev parser...Tests that use real hardware or the registry are marked #[ignore] and run on request (Windows):
cargo test brightness_write -- --ignored --nocapture # nudges the panel by 1 %, reads it back, restores it
cargo test startup_round_trip -- --ignored # writes and removes the "start with Windows" valueOn Linux, tools/linux-e2e.py runs the real daemon against a fake touchpad created through uinput, performs finger gestures and checks the key events that come out (volume, Alt held through a slide, corner presses, settings reload, custom keys). It needs root and a kernel with uinput, and a desktop would also see the fake touchpad, so use a VM, container or WSL:
cargo build --release && sudo python3 tools/linux-e2e.py target/release/margin#Code layout
Everything runs on one thread per program (Windows: one message loop; Linux: one poll loop). The gesture logic has no OS calls in it, so it is unit-tested without a touchpad.
| Module | Role |
|---|---|
settings.rs, geometry.rs |
settings model and JSON; where each edge and corner sits on the pad |
engine.rs |
the gesture state machine; turns touch frames and clicks into effects (pure, tested) |
keys.rs |
shortcut parsing and key codes; SendInput on Windows |
touchpad/evdev.rs, touchpad/tracker.rs |
evdev event parser (pure, tested on every OS); fingers and button state |
touchpad/raw.rs, hook.rs, brightness.rs, hud.rs, tray.rs, ui/, app.rs, ... |
Windows: Raw Input, mouse hook, WMI, on-screen display, tray, settings window |
linux/ |
Linux: device discovery, daemon loop, uinput output, corner actions, settings web server and page |
build.rs embeds the Windows manifest (per-monitor DPI, visual styles), version info and an icon generated from the same drawing code the tray uses. A GitHub Actions workflow tests on Linux and Windows and builds the release binaries when a v* tag is pushed.