From 3cb88eefd644da1bb00480b44c0b3aa9d5e61473 Mon Sep 17 00:00:00 2001 From: akallabeth Date: Fri, 30 Jan 2026 11:03:40 +0100 Subject: [PATCH] [client,sdl] detect displays on startup before RDP do a simple display query on main SDL thread before starting RDP. This way the required rdpMonitor details are already available when the monitor layout or desktop resolution must be sent to the server --- client/SDL/SDL3/sdl_freerdp.cpp | 16 +++++---- client/SDL/SDL3/sdl_monitor.cpp | 60 ++++----------------------------- 2 files changed, 15 insertions(+), 61 deletions(-) diff --git a/client/SDL/SDL3/sdl_freerdp.cpp b/client/SDL/SDL3/sdl_freerdp.cpp index ef761324a..5bab3abd7 100644 --- a/client/SDL/SDL3/sdl_freerdp.cpp +++ b/client/SDL/SDL3/sdl_freerdp.cpp @@ -605,6 +605,13 @@ int main(int argc, char* argv[]) if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS)) return -1; + SDL_SetHint(SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED, "0"); + SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0"); + SDL_SetHint(SDL_HINT_PEN_MOUSE_EVENTS, "0"); + SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0"); + SDL_SetHint(SDL_HINT_PEN_TOUCH_EVENTS, "1"); + SDL_SetHint(SDL_HINT_TRACKPAD_IS_TOUCH_ONLY, "1"); + /* Redirect SDL log messages to wLog */ SDL_SetLogOutputFunction(winpr_LogOutputFunction, sdl); auto level = WLog_GetLogLevel(sdl->getWLog()); @@ -614,13 +621,6 @@ int main(int argc, char* argv[]) WLog_Print(sdl->getWLog(), WLOG_DEBUG, "client is using backend '%s'", backend); sdl_dialogs_init(); - SDL_SetHint(SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED, "0"); - SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0"); - SDL_SetHint(SDL_HINT_PEN_MOUSE_EVENTS, "0"); - SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0"); - SDL_SetHint(SDL_HINT_PEN_TOUCH_EVENTS, "1"); - SDL_SetHint(SDL_HINT_TRACKPAD_IS_TOUCH_ONLY, "1"); - /* SDL cleanup code if the client exits */ ScopeGuard guard( [&]() @@ -630,6 +630,8 @@ int main(int argc, char* argv[]) sdl_dialogs_uninit(); SDL_Quit(); }); + if (!sdl->detectDisplays()) + return -1; /* Initialize RDP */ auto context = sdl->context(); diff --git a/client/SDL/SDL3/sdl_monitor.cpp b/client/SDL/SDL3/sdl_monitor.cpp index 7fbab74e1..4664fb4f6 100644 --- a/client/SDL/SDL3/sdl_monitor.cpp +++ b/client/SDL/SDL3/sdl_monitor.cpp @@ -179,42 +179,6 @@ int sdl_list_monitors([[maybe_unused]] SdlContext* sdl) return static_cast(sval); } -[[nodiscard]] static BOOL sdl_apply_monitor_properties(rdpMonitor& monitor, SDL_DisplayID id, - bool isPrimary) -{ - auto mode = SDL_GetCurrentDisplayMode(id); - if (!mode) - return FALSE; - - const float dpi = roundf(mode->pixel_density * 100.0f); - const float factor = mode->pixel_density; - SDL_Rect rect = {}; - - if (!SDL_GetDisplayBounds(id, &rect)) - return FALSE; - - WINPR_ASSERT(rect.w > 0); - WINPR_ASSERT(rect.h > 0); - - bool highDpi = dpi > 100; - - const SDL_DisplayOrientation orientation = SDL_GetCurrentDisplayOrientation(id); - const UINT32 rdp_orientation = sdl::utils::orientaion_to_rdp(orientation); - - monitor.orig_screen = id; - monitor.x = rect.x; - monitor.y = rect.y; - monitor.width = roundf(rect.w * factor); - monitor.height = roundf(rect.h * factor); - monitor.is_primary = isPrimary; - monitor.attributes.desktopScaleFactor = static_cast(dpi); - monitor.attributes.deviceScaleFactor = 100; - monitor.attributes.orientation = rdp_orientation; - monitor.attributes.physicalWidth = WINPR_ASSERTING_INT_CAST(uint32_t, rect.w); - monitor.attributes.physicalHeight = WINPR_ASSERTING_INT_CAST(uint32_t, rect.h); - return TRUE; -} - [[nodiscard]] static BOOL sdl_apply_display_properties(SdlContext* sdl) { WINPR_ASSERT(sdl); @@ -231,9 +195,10 @@ int sdl_list_monitors([[maybe_unused]] SdlContext* sdl) if (sdl->monitorIds().empty()) return FALSE; const auto id = sdl->monitorIds().front(); - rdpMonitor monitor = {}; - if (!sdl_apply_monitor_properties(monitor, id, TRUE)) - return FALSE; + auto monitor = sdl->getDisplay(id); + monitor.is_primary = true; + monitor.x = 0; + monitor.y = 0; monitors.emplace_back(monitor); return freerdp_settings_set_monitor_def_array_sorted(settings, monitors.data(), monitors.size()); @@ -242,10 +207,7 @@ int sdl_list_monitors([[maybe_unused]] SdlContext* sdl) } for (const auto& id : sdl->monitorIds()) { - rdpMonitor monitor = {}; - const auto primary = SDL_GetPrimaryDisplay(); - if (!sdl_apply_monitor_properties(monitor, id, id == primary)) - return FALSE; + const auto monitor = sdl->getDisplay(id); monitors.emplace_back(monitor); } return freerdp_settings_set_monitor_def_array_sorted(settings, monitors.data(), @@ -297,17 +259,7 @@ BOOL sdl_detect_monitors(SdlContext* sdl, UINT32* pMaxWidth, UINT32* pMaxHeight) rdpSettings* settings = sdl->context()->settings; WINPR_ASSERT(settings); - std::vector ids; - { - int numDisplays = 0; - auto sids = SDL_GetDisplays(&numDisplays); - if (sids && (numDisplays > 0)) - ids = std::vector(sids, sids + numDisplays); - SDL_free(sids); - if (numDisplays < 0) - return FALSE; - } - + const auto& ids = sdl->getDisplayIds(); auto nr = freerdp_settings_get_uint32(settings, FreeRDP_NumMonitorIds); if (nr == 0) {