tst_QQuickMenu::contextMenuKeyboard: Fix flakiness on xcb platforms

This patch addresses flaky failures in the context menu keyboard test
on xcb platforms. Previously, after opening the menu, the menu was
sometimes not opened as expected. Additionally, simulating a Tab key
press after opening the menu did not always give focus to the first
menu item.

The root cause was the focus timing inconsistencies on xcb: when the
window is shown, it may not receive focus immediately. This can
deactivate the application's focus window, causing popups/menus to
close unexpectedly or preventing the Tab key from correctly focusing
the first menu item.

To fix this, the patch processes pending and deferred events before
opening the menu, but only on xcb platforms, ensuring the window
receives focus in time.

Pick-to: 6.10
Task-number: QTBUG-133858
Change-Id: I648c72b484852d23c84e41dc6450c1f50cc4bdc2
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
This commit is contained in:
MohammadHossein Qanbari 2025-06-05 17:13:56 +02:00 committed by Mitch Curtis
parent 2a6e8582fc
commit e53a22722d
1 changed files with 17 additions and 1 deletions

View File

@ -391,6 +391,7 @@ void tst_QQuickMenu::contextMenuKeyboard()
centerOnScreen(window);
moveMouseAway(window);
window->show();
QVERIFY(QTest::qWaitForWindowExposed(window));
window->requestActivate();
QVERIFY(QTest::qWaitForWindowActive(window));
QVERIFY(QGuiApplication::focusWindow() == window);
@ -418,6 +419,20 @@ void tst_QQuickMenu::contextMenuKeyboard()
QVERIFY(firstItem);
QSignalSpy visibleSpy(menu, SIGNAL(visibleChanged()));
#if QT_CONFIG(xcb)
// The focus-out event is triggered when the expected focus-in event does not occur
// within a certain time frame. In this case, the xcb connection sends a focus-out event,
// causing the active window to lose focus. As a result, if the menu is already open,
// it will be closed automatically.
// To prevent this issue, we force the application to process pending and deferred events,
// ensuring that the focus-in event is handled before opening the menu.
// See also QXcbConnection::QXcbConnection() (line: m_focusInTimer.callOnTimeout(...)).
if (QGuiApplication::platformName().compare(QLatin1String("xcb"), Qt::CaseInsensitive)) {
QGuiApplication::processEvents();
QGuiApplication::sendPostedEvents();
}
#endif
QVERIFY(menu->hasFocus());
menu->open();
@ -428,7 +443,8 @@ void tst_QQuickMenu::contextMenuKeyboard()
QTRY_VERIFY(menuPrivate->popupWindow);
parentItem = menuPrivate->popupWindow->contentItem();
QVERIFY(QTest::qWaitForWindowExposed(menuPrivate->popupWindow));
QQuickTest::qWaitForPolish(menuPrivate->popupWindow);
QVERIFY(QTest::qWaitForWindowActive(menuPrivate->popupWindow));
QVERIFY(QQuickTest::qWaitForPolish(menuPrivate->popupWindow));
}
QTRY_VERIFY(menu->isOpened());