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_lastResizeHeight = height;
|
||||||
m_lastResizeScale = static_cast<int>(scaleValue);
|
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
|
// Best-effort nudge: some hosts don't fully repaint their own
|
||||||
// desktop after a resolution change (observed: taskbar missing
|
// desktop after a resolution change (observed: taskbar missing
|
||||||
// until something else forces a redraw). Explicitly asking for
|
// until something else forces a redraw). Explicitly asking for
|
||||||
|
|||||||
Reference in New Issue
Block a user