Repository navigation
Repaint windows when the display comes back on Windows - #59
Merged
Marc-André Moreau (mamoreau-devolutions) merged 1 commit intoOct 23, 2026
Merged
Marc-André Moreau (mamoreau-devolutions) merged 1 commit into
Marc-André Moreau (mamoreau-devolutions) merged 1 commit into
Conversation
Avalonia draws each window into a Windows.UI.Composition drawing surface. Windows can discard that surface's contents while the display is off, the session is locked or the GPU resets, and Avalonia does not observe RenderingDeviceReplaced. Because DT skips frames while nothing is damaged, an idle terminal then shows only the Mica backdrop until something repaints. Register every window for display-state, session and resume notifications and invalidate the HWND when the display returns; Avalonia answers WM_PAINT with a full redraw (recreating the render target if the device was lost). A second repaint runs a second later in case the display stack is still settling. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Marc-André Moreau (mamoreau-devolutions)
deployed
to
publish-dry-run
October 23, 2026 13:24 — with
GitHub Actions
Active
Marc-André Moreau (mamoreau-devolutions)
deployed
to
publish-dry-run
October 23, 2026 13:24 — with
GitHub Actions
Active
Marc-André Moreau (mamoreau-devolutions)
deployed
to
publish-dry-run
October 23, 2026 13:24 — with
GitHub Actions
Active
Marc-André Moreau (mamoreau-devolutions)
deployed
to
publish-dry-run
October 23, 2026 13:24 — with
GitHub Actions
Active
Marc-André Moreau (mamoreau-devolutions)
merged commit Oct 23, 2026
a362207
into
master
46 checks passed
Marc-André Moreau (mamoreau-devolutions)
deleted the
claude/dt-blank-screen-c9d436
branch
October 23, 2026 13:45
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
After DT is left idle for a while (display off / session locked), the window can come back completely blank: only the Mica backdrop is visible, with no title bar or terminal content, until something forces a repaint.
Cause
RenderingDeviceReplaced, so it doesn't know the contents are gone.TermControlblink timer), so an idle window presents no new frame.TransparencyLevelHint="Mica,..."puts a Mica backdrop behind the window, which is what shows through the empty surface.Fix
New
WindowsSurfaceRecovery(Windows-only, installed once at app startup viaWindow.WindowOpenedEvent):GUID_CONSOLE_DISPLAY_STATEpower-setting notifications and WTS session notifications, and hooks its WndProc throughWin32Properties.AddWndProcHookCallback.PBT_APMRESUMESUSPEND/PBT_APMRESUMEAUTOMATIC) orWM_DISPLAYCHANGE, it callsInvalidateRect. Avalonia handles the resultingWM_PAINTwith a full redraw, and recreates the render target if the device was lost.WM_DESTROY, and the hook is removed onClosed.Testing
WindowsSurfaceRecoveryTestscover which messages trigger a repaint.Devolutions.Terminal.App.Testssuite: 623 passed.wtsapi32.dllloads, unlike the shipped build), and it keeps rendering correctly after it receivesWM_DISPLAYCHANGE, unlock and resume messages.🤖 Generated with Claude Code