https://github.com/feschber/lan-mouse Skip to content Toggle navigation Sign in * Product + Actions Automate any workflow + Packages Host and manage packages + Security Find and fix vulnerabilities + Codespaces Instant dev environments + Copilot Write better code with AI + Code review Manage code changes + Issues Plan and track work + Discussions Collaborate outside of code Explore + All features + Documentation + GitHub Skills + Blog * Solutions For + Enterprise + Teams + Startups + Education By Solution + CI/CD & Automation + DevOps + DevSecOps Resources + Learning Pathways + White papers, Ebooks, Webinars + Customer Stories + Partners * Open Source + GitHub Sponsors Fund open source developers + The ReadME Project GitHub community articles Repositories + Topics + Trending + Collections * Pricing Search or jump to... Search code, repositories, users, issues, pull requests... Search [ ] Clear Search syntax tips Provide feedback We read every piece of feedback, and take your input very seriously. [ ] [ ] Include my email address so I can be contacted Cancel Submit feedback Saved searches Use saved searches to filter your results more quickly Name [ ] Query [ ] To see all available qualifiers, see our documentation. Cancel Create saved search Sign in Sign up You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session. Dismiss alert {{ message }} feschber / lan-mouse Public * Notifications * Fork 6 * Star 217 mouse & keyboard sharing via LAN License GPL-3.0 license 217 stars 6 forks Activity Star Notifications * Code * Issues 7 * Pull requests 1 * Actions * Projects 0 * Security * Insights Additional navigation options * Code * Issues * Pull requests * Actions * Projects * Security * Insights feschber/lan-mouse This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository. main Switch branches/tags [ ] Branches Tags Could not load branches Nothing to show {{ refName }} default View all branches Could not load tags Nothing to show {{ refName }} default View all tags Name already in use A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch? Cancel Create 5 branches 12 tags Code * Local * Codespaces * Clone HTTPS GitHub CLI [https://github.com/f] Use Git or checkout with SVN using the web URL. [gh repo clone feschb] Work fast with our official CLI. Learn more about the CLI. * Open with GitHub Desktop * Download ZIP Sign In Required Please sign in to use Codespaces. Launching GitHub Desktop If nothing happens, download GitHub Desktop and try again. Launching GitHub Desktop If nothing happens, download GitHub Desktop and try again. Launching Xcode If nothing happens, download Xcode and try again. Launching Visual Studio Code Your codespace will open once ready. There was a problem preparing your codespace, please try again. Latest commit @feschber feschber Update README.md ... 1553ed4 Jan 2, 2024 Update README.md 1553ed4 Git stats * 198 commits Files Permalink Failed to load latest commit information. Type Name Latest commit message Commit time .github/workflows ci: rename lan-mouse.zip to lan-mouse-windows.zip December 27, 2023 21:58 resources downgrade libadwaita December 19, 2023 22:09 src layer-shell: recreate windows, when output is removed / added (#62) January 1, 2024 22:48 .gitignore Implement keycode translation for windows (#54) December 18, 2023 18:08 Cargo.lock chore: Release lan-mouse version 0.5.0 December 28, 2023 17:57 Cargo.toml chore: Release lan-mouse version 0.5.0 December 28, 2023 17:57 DOC.md support for cmdline args and better error handling (#4) February 18, 2023 04:03 LICENSE Create LICENSE (#17) June 13, 2023 20:02 README.md Update README.md January 2, 2024 22:46 build.rs enable gtk frontend in windows (#58) December 24, 2023 18:00 config.toml read all output globals September 21, 2023 00:12 de.feschber.LanMouse.yml Frontend improvement (#27) September 25, 2023 13:03 deny.toml Epoll (#20) September 19, 2023 19:12 lan-mouse.desktop chore: Release lan-mouse version 0.5.0 December 28, 2023 17:57 View code [ ] Lan Mouse OS Support Build and Run Install Dependencies Macos Ubuntu and derivatives Arch and derivatives Fedora and derivatives Windows Build and run Conditional Compilation Usage Gtk Frontend Command Line Interface Daemon Configuration Example config Roadmap Protocol Bandwidth considerations Packets per Second Security Wayland support Input Emulation (for receiving events) Wlroots KDE Gnome Input capture README.md Lan Mouse Lan Mouse is a mouse and keyboard sharing software similar to universal-control on Apple devices. It allows for using multiple pcs with a single set of mouse and keyboard. This is also known as a Software KVM switch. The primary target is Wayland on Linux but Windows and MacOS and Linux on Xorg have partial support as well (see below for more details). * Now with a gtk frontend Goal of this project is to be an open-source replacement for proprietary tools like Synergy 2/3, Share Mouse. Focus lies on performance and a clean, manageable implementation that can easily be expanded to support additional backends like e.g. Android, iOS, ... . blazingly fast(tm) because it's written in rust. For an alternative (with slightly different goals) you may check out Input Leap. OS Support The following table shows support for input emulation (to emulate events received from other clients) and input capture (to send events to other clients) on different operating systems: Backend input emulation input capture Wayland (wlroots) [?] [?] Wayland (KDE) [?] [?] Wayland (Gnome) [?] WIP X11 [?] WIP Windows [?] WIP MacOS ( [?] ) WIP Keycode translation is not yet implemented so on MacOS only mouse emulation works as of right now. Build and Run Install Dependencies Macos brew install libadwaita Ubuntu and derivatives sudo apt install libadwaita-1-dev libgtk-4-dev libx11-dev libxtst-dev Arch and derivatives sudo pacman -S libadwaita gtk libx11 libxtst Fedora and derivatives sudo dnf install libadwaita-devel libXtst-devel libX11-devel Windows 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 chocolatey Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1')) # install python 3.11 (Version is important, as 3.12 does not work currently) choco install python --version=3.11.0 # install git choco install git # install msys2 choco install msys2 # install Visual Studio 2022 choco install visualstudio2022-workload-vctools * The following commands should be run in a regular power shell instance: # install gvsbuild with python python -m pip install --user pipx python -m pipx ensurepath pipx install gvsbuild # build gtk + libadwaita gvsbuild build gtk4 libadwaita librsvg Make sure to add the directory C:\gtk-build\gtk\x64\release\bin to the PATH environment variable. Otherwise the project will fail to build. To avoid building GTK from source, it is possible to disable the gtk frontend (see conditional compilation below). Build and run Build in release mode: cargo build --release Run directly: cargo run --release Conditional Compilation Currently only x11, wayland, windows and MacOS are supported backends. Depending on the toolchain used, support for other platforms is omitted automatically (it does not make sense to build a Windows .exe with support for x11 and wayland backends). However one might still want to omit support for e.g. wayland, x11 or libei on a Linux system. This is possible through cargo features. E.g. if only wayland support is needed, the following command produces an executable with just support for wayland: cargo build --no-default-features --features wayland For a detailed list of available features, checkout the Cargo.toml Usage Gtk Frontend By default the gtk frontend will open when running lan-mouse. To add a new connection, simply click the Add button on both devices, enter the corresponding hostname and activate it. If the mouse can not be moved onto a device, make sure you have port 4242 (or the one selected) opened up in your firewall. Command Line Interface The cli interface can be enabled using --frontend cli as commandline arguments. Type help to list the available commands. E.g.: $ cargo run --release -- --frontend cli (...) > connect left|right|top|bottom (...) > list (...) > activate 0 Daemon Lan Mouse can be launched in daemon mode to keep it running in the background. To do so, add --daemon to the commandline args: $ cargo run --release -- --daemon 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 # example configuration # optional port (defaults to 4242) port = 4242 # # optional frontend -> defaults to gtk if available # # possible values are "cli" and "gtk" # frontend = "gtk" # define a client on the right side with host name "iridium" [right] # hostname host_name = "iridium" # optional list of (known) ip addresses ips = ["192.168.178.156"] # define a client on the left side with IP address 192.168.178.189 [left] # The hostname is optional: When no hostname is specified, # at least one ip address needs to be specified. host_name = "thorium" # ips for ethernet and wifi ips = ["192.168.178.189", "192.168.178.172"] # optional port port = 4242 Where left can be either left, right, top or bottom. 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 * [ ] Libei Input Capture * [ ] X11 Input Capture * [ ] Windows Input Capture * [ ] MacOS Input Capture * [ ] MaxOS KeyCode Translation * [ ] Latency measurement and visualization * [ ] Bandwidth usage measurement and visualization * [ ] Clipboard support * [ ] Encryption Protocol Currently all mouse and keyboard events are sent via UDP for performance reasons. Each event is sent as one single datagram, currently without any acknowledgement to guarantee 0% packet loss. This means, any packet that is lost results in a discarded mouse / key event, which is ignored for now. UDP also has the additional benefit that no reconnection logic is required. Any client can just go offline and it will simply start working again as soon as it comes back online. Additionally a tcp server is hosted for data that needs to be sent reliably (e.g. the keymap from the server or clipboard contents in the future) can be requested via a tcp connection. Bandwidth considerations The most bandwidth is taken up by mouse events. A typical office mouse has a polling rate of 125Hz while gaming mice typically have a much higher polling rate of 1000Hz. A mouse Event consists of 21 Bytes: * 1 Byte for the event type enum, * 4 Bytes (u32) for the timestamp, * 8 Bytes (f64) for dx, * 8 Bytes (f64) for dy. Additionally the IP header with 20 Bytes and the udp header with 8 Bytes take up another 28 Byte. So in total there is 49 * 1000 Bytes/s for a 1000Hz gaming mouse. This makes for a bandwidth requirement of 392 kbit/s in total even for a high end gaming mouse. So bandwidth is a non-issue. Larger data chunks, like the keymap are offered by the server via tcp listening on the same port. This way we dont need to implement any congestion control and leave this up to tcp. In the future this can be used for e.g. clipboard contents as well. Packets per Second While on LAN the performance is great, some WIFI cards seem to struggle with the amount of packets per second, particularly on high-end gaming mice with 1000Hz+ polling rates. The plan is to implement a way of accumulating packets and sending them as one single key event to reduce the packet rate (basically reducing the polling rate artificially). The way movement data is currently sent is also quite wasteful since even a 16bit integer is likely enough to represent even the fastest possible mouse movement. A different encoding that is more efficient for smaller values like Protocol Buffers would be a better choice for the future and could also help for WIFI connections. Security Sending key and mouse event data over the local network might not be the biggest security concern but in any public network or business environment it's QUITE a problem to basically broadcast your keystrokes. * There should be an encryption layer below the application to enable a secure link. * The encryption keys could be generated by the graphical frontend. Wayland support Input Emulation (for receiving events) On wayland input-emulation is in an early/unstable state as of writing this. For this reason a suitable backend is chosen based on the active desktop environment / compositor. Different compositors have different ways of enabling input emulation: Wlroots Most wlroots-based compositors like Hyprland and Sway support the following unstable wayland protocols for keyboard and mouse emulation: * virtual-keyboard-unstable-v1 * wlr-virtual-pointer-unstable-v1 KDE KDE also has a protocol for input emulation (kde-fake-input), it is however not exposed to third party applications. The recommended way to emulate input on KDE is the freedesktop remote-desktop-portal. Gnome Gnome uses libei for input emulation and capture, which has the goal to become the general approach for emulating and capturing Input on Wayland. Input capture To capture mouse and keyboard input, a few things are necessary: * Displaying an immovable surface at screen edges * Locking the mouse in place * (optionally but highly recommended) reading unaccelerated mouse input Required Protocols (Event Emitting) Sway Kwin Gnome pointer-constraints-unstable-v1 [?] [?] [?] relative-pointer-unstable-v1 [?] [?] [?] keyboard-shortcuts-inhibit-unstable-v1 [?] [?] [?] wlr-layer-shell-unstable-v1 [?] [?] The zwlr_virtual_pointer_manager_v1 is required to display surfaces on screen edges and used to display the immovable window on both wlroots based compositors and KDE. Gnome unfortunately does not support this protocol and likely won't ever support it. [DEL:In order for layershell surfaces to be able to lock the pointer using the pointer_constraints protocol this patch needs to be applied to sway.:DEL] (this works natively on sway versions >= 1.8) About mouse & keyboard sharing via LAN Topics windows macos linux rust open-source tcp gplv3 lan udp wayland keyboard-emulation mouse-emulation wayland-client wlroots kvm-switch libadwaita gtk4-rs hyprland Resources Readme License GPL-3.0 license Activity Stars 217 stars Watchers 8 watching Forks 6 forks Report repository Releases 11 v0.5.0 Latest Dec 28, 2023 + 10 releases Packages 0 No packages published Contributors 2 * * Languages * Rust 99.9% * CSS 0.1% Footer (c) 2024 GitHub, Inc. Footer navigation * Terms * Privacy * Security * Status * Docs * Contact * Manage cookies * Do not share my personal information You can't perform that action at this time.