mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
Merge pull request #10982 from jpy794/sdl3-hidpi
Fix sdl3-freerdp blurry scaling on wayland when scale factor > 1
This commit is contained in:
@@ -51,8 +51,7 @@ BOOL sdlDispContext::settings_changed()
|
||||
freerdp_settings_get_uint16(settings, FreeRDP_DesktopOrientation))
|
||||
return TRUE;
|
||||
|
||||
if (_lastSentDesktopScaleFactor !=
|
||||
freerdp_settings_get_uint32(settings, FreeRDP_DesktopScaleFactor))
|
||||
if (_lastSentDesktopScaleFactor != _targetDesktopScaleFactor)
|
||||
return TRUE;
|
||||
|
||||
if (_lastSentDeviceScaleFactor !=
|
||||
@@ -75,7 +74,7 @@ BOOL sdlDispContext::update_last_sent()
|
||||
_lastSentWidth = _targetWidth;
|
||||
_lastSentHeight = _targetHeight;
|
||||
_lastSentDesktopOrientation = freerdp_settings_get_uint16(settings, FreeRDP_DesktopOrientation);
|
||||
_lastSentDesktopScaleFactor = freerdp_settings_get_uint32(settings, FreeRDP_DesktopScaleFactor);
|
||||
_lastSentDesktopScaleFactor = _targetDesktopScaleFactor;
|
||||
_lastSentDeviceScaleFactor = freerdp_settings_get_uint32(settings, FreeRDP_DeviceScaleFactor);
|
||||
// TODO _fullscreen = _sdl->fullscreen;
|
||||
return TRUE;
|
||||
@@ -116,8 +115,7 @@ BOOL sdlDispContext::sendResize()
|
||||
layout.Width = WINPR_ASSERTING_INT_CAST(uint32_t, _targetWidth);
|
||||
layout.Height = WINPR_ASSERTING_INT_CAST(uint32_t, _targetHeight);
|
||||
layout.Orientation = freerdp_settings_get_uint16(settings, FreeRDP_DesktopOrientation);
|
||||
layout.DesktopScaleFactor =
|
||||
freerdp_settings_get_uint32(settings, FreeRDP_DesktopScaleFactor);
|
||||
layout.DesktopScaleFactor = _targetDesktopScaleFactor;
|
||||
layout.DeviceScaleFactor = freerdp_settings_get_uint32(settings, FreeRDP_DeviceScaleFactor);
|
||||
layout.PhysicalWidth = WINPR_ASSERTING_INT_CAST(uint32_t, _targetWidth);
|
||||
layout.PhysicalHeight = WINPR_ASSERTING_INT_CAST(uint32_t, _targetHeight);
|
||||
@@ -356,13 +354,19 @@ BOOL sdlDispContext::handle_window_event(const SDL_WindowEvent* ev)
|
||||
case SDL_EVENT_WINDOW_RESTORED:
|
||||
gdi_send_suppress_output(_sdl->context()->gdi, FALSE);
|
||||
return TRUE;
|
||||
|
||||
case SDL_EVENT_WINDOW_RESIZED:
|
||||
case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED:
|
||||
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
|
||||
_targetWidth = ev->data1;
|
||||
_targetHeight = ev->data2;
|
||||
{
|
||||
if (freerdp_settings_get_bool(_sdl->context()->settings,
|
||||
FreeRDP_DynamicResolutionUpdate))
|
||||
{
|
||||
const auto& window = _sdl->windows.at(ev->windowID);
|
||||
const auto factor = SDL_GetWindowDisplayScale(window.window());
|
||||
_targetDesktopScaleFactor = static_cast<UINT32>(100 * factor);
|
||||
}
|
||||
assert(SDL_GetWindowSizeInPixels(it->second.window(), &_targetWidth, &_targetHeight));
|
||||
return addTimer();
|
||||
|
||||
}
|
||||
case SDL_EVENT_WINDOW_MOUSE_LEAVE:
|
||||
WINPR_ASSERT(_sdl);
|
||||
_sdl->input.keyboard_grab(ev->windowID, false);
|
||||
@@ -456,6 +460,8 @@ sdlDispContext::sdlDispContext(SdlContext* sdl) : _sdl(sdl)
|
||||
int32_t, freerdp_settings_get_uint32(settings, FreeRDP_DesktopWidth));
|
||||
_lastSentHeight = _targetHeight = WINPR_ASSERTING_INT_CAST(
|
||||
int32_t, freerdp_settings_get_uint32(settings, FreeRDP_DesktopHeight));
|
||||
_lastSentDesktopScaleFactor = _targetDesktopScaleFactor =
|
||||
freerdp_settings_get_uint32(settings, FreeRDP_DesktopScaleFactor);
|
||||
PubSub_SubscribeActivated(pubSub, sdlDispContext::OnActivated);
|
||||
PubSub_SubscribeGraphicsReset(pubSub, sdlDispContext::OnGraphicsReset);
|
||||
addTimer();
|
||||
|
||||
@@ -45,6 +45,11 @@ class sdlDispContext
|
||||
|
||||
BOOL handle_window_event(const SDL_WindowEvent* ev);
|
||||
|
||||
[[nodiscard]] UINT32 scale_factor() const
|
||||
{
|
||||
return _lastSentDesktopScaleFactor;
|
||||
}
|
||||
|
||||
private:
|
||||
UINT DisplayControlCaps(UINT32 maxNumMonitors, UINT32 maxMonitorAreaFactorA,
|
||||
UINT32 maxMonitorAreaFactorB);
|
||||
@@ -75,6 +80,7 @@ class sdlDispContext
|
||||
UINT16 _lastSentDesktopOrientation = 0;
|
||||
UINT32 _lastSentDesktopScaleFactor = 0;
|
||||
UINT32 _lastSentDeviceScaleFactor = 0;
|
||||
UINT32 _targetDesktopScaleFactor = 0;
|
||||
SDL_TimerID _timer = 0;
|
||||
unsigned _timer_retries = 0;
|
||||
};
|
||||
|
||||
@@ -403,6 +403,8 @@ static BOOL sdl_draw_to_window(SdlContext* sdl, SdlWindow& window,
|
||||
|
||||
if (!freerdp_settings_get_bool(context->settings, FreeRDP_SmartSizing))
|
||||
{
|
||||
window.setOffsetX(0);
|
||||
window.setOffsetY(0);
|
||||
if (gdi->width < size.w)
|
||||
{
|
||||
window.setOffsetX((size.w - gdi->width) / 2);
|
||||
@@ -775,12 +777,13 @@ static BOOL sdl_create_windows(SdlContext* sdl)
|
||||
|
||||
static BOOL sdl_wait_create_windows(SdlContext* sdl)
|
||||
{
|
||||
std::lock_guard<CriticalSection> lock(sdl->critical);
|
||||
std::unique_lock<CriticalSection> lock(sdl->critical);
|
||||
sdl->windows_created.clear();
|
||||
if (!sdl_push_user_event(SDL_EVENT_USER_CREATE_WINDOWS, sdl))
|
||||
return FALSE;
|
||||
lock.unlock();
|
||||
|
||||
HANDLE handles[] = { sdl->initialized.handle(), freerdp_abort_event(sdl->context()) };
|
||||
HANDLE handles[] = { sdl->windows_created.handle(), freerdp_abort_event(sdl->context()) };
|
||||
|
||||
const DWORD rc = WaitForMultipleObjects(ARRAYSIZE(handles), handles, FALSE, INFINITE);
|
||||
switch (rc)
|
||||
@@ -864,6 +867,16 @@ static int sdl_run(SdlContext* sdl)
|
||||
}
|
||||
}
|
||||
|
||||
auto point2pix = [](Uint32 win_id, float& x, float& y)
|
||||
{
|
||||
auto win = SDL_GetWindowFromID(win_id);
|
||||
assert(win);
|
||||
auto scale = SDL_GetWindowDisplayScale(win);
|
||||
assert(scale);
|
||||
x *= scale;
|
||||
y *= scale;
|
||||
};
|
||||
|
||||
switch (windowEvent.type)
|
||||
{
|
||||
case SDL_EVENT_QUIT:
|
||||
@@ -882,15 +895,18 @@ static int sdl_run(SdlContext* sdl)
|
||||
break; // TODO: Switch keyboard layout
|
||||
case SDL_EVENT_MOUSE_MOTION:
|
||||
{
|
||||
const SDL_MouseMotionEvent* ev = &windowEvent.motion;
|
||||
sdl_handle_mouse_motion(sdl, ev);
|
||||
SDL_MouseMotionEvent& ev = windowEvent.motion;
|
||||
point2pix(ev.windowID, ev.x, ev.y);
|
||||
point2pix(ev.windowID, ev.xrel, ev.yrel);
|
||||
sdl_handle_mouse_motion(sdl, &ev);
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||
case SDL_EVENT_MOUSE_BUTTON_UP:
|
||||
{
|
||||
const SDL_MouseButtonEvent* ev = &windowEvent.button;
|
||||
sdl_handle_mouse_button(sdl, ev);
|
||||
SDL_MouseButtonEvent& ev = windowEvent.button;
|
||||
point2pix(ev.windowID, ev.x, ev.y);
|
||||
sdl_handle_mouse_button(sdl, &ev);
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_MOUSE_WHEEL:
|
||||
@@ -1017,6 +1033,7 @@ static int sdl_run(SdlContext* sdl)
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_USER_POINTER_SET:
|
||||
windowEvent.user.code = static_cast<Sint32>(sdl->disp.scale_factor());
|
||||
sdl_Pointer_Set_Process(&windowEvent.user);
|
||||
break;
|
||||
case SDL_EVENT_CLIPBOARD_UPDATE:
|
||||
@@ -1041,10 +1058,32 @@ static int sdl_run(SdlContext* sdl)
|
||||
|
||||
switch (ev->type)
|
||||
{
|
||||
case SDL_EVENT_WINDOW_RESIZED:
|
||||
case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED:
|
||||
{
|
||||
if (freerdp_settings_get_bool(sdl->context()->settings,
|
||||
FreeRDP_DynamicResolutionUpdate))
|
||||
{
|
||||
break;
|
||||
}
|
||||
auto win = window->second.window();
|
||||
int w_pix{};
|
||||
int h_pix{};
|
||||
assert(SDL_GetWindowSizeInPixels(win, &w_pix, &h_pix));
|
||||
auto scale = SDL_GetWindowDisplayScale(win);
|
||||
assert(scale != 0);
|
||||
auto w_gdi = sdl->context()->gdi->width;
|
||||
auto h_gdi = sdl->context()->gdi->height;
|
||||
auto pix2point = [=](int pix)
|
||||
{ return static_cast<int>(static_cast<float>(pix) / scale); };
|
||||
if (w_pix != w_gdi || h_pix != h_gdi)
|
||||
{
|
||||
SDL_SetWindowSize(win, pix2point(w_gdi), pix2point(h_gdi));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
|
||||
window->second.fill();
|
||||
window->second.updateSurface();
|
||||
sdl_draw_to_window(sdl, window->second);
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_MOVED:
|
||||
{
|
||||
|
||||
@@ -158,10 +158,23 @@ BOOL sdl_Pointer_Set_Process(SDL_UserEvent* uptr)
|
||||
if (!rc)
|
||||
return FALSE;
|
||||
|
||||
ptr->cursor = SDL_CreateColorCursor(ptr->image, x, y);
|
||||
// create a cursor image in 100% display scale to trick SDL into creating the cursor with the
|
||||
// correct size
|
||||
const auto hidpi_scale = static_cast<float>(uptr->code) / 100;
|
||||
auto normal = SDL_CreateSurface(
|
||||
static_cast<int>(static_cast<float>(ptr->image->w) / hidpi_scale),
|
||||
static_cast<int>(static_cast<float>(ptr->image->h) / hidpi_scale), ptr->image->format);
|
||||
assert(normal);
|
||||
SDL_BlitSurfaceScaled(ptr->image, nullptr, normal, nullptr,
|
||||
SDL_ScaleMode::SDL_SCALEMODE_NEAREST);
|
||||
SDL_AddSurfaceAlternateImage(normal, ptr->image);
|
||||
|
||||
ptr->cursor = SDL_CreateColorCursor(normal, x, y);
|
||||
if (!ptr->cursor)
|
||||
return FALSE;
|
||||
|
||||
SDL_DestroySurface(normal);
|
||||
|
||||
SDL_SetCursor(ptr->cursor);
|
||||
SDL_ShowCursor();
|
||||
return TRUE;
|
||||
|
||||
@@ -29,6 +29,7 @@ SdlWindow::SdlWindow(const std::string& title, Sint32 startupX, Sint32 startupY,
|
||||
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, startupY);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, width);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, height);
|
||||
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIGH_PIXEL_DENSITY_BOOLEAN, true);
|
||||
// SDL_SetProperty(props, SDL_PROP_WINDOW_CREATE_FL);
|
||||
_window = SDL_CreateWindowWithProperties(props);
|
||||
SDL_DestroyProperties(props);
|
||||
@@ -65,7 +66,7 @@ SDL_Rect SdlWindow::rect() const
|
||||
if (_window)
|
||||
{
|
||||
SDL_GetWindowPosition(_window, &rect.x, &rect.y);
|
||||
SDL_GetWindowSize(_window, &rect.w, &rect.h);
|
||||
SDL_GetWindowSizeInPixels(_window, &rect.w, &rect.h);
|
||||
}
|
||||
return rect;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user