Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

netscreen-extend

Sunshine extended display for Linux

Turn any device running Moonlight into a second monitor for your Linux computer. Old laptop, all-in-one, tablet, phone or TV: if it runs Moonlight, it becomes an extended display.

License: MIT Platform: Linux X11 Shell: Bash Host: Sunshine Client: Moonlight PRs welcome

Leia em português · How it works · Contributing

Unofficial community project. Not affiliated with Sunshine (LizardByte) or Moonlight. It builds on both.


Highlights

  • Extended display, not a mirror: windows, maximizing and the mouse work as on a physical monitor.
  • No dummy plug required. An empty HDMI output becomes a virtual display, with Secure Boot enabled, no kernel module and no reboot.
  • Streams only the extended display, through a dedicated Sunshine instance. An existing Sunshine setup keeps working.
  • Audio can play on the host or on the client, switchable at any time with netscreen audio toggle.
  • Direct cable mode identifies the client by MAC address, never shares the network on a cable connected to a router, and turns everything off when the cable is unplugged.
  • uninstall.sh removes everything and restores what was changed.

Measured on a low-end client (Intel Pentium all-in-one, direct gigabit cable): 1080p60, about 1 ms network latency, 0.8 ms hardware decode.

Quick start

git clone https://github.com/daeoxide/netscreen-extend.git
cd netscreen-extend
./install.sh        # answers are auto-detected, just confirm
netscreen on        # then pair Moonlight and start "Desktop"

Contents

What it does · Requirements · Install · Usage · Configuration · Files · Uninstall · Troubleshooting · Roadmap · Contributing


What it does

 LINUX HOST (X11)                                             CLIENT (any OS)
 ┌───────────────────────────────────────┐                   ┌───────────────────┐
 │ built-in display                      │                   │                   │
 │ HDMI-1  extended display (virtual)    │                   │  Moonlight        │
 │   └─► dedicated Sunshine instance ─────┼── cable or LAN ──►│  full screen      │
 │       hardware encoding               │                   │                   │
 └───────────────────────────────────────┘                   └───────────────────┘

Requirements

Host (the Linux computer)

  • X11 session. Wayland is not supported yet. On Ubuntu, choose Ubuntu on Xorg on the login screen.
  • A free video output, preferably HDMI. A dummy plug or adapter on any output also works.
  • Sunshine installed, plus xrandr, cvt (from xserver-xorg-core), sudo and flock.
  • Direct cable mode: NetworkManager (nmcli) and an Ethernet port.
  • GPU: tested on Intel (i915). Forcing an empty HDMI output depends on the driver. On other GPUs, a dummy plug always works (see how it works).

Client (the screen)

Install

git clone https://github.com/daeoxide/netscreen-extend.git
cd netscreen-extend
./install.sh

The installer asks a few questions. The defaults are detected automatically.

Question Default
Built-in display First eDP/LVDS/DSI output
Output for the extended display First free HDMI output
Resolution, refresh rate, position 1920x1080, 60 Hz, right-of
Connection mode direct if there is an Ethernet port, otherwise lan
Client MAC (direct) Detected with the cable connected
Audio host
Sunshine port and name 48089, <hostname>-netscreen

Run it again at any time. It keeps the saved configuration; use ./install.sh --reconfigure to answer the questions again.

Pair the client (once)

  1. Run netscreen on.
  2. Open https://localhost:48090 (port + 1) and create a login for this instance.
  3. In Moonlight on the client, choose Add PC manually and enter the address printed by netscreen on (for example 10.42.0.1:48089).
  4. Type the PIN shown by Moonlight in the web UI, on the PIN tab.
  5. Start Desktop.

Recommended Moonlight settings

Setting Value Why
Resolution Same as the extended display (e.g. 1080p) Any other value is rescaled and looks blurry.
Frame rate 60 FPS
Bitrate 50–80 Mbps on a cable, less on Wi-Fi The default bitrate is too low for sharp text on a desktop.
Video codec H.264 on weak clients, HEVC if the client decodes it in hardware Check the decode time in the stats overlay (Ctrl+Alt+Shift+S).
V-Sync / frame pacing On Stable picture. Turning them off lowers latency but may tear.

Usage

Command Shortcut What it does
netscreen on NetScreen on Checks the client (direct mode), creates the display, starts streaming
netscreen off NetScreen off Stops streaming and removes the display
netscreen status Shows the display, stream, audio, cable and client state
netscreen audio host / client Chooses where sound plays
netscreen audio toggle NetScreen audio: switch output Switches between host and client

Audio

AUDIO Result
host Sound stays on this computer (speakers, headphones). Nothing is sent to the client.
client Sound is streamed to the client, and Sunshine mutes the host while the stream is active.

Switching during a stream restarts the Sunshine instance, so you need to reconnect in Moonlight. The choice is saved in the config file.

Connection modes

direct: cable straight between host and client

The installer creates two NetworkManager profiles on the chosen Ethernet port:

Profile Type Autoconnect Purpose
netscreen-dhcp DHCP, requires IPv4, 15 s timeout yes Normal behavior when the cable goes to a router
netscreen-direct Shared (10.42.0.1/24, DHCP + NAT for the client) no Enabled only after confirming there is no router on the cable

What happens automatically (systemd user service netscreen-watch):

Situation Behavior
Cable plugged into a router netscreen-dhcp gets an address. Direct mode stays off, so your computer never acts as a DHCP server on someone else's network.
Cable plugged into the client No DHCP answer, so netscreen-direct is enabled and the client's MAC is searched for up to CLIENT_WAIT seconds. A notification is shown when the client is found.
Cable plugged into something else without DHCP netscreen-direct is disabled again after the wait.
Cable unplugged while streaming netscreen off runs automatically.

The service never turns the display on by itself. Run netscreen on when you want it.

lan: client on the same network

No network changes and no service. Moonlight connects to this computer's LAN IP, which netscreen on prints. Quality depends on your network; a cable is better than Wi-Fi.

Configuration

Saved in ~/.config/netscreen-extend/config. Run ./install.sh again after editing.

Key Description
INTERNAL_OUTPUT Built-in display (xrandr name)
EXTEND_OUTPUT Output used as the extended display (xrandr name)
EXTEND_CONNECTOR Kernel name of the same output (/sys/class/drm/card*-NAME), detected by the installer
WIDTH, HEIGHT, REFRESH Mode of the extended display (1920x1080@60 uses CEA timing; others use cvt)
POSITION right-of, left-of, above or below the built-in display
NETWORK_MODE direct or lan
IFACE, HOST_IP, CLIENT_MAC Direct mode: Ethernet port, host IP on the cable, client MAC
PROFILE_DIRECT, PROFILE_DHCP Direct mode: NetworkManager profile names
CLIENT_WAIT Direct mode: seconds to look for the client after plugging the cable
AUDIO host or client
SUNSHINE_PORT, SUNSHINE_NAME Dedicated instance port (web UI = port + 1) and name shown in Moonlight
SUNSHINE_OUTPUT_INDEX auto (position in the xrandr list) or a fixed Sunshine display index
FEC_PERCENT Sunshine forward error correction: 5 for direct, 20 for LAN

Files

Repository

Path Purpose
bin/netscreen Command-line tool (on, off, status, audio, watch)
lib/common.sh Paths, config loading, messages, root helper call
lib/display.sh Output/connector detection, custom modes, display on/off
lib/sunshine.sh Dedicated Sunshine instance: config generation, start, stop
lib/network.sh Direct mode: router detection, shared profile, client detection by MAC
root/netscreen-connector Root helper that forces or releases one DRM connector
templates/ Sunshine config, app list, systemd unit and desktop shortcuts
install.sh / uninstall.sh Setup and complete removal
docs/how-it-works.md Technical details and design decisions

Created on your system

Path Created by Removed by uninstall
~/.config/netscreen-extend/config installer questions optional prompt
~/.local/state/netscreen-extend/ Sunshine instance data (pairing, logs), runtime files, backups optional prompt
~/.local/bin/netscreen symlink to bin/netscreen yes
~/.local/share/applications/netscreen-*.desktop shortcuts yes
~/.config/systemd/user/netscreen-watch.service direct mode yes
/usr/local/sbin/netscreen-connector root helper yes
/etc/sudoers.d/netscreen-extend allows only netscreen-connector on/off <your connector> without a password yes
NetworkManager netscreen-direct, netscreen-dhcp direct mode yes

Existing shared profiles that autoconnect on the port get autoconnect disabled, and uninstall restores it. ~/.config/monitors.xml is backed up on the first install, and uninstall offers to restore it.

Uninstall

./uninstall.sh

It turns the display off, removes the service, shortcuts, command, network profiles, root helper and sudoers rule, and restores autoconnect on previously changed profiles. It then asks whether to restore monitors.xml and whether to delete the settings and pairing data. Sunshine itself is never modified.

Troubleshooting

Problem What to check
an X11 session is required Log in with Ubuntu on Xorg (or your desktop's X11 session).
Moonlight cannot find the host netscreen status. In direct mode the cable profile must be netscreen-direct, and the client must have a 10.42.0.x address. A 169.254.x.x address means the client gave up on DHCP: replug the cable.
client not available The client must be on and connected straight to the cable. Follow the log with journalctl --user -u netscreen-watch -f.
could not force <connector> Check that the root helper is installed (run ./install.sh). The driver may not allow forcing that output: use a dummy plug.
Black screen in Moonlight Wrong display index: set SUNSHINE_OUTPUT_INDEX using the Detected display lines in ~/.local/state/netscreen-extend/sunshine/sunshine.log.
Blurry picture Match the Moonlight resolution to the extended display and raise the bitrate.
Sound plays in the wrong place netscreen audio host or netscreen audio client, then reconnect Moonlight.
A leftover empty display after an error netscreen off, or reboot (forcing a connector does not persist).

Security notes

  • Password-free root: the sudoers rule allows only /usr/local/sbin/netscreen-connector on|off <connector>. The helper is root-owned, validates its arguments and writes one word to one sysfs file.
  • Network exposure: the dedicated Sunshine instance listens on all interfaces, like Sunshine itself. Only paired devices can stream. Run netscreen off when you are not using it.
  • Direct mode shares your connection with the client (NAT), and only after confirming there is no router on the cable.

Limitations

  • X11 only, since it relies on xrandr.
  • Forcing an empty output is driver-dependent (tested on Intel i915; DisplayPort usually refuses without a monitor).
  • Streaming uses 4:2:0 color on most clients, so thin colored text is not identical to a cable connection. Latency is low but not zero.

Tested on

  • Host: Ubuntu 24.04, GNOME 46 on X11, Intel UHD Graphics (i915), Secure Boot enabled, Sunshine 2026.x with VAAPI.
  • Client: Windows 10 with Moonlight on a low-power Intel Pentium (Braswell) all-in-one, over a direct gigabit cable.
  • Result: 1080p60, H.264 hardware decoding at about 0.8 ms per frame, about 1 ms network latency, 50–80 Mbps.

Roadmap

Ideas where help is especially welcome:

  • Wayland support (GNOME/KDE virtual monitors through their own APIs instead of xrandr)
  • Test reports on AMD and NVIDIA GPUs, including which outputs can be forced without a dummy plug
  • Auto-detect the Sunshine display index from its log instead of the xrandr order
  • Optional automatic netscreen on when the client is detected
  • More than one extended display or client at a time
  • Packaging (AUR, .deb)

Contributing

Contributions of any size are welcome: bug reports, test results on other hardware, docs, translations and code. Please read CONTRIBUTING.md and open an issue before large changes.

If the project is useful to you, starring the repository helps other people find it.

License

MIT

About

Sunshine extended display for Linux: turn any Moonlight device into a second monitor (virtual display, X11)

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages