Skip to content

Commit 886d1f5

Browse files
senthilauto2023GitHub Enterprise
authored and
GitHub Enterprise
committed
Revert "MAYA-132611: Crash when docking the Select a light source (qt#102)" (qt#105)
#28746 was made to use an older artifact for Maya 2025.2 to save precious hours that would have been otherwise spent on waiting for the Qt build to complete. This PR aims to solve it properly by reverting the offending change specifically. This also allows us to resolve MAYA-132068 This reverts commit aaca5d7.
1 parent f2b8467 commit 886d1f5

File tree

3 files changed

+39
-293
lines changed

3 files changed

+39
-293
lines changed

Diff for: src/widgets/kernel/qwidget.cpp

+39-109
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ using namespace QNativeInterface::Private;
8282
using namespace Qt::StringLiterals;
8383

8484
Q_LOGGING_CATEGORY(lcWidgetPainting, "qt.widgets.painting", QtWarningMsg);
85-
Q_LOGGING_CATEGORY(lcWidgetWindow, "qt.widgets.window", QtWarningMsg);
8685

8786
static 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-
10471029
QWindow *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.

Diff for: src/widgets/kernel/qwidget_p.h

-4
Original file line numberDiff line numberDiff line change
@@ -367,8 +367,6 @@ class Q_WIDGETS_EXPORT QWidgetPrivate : public QObjectPrivate
367367
void showChildren(bool spontaneous);
368368
void hideChildren(bool spontaneous);
369369
void setParent_sys(QWidget *parent, Qt::WindowFlags);
370-
void reparentWidgetWindows(QWidget *parentWithWindow, Qt::WindowFlags windowFlags = {});
371-
void reparentWidgetWindowChildren(QWidget *parentWithWindow);
372370
void scroll_sys(int dx, int dy);
373371
void scroll_sys(int dx, int dy, const QRect &r);
374372
void deactivateWidgetCleanup();
@@ -635,8 +633,6 @@ class Q_WIDGETS_EXPORT QWidgetPrivate : public QObjectPrivate
635633

636634
std::string flagsForDumping() const override;
637635

638-
QWidget *closestParentWidgetWithWindowHandle() const;
639-
640636
// Variables.
641637
// Regular pointers (keep them together to avoid gaps on 64 bit architectures).
642638
std::unique_ptr<QWExtra> extra;

0 commit comments

Comments
 (0)