Window chrome failure modes (Windows-first) (1.32 / 2.54)¶
Product shells should follow Gallery: BackdropSolid + PlatformTitleBar / TitleBar + reportHitTest() after layout, plus a stable geometryPersistenceKey when you want size/pos remembered.
See also window-shells.md (Win/Linux soak matrix) · title-bar-cookbook.md (header slots & hit-test, 2.05) · window-helper.md · window-transparency-dwm.md · graphics-backend.md · platform-linux-wayland.md.
1.04 tightened DPI / backdrop reapply. 1.32 re-soaks the shell matrix and documents multi-monitor geometry clamp as the supported persistence recipe. 1.58 adds mixed-DPI setScreen on restore + Gallery High-DPI & monitors readout — high-dpi.md.
Recommended recipe¶
StandardWindow {
backdrop: WindowHelper.BackdropSolid
geometryPersistenceKey: "MainWindow" // optional but recommended for product apps
header: PlatformTitleBar {
id: chrome
targetWindow: window
TitleBar {
embedded: true
title: window.title
// …
onWidthChanged: chrome.reportHitTest()
onHeightChanged: chrome.reportHitTest()
}
}
Component.onCompleted: Qt.callLater(chrome.reportHitTest)
}
Or ship Extras shells (NavigationWindow / ShellWindow) with the same Solid + persistence key — window-shells.md.
Dialog top-levels:
DialogWindow {
id: dlg
ownerWindow: mainWindow
}
// …
dlg.openDialog() // setTransientParent + centerOnScreen + visible
Or Extras DialogShellWindow / ToolShellWindow with distinct geometryPersistenceKeys — sample examples/multi-window (1.56).
NavigationWindow defaults to BackdropSolid. Prefer it (or ShellWindow) for product UI; keep StandardWindow for Gallery-style hosts.
Host × backdrop matrix (1.32)¶
| Host | Solid | Mica / Acrylic (Win) | Linux frost |
|---|---|---|---|
StandardWindow (Gallery) |
Default | Experiment via Window paradigm page | Coerced → Solid |
ShellWindow / Blank / Nav / MenuStatus |
Prefer Solid | Supported on Win DWM | Coerced → Solid |
| Dialog / Tool / Overlay shells | Prefer Solid | Same as ShellWindow | Coerced → Solid |
Always paint with effectiveBackdrop / WindowHelper.resolveBackdrop(backdrop) when materials may be coerced. For real Mica/Acrylic on Windows, pin OpenGL RHI — graphics-backend.md.
Failure modes¶
| Symptom | Likely cause | Fix |
|---|---|---|
| White / hollow client when using Mica/Acrylic | Transparent clear color without working DWM material (or Linux) | Use BackdropSolid, or rely on resolveBackdrop() / effectiveBackdrop |
| Mica missing after show / theme switch | Qt recreated style after install |
Shells reapply on first visible; Win filter reapplies on activate / show |
| Mica missing after DPI change (125%↔150%) | DWM attributes cleared on WM_DPICHANGED |
1.04 schedules backdrop reapply; QML refreshes hit-test via screensChanged |
| Caption buttons miss clicks after restore + maximize | Hit-test not re-run after geometry restore | Fixed 2.54 — ShellWindowSupport.geometryRestored → reportHitTest(); see window-chrome-footguns-254.md |
| Un-maximize wrong size after saved maximized session | Normal rect not cached on restore | Fixed 2.54 — restore sets _qwinui3_normalGeometry before maximize |
| Caption buttons miss clicks after maximize / DPI | Stale NC hit-test rects | PlatformTitleBar.reportHitTest() on resize, visibility, screen, screensChanged — title-bar-cookbook.md |
| Dialog opens behind main / wrong screen | No transient parent / centered on primary monitor | openDialog(owner) — 2.14: centerOnOwner + realize surfaces before setTransientParent |
| Double title bar on Wayland | Compositor SSD still on | QWinUI3::configureEnvironment / QT_WAYLAND_DISABLE_WINDOWDECORATION=1 — platform-linux-wayland.md (1.38) |
| Snap Layouts flyout never appears | Maximize caption not HTMAXIMIZE |
Ensure nativeChrome path + hit-test reports maximize rect; snapLayoutsEnabled |
Binding flags to paradigm |
HWND recreate loop | Keep flags: WindowHelper.recommendedFlags constant; change paradigm via installParadigmEx |
| Window restores off-screen / wrong monitor | Stale geometry after dock undock | Use geometryPersistenceKey — restore clamps to preferred / intersecting / primary availableGeometry |
| Wrong DPR after restore to another monitor | Window still bound to old QScreen |
1.58 restore calls setScreen after clamp — high-dpi.md |
| Thin white edge on Solid dark window | DWM default border + white swapchain clear in round-corner seam | 1.86: layer fill clear + pinned DWMWA_BORDER_COLOR; still prefer OpenGL for frost — performance.md |
| Thin white edge with frost | D3D RHI + transparent host | Prefer OpenGL — graphics-backend.md |
Geometry persistence checklist¶
- Set a stable unique
geometryPersistenceKeyper top-level role ("MainWindow","Inspector", …). - Rely on shell debounce-save + close-save; do not invent a second QSettings schema.
- Expect multi-monitor clamp on restore (min 160×120, fit inside taskbar-safe area, prefer saved screen name).
- Call
clearSavedGeometry()when shipping a “reset layout” action. - Gallery Main uses
"GalleryMain"— see window-helper.md. - Multi-window (1.56): never reuse one key for main + tool; owned dialogs use
openDialog(owner)— window-shells.md.
DPI checklist¶
Theme.devicePixelRatiotracks the window screen (StandardWindow/ShellWindowSupport).- Hit-test rects are screen-logical (
mapToGlobal); native code multiplies by DPR. - After monitor / scaling changes, expect
WindowHelper.screensChanged→ re-report hit-test + optionalreapply. - Full matrix + Gallery readout: high-dpi.md (1.58).
Backdrop checklist (Windows)¶
| Mode | Client clear | DWM |
|---|---|---|
BackdropSolid |
Opaque Theme.bgLayer |
DWMSBT_NONE (Gallery default) |
BackdropMica / MicaAlt / Acrylic |
Transparent host | System backdrop types |
BackdropNone |
You own the fill | None |
Gallery stays on Solid. Experiments: Gallery Window shells page, or set backdrop and keep effectiveBackdrop for paint.
Examples¶
| Example | Pattern |
|---|---|
examples/nav-settings |
Gallery-like PlatformTitleBar + TitleBar + NavigationView |
examples/settings-cards |
Same chrome + SettingsView |
examples/dashboard |
Same chrome + dashboard body |
examples/master-detail |
Same chrome + ListDetailsView (1.26) |
examples/form-settings |
Same chrome + FormLayout / SettingsCard (1.26) |