From 448f16220c26fda4e0915bb7e9c362c3cec4c9d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Thu, 23 May 2013 08:23:32 +0200 Subject: [PATCH] Use a QSocketNotifier to wait for Wayland events Nicely integrates Qt's event loop with the Wayland event handling. We still need to dispatch pending events before calling eglSwapBuffers as that call might block. --- egl_wayland_backend.cpp | 17 +++++++++++++++-- egl_wayland_backend.h | 5 ++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/egl_wayland_backend.cpp b/egl_wayland_backend.cpp index 12378d133d..ccac0b58a1 100644 --- a/egl_wayland_backend.cpp +++ b/egl_wayland_backend.cpp @@ -27,6 +27,8 @@ along with this program. If not, see . // KDE #include #include +// Qt +#include // xcb #include // Wayland @@ -521,7 +523,8 @@ void WaylandSeat::resetCursor() } WaylandBackend::WaylandBackend() - : m_display(wl_display_connect(NULL)) + : QObject(NULL) + , m_display(wl_display_connect(NULL)) , m_registry(wl_display_get_registry(m_display)) , m_compositor(NULL) , m_shell(NULL) @@ -535,6 +538,9 @@ WaylandBackend::WaylandBackend() // setup the registry wl_registry_add_listener(m_registry, &s_registryListener, this); wl_display_dispatch(m_display); + int fd = wl_display_get_fd(m_display); + QSocketNotifier *notifier = new QSocketNotifier(fd, QSocketNotifier::Read, this); + connect(notifier, SIGNAL(activated(int)), SLOT(readEvents())); } WaylandBackend::~WaylandBackend() @@ -564,6 +570,13 @@ WaylandBackend::~WaylandBackend() kDebug(1212) << "Destroyed Wayland display"; } +void WaylandBackend::readEvents() +{ + // TODO: this still seems to block + wl_display_flush(m_display); + wl_display_dispatch(m_display); +} + void WaylandBackend::createSeat(uint32_t name) { wl_seat *seat = reinterpret_cast(wl_registry_bind(m_registry, name, &wl_seat_interface, 1)); @@ -786,10 +799,10 @@ bool EglWaylandBackend::initBufferConfigs() void EglWaylandBackend::present() { setLastDamage(QRegion()); + // need to dispatch pending events as eglSwapBuffers can block wl_display_dispatch_pending(m_wayland->display()); wl_display_flush(m_wayland->display()); eglSwapBuffers(m_display, m_surface); - eglWaitGL(); } void EglWaylandBackend::screenGeometryChanged(const QSize &size) diff --git a/egl_wayland_backend.h b/egl_wayland_backend.h index afdf8c43ad..66519372f9 100644 --- a/egl_wayland_backend.h +++ b/egl_wayland_backend.h @@ -120,8 +120,9 @@ private: * It creates the connection to the Wayland Compositor, set's up the registry and creates * the Wayland surface and it's shell and egl mapping. */ -class WaylandBackend +class WaylandBackend : public QObject { + Q_OBJECT public: WaylandBackend(); virtual ~WaylandBackend(); @@ -138,6 +139,8 @@ public: void ping(uint32_t serial); bool createSurface(); +private Q_SLOTS: + void readEvents(); private: wl_display *m_display; wl_registry *m_registry;