[client,sdl] fix display channel updates

* always send updates if enabled and a monitor setting changed
* properly handle window and display updates
This commit is contained in:
akallabeth
2026-01-23 10:33:49 +01:00
parent 636590374a
commit caffbab7d4
4 changed files with 56 additions and 36 deletions

View File

@@ -783,6 +783,26 @@ SDL_PixelFormat SdlContext::pixelFormat() const
return _sdlPixelFormat;
}
bool SdlContext::addDisplayWindow(SDL_DisplayID id)
{
const auto flags =
SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS;
auto title = sdl::utils::windowTitle(context()->settings);
auto w = SdlWindow::create(id, title, flags);
_windows.emplace(w.id(), std::move(w));
return true;
}
bool SdlContext::removeDisplay(SDL_DisplayID id)
{
for (auto& w : _windows)
{
if (w.second.displayIndex() == id)
_windows.erase(w.first);
}
return true;
}
SdlWindow* SdlContext::getWindowForId(SDL_WindowID id)
{
auto it = _windows.find(id);

View File

@@ -109,6 +109,9 @@ class SdlContext
[[nodiscard]] SdlWindow* getWindowForId(SDL_WindowID id);
[[nodiscard]] SdlWindow* getFirstWindow();
[[nodiscard]] bool addDisplayWindow(SDL_DisplayID id);
[[nodiscard]] bool removeDisplay(SDL_DisplayID id);
[[nodiscard]] sdlDispContext& getDisplayChannelContext();
[[nodiscard]] sdlInput& getInputChannelContext();
[[nodiscard]] sdlClip& getClipboardChannelContext();

View File

@@ -88,7 +88,7 @@ bool sdlDispContext::sendResize()
return sendLayout(monitors, mcount) != CHANNEL_RC_OK;
}
bool sdlDispContext::set_window_resizable()
bool sdlDispContext::setWindowResizeable()
{
return _sdl->setResizeable(true);
}
@@ -125,7 +125,8 @@ void sdlDispContext::OnActivated(void* context, const ActivatedEventArgs* e)
if (sdlDisp->_activated && !freerdp_settings_get_bool(settings, FreeRDP_Fullscreen))
{
sdlDisp->set_window_resizable();
if (!sdlDisp->setWindowResizeable())
return;
if (e->firstActivation)
return;
@@ -148,7 +149,7 @@ void sdlDispContext::OnGraphicsReset(void* context, const GraphicsResetEventArgs
if (sdlDisp->_activated && !freerdp_settings_get_bool(settings, FreeRDP_Fullscreen))
{
sdlDisp->set_window_resizable();
sdlDisp->setWindowResizeable();
sdlDisp->addTimer();
}
}
@@ -170,8 +171,6 @@ Uint32 sdlDispContext::OnTimer(void* param, [[maybe_unused]] SDL_TimerID timerID
return 0;
WLog_Print(sdl->getWLog(), WLOG_TRACE, "checking for display changes...");
if (!sdlDisp->_activated || freerdp_settings_get_bool(settings, FreeRDP_Fullscreen))
return 0;
auto rc = sdlDisp->sendResize();
if (!rc)
@@ -279,7 +278,8 @@ bool sdlDispContext::addTimer()
WLog_Print(_sdl->getWLog(), WLOG_TRACE, "adding new display check timer");
_timer_retries = 0;
sendResize();
if (!sendResize())
return false;
_timer = SDL_AddTimer(1000, sdlDispContext::OnTimer, this);
return true;
}
@@ -288,36 +288,19 @@ bool sdlDispContext::updateMonitor(SDL_WindowID id)
{
auto settings = _sdl->context()->settings;
if (freerdp_settings_get_bool(settings, FreeRDP_UseMultimon))
return updateMonitors(SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED);
return updateMonitors(SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED, id);
if (!freerdp_settings_get_bool(_sdl->context()->settings, FreeRDP_DynamicResolutionUpdate))
return true;
const auto window = _sdl->getWindowForId(id);
if (!window)
return false;
const auto& monitor = window->monitor(true);
if (!freerdp_settings_set_monitor_def_array_sorted(settings, &monitor, 1))
if (!_sdl->updateWindowList())
return false;
return addTimer();
}
bool sdlDispContext::updateMonitors(SDL_EventType type)
bool sdlDispContext::updateMonitors(SDL_EventType type, SDL_DisplayID displayID)
{
switch (type)
{
case SDL_EVENT_DISPLAY_ADDED:
case SDL_EVENT_DISPLAY_REMOVED:
case SDL_EVENT_DISPLAY_MOVED:
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "TODO [%s] Not fully supported yet",
sdl_event_type_str(type));
break;
default:
break;
}
auto settings = _sdl->context()->settings;
if (!freerdp_settings_get_bool(settings, FreeRDP_UseMultimon))
return true;
@@ -325,6 +308,20 @@ bool sdlDispContext::updateMonitors(SDL_EventType type)
if (!freerdp_settings_get_bool(settings, FreeRDP_DynamicResolutionUpdate))
return true;
switch (type)
{
case SDL_EVENT_DISPLAY_ADDED:
if (!_sdl->addDisplayWindow(displayID))
return false;
break;
case SDL_EVENT_DISPLAY_REMOVED:
if (!_sdl->removeDisplay(displayID))
return false;
break;
default:
break;
}
if (!_sdl->updateWindowList())
return false;
return addTimer();
@@ -338,25 +335,25 @@ bool sdlDispContext::handle_display_event(const SDL_DisplayEvent* ev)
{
case SDL_EVENT_DISPLAY_ADDED:
SDL_Log("A new display with id %u was connected", ev->displayID);
return updateMonitors(ev->type);
return updateMonitors(ev->type, ev->displayID);
case SDL_EVENT_DISPLAY_REMOVED:
SDL_Log("The display with id %u was disconnected", ev->displayID);
return updateMonitors(ev->type);
return updateMonitors(ev->type, ev->displayID);
case SDL_EVENT_DISPLAY_ORIENTATION:
SDL_Log("The orientation of display with id %u was changed", ev->displayID);
return updateMonitors(ev->type);
return updateMonitors(ev->type, ev->displayID);
case SDL_EVENT_DISPLAY_MOVED:
SDL_Log("The display with id %u was moved", ev->displayID);
return updateMonitors(ev->type);
return updateMonitors(ev->type, ev->displayID);
case SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED:
SDL_Log("The display with id %u changed scale", ev->displayID);
return updateMonitors(ev->type);
return updateMonitors(ev->type, ev->displayID);
case SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED:
SDL_Log("The display with id %u changed mode", ev->displayID);
return updateMonitors(ev->type);
return updateMonitors(ev->type, ev->displayID);
case SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED:
SDL_Log("The display with id %u changed desktop mode", ev->displayID);
return updateMonitors(ev->type);
return updateMonitors(ev->type, ev->displayID);
default:
return true;
}
@@ -438,7 +435,7 @@ UINT sdlDispContext::DisplayControlCaps(UINT32 maxNumMonitors, UINT32 maxMonitor
return CHANNEL_RC_OK;
WLog_DBG(TAG, "DisplayControlCapsPdu: setting the window as resizable");
return set_window_resizable() ? CHANNEL_RC_OK : CHANNEL_RC_NO_MEMORY;
return setWindowResizeable() ? CHANNEL_RC_OK : CHANNEL_RC_NO_MEMORY;
}
bool sdlDispContext::init(DispClientContext* disp)

View File

@@ -49,7 +49,7 @@ class sdlDispContext
private:
[[nodiscard]] UINT DisplayControlCaps(UINT32 maxNumMonitors, UINT32 maxMonitorAreaFactorA,
UINT32 maxMonitorAreaFactorB);
[[nodiscard]] bool set_window_resizable();
[[nodiscard]] bool setWindowResizeable();
[[nodiscard]] bool sendResize();
[[nodiscard]] bool settings_changed(const std::vector<DISPLAY_CONTROL_MONITOR_LAYOUT>& layout);
@@ -58,7 +58,7 @@ class sdlDispContext
[[nodiscard]] bool addTimer();
bool updateMonitor(SDL_WindowID id);
bool updateMonitors(SDL_EventType type);
bool updateMonitors(SDL_EventType type, SDL_DisplayID displayID);
[[nodiscard]] static UINT DisplayControlCaps(DispClientContext* disp, UINT32 maxNumMonitors,
UINT32 maxMonitorAreaFactorA,