Skip to content

Repository files navigation

Orbiscreen

Orbiscreen

Real virtual secondary displays for Linux, streamed to Android - one command, zero hassle

Version License Rust Platform Stars


🌐 Language

πŸ‡¬πŸ‡§ English Β· πŸ‡ΈπŸ‡¦ Ψ§Ω„ΨΉΨ±Ψ¨ΩŠΨ©


πŸ“‹ Table of Contents


πŸ€” What is Orbiscreen?

Orbiscreen turns a spare Android tablet or phone into a real second monitor for your Linux desktop. Unlike X11-only or browser-only workarounds, Orbiscreen creates a kernel-level virtual display via DisplayLink's evdi, which appears as a genuine monitor to both X11 and Wayland compositors, and streams it using MPEG-TS/H.264 with reverse touch input natively on Android.


🧭 Why Orbiscreen Exists

Problem Other Projects Orbiscreen
No Linux host support ❌ spacedesk refuses officially βœ… Real kernel-level virtual display
X11-only workaround ❌ VirtScreen unmaintained since 2018 βœ… X11 and Wayland via evdi/DRM
Wayland second screen missing ❌ Weylus caps it to X11 βœ… Full Wayland path via ashpd + PipeWire
Manual IP configuration ❌ Most projects βœ… mDNS discovery + live network scan + manual add
Single-purpose client ❌ spacedesk only βœ… Native Android screen + host control panel

✨ Highlights

  • Real virtual display via evdi (X11 and Wayland)
  • Material 3 Android client - Jetpack Compose, Catppuccin Mocha / Latte brand palette, light/dark theme
  • Live discovery - NSD scan of nearby hosts, manual host:port entry, optional subnet scanner
  • Native streaming - ExoPlayer with OkHttpDataSource + DefaultLoadControl for low-latency MPEG-TS / H.264
  • Reverse touch - absolute pointer / keyboard / stylus / wheel events flow Android β†’ host
  • Host control panel - keyboard, lock, blank, Ctrl+Alt+Del, file manager, and retry actions
  • USB transport via adb reverse, no special drivers
  • Hardware encoding - VAAPI, NVENC, x264 software fallback
  • Cryptographic signing of every Linux and Android artifact

πŸ“Š Status

Phase Goal State
0 Workspace scaffolding + evdi feasibility βœ… Completed
1 Display + capture + encode + input (X11) βœ… Completed
2 Android client + USB transport + mDNS βœ… Completed
3 Wayland capture + portal fallback + input βœ… Completed
4 Packaging + GTK4 GUI + D-Bus service + Standalone installation βœ… Completed
5 Material 3 UI + live discovery + control panel βœ… Completed

See CHANGELOG.md for the complete release history.


πŸš€ Quick Start

1. Official Packages & Pre-built Artifacts (GitHub Releases)

Download pre-built packages from GitHub Releases:

  • Debian / Ubuntu (.deb):

    sudo dpkg -i orbiscreen_amd64.deb || sudo apt-get install -f
  • Fedora / RHEL (.rpm):

    Note: Our RPM packages are cryptographically signed. You must import the public key first.

    sudo rpm --import https://raw.githubusercontent.com/shadow-x78/orbiscreen/main/orbiscreen.asc
    sudo dnf install ./orbiscreen_x86_64.rpm
  • Universal AppImage (.AppImage):

    chmod +x orbiscreen-x86_64.AppImage
    ./orbiscreen-x86_64.AppImage
  • Standalone Tarball (.tar.gz):

    tar -xzvf orbiscreen-linux-x86_64.tar.gz
    cd release-bundle && ./install.sh
  • Android (.apk): Install orbiscreen-android-release.apk (cryptographically signed release build to bypass Play Protect warnings).

2. Building from Source

# Clone the repository
git clone https://github.com/shadow-x78/orbiscreen.git ~/Orbiscreen
cd ~/Orbiscreen

# One-command installation for Linux
./scripts/install.sh

# Probe local capture, input, and display backends
orbiscreen probe

# Start the Orbiscreen daemon (EVDI DRM or Wayland Portal auto-fallback)
orbiscreen start

⌨️ Commands

Command Description
orbiscreen start Create the virtual display and start streaming
orbiscreen start --no-mdns Start without mDNS advertising
orbiscreen list-displays List configured virtual displays
orbiscreen probe Report capture / input / display backends
orbiscreen print-config Print the resolved configuration
orbiscreen uninstall Remove the daemon, systemd service, and desktop entries
orbiscreen --config orbiscreen.toml --verbose probe

To remove everything, including saved config and evdi module state:

orbiscreen uninstall && ./scripts/uninstall.sh

πŸ“± Android App

The Android client is a Material 3 + Jetpack Compose single-Activity app with three screens wired through Compose Navigation:

Screen What it does
Discovery Live NSD scan of _orbiscreen._tcp. hosts, quick-connect chips, manual host:port entry, USB mode via adb reverse, recent host pinned on top
Stream Full-screen ExoPlayer (MPEG-TS over HTTP) with a floating control toolbar: keyboard, lock, blank, Ctrl+Alt+Del, files, retry
Settings Theme (System / Light / Dark), force software decoder, advanced subnet scanner, recent host, about

Reverse touch works out of the box: InputDispatcher maps Android touch to absolute host coordinates over the /input endpoint, debounced so the network never backs up during a fast drag.

The client talks to the daemon through three lightweight JSON endpoints in addition to /stream and /input:

Endpoint Method Purpose
/api/info GET Display resolution, encoder, and version
/api/control POST Host-side actions (blank, lock, ctrl-alt-del, open)
/health GET Liveness probe

πŸ—οΈ Architecture

orbiscreen/
β”œβ”€β”€ crates/
β”‚   β”œβ”€β”€ orbiscreen-core/        # types, config, errors
β”‚   β”œβ”€β”€ orbiscreen-display/     # evdi-backed virtual displays
β”‚   β”œβ”€β”€ orbiscreen-capture/     # X11 (x11rb) + Wayland (ashpd + PipeWire)
β”‚   β”œβ”€β”€ orbiscreen-encode/      # GStreamer pipeline (VAAPI / NVENC / x264)
β”‚   β”œβ”€β”€ orbiscreen-input/       # evdevil + ashpd RemoteDesktop
β”‚   β”œβ”€β”€ orbiscreen-transport/   # axum + mDNS + /api/info + /api/control
β”‚   └── orbiscreen-daemon/      # CLI binary wiring every layer together
β”œβ”€β”€ clients/
β”‚   β”œβ”€β”€ web/                    # browser MPEG-TS client (HTML / CSS / JS)
β”‚   └── android/                # Material 3 Compose app
β”‚       └── app/src/main/java/com/orbiscreen/android/
β”‚           β”œβ”€β”€ MainActivity.kt
β”‚           β”œβ”€β”€ data/           # PrefsStore (recent host + settings)
β”‚           β”œβ”€β”€ net/            # DiscoveryService, SubnetScanner, HostApi
β”‚           β”œβ”€β”€ player/         # PlayerHolder, StreamUrl
β”‚           β”œβ”€β”€ input/          # InputDispatcher
β”‚           └── ui/
β”‚               β”œβ”€β”€ theme/      # Material 3 colour, typography, theme
β”‚               β”œβ”€β”€ nav/        # Compose Navigation graph
β”‚               β”œβ”€β”€ discovery/  # DiscoveryScreen + ViewModel
β”‚               β”œβ”€β”€ stream/     # StreamScreen, PlayerSurface, ControlToolbar
β”‚               └── settings/   # SettingsScreen
β”œβ”€β”€ packaging/{flatpak,appimage,debian}/
β”œβ”€β”€ scripts/{setup-dev-env.sh,test-evdi.sh,install.sh,uninstall.sh}
β”œβ”€β”€ .github/{workflows/,ISSUE_TEMPLATE/,dependabot.yml}
└── .editorconfig, .gitignore, .gitattributes, deny.toml, rustfmt.toml
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  orbiscreen-daemon (CLI, clap)                               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚ display      β”‚  β”‚ capture      β”‚  β”‚ encode            β”‚   β”‚
β”‚  β”‚  evdi crate  β”‚  β”‚ x11rb/ashpd  β”‚  β”‚ gstreamer-rs      β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ input        β”‚  β”‚ transport                            β”‚  β”‚
β”‚  β”‚ evdevil/ashpdβ”‚  β”‚ axum + mdns-sd + adb                 β”‚  β”‚
β”‚  β”‚              β”‚  β”‚ + /api/info + /api/control + /health  β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚  β”‚ core: shared types, config, errors                   β”‚    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚                  β”‚                    β”‚
       β–Ό                  β–Ό                    β–Ό
   /dev/dri/...     X11 / Wayland         Network (mDNS + HTTP)

πŸ“š Documentation

Document Description
docs/ARCHITECTURE.md Β· AR System topology, zero-copy pipeline & D-Bus architecture
docs/INSTALL.md Β· AR Multi-distro installation walkthroughs
docs/PACKAGING.md Β· AR Multi-distro packaging specs (.deb, .rpm, AppImage, Flatpak)
docs/DBUS_SPEC.md Β· AR D-Bus Session Bus IPC interface specifications
docs/TROUBLESHOOTING.md Β· AR Common issues, diagnostics & hardware acceleration fixes
SECURITY.md Security model, transport safety & network policies
CHANGELOG.md Full release history
CONTRIBUTING.md Guidelines for contributing and building from source

🀝 Contributing

Please read our Contributing Guidelines for details on how to set up the development environment, format your code, and submit Pull Requests.

When committing, follow the convention:

orbiscreen | <scope>: <message>

For example:

orbiscreen | android | player: retry on transient network errors
orbiscreen | docs | readme: clarify mDNS discovery flow
orbiscreen | v0.10.3 | release: host-input protocol alignment

πŸ“œ License

Distributed under the GPL-3.0 License.


Built by shadow-x78 Β· Changelog Β· Security

Β© 2026 Orbiscreen

About

Kernel-level virtual secondary displays for Linux (X11 & Wayland via evdi), streamed natively to Android tablets and phones over MPEG-TS/H.264. ExoPlayer client with reverse touch, Wi-Fi mDNS discovery or USB adb reverse. VAAPI/NVENC hardware encoding, cryptographically signed artifacts.

Topics

Resources

Contributing

Security policy

Stars

8 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages