Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save justmiles/346aebfb4993d83a83965b9dccb753e3 to your computer and use it in GitHub Desktop.

Select an option

Save justmiles/346aebfb4993d83a83965b9dccb753e3 to your computer and use it in GitHub Desktop.
Remote Linux Display via Sunshine and Deskflow

Remote Linux Display via Sunshine and Deskflow

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.

The layout

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.

1. Deskflow

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.

Desktop (server)

This is the machine your keyboard and mouse are physically plugged into.

  1. Open Deskflow and choose Server mode.
  2. Click Configure Server and add a screen for the laptop. Use the laptop's hostname.
  3. 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.
  4. Start the server.

Laptop (client)

  1. Open Deskflow and choose Client mode.
  2. Set the server address to your desktop's IP or hostname.
  3. Start the client and accept the SSL fingerprint prompt if one appears on first connect.

Verify input goes to the client

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.

2. Sunshine (laptop)

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 display lines and use the id in parentheses if 0 isn'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 sunshine

3. Moonlight (desktop)

Install 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.

Bonus: match resolution on the laptop

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment