diff --git a/autotests/client/test_wayland_seat.cpp b/autotests/client/test_wayland_seat.cpp --- a/autotests/client/test_wayland_seat.cpp +++ b/autotests/client/test_wayland_seat.cpp @@ -1201,6 +1201,21 @@ QCOMPARE(keyChangedSpy.at(4).at(1).value(), Keyboard::KeyState::Released); QCOMPARE(keyChangedSpy.at(4).at(2).value(), quint32(8)); + // releasing a key which is already released should not set a key changed + m_seatInterface->keyReleased(KEY_F1); + QVERIFY(!keyChangedSpy.wait(200)); + // let's press it again + m_seatInterface->keyPressed(KEY_F1); + QVERIFY(keyChangedSpy.wait()); + QCOMPARE(keyChangedSpy.count(), 6); + // press again should be ignored + m_seatInterface->keyPressed(KEY_F1); + QVERIFY(!keyChangedSpy.wait(200)); + // and release + m_seatInterface->keyReleased(KEY_F1); + QVERIFY(keyChangedSpy.wait()); + QCOMPARE(keyChangedSpy.count(), 7); + m_seatInterface->updateKeyboardModifiers(1, 2, 3, 4); QVERIFY(modifierSpy.wait()); QCOMPARE(modifierSpy.count(), 2); diff --git a/src/server/seat_interface.cpp b/src/server/seat_interface.cpp --- a/src/server/seat_interface.cpp +++ b/src/server/seat_interface.cpp @@ -132,14 +132,18 @@ it.value() = state; } -void SeatInterface::Private::updateKey(quint32 key, Keyboard::State state) +bool SeatInterface::Private::updateKey(quint32 key, Keyboard::State state) { auto it = keys.states.find(key); if (it == keys.states.end()) { keys.states.insert(key, state); - return; + return true; + } + if (it.value() == state) { + return false; } it.value() = state; + return true; } void SeatInterface::Private::sendName(wl_resource *r) @@ -825,7 +829,9 @@ { Q_D(); d->keys.lastStateSerial = d->display->nextSerial(); - d->updateKey(key, Private::Keyboard::State::Pressed); + if (!d->updateKey(key, Private::Keyboard::State::Pressed)) { + return; + } if (d->keys.focus.keyboard && d->keys.focus.surface) { d->keys.focus.keyboard->keyPressed(key, d->keys.lastStateSerial); } @@ -835,7 +841,9 @@ { Q_D(); d->keys.lastStateSerial = d->display->nextSerial(); - d->updateKey(key, Private::Keyboard::State::Released); + if (!d->updateKey(key, Private::Keyboard::State::Released)) { + return; + } if (d->keys.focus.keyboard && d->keys.focus.surface) { d->keys.focus.keyboard->keyReleased(key, d->keys.lastStateSerial); } diff --git a/src/server/seat_interface_p.h b/src/server/seat_interface_p.h --- a/src/server/seat_interface_p.h +++ b/src/server/seat_interface_p.h @@ -124,7 +124,7 @@ } keyRepeat; }; Keyboard keys; - void updateKey(quint32 key, Keyboard::State state); + bool updateKey(quint32 key, Keyboard::State state); struct TextInput { struct Focus {