Releases: mattabott/mouseferry
Releases · mattabott/mouseferry
v0.2.0 — multi-entry mode
What's new
- Multi-entry mode. Pass
--entry MONITOR:DIRECTIONrepeatably on the CLI to ferry to a single Android device from multiple monitor edges at once. Example:mouseferry --entry 1:right --entry 2:bottomtriggers the ferry both from the right edge of monitor 1 and from the bottom edge of monitor 2. - All four directions.
topandbottomjoinleftandrightas valid edges (top/bottom available only via--entry, not in single-entry config mode). - Dynamic return. By default, the cursor returns based on your sweep direction: sweep left/right → warp to the monitor of an entry with
right/leftdirection; sweep up/down → warp to an entry withtop/bottom. No need to remember which entry triggered the ferry — the sweep itself picks where to come back. A new pure helperwinning_entry()evaluates all configured entries against the current sweep accumulator. --return MONITORoverride. Forces a fixed return target (warp to center of that monitor regardless of sweep direction) for users who prefer the static behavior.- Conflict-tolerant CLI. Passing
--left/--right/--monitoralongside--entryprints a warning (not an error) and proceeds in multi-entry mode. Safe for incremental migration. - Pre-flight validation. Malformed
--entryvalues fail fast with a clear message and exit 2, before any X/adb/evdev I/O. Works cleanly in headless/CI contexts too.
Fixed
entry_matchesbounding-box bug. The edge check now verifies the cursor is inside the target monitor's full bounding box before checking proximity to the named edge. Previously--entry DisplayPort-2:bottomcould match instantly at launch if the cursor was on a different monitor located below DisplayPort-2. The same bug existed latently in v0.1.1 but was invisible in most setups. 4 regression tests added.
Tests & CI
- 61 unit tests (up from 24 in v0.1.0). New coverage for
parse_entry_spec(8),direction_return_config(5),entry_matcheshappy path + cursor-past-edge regressions (13),winning_entry(7), plus threshold/whitespace edge cases. CI (ruff + pytest) green on every push.
Compatibility
- 100% backward compatible. No
--entry? Same behavior as v0.1.1 — config-driven single-entry on left/right. - Multi-entry is CLI-only by design (no
[entries]config section). Use shell aliases for recurring setups:alias mf-office='mouseferry --entry 1:right --entry 2:bottom'
- Linux / X11 only (Wayland unchanged). Hotplug still requires restart.
Closes
- #1 — Multi-entry monitors with per-monitor direction
v0.1.1 — multi-monitor edge detection
What's new
- Multi-monitor support. The trigger edge is now bound to a single target monitor instead of the whole virtual desktop. Configure via
monitor = primary | auto-from-cursor | <xrandr-name> | <1-based index>inconfig.ini, or override per-run with--monitor. See README → Multi-monitor setups. - 2D edge check. The trigger only fires when the cursor is at the configured edge and inside the target monitor's vertical band — no more false positives when the cursor wanders onto a stacked monitor.
- New
--list-monitorsflag — prints connected monitors (with 1-based index, geometry, and primary marker), then exits. Useful for discovering what to put inconfig.ini. - Numeric-index selection —
--monitor 1(ormonitor = 1in config) picks a monitor by its position in the--list-monitorsoutput. Handy when you don't remember the xrandr name. - Restructured
--helpwith argument groups and inline examples covering all four spec forms. - Graceful fallback. If the configured monitor is not connected,
mouseferryprints a warning and falls back toprimary(then to the first available monitor). Keeps working when you undock.
Fixed
return_sensitivitydefault lowered from 2000 to 800. The previous default was too stiff for typical mouse DPI — the average sweep back to the PC produces a net REL_X delta around 800, so the old default required an unnaturally decisive gesture. Users with a custom value are unaffected.
Tests & CI
- 24 unit tests covering the parsers, resolver, fallback chain, and numeric-index branch.
- CI now runs pytest alongside ruff.
Compatibility
- Fully backwards-compatible configs. Configs without a
monitorkey default toprimarybehavior. - Still Linux / X11 only. Wayland support remains out of scope.
- Hotplug: the monitor layout is snapshotted at startup; restart
mouseferryif you plug or unplug a display.
v0.1.0 — Initial release
First public release of mouseferry — seamless mouse sharing between a Linux PC and an Android device via scrcpy.
Highlights
- Edge-triggered entry. Move the mouse past the configured screen edge (
leftorright) and a scrcpy session is launched on demand; the cursor is ferried to the Android device with UHID mouse injection. - Sweep-return via evdev. A decisive sweep of the physical mouse back toward the PC is detected through evdev — the only mechanism that keeps working while SDL has grabbed the pointer — and releases control cleanly.
- No phantom cursor. scrcpy is killed on return, the UHID device is removed, and the pointer is warped back to the desktop.
- Single-file Python script, configurable via
~/.config/mouseferry/config.ini, with an optional GNOME/KDE/Xfce autostart.desktoptemplate.
Requirements
Linux + X11, Python 3.8+, scrcpy ≥ 2.4, xdotool, xrandr, adb, python-evdev, user in the input group. Full details in the README.
Known limitations
- X11 only (no Wayland support).
- One Android device at a time (manual
serialfor multi-device setups).
License
PolyForm Noncommercial 1.0.0 — free for any personal, hobby, research, or educational use. Commercial use is not permitted.