@@ -82,7 +82,6 @@ using namespace QNativeInterface::Private;
8282using namespace Qt ::StringLiterals;
8383
8484Q_LOGGING_CATEGORY (lcWidgetPainting, " qt.widgets.painting" , QtWarningMsg);
85- Q_LOGGING_CATEGORY (lcWidgetWindow, " qt.widgets.window" , QtWarningMsg);
8685
8786static inline bool qRectIntersects (const QRect &r1, const QRect &r2)
8887{
@@ -1027,23 +1026,6 @@ void QWidgetPrivate::createRecursively()
10271026 }
10281027}
10291028
1030- /* !
1031- \internal
1032- Returns the closest parent widget that has a QWindow window handle
1033-
1034- \note This behavior is different from nativeParentWidget(), which
1035- returns the closest parent that has a QWindow window handle with
1036- a created QPlatformWindow, and hence native window (winId).
1037- */
1038- QWidget *QWidgetPrivate::closestParentWidgetWithWindowHandle () const
1039- {
1040- Q_Q (const QWidget);
1041- QWidget *parent = q->parentWidget ();
1042- while (parent && !parent->windowHandle ())
1043- parent = parent->parentWidget ();
1044- return parent;
1045- }
1046-
10471029QWindow *QWidgetPrivate::windowHandle (WindowHandleMode mode) const
10481030{
10491031 if (mode == WindowHandleMode::Direct || mode == WindowHandleMode::Closest) {
@@ -1053,7 +1035,6 @@ QWindow *QWidgetPrivate::windowHandle(WindowHandleMode mode) const
10531035 }
10541036 }
10551037 if (mode == WindowHandleMode::Closest) {
1056- // FIXME: Use closestParentWidgetWithWindowHandle instead
10571038 if (auto nativeParent = q_func ()->nativeParentWidget ()) {
10581039 if (auto window = nativeParent->windowHandle ())
10591040 return window;
@@ -10880,61 +10861,57 @@ void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f)
1088010861
1088110862 setWinId (0 );
1088210863
10864+ if (parent != newparent) {
10865+ QObjectPrivate::setParent_helper (newparent); // ### why does this have to be done in the _sys function???
10866+ if (q->windowHandle ()) {
10867+ q->windowHandle ()->setFlags (f);
10868+ QWidget *parentWithWindow =
10869+ newparent ? (newparent->windowHandle () ? newparent : newparent->nativeParentWidget ()) : nullptr ;
10870+ if (parentWithWindow) {
10871+ QWidget *topLevel = parentWithWindow->window ();
10872+ if ((f & Qt::Window) && topLevel && topLevel->windowHandle ()) {
10873+ q->windowHandle ()->setTransientParent (topLevel->windowHandle ());
10874+ q->windowHandle ()->setParent (nullptr );
10875+ } else {
10876+ q->windowHandle ()->setTransientParent (nullptr );
10877+ q->windowHandle ()->setParent (parentWithWindow->windowHandle ());
10878+ }
10879+ } else {
10880+ q->windowHandle ()->setTransientParent (nullptr );
10881+ q->windowHandle ()->setParent (nullptr );
10882+ }
10883+ }
10884+ }
10885+
1088310886 if (!newparent) {
1088410887 f |= Qt::Window;
1088510888 if (parent)
1088610889 targetScreen = q->parentWidget ()->window ()->screen ();
1088710890 }
1088810891
10889- const bool destroyWindow = (
10890- // Reparenting top level to child
10891- (oldFlags & Qt::Window) && !(f & Qt::Window)
10892- // And we can dispose of the window
10893- && wasCreated && !q->testAttribute (Qt::WA_NativeWindow)
10894- );
10895-
10896- if (parent != newparent) {
10897- // Update object parent now, so we can resolve new parent window below
10898- QObjectPrivate::setParent_helper (newparent);
10899-
10900- if (q->windowHandle ())
10901- q->windowHandle ()->setFlags (f);
10902-
10903- // If the widget itself or any of its children have been created,
10904- // we need to reparent their QWindows as well.
10905- QWidget *parentWithWindow = closestParentWidgetWithWindowHandle ();
10906- // But if the widget is about to be destroyed we must skip the
10907- // widget itself, and only reparent children.
10908- if (destroyWindow)
10909- reparentWidgetWindowChildren (parentWithWindow);
10910- else
10911- reparentWidgetWindows (parentWithWindow, f);
10912- }
10913-
1091410892 bool explicitlyHidden = q->testAttribute (Qt::WA_WState_Hidden) && q->testAttribute (Qt::WA_WState_ExplicitShowHide);
1091510893
10916- if (destroyWindow) {
10894+ // Reparenting toplevel to child
10895+ if (wasCreated && !(f & Qt::Window) && (oldFlags & Qt::Window) && !q->testAttribute (Qt::WA_NativeWindow)) {
1091710896 if (extra && extra->hasWindowContainer )
1091810897 QWindowContainer::toplevelAboutToBeDestroyed (q);
1091910898
10920- // There shouldn't be any QWindow children left, but if there
10921- // are, re-parent them now, before we destroy.
10922- if (!q->windowHandle ()->children ().isEmpty ()) {
10923- QWidget *parentWithWindow = closestParentWidgetWithWindowHandle ();
10924- QWindow *newParentWindow = parentWithWindow ? parentWithWindow->windowHandle () : nullptr ;
10925- for (QObject *child : q->windowHandle ()->children ()) {
10926- if (QWindow *childWindow = qobject_cast<QWindow *>(child)) {
10927- qCWarning (lcWidgetWindow) << " Reparenting" << childWindow
10928- << " before destroying" << this ;
10929- childWindow->setParent (newParentWindow);
10930- }
10931- }
10932- }
10899+ QWindow *newParentWindow = newparent->windowHandle ();
10900+ if (!newParentWindow)
10901+ if (QWidget *npw = newparent->nativeParentWidget ())
10902+ newParentWindow = npw->windowHandle ();
1093310903
10934- // We have reparented any child windows of the widget we are
10935- // about to destroy to the new parent window handle, so we can
10936- // safely destroy this widget without destroying sub windows.
10937- q->destroy (true , false );
10904+ for (QObject *child : q->windowHandle ()->children ()) {
10905+ QWindow *childWindow = qobject_cast<QWindow *>(child);
10906+ if (!childWindow)
10907+ continue ;
10908+
10909+ QWidgetWindow *childWW = qobject_cast<QWidgetWindow *>(childWindow);
10910+ QWidget *childWidget = childWW ? childWW->widget () : nullptr ;
10911+ if (!childWW || (childWidget && childWidget->testAttribute (Qt::WA_NativeWindow)))
10912+ childWindow->setParent (newParentWindow);
10913+ }
10914+ q->destroy ();
1093810915 }
1093910916
1094010917 adjustFlags (f, q);
@@ -10960,53 +10937,6 @@ void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f)
1096010937 }
1096110938}
1096210939
10963- void QWidgetPrivate::reparentWidgetWindows (QWidget *parentWithWindow, Qt::WindowFlags windowFlags)
10964- {
10965- if (QWindow *window = windowHandle ()) {
10966- // Reparent this QWindow, and all QWindow children will follow
10967- if (parentWithWindow) {
10968- // The reparented widget has not updated its window flags yet,
10969- // so we can't ask the widget directly. And we can't use the
10970- // QWindow flags, as unlike QWidgets the QWindow flags always
10971- // reflect Qt::Window, even for child windows. And we can't use
10972- // QWindow::isTopLevel() either, as that depends on the parent,
10973- // which we are in the process of updating. So we propagate the
10974- // new flags of the reparented window from setParent_sys().
10975- if (windowFlags & Qt::Window) {
10976- // Top level windows can only have transient parents,
10977- // and the transient parent must be another top level.
10978- QWidget *topLevel = parentWithWindow->window ();
10979- auto *transientParent = topLevel->windowHandle ();
10980- Q_ASSERT (transientParent);
10981- qCDebug (lcWidgetWindow) << " Setting" << window << " transient parent to" << transientParent;
10982- window->setTransientParent (transientParent);
10983- window->setParent (nullptr );
10984- } else {
10985- auto *parentWindow = parentWithWindow->windowHandle ();
10986- qCDebug (lcWidgetWindow) << " Reparenting" << window << " into" << parentWindow;
10987- window->setTransientParent (nullptr );
10988- window->setParent (parentWindow);
10989- }
10990- } else {
10991- qCDebug (lcWidgetWindow) << " Making" << window << " top level window" ;
10992- window->setTransientParent (nullptr );
10993- window->setParent (nullptr );
10994- }
10995- } else {
10996- reparentWidgetWindowChildren (parentWithWindow);
10997- }
10998- }
10999-
11000- void QWidgetPrivate::reparentWidgetWindowChildren (QWidget *parentWithWindow)
11001- {
11002- for (auto *child : std::as_const (children)) {
11003- if (auto *childWidget = qobject_cast<QWidget*>(child)) {
11004- auto *childPrivate = QWidgetPrivate::get (childWidget);
11005- childPrivate->reparentWidgetWindows (parentWithWindow);
11006- }
11007- }
11008- }
11009-
1101010940/* !
1101110941 Scrolls the widget including its children \a dx pixels to the
1101210942 right and \a dy downward. Both \a dx and \a dy may be negative.
0 commit comments