From a12f14afb6e534e7e48235501a6ad9a4bb3c231a Mon Sep 17 00:00:00 2001 From: akallabeth Date: Mon, 5 May 2025 14:35:35 +0200 Subject: [PATCH] [client,sdl] fix dpi scaling for dialogs * Unify SDL_CreateWindowAndRenderer calls * remove SDL_WINDOW_HIGH_PIXEL_DENSITY flag --- client/SDL/SDL3/dialogs/CMakeLists.txt | 2 ++ .../SDL3/dialogs/sdl_connection_dialog.cpp | 23 ++++-------- .../SDL3/dialogs/sdl_connection_dialog.hpp | 8 ++--- client/SDL/SDL3/dialogs/sdl_input_widgets.cpp | 36 ++++++++++++------- client/SDL/SDL3/dialogs/sdl_input_widgets.hpp | 25 ++++++++++--- client/SDL/SDL3/dialogs/sdl_selectlist.cpp | 18 ++-------- client/SDL/SDL3/dialogs/sdl_selectlist.hpp | 6 ++-- client/SDL/SDL3/dialogs/sdl_widget.cpp | 17 ++++++++- client/SDL/SDL3/dialogs/sdl_widget.hpp | 9 +++-- client/SDL/SDL3/dialogs/sdl_widget_list.cpp | 18 ++++++++++ client/SDL/SDL3/dialogs/sdl_widget_list.hpp | 26 ++++++++++++++ 11 files changed, 127 insertions(+), 61 deletions(-) create mode 100644 client/SDL/SDL3/dialogs/sdl_widget_list.cpp create mode 100644 client/SDL/SDL3/dialogs/sdl_widget_list.hpp diff --git a/client/SDL/SDL3/dialogs/CMakeLists.txt b/client/SDL/SDL3/dialogs/CMakeLists.txt index 4d47fc5ef..a24438f0e 100644 --- a/client/SDL/SDL3/dialogs/CMakeLists.txt +++ b/client/SDL/SDL3/dialogs/CMakeLists.txt @@ -24,6 +24,8 @@ set(SRCS sdl_dialogs.hpp sdl_widget.hpp sdl_widget.cpp + sdl_widget_list.hpp + sdl_widget_list.cpp sdl_input.hpp sdl_input.cpp sdl_input_widgets.cpp diff --git a/client/SDL/SDL3/dialogs/sdl_connection_dialog.cpp b/client/SDL/SDL3/dialogs/sdl_connection_dialog.cpp index cf7cbd704..2c24793a4 100644 --- a/client/SDL/SDL3/dialogs/sdl_connection_dialog.cpp +++ b/client/SDL/SDL3/dialogs/sdl_connection_dialog.cpp @@ -333,24 +333,13 @@ bool SDLConnectionDialog::createWindow() { destroyWindow(); - const int widget_height = 50; - const int widget_width = 600; - const int total_height = 300; + const size_t widget_height = 50; + const size_t widget_width = 600; + const size_t total_height = 300; - SDL_Renderer* renderer = nullptr; - SDL_Window* window = nullptr; - auto rc = SDL_CreateWindowAndRenderer(_title.c_str(), widget_width, total_height, - SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_MOUSE_FOCUS | - SDL_WINDOW_INPUT_FOCUS, - &window, &renderer); - _renderer = std::shared_ptr(renderer, SDL_DestroyRenderer); - _window = std::shared_ptr(window, SDL_DestroyWindow); - - if (rc != 0) - { - widget_log_error(rc, "SDL_CreateWindowAndRenderer"); + if (!reset(_title, widget_width, widget_height)) return false; - } + setModal(); SDL_Color res_bgcolor; @@ -390,7 +379,7 @@ bool SDLConnectionDialog::createWindow() break; } - int height = (total_height - 3ul * vpadding) / 2ul; + const auto height = (total_height - 3ul * vpadding) / 2ul; SDL_FRect iconRect{ hpadding, vpadding, widget_width / 4ul - 2ul * hpadding, static_cast(height) }; widget_cfg_t icon{ textcolor, diff --git a/client/SDL/SDL3/dialogs/sdl_connection_dialog.hpp b/client/SDL/SDL3/dialogs/sdl_connection_dialog.hpp index 3099af4cd..f5529c880 100644 --- a/client/SDL/SDL3/dialogs/sdl_connection_dialog.hpp +++ b/client/SDL/SDL3/dialogs/sdl_connection_dialog.hpp @@ -28,11 +28,12 @@ #include +#include "sdl_widget_list.hpp" #include "sdl_widget.hpp" #include "sdl_buttons.hpp" #include "sdl_connection_dialog_wrapper.hpp" -class SDLConnectionDialog +class SDLConnectionDialog : public SdlWidgetList { public: explicit SDLConnectionDialog(rdpContext* context); @@ -87,8 +88,6 @@ class SDLConnectionDialog }; rdpContext* _context = nullptr; - std::shared_ptr _window = nullptr; - std::shared_ptr _renderer = nullptr; mutable std::mutex _mux; std::string _title; std::string _msg; @@ -96,8 +95,7 @@ class SDLConnectionDialog SdlConnectionDialogWrapper::MsgType _type_active = SdlConnectionDialogWrapper::MSG_NONE; SDL_TimerID _timer = 0; bool _running = false; - std::vector _list; - SdlButtonList _buttons; + std::vector _list{}; }; class SDLConnectionDialogHider diff --git a/client/SDL/SDL3/dialogs/sdl_input_widgets.cpp b/client/SDL/SDL3/dialogs/sdl_input_widgets.cpp index 07f5a4312..5e906193e 100644 --- a/client/SDL/SDL3/dialogs/sdl_input_widgets.cpp +++ b/client/SDL/SDL3/dialogs/sdl_input_widgets.cpp @@ -1,8 +1,28 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * SDL Client helper dialogs + * + * Copyright 2025 Armin Novak + * Copyright 2025 Thincast Technologies GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include #include #include +#include "sdl_widget_list.hpp" #include "sdl_input_widgets.hpp" static const Uint32 vpadding = 5; @@ -11,7 +31,6 @@ SdlInputWidgetList::SdlInputWidgetList(const std::string& title, const std::vector& labels, const std::vector& initial, const std::vector& flags) - : _window(nullptr), _renderer(nullptr) { assert(labels.size() == initial.size()); assert(labels.size() == flags.size()); @@ -26,17 +45,8 @@ SdlInputWidgetList::SdlInputWidgetList(const std::string& title, const size_t total_height = input_height + widget_heigth; assert(total_width <= INT32_MAX); assert(total_height <= INT32_MAX); - SDL_Renderer* renderer = nullptr; - SDL_Window* window = nullptr; - auto rc = SDL_CreateWindowAndRenderer( - title.c_str(), total_width, static_cast(total_height), - SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_INPUT_FOCUS, &window, - &renderer); - _renderer = std::shared_ptr(renderer, SDL_DestroyRenderer); - _window = std::shared_ptr(window, SDL_DestroyWindow); - if (!rc) - widget_log_error(rc, "SDL_CreateWindowAndRenderer"); - else + + if (reset(title, total_width, total_height)) { for (size_t x = 0; x < labels.size(); x++) { @@ -148,7 +158,7 @@ int SdlInputWidgetList::run(std::vector& result) bool running = true; while (running) { - if (!clear_window(_renderer)) + if (!SdlWidget::clear_window(_renderer)) throw; if (!update(_renderer)) diff --git a/client/SDL/SDL3/dialogs/sdl_input_widgets.hpp b/client/SDL/SDL3/dialogs/sdl_input_widgets.hpp index 3ae66b6e8..0f3680d08 100644 --- a/client/SDL/SDL3/dialogs/sdl_input_widgets.hpp +++ b/client/SDL/SDL3/dialogs/sdl_input_widgets.hpp @@ -1,13 +1,33 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * SDL Client helper dialogs + * + * Copyright 2025 Armin Novak + * Copyright 2025 Thincast Technologies GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #pragma once #include #include #include +#include "sdl_widget_list.hpp" #include "sdl_input.hpp" #include "sdl_buttons.hpp" -class SdlInputWidgetList +class SdlInputWidgetList : public SdlWidgetList { public: SdlInputWidgetList(const std::string& title, const std::vector& labels, @@ -37,8 +57,5 @@ class SdlInputWidgetList [[nodiscard]] bool valid(ssize_t current) const; std::shared_ptr get(ssize_t index); - std::shared_ptr _window; - std::shared_ptr _renderer; std::vector> _list; - SdlButtonList _buttons; }; diff --git a/client/SDL/SDL3/dialogs/sdl_selectlist.cpp b/client/SDL/SDL3/dialogs/sdl_selectlist.cpp index 2f4132d06..7d91b81b5 100644 --- a/client/SDL/SDL3/dialogs/sdl_selectlist.cpp +++ b/client/SDL/SDL3/dialogs/sdl_selectlist.cpp @@ -1,30 +1,18 @@ #include #include #include "sdl_selectlist.hpp" +#include "../sdl_utils.hpp" static const Uint32 vpadding = 5; SdlSelectList::SdlSelectList(const std::string& title, const std::vector& labels) - : _window(nullptr), _renderer(nullptr) { const size_t widget_height = 50; const size_t widget_width = 600; const size_t total_height = labels.size() * (widget_height + vpadding) + vpadding; const size_t height = total_height + widget_height; - static_assert(widget_width <= INT32_MAX); - assert(height <= INT32_MAX); - SDL_Renderer* renderer = nullptr; - SDL_Window* window = nullptr; - auto rc = SDL_CreateWindowAndRenderer( - title.c_str(), static_cast(widget_width), static_cast(height), - SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_INPUT_FOCUS, &window, - &renderer); - _renderer = std::shared_ptr(renderer, SDL_DestroyRenderer); - _window = std::shared_ptr(window, SDL_DestroyWindow); - if (rc != 0) - widget_log_error(rc, "SDL_CreateWindowAndRenderer"); - else + if (reset(title, widget_width, height)) { SDL_FRect rect = { 0, 0, widget_width, widget_height }; for (auto& label : labels) @@ -60,7 +48,7 @@ int SdlSelectList::run() { while (running) { - if (!clear_window(_renderer)) + if (!SdlWidget::clear_window(_renderer)) throw; if (!update_text()) diff --git a/client/SDL/SDL3/dialogs/sdl_selectlist.hpp b/client/SDL/SDL3/dialogs/sdl_selectlist.hpp index 95133a20c..3dafbb795 100644 --- a/client/SDL/SDL3/dialogs/sdl_selectlist.hpp +++ b/client/SDL/SDL3/dialogs/sdl_selectlist.hpp @@ -5,11 +5,12 @@ #include +#include "sdl_widget_list.hpp" #include "sdl_select.hpp" #include "sdl_button.hpp" #include "sdl_buttons.hpp" -class SdlSelectList +class SdlSelectList : public SdlWidgetList { public: SdlSelectList(const std::string& title, const std::vector& labels); @@ -34,8 +35,5 @@ class SdlSelectList void reset_mouseover(); void reset_highlight(); - std::shared_ptr _window; - std::shared_ptr _renderer; std::vector _list; - SdlButtonList _buttons; }; diff --git a/client/SDL/SDL3/dialogs/sdl_widget.cpp b/client/SDL/SDL3/dialogs/sdl_widget.cpp index 20a35365e..2d5f17fbc 100644 --- a/client/SDL/SDL3/dialogs/sdl_widget.cpp +++ b/client/SDL/SDL3/dialogs/sdl_widget.cpp @@ -218,6 +218,21 @@ bool SdlWidget::error_ex(bool success, const char* what, const char* file, size_ return sdl_log_error_ex(-1, log, what, file, line, fkt); } +bool SdlWidget::createWindowAndRenderer(const std::string& title, size_t width, size_t height, + std::shared_ptr& _window, + std::shared_ptr& _renderer) +{ + auto w = WINPR_ASSERTING_INT_CAST(int, width); + auto h = WINPR_ASSERTING_INT_CAST(int, height); + SDL_Renderer* renderer = nullptr; + SDL_Window* window = nullptr; + auto rc = SDL_CreateWindowAndRenderer( + title.c_str(), w, h, SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_INPUT_FOCUS, &window, &renderer); + _renderer = std::shared_ptr(renderer, SDL_DestroyRenderer); + _window = std::shared_ptr(window, SDL_DestroyWindow); + return rc; +} + static bool draw_rect(std::shared_ptr& renderer, const SDL_FRect* rect, SDL_Color color) { @@ -328,7 +343,7 @@ bool SdlWidget::update_text(std::shared_ptr& renderer, const std:: return !widget_log_error(rc, "SDL_RenderCopy"); } -bool clear_window(std::shared_ptr& renderer) +bool SdlWidget::clear_window(std::shared_ptr& renderer) { assert(renderer); diff --git a/client/SDL/SDL3/dialogs/sdl_widget.hpp b/client/SDL/SDL3/dialogs/sdl_widget.hpp index 040d02cbe..2bc282e02 100644 --- a/client/SDL/SDL3/dialogs/sdl_widget.hpp +++ b/client/SDL/SDL3/dialogs/sdl_widget.hpp @@ -72,6 +72,13 @@ class SdlWidget static bool error_ex(bool success, const char* what, const char* file, size_t line, const char* fkt); + static bool clear_window(std::shared_ptr& renderer); + + protected: + static bool createWindowAndRenderer(const std::string& title, size_t width, size_t height, + std::shared_ptr& _window, + std::shared_ptr& _renderer); + private: std::shared_ptr render_text(std::shared_ptr& renderer, const std::string& text, SDL_Color fgcolor, @@ -88,5 +95,3 @@ class SdlWidget bool _wrap = false; size_t _text_width = 0; }; - -bool clear_window(std::shared_ptr& renderer); diff --git a/client/SDL/SDL3/dialogs/sdl_widget_list.cpp b/client/SDL/SDL3/dialogs/sdl_widget_list.cpp new file mode 100644 index 000000000..20a391b84 --- /dev/null +++ b/client/SDL/SDL3/dialogs/sdl_widget_list.cpp @@ -0,0 +1,18 @@ +#include "sdl_widget_list.hpp" + +bool SdlWidgetList::reset(const std::string& title, size_t width, size_t height) +{ + auto w = WINPR_ASSERTING_INT_CAST(int, width); + auto h = WINPR_ASSERTING_INT_CAST(int, height); + SDL_Renderer* renderer = nullptr; + SDL_Window* window = nullptr; + auto rc = SDL_CreateWindowAndRenderer(title.c_str(), w, h, + SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_MOUSE_FOCUS | + SDL_WINDOW_INPUT_FOCUS, + &window, &renderer); + _renderer = std::shared_ptr(renderer, SDL_DestroyRenderer); + _window = std::shared_ptr(window, SDL_DestroyWindow); + if (!rc) + widget_log_error(rc, "SDL_CreateWindowAndRenderer"); + return rc; +} diff --git a/client/SDL/SDL3/dialogs/sdl_widget_list.hpp b/client/SDL/SDL3/dialogs/sdl_widget_list.hpp new file mode 100644 index 000000000..865613f6a --- /dev/null +++ b/client/SDL/SDL3/dialogs/sdl_widget_list.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include + +#include +#include + +#include "sdl_buttons.hpp" + +class SdlWidgetList +{ + public: + SdlWidgetList() = default; + + SdlWidgetList(const SdlWidgetList& other) = delete; + SdlWidgetList(SdlWidgetList&& other) = delete; + SdlWidgetList& operator=(const SdlWidgetList& other) = delete; + SdlWidgetList& operator=(SdlWidgetList&& other) = delete; + + bool reset(const std::string& title, size_t width, size_t height); + + protected: + std::shared_ptr _window{}; + std::shared_ptr _renderer{}; + SdlButtonList _buttons; +};