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 <2546789017@qq.com> Reviewed-by: Wladimir Leuschner <wladimir.leuschner@qt.io> Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> Reviewed-by: Pavel Dubsky <pavel.dubsky@qt.io>
This commit is contained in:
parent
312215ba87
commit
33d1ac4095
@ -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()
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user