You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
RDP: strip of bare page on the right when Windows rounds the width down (GFX off) #251
An RDP session that should fill the browser window leaves a strip of bare page down the right-hand edge, about the width of a scrollbar. Seen in Safari fullscreen on a 1710x1112 MacBook display, but it is not browser specific.
The client asks for 1710x960. Windows honours the height but rounds the width down to a multiple of 16 when the session runs without the Graphics Pipeline (the entry has GFX off, which is rustguac's default), so the framebuffer comes back 1696 wide. scaleDisplay() in client.html then fits with a uniform min(availW / dw, availH / dh): the height already matches, the scale stays at 1, and the missing 14px shows as a strip. guacd's own rounding is only to a multiple of 4 on the initial connect and to even widths on resize (guac_rdp_disp_set_size), so the rest is the server's doing.
Turning GFX on for the entry avoids it, since RDPGFX accepts any even width, but the client should not show a strip over a 0.8% shortfall whatever the server does.
Fix
In scaleDisplay(), after the uniform fit, stretch the display element by the remaining fraction on each axis when that fraction is at most 2.5%, and divide the same factors out of pointer coordinates before sendMouseState. A gap bigger than that is a real aspect mismatch (fixed-resolution server, no resize support) and keeps the letterbox as today. Multi-monitor pop-outs are untouched.
The rounding is coming from rustguac's own guacd, not from Windows. patches/007-rdp-disp-mod16.patch changes guac_rdp_disp_set_size to round both dimensions down to a multiple of 16 (stock guacamole-server rounds to even, which is probably the source being read here). 1710x960 → 1696x960 is exactly that: 960 is already a multiple of 16, and 1710 isn't. Turning GFX on shouldn't avoid it either, since resizes go through the display channel with or without GFX. If you're seeing a difference with GFX on, I'd be curious what guacd logs for the requested size.
I added that patch deliberately. When the negotiated size isn't mod-16, the H.264 encoder pads to whole macroblocks, the padding contaminates the bottom chroma row, and once that is scaled it shows as a saturated green band along the edge. The patch comment already names the cost: "up to 15px of unused canvas margin". This issue is that cost made visible, so please don't take it as a reason to relax the rounding. The green band is the worse of the two.
On the proposed fix: because every RDP session whose window isn't mod-16 will have up to 15px of margin, a ≤2.5% stretch would apply to almost every RDP session, not an edge case. A non-integer CSS scale resamples the whole picture, which softens single-pixel text across the entire screen. It also breaks pixel-exact rendering when the framebuffer is requested at device pixels on HiDPI displays (1 framebuffer pixel per physical pixel), where even a small stretch is measurably soft. Trading a 14px strip for blur everywhere seems like the wrong trade.
Two alternatives that keep it sharp:
Centre the framebuffer and give the margin the display's background colour (7px a side on dark rather than 14px of bare page on one side), or
Only apply the fill when the display is already being resampled (display.getScale() * devicePixelRatio !== 1), so it never costs sharpness on a pixel-exact session.
The pointer maths in the current patch is right, by the way: Guacamole.Position uses offsetLeft, which ignores transforms, so dividing out fillX/fillY is correct.
Activity
client: fill a small framebuffer shortfall instead of leaving a strip
pletch commentedon Oct 11, 2026
The rounding is coming from rustguac's own guacd, not from Windows.
patches/007-rdp-disp-mod16.patchchangesguac_rdp_disp_set_sizeto round both dimensions down to a multiple of 16 (stock guacamole-server rounds to even, which is probably the source being read here). 1710x960 → 1696x960 is exactly that: 960 is already a multiple of 16, and 1710 isn't. Turning GFX on shouldn't avoid it either, since resizes go through the display channel with or without GFX. If you're seeing a difference with GFX on, I'd be curious what guacd logs for the requested size.I added that patch deliberately. When the negotiated size isn't mod-16, the H.264 encoder pads to whole macroblocks, the padding contaminates the bottom chroma row, and once that is scaled it shows as a saturated green band along the edge. The patch comment already names the cost: "up to 15px of unused canvas margin". This issue is that cost made visible, so please don't take it as a reason to relax the rounding. The green band is the worse of the two.
On the proposed fix: because every RDP session whose window isn't mod-16 will have up to 15px of margin, a ≤2.5% stretch would apply to almost every RDP session, not an edge case. A non-integer CSS scale resamples the whole picture, which softens single-pixel text across the entire screen. It also breaks pixel-exact rendering when the framebuffer is requested at device pixels on HiDPI displays (1 framebuffer pixel per physical pixel), where even a small stretch is measurably soft. Trading a 14px strip for blur everywhere seems like the wrong trade.
Two alternatives that keep it sharp:
display.getScale() * devicePixelRatio !== 1), so it never costs sharpness on a pixel-exact session.The pointer maths in the current patch is right, by the way:
Guacamole.PositionusesoffsetLeft, which ignores transforms, so dividing outfillX/fillYis correct.connect: fix framed session (black screen), reuse, sharp RDP fit, titles
client: fill a small framebuffer shortfall instead of leaving a strip
client: keep a pixel-exact RDP picture crisp and centre the mod-16 ma…
tests: pin the framebuffer fit rules from sol1#251
client: fill a small framebuffer shortfall instead of leaving a strip
client: keep a pixel-exact RDP picture crisp and centre the mod-16 ma…
tests: pin the framebuffer fit rules from sol1#251
tests: pin the framebuffer fit rules from #251
client: name the real cause of the RDP mod-16 margin
ci: run the plain-node client tests
client: fill a small framebuffer shortfall instead of leaving a strip
client: keep a pixel-exact RDP picture crisp and centre the mod-16 ma…