Add a Client::EventQueue

The EventQueue is a wrapper for wl_event_queue. The usage is for the
case that the connection is in a different thread.

The EventQueue needs to be added to the Registry before Registry::create
is invoked. This ensures that the Registry gets added to the EventQueue
and all objects created by the Registry (and further down the tree)
will be added to the same EventQueue.

The auto-tests which already used a wl_event_queue are transited to the
EventQueue class. That's also the reason why there is no dedicated
unit test: the new code is sufficiently tested by the existing tests.
This commit is contained in:
Martin Gräßlin 2014-09-23 11:55:07 +02:00
parent 53b9b5b9b2
commit f72e4a4d6f
3 changed files with 43 additions and 33 deletions

View file

@ -21,6 +21,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
#include <QtTest/QtTest>
// KWin
#include "../../src/client/connection_thread.h"
#include "../../src/client/event_queue.h"
#include "../../src/server/display.h"
// Wayland
#include <wayland-client-protocol.h>
@ -140,10 +141,11 @@ void TestWaylandConnectionThread::testConnectionThread()
// now we have the connection ready, let's get some events
QSignalSpy eventsSpy(connection.data(), SIGNAL(eventsRead()));
wl_display *display = connection->display();
wl_event_queue *queue = wl_display_create_queue(display);
QScopedPointer<KWayland::Client::EventQueue> queue(new KWayland::Client::EventQueue);
queue->setup(display);
wl_registry *registry = wl_display_get_registry(display);
wl_proxy_set_queue((wl_proxy*)registry, queue);
wl_proxy_set_queue((wl_proxy*)registry, *(queue.data()));
wl_registry_add_listener(registry, &s_registryListener, this);
wl_display_flush(display);
@ -154,7 +156,7 @@ void TestWaylandConnectionThread::testConnectionThread()
QVERIFY(!eventsSpy.isEmpty());
wl_registry_destroy(registry);
wl_event_queue_destroy(queue);
queue.reset();
connectionThread->quit();
connectionThread->wait();

View file

@ -22,6 +22,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
// KWin
#include "../../src/client/compositor.h"
#include "../../src/client/connection_thread.h"
#include "../../src/client/event_queue.h"
#include "../../src/client/keyboard.h"
#include "../../src/client/pointer.h"
#include "../../src/client/surface.h"
@ -63,6 +64,7 @@ private:
KWayland::Client::ConnectionThread *m_connection;
KWayland::Client::Compositor *m_compositor;
KWayland::Client::Seat *m_seat;
KWayland::Client::EventQueue *m_queue;
QThread *m_thread;
};
@ -76,6 +78,7 @@ TestWaylandSeat::TestWaylandSeat(QObject *parent)
, m_connection(nullptr)
, m_compositor(nullptr)
, m_seat(nullptr)
, m_queue(nullptr)
, m_thread(nullptr)
{
}
@ -113,22 +116,17 @@ void TestWaylandSeat::init()
m_connection->initConnection();
QVERIFY(connectedSpy.wait());
// TODO: we should destroy the queue
wl_event_queue *queue = wl_display_create_queue(m_connection->display());
connect(m_connection, &KWayland::Client::ConnectionThread::eventsRead, this,
[this, queue]() {
wl_display_dispatch_queue_pending(m_connection->display(), queue);
wl_display_flush(m_connection->display());
},
Qt::QueuedConnection);
m_queue = new KWayland::Client::EventQueue(this);
m_queue->setup(m_connection);
KWayland::Client::Registry registry;
QSignalSpy compositorSpy(&registry, SIGNAL(compositorAnnounced(quint32,quint32)));
QSignalSpy seatSpy(&registry, SIGNAL(seatAnnounced(quint32,quint32)));
registry.setEventQueue(m_queue);
registry.create(m_connection->display());
QVERIFY(registry.isValid());
registry.setup();
wl_proxy_set_queue((wl_proxy*)registry.registry(), queue);
QVERIFY(compositorSpy.wait());
m_seatInterface = m_display->createSeat();
@ -157,14 +155,20 @@ void TestWaylandSeat::cleanup()
delete m_compositor;
m_compositor = nullptr;
}
if (m_queue) {
delete m_queue;
m_queue = nullptr;
}
if (m_connection) {
m_connection->deleteLater();
m_connection = nullptr;
}
if (m_thread) {
m_thread->quit();
m_thread->wait();
delete m_thread;
m_thread = nullptr;
}
delete m_connection;
m_connection = nullptr;
delete m_compositorInterface;
m_compositorInterface = nullptr;
@ -539,6 +543,7 @@ void TestWaylandSeat::testDestroy()
delete m_compositor;
m_compositor = nullptr;
connect(m_connection, &ConnectionThread::connectionDied, m_seat, &Seat::destroy);
connect(m_connection, &ConnectionThread::connectionDied, m_queue, &EventQueue::destroy);
QVERIFY(m_seat->isValid());
QSignalSpy connectionDiedSpy(m_connection, SIGNAL(connectionDied()));

View file

@ -22,6 +22,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
// KWin
#include "../../src/client/compositor.h"
#include "../../src/client/connection_thread.h"
#include "../../src/client/event_queue.h"
#include "../../src/client/shell.h"
#include "../../src/client/surface.h"
#include "../../src/client/registry.h"
@ -56,6 +57,7 @@ private:
KWayland::Client::ConnectionThread *m_connection;
KWayland::Client::Compositor *m_compositor;
KWayland::Client::Shell *m_shell;
KWayland::Client::EventQueue *m_queue;
QThread *m_thread;
};
@ -69,6 +71,7 @@ TestWaylandShell::TestWaylandShell(QObject *parent)
, m_connection(nullptr)
, m_compositor(nullptr)
, m_shell(nullptr)
, m_queue(nullptr)
, m_thread(nullptr)
{
}
@ -101,32 +104,23 @@ void TestWaylandShell::init()
m_connection->moveToThread(m_thread);
m_thread->start();
connect(QCoreApplication::eventDispatcher(), &QAbstractEventDispatcher::aboutToBlock, m_connection,
[this]() {
if (m_connection->display()) {
wl_display_flush(m_connection->display());
}
}
);
m_connection->initConnection();
QVERIFY(connectedSpy.wait());
// TODO: we should destroy the queue
wl_event_queue *queue = wl_display_create_queue(m_connection->display());
connect(m_connection, &KWayland::Client::ConnectionThread::eventsRead, this,
[this, queue]() {
wl_display_dispatch_queue_pending(m_connection->display(), queue);
wl_display_flush(m_connection->display());
},
Qt::QueuedConnection);
m_queue = new KWayland::Client::EventQueue(this);
QVERIFY(!m_queue->isValid());
m_queue->setup(m_connection);
QVERIFY(m_queue->isValid());
KWayland::Client::Registry registry;
QSignalSpy compositorSpy(&registry, SIGNAL(compositorAnnounced(quint32,quint32)));
QSignalSpy shellSpy(&registry, SIGNAL(shellAnnounced(quint32,quint32)));
QVERIFY(!registry.eventQueue());
registry.setEventQueue(m_queue);
QCOMPARE(registry.eventQueue(), m_queue);
registry.create(m_connection->display());
QVERIFY(registry.isValid());
registry.setup();
wl_proxy_set_queue((wl_proxy*)registry.registry(), queue);
QVERIFY(compositorSpy.wait());
m_compositor = new KWayland::Client::Compositor(this);
@ -150,14 +144,20 @@ void TestWaylandShell::cleanup()
delete m_compositor;
m_compositor = nullptr;
}
if (m_queue) {
delete m_queue;
m_queue = nullptr;
}
if (m_connection) {
m_connection->deleteLater();
m_connection = nullptr;
}
if (m_thread) {
m_thread->quit();
m_thread->wait();
delete m_thread;
m_thread = nullptr;
}
delete m_connection;
m_connection = nullptr;
delete m_shellInterface;
m_shellInterface = nullptr;
@ -313,6 +313,7 @@ void TestWaylandShell::testDestroy()
connect(m_connection, &ConnectionThread::connectionDied, m_shell, &Shell::destroy);
connect(m_connection, &ConnectionThread::connectionDied, m_compositor, &Compositor::destroy);
connect(m_connection, &ConnectionThread::connectionDied, s.data(), &Surface::destroy);
connect(m_connection, &ConnectionThread::connectionDied, m_queue, &EventQueue::destroy);
QSignalSpy connectionDiedSpy(m_connection, SIGNAL(connectionDied()));
QVERIFY(connectionDiedSpy.isValid());
@ -334,6 +335,7 @@ void TestWaylandShell::testCast()
using namespace KWayland::Client;
Registry registry;
QSignalSpy shellSpy(&registry, SIGNAL(shellAnnounced(quint32,quint32)));
registry.setEventQueue(m_queue);
registry.create(m_connection->display());
QVERIFY(registry.isValid());
registry.setup();
@ -341,6 +343,7 @@ void TestWaylandShell::testCast()
Shell s;
auto wlShell = registry.bindShell(shellSpy.first().first().value<quint32>(), shellSpy.first().last().value<quint32>());
m_queue->addProxy(wlShell);
QVERIFY(wlShell);
QVERIFY(!s.isValid());
s.setup(wlShell);