Client: Check for shell integration when initializing platform plugin

This makes QWaylandDisplay::initialize return a boolean and moves the
QWaylandIntegration's failure check out of constructor as
QWaylandIntegration::shellIntegration is a virtual method, this also
removes the out-of-date comments about processEvents as it's no more
used in QWaylandDisplay::forceRoundTrip.

Fixes: QTBUG-102457
Pick-to: 6.5
Change-Id: I3c8f1d9fd195326b587b45318443c2beee1ebfc2
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: David Edmundson <davidedmundson@kde.org>
This commit is contained in:
Ilya Fedin 2023-03-28 01:16:56 +04:00
parent d6d416b05e
commit 5e864b671e
5 changed files with 28 additions and 16 deletions

View File

@ -379,8 +379,11 @@ QWaylandDisplay::~QWaylandDisplay(void)
// Steps which is called just after constructor. This separates registry_global() out of the constructor
// so that factory functions in integration can be overridden.
void QWaylandDisplay::initialize()
bool QWaylandDisplay::initialize()
{
if (!isInitialized())
return false;
forceRoundTrip();
if (!mWaitingScreens.isEmpty()) {
@ -389,6 +392,8 @@ void QWaylandDisplay::initialize()
}
if (!mClientSideInputContextRequested)
mTextInputManagerIndex = INT_MAX;
return qEnvironmentVariableIntValue("QT_WAYLAND_DONT_CHECK_SHELL_INTEGRATION") || shellIntegration();
}
void QWaylandDisplay::ensureScreen()

View File

@ -97,7 +97,7 @@ public:
QWaylandDisplay(QWaylandIntegration *waylandIntegration);
~QWaylandDisplay(void) override;
void initialize();
bool initialize();
#if QT_CONFIG(xkbcommon)
struct xkb_context *xkbContext() const { return mXkbContext.get(); }

View File

@ -83,10 +83,6 @@ QWaylandIntegration::QWaylandIntegration()
#endif
{
mDisplay.reset(new QWaylandDisplay(this));
if (!mDisplay->isInitialized()) {
mFailed = true;
return;
}
QWaylandWindow::fixedToplevelPositions =
!qEnvironmentVariableIsSet("QT_WAYLAND_DISABLE_FIXED_POSITIONS");
@ -99,6 +95,11 @@ QWaylandIntegration::~QWaylandIntegration()
sInstance = nullptr;
}
bool QWaylandIntegration::init()
{
return mDisplay->initialize();
}
QPlatformNativeInterface * QWaylandIntegration::nativeInterface() const
{
return mNativeInterface.data();
@ -168,7 +169,7 @@ QPlatformNativeInterface *QWaylandIntegration::createPlatformNativeInterface()
// Support platform specific initialization
void QWaylandIntegration::initializePlatform()
{
mDisplay->initialize();
mDisplay->initEventThread();
mNativeInterface.reset(createPlatformNativeInterface());
initializeInputDeviceIntegration();
@ -184,14 +185,9 @@ void QWaylandIntegration::initializePlatform()
void QWaylandIntegration::initialize()
{
mDisplay->initEventThread();
// Call this after initializing event thread for QWaylandDisplay::forceRoundTrip()
initializePlatform();
// But the aboutToBlock() and awake() should be connected after initializePlatform().
// Otherwise the connected flushRequests() may consumes up all events before processEvents starts to wait,
// so that processEvents(QEventLoop::WaitForMoreEvents) may be blocked in the forceRoundTrip().
// Call this after initializing event thread for QWaylandDisplay::flushRequests()
QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher;
QObject::connect(dispatcher, SIGNAL(aboutToBlock()), mDisplay.data(), SLOT(flushRequests()));
QObject::connect(dispatcher, SIGNAL(awake()), mDisplay.data(), SLOT(flushRequests()));

View File

@ -43,7 +43,7 @@ public:
static QWaylandIntegration *instance() { return sInstance; }
bool hasFailed() { return mFailed; }
bool init();
bool hasCapability(QPlatformIntegration::Capability cap) const override;
QPlatformWindow *createPlatformWindow(QWindow *window) const override;
@ -134,7 +134,6 @@ private:
#if QT_CONFIG(accessibility)
mutable QScopedPointer<QPlatformAccessibility> mAccessibility;
#endif
bool mFailed = false;
QMutex mClientBufferInitLock;
bool mClientBufferIntegrationInitialized = false;
bool mServerBufferIntegrationInitialized = false;

View File

@ -123,5 +123,17 @@ void tst_clientextension::globalRemoved()
QCOMPARE(spy.size(), 1);
}
QCOMPOSITOR_TEST_MAIN(tst_clientextension)
int main(int argc, char **argv)
{
QTemporaryDir tmpRuntimeDir;
setenv("XDG_RUNTIME_DIR", tmpRuntimeDir.path().toLocal8Bit(), 1);
setenv("QT_QPA_PLATFORM", "wayland", 1);
setenv("QT_WAYLAND_DONT_CHECK_SHELL_INTEGRATION", "1", 1);
tst_clientextension tc;
QGuiApplication app(argc, argv);
QTEST_SET_MAIN_SOURCE_PATH
return QTest::qExec(&tc, argc, argv);
}
#include "tst_clientextension.moc"