Skip to content

Commit ada885d

Browse files
dfaure-kdabASpoerl
authored andcommitted
QKeySequence: tolerate spaces when parsing a key sequence string
Fixes: QTBUG-130063 Pick-to: 6.9 6.8 Change-Id: I0f0aff0ca0824cd1c9297cd18a1f5cf9a2a44951 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io> Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
1 parent 67e9e2a commit ada885d

File tree

2 files changed

+53
-14
lines changed

2 files changed

+53
-14
lines changed

src/gui/kernel/qkeysequence.cpp

+35-13
Original file line numberDiff line numberDiff line change
@@ -1102,10 +1102,16 @@ QKeyCombination QKeySequencePrivate::decodeString(QString accel, QKeySequence::S
11021102
return Qt::Key_unknown;
11031103
#endif
11041104

1105+
int singlePlus = -1;
11051106
qsizetype i = 0;
11061107
qsizetype lastI = 0;
11071108
while ((i = sl.indexOf(u'+', i + 1)) != -1) {
1108-
const QStringView sub = QStringView{sl}.mid(lastI, i - lastI + 1);
1109+
QStringView sub = QStringView{ sl }.mid(lastI, i - lastI + 1);
1110+
while (sub.size() > 1 && sub.at(0) == QLatin1Char(' ')) {
1111+
sub = sub.mid(1);
1112+
++lastI;
1113+
}
1114+
11091115
// If we get here the shortcuts contains at least one '+'. We break up
11101116
// along the following strategy:
11111117
// Meta+Ctrl++ ( "Meta+", "Ctrl+", "+" )
@@ -1117,33 +1123,49 @@ QKeyCombination QKeySequencePrivate::decodeString(QString accel, QKeySequence::S
11171123
// Only '+' can have length 1.
11181124
if (sub.size() == 1) {
11191125
// Make sure we only encounter a single '+' at the end of the accel
1120-
if (accel.lastIndexOf(u'+') != accel.size()-1)
1126+
if (singlePlus >= 0)
11211127
return Qt::Key_unknown;
1128+
singlePlus = lastI;
11221129
} else {
1123-
// Identify the modifier
1124-
bool validModifier = false;
1125-
for (int j = 0; j < modifs.size(); ++j) {
1126-
const QModifKeyName &mkf = modifs.at(j);
1127-
if (sub == mkf.name) {
1128-
ret |= mkf.qt_key;
1129-
validModifier = true;
1130-
break; // Shortcut, since if we find an other it would/should just be a dup
1130+
1131+
const auto identifyModifier = [&](QStringView sub) {
1132+
for (int j = 0; j < modifs.size(); ++j) {
1133+
const QModifKeyName &mkf = modifs.at(j);
1134+
if (sub == mkf.name) {
1135+
ret |= mkf.qt_key;
1136+
return true; // Shortcut, since if we find another it would/should just be a dup
1137+
}
11311138
}
1132-
}
1139+
return false;
1140+
};
11331141

1142+
bool validModifier = identifyModifier(sub);
1143+
1144+
if (!validModifier) {
1145+
// Try harder with slower code that trims spaces
1146+
const QString cleanedSub = sub.toString().remove(QLatin1Char(' '));
1147+
validModifier = identifyModifier(cleanedSub);
1148+
}
11341149
if (!validModifier)
11351150
return Qt::Key_unknown;
11361151
}
11371152
lastI = i + 1;
11381153
}
11391154

1140-
qsizetype p = accel.lastIndexOf(u'+', accel.size() - 2); // -2 so that Ctrl++ works
1155+
qsizetype p = accel.lastIndexOf(u'+', singlePlus > 0 ? singlePlus - 1 : accel.size() - 1);
11411156
QStringView accelRef(accel);
11421157
if (p > 0)
11431158
accelRef = accelRef.mid(p + 1);
11441159

1160+
while (accelRef.size() > 1 && accelRef.at(0) == QLatin1Char(' '))
1161+
accelRef = accelRef.mid(1);
1162+
while (accelRef.size() > 1 && accelRef.endsWith(QLatin1Char(' ')))
1163+
accelRef.chop(1);
1164+
11451165
int fnum = 0;
1146-
if (accelRef.size() == 1) {
1166+
if (accelRef.isEmpty())
1167+
return Qt::Key_unknown;
1168+
else if (accelRef.size() == 1) {
11471169
#if defined(Q_OS_APPLE)
11481170
int qtKey = qtkeyForAppleSymbol(accelRef.at(0));
11491171
if (qtKey != -1) {

tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp

+18-1
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,20 @@ void tst_QKeySequence::parseString_data()
543543
QTest::newRow("Meta+A") << "Meta+a" << QKeySequence(Qt::META | Qt::Key_A);
544544
QTest::newRow("mEtA+A") << "mEtA+a" << QKeySequence(Qt::META | Qt::Key_A);
545545
QTest::newRow("Ctrl++") << "Ctrl++" << QKeySequence(Qt::CTRL | Qt::Key_Plus);
546+
QTest::newRow("+") << "+" << QKeySequence(Qt::Key_Plus);
547+
548+
// Tolerance for spaces
549+
QTest::newRow("Ctrl_+_Del") << "Ctrl + Del" << QKeySequence(Qt::CTRL | Qt::Key_Delete);
550+
QTest::newRow("Ctrl+Del_") << "Ctrl+Del " << QKeySequence(Qt::CTRL | Qt::Key_Delete);
551+
QTest::newRow("Ctrl_+_Del_") << "Ctrl + Del " << QKeySequence(Qt::CTRL | Qt::Key_Delete);
552+
QTest::newRow("space") << " " << QKeySequence(Qt::Key_Space);
553+
QTest::newRow("Ctrl+space") << "Ctrl+ " << QKeySequence(Qt::CTRL | Qt::Key_Space);
554+
QTest::newRow("Ctrl_++") << "Ctrl ++" << QKeySequence(Qt::CTRL | Qt::Key_Plus);
555+
QTest::newRow("Ctrl_+_+") << "Ctrl + +" << QKeySequence(Qt::CTRL | Qt::Key_Plus);
556+
QTest::newRow("Ctrl_+_+_") << "Ctrl + + " << QKeySequence(Qt::CTRL | Qt::Key_Plus);
557+
QTest::newRow("+_") << "+ " << QKeySequence(Qt::Key_Plus);
558+
QTest::newRow("_+") << " +" << QKeySequence(Qt::Key_Plus);
559+
QTest::newRow("_+_") << " + " << QKeySequence(Qt::Key_Plus);
546560

547561
// Invalid modifiers
548562
QTest::newRow("Win+A") << "Win+a" << QKeySequence(Qt::Key_unknown);
@@ -557,7 +571,9 @@ void tst_QKeySequence::parseString_data()
557571
QTest::newRow("4+3=2") << "4+3=2" << QKeySequence(Qt::Key_unknown);
558572
QTest::newRow("Alabama") << "Alabama" << QKeySequence(Qt::Key_unknown);
559573
QTest::newRow("Simon+G") << "Simon+G" << QKeySequence(Qt::Key_unknown);
560-
QTest::newRow("Shift+++2") << "Shift+++2" << QKeySequence(Qt::Key_unknown);
574+
QTest::newRow("Shift+++2") << "Shift+++2" << QKeySequence(Qt::Key_unknown);
575+
QTest::newRow("Ctrl+D_el") << "Ctrl+D el" << QKeySequence(Qt::Key_unknown);
576+
QTest::newRow("Ct_rl+D_el") << "Ct rl+D el" << QKeySequence(Qt::Key_unknown);
561577

562578
// Wrong order
563579
QTest::newRow("A+Meta") << "a+Meta" << QKeySequence(Qt::Key_unknown);
@@ -570,6 +586,7 @@ void tst_QKeySequence::parseString_data()
570586
//QTest::newRow("Shift") << "Shift" << QKeySequence(Qt::SHIFT);
571587

572588
// Incomplete
589+
QTest::newRow("Ctrl+") << "Ctrl+" << QKeySequence(Qt::Key_unknown);
573590
QTest::newRow("Meta+Shift+") << "Meta+Shift+" << QKeySequence(Qt::Key_unknown);
574591
}
575592

0 commit comments

Comments
 (0)