diff --git a/client/SDL/SDL3/sdl_monitor.cpp b/client/SDL/SDL3/sdl_monitor.cpp index 9b8b78031..689b3d266 100644 --- a/client/SDL/SDL3/sdl_monitor.cpp +++ b/client/SDL/SDL3/sdl_monitor.cpp @@ -193,13 +193,8 @@ int sdl_list_monitors([[maybe_unused]] SdlContext* sdl) WINPR_ASSERT(rect.w > 0); WINPR_ASSERT(rect.h > 0); - bool highDpi = dpi > 100; - - if (highDpi) + // always enumerate fullscreen modes since SDL_GetDisplayBounds might return logical coords { - // HighDPI is problematic with SDL: We can only get native resolution by creating a - // window. Work around this by checking the supported resolutions (and keep maximum) - // Also scale the DPI const SDL_Rect scaleRect = rect; int count = 0; auto modes = SDL_GetFullscreenDisplayModes(id, &count); @@ -234,8 +229,7 @@ int sdl_list_monitors([[maybe_unused]] SdlContext* sdl) const SDL_DisplayOrientation orientation = SDL_GetCurrentDisplayOrientation(id); const UINT32 rdp_orientation = sdl::utils::orientaion_to_rdp(orientation); - /* windows uses 96 dpi as 'default' and the scale factors are in percent. */ - const auto factor = dpi / 96.0f * 100.0f; + const auto factor = dpi * 100.0f; monitor.orig_screen = id; monitor.x = rect.x; monitor.y = rect.y; diff --git a/client/SDL/SDL3/sdl_window.cpp b/client/SDL/SDL3/sdl_window.cpp index 0bed3e3fe..c38778a31 100644 --- a/client/SDL/SDL3/sdl_window.cpp +++ b/client/SDL/SDL3/sdl_window.cpp @@ -17,6 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include #include #include @@ -27,12 +28,14 @@ SdlWindow::SdlWindow(SDL_DisplayID id, const std::string& title, const SDL_Rect& [[maybe_unused]] Uint32 flags) : _displayID(id) { + // since scale not known until surface is mapped, + // create 1×1 and sync to get scale, then resize to logical size auto props = SDL_CreateProperties(); SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, title.c_str()); SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, rect.x); SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, rect.y); - SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, rect.w); - SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, rect.h); + SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, 1); + SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, 1); if (flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIGH_PIXEL_DENSITY_BOOLEAN, true); @@ -46,13 +49,22 @@ SdlWindow::SdlWindow(SDL_DisplayID id, const std::string& title, const SDL_Rect& _window = SDL_CreateWindowWithProperties(props); SDL_DestroyProperties(props); - auto sc = scale(); - const int iscale = static_cast(sc * 100.0f); - auto w = 100 * rect.w / iscale; - auto h = 100 * rect.h / iscale; - std::ignore = resize({ w, h }); - SDL_SetHint(SDL_HINT_APP_NAME, ""); std::ignore = SDL_SyncWindow(_window); + + if (!(flags & SDL_WINDOW_FULLSCREEN)) + { + // windowed: convert physical pixels to logical coords + auto sc = scale(); + if (sc < 1.0f) + sc = 1.0f; + auto logicalW = static_cast(std::lroundf(static_cast(rect.w) / sc)); + auto logicalH = static_cast(std::lroundf(static_cast(rect.h) / sc)); + std::ignore = resize({ logicalW, logicalH }); + std::ignore = SDL_SyncWindow(_window); + } + // fullscreen: SDL sizes the window to the display automatically + + SDL_SetHint(SDL_HINT_APP_NAME, ""); } SdlWindow::SdlWindow(SdlWindow&& other) noexcept @@ -328,13 +340,18 @@ SdlWindow SdlWindow::create(SDL_DisplayID id, const std::string& title, Uint32 f { flags |= SDL_WINDOW_HIGH_PIXEL_DENSITY; + // width/height from caller is actual physical pixels SDL_Rect rect = { static_cast(SDL_WINDOWPOS_CENTERED_DISPLAY(id)), static_cast(SDL_WINDOWPOS_CENTERED_DISPLAY(id)), static_cast(width), static_cast(height) }; if ((flags & SDL_WINDOW_FULLSCREEN) != 0) { - std::ignore = SDL_GetDisplayBounds(id, &rect); + // only use display bounds for positioning, let SDL handle fullscreen size + SDL_Rect bounds = {}; + std::ignore = SDL_GetDisplayBounds(id, &bounds); + rect.x = bounds.x; + rect.y = bounds.y; } SdlWindow window{ id, title, rect, flags };