10 KiB
Linux headless operation
CrossDesk can reuse an existing X11 desktop or create a separate Xvfb desktop on a Linux host without a monitor. Capture, input, cursor and clipboard use the same display.
Preserve the existing desktop and applications
Start CrossDesk normally. It automatically discovers and selects your existing desktop, preserving its Dock, panel, wallpaper and open applications. No display number or DISPLAY configuration is required:
crossdesk
# Source build:
xmake r crossdesk
With multiple desktops, selection prefers the startup environment's desktop, then the current login session, the active primary desktop, other active desktops, and online desktops. Equal-priority desktops use a stable display order, also used when systemd/logind metadata is unavailable. Inaccessible sessions and bare Xvfb displays without a window manager are excluded from existing-desktop selection.
Reusing a desktop does not require Xvfb. Exiting CrossDesk does not terminate that desktop or its applications. A locked session initially shows the system lock screen; unlock it with that user's system password.
Discovery combines the current user's login-session metadata with their X11 sockets and verifies a live window manager. It works without systemd/logind as well. It respects XAUTHORITY or Xlib's default location when unset, and can try the user's GDM authority file. Other users' desktops and login greeters are not automatically selected.
--headless explicitly requests automatic selection, for example when the shell has stale Wayland environment variables. The display override is retained only for advanced use and debugging:
crossdesk --headless-display :10 # Example display, not needed for normal startup.
The override fails if the specified desktop is inaccessible or has no window manager; it never substitutes a blank Xvfb.
Do not add --headless-size or --headless-session to reuse an existing desktop: those options create a separate Xvfb. The existing display server controls its resolution.
Terminal console
Headless mode keeps routine logs in files and displays the device ID, connection password, online status and command results in the terminal. SSH launches without a graphical environment enable this automatically; to request it explicitly:
xmake r crossdesk --headless
Enter commands in that terminal while CrossDesk is running:
| Command | Action |
|---|---|
status |
Show the device ID, current password and connection state |
settings |
Open the numbered settings menu; back returns |
settings show |
Show settings without entering the menu |
settings set KEY VALUE |
Change a setting directly |
password |
Prompt for a new password; six ASCII letters or digits, or cancel |
password Ab12Cd |
Submit a password directly (example only) |
random |
Generate and submit a random password |
help |
Print command help |
quit |
Exit CrossDesk, preserving a reused desktop |
The menu shares the GUI's config.ini. Each valid change is saved immediately; cancel discards the value being edited. Console status, menus, password messages and help follow the saved Chinese, English or Russian language setting. Command names remain the same.
| Key | Values / format | When applied |
|---|---|---|
language |
zh-CN / en-US / ru-RU |
Immediately, including the GUI; retained on restart |
codec |
h264 / av1 |
Reconnect after saving |
hardware |
on / off |
Reconnect; enabling requires a build with hardware codec support |
turn |
off / auto / udp / tcp |
Reconnect; UDP/TCP force relay use |
server_host |
Hostname, IP, or HTTPS/WSS signaling URL, with optional path and explicit port | Reconnect if self-hosting is enabled; otherwise saved for later |
server_port |
1–65535 |
Same as server host |
self_hosted |
on / off |
Configure host/port first, then enable; reconnect |
privacy |
on / off |
Automatic privacy screen on subsequent connections |
file_path |
Existing writable absolute directory, or default |
Subsequent received files; spaces need no extra quotes |
autostart |
on / off |
Next graphical desktop login, not a system boot service |
daemon |
on / off |
Next normal-mode start; the headless console remains in the foreground |
Example commands inside the running console:
settings
1
en-US
back
settings set codec av1
settings set file_path /home/user/Received Files
Connection settings cannot change while a remote session is connected/connecting or a password change is unresolved. Switching signaling servers may change the device identity; use status after reconnection. Quality/frame rate are controlled by the viewer, and headless Linux capture uses X11; those options are not additional mutable global settings.
Password changes require a signaling connection. The console reports submission, server confirmation and reconnection, using the GUI's existing persistence and timeout recovery flow. Invalid input, offline changes and pending requests produce concise messages. A password change reconnects the host.
Startup prints the existing log location. Logs retain their original crossdesk-YYYYMMDD-HHMMSS.log and minirtc-YYYYMMDD-HHMMSS.log names and rotation policy, with no extra headless log file. Bootstrap diagnostics use the CrossDesk logger; terminal log copies and direct third-party stdout/stderr output are silenced. Credential display goes directly to the terminal, not through the logger. Noninteractive output (services or redirection) hides the plaintext password. End-of-input does not terminate a background service.
The interactive console stays in the foreground regardless of the built-in daemon setting. Exit any older instance and start the new build to use these commands.
Create a separate virtual desktop
The standard Debian/Ubuntu package, crossdesk, does not depend on Xvfb or Xfce; reusing an existing desktop needs neither. For a complete independent desktop, choose crossdesk-virtual-desktop-xfce. It contains the same CrossDesk application and requires Xvfb, Xfce and D-Bus session tools through Depends, so APT installs them even with --no-install-recommends. These components come from the system repositories; the package is not a complete offline desktop environment.
Install only one package. Exit CrossDesk, use sudo apt install ./chosen-package.deb to upgrade or switch variants, then restart the app; user settings are preserved. Installation and switching do not start a virtual session, change the default desktop or remove previously installed Xfce components. Update downloads retain the installed package type. If its download is missing or incomplete, the app opens the Releases list instead of selecting another package type.
For a host without a desktop session, or to start an independent Xfce session (the virtual desktop package already supplies the dependencies; standard-package and source-build users install them as needed):
sudo apt install xvfb xfce4 dbus
crossdesk --headless-size 1920x1080 --headless-session startxfce4
The default size is 1920×1080; dimensions must be even, between 320 and 8192. --headless-session accepts an executable name or path and runs it under a private dbus-run-session. Use an executable script ending in exec if arguments are required.
For capture debugging, explicitly request a bare display:
sudo apt install xvfb
crossdesk --headless-session none
Bare Xvfb only provides a screen. It has no Dock, panel or existing application windows. Specifying only --headless-size also creates a bare display and records a diagnostic in the log. This explains a screen that shows CrossDesk against a black background.
Selection and limits
- Ordinary graphical launches retain the supplied X11 or Wayland session. X11 root capture works without active RandR outputs or a RandR extension.
--headless, or startup without an accessible X11 display or advertised Wayland session, automatically selects an existing desktop before falling back to Xvfb. Bare Xvfb fallback explicitly reports that it has no desktop environment or existing apps.--headless-displaycannot be combined with--headless-sizeor--headless-session.--no-headlessdisables automatic discovery/fallback;--headless-helpprints usage.- Applications are not migrated between sessions. Creating Xvfb cannot recover applications from an unavailable graphical session.
Run as a service
When creating a private display, the foreground supervisor owns Xvfb, the optional desktop session and CrossDesk. Application exit, SIGINT/SIGTERM/SIGHUP, or a monitored process exiting tears down that session's child processes and temporary authorization file. Xvfb allocates an unused display number, disables TCP listening and requires a random authentication cookie. The authority file is private to the current user. Startup diagnostic logs record DISPLAY and XAUTHORITY; use them from a terminal as the same user to launch additional applications on the virtual desktop.
Example ~/.config/systemd/user/crossdesk-headless.service (adjust the executable path):
[Unit]
Description=CrossDesk virtual desktop
[Service]
Type=simple
ExecStart=/usr/bin/crossdesk --headless-size 1920x1080 --headless-session startxfce4
Restart=on-failure
RestartSec=5
KillMode=mixed
TimeoutStopSec=15
[Install]
WantedBy=default.target
systemctl --user daemon-reload
systemctl --user enable --now crossdesk-headless.service
journalctl --user -u crossdesk-headless.service -f
To reuse an existing desktop instead, set ExecStart=/usr/bin/crossdesk; discovery and selection are automatic, but a graphical session must already be logged in. An administrator can enable a user service before login with sudo loginctl enable-linger USERNAME. The built-in daemon setting is bypassed when creating a private Xvfb; systemd can restart the whole session. Save work before stopping the service, which also closes applications on the virtual desktop.
Runtime limitations
The GUI uses software rendering and capture uses X11 → NV12. Video encoding follows the configured codec and available encoders. Audio requires an available user audio service; Xvfb does not provide a sound device. This implementation targets Linux. For Windows hosts without monitors, see the FAQ.