Widgets: use QPlatformTheme::ButtonPressKeys for pressing buttons
QComboBox is included because it works like a button when it is not editable. QGroupBox is included because it has a checkbox and QCheckBox is a subclass of QAbstractButton. Change-Id: Iad89259314e77f78c915dce83ec601df94c88941 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
parent
2de667a6ff
commit
64ffe0aacb
@ -55,6 +55,7 @@
|
||||
#ifndef QT_NO_ACCESSIBILITY
|
||||
#include "qaccessible.h"
|
||||
#endif
|
||||
#include <qpa/qplatformtheme.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@ -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<QList<Qt::Key>>();
|
||||
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<QList<Qt::Key>>();
|
||||
if (buttonPressKeys.contains(e->key()) && !e->isAutoRepeat() && d->down) {
|
||||
d->click();
|
||||
return;
|
||||
}
|
||||
|
||||
e->ignore();
|
||||
}
|
||||
|
||||
/*!\reimp
|
||||
|
@ -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<QList<Qt::Key>>();
|
||||
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())
|
||||
|
@ -54,6 +54,8 @@
|
||||
#include "qaccessible.h"
|
||||
#endif
|
||||
#include <private/qwidget_p.h>
|
||||
#include <private/qguiapplication_p.h>
|
||||
#include <qpa/qplatformtheme.h>
|
||||
|
||||
#include "qdebug.h"
|
||||
|
||||
@ -360,7 +362,10 @@ bool QGroupBox::event(QEvent *e)
|
||||
return true;
|
||||
case QEvent::KeyPress: {
|
||||
QKeyEvent *k = static_cast<QKeyEvent*>(e);
|
||||
if (!k->isAutoRepeat() && (k->key() == Qt::Key_Select || k->key() == Qt::Key_Space)) {
|
||||
const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
|
||||
->themeHint(QPlatformTheme::ButtonPressKeys)
|
||||
.value<QList<Qt::Key>>();
|
||||
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<QKeyEvent*>(e);
|
||||
if (!k->isAutoRepeat() && (k->key() == Qt::Key_Select || k->key() == Qt::Key_Space)) {
|
||||
const auto buttonPressKeys = QGuiApplicationPrivate::platformTheme()
|
||||
->themeHint(QPlatformTheme::ButtonPressKeys)
|
||||
.value<QList<Qt::Key>>();
|
||||
if (!k->isAutoRepeat() && buttonPressKeys.contains(k->key())) {
|
||||
bool toggle = (d->pressedControl == QStyle::SC_GroupBoxLabel
|
||||
|| d->pressedControl == QStyle::SC_GroupBoxCheckBox);
|
||||
d->pressedControl = QStyle::SC_None;
|
||||
|
@ -42,6 +42,7 @@
|
||||
|
||||
#include <private/qguiapplication_p.h>
|
||||
#include <qpa/qplatformintegration.h>
|
||||
#include <qpa/qplatformtheme.h>
|
||||
|
||||
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<QList<Qt::Key>>();
|
||||
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<QList<Qt::Key>>();
|
||||
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<QList<Qt::Key>>();
|
||||
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"
|
||||
|
@ -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<QList<Qt::Key>>();
|
||||
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"
|
||||
|
@ -9,5 +9,6 @@ qt_internal_add_test(tst_qcommandlinkbutton
|
||||
tst_qcommandlinkbutton.cpp
|
||||
PUBLIC_LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
Qt::Widgets
|
||||
)
|
||||
|
@ -40,6 +40,9 @@
|
||||
#include <QGridLayout>
|
||||
#include <QPainter>
|
||||
|
||||
#include <private/qguiapplication_p.h>
|
||||
#include <qpa/qplatformtheme.h>
|
||||
|
||||
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<QList<Qt::Key>>();
|
||||
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<QList<Qt::Key>>();
|
||||
if (buttonPressKeys.contains(Qt::Key_Enter)) {
|
||||
return;
|
||||
}
|
||||
|
||||
QTest::keyPress( testWidget,Qt::Key_Enter );
|
||||
QCOMPARE( press_count, (uint)1 );
|
||||
QCOMPARE( release_count, (uint)1 );
|
||||
|
@ -9,5 +9,6 @@ qt_internal_add_test(tst_qgroupbox
|
||||
tst_qgroupbox.cpp
|
||||
PUBLIC_LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
Qt::Widgets
|
||||
)
|
||||
|
@ -36,6 +36,9 @@
|
||||
#include <QDialog>
|
||||
#include <QSignalSpy>
|
||||
|
||||
#include <private/qguiapplication_p.h>
|
||||
#include <qpa/qplatformtheme.h>
|
||||
|
||||
#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<QList<Qt::Key>>();
|
||||
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
|
||||
|
@ -9,5 +9,6 @@ qt_internal_add_test(tst_qpushbutton
|
||||
tst_qpushbutton.cpp
|
||||
PUBLIC_LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
Qt::Widgets
|
||||
)
|
||||
|
@ -41,6 +41,9 @@
|
||||
#include <QStyleFactory>
|
||||
#include <QTabWidget>
|
||||
|
||||
#include <private/qguiapplication_p.h>
|
||||
#include <qpa/qplatformtheme.h>
|
||||
|
||||
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<QList<Qt::Key>>();
|
||||
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<QList<Qt::Key>>();
|
||||
if (buttonPressKeys.contains(Qt::Key_Enter)) {
|
||||
return;
|
||||
}
|
||||
|
||||
QTest::keyPress( testWidget,Qt::Key_Enter );
|
||||
QCOMPARE( press_count, (uint)1 );
|
||||
QCOMPARE( release_count, (uint)1 );
|
||||
|
Loading…
Reference in New Issue
Block a user