diff options
author | Johan Klokkhammer Helsing <johan.helsing@qt.io> | 2019-09-03 03:01:35 +0200 |
---|---|---|
committer | Johan Klokkhammer Helsing <johan.helsing@qt.io> | 2019-09-03 07:24:14 +0200 |
commit | 9f02bfedfe3b6b0b19d7c7a684a33b7544c84111 (patch) | |
tree | 89ecc4e3c982338363540384aa895f6949630e89 /src/client | |
parent | f3668f88ccad6341280fbe2ca493562f80e76955 (diff) | |
parent | cd2c3a8916a9cc7ab31f6e18e6f1510a048f4ace (diff) | |
download | qtwayland-9f02bfedfe3b6b0b19d7c7a684a33b7544c84111.tar.gz |
Merge remote-tracking branch 'origin/5.13' into 5.14
Conflicts:
src/client/qwaylandinputdevice.cpp
src/client/qwaylandwindow.cpp
Change-Id: Ifd64debc484197829d2fe412afa98c29b382efa5
Diffstat (limited to 'src/client')
-rw-r--r-- | src/client/qwaylanddataoffer.cpp | 41 | ||||
-rw-r--r-- | src/client/qwaylanddisplay.cpp | 22 | ||||
-rw-r--r-- | src/client/qwaylanddisplay_p.h | 1 | ||||
-rw-r--r-- | src/client/qwaylandintegration.cpp | 39 | ||||
-rw-r--r-- | src/client/qwaylandintegration_p.h | 2 | ||||
-rw-r--r-- | src/client/qwaylandwindow.cpp | 1 | ||||
-rw-r--r-- | src/client/qwaylandwindow_p.h | 1 |
7 files changed, 59 insertions, 48 deletions
diff --git a/src/client/qwaylanddataoffer.cpp b/src/client/qwaylanddataoffer.cpp index e31e1220..4c06277f 100644 --- a/src/client/qwaylanddataoffer.cpp +++ b/src/client/qwaylanddataoffer.cpp @@ -141,7 +141,7 @@ QVariant QWaylandMimeData::retrieveData_sys(const QString &mimeType, QVariant::T } int pipefd[2]; - if (qt_safe_pipe(pipefd, O_NONBLOCK) == -1) { + if (qt_safe_pipe(pipefd) == -1) { qWarning("QWaylandMimeData: pipe2() failed"); return QVariant(); } @@ -163,23 +163,32 @@ QVariant QWaylandMimeData::retrieveData_sys(const QString &mimeType, QVariant::T int QWaylandMimeData::readData(int fd, QByteArray &data) const { - char buf[4096]; - int retryCount = 0; - int n; - while (true) { - n = QT_READ(fd, buf, sizeof buf); - if (n == -1 && (errno == EAGAIN || errno == EWOULDBLOCK) && ++retryCount < 1000) - usleep(1000); - else - break; - } - if (retryCount >= 1000) + fd_set readset; + FD_ZERO(&readset); + FD_SET(fd, &readset); + struct timeval timeout; + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + int ready = select(FD_SETSIZE, &readset, nullptr, nullptr, &timeout); + if (ready < 0) { + qWarning() << "QWaylandDataOffer: select() failed"; + return -1; + } else if (ready == 0) { qWarning("QWaylandDataOffer: timeout reading from pipe"); - if (n > 0) { - data.append(buf, n); - n = readData(fd, data); + return -1; + } else { + char buf[4096]; + int n = QT_READ(fd, buf, sizeof buf); + + if (n > 0) { + data.append(buf, n); + n = readData(fd, data); + } else if (n < 0) { + qWarning("QWaylandDataOffer: read() failed"); + } + return n; } - return n; } } diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp index cb4f190a..a17e8917 100644 --- a/src/client/qwaylanddisplay.cpp +++ b/src/client/qwaylanddisplay.cpp @@ -189,9 +189,9 @@ void QWaylandDisplay::checkError() const int ecode = wl_display_get_error(mDisplay); if ((ecode == EPIPE || ecode == ECONNRESET)) { // special case this to provide a nicer error - qWarning("The Wayland connection broke. Did the Wayland compositor die?"); + qFatal("The Wayland connection broke. Did the Wayland compositor die?"); } else { - qErrnoWarning(ecode, "The Wayland connection experienced a fatal error"); + qFatal("The Wayland connection experienced a fatal error: %s", strerror(ecode)); } } @@ -201,25 +201,16 @@ void QWaylandDisplay::flushRequests() wl_display_read_events(mDisplay); } - if (wl_display_dispatch_pending(mDisplay) < 0) { + if (wl_display_dispatch_pending(mDisplay) < 0) checkError(); - exitWithError(); - } wl_display_flush(mDisplay); } void QWaylandDisplay::blockingReadEvents() { - if (wl_display_dispatch(mDisplay) < 0) { + if (wl_display_dispatch(mDisplay) < 0) checkError(); - exitWithError(); - } -} - -void QWaylandDisplay::exitWithError() -{ - ::exit(1); } wl_event_queue *QWaylandDisplay::createEventQueue() @@ -248,10 +239,9 @@ void QWaylandDisplay::dispatchQueueWhile(wl_event_queue *queue, std::function<bo else wl_display_cancel_read(mDisplay); - if (wl_display_dispatch_queue_pending(mDisplay, queue) < 0) { + if (wl_display_dispatch_queue_pending(mDisplay, queue) < 0) checkError(); - exitWithError(); - } + if (!condition()) break; } diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h index 1f085e67..14bb7719 100644 --- a/src/client/qwaylanddisplay_p.h +++ b/src/client/qwaylanddisplay_p.h @@ -208,7 +208,6 @@ public slots: private: void waitForScreens(); - void exitWithError(); void checkError() const; void handleWaylandSync(); diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp index 7f79d6b9..f6a80e18 100644 --- a/src/client/qwaylandintegration.cpp +++ b/src/client/qwaylandintegration.cpp @@ -310,11 +310,14 @@ QPlatformTheme *QWaylandIntegration::createPlatformTheme(const QString &name) co return GenericWaylandTheme::createUnixTheme(name); } +// May be called from non-GUI threads QWaylandClientBufferIntegration *QWaylandIntegration::clientBufferIntegration() const { - if (!mClientBufferIntegrationInitialized) + // Do an inexpensive check first to avoid locking whenever possible + if (Q_UNLIKELY(!mClientBufferIntegrationInitialized)) const_cast<QWaylandIntegration *>(this)->initializeClientBufferIntegration(); + Q_ASSERT(mClientBufferIntegrationInitialized); return mClientBufferIntegration && mClientBufferIntegration->isValid() ? mClientBufferIntegration.data() : nullptr; } @@ -334,9 +337,12 @@ QWaylandShellIntegration *QWaylandIntegration::shellIntegration() const return mShellIntegration.data(); } +// May be called from non-GUI threads void QWaylandIntegration::initializeClientBufferIntegration() { - mClientBufferIntegrationInitialized = true; + QMutexLocker lock(&mClientBufferInitLock); + if (mClientBufferIntegrationInitialized) + return; QString targetKey = QString::fromLocal8Bit(qgetenv("QT_WAYLAND_CLIENT_BUFFER_INTEGRATION")); @@ -352,22 +358,25 @@ void QWaylandIntegration::initializeClientBufferIntegration() if (targetKey.isEmpty()) { qWarning("Failed to determine what client buffer integration to use"); - return; - } - - QStringList keys = QWaylandClientBufferIntegrationFactory::keys(); - qCDebug(lcQpaWayland) << "Available client buffer integrations:" << keys; + } else { + QStringList keys = QWaylandClientBufferIntegrationFactory::keys(); + qCDebug(lcQpaWayland) << "Available client buffer integrations:" << keys; - if (keys.contains(targetKey)) - mClientBufferIntegration.reset(QWaylandClientBufferIntegrationFactory::create(targetKey, QStringList())); + if (keys.contains(targetKey)) + mClientBufferIntegration.reset(QWaylandClientBufferIntegrationFactory::create(targetKey, QStringList())); - if (mClientBufferIntegration) { - qCDebug(lcQpaWayland) << "Initializing client buffer integration" << targetKey; - mClientBufferIntegration->initialize(mDisplay.data()); - } else { - qCWarning(lcQpaWayland) << "Failed to load client buffer integration:" << targetKey; - qCWarning(lcQpaWayland) << "Available client buffer integrations:" << keys; + if (mClientBufferIntegration) { + qCDebug(lcQpaWayland) << "Initializing client buffer integration" << targetKey; + mClientBufferIntegration->initialize(mDisplay.data()); + } else { + qCWarning(lcQpaWayland) << "Failed to load client buffer integration:" << targetKey; + qCWarning(lcQpaWayland) << "Available client buffer integrations:" << keys; + } } + + // This must be set last to make sure other threads don't use the + // integration before initialization is complete. + mClientBufferIntegrationInitialized = true; } void QWaylandIntegration::initializeServerBufferIntegration() diff --git a/src/client/qwaylandintegration_p.h b/src/client/qwaylandintegration_p.h index 3aef2c4d..a66999c7 100644 --- a/src/client/qwaylandintegration_p.h +++ b/src/client/qwaylandintegration_p.h @@ -54,6 +54,7 @@ #include <QtWaylandClient/qtwaylandclientglobal.h> #include <qpa/qplatformintegration.h> #include <QtCore/QScopedPointer> +#include <QtCore/QMutex> QT_BEGIN_NAMESPACE @@ -152,6 +153,7 @@ private: mutable QScopedPointer<QPlatformAccessibility> mAccessibility; #endif bool mFailed = false; + QMutex mClientBufferInitLock; bool mClientBufferIntegrationInitialized = false; bool mServerBufferIntegrationInitialized = false; bool mShellIntegrationInitialized = false; diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index ce58003c..60317cda 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -205,6 +205,7 @@ void QWaylandWindow::initializeWlSurface() connect(mSurface.data(), &QWaylandSurface::screensChanged, this, &QWaylandWindow::handleScreensChanged); mSurface->m_window = this; + emit wlSurfaceCreated(); } bool QWaylandWindow::shouldCreateShellSurface() const diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h index 8d8565d7..471ace4c 100644 --- a/src/client/qwaylandwindow_p.h +++ b/src/client/qwaylandwindow_p.h @@ -203,6 +203,7 @@ public slots: void applyConfigure(); signals: + void wlSurfaceCreated(); void wlSurfaceDestroyed(); protected: |