diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index ebbb2dffb88..cf32ff6c93e 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -6513,11 +6513,15 @@ void QWidget::setFocus(Qt::FocusReason reason) QApplicationPrivate::setFocusWidget(f, reason); #if QT_CONFIG(accessibility) - // menus update the focus manually and this would create bogus events - if (!(f->inherits("QMenuBar") || f->inherits("QMenu") || f->inherits("QMenuItem"))) - { - QAccessibleEvent event(f, QAccessible::Focus); - QAccessible::updateAccessibility(&event); + // If the widget gets focus because its window becomes active, then the accessibility + // subsystem is already informed about the window opening, and also knows which child + // within the window has focus. Don't interrupt it by emitting another focus event. + if (reason != Qt::ActiveWindowFocusReason) { + // menus update the focus manually and this would create bogus events + if (!(f->inherits("QMenuBar") || f->inherits("QMenu") || f->inherits("QMenuItem"))) { + QAccessibleEvent event(f, QAccessible::Focus); + QAccessible::updateAccessibility(&event); + } } #endif #if QT_CONFIG(graphicsview) diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index de0942ba085..fa9f2a58664 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -4288,10 +4288,20 @@ void tst_QAccessibility::messageBoxTest() if (!boxPrivate->canBeNativeDialog()) { // platforms that use a native message box will not emit accessibility events box.show(); + QVERIFY(QTest::qWaitForWindowActive(&box)); QAccessibleEvent showEvent(&box, QAccessible::DialogStart); QVERIFY(QTestAccessibility::containsEvent(&showEvent)); + // on some platforms, like macOS, not all widgets get key board focus; we + // only care about a push button getting focus + if (QTest::qWaitFor([&box]{ return qobject_cast(box.focusWidget()); }, 1000)) { + // a widget that gets focus through window activation should not emit an accessibility + // notification + QAccessibleEvent focusEvent(box.focusWidget(), QAccessible::Focus); + QVERIFY(!QTestAccessibility::containsEvent(&focusEvent)); + } + box.hide(); QAccessibleEvent hideEvent(&box, QAccessible::DialogEnd);