diff --git a/src/plugins/platforms/wayland/CMakeLists.txt b/src/plugins/platforms/wayland/CMakeLists.txt index 4916af81e08..300fd4ffa82 100644 --- a/src/plugins/platforms/wayland/CMakeLists.txt +++ b/src/plugins/platforms/wayland/CMakeLists.txt @@ -42,6 +42,7 @@ qt_internal_add_module(WaylandClient qwaylandinputmethodcontext.cpp qwaylandinputmethodcontext_p.h qwaylandintegration.cpp qwaylandintegration_p.h qwaylandnativeinterface.cpp qwaylandnativeinterface_p.h + qwaylandplatformservices.cpp qwaylandplatformservices_p.h qwaylandpointergestures.cpp qwaylandpointergestures_p.h qwaylandqtkey.cpp qwaylandqtkey_p.h qwaylandscreen.cpp qwaylandscreen_p.h diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp index 265f0bb3f19..9bd60e74129 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp +++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp @@ -312,7 +312,7 @@ QWaylandClientBufferIntegration * QWaylandDisplay::clientBufferIntegration() con QWaylandWindowManagerIntegration *QWaylandDisplay::windowManagerIntegration() const { - return mWindowManagerIntegration.data(); + return mGlobals.windowManagerIntegration.get(); } QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration) @@ -335,8 +335,6 @@ void QWaylandDisplay::setupConnection() struct ::wl_registry *registry = wl_display_get_registry(mDisplay); init(registry); - mWindowManagerIntegration.reset(new QWaylandWindowManagerIntegration(this)); - #if QT_CONFIG(xkbcommon) mXkbContext.reset(xkb_context_new(XKB_CONTEXT_NO_FLAGS)); if (!mXkbContext) @@ -373,7 +371,6 @@ QWaylandDisplay::~QWaylandDisplay(void) // Reset the globals manually since they need to be destroyed before the wl_display mGlobals = {}; - mWindowManagerIntegration.reset(); if (object()) wl_registry_destroy(object()); @@ -781,6 +778,9 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin mGlobals.xdgToplevelDragManager.reset( new WithDestructor(registry, id, 1)); + } else if (interface == QLatin1String(QtWayland::qt_windowmanager::interface()->name)) { + mGlobals.windowManagerIntegration.reset( + new QWaylandWindowManagerIntegration(this, id, version)); } mRegistryGlobals.append(RegistryGlobal(id, interface, version, registry)); diff --git a/src/plugins/platforms/wayland/qwaylanddisplay_p.h b/src/plugins/platforms/wayland/qwaylanddisplay_p.h index 5b564c8d796..2fd176d8405 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay_p.h +++ b/src/plugins/platforms/wayland/qwaylanddisplay_p.h @@ -316,8 +316,6 @@ private: QScopedPointer mCursor; #endif - QScopedPointer mWindowManagerIntegration; - struct GlobalHolder { std::unique_ptr compositor; @@ -346,6 +344,7 @@ private: std::unique_ptr fractionalScaleManager; std::unique_ptr cursorShapeManager; std::unique_ptr xdgToplevelDragManager; + std::unique_ptr windowManagerIntegration; } mGlobals; int mFd = -1; int mWritableNotificationFd = -1; diff --git a/src/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp index eb19be45df8..c5eb1e96ae4 100644 --- a/src/plugins/platforms/wayland/qwaylandintegration.cpp +++ b/src/plugins/platforms/wayland/qwaylandintegration.cpp @@ -15,6 +15,7 @@ #endif #include "qwaylanddnd_p.h" #include "qwaylandwindowmanagerintegration_p.h" +#include "qwaylandplatformservices_p.h" #include "qwaylandscreen_p.h" #include "qwaylandcursor_p.h" @@ -83,6 +84,7 @@ QWaylandIntegration::QWaylandIntegration() #endif { mDisplay.reset(new QWaylandDisplay(this)); + mPlatformServices.reset(new QWaylandPlatformServices(mDisplay.data())); QWaylandWindow::fixedToplevelPositions = !qEnvironmentVariableIsSet("QT_WAYLAND_DISABLE_FIXED_POSITIONS"); @@ -246,7 +248,7 @@ QPlatformAccessibility *QWaylandIntegration::accessibility() const QPlatformServices *QWaylandIntegration::services() const { - return mDisplay->windowManagerIntegration(); + return mPlatformServices.data(); } QWaylandDisplay *QWaylandIntegration::display() const @@ -525,8 +527,7 @@ void QWaylandIntegration::reset() void QWaylandIntegration::setApplicationBadge(qint64 number) { - auto unixServices = mDisplay->windowManagerIntegration(); - unixServices->setApplicationBadge(number); + mPlatformServices->setApplicationBadge(number); } } diff --git a/src/plugins/platforms/wayland/qwaylandintegration_p.h b/src/plugins/platforms/wayland/qwaylandintegration_p.h index 81d1ae6d2b7..f26cc3d2916 100644 --- a/src/plugins/platforms/wayland/qwaylandintegration_p.h +++ b/src/plugins/platforms/wayland/qwaylandintegration_p.h @@ -34,6 +34,7 @@ class QWaylandInputDeviceIntegration; class QWaylandInputDevice; class QWaylandScreen; class QWaylandCursor; +class QWaylandPlatformServices; class Q_WAYLANDCLIENT_EXPORT QWaylandIntegration : public QPlatformIntegration { @@ -136,6 +137,7 @@ private: #if QT_CONFIG(accessibility) mutable QScopedPointer mAccessibility; #endif + QScopedPointer mPlatformServices; QMutex mClientBufferInitLock; bool mClientBufferIntegrationInitialized = false; bool mServerBufferIntegrationInitialized = false; diff --git a/src/plugins/platforms/wayland/qwaylandplatformservices.cpp b/src/plugins/platforms/wayland/qwaylandplatformservices.cpp new file mode 100644 index 00000000000..14556d2825f --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandplatformservices.cpp @@ -0,0 +1,50 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qwaylandplatformservices_p.h" +#include "qwaylandwindow_p.h" +#include "qwaylanddisplay_p.h" +#include "qwaylandshellsurface_p.h" +#include "qwaylandwindowmanagerintegration_p.h" + +QT_BEGIN_NAMESPACE + +namespace QtWaylandClient { + +QWaylandPlatformServices::QWaylandPlatformServices(QWaylandDisplay *display) + : m_display(display) { } + +bool QWaylandPlatformServices::openUrl(const QUrl &url) +{ + if (auto windowManagerIntegration = m_display->windowManagerIntegration()) { + windowManagerIntegration->openUrl(url); + return true; + } + return QGenericUnixServices::openUrl(url); +} + +bool QWaylandPlatformServices::openDocument(const QUrl &url) +{ + if (auto windowManagerIntegration = m_display->windowManagerIntegration()) { + windowManagerIntegration->openUrl(url); + return true; + } + return QGenericUnixServices::openDocument(url); +} + +QString QWaylandPlatformServices::portalWindowIdentifier(QWindow *window) +{ + if (window && window->handle()) { + auto shellSurface = static_cast(window->handle())->shellSurface(); + if (shellSurface) { + const QString handle = shellSurface->externWindowHandle(); + return QLatin1String("wayland:") + handle; + } + } + return QString(); +} +} // namespace QtWaylandClient + +QT_END_NAMESPACE + +#include "moc_qwaylandplatformservices_p.cpp" diff --git a/src/plugins/platforms/wayland/qwaylandplatformservices_p.h b/src/plugins/platforms/wayland/qwaylandplatformservices_p.h new file mode 100644 index 00000000000..6106a901888 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandplatformservices_p.h @@ -0,0 +1,48 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QWAYLANDPLATFORMSERVICES_H +#define QWAYLANDPLATFORMSERVICES_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +namespace QtWaylandClient { + +class QWaylandDisplay; + +class Q_WAYLANDCLIENT_EXPORT QWaylandPlatformServices : public QGenericUnixServices +{ +public: + explicit QWaylandPlatformServices(QWaylandDisplay *waylandDisplay); + + bool openUrl(const QUrl &url) override; + bool openDocument(const QUrl &url) override; + QString portalWindowIdentifier(QWindow *window) override; + +private: + QWaylandDisplay *m_display; +}; + +QT_END_NAMESPACE + +} // namespace QtWaylandClient + +#endif // QWAYLANDPLATFORMSERVICES_H diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index 081110f8334..73fb331ebb1 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -12,7 +12,7 @@ #include "qwaylandshellsurface_p.h" #include "qwaylandsubsurface_p.h" #include "qwaylandabstractdecoration_p.h" -#include "qwaylandwindowmanagerintegration_p.h" +#include "qwaylandplatformservices_p.h" #include "qwaylandnativeinterface_p.h" #include "qwaylanddecorationfactory_p.h" #include "qwaylandshmbackingstore_p.h" diff --git a/src/plugins/platforms/wayland/qwaylandwindowmanagerintegration.cpp b/src/plugins/platforms/wayland/qwaylandwindowmanagerintegration.cpp index 149190420c2..c7a5c0d1471 100644 --- a/src/plugins/platforms/wayland/qwaylandwindowmanagerintegration.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindowmanagerintegration.cpp @@ -22,49 +22,26 @@ QT_BEGIN_NAMESPACE namespace QtWaylandClient { -class QWaylandWindowManagerIntegrationPrivate { -public: - QWaylandWindowManagerIntegrationPrivate(QWaylandDisplay *waylandDisplay); - bool m_blockPropertyUpdates = false; - QWaylandDisplay *m_waylandDisplay = nullptr; - QHash m_queuedProperties; - bool m_showIsFullScreen = false; -}; - -QWaylandWindowManagerIntegrationPrivate::QWaylandWindowManagerIntegrationPrivate(QWaylandDisplay *waylandDisplay) - : m_waylandDisplay(waylandDisplay) +QWaylandWindowManagerIntegration::QWaylandWindowManagerIntegration(QWaylandDisplay *waylandDisplay, + uint id, uint version) + : QtWayland::qt_windowmanager(waylandDisplay->object(), id, version), + m_waylandDisplay(waylandDisplay) { } -QWaylandWindowManagerIntegration::QWaylandWindowManagerIntegration(QWaylandDisplay *waylandDisplay) - : d_ptr(new QWaylandWindowManagerIntegrationPrivate(waylandDisplay)) -{ - waylandDisplay->addRegistryListener(&wlHandleListenerGlobal, this); -} - QWaylandWindowManagerIntegration::~QWaylandWindowManagerIntegration() { - if (object()) - qt_windowmanager_destroy(object()); + qt_windowmanager_destroy(object()); } bool QWaylandWindowManagerIntegration::showIsFullScreen() const { - Q_D(const QWaylandWindowManagerIntegration); - return d->m_showIsFullScreen; -} - -void QWaylandWindowManagerIntegration::wlHandleListenerGlobal(void *data, wl_registry *registry, uint32_t id, const QString &interface, uint32_t version) -{ - Q_UNUSED(version); - if (interface == QStringLiteral("qt_windowmanager")) - static_cast(data)->init(registry, id, 1); + return m_showIsFullScreen; } void QWaylandWindowManagerIntegration::windowmanager_hints(int32_t showIsFullScreen) { - Q_D(QWaylandWindowManagerIntegration); - d->m_showIsFullScreen = showIsFullScreen; + m_showIsFullScreen = showIsFullScreen; } void QWaylandWindowManagerIntegration::windowmanager_quit() @@ -72,11 +49,9 @@ void QWaylandWindowManagerIntegration::windowmanager_quit() QGuiApplication::quit(); } -void QWaylandWindowManagerIntegration::openUrl_helper(const QUrl &url) +void QWaylandWindowManagerIntegration::openUrl(const QUrl &url) { - Q_ASSERT(isInitialized()); QString data = url.toString(); - static const int chunkSize = 128; while (!data.isEmpty()) { QString chunk = data.left(chunkSize); @@ -88,36 +63,6 @@ void QWaylandWindowManagerIntegration::openUrl_helper(const QUrl &url) open_url(!data.isEmpty(), chunk); } } - -bool QWaylandWindowManagerIntegration::openUrl(const QUrl &url) -{ - if (isInitialized()) { - openUrl_helper(url); - return true; - } - return QGenericUnixServices::openUrl(url); -} - -bool QWaylandWindowManagerIntegration::openDocument(const QUrl &url) -{ - if (isInitialized()) { - openUrl_helper(url); - return true; - } - return QGenericUnixServices::openDocument(url); -} - -QString QWaylandWindowManagerIntegration::portalWindowIdentifier(QWindow *window) -{ - if (window && window->handle()) { - auto shellSurface = static_cast(window->handle())->shellSurface(); - if (shellSurface) { - const QString handle = shellSurface->externWindowHandle(); - return QLatin1String("wayland:") + handle; - } - } - return QString(); -} } QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland/qwaylandwindowmanagerintegration_p.h b/src/plugins/platforms/wayland/qwaylandwindowmanagerintegration_p.h index 18eb171b63c..76d9b0da045 100644 --- a/src/plugins/platforms/wayland/qwaylandwindowmanagerintegration_p.h +++ b/src/plugins/platforms/wayland/qwaylandwindowmanagerintegration_p.h @@ -16,9 +16,6 @@ // #include -#include - -#include #include #include @@ -27,35 +24,28 @@ QT_BEGIN_NAMESPACE namespace QtWaylandClient { -class QWaylandWindow; class QWaylandDisplay; class QWaylandWindowManagerIntegrationPrivate; -class Q_WAYLANDCLIENT_EXPORT QWaylandWindowManagerIntegration : public QObject, public QGenericUnixServices, public QtWayland::qt_windowmanager +class Q_WAYLANDCLIENT_EXPORT QWaylandWindowManagerIntegration : public QtWayland::qt_windowmanager { - Q_OBJECT - Q_DECLARE_PRIVATE(QWaylandWindowManagerIntegration) -public: - explicit QWaylandWindowManagerIntegration(QWaylandDisplay *waylandDisplay); - ~QWaylandWindowManagerIntegration() override; - bool openUrl(const QUrl &url) override; - bool openDocument(const QUrl &url) override; - QString portalWindowIdentifier(QWindow *window) override; +public: + explicit QWaylandWindowManagerIntegration(QWaylandDisplay *waylandDisplay, uint id, + uint version); + ~QWaylandWindowManagerIntegration(); + + void openUrl(const QUrl &url); bool showIsFullScreen() const; private: - static void wlHandleListenerGlobal(void *data, wl_registry *registry, uint32_t id, - const QString &interface, uint32_t version); - - QScopedPointer d_ptr; - void windowmanager_hints(int32_t showIsFullScreen) override; void windowmanager_quit() override; - void openUrl_helper(const QUrl &url); + QWaylandDisplay *m_waylandDisplay = nullptr; + bool m_showIsFullScreen = false; }; QT_END_NAMESPACE