XCB/Windows: Decouple foreign window from QWindow parent on destroy
Qt's foreign windows do not take (full) ownership of the native handle, so our platform window implementations take care to not fully destroy the native handle in their destructors. But if the foreign window had a QWindow parent at the time of destruction, and we fail to decouple the native handle from its native handle parent, the destruction of the QWindow parent may bring down the foreign window native handle as well, as part of deleting the parent QWindow's native handle. We take care to selectively do this decoupling on macOS, iOS, and Android, but were failing to do so on XCB and Windows. This has now been corrected, which allows us to remove the workaround in QWindow, which was also in the wrong place (before setVisible(false) on the foreign window child). Note that we do not unconditionally reparent the foreign window, as it might be a foreign window used for containing other QWindows, in which case we don't want to mess with the native view hierarchy. Change-Id: Ic526ca63fbf72dae5013ae9e44cb5cddf61c944b Reviewed-by: Liang Qi <liang.qi@qt.io> (cherry picked from commit 8f8ce8d7a7e029e62a4f9b5b209dcc37f61410cb) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
fb6cfadc38
commit
046cc59aee
@ -2083,16 +2083,6 @@ void QWindowPrivate::destroy()
|
||||
QObject *object = childrenWindows.at(i);
|
||||
if (object->isWindowType()) {
|
||||
QWindow *w = static_cast<QWindow*>(object);
|
||||
auto *childPlatformWindow = w->handle();
|
||||
if (!childPlatformWindow)
|
||||
continue;
|
||||
|
||||
// Decouple the foreign window from this window,
|
||||
// so that destroying our native handle doesn't
|
||||
// bring down the foreign window as well.
|
||||
if (childPlatformWindow->isForeignWindow())
|
||||
childPlatformWindow->setParent(nullptr);
|
||||
|
||||
qt_window_private(w)->destroy();
|
||||
}
|
||||
}
|
||||
|
@ -1364,6 +1364,12 @@ QWindowsForeignWindow::QWindowsForeignWindow(QWindow *window, HWND hwnd)
|
||||
setParent(QPlatformWindow::parent());
|
||||
}
|
||||
|
||||
QWindowsForeignWindow::~QWindowsForeignWindow()
|
||||
{
|
||||
if (QPlatformWindow::parent())
|
||||
setParent(nullptr);
|
||||
}
|
||||
|
||||
void QWindowsForeignWindow::setParent(const QPlatformWindow *newParentWindow)
|
||||
{
|
||||
const bool wasTopLevel = isTopLevel_sys();
|
||||
|
@ -160,6 +160,7 @@ class QWindowsForeignWindow : public QWindowsBaseWindow
|
||||
{
|
||||
public:
|
||||
explicit QWindowsForeignWindow(QWindow *window, HWND hwnd);
|
||||
~QWindowsForeignWindow();
|
||||
|
||||
void setParent(const QPlatformWindow *window) override;
|
||||
void setGeometry(const QRect &rect) override { setGeometry_sys(rect); }
|
||||
|
@ -530,6 +530,9 @@ QXcbForeignWindow::QXcbForeignWindow(QWindow *window, WId nativeHandle)
|
||||
|
||||
QXcbForeignWindow::~QXcbForeignWindow()
|
||||
{
|
||||
if (QPlatformWindow::parent())
|
||||
setParent(nullptr);
|
||||
|
||||
// Clear window so that destroy() does not affect it
|
||||
m_window = 0;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user