AnotherOS

Documentation

Remote control

A VNC server built into the compositor — see and drive the live desktop over the network.

AnotherOS ships a VNC server inside the compositor itself. Point any standard VNC client at the machine and you both see and control the live desktop.

vncviewer <address-of-the-machine>:5900

It listens on TCP 5900 and speaks RFB 3.8.

Read this before putting a machine on a network

The server is on by default and, out of the box, requires no password.

That is a deliberate choice — a freshly booted machine is reachable without having to configure it first, which is exactly what you want on a workbench. It is exactly what you do not want on a network you do not control.

Set a password before connecting such a machine to anything shared. With one set, the server switches to VNC's challenge/response authentication and refuses a client that cannot answer it.

Note what that authentication is: it is the classic VNC scheme, which is weak by modern standards and protects the session, not the traffic. Treat VNC here as something to run on a trusted network or through a tunnel, not as something to expose to the internet.

What you get

The framebuffer is the composited desktop exactly as it appears on the panel: the wallpaper, the menu bar, every window.

Control works. Pointer and keyboard from the client drive the desktop — moving, clicking, dragging a window by its title bar, opening menus and the dock, scrolling and typing. Injected input runs the same code path as a real mouse or keyboard, so a remote click and a local click are indistinguishable to the compositor, and nothing behaves differently over VNC.

Configuration

Settings live in remote.conf in the compositor's configuration directory. They are read once, at startup — editing the file does not affect a running session, so restart the session or the machine after changing it.

vnc_enable   = on        # default on
vnc_port     = 5900
vnc_max_kbps = 0         # 0 = unlimited (the default)
vnc_password =           # empty means no authentication
ssh_enable   = on
ssh_port     = 22

On a live or read-only boot this file is on the RAM overlay and reverts on reboot. On an installed system it persists.

For a one-off boot, the kernel command line can inject the same settings into the session, which is the recovery path when a machine is only reachable remotely:

Variable Effect
FZ_VNC=0 / FZ_VNC=1 Force the server off or on for this boot.
FZ_VNC_PASSWORD=<pw> Require this password.
FZ_VNC_PORT=<n> Listen elsewhere.
FZ_VNC_MAX_KBPS=<n> Bandwidth ceiling in kbit/s; 0 is unlimited.

What it prints

Every step is announced on the session's output, which is how a machine with no screen can be diagnosed:

vnc: server listening on port 5900 (auth=none, max=0 kbit/s — UNLIMITED)
vnc: client connected fd=7 slot=0
vnc: client 0 init 1024x768 shared=1
vnc: framebuffer update client=0 1024x768+0+0 enc=raw rects=1 bytes=3145728

rects is how many rectangles the update carried and bytes how many went on the wire. On a mostly static desktop an incremental update should be a few kilobytes, not a full frame — so those two numbers are the first thing to look at when a remote session feels slow.

A disabled server says vnc: server disabled and binds nothing.

How it stays out of the way

The server owns a dedicated thread for the listening socket and every client, so it can neither stall the render loop nor be stalled by it.

The framebuffer is served from a shadow copy of the compositor's back buffer, never the live one. The copy happens the instant a frame is presented — the one moment the back buffer is stable — so there is no tearing against the compositor's writes and no new lock on the paint path. With no client connected the whole mechanism is one atomic load and a return.

Only the pixels that actually changed are sent. The compositor reports damage as a single bounding box, and a full-scene repaint — a clock tick, a focus change, a menu opening — makes that box the whole screen. The server keeps a copy of what each client already holds, walks the damage box in tiles, and sends only the tiles that differ, coalescing runs across a tile row into one rectangle.

Measured on a 1366×768 desktop: a clock tick on an otherwise static screen changed one tile out of 528, taking the update from about 4.2 MB to about 8 KB.

The bandwidth ceiling, and why it is off

vnc_max_kbps charges each update against a per-client budget and delays the next one until the budget allows. It is off by default, and that default is a correction rather than an oversight.

A ceiling costs latency, and latency is what a person actually sees. A full uncompressed frame here is about 4.2 MB, so at 8000 kbit/s a client can be served only about once every 4.6 seconds. Measured with three back-to-back full frames: 0.39 / 4.59 / 4.60 s with the ceiling, and 0.41 / 0.40 / 0.40 s without it. Under sustained change the view is then always several seconds behind — you load one page, then another, and are still being shown the first.

The sender already coalesces: there is one pending damage region per client and its pixels are read at send time, so a client that falls behind skips forward rather than replaying.

A ceiling belongs here again once updates are cheap enough that it does not bind — that means a compressed encoding, not a better constant. Set vnc_max_kbps to restore one meanwhile.

Known limitations

  • The encoding is still Raw. The tile diff removes redundant pixels, but a genuinely animating full screen is inherently expensive. A compressed encoding is the next step and would raise the usable frame rate.
  • No desktop-resize pseudo-encoding yet. Changing the screen resolution mid-session forces full frames and may need the client to reconnect.
  • A port change takes effect when the listener is rebound, which in practice means a restart.