Return focus to correct widget after showing menu
By the time we call setKeyboardMode(true), the menu may already have taken focus. This change sets keyboardFocusWidget before opening the popup, and makes sure that keyboardFocusWidget is not set to the popup. (We cannot remove the assignment from setKeyboardMode(), since it's called from several places.) [ChangeLog][QtWidgets] Fixed widget losing focus after showing menu second time. Task-number: QTBUG-56860 Change-Id: Ic01726bf694e6f365dd7b601ad555156e0fdf6c5 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
parent
bc31d2235c
commit
35781b3588
@ -288,7 +288,7 @@ void QMenuBarPrivate::setKeyboardMode(bool b)
|
||||
keyboardState = b;
|
||||
if(b) {
|
||||
QWidget *fw = QApplication::focusWidget();
|
||||
if (fw != q)
|
||||
if (fw && fw != q && fw->window() != QApplication::activePopupWidget())
|
||||
keyboardFocusWidget = fw;
|
||||
focusFirstAction();
|
||||
q->setFocus(Qt::MenuBarFocusReason);
|
||||
@ -1706,6 +1706,7 @@ void QMenuBarPrivate::_q_internalShortcutActivated(int id)
|
||||
}
|
||||
}
|
||||
|
||||
keyboardFocusWidget = QApplication::focusWidget();
|
||||
setCurrentAction(act, true, true);
|
||||
if (act && !act->menu()) {
|
||||
activateAction(act, QAction::Trigger);
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include <qstyleoption.h>
|
||||
#include <QVBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPlainTextEdit>
|
||||
#include <qscreen.h>
|
||||
|
||||
#include <qobject.h>
|
||||
@ -106,6 +107,7 @@ private slots:
|
||||
void allowActiveAndDisabled();
|
||||
#endif
|
||||
|
||||
void taskQTBUG56860_focus();
|
||||
void check_endKey();
|
||||
void check_homeKey();
|
||||
|
||||
@ -710,6 +712,52 @@ void tst_QMenuBar::check_cursorKeys3()
|
||||
}
|
||||
#endif
|
||||
|
||||
void tst_QMenuBar::taskQTBUG56860_focus()
|
||||
{
|
||||
#if defined(Q_OS_DARWIN)
|
||||
QSKIP("Native key events are needed to test menu action activation on macOS.");
|
||||
#endif
|
||||
QMainWindow w;
|
||||
QMenuBar *mb = w.menuBar();
|
||||
|
||||
if (mb->platformMenuBar())
|
||||
QSKIP("This test requires the Qt menubar.");
|
||||
|
||||
QMenu *em = mb->addMenu("&Edit");
|
||||
em->setObjectName("EditMenu");
|
||||
em->addAction("&Cut");
|
||||
em->addAction("C&opy");
|
||||
QPlainTextEdit *e = new QPlainTextEdit;
|
||||
e->setObjectName("edit");
|
||||
|
||||
w.setCentralWidget(e);
|
||||
w.show();
|
||||
QApplication::setActiveWindow(&w);
|
||||
QVERIFY(QTest::qWaitForWindowActive(&w));
|
||||
|
||||
QTRY_COMPARE(QApplication::focusWidget(), e);
|
||||
|
||||
// Open menu
|
||||
QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_E, Qt::AltModifier );
|
||||
QTRY_COMPARE(QApplication::activePopupWidget(), em);
|
||||
// key down to trigger focus
|
||||
QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_Down );
|
||||
// and press ENTER to close
|
||||
QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_Enter );
|
||||
QTRY_COMPARE(QApplication::activePopupWidget(), nullptr);
|
||||
// focus should have returned to the editor by now
|
||||
QTRY_COMPARE(QApplication::focusWidget(), e);
|
||||
|
||||
// Now do it all over again...
|
||||
QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_E, Qt::AltModifier );
|
||||
QTRY_COMPARE(QApplication::activePopupWidget(), em);
|
||||
QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_Down );
|
||||
QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_Enter );
|
||||
QTRY_COMPARE(QApplication::activePopupWidget(), nullptr);
|
||||
QTRY_COMPARE(QApplication::focusWidget(), e);
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
If a popupmenu is active you can use home to go quickly to the first item in the menu.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user