diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2021-09-24 23:33:27 +0200 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2021-09-28 17:42:57 +0200 |
commit | 223066d4319d611e724da69089c8f49d525a2566 (patch) | |
tree | 2f103445b1ff04db0aaef7020a45327fefbce880 /src/widgets/kernel/qwidget.cpp | |
parent | 5e2725772aa25e0ee95269c8f996fdb7bc4705e7 (diff) |
Don't clear focus if setParent doesn't change the parent
QWidget::setParent might be called to change the window flags, without
changing the parent. For those cases, we don't have to clear the focus.
Decouple the newParent state from the wasCreated flag. In most places
where newParent was tested, wasCreated was either tested previously and
can't be false anyway, or the code executed is irrelevant for widgets
that are not yet created (there can't be a paint manager). In the
remaining case, test wasCreated explicitly to maintain existing logic.
Add test for the cases where the previous code broke the focus, both
for QWidget and QDialog.
Fixes: QTBUG-93005
Pick-to: 6.2
Change-Id: I39dc179c2d348054de3927aa8b69eecef4935511
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
Reviewed-by: Doris Verria <doris.verria@qt.io>
Diffstat (limited to 'src/widgets/kernel/qwidget.cpp')
-rw-r--r-- | src/widgets/kernel/qwidget.cpp | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index a92454547a..580e71ff22 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -10543,8 +10543,8 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f) }); #endif - bool resized = testAttribute(Qt::WA_Resized); - bool wasCreated = testAttribute(Qt::WA_WState_Created); + const bool resized = testAttribute(Qt::WA_Resized); + const bool wasCreated = testAttribute(Qt::WA_WState_Created); QWidget *oldtlw = window(); if (f & Qt::Window) // Frame geometry likely changes, refresh. @@ -10553,7 +10553,7 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f) QWidget *desktopWidget = nullptr; if (parent && parent->windowType() == Qt::Desktop) desktopWidget = parent; - bool newParent = (parent != parentWidget()) || !wasCreated || desktopWidget; + bool newParent = (parent != parentWidget()) || desktopWidget; if (newParent && parent && !desktopWidget) { if (testAttribute(Qt::WA_NativeWindow) && !QCoreApplication::testAttribute(Qt::AA_DontCreateNativeWidgetSiblings)) @@ -10572,7 +10572,9 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f) QCoreApplication::sendEvent(this, &e); } } - if (newParent && isAncestorOf(focusWidget())) + // If we get parented into another window, children will be folded + // into the new parent's focus chain, so clear focus now. + if (newParent && isAncestorOf(focusWidget()) && !(f & Qt::Window)) focusWidget()->clearFocus(); d->setParent_sys(parent, f); @@ -10619,7 +10621,7 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f) // event to handle recreation/rebinding of the GL context, hence the // (f & Qt::MSWindowsOwnDC) clause (which is set on QGLWidgets on all // platforms). - if (newParent + if (newParent || !wasCreated #if QT_CONFIG(opengles2) || (f & Qt::MSWindowsOwnDC) #endif |