Implement repeat info on wl_keyboard protocol
* Raises wl_seat supported version to 4 in both server and client * Raises wl_keyboard supported version to 4 in wl_keyboard * wl_pointer and wl_touch are still on version 3 * Raises minimum Wayland version to 1.6
This commit is contained in:
parent
4c3aa31cd3
commit
13bf4c9484
7 changed files with 124 additions and 4 deletions
|
@ -642,12 +642,32 @@ void TestWaylandSeat::testKeyboard()
|
|||
QVERIFY(!m_seatInterface->focusedKeyboard());
|
||||
|
||||
Keyboard *keyboard = m_seat->createKeyboard(m_seat);
|
||||
QSignalSpy repeatInfoSpy(keyboard, &Keyboard::keyRepeatChanged);
|
||||
QVERIFY(repeatInfoSpy.isValid());
|
||||
const Keyboard &ckeyboard = *keyboard;
|
||||
QVERIFY(keyboard->isValid());
|
||||
QCOMPARE(keyboard->isKeyRepeatEnabled(), false);
|
||||
QCOMPARE(keyboard->keyRepeatDelay(), 0);
|
||||
QCOMPARE(keyboard->keyRepeatRate(), 0);
|
||||
wl_display_flush(m_connection->display());
|
||||
QTest::qWait(100);
|
||||
QVERIFY(m_seatInterface->focusedKeyboard());
|
||||
|
||||
// we should get the repeat info announced
|
||||
QCOMPARE(repeatInfoSpy.count(), 1);
|
||||
QCOMPARE(keyboard->isKeyRepeatEnabled(), false);
|
||||
QCOMPARE(keyboard->keyRepeatDelay(), 0);
|
||||
QCOMPARE(keyboard->keyRepeatRate(), 0);
|
||||
|
||||
// let's change repeat in server
|
||||
m_seatInterface->setKeyRepeatInfo(25, 660);
|
||||
m_seatInterface->focusedKeyboard()->client()->flush();
|
||||
QVERIFY(repeatInfoSpy.wait());
|
||||
QCOMPARE(repeatInfoSpy.count(), 2);
|
||||
QCOMPARE(keyboard->isKeyRepeatEnabled(), true);
|
||||
QCOMPARE(keyboard->keyRepeatRate(), 25);
|
||||
QCOMPARE(keyboard->keyRepeatDelay(), 660);
|
||||
|
||||
m_seatInterface->setTimestamp(1);
|
||||
m_seatInterface->keyPressed(KEY_K);
|
||||
m_seatInterface->setTimestamp(2);
|
||||
|
@ -745,6 +765,20 @@ void TestWaylandSeat::testKeyboard()
|
|||
QTest::qWait(100);
|
||||
QVERIFY(!m_seatInterface->focusedKeyboardSurface());
|
||||
QVERIFY(!m_seatInterface->focusedKeyboard());
|
||||
|
||||
// create a second Keyboard to verify that repeat info is announced properly
|
||||
Keyboard *keyboard2 = m_seat->createKeyboard(m_seat);
|
||||
QSignalSpy repeatInfoSpy2(keyboard2, &Keyboard::keyRepeatChanged);
|
||||
QVERIFY(repeatInfoSpy2.isValid());
|
||||
QVERIFY(keyboard2->isValid());
|
||||
QCOMPARE(keyboard2->isKeyRepeatEnabled(), false);
|
||||
QCOMPARE(keyboard2->keyRepeatDelay(), 0);
|
||||
QCOMPARE(keyboard2->keyRepeatRate(), 0);
|
||||
wl_display_flush(m_connection->display());
|
||||
QVERIFY(repeatInfoSpy2.wait());
|
||||
QCOMPARE(keyboard2->isKeyRepeatEnabled(), true);
|
||||
QCOMPARE(keyboard2->keyRepeatRate(), 25);
|
||||
QCOMPARE(keyboard2->keyRepeatDelay(), 660);
|
||||
}
|
||||
|
||||
void TestWaylandSeat::testCast()
|
||||
|
|
|
@ -36,6 +36,7 @@ private Q_SLOTS:
|
|||
void testPointerButton();
|
||||
void testPointerPos();
|
||||
void testDestroyThroughTerminate();
|
||||
void testRepeatInfo();
|
||||
};
|
||||
|
||||
static const QString s_socketName = QStringLiteral("kwin-wayland-server-seat-test-0");
|
||||
|
@ -179,5 +180,22 @@ void TestWaylandServerSeat::testDestroyThroughTerminate()
|
|||
QVERIFY(!destroyedSpy.isEmpty());
|
||||
}
|
||||
|
||||
void TestWaylandServerSeat::testRepeatInfo()
|
||||
{
|
||||
Display display;
|
||||
display.setSocketName(s_socketName);
|
||||
display.start();
|
||||
SeatInterface *seat = display.createSeat();
|
||||
QCOMPARE(seat->keyRepeatRate(), 0);
|
||||
QCOMPARE(seat->keyRepeatDelay(), 0);
|
||||
seat->setKeyRepeatInfo(25, 660);
|
||||
QCOMPARE(seat->keyRepeatRate(), 25);
|
||||
QCOMPARE(seat->keyRepeatDelay(), 660);
|
||||
// setting negative values should result in 0
|
||||
seat->setKeyRepeatInfo(-25, -660);
|
||||
QCOMPARE(seat->keyRepeatRate(), 0);
|
||||
QCOMPARE(seat->keyRepeatDelay(), 0);
|
||||
}
|
||||
|
||||
QTEST_GUILESS_MAIN(TestWaylandServerSeat)
|
||||
#include "test_seat.moc"
|
||||
|
|
|
@ -169,6 +169,16 @@ void KeyboardInterface::updateModifiers(quint32 depressed, quint32 latched, quin
|
|||
d->sendModifiers(depressed, latched, locked, group, serial);
|
||||
}
|
||||
|
||||
void KeyboardInterface::repeatInfo(qint32 charactersPerSecond, qint32 delay)
|
||||
{
|
||||
Q_D();
|
||||
if (wl_resource_get_version(d->resource) < 4) {
|
||||
// only supported since version 4
|
||||
return;
|
||||
}
|
||||
wl_keyboard_send_repeat_info(d->resource, charactersPerSecond, delay);
|
||||
}
|
||||
|
||||
SurfaceInterface *KeyboardInterface::focusedSurface() const
|
||||
{
|
||||
Q_D();
|
||||
|
|
|
@ -46,6 +46,7 @@ private:
|
|||
void updateModifiers(quint32 depressed, quint32 latched, quint32 locked, quint32 group, quint32 serial);
|
||||
void keyPressed(quint32 key, quint32 serial);
|
||||
void keyReleased(quint32 key, quint32 serial);
|
||||
void repeatInfo(qint32 charactersPerSecond, qint32 delay);
|
||||
friend class SeatInterface;
|
||||
explicit KeyboardInterface(SeatInterface *parent, wl_resource *parentResource);
|
||||
|
||||
|
|
|
@ -38,7 +38,10 @@ namespace KWayland
|
|||
namespace Server
|
||||
{
|
||||
|
||||
static const quint32 s_version = 3;
|
||||
static const quint32 s_version = 4;
|
||||
static const qint32 s_pointerVersion = 3;
|
||||
static const qint32 s_touchVersion = 3;
|
||||
static const qint32 s_keyboardVersion = 4;
|
||||
|
||||
SeatInterface::Private::Private(SeatInterface *q, Display *display)
|
||||
: Global::Private(display, &wl_seat_interface, s_version)
|
||||
|
@ -303,7 +306,7 @@ void SeatInterface::Private::getPointer(wl_client *client, wl_resource *resource
|
|||
{
|
||||
// TODO: only create if seat has pointer?
|
||||
PointerInterface *pointer = new PointerInterface(q, resource);
|
||||
pointer->create(display->getConnection(client), wl_resource_get_version(resource), id);
|
||||
pointer->create(display->getConnection(client), qMin(wl_resource_get_version(resource), s_pointerVersion), id);
|
||||
if (!pointer->resource()) {
|
||||
wl_resource_post_no_memory(resource);
|
||||
delete pointer;
|
||||
|
@ -337,12 +340,13 @@ void SeatInterface::Private::getKeyboard(wl_client *client, wl_resource *resourc
|
|||
{
|
||||
// TODO: only create if seat has keyboard?
|
||||
KeyboardInterface *keyboard = new KeyboardInterface(q, resource);
|
||||
keyboard->create(display->getConnection(client), wl_resource_get_version(resource), id);
|
||||
keyboard->create(display->getConnection(client), qMin(wl_resource_get_version(resource), s_keyboardVersion) , id);
|
||||
if (!keyboard->resource()) {
|
||||
wl_resource_post_no_memory(resource);
|
||||
delete keyboard;
|
||||
return;
|
||||
}
|
||||
keyboard->repeatInfo(keys.keyRepeat.charactersPerSecond, keys.keyRepeat.delay);
|
||||
if (keys.keymap.xkbcommonCompatible) {
|
||||
keyboard->setKeymap(keys.keymap.fd, keys.keymap.size);
|
||||
}
|
||||
|
@ -374,7 +378,7 @@ void SeatInterface::Private::getTouch(wl_client *client, wl_resource *resource,
|
|||
{
|
||||
// TODO: only create if seat has touch?
|
||||
TouchInterface *touch = new TouchInterface(q, resource);
|
||||
touch->create(display->getConnection(client), wl_resource_get_version(resource), id);
|
||||
touch->create(display->getConnection(client), qMin(wl_resource_get_version(resource), s_touchVersion), id);
|
||||
if (!touch->resource()) {
|
||||
wl_resource_post_no_memory(resource);
|
||||
delete touch;
|
||||
|
@ -718,6 +722,28 @@ void SeatInterface::updateKeyboardModifiers(quint32 depressed, quint32 latched,
|
|||
}
|
||||
}
|
||||
|
||||
void SeatInterface::setKeyRepeatInfo(qint32 charactersPerSecond, qint32 delay)
|
||||
{
|
||||
Q_D();
|
||||
d->keys.keyRepeat.charactersPerSecond = qMax(charactersPerSecond, 0);
|
||||
d->keys.keyRepeat.delay = qMax(delay, 0);
|
||||
for (auto it = d->keyboards.constBegin(); it != d->keyboards.constEnd(); ++it) {
|
||||
(*it)->repeatInfo(d->keys.keyRepeat.charactersPerSecond, d->keys.keyRepeat.delay);
|
||||
}
|
||||
}
|
||||
|
||||
qint32 SeatInterface::keyRepeatDelay() const
|
||||
{
|
||||
Q_D();
|
||||
return d->keys.keyRepeat.delay;
|
||||
}
|
||||
|
||||
qint32 SeatInterface::keyRepeatRate() const
|
||||
{
|
||||
Q_D();
|
||||
return d->keys.keyRepeat.charactersPerSecond;
|
||||
}
|
||||
|
||||
bool SeatInterface::isKeymapXkbCompatible() const
|
||||
{
|
||||
Q_D();
|
||||
|
|
|
@ -89,6 +89,19 @@ public:
|
|||
void keyPressed(quint32 key);
|
||||
void keyReleased(quint32 key);
|
||||
void updateKeyboardModifiers(quint32 depressed, quint32 latched, quint32 locked, quint32 group);
|
||||
/**
|
||||
* Sets the key repeat information to be forwarded to all bound keyboards.
|
||||
*
|
||||
* To disable key repeat set a @p charactersPerSecond of @c 0.
|
||||
*
|
||||
* Requires wl_seat version 4.
|
||||
*
|
||||
* @param charactersPerSecond The characters per second rate, value of @c 0 disables key repeating
|
||||
* @param delay The delay on key press before starting repeating keys
|
||||
*
|
||||
* @since 5.5
|
||||
***/
|
||||
void setKeyRepeatInfo(qint32 charactersPerSecond, qint32 delay);
|
||||
quint32 depressedModifiers() const;
|
||||
quint32 latchedModifiers() const;
|
||||
quint32 lockedModifiers() const;
|
||||
|
@ -98,6 +111,20 @@ public:
|
|||
quint32 keymapSize() const;
|
||||
bool isKeymapXkbCompatible() const;
|
||||
QVector<quint32> pressedKeys() const;
|
||||
/**
|
||||
* @returns The key repeat in character per second
|
||||
* @since 5.5
|
||||
* @see setKeyRepeatInfo
|
||||
* @see keyRepeatDelay
|
||||
**/
|
||||
qint32 keyRepeatRate() const;
|
||||
/**
|
||||
* @returns The delay on key press before starting repeating keys
|
||||
* @since 5.5
|
||||
* @see keyRepeatRate
|
||||
* @see setKeyRepeatInfo
|
||||
**/
|
||||
qint32 keyRepeatDelay() const;
|
||||
|
||||
void setFocusedKeyboardSurface(SurfaceInterface *surface);
|
||||
SurfaceInterface *focusedKeyboardSurface() const;
|
||||
|
|
|
@ -112,6 +112,10 @@ public:
|
|||
};
|
||||
Focus focus;
|
||||
quint32 lastStateSerial = 0;
|
||||
struct {
|
||||
qint32 charactersPerSecond = 0;
|
||||
qint32 delay = 0;
|
||||
} keyRepeat;
|
||||
};
|
||||
Keyboard keys;
|
||||
void updateKey(quint32 key, Keyboard::State state);
|
||||
|
|
Loading…
Reference in a new issue