diff options
author | Tor Arne Vestbø <[email protected]> | 2025-05-08 10:22:40 +0200 |
---|---|---|
committer | Tor Arne Vestbø <[email protected]> | 2025-05-15 07:54:00 +0000 |
commit | 33d1ac4095755f6faac0562882b1977f48d79a9f (patch) | |
tree | 8f6c43b70832f2febde6694da0b68d0fdc2139d9 | |
parent | 312215ba87b00b0065babe1cf190980e2d9dbc4a (diff) |
Windows: Detect lack of WS_CLIPCHILDREN when adding child windows
The lack of WS_CLIPCHILDREN will cause drawing artifacts, so ensure
we have WS_CLIPCHILDREN in our native window manual tests, and warn
if users inadvertently end up reparenting windows into a HWND that
doesn't have WS_CLIPCHILDREN set.
Change-Id: Ic4dac83882167562599d63f46232071c8c21b617
Reviewed-by: Zhao Yuhang <[email protected]>
Reviewed-by: Wladimir Leuschner <[email protected]>
Reviewed-by: Oliver Wolff <[email protected]>
Reviewed-by: Pavel Dubsky <[email protected]>
-rw-r--r-- | src/plugins/platforms/windows/qwindowswindow.cpp | 20 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowswindow.h | 2 | ||||
-rw-r--r-- | tests/manual/embeddedwindows/main.cpp | 9 | ||||
-rw-r--r-- | tests/shared/nativewindow.h | 2 |
4 files changed, 22 insertions, 11 deletions
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index cf22783c286..22277af52bb 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1402,6 +1402,24 @@ void QWindowsBaseWindow::setCustomMargins(const QMargins &) Q_UNIMPLEMENTED(); } +bool QWindowsBaseWindow::windowEvent(QEvent *event) +{ + switch (event->type()) { + case QEvent::ChildWindowAdded: + if (!(GetWindowLongPtr(handle(), GWL_STYLE) & WS_CLIPCHILDREN)) { + auto *childWindowEvent = static_cast<QChildWindowEvent*>(event); + qWarning() << childWindowEvent->child() << "added as child to" + << window() << "which does not have WS_CLIPCHILDREN set." + << "This will result in drawing artifacts!"; + } + break; + default: + break; + } + + return QPlatformWindow::windowEvent(event); +} + /*! \class QWindowsDesktopWindow \brief Window wrapping GetDesktopWindow not allowing any manipulation. @@ -2928,7 +2946,7 @@ bool QWindowsWindow::windowEvent(QEvent *event) break; } - return QPlatformWindow::windowEvent(event); + return QWindowsBaseWindow::windowEvent(event); } void QWindowsWindow::propagateSizeHints() diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index 7805530681a..a384b4b1c7a 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -126,6 +126,8 @@ public: static QWindowsBaseWindow *baseWindowOf(const QWindow *w); static HWND handleOf(const QWindow *w); + bool windowEvent(QEvent *event) override; + protected: HWND parentHwnd() const { return GetAncestor(handle(), GA_PARENT); } bool isTopLevel_sys() const; diff --git a/tests/manual/embeddedwindows/main.cpp b/tests/manual/embeddedwindows/main.cpp index c88d1ddb99d..e34c7206eaa 100644 --- a/tests/manual/embeddedwindows/main.cpp +++ b/tests/manual/embeddedwindows/main.cpp @@ -93,15 +93,6 @@ int main(int argc, char *argv[]) NativeWindow nativeParentWindow; if (QWindow *foreignWindow = QWindow::fromWinId(nativeParentWindow)) { - -#ifdef Q_OS_WIN - // Native parent windows should have WS_CLIPCHILDREN style set - // to prevent overdrawing child area and cause flickering. - const HWND hwnd = reinterpret_cast<HWND>(foreignWindow->winId()); - const LONG_PTR oldStyle = GetWindowLongPtr(hwnd, GWL_STYLE); - SetWindowLongPtr(hwnd, GWL_STYLE, oldStyle | WS_CLIPCHILDREN); -#endif - foreignWindow->setParent(&window); foreignWindow->setGeometry(50, 350, 100, 100); foreignWindow->showNormal(); diff --git a/tests/shared/nativewindow.h b/tests/shared/nativewindow.h index 163ca316347..c119280cb67 100644 --- a/tests/shared/nativewindow.h +++ b/tests/shared/nativewindow.h @@ -133,7 +133,7 @@ NativeWindow::NativeWindow() RegisterClass(&wc); return wc.lpszClassName; }(); - m_handle = CreateWindowEx(0, className, nullptr, WS_POPUP, + m_handle = CreateWindowEx(0, className, nullptr, WS_POPUP | WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, GetModuleHandle(nullptr), nullptr); } |