Skip to content

Commit 0619513

Browse files
authored
Fix native child widget (#133)
* Fix WM_NCCALCSIZE handler * Add comment
1 parent be3c667 commit 0619513

File tree

2 files changed

+14
-12
lines changed

2 files changed

+14
-12
lines changed

README.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -276,17 +276,14 @@ See [examples](examples) for more demo use cases. The examples have no High DPI
276276
- Once you have made the window frameless, it will not be able to switch back to the system frame again unless you destroy your window and recreate it with different settings.
277277

278278
#### Native Child Widget
279-
- There **must not** be any internal child widget with `Qt::WA_NativeWindow` property enabled, otherwise the native features and display may be abnormal. Therefore, do not set any widget that has called `QWidget::winId()` or `QWidget::setAttribute(Qt::WA_NativeWindow)` as a descendant of a frameless window.
280-
- If you really need to move widgets between different windows, make sure that the widget is not a top-level window and wrap it with a frameless container window.
279+
- If you are about to add a widget with `Qt::WA_NativeWindow` property enabled as a descendent of the frameless window, you should enable `Qt::WA_DontCreateNativeAncestors` of it in advance.
281280

282281
#### Size Constrains
283282
- If you want to disable window resizing, you can set a fixed size, which is officially supported by QWindowKit. If you use other special means to achieve this, QWK doesn't guarantee everything can still be fully functional.
284283
- If you set a maximized width or height, the window should not be maximized because you cannot get the correct window size through Qt APIs. You may workaround this by using system APIs such as `GetWindowRect` or `GetClientRect`. The root cause lies deep in Qt QPA implementations and currently we don't know how to fix it without modifying Qt itself.
285284

286285
#### Windows 10
287-
288286
- Due to the inherent defects in the Windows 10 window system, the top border will disappear when the system title bar is removed. We have filtered Qt's event and perfectly reshown the system top border, thanks to the implementation of Windows Terminal for our reference. However, this workaround only works with QtWidgets and QtQuick (**only when rendering through D3D**) applications.
289-
290287
- In QtQuick applications that use OpenGL or other rendering backends, we use Qt's painting system to emulate this border. But since Windows 10 system border is translucent, the difference from the system border is more noticeable in a dark background.
291288

292289
## TODO

src/core/contexts/win32windowcontext.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -834,9 +834,7 @@ namespace QWK {
834834
}
835835

836836
if (key == QStringLiteral("title-bar-height")) {
837-
return m_windowId
838-
? int(getTitleBarHeight(reinterpret_cast<HWND>(m_windowId)))
839-
: 0;
837+
return m_windowId ? int(getTitleBarHeight(reinterpret_cast<HWND>(m_windowId))) : 0;
840838
}
841839
return AbstractWindowContext::windowAttribute(key);
842840
}
@@ -1695,7 +1693,8 @@ namespace QWK {
16951693
// outside the window, that is, the three transparent window resize area.
16961694
// Returning HTCLIENT will confuse Windows, we can't put our controls there
16971695
// anyway.
1698-
*result = HTNOWHERE; // Make sure we can know we don't set any value explicitly later.
1696+
*result = HTNOWHERE; // Make sure we can know we don't set any value
1697+
// explicitly later.
16991698
if (originalHitTestResult == HTCAPTION) {
17001699
} else if (isFixedSize || dontOverrideCursor) {
17011700
*result = HTBORDER;
@@ -1724,11 +1723,13 @@ namespace QWK {
17241723
} else {
17251724
*result = HTLEFT;
17261725
}
1727-
} else if (originalHitTestResult == HTLEFT || originalHitTestResult == HTRIGHT) {
1726+
} else if (originalHitTestResult == HTLEFT ||
1727+
originalHitTestResult == HTRIGHT) {
17281728
if (isFixedWidth) {
17291729
*result = HTBORDER;
17301730
}
1731-
} else if (originalHitTestResult == HTTOP || originalHitTestResult == HTBOTTOM) {
1731+
} else if (originalHitTestResult == HTTOP ||
1732+
originalHitTestResult == HTBOTTOM) {
17321733
if (isFixedHeight) {
17331734
*result = HTBORDER;
17341735
}
@@ -1757,7 +1758,8 @@ namespace QWK {
17571758
// inside our homemade title bar now, return HTCLIENT to let our
17581759
// title bar can still capture mouse events.
17591760
*result = [&]() {
1760-
if (isFixedSize || isFixedHeight || dontOverrideCursor || (isFixedWidth && (isInLeftBorder || isInRightBorder))) {
1761+
if (isFixedSize || isFixedHeight || dontOverrideCursor ||
1762+
(isFixedWidth && (isInLeftBorder || isInRightBorder))) {
17611763
if (isInTitleBar) {
17621764
return HTCAPTION;
17631765
} else {
@@ -2173,7 +2175,10 @@ namespace QWK {
21732175
// of the upper-left non-client area. It's confirmed that this issue exists
21742176
// from Windows 7 to Windows 10. Not tested on Windows 11 yet. Don't know
21752177
// whether it exists on Windows XP to Windows Vista or not.
2176-
*result = wParam ? WVR_REDRAW : FALSE;
2178+
2179+
// https://github.com/chromium/chromium/blob/5d297da3cf2a642e9ace2b23fed097370bc70814/ui/views/win/hwnd_message_handler.cc#L2330
2180+
// Do not return WVR_REDRAW otherwise child HWNDs will be mispositioned.
2181+
*result = FALSE;
21772182
return true;
21782183
}
21792184

0 commit comments

Comments
 (0)