Skip to content

Releases: mattabott/mouseferry

v0.2.0 — multi-entry mode

24 Apr 11:14

Choose a tag to compare

What's new

  • Multi-entry mode. Pass --entry MONITOR:DIRECTION repeatably on the CLI to ferry to a single Android device from multiple monitor edges at once. Example: mouseferry --entry 1:right --entry 2:bottom triggers the ferry both from the right edge of monitor 1 and from the bottom edge of monitor 2.
  • All four directions. top and bottom join left and right as 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/left direction; sweep up/down → warp to an entry with top/bottom. No need to remember which entry triggered the ferry — the sweep itself picks where to come back. A new pure helper winning_entry() evaluates all configured entries against the current sweep accumulator.
  • --return MONITOR override. 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/--monitor alongside --entry prints a warning (not an error) and proceeds in multi-entry mode. Safe for incremental migration.
  • Pre-flight validation. Malformed --entry values 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_matches bounding-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:bottom could 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_matches happy 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

24 Apr 08:16

Choose a tag to compare

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> in config.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-monitors flag — prints connected monitors (with 1-based index, geometry, and primary marker), then exits. Useful for discovering what to put in config.ini.
  • Numeric-index selection--monitor 1 (or monitor = 1 in config) picks a monitor by its position in the --list-monitors output. Handy when you don't remember the xrandr name.
  • Restructured --help with argument groups and inline examples covering all four spec forms.
  • Graceful fallback. If the configured monitor is not connected, mouseferry prints a warning and falls back to primary (then to the first available monitor). Keeps working when you undock.

Fixed

  • return_sensitivity default 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 monitor key default to primary behavior.
  • Still Linux / X11 only. Wayland support remains out of scope.
  • Hotplug: the monitor layout is snapshotted at startup; restart mouseferry if you plug or unplug a display.

v0.1.0 — Initial release

23 Apr 19:44

Choose a tag to compare

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 (left or right) 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 .desktop template.

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 serial for multi-device setups).

License

PolyForm Noncommercial 1.0.0 — free for any personal, hobby, research, or educational use. Commercial use is not permitted.