[client,sdl] fix dpi scaling for dialogs

* Unify SDL_CreateWindowAndRenderer calls
* remove SDL_WINDOW_HIGH_PIXEL_DENSITY flag
This commit is contained in:
akallabeth
2025-05-05 14:35:35 +02:00
parent 67452e1a58
commit a12f14afb6
11 changed files with 127 additions and 61 deletions

View File

@@ -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

View File

@@ -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<SDL_Renderer>(renderer, SDL_DestroyRenderer);
_window = std::shared_ptr<SDL_Window>(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<float>(height) };
widget_cfg_t icon{ textcolor,

View File

@@ -28,11 +28,12 @@
#include <freerdp/freerdp.h>
#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<SDL_Window> _window = nullptr;
std::shared_ptr<SDL_Renderer> _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<widget_cfg_t> _list;
SdlButtonList _buttons;
std::vector<widget_cfg_t> _list{};
};
class SDLConnectionDialogHider

View File

@@ -1,8 +1,28 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* SDL Client helper dialogs
*
* Copyright 2025 Armin Novak <armin.novak@thincast.com>
* 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 <cassert>
#include <algorithm>
#include <winpr/cast.h>
#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<std::string>& labels,
const std::vector<std::string>& initial,
const std::vector<Uint32>& 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<int>(total_height),
SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_INPUT_FOCUS, &window,
&renderer);
_renderer = std::shared_ptr<SDL_Renderer>(renderer, SDL_DestroyRenderer);
_window = std::shared_ptr<SDL_Window>(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<std::string>& result)
bool running = true;
while (running)
{
if (!clear_window(_renderer))
if (!SdlWidget::clear_window(_renderer))
throw;
if (!update(_renderer))

View File

@@ -1,13 +1,33 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* SDL Client helper dialogs
*
* Copyright 2025 Armin Novak <armin.novak@thincast.com>
* 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 <string>
#include <vector>
#include <SDL3/SDL.h>
#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<std::string>& labels,
@@ -37,8 +57,5 @@ class SdlInputWidgetList
[[nodiscard]] bool valid(ssize_t current) const;
std::shared_ptr<SdlInputWidget> get(ssize_t index);
std::shared_ptr<SDL_Window> _window;
std::shared_ptr<SDL_Renderer> _renderer;
std::vector<std::shared_ptr<SdlInputWidget>> _list;
SdlButtonList _buttons;
};

View File

@@ -1,30 +1,18 @@
#include <cassert>
#include <winpr/cast.h>
#include "sdl_selectlist.hpp"
#include "../sdl_utils.hpp"
static const Uint32 vpadding = 5;
SdlSelectList::SdlSelectList(const std::string& title, const std::vector<std::string>& 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<int>(widget_width), static_cast<int>(height),
SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_INPUT_FOCUS, &window,
&renderer);
_renderer = std::shared_ptr<SDL_Renderer>(renderer, SDL_DestroyRenderer);
_window = std::shared_ptr<SDL_Window>(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())

View File

@@ -5,11 +5,12 @@
#include <SDL3/SDL.h>
#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<std::string>& labels);
@@ -34,8 +35,5 @@ class SdlSelectList
void reset_mouseover();
void reset_highlight();
std::shared_ptr<SDL_Window> _window;
std::shared_ptr<SDL_Renderer> _renderer;
std::vector<SdlSelectWidget> _list;
SdlButtonList _buttons;
};

View File

@@ -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<SDL_Window>& _window,
std::shared_ptr<SDL_Renderer>& _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<SDL_Renderer>(renderer, SDL_DestroyRenderer);
_window = std::shared_ptr<SDL_Window>(window, SDL_DestroyWindow);
return rc;
}
static bool draw_rect(std::shared_ptr<SDL_Renderer>& renderer, const SDL_FRect* rect,
SDL_Color color)
{
@@ -328,7 +343,7 @@ bool SdlWidget::update_text(std::shared_ptr<SDL_Renderer>& renderer, const std::
return !widget_log_error(rc, "SDL_RenderCopy");
}
bool clear_window(std::shared_ptr<SDL_Renderer>& renderer)
bool SdlWidget::clear_window(std::shared_ptr<SDL_Renderer>& renderer)
{
assert(renderer);

View File

@@ -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<SDL_Renderer>& renderer);
protected:
static bool createWindowAndRenderer(const std::string& title, size_t width, size_t height,
std::shared_ptr<SDL_Window>& _window,
std::shared_ptr<SDL_Renderer>& _renderer);
private:
std::shared_ptr<SDL_Texture> render_text(std::shared_ptr<SDL_Renderer>& 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<SDL_Renderer>& renderer);

View File

@@ -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<SDL_Renderer>(renderer, SDL_DestroyRenderer);
_window = std::shared_ptr<SDL_Window>(window, SDL_DestroyWindow);
if (!rc)
widget_log_error(rc, "SDL_CreateWindowAndRenderer");
return rc;
}

View File

@@ -0,0 +1,26 @@
#pragma once
#include <memory>
#include <SDL3/SDL.h>
#include <winpr/assert.h>
#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<SDL_Window> _window{};
std::shared_ptr<SDL_Renderer> _renderer{};
SdlButtonList _buttons;
};