Fix ghost window on Windows by using proper dialog window flags#13201
Open
mattezell wants to merge 2 commits intokeepassxreboot:developfrom
Open
Fix ghost window on Windows by using proper dialog window flags#13201mattezell wants to merge 2 commits intokeepassxreboot:developfrom
mattezell wants to merge 2 commits intokeepassxreboot:developfrom
Conversation
Replace Qt::Window with Qt::Dialog | Qt::WindowTitleHint | Qt::WindowCloseButtonHint in UpdateCheckDialog to prevent an orphaned DWM window frame on Windows 11. Using bare Qt::Window on a QDialog causes Windows DWM to create an independently managed top-level composition surface. If the dialog's native handle is not cleanly destroyed (e.g., during process exit while the dialog exists), DWM can leave behind a transparent, non-interactive ghost window frame that persists even after the process is gone and can only be cleared by rebooting. Using Qt::Dialog keeps the dialog properly associated with its parent window in DWM's composition tree, preventing the orphaned frame. Fixes keepassxreboot#9493
Contributor
There was a problem hiding this comment.
Pull request overview
Adjusts the UpdateCheckDialog window flags to ensure it behaves as a proper dialog on Windows, preventing an orphaned “ghost” window frame from being left behind by DWM after app exit (per #9493).
Changes:
- Replaces
setWindowFlags(Qt::Window)with dialog-appropriate flags (Qt::Dialog | Qt::WindowTitleHint | Qt::WindowCloseButtonHint) inUpdateCheckDialog. - Preserves expected title bar / close button while avoiding Windows 11 ghost frame behavior.
Member
|
Looks great but fix your code format |
Author
|
Fixed the indentation in 03b3c64. Thanks for the quick review! |
droidmonkey
approved these changes
Mar 26, 2026
Author
|
@droidmonkey anything that I need to action on with this? I see the failures, but they don't seem to be related to my change - and I also notice that many other PRs have failed in what seems to be basically the same way, almost as if it's environmental in the build / test env. |
Member
|
Unrelated, you are good to go here |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
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.
On Windows 11, the UpdateCheckDialog leaves behind a transparent, non-interactive ghost window frame that persists even after the KeePassXC process has fully exited. The only way to remove this phantom window is to reboot. This has been reported and reproduced by multiple users (see #9493).
The root cause is
setWindowFlags(Qt::Window)in theUpdateCheckDialogconstructor. Using bareQt::Windowon aQDialogcauses Windows DWM (Desktop Window Manager) to create an independently managed top-level composition surface for the dialog. If the dialog's native HWND is not cleanly destroyed through the normalDestroyWindow->WM_NCDESTROYsequence (e.g., during process exit while the dialog exists, or during an update installation), DWM is left with an orphaned composition surface -- the title bar, borders, and shadow that DWM draws itself -- which persists as a ghost frame even after the owning process is gone.This change replaces
Qt::WindowwithQt::Dialog | Qt::WindowTitleHint | Qt::WindowCloseButtonHint, which:Fixes #9493
Screenshots
N/A - This is a window flags change that prevents a ghost window artifact. The dialog's visual appearance remains the same.
Testing strategy
Generative AI (Claude) was used to help identify the root cause and suggest the fix.
Type of change