summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Olav Tvete <paul.tvete@qt.io>2019-08-23 09:55:56 +0200
committerPaul Olav Tvete <paul.tvete@qt.io>2019-08-23 10:34:58 +0200
commit717b4ddc6044d6ade9186148edd47c77b4120af5 (patch)
treeea3c8b66fd6f6b6e040d5d1de6a14bb6a230eb53
parent5d43a686fc3d5f13087a61e8ef216ecbbae0d15e (diff)
parent13ca5859d3e4a3e22532978dc1bd8629d9aa2107 (diff)
Merge "Merge remote-tracking branch 'qt/5.12' into 5.12.5"
-rw-r--r--src/client/qwaylanddisplay.cpp22
-rw-r--r--src/client/qwaylanddisplay_p.h1
-rw-r--r--src/client/qwaylandintegration.cpp31
-rw-r--r--src/client/qwaylandintegration_p.h2
-rw-r--r--src/client/qwaylandwindow.cpp8
-rw-r--r--src/client/qwaylandwindow_p.h4
-rw-r--r--src/shared/qwaylandxkb.cpp2
7 files changed, 39 insertions, 31 deletions
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
index 82003a308..47b107e80 100644
--- a/src/client/qwaylanddisplay.cpp
+++ b/src/client/qwaylanddisplay.cpp
@@ -172,9 +172,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));
}
}
@@ -184,25 +184,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()
@@ -231,10 +222,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 6bf6abd5d..ae8ec0ab8 100644
--- a/src/client/qwaylanddisplay_p.h
+++ b/src/client/qwaylanddisplay_p.h
@@ -191,7 +191,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 97e0203cd..46bef2944 100644
--- a/src/client/qwaylandintegration.cpp
+++ b/src/client/qwaylandintegration.cpp
@@ -301,11 +301,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;
}
@@ -325,9 +328,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;
bool disableHardwareIntegration = qEnvironmentVariableIsSet("QT_WAYLAND_DISABLE_HW_INTEGRATION");
@@ -345,17 +351,20 @@ void QWaylandIntegration::initializeClientBufferIntegration()
if (targetKey.isEmpty()) {
qWarning("Failed to determine what client buffer integration to use");
- return;
+ } else {
+ QStringList keys = QWaylandClientBufferIntegrationFactory::keys();
+ if (keys.contains(targetKey)) {
+ mClientBufferIntegration.reset(QWaylandClientBufferIntegrationFactory::create(targetKey, QStringList()));
+ }
+ if (mClientBufferIntegration)
+ mClientBufferIntegration->initialize(mDisplay.data());
+ else
+ qWarning("Failed to load client buffer integration: %s\n", qPrintable(targetKey));
}
- QStringList keys = QWaylandClientBufferIntegrationFactory::keys();
- if (keys.contains(targetKey)) {
- mClientBufferIntegration.reset(QWaylandClientBufferIntegrationFactory::create(targetKey, QStringList()));
- }
- if (mClientBufferIntegration)
- mClientBufferIntegration->initialize(mDisplay.data());
- else
- qWarning("Failed to load client buffer integration: %s\n", qPrintable(targetKey));
+ // 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 a5a3d7b69..7c1cb978a 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
@@ -148,6 +149,7 @@ private:
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 1d4315a39..f82898bd2 100644
--- a/src/client/qwaylandwindow.cpp
+++ b/src/client/qwaylandwindow.cpp
@@ -211,8 +211,11 @@ void QWaylandWindow::initWindow()
void QWaylandWindow::initializeWlSurface()
{
Q_ASSERT(!isInitialized());
- QWriteLocker lock(&mSurfaceLock);
- init(mDisplay->createSurface(static_cast<QtWayland::wl_surface *>(this)));
+ {
+ QWriteLocker lock(&mSurfaceLock);
+ init(mDisplay->createSurface(static_cast<QtWayland::wl_surface *>(this)));
+ }
+ emit wlSurfaceCreated();
}
bool QWaylandWindow::shouldCreateShellSurface() const
@@ -248,6 +251,7 @@ void QWaylandWindow::reset(bool sendDestroyEvent)
delete mSubSurfaceWindow;
mSubSurfaceWindow = nullptr;
if (isInitialized()) {
+ emit wlSurfaceDestroyed();
QWriteLocker lock(&mSurfaceLock);
destroy();
}
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
index ed4061f0e..717709938 100644
--- a/src/client/qwaylandwindow_p.h
+++ b/src/client/qwaylandwindow_p.h
@@ -201,6 +201,10 @@ public:
public slots:
void applyConfigure();
+signals:
+ void wlSurfaceCreated();
+ void wlSurfaceDestroyed();
+
protected:
void surface_enter(struct ::wl_output *output) override;
void surface_leave(struct ::wl_output *output) override;
diff --git a/src/shared/qwaylandxkb.cpp b/src/shared/qwaylandxkb.cpp
index 3cfc4b074..2dff8a5b1 100644
--- a/src/shared/qwaylandxkb.cpp
+++ b/src/shared/qwaylandxkb.cpp
@@ -376,7 +376,7 @@ QVector<xkb_keysym_t> QWaylandXkb::toKeysym(QKeyEvent *event)
keysyms.append(XKB_KEY_KP_0 + (event->key() - Qt::Key_0));
else
keysyms.append(toKeysymFromTable(event->key()));
- } else if (!event->text().isEmpty()) {
+ } else if (!event->text().isEmpty() && event->key() != Qt::Key_Return) {
// From libxkbcommon keysym-utf.c:
// "We allow to represent any UCS character in the range U-00000000 to
// U-00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff."