Revert "QWindow: Persist foreign winId to support destroy/create cycles"

This reverts commit 4d5aedac1de02ec21bc6f4ae8c66e1e7bfc665a4.

It broke window activation on iOS somehow.

Change-Id: I01fc476d23a65f39aa33d9abd06417ffcd13b5aa
Task-number: QTBUG-125142
Reviewed-by: Jani Heikkinen <jani.heikkinen@qt.io>
This commit is contained in:
Tor Arne Vestbø 2024-05-08 09:42:08 +00:00 committed by The Qt Project
parent 3eb0c8007c
commit c195fe7d33
7 changed files with 5 additions and 78 deletions

View File

@ -521,9 +521,7 @@ void QWindowPrivate::setTopLevelScreen(QScreen *newScreen, bool recreate)
}
}
static constexpr auto kForeignWindowId = "_q_foreignWinId";
void QWindowPrivate::create(bool recursive)
void QWindowPrivate::create(bool recursive, WId nativeHandle)
{
Q_Q(QWindow);
if (platformWindow)
@ -551,8 +549,6 @@ void QWindowPrivate::create(bool recursive)
setTopLevelScreen(screen, false);
}
const WId nativeHandle = q->property(kForeignWindowId).value<WId>();
QPlatformIntegration *platformIntegration = QGuiApplicationPrivate::platformIntegration();
platformWindow = nativeHandle ? platformIntegration->createForeignWindow(q, nativeHandle)
: platformIntegration->createPlatformWindow(q);
@ -2063,16 +2059,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();
}
}
@ -3000,11 +2986,7 @@ QWindow *QWindow::fromWinId(WId id)
}
QWindow *window = new QWindow;
// Persist the winId in a private property so that we
// can recreate the window after being destroyed.
window->setProperty(kForeignWindowId, id);
window->create();
qt_window_private(window)->create(false, id);
if (!window->handle()) {
delete window;

View File

@ -66,7 +66,7 @@ public:
void updateSiblingPosition(SiblingPosition);
bool windowRecreationRequired(QScreen *newScreen) const;
void create(bool recursive);
void create(bool recursive, WId nativeHandle = 0);
void destroy();
void setTopLevelScreen(QScreen *newScreen, bool recreate);
void connectToScreen(QScreen *topLevelScreen);

View File

@ -55,8 +55,7 @@ QIOSWindow::QIOSWindow(QWindow *window, WId nativeHandle)
connect(qGuiApp, &QGuiApplication::applicationStateChanged, this, &QIOSWindow::applicationStateChanged);
if (QPlatformWindow::parent())
setParent(QPlatformWindow::parent());
setParent(QPlatformWindow::parent());
if (!isForeignWindow()) {
// Resolve default window geometry in case it was not set before creating the

View File

@ -1357,8 +1357,6 @@ QWindowsForeignWindow::QWindowsForeignWindow(QWindow *window, HWND hwnd)
, m_hwnd(hwnd)
, m_topLevelStyle(0)
{
if (QPlatformWindow::parent())
setParent(QPlatformWindow::parent());
}
void QWindowsForeignWindow::setParent(const QPlatformWindow *newParentWindow)

View File

@ -522,10 +522,6 @@ QXcbForeignWindow::QXcbForeignWindow(QWindow *window, WId nativeHandle)
QRect nativeGeometry(geometry->x, geometry->y, geometry->width, geometry->height);
QPlatformWindow::setGeometry(nativeGeometry);
}
// And reparent, if we have a parent already
if (QPlatformWindow::parent())
setParent(QPlatformWindow::parent());
}
QXcbForeignWindow::~QXcbForeignWindow()

View File

@ -26,9 +26,6 @@ private slots:
void embedForeignWindow();
void embedInForeignWindow();
void destroyExplicitly();
void destroyWhenParentIsDestroyed();
};
void tst_ForeignWindow::fromWinId()
@ -141,50 +138,5 @@ void tst_ForeignWindow::embedInForeignWindow()
}
}
void tst_ForeignWindow::destroyExplicitly()
{
NativeWindow nativeWindow;
QVERIFY(nativeWindow);
std::unique_ptr<QWindow> foreignWindow(QWindow::fromWinId(nativeWindow));
QVERIFY(foreignWindow->handle());
// Explicitly destroying a foreign window is a no-op, as
// the documentation claims that it "releases the native
// platform resources associated with this window.", which
// is not technically true for foreign windows.
auto *windowHandleBeforeDestroy = foreignWindow->handle();
foreignWindow->destroy();
QCOMPARE(foreignWindow->handle(), windowHandleBeforeDestroy);
}
void tst_ForeignWindow::destroyWhenParentIsDestroyed()
{
QWindow parentWindow;
NativeWindow nativeWindow;
QVERIFY(nativeWindow);
std::unique_ptr<QWindow> foreignWindow(QWindow::fromWinId(nativeWindow));
foreignWindow->setParent(&parentWindow);
QTRY_COMPARE(nativeWindow.parentWinId(), parentWindow.winId());
// Reparenting into a window will result in creating it
QVERIFY(parentWindow.handle());
// Destroying the parent window of the foreign window results
// in destroying the foreign window as well, as the foreign
// window no longer has a parent it can be embedded in.
QVERIFY(foreignWindow->handle());
parentWindow.destroy();
QVERIFY(!foreignWindow->handle());
// But the foreign window can be recreated again, and will
// continue to be a native child of the parent window.
foreignWindow->create();
QVERIFY(foreignWindow->handle());
QTRY_COMPARE(nativeWindow.parentWinId(), parentWindow.winId());
}
#include <tst_foreignwindow.moc>
QTEST_MAIN(tst_ForeignWindow)

View File

@ -238,7 +238,7 @@ WId NativeWindow::parentWinId() const
xcb_query_tree_reply_t *tree = xcb_query_tree_reply(
connection, xcb_query_tree(connection, m_handle), nullptr);
const auto cleanup = qScopeGuard([&]{ free(tree); });
return tree ? tree->parent : 0;
return tree->parent;
}
bool NativeWindow::isParentOf(WId childWinId)