Skip to content

ExtendedDesktopSize advertised with screen id 0 breaks client-initiated resize (Guacamole/guacd) #172

Description

@ThilinaTLM

Summary

neatvnc advertises its ExtendedDesktopSize screen with id = 0. libvncclient (LibVNCServer) explicitly treats a screen with id == 0 as invalid and never stores it into client->screen. As a result, any libvncclient-based client cannot perform a client-initiated desktop resize against neatvnc/wayvnc.

The most visible victim is Apache Guacamole / guacd (which added VNC auto-resize in 1.6.0, GUACAMOLE-1196): the browser desktop never resizes to the viewport. guacd logs Screen data has not been initialized and Failed to send desktop size message on every resize attempt.

Root cause

In src/server.c, send_extended_desktop_size_rect() builds the screen entry without setting id, so it defaults to 0:

struct rfb_screen screen = {
    .width = htons(width),
    .height = htons(height),
};

On the client side, libvncclient's ExtendedDesktopSize handler (libvncclient/rfbproto.c) only records the screen when id != 0:

if (screen.id != 0 && screen.width && screen.height) {
    client->screen = screen;
} else {
    invalidScreen = TRUE;   /* id == 0 is discarded */
}

Because the advertised id is 0, client->screen.width/height stay 0. guacd then refuses to send a SetDesktopSize, guarded by:

/* guacamole-server: src/protocols/vnc/display.c */
if (client->screen.width == 0 || client->screen.height == 0) {
    guac_client_log(gc, GUAC_LOG_DEBUG, "Screen data has not been initialized, yet.");
    return FALSE;
}

So the negotiation looks healthy (the client advertises extended-desktop-size, neatvnc sends the resize rect), but the resize round-trip can never start.

Reproduction

  1. Run wayvnc on a headless Sway output.
  2. Connect through Guacamole/guacd 1.6.0 (VNC, disable-display-resize unset/false).
  3. Resize the browser window → desktop stays at its initial size (letter-/pillar-boxed).
  4. guacd trace shows repeated Setting VNC display size.Failed to send desktop size message. and Screen data has not been initialized.

Confirmed via wayvnc debug logs: Client set encodings: ...,extended-desktop-size,... and Sending extended desktop resize rect: 1920x1080, but no client-initiated resize ever follows.

Proposed fix

Advertise a non-zero screen id. id 1 works well in practice — it is what guacd uses for its own resize message (GUAC_VNC_SCREEN_ID = 1), so the subsequent SetDesktopSize is accepted by check_desktop_layout() for the single-output case:

 	struct rfb_screen screen = {
+		.id = htonl(1),
 		.width = htons(width),
 		.height = htons(height),
 	};

With this one-line change, Guacamole/guacd resizes the wayvnc desktop to match the browser viewport on connect and on every window resize.

(Arguably libvncclient's id != 0 requirement is also overly strict, but advertising a non-zero id is the simplest interoperable fix and is harmless to spec-compliant clients.)

Environment

  • neatvnc 0.9.5, wayvnc 0.9.1, Sway 1.12 (wlroots headless backend)
  • guacd / guacamole-server 1.6.0 (bundled libvncclient 0.9.15)
  • Arch Linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions