From d28f95f60303cf8bee19e60c44bc34dfeb608f98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Tue, 21 Apr 2015 08:56:19 +0200 Subject: [PATCH] [server] Better split flushing events and dispatch events Running real world applications (Xwayland) showed that it doesn't like at all that we do a dispatch when we are going to flush. This caused in a very reliable manner a "Connection closed" error in XWayland, taking down the client and in return the (xwayland-enabled) server. --- .../autotests/client/test_wayland_surface.cpp | 2 +- src/wayland/display.cpp | 12 ++++++++++-- src/wayland/keyboard_interface.cpp | 1 + src/wayland/pointer_interface.cpp | 1 + src/wayland/server/buffer_interface.cpp | 1 + 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/wayland/autotests/client/test_wayland_surface.cpp b/src/wayland/autotests/client/test_wayland_surface.cpp index 44fb305b84..0240d3c33a 100644 --- a/src/wayland/autotests/client/test_wayland_surface.cpp +++ b/src/wayland/autotests/client/test_wayland_surface.cpp @@ -358,7 +358,7 @@ void TestWaylandSurface::testAttachBuffer() QVERIFY(!buffer2->isReferenced()); delete buffer2; // TODO: we should have a signal on when the Buffer gets released - QTest::qWait(100); + QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents); QVERIFY(redBuffer.data()->isReleased()); KWayland::Server::BufferInterface *buffer3 = serverSurface->buffer(); diff --git a/src/wayland/display.cpp b/src/wayland/display.cpp index 8443edded9..42cfadb687 100644 --- a/src/wayland/display.cpp +++ b/src/wayland/display.cpp @@ -46,6 +46,7 @@ class Display::Private public: Private(Display *q); void flush(); + void dispatch(); void setRunning(bool running); void installSocketNotifier(); @@ -77,7 +78,7 @@ void Display::Private::installSocketNotifier() return; } QSocketNotifier *m_notifier = new QSocketNotifier(fd, QSocketNotifier::Read, q); - QObject::connect(m_notifier, &QSocketNotifier::activated, q, [this] { flush(); } ); + QObject::connect(m_notifier, &QSocketNotifier::activated, q, [this] { dispatch(); } ); QObject::connect(QThread::currentThread()->eventDispatcher(), &QAbstractEventDispatcher::aboutToBlock, q, [this] { flush(); }); setRunning(true); } @@ -94,6 +95,14 @@ Display::~Display() } void Display::Private::flush() +{ + if (!display || !loop) { + return; + } + wl_display_flush_clients(display); +} + +void Display::Private::dispatch() { if (!display || !loop) { return; @@ -101,7 +110,6 @@ void Display::Private::flush() if (wl_event_loop_dispatch(loop, 0) != 0) { qCWarning(KWAYLAND_SERVER) << "Error on dispatching Wayland event loop"; } - wl_display_flush_clients(display); } void Display::setSocketName(const QString &name) diff --git a/src/wayland/keyboard_interface.cpp b/src/wayland/keyboard_interface.cpp index ed2d233896..bfd1c6bc27 100644 --- a/src/wayland/keyboard_interface.cpp +++ b/src/wayland/keyboard_interface.cpp @@ -143,6 +143,7 @@ void KeyboardInterface::setFocusedSurface(SurfaceInterface *surface, quint32 ser wl_array_release(&keys); d->sendModifiers(); + d->client->flush(); } void KeyboardInterface::keyPressed(quint32 key, quint32 serial) diff --git a/src/wayland/pointer_interface.cpp b/src/wayland/pointer_interface.cpp index ac1f33995b..78440db663 100644 --- a/src/wayland/pointer_interface.cpp +++ b/src/wayland/pointer_interface.cpp @@ -135,6 +135,7 @@ void PointerInterface::setFocusedSurface(SurfaceInterface *surface, quint32 seri wl_pointer_send_enter(d->resource, serial, d->focusedSurface->resource(), wl_fixed_from_double(pos.x()), wl_fixed_from_double(pos.y())); + d->client->flush(); } void PointerInterface::buttonPressed(quint32 button, quint32 serial) diff --git a/src/wayland/server/buffer_interface.cpp b/src/wayland/server/buffer_interface.cpp index 20556bb2ab..77d34a1ff1 100644 --- a/src/wayland/server/buffer_interface.cpp +++ b/src/wayland/server/buffer_interface.cpp @@ -181,6 +181,7 @@ void BufferInterface::unref() if (d->refCount == 0) { if (d->buffer) { wl_buffer_send_release(d->buffer); + wl_client_flush(wl_resource_get_client(d->buffer)); } deleteLater(); }