Merge remote-tracking branch 'qt/5.12' into 5.12.5

Conflicts:
	src/client/qwaylandwindow.cpp

Change-Id: I89fefe5bfc247eeaad3981850efa0faaab3cb145
This commit is contained in:
Paul Olav Tvete 2019-08-23 09:55:56 +02:00
commit 2bb9acf847
7 changed files with 39 additions and 31 deletions

View File

@ -172,9 +172,9 @@ void QWaylandDisplay::checkError() const
int ecode = wl_display_get_error(mDisplay); int ecode = wl_display_get_error(mDisplay);
if ((ecode == EPIPE || ecode == ECONNRESET)) { if ((ecode == EPIPE || ecode == ECONNRESET)) {
// special case this to provide a nicer error // 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 { } 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); wl_display_read_events(mDisplay);
} }
if (wl_display_dispatch_pending(mDisplay) < 0) { if (wl_display_dispatch_pending(mDisplay) < 0)
checkError(); checkError();
exitWithError();
}
wl_display_flush(mDisplay); wl_display_flush(mDisplay);
} }
void QWaylandDisplay::blockingReadEvents() void QWaylandDisplay::blockingReadEvents()
{ {
if (wl_display_dispatch(mDisplay) < 0) { if (wl_display_dispatch(mDisplay) < 0)
checkError(); checkError();
exitWithError();
}
}
void QWaylandDisplay::exitWithError()
{
::exit(1);
} }
wl_event_queue *QWaylandDisplay::createEventQueue() wl_event_queue *QWaylandDisplay::createEventQueue()
@ -231,10 +222,9 @@ void QWaylandDisplay::dispatchQueueWhile(wl_event_queue *queue, std::function<bo
else else
wl_display_cancel_read(mDisplay); wl_display_cancel_read(mDisplay);
if (wl_display_dispatch_queue_pending(mDisplay, queue) < 0) { if (wl_display_dispatch_queue_pending(mDisplay, queue) < 0)
checkError(); checkError();
exitWithError();
}
if (!condition()) if (!condition())
break; break;
} }

View File

@ -191,7 +191,6 @@ public slots:
private: private:
void waitForScreens(); void waitForScreens();
void exitWithError();
void checkError() const; void checkError() const;
void handleWaylandSync(); void handleWaylandSync();

View File

@ -301,11 +301,14 @@ QPlatformTheme *QWaylandIntegration::createPlatformTheme(const QString &name) co
return GenericWaylandTheme::createUnixTheme(name); return GenericWaylandTheme::createUnixTheme(name);
} }
// May be called from non-GUI threads
QWaylandClientBufferIntegration *QWaylandIntegration::clientBufferIntegration() const 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(); const_cast<QWaylandIntegration *>(this)->initializeClientBufferIntegration();
Q_ASSERT(mClientBufferIntegrationInitialized);
return mClientBufferIntegration && mClientBufferIntegration->isValid() ? mClientBufferIntegration.data() : nullptr; return mClientBufferIntegration && mClientBufferIntegration->isValid() ? mClientBufferIntegration.data() : nullptr;
} }
@ -325,9 +328,12 @@ QWaylandShellIntegration *QWaylandIntegration::shellIntegration() const
return mShellIntegration.data(); return mShellIntegration.data();
} }
// May be called from non-GUI threads
void QWaylandIntegration::initializeClientBufferIntegration() void QWaylandIntegration::initializeClientBufferIntegration()
{ {
mClientBufferIntegrationInitialized = true; QMutexLocker lock(&mClientBufferInitLock);
if (mClientBufferIntegrationInitialized)
return;
QString targetKey; QString targetKey;
bool disableHardwareIntegration = qEnvironmentVariableIsSet("QT_WAYLAND_DISABLE_HW_INTEGRATION"); bool disableHardwareIntegration = qEnvironmentVariableIsSet("QT_WAYLAND_DISABLE_HW_INTEGRATION");
@ -345,9 +351,7 @@ void QWaylandIntegration::initializeClientBufferIntegration()
if (targetKey.isEmpty()) { if (targetKey.isEmpty()) {
qWarning("Failed to determine what client buffer integration to use"); qWarning("Failed to determine what client buffer integration to use");
return; } else {
}
QStringList keys = QWaylandClientBufferIntegrationFactory::keys(); QStringList keys = QWaylandClientBufferIntegrationFactory::keys();
if (keys.contains(targetKey)) { if (keys.contains(targetKey)) {
mClientBufferIntegration.reset(QWaylandClientBufferIntegrationFactory::create(targetKey, QStringList())); mClientBufferIntegration.reset(QWaylandClientBufferIntegrationFactory::create(targetKey, QStringList()));
@ -358,6 +362,11 @@ void QWaylandIntegration::initializeClientBufferIntegration()
qWarning("Failed to load client buffer integration: %s\n", qPrintable(targetKey)); 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() void QWaylandIntegration::initializeServerBufferIntegration()
{ {
mServerBufferIntegrationInitialized = true; mServerBufferIntegrationInitialized = true;

View File

@ -54,6 +54,7 @@
#include <QtWaylandClient/qtwaylandclientglobal.h> #include <QtWaylandClient/qtwaylandclientglobal.h>
#include <qpa/qplatformintegration.h> #include <qpa/qplatformintegration.h>
#include <QtCore/QScopedPointer> #include <QtCore/QScopedPointer>
#include <QtCore/QMutex>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -148,6 +149,7 @@ private:
QScopedPointer<QPlatformAccessibility> mAccessibility; QScopedPointer<QPlatformAccessibility> mAccessibility;
#endif #endif
bool mFailed = false; bool mFailed = false;
QMutex mClientBufferInitLock;
bool mClientBufferIntegrationInitialized = false; bool mClientBufferIntegrationInitialized = false;
bool mServerBufferIntegrationInitialized = false; bool mServerBufferIntegrationInitialized = false;
bool mShellIntegrationInitialized = false; bool mShellIntegrationInitialized = false;

View File

@ -211,9 +211,12 @@ void QWaylandWindow::initWindow()
void QWaylandWindow::initializeWlSurface() void QWaylandWindow::initializeWlSurface()
{ {
Q_ASSERT(!isInitialized()); Q_ASSERT(!isInitialized());
{
QWriteLocker lock(&mSurfaceLock); QWriteLocker lock(&mSurfaceLock);
init(mDisplay->createSurface(static_cast<QtWayland::wl_surface *>(this))); init(mDisplay->createSurface(static_cast<QtWayland::wl_surface *>(this)));
} }
emit wlSurfaceCreated();
}
bool QWaylandWindow::shouldCreateShellSurface() const bool QWaylandWindow::shouldCreateShellSurface() const
{ {
@ -248,6 +251,7 @@ void QWaylandWindow::reset(bool sendDestroyEvent)
delete mSubSurfaceWindow; delete mSubSurfaceWindow;
mSubSurfaceWindow = nullptr; mSubSurfaceWindow = nullptr;
if (isInitialized()) { if (isInitialized()) {
emit wlSurfaceDestroyed();
QWriteLocker lock(&mSurfaceLock); QWriteLocker lock(&mSurfaceLock);
destroy(); destroy();
} }

View File

@ -201,6 +201,10 @@ public:
public slots: public slots:
void applyConfigure(); void applyConfigure();
signals:
void wlSurfaceCreated();
void wlSurfaceDestroyed();
protected: protected:
void surface_enter(struct ::wl_output *output) override; void surface_enter(struct ::wl_output *output) override;
void surface_leave(struct ::wl_output *output) override; void surface_leave(struct ::wl_output *output) override;

View File

@ -376,7 +376,7 @@ QVector<xkb_keysym_t> QWaylandXkb::toKeysym(QKeyEvent *event)
keysyms.append(XKB_KEY_KP_0 + (event->key() - Qt::Key_0)); keysyms.append(XKB_KEY_KP_0 + (event->key() - Qt::Key_0));
else else
keysyms.append(toKeysymFromTable(event->key())); 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: // From libxkbcommon keysym-utf.c:
// "We allow to represent any UCS character in the range U-00000000 to // "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." // U-00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff."