Two computers, one keyboard, zero mouse-dragging.
On Wayland, input-leap can't switch screens from the keyboard. ilhop can, in ~25 ms, and lands you in the right window.
Requirements · Install · Use · Known limits
One key moves your pointer and keyboard between a Linux machine and a Mac shared with input-leap, in both directions. On Wayland, input-leap's own keyboard screen-switching does not work at all; ilhop replaces it with a hop that takes ~25ms.
- ALT+C on either machine hops to the other one.
- The pointer lands in the middle of the window nearest the edge it crossed, and that window gets keyboard focus, so you can type straight away.
This is the one tested combination. Anything else is untested and probably will not work without changes.
| Linux (input-leap server) | Mac (input-leap client) | |
|---|---|---|
| Window manager | Hyprland with Lua dispatch (hl.dsp.*, the Ryoku fork) |
AeroSpace |
| input-leap | input-leaps --use-ei as a systemd user service named input-leap-server, at --debug INFO |
input-leapc connected to it |
| Tools | ydotool, jq, ssh, flock, a C compiler, systemd |
nc, osascript (both ship with macOS) |
The Mac may sit on either side of the Linux screen. ilhop never stores the
side: it reads it on every hop from the links in input-leap's server.conf,
which input-leap needs to match your desk for the mouse anyway. They must
link the two screens both ways, mirrored. Mac on the left:
section: links
<linux-screen>:
left = <mac-screen>
<mac-screen>:
right = <linux-screen>
end
Mac on the right:
section: links
<linux-screen>:
right = <mac-screen>
<mac-screen>:
left = <linux-screen>
end
Want the mouse to cross at both side edges (wrap-around)? Link both ways under each screen. List the side the Mac really sits on first: ALT+C walks that way, and the Mac's landing pick uses it.
section: links
<linux-screen>:
right = <mac-screen>
left = <mac-screen>
<mac-screen>:
left = <linux-screen>
right = <linux-screen>
end
ilhop side refuses to rewrite a wrap-around conf; swap the line order by
hand to change the real side.
After moving the Mac to the other side, run ilhop side left or
ilhop side right on Linux. It rewrites just those two lines (keeping
server.conf.bak), restarts input-leap, and redials the Mac's session so
the Mac relearns the side within seconds. ilhop side alone prints the
side ilhop is using.
Keep input-leap-server at --debug INFO: ilhop follows its journal to know
which machine has the pointer, and DEBUG floods it.
The two machines talk over ssh with keys, never passwords:
- Linux → Mac under an alias (default
mac). Turn on Remote Login on the Mac. - Mac → Linux under an alias (default
ryuk). The Mac holds this session open so a hop from the Mac costs ~10ms instead of a fresh ssh.
Check both work without a prompt: ssh -o BatchMode=yes mac true on Linux,
ssh -o BatchMode=yes ryuk true on the Mac.
Your Linux user must be able to write /dev/uinput, which usually means
being in the input group. ilhop doctor says exactly what is wrong if not.
Clone this repo on both machines and run the installer on each:
git clone <this repo> ilhop && cd ilhop
ILHOP_MAC_HOST=mac ./install.sh # on Linux: the alias that reaches the Mac
ILHOP_LINUX_HOST=ryuk ./install.sh # on the Mac: the alias that reaches LinuxThe installer:
- Linux: copies the commands to
~/.local/bin, buildsil-heldmods, installs and startsil-side-watch.service(andydotoold.serviceif you do not already have one), and binds ALT+C in~/.config/hypr/user.luaunless ALT+C is already bound. It also gives ydotoold's virtual pointer a flat acceleration profile there (hl.device({ ..., accel_profile = "flat" })): the hop moves the pointer by exact distances and libinput's default acceleration would scale them by up to 2x. Only that virtual device changes; your own mouse keeps its feel. - Mac: copies three scripts to
~/.local/bin, loads theilhop.hop-pipelaunchd agent, and addsalt-candon-focus-changedtoaerospace.toml(it leaves either alone if you already set it, and tells you what to add). - Both: writes the settings to
~/.config/ilhop/config. Edit it later if an alias or the screen name changes.
./install.sh --link symlinks instead of copying, for working on ilhop itself.
Upgrading, either machine can go first: an old Mac with a new Linux, or a
new Mac with an old Linux, still hops both ways on ALT+C. One exception
while they differ: with the Mac on the right, an old Mac whose fast session
is down falls back to il-jump right, which a new Linux reads as "toward
the Mac", so that press does nothing. Upgrade the Mac soon after Linux.
| Command | What it does |
|---|---|
ilhop / ilhop toggle |
Hop to the other machine (what ALT+C runs on Linux) |
ilhop mac / ilhop linux |
Hop to the Mac / back to Linux |
ilhop left / ilhop right |
Hop that way, to whichever machine sits there |
ilhop side [left|right] |
Print which side the Mac is on, or move it there in server.conf |
ilhop doctor |
Check every moving part, with the fix for each failure |
ilhop doctor --test |
Also do a real round trip and time it |
ilhop reset |
Panic button: release every modifier, restart the input services, bring the pointer home |
ilhop help |
List every command |
If your keyboard is stuck, run ilhop reset over ssh from the Mac:
ssh ryuk ilhop reset. It releases every modifier whether or not it thinks
one is held, and it waits for any hop in flight rather than interleaving
with it.
The old il-* command names still work.
On each machine, from the clone:
./install.sh --uninstallIt removes every file, unit, launchd agent and config line the installer
added, then checks for leftovers and prints no trace left or lists what
remains. Lines you wrote yourself are never touched: the installer marks its
own with an ilhop comment.
- A modifier held across a hop needs a patched input-leap. Stock
input-leap drops it: hold ALT through the hop, press
1on the Mac, and nothing happens until you release and re-press ALT.upstream/input-leap/has the fix as an Arch package (cd upstream/input-leap && makepkg -si --nocheck, thensystemctl --user restart input-leap-server). The next stock input-leap update replaces it;ilhop doctorwarns when that happens. - The Mac landing aims only horizontally. Moving the pointer vertically would sweep through the Mac's hot corners. With two windows stacked on the side of the Mac facing Linux, the pointer may land in the one that does not have focus.
- The landing spot is worked out when you last left a machine. If a window moves or closes while you are on the other side, the next hop can land on empty space. On the Mac, AeroSpace refreshes it on every focus change.
- Right after sleep or a network change, the Mac's fast connection takes a second or two to come back. ALT+C on the Mac still works in that window; it just goes over a slower fresh ssh.
- After
ilhop side, the Mac's landing pick catches up on the redial. The hop direction follows the change on the very next press; the Mac learns which of its edges faces Linux only once its session reconnects (seconds). - The Mac landing is a little less reliable than the hop itself. The first motion after the crossing is dropped by input-leap, so the hop sends throwaways first. If the landing move is still dropped, the pointer sits at the Mac's edge for ~0.3s until a background check moves it. Keyboard focus is right either way.
- Macs wider than 2400 logical pixels need a fourth step on the way back
(
burstinil-jump). - One monitor per machine, side by side (left or right, not above or below).
If ilhop saved your wrist a few thousand mouse drags, a ⭐ on GitHub helps other Wayland + Mac users find it.
Bugs and ideas: open an issue.