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)