Dear Maintainer,
On sway, sdl-freerdp3 cannot start a fullscreen (/f) or /multimon session.
It aborts in pre-connect, before any network traffic:
$ sdl-freerdp3 /cert:ignore /f /v:127.0.0.1:9 /u:x /p:x
[INFO][com.freerdp.client.SDL] - [preConnect]: Update size to 64x64
[ERROR][com.freerdp.settings] - [freerdp_settings_client_monitors_check_primary_and_origin]: Monitor configuration virtual desktop width must be 200 <= 64 <= 32766
[ERROR][com.freerdp.settings] - [freerdp_settings_client_monitors_check_primary_and_origin]: Monitor configuration virtual desktop height must be 200 <= 64 <= 32766
[ERROR][com.freerdp.settings] - [log_monitor]: [0] [primary] {0x0-64x64} [3] {64x64, orientation: ORIENTATION_LANDSCAPE [0], desktopScale: 100, deviceScale: 100}
[ERROR][com.freerdp.core] - [freerdp_connect_begin]: ERRCONNECT_PRE_CONNECT_FAILED [0x00020001]
A configuration error prevented a connection to be established.
(Any target works, because the failure comes before connecting. The output is
a single 1920x1080 sway output, and XDG_SESSION_DESKTOP=XDG_CURRENT_DESKTOP=sway.)
Windowed sessions (/size:WxH) work. SDL_VIDEODRIVER=x11 (XWayland) also fails
in the same way, reporting 75x64.
Analysis
--------
SdlContext::addOrUpdateDisplay() calls SdlWindow::query(id), which creates
a 64x64 probe window in createDummy(), calls SDL_SetWindowFullscreen(true),
and reads its size back. SdlWindow::rect() contains a workaround for exactly
this wlroots behaviour (the probe keeps its 64x64 creation size, so it falls
back to SDL_GetDisplayBounds()), but the workaround is gated by
const auto fs = (flags & SDL_WINDOW_FULLSCREEN) == SDL_WINDOW_FULLSCREEN;
if (tryFallback(fs))
and on sway the probe window never reports SDL_WINDOW_FULLSCREEN. Because of
that, tryFallback() returns false in the default auto-detect mode and with
FREERDP_WLROOTS_HACK=1. Only FREERDP_WLROOTS_HACK=force, which overrides
isFullscreen, makes it work:
default -> Update size to 64x64 -> PRE_CONNECT_FAILED
FREERDP_WLROOTS_HACK=1 -> Update size to 64x64 -> PRE_CONNECT_FAILED
FREERDP_WLROOTS_HACK=force -> Update size to 1920x1080, connects
Upstream has the same root cause in
https://github.com/FreeRDP/FreeRDP/issues/13275 (reported for /multimon on
Hyprland, 3.30.0). That issue was closed with "use FREERDP_WLROOTS_HACK=force".
The code is unchanged in current upstream master.
Fix
---
The attached patch passes an "isProbe" flag from the two probe paths
(SdlWindow::query(SDL_DisplayID) and SdlWindow::rect(SDL_DisplayID)) into
SdlWindow::rect(SDL_Window*), which then treats the probe as fullscreen, since
that is what createDummy() requested. Real session windows
(SdlWindow::rect() const) still use the actual window flags, so windowed
sessions are unaffected. The fallback is still limited to detected wlroots
sessions under the Wayland driver, and FREERDP_WLROOTS_HACK=0 still turns it
off.
I built 3.32.2+dfsg-1 with the patch and tested it on sway 1.12 /
libsdl3-0 3.4.18:
/f -> Update size to 1920x1080, reaches connect
/f, FREERDP_WLROOTS_HACK=0 -> 64x64 / PRE_CONNECT_FAILED (opt-out honoured)
/size:1280x720 -> reaches connect (unchanged)
/multimon -> reaches connect
Workaround until fixed: export FREERDP_WLROOTS_HACK=force, or use /size:WxH
instead of /f.
--- a/client/SDL/SDL3/sdl_window.cpp 2026-10-12 13:45:30.000000000 +0200
+++ b/client/SDL/SDL3/sdl_window.cpp 2026-11-02 13:35:48.739790742 +0100
@@ -394,12 +394,13 @@
return SDL_FillSurfaceRect(surface, &rect, color);
}