Skip to content

docs(h264): reconnect-blank is two stacked mstsc bugs (full xrdp mirror tried) - #9

Merged
clintcan merged 1 commit into
mainfrom
egfx-reconnect-two-layer-finding
Jun 22, 2026
Merged

docs(h264): reconnect-blank is two stacked mstsc bugs (full xrdp mirror tried)#9
clintcan merged 1 commit into
mainfrom
egfx-reconnect-two-layer-finding

Conversation

@clintcan

Copy link
Copy Markdown
Owner

Corrects + supersedes the earlier "all three server-side avenues dead / mstsc disconnect is always abrupt" note. Re-opened because xrdp+mstsc reconnects in-process cleanly, proving a server-side fix can work.

Findings: mstsc's connection-bar X (close, keep process) is a graceful disconnect arriving as an io-channel Shutdown Request — the client loop exits Ok(RunState::Disconnect) with the socket still alive, so the disconnect hook IS reachable. (The earlier Broken pipe was the 60fps frame-write losing the select! race, not inherent.) We then sent DELETE_SURFACE(all) + a DYNVC_CLOSE of the Graphics channel there — fully mirroring xrdp's shutdown_full.

Result on real mstsc: symptom changed but didn't resolve — delete-only → still black; delete + DYNVC_CLOSE → transparent (client's local desktop shows through, non-interactive). So the blank is two stacked mstsc bugs:

  1. black = mstsc retains surface 0 across the drop → composites the stale surface. The channel-close fixes this.
  2. transparent = mstsc won't re-map/composite a fresh output surface on an in-process reconnect. Not server-fixable — xrdp gets past it via its persistent-X-session reconnect architecture.

Decision: stop — documented mstsc client limitation; recovery stays close+reopen mstsc (fresh process, neither layer's state). FreeRDP/Thincast unaffected. Do not re-attempt unless layer 2 (reconnect re-composite) is cracked. Docs-only.

…or tried)

Corrects + supersedes the earlier "all three server-side avenues dead / mstsc
disconnect is always abrupt" conclusion. Re-opened because xrdp+mstsc reconnects
in-process cleanly, proving a server-side fix can work.

Findings: mstsc's connection-bar X (close, keep process) is a GRACEFUL disconnect
that arrives as an io-channel Shutdown Request ("Got disconnect request"); the
client loop exits Ok(RunState::Disconnect) with the socket still alive — so the
disconnect hook IS reachable (the earlier Broken-pipe was the 60fps frame-write
losing the select! race, not inherent). We then sent DELETE_SURFACE(all) + a
DYNVC_CLOSE of the Graphics channel there, fully mirroring xrdp's shutdown_full.

Result on real mstsc: symptom changed but didn't resolve — delete-only → still
black; delete + DYNVC_CLOSE → TRANSPARENT (client's local desktop shows through).
So the blank is TWO stacked mstsc bugs: (1) black = retains surface 0 across the
drop (channel-close FIXES this) and (2) transparent = won't re-composite a fresh
output surface on in-process reconnect (NOT server-fixable; xrdp gets past it via
its persistent-X-session reconnect architecture). DECISION: stop, documented
client limitation, recovery = close+reopen mstsc. Do not re-attempt unless layer
2 (reconnect re-composite) is cracked. Docs-only.
@clintcan
clintcan merged commit 7186ae5 into main Jun 22, 2026
2 checks passed
@clintcan
clintcan deleted the egfx-reconnect-two-layer-finding branch June 22, 2026 20:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant