I keep a laptop plugged into my server rack. From my desktop a room away, I dedicate one of my three monitors to that laptop's display. The Linux environment stays up and reachable without walking to the rack, and it's become a real part of my daily workflow.
Three tools make this work: Deskflow for keyboard and mouse, Sunshine to stream the display from the laptop, and Moonlight to receive it on the desktop. Deskflow handles input; Sunshine and Moonlight handle video. Keep those roles separate and it works well.
| Machine | Role | Software |
|---|---|---|
| Desktop (keyboard & mouse live here) | Deskflow server, Moonlight client | Receives the video stream on one monitor |
| Laptop in the rack | Deskflow client, Sunshine host | Streams its display |
When my cursor crosses onto the dedicated monitor, Deskflow sends keyboard and mouse events to the laptop. Sunshine only ships pixels - input is disabled on its side so nothing fights over the same events.
Set this up first. If input routing isn't right, the rest of the stack is painful to debug. Sunshine supports sending mouse/keyboard events as well, but in my experience it's delayed enough to be disruptive. What I've found is that if we disable that capability in Sunshine and dedicate a separate tool to it, it's seamless.
Install Deskflow on both machines.
This is the machine your keyboard and mouse are physically plugged into.
- Open Deskflow and choose Server mode.
- Click Configure Server and add a screen for the laptop. Use the laptop's hostname.
- Arrange the screens to match your physical monitor layout. Put the laptop screen where your dedicated monitor sits—if it's the rightmost display, drag it to the right edge of your desktop screen.
- Start the server.
- Open Deskflow and choose Client mode.
- Set the server address to your desktop's IP or hostname.
- Start the client and accept the SSL fingerprint prompt if one appears on first connect.
Move the mouse off the edge of your desktop screen toward the laptop monitor. The cursor should land on the laptop. Click around and type something—a terminal on the laptop is an easy test. If the cursor stops at the edge or input stays on the desktop, recheck the screen layout in the server config and confirm the client is connected.
Deskflow is doing the heavy lifting for input. Once this works, disable Sunshine's input forwarding in the next step.
Install Sunshine on the laptop—the machine whose display you want to stream.
Edit ~/.config/sunshine/sunshine.conf and add or update these settings:
controller = disabled
keyboard = disabled
mouse = disabled
nvenc_preset = 7
nvenc_twopass = full_res
output_name = 0
sw_tune = film
A few notes on the non-obvious bits:
- keyboard / mouse / controller = disabled — Deskflow owns input. Leave these off or you'll get duplicate or conflicting events.
- output_name — Sunshine assigns numeric IDs to displays at startup. Check the Sunshine logs for
Detected displaylines and use theidin parentheses if0isn't the display you want. - nvenc_preset = 7 — Slowest NVENC preset, best quality per bit. Fine on a wired LAN.
- nvenc_twopass = full_res — Worth the extra encode cost for a cleaner image at a given bitrate.
- sw_tune = film — Fallback tuning if Sunshine falls back to software encoding.
Restart Sunshine after editing the config:
systemctl --user restart sunshineInstall Moonlight on the desktop. Add the laptop as a host (Deskflow's LAN discovery and Sunshine's mDNS usually make this painless), then connect.
These are the settings I run with on a 1440p dedicated monitor:
| Setting | Value |
|---|---|
| Resolution | 1440p |
| FPS | 60 |
| Video bitrate | 40 Mbps |
| Display mode | Fullscreen |
| V-Sync | On |
| Frame pacing | On |
| Audio | Stereo |
| Mute host speakers while streaming | On |
| Mute stream when Moonlight isn't focused | On |
| Optimize game settings for streaming | On |
| Video decoder / codec | Automatic |
| Enable HDR | On (experimental) |
| Auto-find PCs on LAN | On |
Launch Moonlight on the dedicated monitor and leave it connected. Deskflow handles the handoff when you move the cursor over; Moonlight just keeps the picture coming.
Moonlight looks best when the host display resolution matches your client monitor. My laptop panel is 1920×1200 but the monitor I stream to wants a different effective size, so I scale with xrandr on the laptop before connecting.
Figure out your client monitor's target resolution, then set the laptop display to match. I keep two aliases in my NixOS config:
shellAliases = {
display-high = "xrandr --output eDP-1 --mode 1920x1200 --scale 1x1 && xrandr --output eDP-1 --mode 1920x1200 --scale 1.333333x1.2";
display-default = "xrandr --output eDP-1 --mode 1920x1200 --scale 1x1";
};Swap eDP-1 for your output name (xrandr --query will tell you). Run the high-res alias before streaming, display-default when you're done. One sharp stream, no letterboxing surprises.