QWindow: don't destroy foreign windows
Calling QWindow::destroy() is documented to "release the native platform resources associated with this window.", but in the case of foreign windows we do not control the native platform resource, so we shouldn't destroy the platform window until the QWindow is destroyed. This also allows code paths to defer to the platform window to answer questions like winId() instead of having to duplicate the ID on the QWindow side in _q_foreignWinId. Change-Id: Ie00ee570bdddde958d97d49edcba2bc1bf519a99 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
parent
a57f2128b1
commit
0c6911e5cd
@ -208,7 +208,8 @@ QWindow::QWindow(QWindowPrivate &dd, QWindow *parent)
|
|||||||
*/
|
*/
|
||||||
QWindow::~QWindow()
|
QWindow::~QWindow()
|
||||||
{
|
{
|
||||||
destroy();
|
Q_D(QWindow);
|
||||||
|
d->destroy();
|
||||||
QGuiApplicationPrivate::window_list.removeAll(this);
|
QGuiApplicationPrivate::window_list.removeAll(this);
|
||||||
if (!QGuiApplicationPrivate::is_app_closing)
|
if (!QGuiApplicationPrivate::is_app_closing)
|
||||||
QGuiApplicationPrivate::instance()->modalWindowList.removeOne(this);
|
QGuiApplicationPrivate::instance()->modalWindowList.removeOne(this);
|
||||||
@ -1762,42 +1763,54 @@ void QWindow::destroy()
|
|||||||
if (!d->platformWindow)
|
if (!d->platformWindow)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QObjectList childrenWindows = children();
|
if (d->platformWindow->isForeignWindow())
|
||||||
|
return;
|
||||||
|
|
||||||
|
d->destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWindowPrivate::destroy()
|
||||||
|
{
|
||||||
|
if (!platformWindow)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Q_Q(QWindow);
|
||||||
|
QObjectList childrenWindows = q->children();
|
||||||
for (int i = 0; i < childrenWindows.size(); i++) {
|
for (int i = 0; i < childrenWindows.size(); i++) {
|
||||||
QObject *object = childrenWindows.at(i);
|
QObject *object = childrenWindows.at(i);
|
||||||
if (object->isWindowType()) {
|
if (object->isWindowType()) {
|
||||||
QWindow *w = static_cast<QWindow*>(object);
|
QWindow *w = static_cast<QWindow*>(object);
|
||||||
w->destroy();
|
qt_window_private(w)->destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (QGuiApplicationPrivate::focus_window == this)
|
if (QGuiApplicationPrivate::focus_window == q)
|
||||||
QGuiApplicationPrivate::focus_window = parent();
|
QGuiApplicationPrivate::focus_window = q->parent();
|
||||||
if (QGuiApplicationPrivate::currentMouseWindow == this)
|
if (QGuiApplicationPrivate::currentMouseWindow == q)
|
||||||
QGuiApplicationPrivate::currentMouseWindow = parent();
|
QGuiApplicationPrivate::currentMouseWindow = q->parent();
|
||||||
if (QGuiApplicationPrivate::currentMousePressWindow == this)
|
if (QGuiApplicationPrivate::currentMousePressWindow == q)
|
||||||
QGuiApplicationPrivate::currentMousePressWindow = parent();
|
QGuiApplicationPrivate::currentMousePressWindow = q->parent();
|
||||||
|
|
||||||
for (int i = 0; i < QGuiApplicationPrivate::tabletDevicePoints.size(); ++i)
|
for (int i = 0; i < QGuiApplicationPrivate::tabletDevicePoints.size(); ++i)
|
||||||
if (QGuiApplicationPrivate::tabletDevicePoints.at(i).target == this)
|
if (QGuiApplicationPrivate::tabletDevicePoints.at(i).target == q)
|
||||||
QGuiApplicationPrivate::tabletDevicePoints[i].target = parent();
|
QGuiApplicationPrivate::tabletDevicePoints[i].target = q->parent();
|
||||||
|
|
||||||
bool wasVisible = isVisible();
|
bool wasVisible = q->isVisible();
|
||||||
d->visibilityOnDestroy = wasVisible && d->platformWindow;
|
visibilityOnDestroy = wasVisible && platformWindow;
|
||||||
|
|
||||||
setVisible(false);
|
q->setVisible(false);
|
||||||
|
|
||||||
QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed);
|
QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed);
|
||||||
QGuiApplication::sendEvent(this, &e);
|
QGuiApplication::sendEvent(q, &e);
|
||||||
|
|
||||||
delete d->platformWindow;
|
delete platformWindow;
|
||||||
d->resizeEventPending = true;
|
resizeEventPending = true;
|
||||||
d->receivedExpose = false;
|
receivedExpose = false;
|
||||||
d->exposed = false;
|
exposed = false;
|
||||||
d->platformWindow = 0;
|
platformWindow = 0;
|
||||||
|
|
||||||
if (wasVisible)
|
if (wasVisible)
|
||||||
d->maybeQuitOnLastWindowClosed();
|
maybeQuitOnLastWindowClosed();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -137,6 +137,7 @@ public:
|
|||||||
|
|
||||||
bool windowRecreationRequired(QScreen *newScreen) const;
|
bool windowRecreationRequired(QScreen *newScreen) const;
|
||||||
void create(bool recursive);
|
void create(bool recursive);
|
||||||
|
void destroy();
|
||||||
void setTopLevelScreen(QScreen *newScreen, bool recreate);
|
void setTopLevelScreen(QScreen *newScreen, bool recreate);
|
||||||
void connectToScreen(QScreen *topLevelScreen);
|
void connectToScreen(QScreen *topLevelScreen);
|
||||||
void disconnectFromScreen();
|
void disconnectFromScreen();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user