plugins/buttonrebinds: correctly handle level 1 keys

Level 1 keys (e.g., !=Shift+1) need to have shift added.

BUG: 484367
This commit is contained in:
Yifan Zhu 2024-07-31 14:48:50 -07:00
parent 20dc8f1684
commit 1240ac1dfe
5 changed files with 12 additions and 6 deletions

View file

@ -89,6 +89,7 @@ void TestButtonRebind::testKey_data()
QTest::newRow("delete") << QKeySequence(Qt::Key_Delete) << QList<quint32>{KEY_DELETE};
QTest::newRow("keypad delete") << QKeySequence(Qt::KeypadModifier | Qt::Key_Delete) << QList<quint32>{KEY_KPDOT};
QTest::newRow("keypad enter") << QKeySequence(Qt::KeypadModifier | Qt::Key_Enter) << QList<quint32>{KEY_KPENTER};
QTest::newRow("exclamation mark") << QKeySequence(Qt::Key_Exclam) << QList<quint32>{KEY_LEFTSHIFT, KEY_1};
}
void TestButtonRebind::testKey()

View file

@ -71,7 +71,7 @@ static std::vector<quint32> textToKey(const QString &text)
for (xkb_keysym_t sym : syms) {
auto code = input()->keyboard()->xkb()->keycodeFromKeysym(sym);
if (code) {
keyCode = code;
keyCode = code->first;
break;
}
}

View file

@ -362,10 +362,12 @@ bool ButtonRebindsFilter::sendKeySequence(const QKeySequence &keys, bool pressed
}
// KKeyServer returns upper case syms, lower it to not confuse modifiers handling
std::optional<int> keyCode;
std::optional<int> level;
for (int sym : syms) {
auto code = KWin::input()->keyboard()->xkb()->keycodeFromKeysym(sym);
if (code) {
keyCode = code;
keyCode = code->first;
level = code->second;
break;
}
}
@ -376,7 +378,7 @@ bool ButtonRebindsFilter::sendKeySequence(const QKeySequence &keys, bool pressed
RebindScope scope;
if (key & Qt::ShiftModifier) {
if (key & Qt::ShiftModifier || level == 1) {
sendKey(KEY_LEFTSHIFT);
}
if (key & Qt::ControlModifier) {

View file

@ -1105,7 +1105,7 @@ void Xkb::setSeat(SeatInterface *seat)
m_seat = QPointer<SeatInterface>(seat);
}
std::optional<int> Xkb::keycodeFromKeysym(xkb_keysym_t keysym)
std::optional<std::pair<int, int>> Xkb::keycodeFromKeysym(xkb_keysym_t keysym)
{
auto layout = xkb_state_serialize_layout(m_state, XKB_STATE_LAYOUT_EFFECTIVE);
const xkb_keycode_t max = xkb_keymap_max_keycode(m_keymap);
@ -1116,7 +1116,7 @@ std::optional<int> Xkb::keycodeFromKeysym(xkb_keysym_t keysym)
uint num_syms = xkb_keymap_key_get_syms_by_level(m_keymap, keycode, layout, currentLevel, &syms);
for (uint sym = 0; sym < num_syms; sym++) {
if (syms[sym] == keysym) {
return {keycode - EVDEV_OFFSET};
return {{keycode - EVDEV_OFFSET, currentLevel}};
}
}
}

View file

@ -116,7 +116,10 @@ public:
void setSeat(SeatInterface *seat);
QByteArray keymapContents() const;
std::optional<int> keycodeFromKeysym(xkb_keysym_t keysym);
/**
* Returns a pair of <keycode, level> for the given keysym.
*/
std::optional<std::pair<int, int>> keycodeFromKeysym(xkb_keysym_t keysym);
/**
* Returns list of candidate keysyms corresponding to the given Qt key.