Client tests: Add simple test for keyboard press
Change-Id: Ib28be5277af9145834c7808f993c747e21845616 Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
This commit is contained in:
parent
f91e358902
commit
d2c9c5537d
@ -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"
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user