- F11 - Maximize Ctrl M - normal Ctrl N - Dump: Ctrl D Qt 4 with Windowflags=frameless only (window has no frame, initially) ===================================================================== 4.8.6 ("-of") flags= QFlags(0x800) MainWindow::toggle_borderless borderless= true Style 2516582400 2160525312 WM_NCCALCSIZE/borderless WM_NCCALCSIZE/borderless WM_NCCALCSIZE/borderless geom QRect(200,200 200x100) frameGeom= QRect(200,200 200x100) QMargins(0, 0, 0, 0) Margins match accidentally. Qt 4 with Windowflags=flags() | frameless (window has frame initially) =====================================-======================-========== 4.8.6 ("f") flags= QFlags(0x1|0x800|0x1000|0x2000|0x4000|0x8000|0x8000000) MainWindow::toggle_borderless borderless= true Style 2529886208 2160525312 WM_NCCALCSIZE/borderless WM_NCCALCSIZE/borderless WM_NCCALCSIZE/borderless WM_NCCALCSIZE/borderless geom QRect(200,200 232x178) frameGeom= QRect(192,169 248x217) QMargins(8, 31, 8, 8) Margins are offset, no artifacts visible Qt 5 Windowflags=flags() | frameless (window has no frame initially) ===================================================================== 5.4.0 () flags= QFlags(0x1|0x800|0x1000|0x2000|0x4000|0x8000|0x8000000|-0x80000000) MainWindow::toggle_borderless borderless= true Style 0x960b0000 0x80c70000 WM_NCCALCSIZE/borderless WM_NCCALCSIZE/borderless WM_NCCALCSIZE/borderless geom QRect(208,231 184x61) frameGeom= QRect(200,200 200x100) QMargins(8, 31, 8, 8) QWindow: geom QRect(208,231 184x61) frameGeom= QRect(200,200 200x100) QMargins(8, 31, 8, 8) Margins are offset, artifacts visible Conclusion ========== The example tries to achieve a frameless window by custom handling of the WM_NCCALCSIZE (as opposed to the normal style flags) and WM_NCCHITTEST for window border detection. Motivation for this is to have a frameless mainwindow for which the WM features (Aero snap/Shake) work . More precisely, WS_THICKFRAME is required to make Aero left snap (Windows Key + Left Arrow) work. For this, it is not sufficient to set Qt::FramelessWindowHint and handling only WM_NCCHITTEST to fake resizable/movable window borders. Additional quirk here to be observed: - Qt 5: Setting flags() | Qt::FramelessWindowHint results in "0x960b0000 WS_POPUP WS_CLIPSIBLINGS WS_CLIPCHILDREN WS_SYSMENU WS_MINIMIZEBOX WS_MAXIMIZEBOX" and this causes returning borders in WM_NCCHITTEST not to work; only 2 (CAPTION) works (allowing to move the window). One needs to set Qt::FramelessWindowHint as the only window flag (-of), resulting in "0x96000000 WS_POPUP WS_CLIPSIBLINGS WS_CLIPCHILDREN". The WM_NCCHITTEST will then work as expected including resizable borders. [Note: THis is the only way to achieve a frameless window in Qt 4]. The *right* solution here would be to somehow reflect that in Qt's WindowFlags as an additional hint and do it in the QPA plugin as this custom message handling clashes with Qt' handling (and it therefore not supported). However, Qt::Window_Type is full (all 32bits are used). When modifying the frames using WM_NCCALCSIZE, the size constraints (minimum size of windows with caption) still apply, that is , it can therefore NOT be made the default behaviour of Windows for which (type & Qt::Popup) == 0 or similar. The artifacts arise from the fact that the window margins are offset by the custom handling of WM_NCCALCSIZE, which Qt does not notice (Window margins are calculated from the style on Windows). Basically, this appears to work in Qt 4 when the initial style is set to completely frameless, so that Qt apparently stores/caches the zero margin before the Aero setting is done. In Qt 5, the margins are always recalculated depending on current style and so non-zero margins result since the Aero style has margins. A crude workaround might be to always return zero margins when the Qt::FramelessWindowHint is set, ignoring the actual style.