From fef702ffdd88d6f2c7edcce46cf834e564f991ee Mon Sep 17 00:00:00 2001 From: Ferdinand Schober Date: Thu, 7 Nov 2024 02:35:32 +0100 Subject: [PATCH] Update README.md (#229) --- README.md | 323 +++++++++++++++++++++++++----------------------------- 1 file changed, 147 insertions(+), 176 deletions(-) diff --git a/README.md b/README.md index a2b1866..87796e0 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,14 @@ # 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. +Lan Mouse is a *cross-platform* mouse and keyboard sharing software similar to universal-control on Apple devices. +It allows for using multiple PCs using 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). +Goal of this project is to be an open-source alternative to proprietary tools like [Synergy 2/3](https://symless.com/synergy), [Share Mouse](https://www.sharemouse.com/de/) +and an alternative to other open source tools like [Deskflow](https://github.com/deskflow/deskflow) or [Input Leap](https://github.com/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_ @@ -14,65 +19,47 @@ The primary target is Wayland on Linux but Windows and MacOS and Linux on Xorg h -Goal of this project is to be an open-source replacement for proprietary tools like [Synergy 2/3](https://symless.com/synergy), [Share Mouse](https://www.sharemouse.com/de/). - -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â„¢*** because it's written in rust. - -For an alternative (with slightly different goals) you may check out [Deskflow](https://github.com/deskflow/deskflow) or [Input Leap](https://github.com/input-leap) (Synergy fork). - - > [!WARNING] -> Since this tool has gained a bit of popularity over the past couple of days: -> -> All network traffic is currently **unencrypted** and sent in **plaintext**. +> DISCLAIMER: +> Until [#200](https://github.com/feschber/lan-mouse/pulls/200) is merged, all network traffic is **unencrypted** and sent in **plaintext**! > > A malicious actor with access to the network could read input data or send input events with spoofed IPs to take control over a device. > -> Therefore you should only use this tool in your local network with trusted devices for now -> and I take no responsibility for any leakage of data! +> Therefore you should only use this tool in your local network with trusted devices. +> I take no responsibility for any security breaches! ## 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: +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 -| OS / Desktop Environment | input emulation | input capture | -|---------------------------|--------------------------|--------------------------------------| -| Wayland (wlroots) | :heavy_check_mark: | :heavy_check_mark: | -| Wayland (KDE) | :heavy_check_mark: | :heavy_check_mark: | -| Wayland (Gnome) | :heavy_check_mark: | :heavy_check_mark: (starting at GNOME 45) | -| Windows | :heavy_check_mark: | :heavy_check_mark: | -| X11 | :heavy_check_mark: | WIP | -| MacOS | :heavy_check_mark: | WIP | + +### Caveats / Known Issues > [!Important] -> Gnome -> Sway only partially works (modifier events are not handled correctly) - -> [!Important] -> **Wayfire** +> - **X11** currently only has support for input emulation, i.e. can only be used on the receiving end. > -> If you are using [Wayfire](https://github.com/WayfireWM/wayfire), make sure to use a recent version (must be newer than October 23rd) and **add `shortcuts-inhibit` to the list of plugins in your wayfire config!** +> - **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-shell` backend +> +> - **Wayfire**: If you are using [Wayfire](https://github.com/WayfireWM/wayfire), make sure to use a recent version (must be newer than October 23rd) and **add `shortcuts-inhibit` to the list of plugins in your wayfire config!** > Otherwise input capture will not work. - -> [!Important] -> The mouse cursor will be invisible when sending input to a Windows system if +> +> - **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) + + ## Installation -### Install via cargo -```sh -cargo install lan-mouse -``` -### Download from Releases -Precompiled release binaries for Windows, MacOS and Linux are available in the [releases section](https://github.com/feschber/lan-mouse/releases). - -For Windows, the depenedencies are included in the .zip file, for other operating systems see [Installing Dependencies](#installing-dependencies). - -### Arch Linux +
+ Arch Linux Lan Mouse can be installed from the [official repositories](https://archlinux.org/packages/extra/x86_64/lan-mouse/): @@ -80,46 +67,37 @@ Lan Mouse can be installed from the [official repositories](https://archlinux.or pacman -S lan-mouse ``` -It is also available on the AUR: +The prerelease version (following `main`) is available on the AUR: ```sh -# git version (includes latest changes) paru -S lan-mouse-git - -# alternatively -paru -S lan-mouse-bin ``` +
+ + +
+ Nix (OS) -### Nix - nixpkgs: [search.nixos.org](https://search.nixos.org/packages?channel=unstable&show=lan-mouse&from=0&size=50&sort=relevance&type=packages&query=lan-mouse) - flake: [README.md](./nix/README.md) +
-### Building from source with Nix -In the root of the project to build Lan Mouse, run -```sh -nix-build -``` -You can find the executable in `result/bin/lan-mouse` . -### Manual Installation +
+ Manual Installation First make sure to [install the necessary dependencies](#installing-dependencies). -Build in release mode: -```sh -cargo build --release -``` +Precompiled release binaries for Windows, MacOS and Linux are available in the [releases section](https://github.com/feschber/lan-mouse/releases). +For Windows, the depenedencies are included in the .zip file, for other operating systems see [Installing Dependencies](#installing-dependencies). -Run directly: -```sh -cargo run --release -``` +Alternatively, the `lan-mouse` binary can be compiled from source (see below). -Install the files: +### Installing desktop file, app icon and firewall rules (optional) ```sh -# install lan-mouse -sudo cp target/release/lan-mouse /usr/local/bin/ +# install lan-mouse (replace path/to/ with the correct path) +sudo cp path/to/lan-mouse /usr/local/bin/ # install app icon sudo mkdir -p /usr/local/share/icons/hicolor/scalable/apps @@ -137,17 +115,34 @@ sudo cp firewall/lan-mouse.xml /etc/firewalld/services # -> enable the service in firewalld settings ``` -### Conditional Compilation +Instead of downloading from the releases, the `lan-mouse` binary +can be easily compiled via cargo or nix: -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). +### Compiling and installing manually: +```sh +# compile in release mode +cargo build --release -However one might still want to omit support for e.g. wayland, x11 or libei on -a Linux system. +# install lan-mouse +sudo cp target/release/lan-mouse /usr/local/bin/ +``` -This is possible through +### Compiling and installing via cargo: +```sh +# will end up in ~/.cargo/bin +cargo install lan-mouse +``` + +### Compiling and installing via nix: +```sh +# you can find the executable in result/bin/lan-mouse +nix-build +``` +### 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](https://doc.rust-lang.org/cargo/reference/features.html). E.g. if only wayland support is needed, the following command produces @@ -156,14 +151,17 @@ 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](./Cargo.toml) +
-## Installing Dependencies + + +## Installing Dependencies for Development / Compiling from Source
MacOS ```sh -brew install libadwaita +brew install libadwaita pkg-config ```
@@ -191,10 +189,22 @@ sudo dnf install libadwaita-devel libXtst-devel libX11-devel ```
- Windows + Nix + +```sh +nix-shell . +``` +
+
+ Nix (flake) + +```sh +nix develop +``` +
-> [!NOTE] -> This is only necessary when building lan-mouse from source. The windows release comes with precompiled gtk dlls. +
+ Windows - First install [Rust](https://www.rust-lang.org/tools/install). @@ -226,18 +236,20 @@ python -m pipx ensurepath pipx install gvsbuild # build gtk + libadwaita -gvsbuild build gtk4 libadwaita librsvg +gvsbuild build gtk4 libadwaita librsvg adwaita-icon-theme ``` - **Make sure to add the directory** `C:\gtk-build\gtk\x64\release\bin` [**to the `PATH` environment 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 below). +the gtk frontend (see conditional compilation).
## Usage -### Gtk Frontend +
+ 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, @@ -245,8 +257,11 @@ 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 -### Command Line Interface The cli interface can be enabled using `--frontend cli` as commandline arguments. Type `help` to list the available commands. @@ -260,13 +275,17 @@ $ cargo run --release -- --frontend cli (...) > activate 0 ``` +
+ +
+ 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). -### 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: ```sh -$ cargo run --release -- --daemon +lan-mouse --daemon ``` In order to start lan-mouse with a graphical session automatically, @@ -279,6 +298,7 @@ cp service/lan-mouse.service ~/.config/systemd/user systemctl --user daemon-reload systemctl --user enable --now lan-mouse.service ``` +
## Configuration To automatically load clients on startup, the file `$XDG_CONFIG_HOME/lan-mouse/config.toml` is parsed. @@ -334,109 +354,60 @@ Where `left` can be either `left`, `right`, `top` or `bottom`. - [x] Liveness tracking: Automatically release keys, when server offline - [x] MacOS KeyCode Translation - [x] Libei Input Capture +- [x] MacOS Input Capture +- [x] Windows Input Capture +- [ ] *Encryption* (WIP) - [ ] X11 Input Capture -- [ ] Windows Input Capture -- [ ] MacOS Input Capture - [ ] 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](https://protobuf.dev/programming-guides/encoding/) -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. +## Detailed OS Support -For this reason a suitable backend is chosen based on the active desktop environment / compositor. +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. -Different compositors have different ways of enabling input emulation: +A suitable backend is chosen automatically based on the active desktop environment / compositor. -#### Wlroots -Most wlroots-based compositors like Hyprland and Sway support the following -unstable wayland protocols for keyboard and mouse emulation: -- [virtual-keyboard-unstable-v1](https://wayland.app/protocols/virtual-keyboard-unstable-v1) -- [wlr-virtual-pointer-unstable-v1](https://wayland.app/protocols/wlr-virtual-pointer-unstable-v1) +The following sections detail the emulation and capture backends provided by lan-mouse and their support in desktop environments / operating systems. -#### KDE -KDE also has a protocol for input emulation ([kde-fake-input](https://wayland.app/protocols/kde-fake-input)), -it is however not exposed to third party applications. +### Input Emulation Support -The recommended way to emulate input on KDE is the -[freedesktop remote-desktop-portal](https://flatpak.github.io/xdg-desktop-portal/#gdbus-org.freedesktop.portal.RemoteDesktop). +| 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 | -#### Gnome -Gnome uses [libei](https://gitlab.freedesktop.org/libinput/libei) for input emulation and capture, -which has the goal to become the general approach for emulating and capturing Input on Wayland. +- `wlroots`: This backend makes use of the [wlr-virtual-pointer-unstable-v1](https://wayland.app/protocols/wlr-virtual-pointer-unstable-v1) and [virtual-keyboard-unstable-v1](https://wayland.app/protocols/virtual-keyboard-unstable-v1) protocols and is supported by most wlroots based compositors. +- `libei`: This backend uses [libei](https://gitlab.freedesktop.org/libinput/libei) and is supported by GNOME >= 45 or KDE Plasma >= 6.1. +- `xdp`: This backend uses the [freedesktop remote-desktop-portal](https://flatpak.github.io/xdg-desktop-portal/#gdbus-org.freedesktop.portal.RemoteDesktop) and is supported on GNOME and Plasma. +- `x11`: Backend for X11 sessions. +- `windows`: Backend for Windows. +- `macos`: Backend for MacOS. -### 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 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | -| relative-pointer-unstable-v1 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | -| keyboard-shortcuts-inhibit-unstable-v1 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | -| wlr-layer-shell-unstable-v1 | :heavy_check_mark: | :heavy_check_mark: | :x: | +### Input Capture Support -The [zwlr\_virtual\_pointer\_manager\_v1](wlr-virtual-pointer-unstable-v1) is required -to display surfaces on screen edges and used to display the immovable window on -both wlroots based compositors and KDE. +| 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: | + +- `layer-shell`: This backend creates a single pixel wide window on the edges of Displays to capture the cursor using the [layer-shell protocol](https://wayland.app/protocols/wlr-layer-shell-unstable-v1). +- `libei`: This backend uses [libei](https://gitlab.freedesktop.org/libinput/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) -Gnome unfortunately does not support this protocol -and [likely won't ever support it](https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/1141). -~In order for layershell surfaces to be able to lock the pointer using the pointer\_constraints protocol [this patch](https://github.com/swaywm/sway/pull/7178) needs to be applied to sway.~ -(this works natively on sway versions >= 1.8)