Update README.md (#229)

This commit is contained in:
Ferdinand Schober
2024-11-07 02:35:32 +01:00
committed by GitHub
parent 41ab25cc19
commit fef702ffdd

323
README.md
View File

@@ -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
</picture>
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
<details>
<summary>Arch Linux</summary>
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
```
</details>
<details>
<summary>Nix (OS)</summary>
### 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)
</details>
### 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
<details>
<summary>Manual Installation</summary>
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)
</details>
## Installing Dependencies
## Installing Dependencies for Development / Compiling from Source
<details>
<summary>MacOS</summary>
```sh
brew install libadwaita
brew install libadwaita pkg-config
```
</details>
@@ -191,10 +189,22 @@ sudo dnf install libadwaita-devel libXtst-devel libX11-devel
```
</details>
<details>
<summary>Windows</summary>
<summary>Nix</summary>
```sh
nix-shell .
```
</details>
<details>
<summary>Nix (flake)</summary>
```sh
nix develop
```
</details>
> [!NOTE]
> This is only necessary when building lan-mouse from source. The windows release comes with precompiled gtk dlls.
<details>
<summary>Windows</summary>
- 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).
</details>
## Usage
### Gtk Frontend
<details>
<summary>Gtk Frontend</summary>
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.
</details>
<details>
<summary>Command Line Interface</summary>
### 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
```
</details>
<details>
<summary>Daemon Mode</summary>
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
```
</details>
## 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)