feschber/lan-mouse
{ "createdAt": "2022-09-15T00:15:20Z", "defaultBranch": "main", "description": "mouse & keyboard sharing via LAN", "fullName": "feschber/lan-mouse", "homepage": "", "language": "Rust", "name": "lan-mouse", "pushedAt": "2025-11-03T17:39:58Z", "stargazersCount": 4112, "topics": [ "gplv3", "gtk4-rs", "hyprland", "keyboard-emulation", "kvm-switch", "lan", "libadwaita", "linux", "macos", "mouse-emulation", "open-source", "rust", "tcp", "udp", "wayland", "wayland-client", "windows", "wlroots" ], "updatedAt": "2025-11-25T18:17:26Z", "url": "https://github.com/feschber/lan-mouse"}Lan Mouse
Section titled “Lan Mouse”Lan Mouse is a cross-platform mouse and keyboard sharing software similar to universal-control on Apple devices. It allows for using multiple PCs via a single set of mouse and keyboard. This is also known as a Software KVM switch.
Goal of this project is to be an open-source alternative to proprietary tools like Synergy 2/3, Share Mouse and other open source tools like Deskflow or Input Leap (Synergy fork).
Focus lies on performance, ease of use and a maintainable implementation that can be expanded to support additional backends for e.g. Android, iOS, … in the future.
blazingly fast™ because it’s written in rust.
- Now with a gtk frontend
Encryption
Section titled “Encryption”Lan Mouse encrypts all network traffic using the DTLS implementation provided by WebRTC.rs. There are currently no mitigations in place for timing side-channel attacks.
OS Support
Section titled “OS Support”Most current desktop environments and operating systems are fully supported, this includes
- GNOME >= 45
- KDE Plasma >= 6.1
- Most wlroots based compositors, including Sway (>= 1.8), Hyprland and Wayfire
- Windows
- MacOS
Caveats / Known Issues
Section titled “Caveats / Known Issues”[!Important]
X11 currently only has support for input emulation, i.e. can only be used on the receiving end.
Sway / wlroots: Wlroots based compositors without libei support on the receiving end currently do not handle modifier events on the client side. This results in CTRL / SHIFT / ALT / SUPER keys not working with a sending device that is NOT using the
layer-shellbackendWayfire: If you are using Wayfire, make sure to use a recent version (must be newer than October 23rd) and add
shortcuts-inhibitto the list of plugins in your wayfire config! Otherwise input capture will not work.Windows: The mouse cursor will be invisible when sending input to a Windows system if there is no real mouse connected to the machine.
For more detailed information about os support see [Detailed OS Support]!(#detailed-os-support)
Android & IOS
Section titled “Android & IOS”A proof of concept for an Android / IOS Application by rohitsangwan01 can be found here. It can be used as a remote control for any device supported by Lan Mouse.
Installation
Section titled “Installation”Arch Linux
Lan Mouse can be installed from the official repositories:
pacman -S lan-mouseThe prerelease version (following main) is available on the AUR:
paru -S lan-mouse-gitNix (OS)
- nixpkgs: search.nixos.org
- flake: [README.md]!(./nix/README.md)
Fedora
You can install Lan Mouse from the [Terra Repository](https://terra.fyralabs.com).After enabling Terra:
dnf install lan-mouseMacOS
- Download the package for your Mac (Intel or ARM) from the releases page
- Unzip it
- Remove the quarantine with
xattr -rd com.apple.quarantine "Lan Mouse.app" - Launch the app
- Grant accessibility permissions in System Preferences
Manual Installation
First make sure to [install the necessary dependencies]!(#installing-dependencies-for-development—compiling-from-source).
Precompiled release binaries for Windows, MacOS and Linux are available in the releases section. For Windows, the depenedencies are included in the .zip file, for other operating systems see [Installing Dependencies]!(#installing-dependencies-for-development—compiling-from-source).
Alternatively, the lan-mouse binary can be compiled from source (see below).
Installing desktop file, app icon and firewall rules (optional)
Section titled “Installing desktop file, app icon and firewall rules (optional)”# install lan-mouse (replace path/to/ with the correct path)sudo cp path/to/lan-mouse /usr/local/bin/
# install app iconsudo mkdir -p /usr/local/share/icons/hicolor/scalable/appssudo cp lan-mouse-gtk/resources/de.feschber.LanMouse.svg /usr/local/share/icons/hicolor/scalable/apps
# update icon cachegtk-update-icon-cache /usr/local/share/icons/hicolor/
# install desktop entrysudo mkdir -p /usr/local/share/applicationssudo cp de.feschber.LanMouse.desktop /usr/local/share/applications
# when using firewalld: install firewall rulesudo cp firewall/lan-mouse.xml /etc/firewalld/services# -> enable the service in firewalld settingsInstead of downloading from the releases, the lan-mouse binary
can be easily compiled via cargo or nix:
Compiling and installing manually:
Section titled “Compiling and installing manually:”# compile in release modecargo build --release
# install lan-mousesudo cp target/release/lan-mouse /usr/local/bin/Compiling and installing via cargo:
Section titled “Compiling and installing via cargo:”# will end up in ~/.cargo/bincargo install lan-mouseCompiling and installing via nix:
Section titled “Compiling and installing via nix:”# you can find the executable in result/bin/lan-mousenix-buildConditional compilation
Section titled “Conditional compilation”Support for other platforms is omitted automatically based on the active rust toolchain.
Additionally, available backends and frontends can be configured manually via cargo features.
E.g. if only support for sway is needed, the following command produces
an executable with support for only the layer-shell capture backend
and wlroots emulation backend:
cargo build --no-default-features --features layer_shell_capture,wlroots_emulationFor a detailed list of available features, checkout the [Cargo.toml]!(./Cargo.toml)
Installing Dependencies for Development / Compiling from Source
Section titled “Installing Dependencies for Development / Compiling from Source”MacOS
# Install dependenciesbrew install libadwaita pkg-config imagemagickcargo install cargo-bundle# Create the macOS icon filescripts/makeicns.sh# Create the .app bundlecargo bundle# Copy all dynamic libraries into the bundle, and update the bundle to find them therescripts/copy-macos-dylib.shUbuntu and derivatives
sudo apt install libadwaita-1-dev libgtk-4-dev libx11-dev libxtst-devArch and derivatives
sudo pacman -S libadwaita gtk libx11 libxtstFedora and derivatives
sudo dnf install libadwaita-devel libXtst-devel libX11-develNix
nix-shell .Nix (flake)
nix developWindows
-
First install Rust.
-
Then follow the instructions at gtk-rs.org
TLDR:
Build gtk from source
- The following commands should be run in an admin power shell instance:
# install chocolateySet-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
# install gvsbuild dependencieschoco install python git msys2 visualstudio2022-workload-vctools- The following commands should be run in a regular power shell instance:
# install gvsbuild with pythonpython -m pip install --user pipxpython -m pipx ensurepath- Relaunch your powershell instance so the changes in the environment are reflected.
pipx install gvsbuild
# build gtk + libadwaitagvsbuild build gtk4 libadwaita librsvg adwaita-icon-theme- Make sure to add the directory
C:\gtk-build\gtk\x64\release\bin[to thePATHenvironment variable]!((https://learn.microsoft.com/en-us/previous-versions/office/developer/sharepoint-2010/ee537574(v=office.14))). Otherwise the project will fail to build.
To avoid building GTK from source, it is possible to disable the gtk frontend (see conditional compilation).
Gtk Frontend
By default the gtk frontend will open when running lan-mouse.
To connect a device you want to control, simply click the Add button and enter the hostname
of the device.
On the remote device, authorize your local device for incoming traffic using the Authorize button
under the “Incoming Connections” section.
The fingerprint for authorization can be found under the general section of your local device.
It is of the form “aa:bb:cc:…”
Authorized devices can be persisted using the configuration file (see [Configuration]!(#configuration)).
If the device still can not be entered, make sure you have UDP port 4242 (or the one selected) opened up in your firewall.
Command Line Interface
The cli interface can be accessed by passing cli as a commandline argument.
Use
lan-mouse cli helpto list the available commands and
lan-mouse cli <cmd> helpfor information on how to use a specific command.
Daemon Mode
Lan Mouse can be launched in daemon mode to keep it running in the background (e.g. for use in a systemd-service).
To do so, use the daemon subcommand:
lan-mouse daemonIn order to start lan-mouse with a graphical session automatically, the [systemd-service]!(service/lan-mouse.service) can be used:
Copy the file to ~/.config/systemd/user/ and enable the service:
cp service/lan-mouse.service ~/.config/systemd/usersystemctl --user daemon-reloadsystemctl --user enable --now lan-mouse.serviceConfiguration
Section titled “Configuration”To automatically load clients on startup, the file $XDG_CONFIG_HOME/lan-mouse/config.toml is parsed.
$XDG_CONFIG_HOME defaults to ~/.config/.
To create this file you can copy the following example config:
Example config
Section titled “Example config”[!TIP] key symbols in the release bind are named according to their names in [input-event/src/scancode.rs#L172]!(input-event/src/scancode.rs#L176). This is bound to change
# example configuration
# configure release bindrelease_bind = [ "KeyA", "KeyS", "KeyD", "KeyF" ]
# optional port (defaults to 4242)port = 4242
# list of authorized tls certificate fingerprints that# are accepted for incoming traffic[authorized_fingerprints]"bc:05:ab:7a:a4:de:88:8c:2f:92:ac:bc:b8:49:b8:24:0d:44:b3:e6:a4:ef:d7:0b:6c:69:6d:77:53:0b:14:80" = "iridium"
# define a client on the right side with host name "iridium"[[clients]]# position (left | right | top | bottom)position = "right"# hostnamehostname = "iridium"# activate this client immediately when lan-mouse is startedactivate_on_startup = true# optional list of (known) ip addressesips = ["192.168.178.156"]
# define a client on the left side with IP address 192.168.178.189[[clients]]position = "left"# The hostname is optional: When no hostname is specified,# at least one ip address needs to be specified.hostname = "thorium"# ips for ethernet and wifiips = ["192.168.178.189", "192.168.178.172"]# optional portport = 4242Where left can be either left, right, top or bottom.
Roadmap
Section titled “Roadmap”- Graphical frontend (gtk + libadwaita)
- respect xdg-config-home for config file location.
- IP Address switching
- Liveness tracking Automatically ungrab mouse when client unreachable
- Liveness tracking: Automatically release keys, when server offline
- MacOS KeyCode Translation
- Libei Input Capture
- MacOS Input Capture
- Windows Input Capture
- Encryption
- X11 Input Capture
- Latency measurement and visualization
- Bandwidth usage measurement and visualization
- Clipboard support
Detailed OS Support
Section titled “Detailed OS Support”In order to use a device for sending events, an input-capture backend is required, while receiving events requires a supported input-emulation and input-capture backend.
A suitable backend is chosen automatically based on the active desktop environment / compositor.
The following sections detail the emulation and capture backends provided by lan-mouse and their support in desktop environments / operating systems.
Input Emulation Support
Section titled “Input Emulation Support”| Desktop / Backend | wlroots | libei | remote-desktop portal | windows | macos | x11 |
|---|---|---|---|---|---|---|
| Wayland (wlroots) | :heavy_check_mark: | |||||
| Wayland (KDE) | :heavy_check_mark: | :heavy_check_mark: | ||||
| Wayland (Gnome) | :heavy_check_mark: | :heavy_check_mark: | ||||
| Windows | :heavy_check_mark: | |||||
| MacOS | :heavy_check_mark: | |||||
| X11 | :heavy_check_mark: |
wlroots: This backend makes use of the wlr-virtual-pointer-unstable-v1 and virtual-keyboard-unstable-v1 protocols and is supported by most wlroots based compositors.libei: This backend uses libei and is supported by GNOME >= 45 or KDE Plasma >= 6.1.xdp: This backend uses the freedesktop remote-desktop-portal and is supported on GNOME and Plasma.x11: Backend for X11 sessions.windows: Backend for Windows.macos: Backend for MacOS.
Input Capture Support
Section titled “Input Capture Support”| Desktop / Backend | layer-shell | libei | windows | macos | x11 |
|---|---|---|---|---|---|
| Wayland (wlroots) | :heavy_check_mark: | ||||
| Wayland (KDE) | :heavy_check_mark: | :heavy_check_mark: | |||
| Wayland (Gnome) | :heavy_check_mark: | ||||
| Windows | :heavy_check_mark: | ||||
| MacOS | :heavy_check_mark: | ||||
| X11 | WIP |
layer-shell: This backend creates a single pixel wide window on the edges of Displays to capture the cursor using the layer-shell protocol.libei: This backend uses libei and is supported by GNOME >= 45 or KDE Plasma >= 6.1.windows: Backend for input capture on Windows.macos: Backend for input capture on MacOS.x11: TODO (not yet supported)