diff --git a/src/widgets/widgets/qabstractbutton.cpp b/src/widgets/widgets/qabstractbutton.cpp index de6741c030..becb93a5d3 100644 --- a/src/widgets/widgets/qabstractbutton.cpp +++ b/src/widgets/widgets/qabstractbutton.cpp @@ -55,6 +55,7 @@ #ifndef QT_NO_ACCESSIBILITY #include "qaccessible.h" #endif +#include #include @@ -1043,19 +1044,19 @@ void QAbstractButton::keyPressEvent(QKeyEvent *e) { Q_D(QAbstractButton); bool next = true; - switch (e->key()) { - case Qt::Key_Enter: - case Qt::Key_Return: - e->ignore(); - break; - case Qt::Key_Select: - case Qt::Key_Space: - if (!e->isAutoRepeat()) { - setDown(true); - repaint(); - d->emitPressed(); - } - break; + + const auto key = e->key(); + const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme() + ->themeHint(QPlatformTheme::ButtonPressKeys) + .value>(); + if (buttonPressKeys.contains(key) && !e->isAutoRepeat()) { + setDown(true); + repaint(); + d->emitPressed(); + return; + } + + switch (key) { case Qt::Key_Up: next = false; Q_FALLTHROUGH(); @@ -1120,15 +1121,15 @@ void QAbstractButton::keyReleaseEvent(QKeyEvent *e) if (!e->isAutoRepeat()) d->repeatTimer.stop(); - switch (e->key()) { - case Qt::Key_Select: - case Qt::Key_Space: - if (!e->isAutoRepeat() && d->down) - d->click(); - break; - default: - e->ignore(); + const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme() + ->themeHint(QPlatformTheme::ButtonPressKeys) + .value>(); + if (buttonPressKeys.contains(e->key()) && !e->isAutoRepeat() && d->down) { + d->click(); + return; } + + e->ignore(); } /*!\reimp diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index db7bf9c504..3970c7838c 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -3196,7 +3196,23 @@ void QComboBox::keyPressEvent(QKeyEvent *e) Move move = NoMove; int newIndex = currentIndex(); - switch (e->key()) { + + bool pressLikeButton = !d->lineEdit; +#ifdef QT_KEYPAD_NAVIGATION + pressLikeButton |= QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus(); +#endif + auto key = e->key(); + if (pressLikeButton) { + const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme() + ->themeHint(QPlatformTheme::ButtonPressKeys) + .value>(); + if (buttonPressKeys.contains(key)) { + showPopup(); + return; + } + } + + switch (key) { case Qt::Key_Up: if (e->modifiers() & Qt::ControlModifier) break; // pass to line edit for auto completion @@ -3238,26 +3254,11 @@ void QComboBox::keyPressEvent(QKeyEvent *e) return; } break; - case Qt::Key_Space: - if (!d->lineEdit) { - showPopup(); - return; - } - break; - case Qt::Key_Enter: - case Qt::Key_Return: case Qt::Key_Escape: if (!d->lineEdit) e->ignore(); break; #ifdef QT_KEYPAD_NAVIGATION - case Qt::Key_Select: - if (QApplicationPrivate::keypadNavigationEnabled() - && (!hasEditFocus() || !d->lineEdit)) { - showPopup(); - return; - } - break; case Qt::Key_Left: case Qt::Key_Right: if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus()) diff --git a/src/widgets/widgets/qgroupbox.cpp b/src/widgets/widgets/qgroupbox.cpp index 8945139115..bc4fa6b763 100644 --- a/src/widgets/widgets/qgroupbox.cpp +++ b/src/widgets/widgets/qgroupbox.cpp @@ -54,6 +54,8 @@ #include "qaccessible.h" #endif #include +#include +#include #include "qdebug.h" @@ -360,7 +362,10 @@ bool QGroupBox::event(QEvent *e) return true; case QEvent::KeyPress: { QKeyEvent *k = static_cast(e); - if (!k->isAutoRepeat() && (k->key() == Qt::Key_Select || k->key() == Qt::Key_Space)) { + const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme() + ->themeHint(QPlatformTheme::ButtonPressKeys) + .value>(); + if (!k->isAutoRepeat() && buttonPressKeys.contains(k->key())) { d->pressedControl = QStyle::SC_GroupBoxCheckBox; update(style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxCheckBox, this)); return true; @@ -369,7 +374,10 @@ bool QGroupBox::event(QEvent *e) } case QEvent::KeyRelease: { QKeyEvent *k = static_cast(e); - if (!k->isAutoRepeat() && (k->key() == Qt::Key_Select || k->key() == Qt::Key_Space)) { + const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme() + ->themeHint(QPlatformTheme::ButtonPressKeys) + .value>(); + if (!k->isAutoRepeat() && buttonPressKeys.contains(k->key())) { bool toggle = (d->pressedControl == QStyle::SC_GroupBoxLabel || d->pressedControl == QStyle::SC_GroupBoxCheckBox); d->pressedControl = QStyle::SC_None; diff --git a/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp b/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp index 19a2e46f9f..937a77ca2c 100644 --- a/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp +++ b/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp @@ -42,6 +42,7 @@ #include #include +#include class tst_QAbstractButton : public QObject { @@ -81,6 +82,8 @@ private slots: void keyNavigation(); #endif + void buttonPressKeys(); + protected slots: void onClicked(); void onToggled( bool on ); @@ -276,7 +279,13 @@ void tst_QAbstractButton::setAutoRepeat() QCOMPARE(press_count, click_count); QVERIFY(click_count > 1); break; - case 4: + case 4: { + const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme() + ->themeHint(QPlatformTheme::ButtonPressKeys) + .value>(); + if (buttonPressKeys.contains(Qt::Key_Enter)) { + QSKIP("platform theme has Key_Enter in ButtonPressKeys"); + } // check that pressing ENTER has no effect when autorepeat is false testWidget->setDown( false ); testWidget->setAutoRepeat( false ); @@ -293,7 +302,14 @@ void tst_QAbstractButton::setAutoRepeat() QVERIFY( click_count == 0 ); break; - case 5: + } + case 5: { + const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme() + ->themeHint(QPlatformTheme::ButtonPressKeys) + .value>(); + if (buttonPressKeys.contains(Qt::Key_Enter)) { + QSKIP("platform theme has Key_Enter in ButtonPressKeys"); + } // check that pressing ENTER has no effect when autorepeat is true testWidget->setDown( false ); testWidget->setAutoRepeat( true ); @@ -311,6 +327,7 @@ void tst_QAbstractButton::setAutoRepeat() QVERIFY( click_count == 0 ); break; + } case 6: // verify autorepeat is off by default. MyButton tmp( 0); @@ -687,5 +704,16 @@ void tst_QAbstractButton::keyNavigation() } #endif +void tst_QAbstractButton::buttonPressKeys() +{ + const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme() + ->themeHint(QPlatformTheme::ButtonPressKeys) + .value>(); + for (int i = 0; i < buttonPressKeys.length(); ++i) { + QTest::keyClick(testWidget, buttonPressKeys[i]); + QCOMPARE(click_count, i + 1); + } +} + QTEST_MAIN(tst_QAbstractButton) #include "tst_qabstractbutton.moc" diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp index 4996062c6f..ddc973a35d 100644 --- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp @@ -170,6 +170,7 @@ private slots: void checkMenuItemPosWhenStyleSheetIsSet(); void checkEmbeddedLineEditWhenStyleSheetIsSet(); void propagateStyleChanges(); + void buttonPressKeys(); private: PlatformInputContext m_platformInputContext; @@ -3588,5 +3589,24 @@ void tst_QComboBox::propagateStyleChanges() QVERIFY(frameStyle.inquired); } +void tst_QComboBox::buttonPressKeys() +{ + QComboBox comboBox; + comboBox.setEditable(false); + comboBox.addItem(QString::number(1)); + comboBox.addItem(QString::number(2)); + const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme() + ->themeHint(QPlatformTheme::ButtonPressKeys) + .value>(); + for (int i = 0; i < buttonPressKeys.length(); ++i) { + QTest::keyClick(&comboBox, buttonPressKeys[i]); + // On some platforms, a window will not be immediately visible, + // but take some event-loop iterations to complete. + // Using QTRY_VERIFY to deal with that. + QTRY_VERIFY(comboBox.view()->isVisible()); + comboBox.hidePopup(); + } +} + QTEST_MAIN(tst_QComboBox) #include "tst_qcombobox.moc" diff --git a/tests/auto/widgets/widgets/qcommandlinkbutton/CMakeLists.txt b/tests/auto/widgets/widgets/qcommandlinkbutton/CMakeLists.txt index dfb555673a..9c556296c0 100644 --- a/tests/auto/widgets/widgets/qcommandlinkbutton/CMakeLists.txt +++ b/tests/auto/widgets/widgets/qcommandlinkbutton/CMakeLists.txt @@ -9,5 +9,6 @@ qt_internal_add_test(tst_qcommandlinkbutton tst_qcommandlinkbutton.cpp PUBLIC_LIBRARIES Qt::Gui + Qt::GuiPrivate Qt::Widgets ) diff --git a/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp b/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp index 11bef2dc0d..fe24fdaba1 100644 --- a/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp +++ b/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp @@ -40,6 +40,9 @@ #include #include +#include +#include + class tst_QCommandLinkButton : public QObject { Q_OBJECT @@ -226,6 +229,13 @@ void tst_QCommandLinkButton::setAutoRepeat() // check that pressing ENTER has no effect resetCounters(); testWidget->setDown( false ); + // Skip after reset if ButtonPressKeys has Key_Enter + const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme() + ->themeHint(QPlatformTheme::ButtonPressKeys) + .value>(); + if (buttonPressKeys.contains(Qt::Key_Enter)) { + return; + } testWidget->setAutoRepeat( false ); QTest::keyPress( testWidget, Qt::Key_Enter ); @@ -258,6 +268,14 @@ void tst_QCommandLinkButton::pressed() QCOMPARE( press_count, (uint)1 ); QCOMPARE( release_count, (uint)1 ); + // Skip if ButtonPressKeys has Key_Enter + const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme() + ->themeHint(QPlatformTheme::ButtonPressKeys) + .value>(); + if (buttonPressKeys.contains(Qt::Key_Enter)) { + return; + } + QTest::keyPress( testWidget,Qt::Key_Enter ); QCOMPARE( press_count, (uint)1 ); QCOMPARE( release_count, (uint)1 ); diff --git a/tests/auto/widgets/widgets/qgroupbox/CMakeLists.txt b/tests/auto/widgets/widgets/qgroupbox/CMakeLists.txt index ed08cce5f2..56079857a8 100644 --- a/tests/auto/widgets/widgets/qgroupbox/CMakeLists.txt +++ b/tests/auto/widgets/widgets/qgroupbox/CMakeLists.txt @@ -9,5 +9,6 @@ qt_internal_add_test(tst_qgroupbox tst_qgroupbox.cpp PUBLIC_LIBRARIES Qt::Gui + Qt::GuiPrivate Qt::Widgets ) diff --git a/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp b/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp index c57cd619fa..127dc15575 100644 --- a/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp +++ b/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp @@ -36,6 +36,9 @@ #include #include +#include +#include + #include "qgroupbox.h" class tst_QGroupBox : public QObject @@ -70,6 +73,7 @@ private slots: void propagateFocus(); void task_QTBUG_19170_ignoreMouseReleaseEvent(); void task_QTBUG_15519_propagateMouseEvents(); + void buttonPressKeys(); private: bool checked; @@ -611,6 +615,20 @@ void tst_QGroupBox::task_QTBUG_15519_propagateMouseEvents() QCOMPARE(parent.mouseMoved, true); } +void tst_QGroupBox::buttonPressKeys() +{ + QGroupBox groupBox; + groupBox.setCheckable(true); + QSignalSpy clickedSpy(&groupBox, &QGroupBox::clicked); + const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme() + ->themeHint(QPlatformTheme::ButtonPressKeys) + .value>(); + for (int i = 0; i < buttonPressKeys.length(); ++i) { + QTest::keyClick(&groupBox, buttonPressKeys[i]); + QCOMPARE(clickedSpy.length(), i + 1); + } +} + void tst_QGroupBox::sendMouseMoveEvent(QWidget *widget, const QPoint &localPos) { // Send a MouseMove event without actually moving the pointer diff --git a/tests/auto/widgets/widgets/qpushbutton/CMakeLists.txt b/tests/auto/widgets/widgets/qpushbutton/CMakeLists.txt index 0ec5c1fe09..199a891695 100644 --- a/tests/auto/widgets/widgets/qpushbutton/CMakeLists.txt +++ b/tests/auto/widgets/widgets/qpushbutton/CMakeLists.txt @@ -9,5 +9,6 @@ qt_internal_add_test(tst_qpushbutton tst_qpushbutton.cpp PUBLIC_LIBRARIES Qt::Gui + Qt::GuiPrivate Qt::Widgets ) diff --git a/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp b/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp index 60b5bebdaf..e1d369d76d 100644 --- a/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp +++ b/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp @@ -41,6 +41,9 @@ #include #include +#include +#include + class tst_QPushButton : public QObject { Q_OBJECT @@ -220,6 +223,13 @@ void tst_QPushButton::autoRepeat() // check that pressing ENTER has no effect resetCounters(); testWidget->setDown( false ); + // Skip after reset if ButtonPressKeys has Key_Enter + const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme() + ->themeHint(QPlatformTheme::ButtonPressKeys) + .value>(); + if (buttonPressKeys.contains(Qt::Key_Enter)) { + return; + } testWidget->setAutoRepeat( false ); QTest::keyPress( testWidget, Qt::Key_Enter ); @@ -255,6 +265,14 @@ void tst_QPushButton::pressed() QCOMPARE( press_count, (uint)1 ); QCOMPARE( release_count, (uint)1 ); + // Skip if ButtonPressKeys has Key_Enter + const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme() + ->themeHint(QPlatformTheme::ButtonPressKeys) + .value>(); + if (buttonPressKeys.contains(Qt::Key_Enter)) { + return; + } + QTest::keyPress( testWidget,Qt::Key_Enter ); QCOMPARE( press_count, (uint)1 ); QCOMPARE( release_count, (uint)1 );