Share your keyboard, mouse, and clipboard seamlessly between Linux and Windows.
Features • Installation • Quick Start • How It Works • Configuration • Contributing
MWB Linux is a native Linux client that connects to Microsoft PowerToys Mouse Without Borders on Windows. Move your mouse to the edge of the screen, and it seamlessly jumps to the other machine — along with your keyboard and clipboard.
flowchart LR
A["🐧 <b>Linux PC</b><br/>Mouse · Keyboard"] <-->|" 🖱️ Mouse · ⌨️ Keyboard · 📋 Clipboard "| B["🪟 <b>Windows PC</b><br/>Mouse · Keyboard"]
Move your mouse to the screen edge — the cursor seamlessly jumps to the other machine.
No extra software needed on Windows beyond PowerToys, which bundles Mouse Without Borders.
- Bidirectional mouse sharing — Control both machines from either keyboard/mouse
- Seamless edge switching — Move cursor to screen edge, it appears on the other machine
- Clipboard sync — Copy text or images on one machine, paste on the other
- Keyboard forwarding — Type on your Linux keyboard, text appears on Windows
- Full mouse support — Scroll wheel, horizontal scroll, and side buttons (back/forward)
- Encrypted — AES-256-CBC encryption with PBKDF2 key derivation
- Device isolation — When controlling Windows, your Linux cursor doesn't move
- Dual-mode connection — Acts as both server and client for fast reconnection
- Zero config on Windows — Works with existing PowerToys MWB setup
- Lightweight — Single binary, ~5MB, no GUI dependencies
| Direction | What happens |
|---|---|
| Mouse hits left edge on Linux | Cursor appears on Windows, Linux input disabled |
| Mouse hits right edge on Windows | Cursor returns to Linux, input restored |
| Ctrl+C on Windows | Text/image available on Linux clipboard |
| Ctrl+C on Linux | Text/image available on Windows clipboard |
| Type on Linux keyboard | Text appears in focused Windows app |
curl -fsSL https://raw.githubusercontent.com/lucky-verma/mwb-linux/main/scripts/install.sh | sudo bashDownload the versioned .deb for your architecture from
Releases, then install it:
sudo dpkg -i mwb-linux_*_amd64.deb
# Add yourself to the input group
sudo usermod -aG input $USER# Download binary
wget https://github.com/lucky-verma/mwb-linux/releases/latest/download/mwb-linux-amd64
chmod +x mwb-linux-amd64
sudo mv mwb-linux-amd64 /usr/local/bin/mwb
# Install dependencies
sudo apt install xdotool xclip
# Setup permissions
sudo bash -c 'modprobe uinput && echo uinput > /etc/modules-load.d/uinput.conf'
echo 'KERNEL=="uinput", GROUP="input", MODE="0660"' | sudo tee /etc/udev/rules.d/99-mwb-uinput.rules
sudo udevadm control --reload-rules
sudo usermod -aG input $USERgo install github.com/lucky-verma/mwb-linux/cmd/mwb@latestPuts mwb in $(go env GOPATH)/bin. You still need the system dependencies and
permissions from From Binary: xdotool/xclip, the uinput
module, the udev rule, and membership of the input group. This build reports
dev for mwb version, since the release ldflags are not applied.
git clone https://github.com/lucky-verma/mwb-linux.git
cd mwb-linux
make build
make install # no sudo — installs a per-user service
systemctl --user enable --now mwbmake install is a per-user install: the binary goes to ~/go/bin/mwb and the
service to ~/.config/systemd/user/. Do not run it with sudo — that
installs under root and the --user service then can't find the binary.
The installed service runs receive-only mode (mwb) so it will not
unexpectedly send the Linux mouse to Windows. Use mwb -bidi -edge left
manually when you explicitly want Linux → Windows control.
It does not set up system dependencies. If this is a fresh machine, run the
dependency and permission steps from From Binary first
(xdotool/xclip, the uinput module, the udev rule, and the
input group).
Note: Log out and back in after installation for group changes to take effect.
One installer at a time. The one-line/
.deb/binary methods install a system service that runs/usr/local/bin/mwb.make installinstalls a per-user service that runs~/go/bin/mwb. If you switch methods, stop and disable the old service first so you aren't running a stale binary.
mwb update --check # see what's available
mwb update # download, verify and install
mwb update --restart # install and restart an active user servicemwb update fetches the release artifact for your architecture, verifies it
against the SHA-256 published in that release's checksums.txt, and replaces
the binary atomically — an interrupted update leaves either the old binary or
the new one, never a broken one. It refuses to install anything whose checksum
does not match, and only ever downloads from GitHub. Before replacement it
creates a versioned hard-link backup beside the binary, without overwriting an
existing backup.
A source build reports version dev, which cannot be ordered against a release.
The updater therefore refuses to replace it unless --force is supplied.
If mwb was installed from the .deb, mwb update will not overwrite it behind
dpkg's back; it prints the apt command to use instead. If the binary lives
somewhere only root can write, it tells you to re-run with sudo.
The running service keeps using the old binary until it is restarted. Pass
--restart to do that after a successful update, or restart it separately:
systemctl --user restart mwb.serviceOpen PowerToys → Mouse Without Borders → copy the Security Key.
mkdir -p ~/.config/mwb
cat > ~/.config/mwb/config.toml << EOF
host = "192.168.1.100" # Your Windows machine's IP
key = "YourSecurityKey" # From PowerToys MWB
name = "linux" # This machine's name (max 15 chars)
keyboard_layout = "auto" # Inbound keyboard layout profile
EOF# Receive only (Windows controls Linux)
mwb
# Bidirectional (Linux also controls Windows)
mwb -bidi -edge leftIn PowerToys MWB, enter the security key and device name to connect.
MWB Linux implements the full Mouse Without Borders protocol:
- Dual-mode connection — Listens on port 15101 AND connects outbound (first one wins)
- Handshake — AES-256-CBC encrypted challenge-response with PBKDF2-SHA512 key derivation
- Heartbeats — Proactive keepalive every 5s prevents Windows from dropping the connection
- Edge detection — 10ms cursor polling detects screen edges, instant switching with bounce prevention
- Input forwarding — Mouse (absolute coords) and keyboard (VK codes) sent as MWB packets
- Device isolation — exclusive
EVIOCGRABkernel grabs on local keyboards and pointers prevent dual cursor movement during remote control. The grab is owned by the file descriptor, so the kernel restores local input automatically if mwb exits, crashes or is killed - Clipboard — Bidirectional text/image sync via compressed clipboard packets
- File copy — Copy one file, switch to the other machine, and paste it into the folder you choose. In both directions the receiver stages the file privately on its clipboard; a copy alone never creates a visible destination file. Bytes travel over a second connection on the clipboard port (base; control is base+1), matching PowerToys MWB
For implementation details, see the architecture and file-transfer documentation.
Mouse Without Borders lets a remote machine inject keyboard and mouse input into your Linux session, so treat it like remote control and run it only on networks and machines you trust.
- Local networks only. As defense in depth, the client refuses inbound connections from globally routable addresses before they can consume any handshake work; the internet cannot reach the handshake. Sources on a local network (RFC1918/ULA private space or an IPv6 link-local address) are allowed to attempt it, because the configured peer is a machine rather than an address: a dual-stack Windows host connects from an IPv6 link-local address that no lookup of its IPv4 will return, and DHCP renewal, a second NIC or a VPN route all change the source address without changing the peer. This widens who may attempt authentication, never who passes it. The outbound connection is unchanged.
- Shared secret. Use a long, random
keyand protect the config file. Anyone who obtains the key and can reach the configured host can impersonate an MWB peer. - Firewall. Only expose ports 15100–15101 to your trusted LAN. Block them from the internet, and avoid using the client on untrusted/public Wi-Fi.
- No sudo. Run as your normal user (in the
inputgroup);sudo mwbcan attach to the wrong session and is unnecessary.
For compatibility, the transport uses the original MWB AES-256-CBC protocol rather than a modern authenticated-encryption protocol. Treat the peer-IP check as an additional network boundary, not as a replacement for the shared key, and keep the client on a trusted network segment.
| Field | Default | Description |
|---|---|---|
host |
(required) | Windows machine IP address |
key |
(required) | MWB security key (from PowerToys) |
name |
hostname | This machine's display name |
port |
15100 | Base port (message port = 15101) |
remote_width |
1920 | Remote screen width in pixels |
remote_height |
1080 | Remote screen height in pixels |
edge |
left | Screen edge for switching: left or right |
clipboard |
true | Clipboard sync: set false to disable text/image sharing |
accel_multiplier |
2.0 | Cursor speed when controlling Windows. Lower it (e.g. 1.0, 0.5) if the Windows cursor feels too fast |
inbound_multiplier |
1.0 | Cursor speed when Windows controls Linux. 1.0 mirrors Windows exactly; raise it for faster inbound movement |
file_transfer |
true | Enable the MWB file copy channel. Keep clipboard = true: clipboard events trigger transfers in both directions |
file_dir |
— | Deprecated and ignored. Windows files use hidden clipboard backing storage under $XDG_CACHE_HOME/mwb/clipboard and a native GNOME/generic file selection, then appear in a visible folder only on paste |
max_file_size |
104857600 | Per-transfer cap in bytes. The default matches MWB's own 100 MB limit; a stock Windows peer neither sends nor accepts more |
keyboard_layout |
auto | Inbound Windows-to-Linux keyboard mapping. auto detects the local Linux layout when possible; supported profiles include us, de, fr, be, es, it, gb, pt, no/dk/se/fi, ch, and nl |
Config file security:
config.tomlstores the security key in plaintext. The installer creates it with0600permissions (owner-only), andmwbtightens an existing config to0600on startup so other local accounts can't read the key. Use a long, random key —mwblogs a warning if the configured key is very short.
| Command | Description |
|---|---|
mwb |
Run the client (default when no command is given) |
mwb version |
Print the installed version |
mwb update |
Download and install the latest release |
mwb update --check |
Report whether an update exists, without installing |
mwb update --force |
Reinstall the latest release even if already current |
mwb update --restart |
Install and restart an active mwb.service |
| Flag | Default | Description |
|---|---|---|
-bidi |
false | Enable bidirectional input (Linux → Windows) |
-edge |
(from config) | Override edge from config: left or right |
-no-clipboard |
false | Disable clipboard sharing (overrides config) |
-debug |
false | Enable debug logging |
-config |
~/.config/mwb/config.toml | Config file path |
- PowerToys installed with Mouse Without Borders enabled
- "Move mouse relatively" set to OFF (required for bidirectional mode)
- "Share clipboard" set to ON (for clipboard sync)
- "Block screen saver on other machines" set to ON (recommended, keeps connection alive)
- Security key shared with Linux client
- Windows Firewall must allow ports 15100-15101 (TCP inbound/outbound)
Run the setup permissions commands above, then log out and back in.
Ensure xclip is installed: sudo apt install xclip
Set clipboard = false in config.toml, or run with -no-clipboard. The Linux
client then never reads or writes the local clipboard, so it won't override what
you copied on Windows.
Make sure you are running bidirectional mode with mwb -bidi -edge left after
the udev/input-group setup and a fresh login. Avoid sudo mwb for normal use:
it reads root's config and can miss the user's display/session.
If an older root service is still running, stop it before starting the user service:
sudo systemctl disable --now mwb-linux.service
systemctl --user restart mwb- Check Windows firewall allows port 15100-15101
- Verify the IP address in config.toml
- Ensure PowerToys MWB is enabled on Windows
Set "Move mouse relatively" to OFF in PowerToys MWB settings.
Upgrade to a build with directional MachineSwitched/NextMachine filtering.
The Linux client should only accept return requests from the edge configured by
-edge; touching the other laptop's far edge should stop there, not bring
control back to Ubuntu.
cmd/mwb/ CLI entry point
internal/
capture/ Edge detection, evdev capture, EVIOCGRAB device isolation
clipboard/ Bidirectional clipboard sync (text + images)
config/ TOML configuration
input/ Virtual mouse/keyboard via uinput
network/ TCP connection, encryption, packet send/receive
protocol/ MWB packet types, serialization, AES-256-CBC
docs/
README.md Documentation index
architecture.md Runtime design and contributor invariants
file-transfer.md File-channel behavior and safety controls
scripts/
install.sh Installation helper script
- Keyboard on Windows lock screen — Keyboard input may not work on the Windows lock screen (Winlogon desktop security restriction)
- Middle mouse button auto-scroll — Middle-click auto-scroll (scroll lock mode) does not work in browsers; normal middle-click works
- First connection — Initial handshake takes ~3-16s depending on Windows MWB state; subsequent reconnects are instant
- Bidirectional mode requires X11 — Edge detection queries the X11 server directly;
xdotoolis retained for the infrequent cursor recenter operation. (Device isolation itself is display-server agnostic:EVIOCGRABworks identically on X11, Wayland and the console.) Receive-only mode works on Wayland (XWayland session). Native Wayland bidirectional support requires compositor extensions and is not yet implemented. - Keyboard layout metadata — PowerToys MWB keyboard packets carry Windows virtual-key codes and flags, but not hardware scan codes or Unicode text. MWB Linux uses
keyboard_layoutprofiles for common layouts; unsupported profiles fall back to the original US-compatible mapping. Fully zero-config global layout support requires sender-side scan code or Unicode metadata. - File copy is one file at a time — Matching MWB itself, folders and
multi-file selections are not transferred; zip them first. The 100 MB default
cap is MWB's own limit, not ours. Drag-and-drop between machines is not
supported: that flow needs Explorer
DragEnterand helper windows, so it is Windows-only by construction. - Special-function keys stay local while remote — Media, brightness and similar hardware keys are deliberately not grabbed, so they act on the Linux machine even while the cursor is on the remote. Power and sleep buttons are likewise never grabbed, which keeps the physical power button available as a last-resort recovery path.
- Cursor speed / drift — Remote cursor movement scales raw evdev deltas by
accel_multiplier(default 2×); lower it if the Windows cursor feels too fast (the Windows side adds no acceleration of its own). Tracking is open-loop, so the virtual cursor may still drift from the actual position over long sessions.
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
make build # Build binary
make test # Run tests
make lint # Run linter
make check # All of the above- Microsoft PowerToys — Mouse Without Borders is part of PowerToys (MIT License). This project implements the MWB network protocol for Linux.
- bketelsen/mwb — Initial Go implementation of the MWB receive-only client that this project builds upon.
- The MWB protocol specification was derived from the open-source PowerToys codebase.
MIT License — see LICENSE for details.
