Internal
Public Access
RDP: fix resize corruption by proactively resizing the local GDI buffer
update->DesktopResize (the only place gdi_resize() was called) only fires during a full Deactivation-Reactivation sequence or a GFX ResetGraphics PDU, neither of which our Display Control channel resize path (SendMonitorLayout, MS-RDPEDISP) triggers. The client's own display buffer was left stuck at its initial-connect size for the rest of the session, and FreeRDP's surface-bits handling silently drops updates outside those stale bounds -- producing the missing/misplaced taskbar and stale composited-looking content. sendDisplayResize now calls gdi_resize() itself right after a successful SendMonitorLayout, rather than waiting on a callback that structurally never fires for this channel/codec configuration. Fixes #18. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1933,6 +1933,30 @@ bool RdpSessionBackend::sendDisplayResize(rdp_freerdp* instance, int width, int
|
||||
m_lastResizeHeight = height;
|
||||
m_lastResizeScale = static_cast<int>(scaleValue);
|
||||
|
||||
// The Display Control channel (MS-RDPEDISP) has no server
|
||||
// acknowledgment PDU, and real hosts apply the new resolution
|
||||
// without a Deactivation-Reactivation sequence — so
|
||||
// update->DesktopResize (which only fires for that sequence, or
|
||||
// for the GFX/Progressive pipeline we don't use) never runs for
|
||||
// a channel-driven resize. Without a matching gdi_resize() call,
|
||||
// gdi->width/height stay at the old size, and FreeRDP's own
|
||||
// surface-bits handling (intersect_rect in gdi.c) then silently
|
||||
// *drops* any update reaching outside those stale bounds —
|
||||
// which is what produced the missing/misplaced taskbar and
|
||||
// stale composited-looking content: this call is the fix, not
|
||||
// just a best-effort nudge.
|
||||
if (instance->context->gdi != nullptr
|
||||
&& gdi_resize(instance->context->gdi, static_cast<UINT32>(width),
|
||||
static_cast<UINT32>(height))) {
|
||||
emit remoteDesktopSizeChanged(width, height);
|
||||
} else if (instance->context->gdi != nullptr) {
|
||||
emit eventLogged(QStringLiteral(
|
||||
"RDP warning: local resize to %1x%2 failed; display may show stale content "
|
||||
"until the next full repaint.")
|
||||
.arg(width)
|
||||
.arg(height));
|
||||
}
|
||||
|
||||
// Best-effort nudge: some hosts don't fully repaint their own
|
||||
// desktop after a resolution change (observed: taskbar missing
|
||||
// until something else forces a redraw). Explicitly asking for
|
||||
|
||||
Reference in New Issue
Block a user