diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2021-10-10 09:32:32 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-10-11 17:12:54 +0000 |
commit | d8eac9a71a4f951971d7cf3e20a72dba90800ac7 (patch) | |
tree | b17af6e553a3e2b9de0565505cfb071cdc197cf6 /src/widgets | |
parent | 45af046be7a2251284c923e52d42d7b6c7790026 (diff) |
QDialog: respect WA_ShowWithoutActivating
QDialog overrides setVisible to set focus on the default push button, or
(if there is no such button), make the first autoDefault push button the
default button. QDialog also explicitly sends a FocusIn event to the
focus widget in the dialog.
All this should not be done if the dialog does not become active after
getting shown, which will be prevented if the WA_ShowWithoutActivating
attribute is set.
Add a test case.
Fixes: QTBUG-8857
Change-Id: If47021a4721a280ba45e95b43d0424cdacd9b4ea
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
(cherry picked from commit 44b9aec8d900af77281f2e9209d54e946ee2fe76)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src/widgets')
-rw-r--r-- | src/widgets/dialogs/qdialog.cpp | 69 |
1 files changed, 37 insertions, 32 deletions
diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp index c416ba9a5c..a48599d668 100644 --- a/src/widgets/dialogs/qdialog.cpp +++ b/src/widgets/dialogs/qdialog.cpp @@ -783,42 +783,47 @@ void QDialog::setVisible(bool visible) return; QWidget::setVisible(visible); - QWidget *fw = window()->focusWidget(); - if (!fw) - fw = this; - - /* - The following block is to handle a special case, and does not - really follow propper logic in concern of autoDefault and TAB - order. However, it's here to ease usage for the users. If a - dialog has a default QPushButton, and first widget in the TAB - order also is a QPushButton, then we give focus to the main - default QPushButton. This simplifies code for the developers, - and actually catches most cases... If not, then they simply - have to use [widget*]->setFocus() themselves... - */ + + // Window activation might be prevented. We can't test isActiveWindow here, + // as the window will be activated asynchronously by the window manager. + if (!testAttribute(Qt::WA_ShowWithoutActivating)) { + QWidget *fw = window()->focusWidget(); + if (!fw) + fw = this; + + /* + The following block is to handle a special case, and does not + really follow propper logic in concern of autoDefault and TAB + order. However, it's here to ease usage for the users. If a + dialog has a default QPushButton, and first widget in the TAB + order also is a QPushButton, then we give focus to the main + default QPushButton. This simplifies code for the developers, + and actually catches most cases... If not, then they simply + have to use [widget*]->setFocus() themselves... + */ #if QT_CONFIG(pushbutton) - if (d->mainDef && fw->focusPolicy() == Qt::NoFocus) { - QWidget *first = fw; - while ((first = first->nextInFocusChain()) != fw && first->focusPolicy() == Qt::NoFocus) - ; - if (first != d->mainDef && qobject_cast<QPushButton*>(first)) - d->mainDef->setFocus(); - } - if (!d->mainDef && isWindow()) { - QWidget *w = fw; - while ((w = w->nextInFocusChain()) != fw) { - QPushButton *pb = qobject_cast<QPushButton *>(w); - if (pb && pb->autoDefault() && pb->focusPolicy() != Qt::NoFocus) { - pb->setDefault(true); - break; + if (d->mainDef && fw->focusPolicy() == Qt::NoFocus) { + QWidget *first = fw; + while ((first = first->nextInFocusChain()) != fw && first->focusPolicy() == Qt::NoFocus) + ; + if (first != d->mainDef && qobject_cast<QPushButton*>(first)) + d->mainDef->setFocus(); + } + if (!d->mainDef && isWindow()) { + QWidget *w = fw; + while ((w = w->nextInFocusChain()) != fw) { + QPushButton *pb = qobject_cast<QPushButton *>(w); + if (pb && pb->autoDefault() && pb->focusPolicy() != Qt::NoFocus) { + pb->setDefault(true); + break; + } } } - } #endif - if (fw && !fw->hasFocus()) { - QFocusEvent e(QEvent::FocusIn, Qt::TabFocusReason); - QCoreApplication::sendEvent(fw, &e); + if (fw && !fw->hasFocus()) { + QFocusEvent e(QEvent::FocusIn, Qt::TabFocusReason); + QCoreApplication::sendEvent(fw, &e); + } } #ifndef QT_NO_ACCESSIBILITY |