Display

August 29, 2026 ยท View on GitHub

This subsystem deals with the synchronization of the client's display and its configuration (ie: DPI, HDR, etc), in particular sending updated screen configuration whenever the number of monitors or their configuration changes.

The client may also apply scaling, which changes the display size exposed to the server.
This can be used to reduce the amount of pixels needed to cover a monitor.

ComponentLink
clientxpra.client.subsystem.display
client connectionxpra.server.source.display
serverxpra.server.subsystem.display
CapabilityValueInformation
desktop_sizewidth: int, height: intThe display size, covering all monitors
screen_sizeslist of screensGeometry of all screens, scaled
screen_sizes.unscaledlist of screensUnscaled geometry of all screens
monitorslist of monitorsGeometry of all monitors
dpidictionaryDPI configuration

Normally, every client that shares a session sees the same virtual display: its size is the largest width and height requested by any of them.

With --sharing=combine, the virtual display is instead made large enough to hold every client's monitors placed side by side, and each client is given its own area of it.

Each client is told that the display is exactly the size of its own area, and the server translates between the two coordinate spaces:

  • the positions the server sends to a client (window-create, window-move-resize, window-initiate-moveresize, pointer-position) have the origin of that client's area subtracted
  • the positions the client sends back are resolved from the monitor descriptor attached to its window-map, window-configure and pointer packets, which is offset by that same origin

This is why combine requires XPRA_BACKWARDS_COMPATIBLE=0: without those monitor relative coordinates, the absolute positions sent by two different clients would be indistinguishable and could not be mapped back onto the combined display. It also requires a seamless server whose virtual display can be re-configured with RandR 1.6 (the dummy driver with 16 outputs). When any of those requirements is not met, the server warns and shares the display as it would with sharing=yes.

Every window is still sent to every client, so that moving one from one user's screen to the next is just a metadata update rather than a new window: see window for how the windows outside a client's area are hidden.

Note that each user can only move a window within their own screen, which covers their own area of the display: a window can straddle the boundary between two areas (and is then shown by both clients), but pushing it all the way onto another client's area requires the application itself to move it, or a window manager request.

Packet TypeDirectionArgumentsInformation
display-show-desktopserver to clientshow : booleanThe server is requesting the client to show or hide the desktop
display-resizedserver to clientwidth: int, height: int, max_w: int, max_h: intThe server has updated its display, the client may need to adjust its scaling properties
display-configureclient to servermonitor configuration dictionaryThe client sends its updated monitor layout to the server
display-request-screenshotclient to serverThe client requests a screenshot from the server
display-screenshotserver to clientw, h, encoding, rowstride, dataThe server sends a screenshot in response to display-request-screenshot
display-request-iconclient to serverThe client requests the session icon
display-iconserver to clientw, h, encoding, rowstride, dataThe server sends the session icon