summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tests/auto/client/seatv4/tst_seatv4.cpp27
-rw-r--r--tests/auto/client/shared/coreprotocol.cpp58
-rw-r--r--tests/auto/client/shared/coreprotocol.h18
-rw-r--r--tests/auto/client/shared/mockcompositor.cpp2
-rw-r--r--tests/auto/client/shared/mockcompositor.h1
5 files changed, 101 insertions, 5 deletions
diff --git a/tests/auto/client/seatv4/tst_seatv4.cpp b/tests/auto/client/seatv4/tst_seatv4.cpp
index b6357a25b..f1e948ee2 100644
--- a/tests/auto/client/seatv4/tst_seatv4.cpp
+++ b/tests/auto/client/seatv4/tst_seatv4.cpp
@@ -46,7 +46,7 @@ public:
removeAll<Seat>();
- uint capabilities = MockCompositor::Seat::capability_pointer;
+ uint capabilities = Seat::capability_pointer | Seat::capability_keyboard;
int version = 4;
add<Seat>(capabilities, version);
});
@@ -67,6 +67,8 @@ private slots:
void simpleAxis();
void invalidPointerEvents();
void scaledCursor();
+
+ void keyboardKeyPress();
};
void tst_seatv4::cleanup()
@@ -287,5 +289,28 @@ void tst_seatv4::scaledCursor()
exec([&] { remove(output(1)); });
}
+void tst_seatv4::keyboardKeyPress()
+{
+ class Window : public QRasterWindow {
+ public:
+ void keyPressEvent(QKeyEvent *) override { m_pressed = true; }
+ bool m_pressed = false;
+ };
+
+ Window window;
+ window.resize(64, 64);
+ window.show();
+ QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial);
+
+ uint keyCode = 80; // arbitrarily chosen
+ exec([&] {
+ auto *surface = xdgSurface()->m_surface;
+ keyboard()->sendEnter(surface);
+ keyboard()->sendKey(client(), keyCode, Keyboard::key_state_pressed);
+ keyboard()->sendKey(client(), keyCode, Keyboard::key_state_released);
+ });
+ QTRY_VERIFY(window.m_pressed);
+}
+
QCOMPOSITOR_TEST_MAIN(tst_seatv4)
#include "tst_seatv4.moc"
diff --git a/tests/auto/client/shared/coreprotocol.cpp b/tests/auto/client/shared/coreprotocol.cpp
index fdd5f627c..16494d789 100644
--- a/tests/auto/client/shared/coreprotocol.cpp
+++ b/tests/auto/client/shared/coreprotocol.cpp
@@ -193,8 +193,8 @@ Seat::~Seat()
}
void Seat::setCapabilities(uint capabilities) {
- // TODO: Add support for touch and keyboard
- Q_ASSERT(capabilities == 0 || capabilities == capability_pointer);
+ // TODO: Add support for touch
+ Q_ASSERT(~capabilities & capability_touch);
m_capabilities = capabilities;
@@ -206,6 +206,14 @@ void Seat::setCapabilities(uint capabilities) {
m_pointer = nullptr;
}
+ if (m_capabilities & capability_keyboard) {
+ if (!m_keyboard)
+ m_keyboard = (new Keyboard(this));
+ } else if (m_keyboard) {
+ m_oldKeyboards << m_keyboard;
+ m_keyboard = nullptr;
+ }
+
for (auto *resource : resourceMap())
wl_seat::send_capabilities(resource->handle, capabilities);
}
@@ -225,6 +233,21 @@ void Seat::seat_get_pointer(Resource *resource, uint32_t id)
m_pointer->add(resource->client(), id, resource->version());
}
+void Seat::seat_get_keyboard(QtWaylandServer::wl_seat::Resource *resource, uint32_t id)
+{
+ if (~m_capabilities & capability_pointer) {
+ qWarning() << "Client requested a wl_keyboard without the capability being available."
+ << "This Could be a race condition when hotunplugging,"
+ << "but is most likely a client error";
+ Keyboard *keyboard = new Keyboard(this);
+ keyboard->add(resource->client(), id, resource->version());
+ // TODO: mark as destroyed
+ m_oldKeyboards << keyboard;
+ return;
+ }
+ m_keyboard->add(resource->client(), id, resource->version());
+}
+
Surface *Pointer::cursorSurface()
{
return m_cursorRole ? m_cursorRole->m_surface : nullptr;
@@ -296,6 +319,37 @@ void Pointer::pointer_set_cursor(Resource *resource, uint32_t serial, wl_resourc
emit setCursor(serial);
}
+uint Keyboard::sendEnter(Surface *surface)
+{
+ auto serial = m_seat->m_compositor->nextSerial();
+ wl_client *client = surface->resource()->client();
+ const auto pointerResources = resourceMap().values(client);
+ for (auto *r : pointerResources)
+ send_enter(r->handle, serial, surface->resource()->handle, QByteArray());
+ return serial;
+}
+
+uint Keyboard::sendLeave(Surface *surface)
+{
+ auto serial = m_seat->m_compositor->nextSerial();
+ wl_client *client = surface->resource()->client();
+ const auto pointerResources = resourceMap().values(client);
+ for (auto *r : pointerResources)
+ send_leave(r->handle, serial, surface->resource()->handle);
+ return serial;
+}
+
+uint Keyboard::sendKey(wl_client *client, uint key, uint state)
+{
+ Q_ASSERT(state == key_state_pressed || state == key_state_released);
+ auto time = m_seat->m_compositor->currentTimeMilliseconds();
+ uint serial = m_seat->m_compositor->nextSerial();
+ const auto pointerResources = resourceMap().values(client);
+ for (auto *r : pointerResources)
+ send_key(r->handle, serial, time, key, state);
+ return serial;
+}
+
// Shm implementation
Shm::Shm(CoreCompositor *compositor, QVector<format> formats, int version)
: QtWaylandServer::wl_shm(compositor->m_display, version)
diff --git a/tests/auto/client/shared/coreprotocol.h b/tests/auto/client/shared/coreprotocol.h
index 565ae66ae..da171c202 100644
--- a/tests/auto/client/shared/coreprotocol.h
+++ b/tests/auto/client/shared/coreprotocol.h
@@ -38,6 +38,7 @@ namespace MockCompositor {
class WlCompositor;
class Output;
class Pointer;
+class Keyboard;
class CursorRole;
class ShmPool;
class ShmBuffer;
@@ -245,6 +246,9 @@ public:
Pointer* m_pointer = nullptr;
QVector<Pointer *> m_oldPointers;
+ Keyboard* m_keyboard = nullptr;
+ QVector<Keyboard *> m_oldKeyboards;
+
uint m_capabilities = 0;
protected:
@@ -254,7 +258,7 @@ protected:
}
void seat_get_pointer(Resource *resource, uint32_t id) override;
-// void seat_get_keyboard(Resource *resource, uint32_t id) override;
+ void seat_get_keyboard(Resource *resource, uint32_t id) override;
// void seat_get_touch(Resource *resource, uint32_t id) override;
// void seat_release(Resource *resource) override;
@@ -294,6 +298,18 @@ public:
Surface *m_surface = nullptr;
};
+class Keyboard : public QObject, public QtWaylandServer::wl_keyboard
+{
+ Q_OBJECT
+public:
+ explicit Keyboard(Seat *seat) : m_seat(seat) {}
+ //TODO: Keymap event
+ uint sendEnter(Surface *surface);
+ uint sendLeave(Surface *surface);
+ uint sendKey(wl_client *client, uint key, uint state);
+ Seat *m_seat = nullptr;
+};
+
class Shm : public Global, public QtWaylandServer::wl_shm
{
Q_OBJECT
diff --git a/tests/auto/client/shared/mockcompositor.cpp b/tests/auto/client/shared/mockcompositor.cpp
index bb7cd6f46..6b9af4295 100644
--- a/tests/auto/client/shared/mockcompositor.cpp
+++ b/tests/auto/client/shared/mockcompositor.cpp
@@ -41,7 +41,7 @@ DefaultCompositor::DefaultCompositor()
add<SubCompositor>();
auto *output = add<Output>();
output->m_data.physicalSize = output->m_data.mode.physicalSizeForDpi(96);
- add<Seat>(Seat::capability_pointer);
+ add<Seat>(Seat::capability_pointer | Seat::capability_keyboard);
add<XdgWmBase>();
add<Shm>();
// TODO: other shells, viewporter, xdgoutput etc
diff --git a/tests/auto/client/shared/mockcompositor.h b/tests/auto/client/shared/mockcompositor.h
index c7ea4d009..a6515c04c 100644
--- a/tests/auto/client/shared/mockcompositor.h
+++ b/tests/auto/client/shared/mockcompositor.h
@@ -53,6 +53,7 @@ public:
XdgToplevel *xdgToplevel(int i = 0) { return get<XdgWmBase>()->toplevel(i); }
XdgPopup *xdgPopup(int i = 0) { return get<XdgWmBase>()->popup(i); }
Pointer *pointer() { auto *seat = get<Seat>(); Q_ASSERT(seat); return seat->m_pointer; }
+ Keyboard *keyboard() { auto *seat = get<Seat>(); Q_ASSERT(seat); return seat->m_keyboard; }
uint sendXdgShellPing();
void xdgPingAndWaitForPong();
// Things that can be changed run-time without confusing the client (i.e. don't require separate tests)