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:
Martin Gräßlin 2015-09-02 16:00:11 +02:00
parent 4c3aa31cd3
commit 13bf4c9484
7 changed files with 124 additions and 4 deletions

View file

@ -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()

View file

@ -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"

View file

@ -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();

View file

@ -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);

View file

@ -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();

View file

@ -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;

View file

@ -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);