diff options
79 files changed, 1064 insertions, 1828 deletions
diff --git a/.cmake.conf b/.cmake.conf index dc1d7a924..6792234a2 100644 --- a/.cmake.conf +++ b/.cmake.conf @@ -1,4 +1,4 @@ -set(QT_REPO_MODULE_VERSION "6.8.0") +set(QT_REPO_MODULE_VERSION "6.9.0") set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "alpha1") set(QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_NO_AS_CONST=1") list(APPEND QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_NO_FOREACH=1") diff --git a/dependencies.yaml b/dependencies.yaml index 7929629d8..94dd91270 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -1,10 +1,10 @@ dependencies: ../qtbase: - ref: 0cd5eb895cc96126a495eb3d2d258be47eed193a + ref: 2d72757875c913939909a1a36fcb123a1e26ac26 required: true ../qtdeclarative: - ref: c63bb2bad5b4e741ed8a1e16d8f1f916c9baf61d + ref: 5ca788a7a2bede98c9c75ce1068fa32fd63478cf required: false ../qtsvg: - ref: 69d4dcf5d4bfab4c3a8a3ea7a90e6694b995f799 + ref: dd34b6eea3ab9cba1805cdab1e5f058924732121 required: false diff --git a/licenseRule.json b/licenseRule.json new file mode 100644 index 000000000..be2d93028 --- /dev/null +++ b/licenseRule.json @@ -0,0 +1,124 @@ +[ + { + "comment" : ["file_pattern_ending: strings matched against the end of a file name.", + "location keys: regular expression matched against the beginning of", + "the file path (relative to the git submodule root).", + "spdx: list of SPDX-License-Expression's allowed in the matching files.", + "-------------------------------------------------------", + "Files with the following endings are Build System licensed,", + "unless they are examples", + "Files with other endings can also be build system files" + ], + "file_pattern_ending" : ["CMakeLists.txt", ".cmake", ".pro", ".pri", ".prf", + "configure", "configure.bat", "cmake.in", "plist.in", "CMakeLists.txt.in"], + "location" : { + "" : { + "comment" : "Default", + "file type" : "build system", + "spdx" : ["BSD-3-Clause"] + }, + "(.*)(examples/|snippets/)" : { + "comment" : "Example takes precedence", + "file type" : "examples and snippets", + "spdx" : ["LicenseRef-Qt-Commercial OR BSD-3-Clause"] + } + } + }, + { + "comments" : ["Files with the following endings are Tool licensed,", + "unless they are examples.", + "Files with other endings can also be tool files."], + "file_pattern_ending" : [".sh", ".py", ".pl", ".bat", ".ps1"], + "location" :{ + "" : { + "comment" : "Default", + "file type" : "tools and utils", + "spdx" : ["LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0"] + }, + "(.*)(examples/|snippets/)" : { + "comment" : "Example takes precedence", + "file type" : "examples and snippets", + "spdx" : ["LicenseRef-Qt-Commercial OR BSD-3-Clause"] + } + } + }, + { + "comment" : "Files with the following endings are Documentation licensed.", + "file_pattern_ending" : [".qdoc", ".qdocinc" , ".qdocconf", ".txt", "README", "qt_attribution.json"], + "location" :{ + "" : { + "comment" : "", + "file type" : "documentation", + "spdx" : ["LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only"] + } + } + }, + { + "comment" : ["All other files", + "The licensing is defined only by the file location in the Qt module repository.", + "NO <file_pattern_ending> key for this case!", + "This needs to be the last entry of the file."], + "location" : { + "" : { + "comment" : "Default", + "file type" : "module and plugin", + "spdx" : ["LicenseRef-Qt-Commercial OR GPL-3.0-only"] + }, + "src/" : { + "comment" : "Default", + "file type" : "module and plugin", + "spdx" : ["LicenseRef-Qt-Commercial OR GPL-3.0-only"] + }, + "src/plugins/" : { + "comment" : "Default", + "file type" : "module and plugin", + "spdx" : ["LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only"] + }, + "src/plugins/hardwareintegration/compositor/" : { + "comment" : "Default", + "file type" : "module and plugin", + "spdx" : ["LicenseRef-Qt-Commercial OR GPL-3.0-only"] + }, + "src/shared/" : { + "comment" : "Default", + "file type" : "module and plugin", + "spdx" : ["LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only"] + }, + "src/imports/texture-sharing" : { + "comment" : "Default", + "file type" : "module and plugin", + "spdx" : ["LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only"] + }, + "src/qtwaylandscanner/qtwaylandscanner\\.cpp" : { + "comment" : "Default", + "file type" : "tools and utils", + "spdx" : ["LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0"] + }, + "src/client/" : { + "comment" : "Default", + "file type" : "module and plugin", + "spdx" : ["LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only"] + }, + "src/hardwareintegration/client/" : { + "comment" : "Default", + "file type" : "module and plugin", + "spdx" : ["LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only"] + }, + "tests/" : { + "comment" : "Default", + "file type" : "test", + "spdx" : ["LicenseRef-Qt-Commercial OR GPL-3.0-only"] + }, + "(.*)(examples/|snippets/)" : { + "comment" : "Default", + "file type" : "examples and snippets", + "spdx" : ["LicenseRef-Qt-Commercial OR BSD-3-Clause"] + }, + "config\\.tests/" : { + "comment" : "Default", + "file type" : "build system", + "spdx" : ["BSD-3-Clause"] + } + } + } +] diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index 4916af81e..4d0a106f6 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -9,7 +9,6 @@ qt_internal_add_module(WaylandClient PLUGIN_TYPES wayland-graphics-integration-client wayland-inputdevice-integration wayland-decoration-client wayland-shell-integration - GENERATE_CPP_EXPORTS SOURCES ../shared/qwaylandinputmethodeventbuilder.cpp ../shared/qwaylandinputmethodeventbuilder_p.h ../shared/qwaylandmimehelper.cpp ../shared/qwaylandmimehelper_p.h @@ -31,7 +30,6 @@ qt_internal_add_module(WaylandClient qwaylanddecorationfactory.cpp qwaylanddecorationfactory_p.h qwaylanddecorationplugin.cpp qwaylanddecorationplugin_p.h qwaylanddisplay.cpp qwaylanddisplay_p.h - qwaylandextendedsurface.cpp qwaylandextendedsurface_p.h qwaylandfractionalscale.cpp qwaylandfractionalscale_p.h qwaylandinputcontext.cpp qwaylandinputcontext_p.h qwaylandtextinputv1.cpp qwaylandtextinputv1_p.h @@ -42,6 +40,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 @@ -99,7 +98,6 @@ qt6_generate_wayland_protocol_client_sources(WaylandClient ${CMAKE_CURRENT_SOURCE_DIR}/../extensions/qt-key-unstable-v1.xml ${CMAKE_CURRENT_SOURCE_DIR}/../extensions/qt-text-input-method-unstable-v1.xml ${CMAKE_CURRENT_SOURCE_DIR}/../extensions/qt-windowmanager.xml - ${CMAKE_CURRENT_SOURCE_DIR}/../extensions/surface-extension.xml ${CMAKE_CURRENT_SOURCE_DIR}/../extensions/touch-extension.xml ${CMAKE_CURRENT_SOURCE_DIR}/hardwareintegration/../../extensions/hardware-integration.xml ${CMAKE_CURRENT_SOURCE_DIR}/hardwareintegration/../../extensions/server-buffer-extension.xml diff --git a/src/client/doc/src/cmake/qt_generate_wayland_protocol_client_sources.qdoc b/src/client/doc/src/cmake/qt_generate_wayland_protocol_client_sources.qdoc index 43f448fbd..0abd14d4e 100644 --- a/src/client/doc/src/cmake/qt_generate_wayland_protocol_client_sources.qdoc +++ b/src/client/doc/src/cmake/qt_generate_wayland_protocol_client_sources.qdoc @@ -37,7 +37,8 @@ code in C and C++ for implementing the protocols, and the resulting files will b of the \c target. The options \c{PUBLIC_CODE} and \c{PRIVATE_CODE} correspond to the \c{public-code} and -\c{private-code} options of \c{wayland-scanner}. For backwards compatibility \c{PUBLIC_CODE} is the +\c{private-code} options of \c{wayland-scanner}. \c{PUBLIC_CODE} will cause the symbols in the +code that is generated by \c{wayland-scanner} to be exported. For backwards compatibility \c{PUBLIC_CODE} is the default but generally \c{PRIVATE_CODE} is strongly recommended. qt_generate_wayland_protocol_client_sources() will trigger generation of the files needed to diff --git a/src/client/qwaylandbuffer.cpp b/src/client/qwaylandbuffer.cpp index 1907d5864..dd99b702b 100644 --- a/src/client/qwaylandbuffer.cpp +++ b/src/client/qwaylandbuffer.cpp @@ -31,6 +31,13 @@ void QWaylandBuffer::release(void *data, wl_buffer *) QWaylandBuffer *self = static_cast<QWaylandBuffer *>(data); self->mBusy = false; self->mCommitted = false; + if (self->mDeleteOnRelease) + delete self; +} + +void QWaylandBuffer::setDeleteOnRelease(bool deleteOnRelease) +{ + mDeleteOnRelease = deleteOnRelease; } const wl_buffer_listener QWaylandBuffer::listener = { diff --git a/src/client/qwaylandbuffer_p.h b/src/client/qwaylandbuffer_p.h index 3798ef3eb..c96f213b9 100644 --- a/src/client/qwaylandbuffer_p.h +++ b/src/client/qwaylandbuffer_p.h @@ -43,12 +43,15 @@ public: void setCommitted() { mCommitted = true; } bool committed() const { return mCommitted; } + void setDeleteOnRelease(bool deleteOnRelease); + protected: struct wl_buffer *mBuffer = nullptr; private: bool mBusy = false; bool mCommitted = false; + bool mDeleteOnRelease = false; static void release(void *data, wl_buffer *); static const wl_buffer_listener listener; diff --git a/src/client/qwaylanddatadevice.cpp b/src/client/qwaylanddatadevice.cpp index a59b201f6..30bfb86c5 100644 --- a/src/client/qwaylanddatadevice.cpp +++ b/src/client/qwaylanddatadevice.cpp @@ -195,7 +195,7 @@ void QWaylandDataDevice::data_device_drop() QPlatformDropQtResponse response = QWindowSystemInterface::handleDrop(m_dragWindow, dragData, m_dragPoint, supportedActions, QGuiApplication::mouseButtons(), - QGuiApplication::keyboardModifiers()); + m_inputDevice->modifiers()); if (drag) { auto drag = static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag()); drag->setDropResponse(response); @@ -230,7 +230,7 @@ void QWaylandDataDevice::data_device_enter(uint32_t serial, wl_surface *surface, const QPlatformDragQtResponse &response = QWindowSystemInterface::handleDrag( m_dragWindow, dragData, m_dragPoint, supportedActions, QGuiApplication::mouseButtons(), - QGuiApplication::keyboardModifiers()); + m_inputDevice->modifiers()); if (drag) { static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->setResponse(response); } @@ -243,7 +243,7 @@ void QWaylandDataDevice::data_device_leave() if (m_dragWindow) QWindowSystemInterface::handleDrag(m_dragWindow, nullptr, QPoint(), Qt::IgnoreAction, QGuiApplication::mouseButtons(), - QGuiApplication::keyboardModifiers()); + m_inputDevice->modifiers()); QDrag *drag = static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->currentDrag(); if (!drag) { @@ -274,7 +274,7 @@ void QWaylandDataDevice::data_device_motion(uint32_t time, wl_fixed_t x, wl_fixe const QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(m_dragWindow, dragData, m_dragPoint, supportedActions, QGuiApplication::mouseButtons(), - QGuiApplication::keyboardModifiers()); + m_inputDevice->modifiers()); if (drag) { static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->setResponse(response); diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp index 265f0bb3f..f78bf2dd2 100644 --- a/src/client/qwaylanddisplay.cpp +++ b/src/client/qwaylanddisplay.cpp @@ -34,7 +34,6 @@ #include "qwaylandshellintegration_p.h" #include "qwaylandclientbufferintegration_p.h" -#include "qwaylandextendedsurface_p.h" #include "qwaylandpointergestures_p.h" #include "qwaylandsubsurface_p.h" #include "qwaylandtouch_p.h" @@ -312,7 +311,7 @@ QWaylandClientBufferIntegration * QWaylandDisplay::clientBufferIntegration() con QWaylandWindowManagerIntegration *QWaylandDisplay::windowManagerIntegration() const { - return mWindowManagerIntegration.data(); + return mGlobals.windowManagerIntegration.get(); } QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration) @@ -335,8 +334,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 +370,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()); @@ -645,10 +641,6 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin } else if (interface == QLatin1String(QWaylandDataDeviceManager::interface()->name)) { mGlobals.dndSelectionHandler.reset(new QWaylandDataDeviceManager(this, version, id)); #endif - } else if (interface == QLatin1String(QtWayland::qt_surface_extension::interface()->name)) { - mGlobals.surfaceExtension.reset( - new WithDestructor<QtWayland::qt_surface_extension, qt_surface_extension_destroy>( - registry, id, 1)); } else if (interface == QLatin1String(QtWayland::wl_subcompositor::interface()->name)) { mGlobals.subCompositor.reset( new WithDestructor<QtWayland::wl_subcompositor, wl_subcompositor_destroy>(registry, @@ -781,6 +773,9 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin mGlobals.xdgToplevelDragManager.reset( new WithDestructor<QtWayland::xdg_toplevel_drag_manager_v1, xdg_toplevel_drag_manager_v1_destroy>(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)); @@ -891,7 +886,12 @@ bool QWaylandDisplay::supportsWindowDecoration() const if (disabled) return false; - static bool integrationSupport = clientBufferIntegration() && clientBufferIntegration()->supportsWindowDecoration(); + // Don't initialize client buffer integration just to check whether it can have a decoration. + if (!mWaylandIntegration->mClientBufferIntegrationInitialized) + return true; + + // We can do software-rendered decorations, only disable them if the integration explicitly says it can't. + static bool integrationSupport = !clientBufferIntegration() || clientBufferIntegration()->supportsWindowDecoration(); return integrationSupport; } diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h index 5b564c8d7..b93a2ecc0 100644 --- a/src/client/qwaylanddisplay_p.h +++ b/src/client/qwaylanddisplay_p.h @@ -48,7 +48,6 @@ class QPlatformScreen; class QPlatformPlaceholderScreen; namespace QtWayland { - class qt_surface_extension; class zwp_text_input_manager_v1; class zwp_text_input_manager_v2; class zwp_text_input_manager_v3; @@ -153,10 +152,6 @@ public: return mGlobals.primarySelectionManager.get(); } #endif - QtWayland::qt_surface_extension *windowExtension() const - { - return mGlobals.surfaceExtension.get(); - } #if QT_CONFIG(tabletevent) QWaylandTabletManagerV2 *tabletManager() const { @@ -316,8 +311,6 @@ private: QScopedPointer<QWaylandCursor> mCursor; #endif - QScopedPointer<QWaylandWindowManagerIntegration> mWindowManagerIntegration; - struct GlobalHolder { std::unique_ptr<QtWayland::wl_compositor> compositor; @@ -325,7 +318,6 @@ private: #if QT_CONFIG(wayland_datadevice) std::unique_ptr<QWaylandDataDeviceManager> dndSelectionHandler; #endif - std::unique_ptr<QtWayland::qt_surface_extension> surfaceExtension; std::unique_ptr<QtWayland::wl_subcompositor> subCompositor; std::unique_ptr<QWaylandTouchExtension> touchExtension; std::unique_ptr<QWaylandQtKeyExtension> qtKeyExtension; @@ -346,6 +338,7 @@ private: std::unique_ptr<QtWayland::wp_fractional_scale_manager_v1> fractionalScaleManager; std::unique_ptr<QtWayland::wp_cursor_shape_manager_v1> cursorShapeManager; std::unique_ptr<QtWayland::xdg_toplevel_drag_manager_v1> xdgToplevelDragManager; + std::unique_ptr<QWaylandWindowManagerIntegration> windowManagerIntegration; } mGlobals; int mFd = -1; int mWritableNotificationFd = -1; diff --git a/src/client/qwaylandextendedsurface.cpp b/src/client/qwaylandextendedsurface.cpp deleted file mode 100644 index a61612ce8..000000000 --- a/src/client/qwaylandextendedsurface.cpp +++ /dev/null @@ -1,92 +0,0 @@ -// 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 "qwaylandextendedsurface_p.h" - -#include "qwaylandwindow_p.h" - -#include "qwaylanddisplay_p.h" - -#include "qwaylandnativeinterface_p.h" - -#include <QtGui/QGuiApplication> -#include <qpa/qplatformnativeinterface.h> -#include <qpa/qwindowsysteminterface.h> - -QT_BEGIN_NAMESPACE - -namespace QtWaylandClient { - -QWaylandExtendedSurface::QWaylandExtendedSurface(QWaylandWindow *window) - : QtWayland::qt_extended_surface(window->display()->windowExtension()->get_extended_surface(window->wlSurface())) - , m_window(window) -{ -} - -QWaylandExtendedSurface::~QWaylandExtendedSurface() -{ - qt_extended_surface_destroy(object()); -} - -void QWaylandExtendedSurface::updateGenericProperty(const QString &name, const QVariant &value) -{ - QByteArray byteValue; - QDataStream ds(&byteValue, QIODevice::WriteOnly); - ds << value; - - update_generic_property(name, byteValue); -} - -void QWaylandExtendedSurface::setContentOrientationMask(Qt::ScreenOrientations mask) -{ - int32_t wlmask = 0; - if (mask & Qt::PrimaryOrientation) - wlmask |= QT_EXTENDED_SURFACE_ORIENTATION_PRIMARYORIENTATION; - if (mask & Qt::PortraitOrientation) - wlmask |= QT_EXTENDED_SURFACE_ORIENTATION_PORTRAITORIENTATION; - if (mask & Qt::LandscapeOrientation) - wlmask |= QT_EXTENDED_SURFACE_ORIENTATION_LANDSCAPEORIENTATION; - if (mask & Qt::InvertedPortraitOrientation) - wlmask |= QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDPORTRAITORIENTATION; - if (mask & Qt::InvertedLandscapeOrientation) - wlmask |= QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDLANDSCAPEORIENTATION; - set_content_orientation_mask(wlmask); -} - -void QWaylandExtendedSurface::extended_surface_onscreen_visibility(int32_t visibility) -{ - m_window->window()->setVisibility(static_cast<QWindow::Visibility>(visibility)); -} - -void QWaylandExtendedSurface::extended_surface_set_generic_property(const QString &name, wl_array *value) -{ - QByteArray data = QByteArray::fromRawData(static_cast<char *>(value->data), value->size); - - QVariant variantValue; - QDataStream ds(data); - ds >> variantValue; - - m_window->setProperty(name, variantValue); -} - -void QWaylandExtendedSurface::extended_surface_close() -{ - QWindowSystemInterface::handleCloseEvent(m_window->window()); -} - -Qt::WindowFlags QWaylandExtendedSurface::setWindowFlags(Qt::WindowFlags flags) -{ - uint wlFlags = 0; - - if (flags & Qt::WindowStaysOnTopHint) wlFlags |= QT_EXTENDED_SURFACE_WINDOWFLAG_STAYSONTOP; - if (flags & Qt::WindowOverridesSystemGestures) wlFlags |= QT_EXTENDED_SURFACE_WINDOWFLAG_OVERRIDESSYSTEMGESTURES; - if (flags & Qt::BypassWindowManagerHint) wlFlags |= QT_EXTENDED_SURFACE_WINDOWFLAG_BYPASSWINDOWMANAGER; - - set_window_flags(wlFlags); - - return flags & (Qt::WindowStaysOnTopHint | Qt::WindowOverridesSystemGestures | Qt::BypassWindowManagerHint); -} - -} - -QT_END_NAMESPACE diff --git a/src/client/qwaylandextendedsurface_p.h b/src/client/qwaylandextendedsurface_p.h deleted file mode 100644 index 0a7c6e5ad..000000000 --- a/src/client/qwaylandextendedsurface_p.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (C) 2018 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 QWAYLANDEXTENDEDSURFACE_H -#define QWAYLANDEXTENDEDSURFACE_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 <QtCore/QString> -#include <QtCore/QVariant> -#include <QtCore/QMap> // for QVariantMap - -#include <QtWaylandClient/qtwaylandclientglobal.h> - -#include <QtWaylandClient/private/qwayland-surface-extension.h> -#include <QtCore/private/qglobal_p.h> - -QT_BEGIN_NAMESPACE - -namespace QtWaylandClient { - -class QWaylandDisplay; -class QWaylandWindow; - -class Q_WAYLANDCLIENT_EXPORT QWaylandExtendedSurface : public QtWayland::qt_extended_surface -{ -public: - QWaylandExtendedSurface(QWaylandWindow *window); - ~QWaylandExtendedSurface() override; - - void setContentOrientationMask(Qt::ScreenOrientations mask); - - void updateGenericProperty(const QString &name, const QVariant &value); - - Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags); - -private: - void extended_surface_onscreen_visibility(int32_t visibility) override; - void extended_surface_set_generic_property(const QString &name, wl_array *value) override; - void extended_surface_close() override; - - QWaylandWindow *m_window = nullptr; - QVariantMap m_properties; -}; - -} - -QT_END_NAMESPACE - -#endif // QWAYLANDEXTENDEDSURFACE_H diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp index eb19be45d..c5eb1e96a 100644 --- a/src/client/qwaylandintegration.cpp +++ b/src/client/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/client/qwaylandintegration_p.h b/src/client/qwaylandintegration_p.h index 81d1ae6d2..f26cc3d29 100644 --- a/src/client/qwaylandintegration_p.h +++ b/src/client/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<QPlatformAccessibility> mAccessibility; #endif + QScopedPointer<QWaylandPlatformServices> mPlatformServices; QMutex mClientBufferInitLock; bool mClientBufferIntegrationInitialized = false; bool mServerBufferIntegrationInitialized = false; diff --git a/src/client/qwaylandnativeinterface.cpp b/src/client/qwaylandnativeinterface.cpp index 601f833aa..e1586d244 100644 --- a/src/client/qwaylandnativeinterface.cpp +++ b/src/client/qwaylandnativeinterface.cpp @@ -6,7 +6,6 @@ #include "qwaylandwindow_p.h" #include "qwaylandshellintegration_p.h" #include "qwaylandsubsurface_p.h" -#include "qwaylandextendedsurface_p.h" #include "qwaylandintegration_p.h" #include "qwaylanddisplay_p.h" #include "qwaylandwindowmanagerintegration_p.h" diff --git a/src/client/qwaylandplatformservices.cpp b/src/client/qwaylandplatformservices.cpp new file mode 100644 index 000000000..14556d282 --- /dev/null +++ b/src/client/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<QWaylandWindow *>(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/client/qwaylandplatformservices_p.h b/src/client/qwaylandplatformservices_p.h new file mode 100644 index 000000000..6106a9018 --- /dev/null +++ b/src/client/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 <QtCore/QObject> + +#include <QtGui/private/qgenericunixservices_p.h> + +#include <QtWaylandClient/private/qwayland-qt-windowmanager.h> +#include <QtWaylandClient/qtwaylandclientglobal.h> + +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/client/qwaylandshellsurface.cpp b/src/client/qwaylandshellsurface.cpp index 77d6b97a9..fde1e1d3f 100644 --- a/src/client/qwaylandshellsurface.cpp +++ b/src/client/qwaylandshellsurface.cpp @@ -3,7 +3,6 @@ #include "qwaylandshellsurface_p.h" #include "qwaylandwindow_p.h" -#include "qwaylandextendedsurface_p.h" #include "qwaylandinputdevice_p.h" QT_BEGIN_NAMESPACE diff --git a/src/client/qwaylandsurface.cpp b/src/client/qwaylandsurface.cpp index 949d7b160..274fdda82 100644 --- a/src/client/qwaylandsurface.cpp +++ b/src/client/qwaylandsurface.cpp @@ -15,6 +15,7 @@ QWaylandSurface::QWaylandSurface(QWaylandDisplay *display) : wl_surface(display->createSurface(this)) { connect(qApp, &QGuiApplication::screenRemoved, this, &QWaylandSurface::handleScreenRemoved); + connect(qApp, &QGuiApplication::screenAdded, this, &QWaylandSurface::screensChanged); } QWaylandSurface::~QWaylandSurface() @@ -24,7 +25,14 @@ QWaylandSurface::~QWaylandSurface() QWaylandScreen *QWaylandSurface::oldestEnteredScreen() { - return m_screens.value(0, nullptr); + for (auto *screen : std::as_const(m_screens)) { + // only report valid screens + // we can have some ouptuts waiting for xdg output information + // that are valid QPlatformScreens, but not valid QScreens + if (screen->screen()) + return screen; + } + return nullptr; } QWaylandSurface *QWaylandSurface::fromWlSurface(::wl_surface *surface) diff --git a/src/client/qwaylandtextinputv3.cpp b/src/client/qwaylandtextinputv3.cpp index 017456ac2..bb449c9d6 100644 --- a/src/client/qwaylandtextinputv3.cpp +++ b/src/client/qwaylandtextinputv3.cpp @@ -80,8 +80,8 @@ void QWaylandTextInputv3::zwp_text_input_v3_preedit_string(const QString &text, return; m_pendingPreeditString.text = text; - m_pendingPreeditString.cursorBegin = cursorBegin; - m_pendingPreeditString.cursorEnd = cursorEnd; + m_pendingPreeditString.cursorBegin = QWaylandInputMethodEventBuilder::indexFromWayland(text, cursorBegin); + m_pendingPreeditString.cursorEnd = QWaylandInputMethodEventBuilder::indexFromWayland(text, cursorEnd); } void QWaylandTextInputv3::zwp_text_input_v3_commit_string(const QString &text) @@ -101,8 +101,8 @@ void QWaylandTextInputv3::zwp_text_input_v3_delete_surrounding_text(uint32_t bef if (!QGuiApplication::focusObject()) return; - m_pendingDeleteBeforeText = QWaylandInputMethodEventBuilder::indexFromWayland(m_surroundingText, beforeText); - m_pendingDeleteAfterText = QWaylandInputMethodEventBuilder::indexFromWayland(m_surroundingText, afterText); + m_pendingDeleteBeforeText = beforeText; + m_pendingDeleteAfterText = afterText; } void QWaylandTextInputv3::zwp_text_input_v3_done(uint32_t serial) @@ -157,14 +157,26 @@ void QWaylandTextInputv3::zwp_text_input_v3_done(uint32_t serial) qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO << "DELETE" << m_pendingDeleteBeforeText << m_pendingDeleteAfterText; qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO << "COMMIT" << m_pendingCommitString; - // A workaround for reselection - // It will disable redundant commit after reselection - if (m_pendingDeleteBeforeText != 0 || m_pendingDeleteAfterText != 0) + int replaceFrom = 0; + int replaceLength = 0; + if (m_pendingDeleteBeforeText != 0 || m_pendingDeleteAfterText != 0) { + // A workaround for reselection + // It will disable redundant commit after reselection m_condReselection = true; + const QByteArray &utf8 = QStringView{m_surroundingText}.toUtf8(); + if (m_cursorPos < int(m_pendingDeleteBeforeText)) { + replaceFrom = -QString::fromUtf8(QByteArrayView{utf8}.first(m_pendingDeleteBeforeText)).size(); + replaceLength = QString::fromUtf8(QByteArrayView{utf8}.first(m_pendingDeleteBeforeText + m_pendingDeleteAfterText)).size(); + } else { + replaceFrom = -QString::fromUtf8(QByteArrayView{utf8}.sliced(m_cursorPos - m_pendingDeleteBeforeText, m_pendingDeleteBeforeText)).size(); + replaceLength = QString::fromUtf8(QByteArrayView{utf8}.sliced(m_cursorPos - m_pendingDeleteBeforeText, m_pendingDeleteBeforeText + m_pendingDeleteAfterText)).size(); + } + } + qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO << "DELETE from " << replaceFrom << " length " << replaceLength; event.setCommitString(m_pendingCommitString, - -m_pendingDeleteBeforeText, - m_pendingDeleteBeforeText + m_pendingDeleteAfterText); + replaceFrom, + replaceLength); m_currentPreeditString = m_pendingPreeditString; m_pendingPreeditString.clear(); m_pendingCommitString.clear(); @@ -235,54 +247,63 @@ void QWaylandTextInputv3::updateState(Qt::InputMethodQueries queries, uint32_t f int cursor = event.value(Qt::ImCursorPosition).toInt(); int anchor = event.value(Qt::ImAnchorPosition).toInt(); - qCDebug(qLcQpaWaylandTextInput) << "Orginal surrounding_text from InputMethodQuery: " << text << cursor << anchor; + qCDebug(qLcQpaWaylandTextInput) << "Original surrounding_text from InputMethodQuery: " << text << cursor << anchor; // Make sure text is not too big // surround_text cannot exceed 4000byte in wayland protocol // The worst case will be supposed here. const int MAX_MESSAGE_SIZE = 4000; - if (text.toUtf8().size() > MAX_MESSAGE_SIZE) { - const int selectionStart = QWaylandInputMethodEventBuilder::indexToWayland(text, qMin(cursor, anchor)); - const int selectionEnd = QWaylandInputMethodEventBuilder::indexToWayland(text, qMax(cursor, anchor)); + const int textSize = text.toUtf8().size(); + if (textSize > MAX_MESSAGE_SIZE) { + qCDebug(qLcQpaWaylandTextInput) << "SurroundText size is over " + << MAX_MESSAGE_SIZE + << " byte, some text will be clipped."; + const int selectionStart = qMin(cursor, anchor); + const int selectionEnd = qMax(cursor, anchor); const int selectionLength = selectionEnd - selectionStart; + const int selectionSize = QStringView{text}.sliced(selectionStart, selectionLength).toUtf8().size(); // If selection is bigger than 4000 byte, it is fixed to 4000 byte. // anchor will be moved in the 4000 byte boundary. - if (selectionLength > MAX_MESSAGE_SIZE) { + if (selectionSize > MAX_MESSAGE_SIZE) { if (anchor > cursor) { - const int length = MAX_MESSAGE_SIZE; - anchor = QWaylandInputMethodEventBuilder::trimmedIndexFromWayland(text, length, cursor); - anchor -= cursor; - text = text.mid(cursor, anchor); cursor = 0; + anchor = MAX_MESSAGE_SIZE; + text = text.sliced(selectionStart, selectionLength); } else { - const int length = -MAX_MESSAGE_SIZE; - anchor = QWaylandInputMethodEventBuilder::trimmedIndexFromWayland(text, length, cursor); - cursor -= anchor; - text = text.mid(anchor, cursor); anchor = 0; + cursor = MAX_MESSAGE_SIZE; + text = text.sliced(selectionEnd - selectionLength, selectionLength); } } else { - const int offset = (MAX_MESSAGE_SIZE - selectionLength) / 2; - - int textStart = QWaylandInputMethodEventBuilder::trimmedIndexFromWayland(text, -offset, qMin(cursor, anchor)); - int textEnd = QWaylandInputMethodEventBuilder::trimmedIndexFromWayland(text, MAX_MESSAGE_SIZE, textStart); - - anchor -= textStart; - cursor -= textStart; - text = text.mid(textStart, textEnd - textStart); + // This is not optimal in some cases. + // For examples, if the cursor position and + // the selectionEnd are close to the end of the surround text, + // the tail of the text might always be clipped. + // However all the cases of over 4000 byte are just exceptions. + int selEndSize = QStringView{text}.first(selectionEnd).toUtf8().size(); + cursor = QWaylandInputMethodEventBuilder::indexToWayland(text, cursor); + anchor = QWaylandInputMethodEventBuilder::indexToWayland(text, anchor); + if (selEndSize < MAX_MESSAGE_SIZE) { + text = QString::fromUtf8(QByteArrayView{text.toUtf8()}.first(MAX_MESSAGE_SIZE)); + } else { + const int startOffset = selEndSize - MAX_MESSAGE_SIZE; + text = QString::fromUtf8(QByteArrayView{text.toUtf8()}.sliced(startOffset, MAX_MESSAGE_SIZE)); + cursor -= startOffset; + anchor -= startOffset; + } } + } else { + cursor = QWaylandInputMethodEventBuilder::indexToWayland(text, cursor); + anchor = QWaylandInputMethodEventBuilder::indexToWayland(text, anchor); } qCDebug(qLcQpaWaylandTextInput) << "Modified surrounding_text: " << text << cursor << anchor; - const int cursorPos = QWaylandInputMethodEventBuilder::indexToWayland(text, cursor); - const int anchorPos = QWaylandInputMethodEventBuilder::indexToWayland(text, anchor); - - if (m_surroundingText != text || m_cursorPos != cursorPos || m_anchorPos != anchorPos) { + if (m_surroundingText != text || m_cursorPos != cursor || m_anchorPos != anchor) { qCDebug(qLcQpaWaylandTextInput) << "Current surrounding_text: " << m_surroundingText << m_cursorPos << m_anchorPos; - qCDebug(qLcQpaWaylandTextInput) << "New surrounding_text: " << text << cursorPos << anchorPos; + qCDebug(qLcQpaWaylandTextInput) << "New surrounding_text: " << text << cursor << anchor; - set_surrounding_text(text, cursorPos, anchorPos); + set_surrounding_text(text, cursor, anchor); // A workaround in the case of reselection // It will work when re-clicking a preedit text @@ -294,8 +315,8 @@ void QWaylandTextInputv3::updateState(Qt::InputMethodQueries queries, uint32_t f } m_surroundingText = text; - m_cursorPos = cursorPos; - m_anchorPos = anchorPos; + m_cursorPos = cursor; + m_anchorPos = anchor; m_cursor = cursor; } } diff --git a/src/client/qwaylandtextinputv3_p.h b/src/client/qwaylandtextinputv3_p.h index e8b7aa027..8e32e514d 100644 --- a/src/client/qwaylandtextinputv3_p.h +++ b/src/client/qwaylandtextinputv3_p.h @@ -17,7 +17,6 @@ #include "qwaylandtextinputinterface_p.h" #include <QtWaylandClient/private/qwayland-text-input-unstable-v3.h> -#include <qwaylandinputmethodeventbuilder_p.h> #include <QLoggingCategory> struct wl_callback; @@ -63,8 +62,6 @@ protected: void zwp_text_input_v3_done(uint32_t serial) override; private: - QWaylandInputMethodEventBuilder m_builder; - ::wl_surface *m_surface = nullptr; // ### Here for debugging purposes struct PreeditInfo { @@ -82,8 +79,8 @@ private: PreeditInfo m_pendingPreeditString; PreeditInfo m_currentPreeditString; QString m_pendingCommitString; - uint m_pendingDeleteBeforeText = 0; - uint m_pendingDeleteAfterText = 0; + uint m_pendingDeleteBeforeText = 0; // byte length + uint m_pendingDeleteAfterText = 0; // byte length QString m_surroundingText; int m_cursor; // cursor position in QString diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index 081110f83..e311b2eb4 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/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" @@ -60,8 +60,6 @@ QWaylandWindow::QWaylandWindow(QWindow *window, QWaylandDisplay *display) mFrameCallbackTimeout = frameCallbackTimeout; } - mScale = waylandScreen() ? waylandScreen()->scale() : 1; // fallback to 1 if we don't have a real screen - static WId id = 1; mWindowId = id++; initializeWlSurface(); @@ -327,6 +325,7 @@ void QWaylandWindow::reset() mWaitingToApplyConfigure = false; mCanResize = true; mResizeDirty = false; + mScale = std::nullopt; mOpaqueArea = QRegion(); mMask = QRegion(); @@ -463,7 +462,7 @@ void QWaylandWindow::setGeometry(const QRect &r) if (mShellSurface) { mShellSurface->setWindowGeometry(windowContentGeometry()); - if (!qt_window_private(window())->positionAutomatic) + if (!qt_window_private(window())->positionAutomatic && !mInResizeFromApplyConfigure) mShellSurface->setWindowPosition(windowGeometry().topLeft()); } @@ -558,7 +557,6 @@ QPlatformScreen *QWaylandWindow::calculateScreenFromSurfaceEvents() const if (auto *screen = mSurface->oldestEnteredScreen()) return screen; } - return QPlatformWindow::screen(); } @@ -891,6 +889,7 @@ QMargins QWaylandWindow::clientSideMargins() const void QWaylandWindow::setCustomMargins(const QMargins &margins) { const QMargins oldMargins = mCustomMargins; mCustomMargins = margins; + propagateSizeHints(); setGeometry(geometry().marginsRemoved(oldMargins).marginsAdded(margins)); } @@ -1185,8 +1184,13 @@ QWaylandWindow *QWaylandWindow::guessTransientParent() const if (auto transientParent = closestShellSurfaceWindow(window()->transientParent())) return transientParent; - if (QGuiApplication::focusWindow() && (window()->type() == Qt::ToolTip || window()->type() == Qt::Popup)) - return closestShellSurfaceWindow(QGuiApplication::focusWindow()); + if (window()->type() == Qt::Popup) { + if (mTopPopup) + return mTopPopup; + } + + if (window()->type() == Qt::ToolTip || window()->type() == Qt::Popup) + return display()->lastInputWindow(); return nullptr; } @@ -1433,14 +1437,11 @@ void QWaylandWindow::handleScreensChanged() { QPlatformScreen *newScreen = calculateScreenFromSurfaceEvents(); - if (newScreen == mLastReportedScreen) + if (newScreen->screen() == window()->screen()) return; - if (!newScreen->isPlaceholder() && !newScreen->QPlatformScreen::screen()) - mDisplay->forceRoundTrip(); QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen()); - mLastReportedScreen = newScreen; if (fixedToplevelPositions && !QPlatformWindow::parent() && window()->type() != Qt::Popup && window()->type() != Qt::ToolTip && geometry().topLeft() != newScreen->geometry().topLeft()) { @@ -1470,13 +1471,13 @@ void QWaylandWindow::updateScale() return; } - int scale = mLastReportedScreen->isPlaceholder() ? 1 : static_cast<QWaylandScreen *>(mLastReportedScreen)->scale(); + int scale = screen()->isPlaceholder() ? 1 : static_cast<QWaylandScreen *>(screen())->scale(); setScale(scale); } void QWaylandWindow::setScale(qreal newScale) { - if (qFuzzyCompare(mScale, newScale)) + if (mScale.has_value() && qFuzzyCompare(mScale.value(), newScale)) return; mScale = newScale; @@ -1485,7 +1486,7 @@ void QWaylandWindow::setScale(qreal newScale) if (mViewport) updateViewport(); else if (mSurface->version() >= 3) - mSurface->set_buffer_scale(std::ceil(mScale)); + mSurface->set_buffer_scale(std::ceil(newScale)); } ensureSize(); @@ -1547,7 +1548,7 @@ qreal QWaylandWindow::scale() const qreal QWaylandWindow::devicePixelRatio() const { - return qreal(mScale); + return mScale.value_or(waylandScreen() ? waylandScreen()->scale() : 1); } bool QWaylandWindow::setMouseGrabEnabled(bool grab) diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h index b78c8ce4e..c1b736c1e 100644 --- a/src/client/qwaylandwindow_p.h +++ b/src/client/qwaylandwindow_p.h @@ -310,8 +310,7 @@ protected: bool mSentInitialResize = false; QPoint mOffset; - qreal mScale = 1; - QPlatformScreen *mLastReportedScreen = nullptr; + std::optional<qreal> mScale = std::nullopt; QString mWindowTitle; QIcon mWindowIcon; diff --git a/src/client/qwaylandwindowmanagerintegration.cpp b/src/client/qwaylandwindowmanagerintegration.cpp index 149190420..9668491d2 100644 --- a/src/client/qwaylandwindowmanagerintegration.cpp +++ b/src/client/qwaylandwindowmanagerintegration.cpp @@ -22,49 +22,25 @@ QT_BEGIN_NAMESPACE namespace QtWaylandClient { -class QWaylandWindowManagerIntegrationPrivate { -public: - QWaylandWindowManagerIntegrationPrivate(QWaylandDisplay *waylandDisplay); - bool m_blockPropertyUpdates = false; - QWaylandDisplay *m_waylandDisplay = nullptr; - QHash<QWindow*, QVariantMap> m_queuedProperties; - bool m_showIsFullScreen = false; -}; - -QWaylandWindowManagerIntegrationPrivate::QWaylandWindowManagerIntegrationPrivate(QWaylandDisplay *waylandDisplay) - : m_waylandDisplay(waylandDisplay) -{ -} - -QWaylandWindowManagerIntegration::QWaylandWindowManagerIntegration(QWaylandDisplay *waylandDisplay) - : d_ptr(new QWaylandWindowManagerIntegrationPrivate(waylandDisplay)) +QWaylandWindowManagerIntegration::QWaylandWindowManagerIntegration(QWaylandDisplay *waylandDisplay, + uint id, uint version) + : QtWayland::qt_windowmanager(waylandDisplay->object(), id, version) { - 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<QWaylandWindowManagerIntegration *>(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 +48,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 +62,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<QWaylandWindow *>(window->handle())->shellSurface(); - if (shellSurface) { - const QString handle = shellSurface->externWindowHandle(); - return QLatin1String("wayland:") + handle; - } - } - return QString(); -} } QT_END_NAMESPACE diff --git a/src/client/qwaylandwindowmanagerintegration_p.h b/src/client/qwaylandwindowmanagerintegration_p.h index 18eb171b6..be06d68ee 100644 --- a/src/client/qwaylandwindowmanagerintegration_p.h +++ b/src/client/qwaylandwindowmanagerintegration_p.h @@ -16,9 +16,6 @@ // #include <QtCore/QObject> -#include <QtCore/QScopedPointer> - -#include <QtGui/private/qgenericunixservices_p.h> #include <QtWaylandClient/private/qwayland-qt-windowmanager.h> #include <QtWaylandClient/qtwaylandclientglobal.h> @@ -27,35 +24,27 @@ 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; + explicit QWaylandWindowManagerIntegration(QWaylandDisplay *waylandDisplay, uint id, + uint version); + ~QWaylandWindowManagerIntegration(); - bool openUrl(const QUrl &url) override; - bool openDocument(const QUrl &url) override; - QString portalWindowIdentifier(QWindow *window) override; + 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<QWaylandWindowManagerIntegrationPrivate> d_ptr; - void windowmanager_hints(int32_t showIsFullScreen) override; void windowmanager_quit() override; - void openUrl_helper(const QUrl &url); + bool m_showIsFullScreen = false; }; QT_END_NAMESPACE diff --git a/src/compositor/CMakeLists.txt b/src/compositor/CMakeLists.txt index 856fd07f9..fc742c7a1 100644 --- a/src/compositor/CMakeLists.txt +++ b/src/compositor/CMakeLists.txt @@ -63,7 +63,6 @@ qt_internal_add_module(WaylandCompositor extensions global wayland_wrapper - GENERATE_CPP_EXPORTS LIBRARIES Qt::CorePrivate Qt::GuiPrivate @@ -80,6 +79,12 @@ qt_internal_add_module(WaylandCompositor "^qwayland-.*\.h|^wayland-.*-protocol\.h" ) +# all those macros define structs with Q_OBJECT macros, and should be picked up by moc +set_target_properties(WaylandCompositor WaylandCompositorPrivate + PROPERTIES + INTERFACE_AUTOMOC_MACRO_NAMES "Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_ELEMENT;Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_CLASS;Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS;Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CONTAINER_CLASS" +) + set(compositor_no_pch_sources compat/removed_api.cpp ) diff --git a/src/compositor/compositor_api/qwaylandcompositorquickextensions_p.h b/src/compositor/compositor_api/qwaylandcompositorquickextensions_p.h index 3150f90ae..7e59a5d6e 100644 --- a/src/compositor/compositor_api/qwaylandcompositorquickextensions_p.h +++ b/src/compositor/compositor_api/qwaylandcompositorquickextensions_p.h @@ -80,11 +80,14 @@ private: // Note: These have to be in a header with a Q_OBJECT macro, otherwise we won't run moc on it -Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_CLASS(QWaylandQtWindowManager, QtWindowManager) -Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_CLASS(QWaylandIdleInhibitManagerV1, IdleInhibitManagerV1) -Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_CLASS(QWaylandTextInputManager, TextInputManager) -Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_CLASS(QWaylandTextInputManagerV3, TextInputManagerV3) -Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_CLASS(QWaylandQtTextInputMethodManager, QtTextInputMethodManager) +Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_ELEMENT(QWaylandQtWindowManager, QtWindowManager, 1, 0) +Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_ELEMENT(QWaylandIdleInhibitManagerV1, + IdleInhibitManagerV1, 1, 0) +Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_ELEMENT(QWaylandTextInputManager, TextInputManager, 1, 0) +Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_ELEMENT(QWaylandTextInputManagerV3, TextInputManagerV3, + 1, 0) +Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_ELEMENT(QWaylandQtTextInputMethodManager, + QtTextInputMethodManager, 1, 0) QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandshellsurface.h b/src/compositor/extensions/qwaylandshellsurface.h index 67ee5b8f8..96ef772ca 100644 --- a/src/compositor/extensions/qwaylandshellsurface.h +++ b/src/compositor/extensions/qwaylandshellsurface.h @@ -39,7 +39,7 @@ protected: Q_SIGNALS: void windowTypeChanged(); - void modalChanged(); + Q_REVISION(6, 8) void modalChanged(); }; template <typename T> diff --git a/src/compositor/extensions/qwaylandtextinputmanagerv3.cpp b/src/compositor/extensions/qwaylandtextinputmanagerv3.cpp index 5dbc78459..e9ad25bff 100644 --- a/src/compositor/extensions/qwaylandtextinputmanagerv3.cpp +++ b/src/compositor/extensions/qwaylandtextinputmanagerv3.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2021 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 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "qwaylandtextinputmanagerv3.h" #include "qwaylandtextinputmanagerv3_p.h" diff --git a/src/compositor/extensions/qwaylandtextinputmanagerv3.h b/src/compositor/extensions/qwaylandtextinputmanagerv3.h index 1f3051446..a71fdcbaa 100644 --- a/src/compositor/extensions/qwaylandtextinputmanagerv3.h +++ b/src/compositor/extensions/qwaylandtextinputmanagerv3.h @@ -1,5 +1,5 @@ // Copyright (C) 2021 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 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef QWAYLANDTEXTINPUTMANAGERV3_H #define QWAYLANDTEXTINPUTMANAGERV3_H diff --git a/src/compositor/extensions/qwaylandtextinputmanagerv3_p.h b/src/compositor/extensions/qwaylandtextinputmanagerv3_p.h index c35b19b90..5559a4418 100644 --- a/src/compositor/extensions/qwaylandtextinputmanagerv3_p.h +++ b/src/compositor/extensions/qwaylandtextinputmanagerv3_p.h @@ -1,5 +1,5 @@ // Copyright (C) 2021 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 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef QWAYLANDTEXTINPUTMANAGERV3_P_H #define QWAYLANDTEXTINPUTMANAGERV3_P_H diff --git a/src/compositor/extensions/qwaylandtextinputv3.cpp b/src/compositor/extensions/qwaylandtextinputv3.cpp index 3da89e630..7a0abd5dd 100644 --- a/src/compositor/extensions/qwaylandtextinputv3.cpp +++ b/src/compositor/extensions/qwaylandtextinputv3.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2021 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 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "qwaylandtextinputv3.h" #include "qwaylandtextinputv3_p.h" @@ -99,20 +99,40 @@ void QWaylandTextInputV3Private::sendInputMethodEvent(QInputMethodEvent *event) // Current cursor shape is only line. It means both cursorBegin // and cursorEnd will be the same values. - int32_t preeditCursorPos = newPreeditString.length(); - - if (event->replacementLength() > 0 || event->replacementStart() < 0) { - if (event->replacementStart() <= 0 && (event->replacementLength() >= -event->replacementStart())) { - const int selectionStart = qMin(currentState->cursorPosition, currentState->anchorPosition); - const int selectionEnd = qMax(currentState->cursorPosition, currentState->anchorPosition); - const int before = QWaylandInputMethodEventBuilder::indexToWayland(currentState->surroundingText, -event->replacementStart(), selectionStart + event->replacementStart()); - const int after = QWaylandInputMethodEventBuilder::indexToWayland(currentState->surroundingText, event->replacementLength() + event->replacementStart(), selectionEnd); - send_delete_surrounding_text(focusResource->handle, before, after); - needsDone = true; - } else { - qCWarning(qLcWaylandCompositorTextInput) << "Not yet supported case of replacement. Start:" << event->replacementStart() << "length:" << event->replacementLength(); + int32_t preeditCursorPos = newPreeditString.toUtf8().size(); + + if (event->replacementLength() > 0) { + int replacementStart = event->replacementStart(); + int replacementLength = event->replacementLength(); + const int cursorPos = currentState->cursorPosition; + if (currentState->cursorPosition < -event->replacementStart()) { + qCWarning(qLcWaylandCompositorTextInput) + << Q_FUNC_INFO + << "Invalid replacementStart :" << replacementStart + << "on the cursorPosition :" << cursorPos; + replacementStart = -cursorPos; } - preeditCursorPos = event->replacementStart() + event->replacementLength(); + auto targetText = QStringView{currentState->surroundingText}.sliced(cursorPos + replacementStart); + if (targetText.length() < replacementLength) { + qCWarning(qLcWaylandCompositorTextInput) + << Q_FUNC_INFO + << "Invalid replacementLength :" << replacementLength + << "for the surrounding text :" << targetText; + replacementLength = targetText.length(); + } + const int before = targetText.first(-replacementStart).toUtf8().size(); + const int after = targetText.first(replacementLength).toUtf8().size() - before; + + send_delete_surrounding_text(focusResource->handle, before, after); + needsDone = true; + + // The commit will also be applied here + currentState->surroundingText.replace(cursorPos + replacementStart, + replacementLength, + event->commitString()); + currentState->cursorPosition = cursorPos + replacementStart + event->commitString().length(); + currentState->anchorPosition = cursorPos + replacementStart + event->commitString().length(); + qApp->inputMethod()->update(Qt::ImSurroundingText | Qt::ImCursorPosition | Qt::ImAnchorPosition); } if (currentPreeditString != newPreeditString) { diff --git a/src/compositor/extensions/qwaylandtextinputv3.h b/src/compositor/extensions/qwaylandtextinputv3.h index 1305bddfb..869238631 100644 --- a/src/compositor/extensions/qwaylandtextinputv3.h +++ b/src/compositor/extensions/qwaylandtextinputv3.h @@ -1,5 +1,5 @@ // Copyright (C) 2021 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 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef QWAYLANDTEXTINPUTV3_H #define QWAYLANDTEXTINPUTV3_H diff --git a/src/compositor/extensions/qwaylandtextinputv3_p.h b/src/compositor/extensions/qwaylandtextinputv3_p.h index ed43b88c6..267d14125 100644 --- a/src/compositor/extensions/qwaylandtextinputv3_p.h +++ b/src/compositor/extensions/qwaylandtextinputv3_p.h @@ -1,5 +1,5 @@ // Copyright (C) 2021 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 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef QWAYLANDTEXTINPUTV3_P_H #define QWAYLANDTEXTINPUTV3_P_H diff --git a/src/compositor/extensions/qwaylandxdgshell.h b/src/compositor/extensions/qwaylandxdgshell.h index 82442e841..4c5a2fef7 100644 --- a/src/compositor/extensions/qwaylandxdgshell.h +++ b/src/compositor/extensions/qwaylandxdgshell.h @@ -1,3 +1,4 @@ + // Copyright (C) 2018 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only @@ -197,7 +198,7 @@ Q_SIGNALS: void decorationModeChanged(); - void modalChanged(); + Q_REVISION(6, 8) void modalChanged(); private: QList<int> statesAsInts() const; diff --git a/src/compositor/global/qwaylandquickextension.h b/src/compositor/global/qwaylandquickextension.h index 2338b0d6e..5286f120a 100644 --- a/src/compositor/global/qwaylandquickextension.h +++ b/src/compositor/global/qwaylandquickextension.h @@ -78,24 +78,63 @@ QT_BEGIN_NAMESPACE }; #define Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_CLASS(className, QmlType) \ - class Q_WAYLANDCOMPOSITOR_EXPORT className##QuickExtension : public className, public QQmlParserStatus \ - { \ -/* qmake ignore Q_OBJECT */ \ - Q_OBJECT \ - Q_PROPERTY(QQmlListProperty<QObject> data READ data DESIGNABLE false) \ - Q_CLASSINFO("DefaultProperty", "data") \ - Q_INTERFACES(QQmlParserStatus) \ - QML_NAMED_ELEMENT(QmlType) \ - QML_ADDED_IN_VERSION(1, 0) \ - public: \ - QQmlListProperty<QObject> data() \ - { \ - return QQmlListProperty<QObject>(this, &m_objects); \ - } \ - void classBegin() override {} \ - void componentComplete() override { if (!isInitialized()) initialize(); } \ - private: \ - QList<QObject *> m_objects; \ + Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_ELEMENT(className, QmlType, 1, 0) + +#define Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_ELEMENT(...) \ + QT_OVERLOADED_MACRO(Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_ELEMENT, __VA_ARGS__) + +#define Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_ELEMENT_4(className, QmlType, versionMajor, \ + versionMinor) \ + class Q_WAYLANDCOMPOSITOR_EXPORT className##QuickExtension : public className, \ + public QQmlParserStatus \ + { \ + /* qmake ignore Q_OBJECT */ \ + Q_OBJECT \ + Q_PROPERTY(QQmlListProperty<QObject> data READ data DESIGNABLE false) \ + Q_CLASSINFO("DefaultProperty", "data") \ + Q_INTERFACES(QQmlParserStatus) \ + QML_NAMED_ELEMENT(QmlType) \ + QML_ADDED_IN_VERSION(versionMajor, versionMinor) \ + public: \ + QQmlListProperty<QObject> data() \ + { \ + return QQmlListProperty<QObject>(this, &m_objects); \ + } \ + void classBegin() override { } \ + void componentComplete() override \ + { \ + if (!isInitialized()) \ + initialize(); \ + } \ + \ + private: \ + QList<QObject *> m_objects; \ + }; + +#define Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_ELEMENT_2(className, QmlType) \ + class Q_WAYLANDCOMPOSITOR_EXPORT className##QuickExtension : public className, \ + public QQmlParserStatus \ + { \ + /* qmake ignore Q_OBJECT */ \ + Q_OBJECT \ + Q_PROPERTY(QQmlListProperty<QObject> data READ data DESIGNABLE false) \ + Q_CLASSINFO("DefaultProperty", "data") \ + Q_INTERFACES(QQmlParserStatus) \ + QML_NAMED_ELEMENT(QmlType) \ + public: \ + QQmlListProperty<QObject> data() \ + { \ + return QQmlListProperty<QObject>(this, &m_objects); \ + } \ + void classBegin() override { } \ + void componentComplete() override \ + { \ + if (!isInitialized()) \ + initialize(); \ + } \ + \ + private: \ + QList<QObject *> m_objects; \ }; QT_END_NAMESPACE diff --git a/src/compositor/global/qwaylandquickextension.qdoc b/src/compositor/global/qwaylandquickextension.qdoc index 5977e56c9..f3a213a11 100644 --- a/src/compositor/global/qwaylandquickextension.qdoc +++ b/src/compositor/global/qwaylandquickextension.qdoc @@ -27,7 +27,7 @@ * \l{QWaylandCompositorExtension::initialize()} will be called automatically. The type must be * manually registered in Qt Quick using \l{qmlRegisterType()}. * - * \sa Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_CLASS + * \sa Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_ELEMENT */ /*! @@ -48,10 +48,38 @@ /*! * \macro Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_CLASS(className, QmlType) * \relates <QWaylandQuickExtension> + * \deprecated [6.8] Use Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_ELEMENT instead. * * This macro can be used to define a Qt Quick class based on a Wayland extension. It defines * a new class which inherits from \a className and which suffixes the name with "QuickExtension". * * The macro works the same as \l{Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS}, but will also - * automatically register the new type as \a QmlType in Qt Quick. + * automatically register the new type as \a QmlType in the current QML module with \l + * QML_ADDED_IN_VERSION set to 1.0. + */ + +/*! +\macro Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_ELEMENT(className, QmlType) +\relates <QWaylandQuickExtension> +\since 6.8 + +This macro can be used to define a Qt Quick class based on a Wayland extension. It defines +a new class which inherits from \a className and which suffixes the name with "QuickExtension". + +The macro works the same as \l{Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS}, but will also +automatically register the new type as \a QmlType in the current QML module. +*/ + +/*! +\macro Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_ELEMENT(className, QmlType, versionMajor, versionMinor) +\relates <QWaylandQuickExtension> +\internal +\since 6.8 + +This macro can be used to define a Qt Quick class based on a Wayland extension. It defines +a new class which inherits from \a className and which suffixes the name with "QuickExtension". + +The macro works the same as \l{Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS}, but will also +automatically register the new type as \a QmlType in the current QML module with +\l QML_ADDED_IN_VERSION set to the version passed via \a versionMajor and \a versionMinor. */ diff --git a/src/compositor/wayland_wrapper/qwldatadevice.cpp b/src/compositor/wayland_wrapper/qwldatadevice.cpp index 2604bc068..440401d05 100644 --- a/src/compositor/wayland_wrapper/qwldatadevice.cpp +++ b/src/compositor/wayland_wrapper/qwldatadevice.cpp @@ -50,6 +50,9 @@ void DataDevice::sourceDestroyed(DataSource *source) { if (m_selectionSource == source) m_selectionSource = nullptr; + + if (m_dragDataSource == source) + m_dragDataSource = nullptr; } #if QT_CONFIG(draganddrop) @@ -79,9 +82,11 @@ void DataDevice::setDragFocus(QWaylandSurface *focus, const QPointF &localPositi if (m_dragDataSource && !offer) return; - send_enter(resource->handle, serial, focus->resource(), - wl_fixed_from_double(localPosition.x()), wl_fixed_from_double(localPosition.y()), - offer->resource()->handle); + if (offer) { + send_enter(resource->handle, serial, focus->resource(), + wl_fixed_from_double(localPosition.x()), wl_fixed_from_double(localPosition.y()), + offer->resource()->handle); + } m_dragFocus = focus; m_dragFocusResource = resource; @@ -113,7 +118,7 @@ void DataDevice::drop() if (m_dragFocusResource) { send_drop(m_dragFocusResource->handle); setDragFocus(nullptr, QPoint()); - } else { + } else if (m_dragDataSource) { m_dragDataSource->cancel(); } m_dragOrigin = nullptr; @@ -129,6 +134,8 @@ void DataDevice::data_device_start_drag(Resource *resource, struct ::wl_resource { m_dragClient = resource->client(); m_dragDataSource = source ? DataSource::fromResource(source) : nullptr; + if (m_dragDataSource) + m_dragDataSource->setDevice(this); m_dragOrigin = QWaylandSurface::fromResource(origin); QWaylandDrag *drag = m_seat->drag(); setDragIcon(icon ? QWaylandSurface::fromResource(icon) : nullptr); diff --git a/src/extensions/surface-extension.xml b/src/extensions/surface-extension.xml deleted file mode 100644 index 231db0b35..000000000 --- a/src/extensions/surface-extension.xml +++ /dev/null @@ -1,62 +0,0 @@ -<protocol name="surface_extension"> - - <copyright> - Copyright (C) 2015 The Qt Company Ltd. - SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause - </copyright> - - <interface name="qt_surface_extension" version="1"> - <request name="get_extended_surface"> - <arg name="id" type="new_id" interface="qt_extended_surface"/> - <arg name="surface" type="object" interface="wl_surface"/> - </request> - </interface> - - <interface name="qt_extended_surface" version="1"> - <event name="onscreen_visibility"> - <arg name="visible" type="int"/> - </event> - - <event name="set_generic_property"> - <arg name="name" type="string"/> - <arg name="value" type="array"/> - </event> - - <event name="close"> - </event> - - <request name="update_generic_property"> - <arg name="name" type="string"/> - <arg name="value" type="array"/> - </request> - - <enum name="orientation"> - <entry name="PrimaryOrientation" value="0"/> - <entry name="PortraitOrientation" value="1"/> - <entry name="LandscapeOrientation" value="2"/> - <entry name="InvertedPortraitOrientation" value="4"/> - <entry name="InvertedLandscapeOrientation" value="8"/> - </enum> - - <request name="set_content_orientation_mask"> - <arg name="orientation" type="int"/> - </request> - - <enum name="windowflag"> - <entry name="OverridesSystemGestures" value="1"/> - <entry name="StaysOnTop" value="2"/> - <entry name="BypassWindowManager" value="4"/> - </enum> - - <request name="set_window_flags"> - <arg name="flags" type="int"/> - </request> - - <request name="raise"> - </request> - - <request name="lower"> - </request> - - </interface> -</protocol> diff --git a/src/imports/compositor-extensions/iviapplication/CMakeLists.txt b/src/imports/compositor-extensions/iviapplication/CMakeLists.txt index eaf0f8770..a2899fa27 100644 --- a/src/imports/compositor-extensions/iviapplication/CMakeLists.txt +++ b/src/imports/compositor-extensions/iviapplication/CMakeLists.txt @@ -10,19 +10,14 @@ qt_internal_add_qml_module(WaylandCompositorIviapplication URI "QtWayland.Compositor.IviApplication" VERSION "${PROJECT_VERSION}" - CLASS_NAME QWaylandCompositorIviApplicationPlugin - PLUGIN_TARGET WaylandCompositorIviapplication - NO_PLUGIN_OPTIONAL - NO_GENERATE_PLUGIN_SOURCE - NO_GENERATE_QMLTYPES - INSTALL_SOURCE_QMLTYPES "plugins.qmltypes" SOURCES - qwaylandcompositoriviapplicationplugin.cpp + qwaylandcompositoriviapplicationforeign.cpp qwaylandcompositoriviapplicationforeign_p.h LIBRARIES Qt::Core Qt::Gui Qt::WaylandCompositor NO_GENERATE_CPP_EXPORTS + PAST_MAJOR_VERSIONS 1 ) qt_internal_add_autogen_sync_header_dependencies(WaylandCompositorIviapplication WaylandCompositor) diff --git a/src/imports/compositor-extensions/iviapplication/plugins.qmltypes b/src/imports/compositor-extensions/iviapplication/plugins.qmltypes deleted file mode 100644 index 4427fe42a..000000000 --- a/src/imports/compositor-extensions/iviapplication/plugins.qmltypes +++ /dev/null @@ -1,61 +0,0 @@ -import QtQuick.tooling 1.2 - -// This file describes the plugin-supplied types contained in the library. -// It is used for QML tooling purposes only. -// -// This file was auto-generated by: -// 'qmlplugindump -nonrelocatable QtWayland.Compositor.IviApplication 6.0' - -Module { - dependencies: ["QtQuick 2.0"] - Component { name: "QWaylandCompositorExtension"; prototype: "QWaylandObject" } - Component { - name: "QWaylandIviApplication" - prototype: "QWaylandCompositorExtension" - Signal { - name: "iviSurfaceRequested" - Parameter { name: "surface"; type: "QWaylandSurface"; isPointer: true } - Parameter { name: "iviId"; type: "uint" } - Parameter { name: "resource"; type: "QWaylandResource" } - } - Signal { - name: "iviSurfaceCreated" - Parameter { name: "iviSurface"; type: "QWaylandIviSurface"; isPointer: true } - } - } - Component { - name: "QWaylandIviApplicationQuickExtension" - defaultProperty: "data" - prototype: "QWaylandIviApplication" - exports: ["QtWayland.Compositor.IviApplication/IviApplication 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } - } - Component { - name: "QWaylandIviSurface" - defaultProperty: "data" - prototype: "QWaylandShellSurface" - exports: ["QtWayland.Compositor.IviApplication/IviSurface 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } - Property { name: "surface"; type: "QWaylandSurface"; isReadonly: true; isPointer: true } - Property { name: "iviId"; type: "uint"; isReadonly: true } - Method { - name: "initialize" - Parameter { name: "iviApplication"; type: "QWaylandIviApplication"; isPointer: true } - Parameter { name: "surface"; type: "QWaylandSurface"; isPointer: true } - Parameter { name: "iviId"; type: "uint" } - Parameter { name: "resource"; type: "QWaylandResource" } - } - Method { - name: "sendConfigure" - Parameter { name: "size"; type: "QSize" } - } - } - Component { name: "QWaylandObject"; prototype: "QObject" } - Component { - name: "QWaylandShellSurface" - prototype: "QWaylandCompositorExtension" - Property { name: "windowType"; type: "Qt::WindowType"; isReadonly: true } - } -} diff --git a/src/imports/compositor-extensions/iviapplication/qwaylandcompositoriviapplicationforeign.cpp b/src/imports/compositor-extensions/iviapplication/qwaylandcompositoriviapplicationforeign.cpp new file mode 100644 index 000000000..66a38fbf4 --- /dev/null +++ b/src/imports/compositor-extensions/iviapplication/qwaylandcompositoriviapplicationforeign.cpp @@ -0,0 +1,29 @@ +// Copyright (C) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "qwaylandcompositoriviapplicationforeign_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmlmodule QtWayland.Compositor.IviApplication + \title Qt Wayland IviApplication Extension + \ingroup qmlmodules + \brief Provides a Qt API for the IviApplication shell extension. + + \section2 Summary + IviApplication is a shell extension suitable for lightweight compositors, + for example in In-Vehicle Infotainment (IVI) systems. + + IviApplication corresponds to the Wayland \c ivi_application interface. + + \section2 Usage + To use this module, import it like this: + \qml + import QtWayland.Compositor.IviApplication + \endqml +*/ + +QT_END_NAMESPACE + +#include "moc_qwaylandcompositoriviapplicationforeign_p.cpp" diff --git a/src/imports/compositor-extensions/iviapplication/qwaylandcompositoriviapplicationforeign_p.h b/src/imports/compositor-extensions/iviapplication/qwaylandcompositoriviapplicationforeign_p.h new file mode 100644 index 000000000..89d5e7eba --- /dev/null +++ b/src/imports/compositor-extensions/iviapplication/qwaylandcompositoriviapplicationforeign_p.h @@ -0,0 +1,39 @@ +// Copyright (C) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef QWAYLANDCOMPOSITORIVIAPPLICATIONFOREIGN_H +#define QWAYLANDCOMPOSITORIVIAPPLICATIONFOREIGN_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 <QtQml/qqmlextensionplugin.h> +#include <QtQml/qqml.h> + +#include <QtWaylandCompositor/qwaylandquickextension.h> +#include <QtWaylandCompositor/qwaylandiviapplication.h> +#include <QtWaylandCompositor/qwaylandivisurface.h> + +QT_BEGIN_NAMESPACE + +Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_ELEMENT(QWaylandIviApplication, IviApplication, 1, 0) + +struct QWaylandIviSurfaceForeign { + Q_GADGET + QML_FOREIGN(QWaylandIviSurface) + QML_NAMED_ELEMENT(IviSurface) + QML_ADDED_IN_VERSION(1, 0) +}; + + +QT_END_NAMESPACE + +#endif diff --git a/src/imports/compositor-extensions/iviapplication/qwaylandcompositoriviapplicationplugin.cpp b/src/imports/compositor-extensions/iviapplication/qwaylandcompositoriviapplicationplugin.cpp deleted file mode 100644 index 0c53fb332..000000000 --- a/src/imports/compositor-extensions/iviapplication/qwaylandcompositoriviapplicationplugin.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2020 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only - -#include <QtQml/qqmlextensionplugin.h> -#include <QtQml/qqml.h> - -#include <QtWaylandCompositor/qwaylandquickextension.h> -#include <QtWaylandCompositor/qwaylandiviapplication.h> -#include <QtWaylandCompositor/qwaylandivisurface.h> - -QT_BEGIN_NAMESPACE - -Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandIviApplication) - -/*! - \qmlmodule QtWayland.Compositor.IviApplication - \title Qt Wayland IviApplication Extension - \ingroup qmlmodules - \brief Provides a Qt API for the IviApplication shell extension. - - \section2 Summary - IviApplication is a shell extension suitable for lightweight compositors, - for example in In-Vehicle Infotainment (IVI) systems. - - IviApplication corresponds to the Wayland \c ivi_application interface. - - \section2 Usage - To use this module, import it like this: - \qml - import QtWayland.Compositor.IviApplication - \endqml -*/ - -class QWaylandCompositorIviApplicationPlugin : public QQmlExtensionPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) -public: - void registerTypes(const char *uri) override - { - Q_ASSERT(QLatin1String(uri) == QLatin1String("QtWayland.Compositor.IviApplication")); - defineModule(uri); - } - - static void defineModule(const char *uri) - { - qmlRegisterModule(uri, QT_VERSION_MAJOR, QT_VERSION_MINOR); - qmlRegisterType<QWaylandIviApplicationQuickExtension>(uri, 1, 0, "IviApplication"); - qmlRegisterType<QWaylandIviSurface>(uri, 1, 0, "IviSurface"); - } -}; - -QT_END_NAMESPACE - -#include "qwaylandcompositoriviapplicationplugin.moc" diff --git a/src/imports/compositor-extensions/presentationtime/CMakeLists.txt b/src/imports/compositor-extensions/presentationtime/CMakeLists.txt index f1413dfc1..2a817c012 100644 --- a/src/imports/compositor-extensions/presentationtime/CMakeLists.txt +++ b/src/imports/compositor-extensions/presentationtime/CMakeLists.txt @@ -5,21 +5,24 @@ ## qwaylandcompositorpresentationtimeplugin Plugin: ##################################################################### +# Note: INTERFACE_AUTOMOC_MACRO_NAMES is a CMake 3.27 feature, so readd it here for older CMake versions. +list(APPEND CMAKE_AUTOMOC_MACRO_NAMES + "Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_ELEMENT" + "Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_CLASS" + "Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS" + "Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CONTAINER_CLASS") + qt_internal_add_qml_module(WaylandCompositorPresentationTime URI "QtWayland.Compositor.PresentationTime" VERSION "${PROJECT_VERSION}" - CLASS_NAME QWaylandCompositorPresentationTimePlugin - PLUGIN_TARGET WaylandCompositorPresentationTime - NO_PLUGIN_OPTIONAL - NO_GENERATE_PLUGIN_SOURCE - NO_GENERATE_QMLTYPES SOURCES - qwaylandcompositorpresentationtimeplugin.cpp + qwaylandcompositorpresentationtimeforeign.cpp qwaylandcompositorpresentationtimeforeign_p.h LIBRARIES Qt::Core Qt::Gui Qt::WaylandCompositorPrivate NO_GENERATE_CPP_EXPORTS + PAST_MAJOR_VERSIONS 1 ) qt_internal_add_autogen_sync_header_dependencies(WaylandCompositorPresentationTime diff --git a/src/imports/compositor-extensions/presentationtime/qwaylandcompositorpresentationtimeplugin.cpp b/src/imports/compositor-extensions/presentationtime/qwaylandcompositorpresentationtimeforeign.cpp index ad835af91..05807e74f 100644 --- a/src/imports/compositor-extensions/presentationtime/qwaylandcompositorpresentationtimeplugin.cpp +++ b/src/imports/compositor-extensions/presentationtime/qwaylandcompositorpresentationtimeforeign.cpp @@ -1,16 +1,10 @@ // Copyright (C) 2021 LG Electronics Inc. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only -#include <QtQml/qqmlextensionplugin.h> -#include <QtQml/qqml.h> - -#include <QtWaylandCompositor/qwaylandquickextension.h> -#include <QtWaylandCompositor/private/qwaylandpresentationtime_p.h> +#include "qwaylandcompositorpresentationtimeforeign_p.h" QT_BEGIN_NAMESPACE -Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandPresentationTime) - /*! \qmlmodule QtWayland.Compositor.PresentationTime \title Qt Wayland Presentation Time Extension @@ -33,23 +27,6 @@ Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandPresentationTime) \endqml */ -class QWaylandCompositorPresentationTimePlugin : public QQmlExtensionPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) -public: - void registerTypes(const char *uri) override - { - Q_ASSERT(QLatin1String(uri) == QLatin1String("QtWayland.Compositor.PresentationTime")); - defineModule(uri); - } - - static void defineModule(const char *uri) - { - qmlRegisterModule(uri, QT_VERSION_MAJOR, QT_VERSION_MINOR); - qmlRegisterType<QWaylandPresentationTime>(uri, 1, 0, "PresentationTime"); - } -}; QT_END_NAMESPACE -#include "qwaylandcompositorpresentationtimeplugin.moc" +#include "moc_qwaylandcompositorpresentationtimeforeign_p.cpp" diff --git a/src/imports/compositor-extensions/presentationtime/qwaylandcompositorpresentationtimeforeign_p.h b/src/imports/compositor-extensions/presentationtime/qwaylandcompositorpresentationtimeforeign_p.h new file mode 100644 index 000000000..63827320e --- /dev/null +++ b/src/imports/compositor-extensions/presentationtime/qwaylandcompositorpresentationtimeforeign_p.h @@ -0,0 +1,30 @@ +// Copyright (C) 2021 LG Electronics Inc. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef QWAYLANDCOMPOSITORPRESENTATIONTIMEFOREIGN_H +#define QWAYLANDCOMPOSITORPRESENTATIONTIMEFOREIGN_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 <QtQml/qqmlextensionplugin.h> +#include <QtQml/qqml.h> + +#include <QtWaylandCompositor/qwaylandquickextension.h> +#include <QtWaylandCompositor/private/qwaylandpresentationtime_p.h> + +QT_BEGIN_NAMESPACE + +Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_ELEMENT(QWaylandPresentationTime, PresentationTime, 1, 0) + +QT_END_NAMESPACE + +#endif diff --git a/src/imports/compositor-extensions/qtshell/CMakeLists.txt b/src/imports/compositor-extensions/qtshell/CMakeLists.txt index 7bb165bf3..429d0c26b 100644 --- a/src/imports/compositor-extensions/qtshell/CMakeLists.txt +++ b/src/imports/compositor-extensions/qtshell/CMakeLists.txt @@ -8,18 +8,13 @@ qt_internal_add_qml_module(WaylandCompositorQtShell URI "QtWayland.Compositor.QtShell" VERSION "${PROJECT_VERSION}" - CLASS_NAME QWaylandQtShellPlugin - NO_PLUGIN_OPTIONAL PLUGIN_TARGET WaylandCompositorQtShell - NO_GENERATE_PLUGIN_SOURCE - NO_GENERATE_QMLTYPES - INSTALL_SOURCE_QMLTYPES "plugins.qmltypes" - SOURCES - qwaylandqtshellplugin.cpp qwaylandqtshell.cpp qwaylandqtshell.h qwaylandqtshell_p.h qwaylandqtshellintegration.cpp qwaylandqtshellintegration_p.h qwaylandqtshellchrome.cpp qwaylandqtshellchrome.h qwaylandqtshellchrome_p.h + DEPENDENCIES + QtQuick LIBRARIES Qt::Core Qt::Gui @@ -27,7 +22,7 @@ qt_internal_add_qml_module(WaylandCompositorQtShell Qt::QuickPrivate Qt::WaylandCompositor Qt::WaylandCompositorPrivate - NO_GENERATE_CPP_EXPORTS + PAST_MAJOR_VERSIONS 1 ) qt6_generate_wayland_protocol_server_sources(WaylandCompositorQtShell diff --git a/src/imports/compositor-extensions/qtshell/plugins.qmltypes b/src/imports/compositor-extensions/qtshell/plugins.qmltypes deleted file mode 100644 index 3c09260f9..000000000 --- a/src/imports/compositor-extensions/qtshell/plugins.qmltypes +++ /dev/null @@ -1,442 +0,0 @@ -import QtQuick.tooling 1.2 - -// This file describes the plugin-supplied types contained in the library. -// It is used for QML tooling purposes only. -// -// This file was auto-generated by: -// 'qmlplugindump -nonrelocatable QtWayland.Compositor.QtShell 6.2' -// -// qmlplugindump is deprecated! You should use qmltyperegistrar instead. - -Module { - Component { - name: "QQuickAnchors" - prototype: "QObject" - Enum { - name: "Anchors" - values: { - "InvalidAnchor": 0, - "LeftAnchor": 1, - "RightAnchor": 2, - "TopAnchor": 4, - "BottomAnchor": 8, - "HCenterAnchor": 16, - "VCenterAnchor": 32, - "BaselineAnchor": 64, - "Horizontal_Mask": 19, - "Vertical_Mask": 108 - } - } - Property { name: "left"; type: "QQuickAnchorLine" } - Property { name: "right"; type: "QQuickAnchorLine" } - Property { name: "horizontalCenter"; type: "QQuickAnchorLine" } - Property { name: "top"; type: "QQuickAnchorLine" } - Property { name: "bottom"; type: "QQuickAnchorLine" } - Property { name: "verticalCenter"; type: "QQuickAnchorLine" } - Property { name: "baseline"; type: "QQuickAnchorLine" } - Property { name: "margins"; type: "double" } - Property { name: "leftMargin"; type: "double" } - Property { name: "rightMargin"; type: "double" } - Property { name: "horizontalCenterOffset"; type: "double" } - Property { name: "topMargin"; type: "double" } - Property { name: "bottomMargin"; type: "double" } - Property { name: "verticalCenterOffset"; type: "double" } - Property { name: "baselineOffset"; type: "double" } - Property { name: "fill"; type: "QQuickItem"; isPointer: true } - Property { name: "centerIn"; type: "QQuickItem"; isPointer: true } - Property { name: "alignWhenCentered"; type: "bool" } - Signal { name: "centerAlignedChanged" } - } - Component { - name: "QQuickColorGroup" - prototype: "QObject" - Property { name: "alternateBase"; type: "QColor" } - Property { name: "base"; type: "QColor" } - Property { name: "brightText"; type: "QColor" } - Property { name: "button"; type: "QColor" } - Property { name: "buttonText"; type: "QColor" } - Property { name: "dark"; type: "QColor" } - Property { name: "highlight"; type: "QColor" } - Property { name: "highlightedText"; type: "QColor" } - Property { name: "light"; type: "QColor" } - Property { name: "link"; type: "QColor" } - Property { name: "linkVisited"; type: "QColor" } - Property { name: "mid"; type: "QColor" } - Property { name: "midlight"; type: "QColor" } - Property { name: "shadow"; type: "QColor" } - Property { name: "text"; type: "QColor" } - Property { name: "toolTipBase"; type: "QColor" } - Property { name: "toolTipText"; type: "QColor" } - Property { name: "window"; type: "QColor" } - Property { name: "windowText"; type: "QColor" } - Property { name: "placeholderText"; revision: 1538; type: "QColor" } - Signal { name: "placeholderTextChanged"; revision: 1538 } - Signal { name: "changed" } - } - Component { - name: "QQuickItem" - defaultProperty: "data" - prototype: "QObject" - Enum { - name: "Flags" - values: { - "ItemClipsChildrenToShape": 1, - "ItemAcceptsInputMethod": 2, - "ItemIsFocusScope": 4, - "ItemHasContents": 8, - "ItemAcceptsDrops": 16 - } - } - Enum { - name: "TransformOrigin" - values: { - "TopLeft": 0, - "Top": 1, - "TopRight": 2, - "Left": 3, - "Center": 4, - "Right": 5, - "BottomLeft": 6, - "Bottom": 7, - "BottomRight": 8 - } - } - Property { name: "parent"; type: "QQuickItem"; isPointer: true } - Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } - Property { name: "resources"; type: "QObject"; isList: true; isReadonly: true } - Property { name: "children"; type: "QQuickItem"; isList: true; isReadonly: true } - Property { name: "x"; type: "double" } - Property { name: "y"; type: "double" } - Property { name: "z"; type: "double" } - Property { name: "width"; type: "double" } - Property { name: "height"; type: "double" } - Property { name: "opacity"; type: "double" } - Property { name: "enabled"; type: "bool" } - Property { name: "visible"; type: "bool" } - Property { name: "palette"; revision: 1536; type: "QQuickPalette"; isPointer: true } - Property { name: "visibleChildren"; type: "QQuickItem"; isList: true; isReadonly: true } - Property { name: "states"; type: "QQuickState"; isList: true; isReadonly: true } - Property { name: "transitions"; type: "QQuickTransition"; isList: true; isReadonly: true } - Property { name: "state"; type: "string" } - Property { name: "childrenRect"; type: "QRectF"; isReadonly: true } - Property { name: "anchors"; type: "QQuickAnchors"; isReadonly: true; isPointer: true } - Property { name: "left"; type: "QQuickAnchorLine"; isReadonly: true } - Property { name: "right"; type: "QQuickAnchorLine"; isReadonly: true } - Property { name: "horizontalCenter"; type: "QQuickAnchorLine"; isReadonly: true } - Property { name: "top"; type: "QQuickAnchorLine"; isReadonly: true } - Property { name: "bottom"; type: "QQuickAnchorLine"; isReadonly: true } - Property { name: "verticalCenter"; type: "QQuickAnchorLine"; isReadonly: true } - Property { name: "baseline"; type: "QQuickAnchorLine"; isReadonly: true } - Property { name: "baselineOffset"; type: "double" } - Property { name: "clip"; type: "bool" } - Property { name: "focus"; type: "bool" } - Property { name: "activeFocus"; type: "bool"; isReadonly: true } - Property { name: "activeFocusOnTab"; revision: 513; type: "bool" } - Property { name: "rotation"; type: "double" } - Property { name: "scale"; type: "double" } - Property { name: "transformOrigin"; type: "QQuickItem::TransformOrigin" } - Property { name: "transformOriginPoint"; type: "QPointF"; isReadonly: true } - Property { name: "transform"; type: "QQuickTransform"; isList: true; isReadonly: true } - Property { name: "smooth"; type: "bool" } - Property { name: "antialiasing"; type: "bool" } - Property { name: "implicitWidth"; type: "double" } - Property { name: "implicitHeight"; type: "double" } - Property { name: "containmentMask"; revision: 523; type: "QObject"; isPointer: true } - Property { name: "layer"; type: "QQuickItemLayer"; isReadonly: true; isPointer: true } - Signal { - name: "childrenRectChanged" - Parameter { type: "QRectF" } - } - Signal { - name: "baselineOffsetChanged" - Parameter { type: "double" } - } - Signal { - name: "stateChanged" - Parameter { type: "string" } - } - Signal { - name: "focusChanged" - Parameter { type: "bool" } - } - Signal { - name: "activeFocusChanged" - Parameter { type: "bool" } - } - Signal { - name: "activeFocusOnTabChanged" - revision: 513 - Parameter { type: "bool" } - } - Signal { - name: "parentChanged" - Parameter { type: "QQuickItem"; isPointer: true } - } - Signal { - name: "transformOriginChanged" - Parameter { type: "TransformOrigin" } - } - Signal { - name: "smoothChanged" - Parameter { type: "bool" } - } - Signal { - name: "antialiasingChanged" - Parameter { type: "bool" } - } - Signal { - name: "clipChanged" - Parameter { type: "bool" } - } - Signal { - name: "windowChanged" - revision: 513 - Parameter { name: "window"; type: "QQuickWindow"; isPointer: true } - } - Signal { name: "containmentMaskChanged"; revision: 523 } - Signal { name: "paletteChanged"; revision: 1536 } - Signal { name: "paletteCreated"; revision: 1536 } - Method { name: "update" } - Method { - name: "grabToImage" - revision: 516 - type: "bool" - Parameter { name: "callback"; type: "QJSValue" } - Parameter { name: "targetSize"; type: "QSize" } - } - Method { - name: "grabToImage" - revision: 516 - type: "bool" - Parameter { name: "callback"; type: "QJSValue" } - } - Method { - name: "contains" - type: "bool" - Parameter { name: "point"; type: "QPointF" } - } - Method { - name: "mapFromItem" - Parameter { type: "QQmlV4Function"; isPointer: true } - } - Method { - name: "mapToItem" - Parameter { type: "QQmlV4Function"; isPointer: true } - } - Method { - name: "mapFromGlobal" - revision: 519 - Parameter { type: "QQmlV4Function"; isPointer: true } - } - Method { - name: "mapToGlobal" - revision: 519 - Parameter { type: "QQmlV4Function"; isPointer: true } - } - Method { name: "forceActiveFocus" } - Method { - name: "forceActiveFocus" - Parameter { name: "reason"; type: "Qt::FocusReason" } - } - Method { - name: "nextItemInFocusChain" - revision: 513 - type: "QQuickItem*" - Parameter { name: "forward"; type: "bool" } - } - Method { name: "nextItemInFocusChain"; revision: 513; type: "QQuickItem*" } - Method { - name: "childAt" - type: "QQuickItem*" - Parameter { name: "x"; type: "double" } - Parameter { name: "y"; type: "double" } - } - } - Component { - name: "QQuickItemLayer" - prototype: "QObject" - Property { name: "enabled"; type: "bool" } - Property { name: "textureSize"; type: "QSize" } - Property { name: "sourceRect"; type: "QRectF" } - Property { name: "mipmap"; type: "bool" } - Property { name: "smooth"; type: "bool" } - Property { name: "wrapMode"; type: "QQuickShaderEffectSource::WrapMode" } - Property { name: "format"; type: "QQuickShaderEffectSource::Format" } - Property { name: "samplerName"; type: "QByteArray" } - Property { name: "effect"; type: "QQmlComponent"; isPointer: true } - Property { name: "textureMirroring"; type: "QQuickShaderEffectSource::TextureMirroring" } - Property { name: "samples"; type: "int" } - Signal { - name: "enabledChanged" - Parameter { name: "enabled"; type: "bool" } - } - Signal { - name: "sizeChanged" - Parameter { name: "size"; type: "QSize" } - } - Signal { - name: "mipmapChanged" - Parameter { name: "mipmap"; type: "bool" } - } - Signal { - name: "wrapModeChanged" - Parameter { name: "mode"; type: "QQuickShaderEffectSource::WrapMode" } - } - Signal { - name: "nameChanged" - Parameter { name: "name"; type: "QByteArray" } - } - Signal { - name: "effectChanged" - Parameter { name: "component"; type: "QQmlComponent"; isPointer: true } - } - Signal { - name: "smoothChanged" - Parameter { name: "smooth"; type: "bool" } - } - Signal { - name: "formatChanged" - Parameter { name: "format"; type: "QQuickShaderEffectSource::Format" } - } - Signal { - name: "sourceRectChanged" - Parameter { name: "sourceRect"; type: "QRectF" } - } - Signal { - name: "textureMirroringChanged" - Parameter { name: "mirroring"; type: "QQuickShaderEffectSource::TextureMirroring" } - } - Signal { - name: "samplesChanged" - Parameter { name: "count"; type: "int" } - } - } - Component { - name: "QQuickPalette" - prototype: "QQuickColorGroup" - Property { name: "active"; type: "QQuickColorGroup"; isPointer: true } - Property { name: "inactive"; type: "QQuickColorGroup"; isPointer: true } - Property { name: "disabled"; type: "QQuickColorGroup"; isPointer: true } - Method { - name: "setActive" - Parameter { name: "active"; type: "QQuickColorGroup"; isPointer: true } - } - Method { - name: "setInactive" - Parameter { name: "inactive"; type: "QQuickColorGroup"; isPointer: true } - } - Method { - name: "setDisabled" - Parameter { name: "disabled"; type: "QQuickColorGroup"; isPointer: true } - } - } - Component { name: "QWaylandCompositorExtension"; prototype: "QWaylandObject" } - Component { name: "QWaylandObject"; prototype: "QObject" } - Component { - name: "QWaylandQtShell" - prototype: "QWaylandCompositorExtension" - Signal { - name: "qtShellSurfaceRequested" - Parameter { name: "surface"; type: "QWaylandSurface"; isPointer: true } - Parameter { name: "windowId"; type: "uint" } - Parameter { name: "resource"; type: "QWaylandResource" } - } - Signal { - name: "qtShellSurfaceCreated" - Parameter { name: "qtShellSurface"; type: "QWaylandQtShellSurface"; isPointer: true } - } - } - Component { - name: "QWaylandQtShellChrome" - defaultProperty: "data" - prototype: "QQuickItem" - exports: ["QtWayland.Compositor.QtShell/QtShellChrome 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "hasDecorations"; type: "bool"; isReadonly: true } - Property { name: "windowState"; type: "uint"; isReadonly: true } - Property { name: "windowFlags"; type: "uint"; isReadonly: true } - Property { name: "shellSurfaceItem"; type: "QWaylandQuickShellSurfaceItem"; isPointer: true } - Property { name: "maximizedRect"; type: "QRect" } - Property { name: "frameMarginLeft"; type: "int" } - Property { name: "frameMarginRight"; type: "int" } - Property { name: "frameMarginTop"; type: "int" } - Property { name: "frameMarginBottom"; type: "int" } - Property { name: "titleBar"; type: "QQuickItem"; isPointer: true } - Property { name: "leftResizeHandle"; type: "QQuickItem"; isPointer: true } - Property { name: "rightResizeHandle"; type: "QQuickItem"; isPointer: true } - Property { name: "topResizeHandle"; type: "QQuickItem"; isPointer: true } - Property { name: "bottomResizeHandle"; type: "QQuickItem"; isPointer: true } - Property { name: "topLeftResizeHandle"; type: "QQuickItem"; isPointer: true } - Property { name: "topRightResizeHandle"; type: "QQuickItem"; isPointer: true } - Property { name: "bottomLeftResizeHandle"; type: "QQuickItem"; isPointer: true } - Property { name: "bottomRightResizeHandle"; type: "QQuickItem"; isPointer: true } - Signal { name: "currentWindowStateChanged" } - Signal { name: "currentWindowFlagsChanged" } - Signal { name: "windowMetaInfoChanged" } - Signal { name: "activated" } - Signal { name: "deactivated" } - Signal { name: "clientDestroyed" } - Signal { name: "frameMarginChanged" } - Method { name: "raise" } - Method { name: "lower" } - Method { name: "toggleMaximized" } - Method { name: "toggleMinimized" } - Method { name: "toggleFullScreen" } - Method { name: "activate" } - Method { name: "deactivate" } - } - Component { - name: "QWaylandQtShellQuickExtension" - defaultProperty: "data" - prototype: "QWaylandQtShell" - exports: ["QtWayland.Compositor.QtShell/QtShell 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } - } - Component { - name: "QWaylandQtShellSurface" - defaultProperty: "data" - prototype: "QWaylandShellSurface" - exports: ["QtWayland.Compositor.QtShell/QtShellSurface 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } - Property { name: "surface"; type: "QWaylandSurface"; isReadonly: true; isPointer: true } - Property { name: "windowId"; type: "uint"; isReadonly: true } - Property { name: "windowFlags"; type: "uint"; isReadonly: true } - Property { name: "windowState"; type: "uint"; isReadonly: true } - Property { name: "windowTitle"; type: "string"; isReadonly: true } - Property { name: "windowGeometry"; type: "QRect"; isReadonly: true } - Property { name: "windowPosition"; type: "QPoint" } - Property { name: "positionAutomatic"; type: "bool"; isReadonly: true } - Property { name: "minimumSize"; type: "QSize"; isReadonly: true } - Property { name: "maximumSize"; type: "QSize"; isReadonly: true } - Property { name: "frameMarginLeft"; type: "int" } - Property { name: "frameMarginRight"; type: "int" } - Property { name: "frameMarginTop"; type: "int" } - Property { name: "frameMarginBottom"; type: "int" } - Property { name: "active"; type: "bool" } - Signal { name: "startMove" } - Signal { name: "startResize" } - Signal { name: "frameMarginChanged" } - Signal { name: "raiseRequested" } - Signal { name: "lowerRequested" } - Method { - name: "initialize" - Parameter { name: "qtShell"; type: "QWaylandQtShell"; isPointer: true } - Parameter { name: "surface"; type: "QWaylandSurface"; isPointer: true } - Parameter { name: "windowId"; type: "uint" } - Parameter { name: "resource"; type: "QWaylandResource" } - } - Method { - name: "requestWindowGeometry" - Parameter { name: "windowState"; type: "uint" } - Parameter { name: "windowGeometry"; type: "QRect" } - } - Method { name: "sendClose" } - } - Component { - name: "QWaylandShellSurface" - prototype: "QWaylandCompositorExtension" - Property { name: "windowType"; type: "Qt::WindowType"; isReadonly: true } - } -} diff --git a/src/imports/compositor-extensions/qtshell/qwaylandqtshell.cpp b/src/imports/compositor-extensions/qtshell/qwaylandqtshell.cpp index d0715e8c2..0e918e734 100644 --- a/src/imports/compositor-extensions/qtshell/qwaylandqtshell.cpp +++ b/src/imports/compositor-extensions/qtshell/qwaylandqtshell.cpp @@ -844,4 +844,4 @@ void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_lower(Resource *resourc QT_END_NAMESPACE -#include "moc_qwaylandqtshell.cpp" +#include "moc_qwaylandqtshell_p.cpp" diff --git a/src/imports/compositor-extensions/qtshell/qwaylandqtshell.h b/src/imports/compositor-extensions/qtshell/qwaylandqtshell.h index 6982e0b05..d322b9415 100644 --- a/src/imports/compositor-extensions/qtshell/qwaylandqtshell.h +++ b/src/imports/compositor-extensions/qtshell/qwaylandqtshell.h @@ -11,6 +11,7 @@ #include <QtWaylandCompositor/QWaylandShellSurface> #include <QtWaylandCompositor/qwaylandquickchildren.h> +#include <QtWaylandCompositor/qwaylandquickextension.h> struct wl_resource; struct wl_interface; @@ -50,6 +51,8 @@ private: bool moveChromeToFront(QWaylandQtShellChrome *chrome); }; +Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_ELEMENT(QWaylandQtShell, QtShell, 1, 0) + class QWaylandQtShellSurfacePrivate; class QWaylandSurfaceRole; @@ -58,6 +61,8 @@ class QWaylandResource; class Q_WAYLANDCOMPOSITOR_EXPORT QWaylandQtShellSurface : public QWaylandShellSurfaceTemplate<QWaylandQtShellSurface> { Q_OBJECT + QML_NAMED_ELEMENT(QtShellSurface) + QML_ADDED_IN_VERSION(1, 0) Q_DECLARE_PRIVATE(QWaylandQtShellSurface) Q_WAYLAND_COMPOSITOR_DECLARE_QUICK_CHILDREN(QWaylandQtShellSurface) Q_PROPERTY(QWaylandSurface *surface READ surface NOTIFY surfaceChanged) diff --git a/src/imports/compositor-extensions/qtshell/qwaylandqtshell.qdoc b/src/imports/compositor-extensions/qtshell/qwaylandqtshell.qdoc new file mode 100644 index 000000000..d0e961245 --- /dev/null +++ b/src/imports/compositor-extensions/qtshell/qwaylandqtshell.qdoc @@ -0,0 +1,22 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \qmlmodule QtWayland.Compositor.QtShell + \title Qt Wayland Qt Shell Extension + \ingroup qmlmodules + \since 6.3 + \brief Provides a shell extension for Qt applications running on a Qt Wayland Compositor. + \section2 Summary + The QtShell extension provides a way to associate an QtShellSurface with a regular Wayland + surface. The QtShell extension is written to support the window management features which are + supported by Qt. It may be suitable on a platform where both the compositor and client + applications are written with Qt, and where applications are trusted not to abuse features such + as manual window positioning and "bring-to-front". + For other use cases, consider using IviApplication or XdgShell instead. + \section2 Usage + To use this module, import it like this: + \qml + import QtWayland.Compositor.IviApplication + \endqml +*/ diff --git a/src/imports/compositor-extensions/qtshell/qwaylandqtshellchrome.h b/src/imports/compositor-extensions/qtshell/qwaylandqtshellchrome.h index 381dd7f6d..4fb98008c 100644 --- a/src/imports/compositor-extensions/qtshell/qwaylandqtshellchrome.h +++ b/src/imports/compositor-extensions/qtshell/qwaylandqtshellchrome.h @@ -13,6 +13,8 @@ class QWaylandQtShellChromePrivate; class Q_WAYLANDCOMPOSITOR_EXPORT QWaylandQtShellChrome : public QQuickItem { Q_OBJECT + QML_NAMED_ELEMENT(QtShellChrome) + QML_ADDED_IN_VERSION(1, 0) Q_DECLARE_PRIVATE(QWaylandQtShellChrome) Q_PROPERTY(bool hasDecorations READ hasDecorations NOTIFY windowMetaInfoChanged) Q_PROPERTY(uint windowState READ currentWindowState NOTIFY currentWindowStateChanged) diff --git a/src/imports/compositor-extensions/qtshell/qwaylandqtshellplugin.cpp b/src/imports/compositor-extensions/qtshell/qwaylandqtshellplugin.cpp deleted file mode 100644 index 84f7090ab..000000000 --- a/src/imports/compositor-extensions/qtshell/qwaylandqtshellplugin.cpp +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (C) 2021 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only - -#include <QtQml/qqmlextensionplugin.h> -#include <QtQml/qqml.h> - -#include <QtWaylandCompositor/qwaylandquickextension.h> -#include "qwaylandqtshell.h" -#include "qwaylandqtshellchrome.h" - -QT_BEGIN_NAMESPACE - -Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandQtShell) - -/*! - \qmlmodule QtWayland.Compositor.QtShell - \title Qt Wayland Qt Shell Extension - \ingroup qmlmodules - \since 6.3 - \brief Provides a shell extension for Qt applications running on a Qt Wayland Compositor. - - \section2 Summary - The QtShell extension provides a way to associate an QtShellSurface with a regular Wayland - surface. The QtShell extension is written to support the window management features which are - supported by Qt. It may be suitable on a platform where both the compositor and client - applications are written with Qt, and where applications are trusted not to abuse features such - as manual window positioning and "bring-to-front". - - For other use cases, consider using IviApplication or XdgShell instead. - - \section2 Usage - To use this module, import it like this: - \qml - import QtWayland.Compositor.IviApplication - \endqml -*/ - -class QQtWaylandShellPlugin : public QQmlExtensionPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) -public: - void registerTypes(const char *uri) override - { - Q_ASSERT(QLatin1String(uri) == QLatin1String("QtWayland.Compositor.QtShell")); - defineModule(uri); - } - - static void defineModule(const char *uri) - { - qmlRegisterModule(uri, QT_VERSION_MAJOR, QT_VERSION_MINOR); - qmlRegisterType<QWaylandQtShellQuickExtension>(uri, 1, 0, "QtShell"); - qmlRegisterType<QWaylandQtShellSurface>(uri, 1, 0, "QtShellSurface"); - qmlRegisterType<QWaylandQtShellChrome>(uri, 1, 0, "QtShellChrome"); - } -}; - -QT_END_NAMESPACE - -#include "qwaylandqtshellplugin.moc" diff --git a/src/imports/compositor-extensions/wlshell/CMakeLists.txt b/src/imports/compositor-extensions/wlshell/CMakeLists.txt index 0dd155e35..8987621d3 100644 --- a/src/imports/compositor-extensions/wlshell/CMakeLists.txt +++ b/src/imports/compositor-extensions/wlshell/CMakeLists.txt @@ -1,33 +1,17 @@ # Copyright (C) 2022 The Qt Company Ltd. # SPDX-License-Identifier: BSD-3-Clause -# Generated from wlshell.pro. - -##################################################################### -## qwaylandcompositorwlshellplugin Plugin: -##################################################################### - qt_internal_add_qml_module(WaylandCompositorWLShell URI "QtWayland.Compositor.WlShell" VERSION "${PROJECT_VERSION}" - CLASS_NAME QWaylandCompositorWlShellPlugin - NO_PLUGIN_OPTIONAL - PLUGIN_TARGET WaylandCompositorWLShell - NO_GENERATE_PLUGIN_SOURCE - NO_GENERATE_QMLTYPES - INSTALL_SOURCE_QMLTYPES "plugins.qmltypes" SOURCES - qwaylandcompositorwlshellplugin.cpp + qwaylandcompositorwlshell_p.h qwaylandcompositorwlshell.cpp LIBRARIES Qt::Core Qt::Gui Qt::WaylandCompositor NO_GENERATE_CPP_EXPORTS + PAST_MAJOR_VERSIONS 1 ) qt_internal_add_autogen_sync_header_dependencies(WaylandCompositorWLShell WaylandCompositor) - -#### Keys ignored in scope 1:.:.:wlshell.pro:<TRUE>: -# CXX_MODULE = "qml" -# QML_IMPORT_VERSION = "$$QT_VERSION" -# TARGETPATH = "QtWayland/Compositor/WlShell" diff --git a/src/imports/compositor-extensions/wlshell/plugins.qmltypes b/src/imports/compositor-extensions/wlshell/plugins.qmltypes deleted file mode 100644 index 99a3ce9a6..000000000 --- a/src/imports/compositor-extensions/wlshell/plugins.qmltypes +++ /dev/null @@ -1,140 +0,0 @@ -import QtQuick.tooling 1.2 - -// This file describes the plugin-supplied types contained in the library. -// It is used for QML tooling purposes only. -// -// This file was auto-generated by: -// 'qmlplugindump -nonrelocatable QtWayland.Compositor.WlShell 6.0' - -Module { - dependencies: ["QtQuick 2.0"] - Component { name: "QWaylandCompositorExtension"; prototype: "QWaylandObject" } - Component { name: "QWaylandObject"; prototype: "QObject" } - Component { - name: "QWaylandShell" - prototype: "QWaylandCompositorExtension" - Enum { - name: "FocusPolicy" - values: { - "AutomaticFocus": 0, - "ManualFocus": 1 - } - } - Property { name: "focusPolicy"; type: "FocusPolicy" } - } - Component { - name: "QWaylandShellSurface" - prototype: "QWaylandCompositorExtension" - Property { name: "windowType"; type: "Qt::WindowType"; isReadonly: true } - } - Component { - name: "QWaylandWlShell" - prototype: "QWaylandShell" - Signal { - name: "wlShellSurfaceRequested" - Parameter { name: "surface"; type: "QWaylandSurface"; isPointer: true } - Parameter { name: "resource"; type: "QWaylandResource" } - } - Signal { - name: "wlShellSurfaceCreated" - Parameter { name: "shellSurface"; type: "QWaylandWlShellSurface"; isPointer: true } - } - Method { name: "closeAllPopups" } - } - Component { - name: "QWaylandWlShellQuickExtension" - defaultProperty: "data" - prototype: "QWaylandWlShell" - exports: ["QtWayland.Compositor.WlShell/WlShell 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } - } - Component { - name: "QWaylandWlShellSurface" - defaultProperty: "data" - prototype: "QWaylandShellSurface" - exports: ["QtWayland.Compositor.WlShell/WlShellSurface 1.0"] - exportMetaObjectRevisions: [0] - Enum { - name: "FullScreenMethod" - values: { - "DefaultFullScreen": 0, - "ScaleFullScreen": 1, - "DriverFullScreen": 2, - "FillFullScreen": 3 - } - } - Enum { - name: "ResizeEdge" - values: { - "NoneEdge": 0, - "TopEdge": 1, - "BottomEdge": 2, - "LeftEdge": 4, - "TopLeftEdge": 5, - "BottomLeftEdge": 6, - "RightEdge": 8, - "TopRightEdge": 9, - "BottomRightEdge": 10 - } - } - Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } - Property { name: "surface"; type: "QWaylandSurface"; isReadonly: true; isPointer: true } - Property { name: "shell"; type: "QWaylandWlShell"; isReadonly: true; isPointer: true } - Property { name: "title"; type: "string"; isReadonly: true } - Property { name: "className"; type: "string"; isReadonly: true } - Signal { name: "pong" } - Signal { - name: "startMove" - Parameter { name: "seat"; type: "QWaylandSeat"; isPointer: true } - } - Signal { - name: "startResize" - Parameter { name: "seat"; type: "QWaylandSeat"; isPointer: true } - Parameter { name: "edges"; type: "ResizeEdge" } - } - Signal { name: "setDefaultToplevel" } - Signal { - name: "setTransient" - Parameter { name: "parentSurface"; type: "QWaylandSurface"; isPointer: true } - Parameter { name: "relativeToParent"; type: "QPoint" } - Parameter { name: "inactive"; type: "bool" } - } - Signal { - name: "setFullScreen" - Parameter { name: "method"; type: "FullScreenMethod" } - Parameter { name: "framerate"; type: "uint" } - Parameter { name: "output"; type: "QWaylandOutput"; isPointer: true } - } - Signal { - name: "setPopup" - Parameter { name: "seat"; type: "QWaylandSeat"; isPointer: true } - Parameter { name: "parentSurface"; type: "QWaylandSurface"; isPointer: true } - Parameter { name: "relativeToParent"; type: "QPoint" } - } - Signal { - name: "setMaximized" - Parameter { name: "output"; type: "QWaylandOutput"; isPointer: true } - } - Method { name: "ping" } - Method { - name: "initialize" - Parameter { name: "shell"; type: "QWaylandWlShell"; isPointer: true } - Parameter { name: "surface"; type: "QWaylandSurface"; isPointer: true } - Parameter { name: "resource"; type: "QWaylandResource" } - } - Method { - name: "sizeForResize" - type: "QSize" - Parameter { name: "size"; type: "QSizeF" } - Parameter { name: "delta"; type: "QPointF" } - Parameter { name: "edges"; type: "ResizeEdge" } - } - Method { - name: "sendConfigure" - Parameter { name: "size"; type: "QSize" } - Parameter { name: "edges"; type: "ResizeEdge" } - } - Method { name: "sendPopupDone" } - } -} diff --git a/src/imports/compositor-extensions/wlshell/qwaylandcompositorwlshell.cpp b/src/imports/compositor-extensions/wlshell/qwaylandcompositorwlshell.cpp new file mode 100644 index 000000000..3d7e6a6f1 --- /dev/null +++ b/src/imports/compositor-extensions/wlshell/qwaylandcompositorwlshell.cpp @@ -0,0 +1,30 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "qwaylandcompositorwlshell_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmlmodule QtWayland.Compositor.WlShell + \title Qt Wayland WlShell extension + \ingroup qmlmodules + \brief Provides a Qt API for the WlShell extension. + + \section2 Summary + WlShell is a shell extension providing window system features typical to + desktop systems. It is superseded by XdgShell and exists in Qt mainly + for backwards compatibility with older applications. + + WlShell corresponds to the Wayland interface \c wl_shell. + + \section2 Usage + To use this module, import it like this: + \qml + import QtWayland.Compositor.WlShell + \endqml +*/ + +QT_END_NAMESPACE + +#include "moc_qwaylandcompositorwlshell_p.cpp" diff --git a/src/imports/compositor-extensions/wlshell/qwaylandcompositorwlshell_p.h b/src/imports/compositor-extensions/wlshell/qwaylandcompositorwlshell_p.h new file mode 100644 index 000000000..295d3562f --- /dev/null +++ b/src/imports/compositor-extensions/wlshell/qwaylandcompositorwlshell_p.h @@ -0,0 +1,37 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef QWAYLANDWLSHELLFOREIGN_H +#define QWAYLANDWLSHELLFOREIGN_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 <QtQml/qqmlextensionplugin.h> +#include <QtQml/qqml.h> + +#include <QtWaylandCompositor/qwaylandquickextension.h> +#include <QtWaylandCompositor/qwaylandwlshell.h> + +QT_BEGIN_NAMESPACE + +Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_ELEMENT(QWaylandWlShell, WlShell, 1, 0) + +struct QWaylandWlShellForeign { + Q_GADGET + QML_FOREIGN(QWaylandWlShell) + QML_NAMED_ELEMENT(WlShellSurface) + QML_ADDED_IN_VERSION(1, 0) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/imports/compositor-extensions/wlshell/qwaylandcompositorwlshellplugin.cpp b/src/imports/compositor-extensions/wlshell/qwaylandcompositorwlshellplugin.cpp deleted file mode 100644 index f489cdf12..000000000 --- a/src/imports/compositor-extensions/wlshell/qwaylandcompositorwlshellplugin.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2020 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only - -#include <QtQml/qqmlextensionplugin.h> -#include <QtQml/qqml.h> - -#include <QtWaylandCompositor/qwaylandquickextension.h> -#include <QtWaylandCompositor/qwaylandwlshell.h> - -QT_BEGIN_NAMESPACE - -Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandWlShell) - -/*! - \qmlmodule QtWayland.Compositor.WlShell - \title Qt Wayland WlShell extension - \ingroup qmlmodules - \brief Provides a Qt API for the WlShell extension. - - \section2 Summary - WlShell is a shell extension providing window system features typical to - desktop systems. It is superseded by XdgShell and exists in Qt mainly - for backwards compatibility with older applications. - - WlShell corresponds to the Wayland interface \c wl_shell. - - \section2 Usage - To use this module, import it like this: - \qml - import QtWayland.Compositor.WlShell - \endqml -*/ - -class QWaylandCompositorWlShellPlugin : public QQmlExtensionPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) -public: - void registerTypes(const char *uri) override - { - Q_ASSERT(QLatin1String(uri) == QLatin1String("QtWayland.Compositor.WlShell")); - defineModule(uri); - } - - static void defineModule(const char *uri) - { - qmlRegisterModule(uri, QT_VERSION_MAJOR, QT_VERSION_MINOR); - qmlRegisterType<QWaylandWlShellQuickExtension>(uri, 1, 0, "WlShell"); - qmlRegisterType<QWaylandWlShellSurface>(uri, 1, 0, "WlShellSurface"); - } -}; - -QT_END_NAMESPACE - -#include "qwaylandcompositorwlshellplugin.moc" diff --git a/src/imports/compositor-extensions/xdgshell/CMakeLists.txt b/src/imports/compositor-extensions/xdgshell/CMakeLists.txt index d5bfd9dd8..32f032d93 100644 --- a/src/imports/compositor-extensions/xdgshell/CMakeLists.txt +++ b/src/imports/compositor-extensions/xdgshell/CMakeLists.txt @@ -1,33 +1,18 @@ # Copyright (C) 2022 The Qt Company Ltd. # SPDX-License-Identifier: BSD-3-Clause -# Generated from xdgshell.pro. - -##################################################################### -## qwaylandcompositorxdgshellplugin Plugin: -##################################################################### - qt_internal_add_qml_module(WaylandCompositorXdgShell URI "QtWayland.Compositor.XdgShell" VERSION "${PROJECT_VERSION}" - NO_PLUGIN_OPTIONAL - PLUGIN_TARGET WaylandCompositorXdgShell - NO_GENERATE_PLUGIN_SOURCE - NO_GENERATE_QMLTYPES - INSTALL_SOURCE_QMLTYPES "plugins.qmltypes" - CLASS_NAME QWaylandCompositorXdgShellPlugin SOURCES - qwaylandcompositorxdgshellplugin.cpp + qwaylandcompositorxdgshell_p.h + qwaylandcompositorxdgshell.cpp LIBRARIES Qt::Core Qt::Gui Qt::WaylandCompositor NO_GENERATE_CPP_EXPORTS + PAST_MAJOR_VERSIONS 1 ) qt_internal_add_autogen_sync_header_dependencies(WaylandCompositorXdgShell WaylandCompositor) - -#### Keys ignored in scope 1:.:.:xdgshell.pro:<TRUE>: -# CXX_MODULE = "qml" -# QML_IMPORT_VERSION = "$$QT_VERSION" -# TARGETPATH = "QtWayland/Compositor/XdgShell" diff --git a/src/imports/compositor-extensions/xdgshell/plugins.qmltypes b/src/imports/compositor-extensions/xdgshell/plugins.qmltypes deleted file mode 100644 index b5bf435a0..000000000 --- a/src/imports/compositor-extensions/xdgshell/plugins.qmltypes +++ /dev/null @@ -1,260 +0,0 @@ -import QtQuick.tooling 1.2 - -// This file describes the plugin-supplied types contained in the library. -// It is used for QML tooling purposes only. -// -// This file was auto-generated by: -// 'qmlplugindump -nonrelocatable QtWayland.Compositor.XdgShell 6.0' - -Module { - dependencies: ["QtQuick 2.0"] - Component { name: "QWaylandCompositorExtension"; prototype: "QWaylandObject" } - Component { name: "QWaylandObject"; prototype: "QObject" } - Component { - name: "QWaylandQuickXdgOutputV1" - defaultProperty: "data" - prototype: "QWaylandXdgOutputV1" - exports: ["QtWayland.Compositor.XdgShell/XdgOutputV1 1.14"] - exportMetaObjectRevisions: [0] - } - Component { - name: "QWaylandShell" - prototype: "QWaylandCompositorExtension" - Enum { - name: "FocusPolicy" - values: { - "AutomaticFocus": 0, - "ManualFocus": 1 - } - } - Property { name: "focusPolicy"; type: "FocusPolicy" } - } - Component { - name: "QWaylandShellSurface" - prototype: "QWaylandCompositorExtension" - Property { name: "windowType"; type: "Qt::WindowType"; isReadonly: true } - } - Component { - name: "QWaylandXdgDecorationManagerV1" - prototype: "QWaylandCompositorExtension" - Property { name: "preferredMode"; type: "QWaylandXdgToplevel::DecorationMode" } - } - Component { - name: "QWaylandXdgDecorationManagerV1QuickExtension" - defaultProperty: "data" - prototype: "QWaylandXdgDecorationManagerV1" - exports: ["QtWayland.Compositor.XdgShell/XdgDecorationManagerV1 1.3"] - exportMetaObjectRevisions: [0] - Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } - } - Component { name: "QWaylandXdgOutputManagerV1"; prototype: "QWaylandCompositorExtension" } - Component { - name: "QWaylandXdgOutputManagerV1QuickExtension" - defaultProperty: "data" - prototype: "QWaylandXdgOutputManagerV1" - exports: ["QtWayland.Compositor.XdgShell/XdgOutputManagerV1 1.14"] - exportMetaObjectRevisions: [0] - Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } - } - Component { - name: "QWaylandXdgOutputV1" - defaultProperty: "data" - prototype: "QObject" - Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } - Property { - name: "manager" - type: "QWaylandXdgOutputManagerV1" - isReadonly: true - isPointer: true - } - Property { name: "output"; type: "QWaylandOutput"; isReadonly: true; isPointer: true } - Property { name: "name"; type: "string" } - Property { name: "description"; type: "string" } - Property { name: "logicalPosition"; type: "QPoint" } - Property { name: "logicalSize"; type: "QSize" } - Property { name: "logicalGeometry"; type: "QRect"; isReadonly: true } - } - Component { - name: "QWaylandXdgPopup" - prototype: "QObject" - exports: ["QtWayland.Compositor.XdgShell/XdgPopup 1.3"] - isCreatable: false - exportMetaObjectRevisions: [0] - Property { name: "xdgSurface"; type: "QWaylandXdgSurface"; isReadonly: true; isPointer: true } - Property { - name: "parentXdgSurface" - type: "QWaylandXdgSurface" - isReadonly: true - isPointer: true - } - Property { name: "configuredGeometry"; type: "QRect"; isReadonly: true } - Property { name: "anchorRect"; type: "QRect"; isReadonly: true } - Property { name: "anchorEdges"; type: "Qt::Edges"; isReadonly: true } - Property { name: "gravityEdges"; type: "Qt::Edges"; isReadonly: true } - Property { name: "slideConstraints"; type: "Qt::Orientations"; isReadonly: true } - Property { name: "flipConstraints"; type: "Qt::Orientations"; isReadonly: true } - Property { name: "resizeConstraints"; type: "Qt::Orientations"; isReadonly: true } - Property { name: "offset"; type: "QPoint"; isReadonly: true } - Property { name: "positionerSize"; type: "QSize"; isReadonly: true } - Property { name: "unconstrainedPosition"; type: "QPoint"; isReadonly: true } - Method { - name: "sendConfigure" - type: "uint" - Parameter { name: "geometry"; type: "QRect" } - } - Method { name: "sendPopupDone"; revision: 270 } - } - Component { - name: "QWaylandXdgShell" - prototype: "QWaylandShell" - Signal { - name: "xdgSurfaceCreated" - Parameter { name: "xdgSurface"; type: "QWaylandXdgSurface"; isPointer: true } - } - Signal { - name: "toplevelCreated" - Parameter { name: "toplevel"; type: "QWaylandXdgToplevel"; isPointer: true } - Parameter { name: "xdgSurface"; type: "QWaylandXdgSurface"; isPointer: true } - } - Signal { - name: "popupCreated" - Parameter { name: "popup"; type: "QWaylandXdgPopup"; isPointer: true } - Parameter { name: "xdgSurface"; type: "QWaylandXdgSurface"; isPointer: true } - } - Signal { - name: "pong" - Parameter { name: "serial"; type: "uint" } - } - Method { - name: "ping" - type: "uint" - Parameter { name: "client"; type: "QWaylandClient"; isPointer: true } - } - } - Component { - name: "QWaylandXdgShellQuickExtension" - defaultProperty: "data" - prototype: "QWaylandXdgShell" - exports: ["QtWayland.Compositor.XdgShell/XdgShell 1.3"] - exportMetaObjectRevisions: [0] - Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } - } - Component { - name: "QWaylandXdgSurface" - defaultProperty: "data" - prototype: "QWaylandShellSurface" - exports: ["QtWayland.Compositor.XdgShell/XdgSurface 1.3"] - exportMetaObjectRevisions: [0] - Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } - Property { name: "shell"; type: "QWaylandXdgShell"; isReadonly: true; isPointer: true } - Property { name: "surface"; type: "QWaylandSurface"; isReadonly: true; isPointer: true } - Property { name: "toplevel"; type: "QWaylandXdgToplevel"; isReadonly: true; isPointer: true } - Property { name: "popup"; type: "QWaylandXdgPopup"; isReadonly: true; isPointer: true } - Property { name: "windowGeometry"; type: "QRect"; isReadonly: true } - Signal { name: "toplevelCreated" } - Signal { name: "popupCreated" } - Method { - name: "initialize" - Parameter { name: "xdgShell"; type: "QWaylandXdgShell"; isPointer: true } - Parameter { name: "surface"; type: "QWaylandSurface"; isPointer: true } - Parameter { name: "resource"; type: "QWaylandResource" } - } - } - Component { - name: "QWaylandXdgToplevel" - prototype: "QObject" - exports: ["QtWayland.Compositor.XdgShell/XdgToplevel 1.3"] - isCreatable: false - exportMetaObjectRevisions: [0] - Enum { - name: "State" - values: { - "MaximizedState": 1, - "FullscreenState": 2, - "ResizingState": 3, - "ActivatedState": 4 - } - } - Enum { - name: "DecorationMode" - values: { - "ClientSideDecoration": 1, - "ServerSideDecoration": 2 - } - } - Property { name: "xdgSurface"; type: "QWaylandXdgSurface"; isReadonly: true; isPointer: true } - Property { - name: "parentToplevel" - type: "QWaylandXdgToplevel" - isReadonly: true - isPointer: true - } - Property { name: "title"; type: "string"; isReadonly: true } - Property { name: "appId"; type: "string"; isReadonly: true } - Property { name: "maxSize"; type: "QSize"; isReadonly: true } - Property { name: "minSize"; type: "QSize"; isReadonly: true } - Property { name: "states"; type: "QList<int>"; isReadonly: true } - Property { name: "maximized"; type: "bool"; isReadonly: true } - Property { name: "fullscreen"; type: "bool"; isReadonly: true } - Property { name: "resizing"; type: "bool"; isReadonly: true } - Property { name: "activated"; type: "bool"; isReadonly: true } - Property { name: "decorationMode"; type: "DecorationMode"; isReadonly: true } - Signal { - name: "startMove" - Parameter { name: "seat"; type: "QWaylandSeat"; isPointer: true } - } - Signal { - name: "startResize" - Parameter { name: "seat"; type: "QWaylandSeat"; isPointer: true } - Parameter { name: "edges"; type: "Qt::Edges" } - } - Signal { - name: "showWindowMenu" - Parameter { name: "seat"; type: "QWaylandSeat"; isPointer: true } - Parameter { name: "localSurfacePosition"; type: "QPoint" } - } - Signal { name: "setMaximized" } - Signal { name: "unsetMaximized" } - Signal { - name: "setFullscreen" - Parameter { name: "output"; type: "QWaylandOutput"; isPointer: true } - } - Signal { name: "unsetFullscreen" } - Signal { name: "setMinimized" } - Method { - name: "sizeForResize" - type: "QSize" - Parameter { name: "size"; type: "QSizeF" } - Parameter { name: "delta"; type: "QPointF" } - Parameter { name: "edges"; type: "Qt::Edges" } - } - Method { - name: "sendConfigure" - type: "uint" - Parameter { name: "size"; type: "QSize" } - Parameter { name: "states"; type: "QList<int>" } - } - Method { name: "sendClose" } - Method { - name: "sendMaximized" - type: "uint" - Parameter { name: "size"; type: "QSize" } - } - Method { - name: "sendUnmaximized" - type: "uint" - Parameter { name: "size"; type: "QSize" } - } - Method { name: "sendUnmaximized"; type: "uint" } - Method { - name: "sendFullscreen" - type: "uint" - Parameter { name: "size"; type: "QSize" } - } - Method { - name: "sendResizing" - type: "uint" - Parameter { name: "maxSize"; type: "QSize" } - } - } -} diff --git a/src/imports/compositor-extensions/xdgshell/qwaylandcompositorxdgshell.cpp b/src/imports/compositor-extensions/xdgshell/qwaylandcompositorxdgshell.cpp new file mode 100644 index 000000000..15c96c718 --- /dev/null +++ b/src/imports/compositor-extensions/xdgshell/qwaylandcompositorxdgshell.cpp @@ -0,0 +1,27 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "qwaylandcompositorxdgshell_p.h" + +QT_BEGIN_NAMESPACE +/*! + \qmlmodule QtWayland.Compositor.XdgShell + \title Qt Wayland XdgShell Extension + \ingroup qmlmodules + \brief Provides a Qt API for the XdgShell shell extension. + + \section2 Summary + XdgShell is a shell extension providing window system features typical to + desktop systems. + + XdgShell corresponds to the Wayland interface, \c xdg_shell. + + \section2 Usage + To use this module, import it like this: + \qml + import QtWayland.Compositor.XdgShell + \endqml +*/ +QT_END_NAMESPACE + +#include "moc_qwaylandcompositorxdgshell_p.cpp" diff --git a/src/imports/compositor-extensions/xdgshell/qwaylandcompositorxdgshell_p.h b/src/imports/compositor-extensions/xdgshell/qwaylandcompositorxdgshell_p.h new file mode 100644 index 000000000..f8a70d6ef --- /dev/null +++ b/src/imports/compositor-extensions/xdgshell/qwaylandcompositorxdgshell_p.h @@ -0,0 +1,66 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef QWAYLANDCOMPOSITORXDGSHELLFOREIGN_H +#define QWAYLANDCOMPOSITORXDGSHELLFOREIGN_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 <QtQml/qqmlextensionplugin.h> +#include <QtQml/qqml.h> + +#include <QtWaylandCompositor/QWaylandQuickExtension> +#include <QtWaylandCompositor/QWaylandXdgShell> +#include <QtWaylandCompositor/QWaylandXdgDecorationManagerV1> +#include <QtWaylandCompositor/QWaylandQuickXdgOutputV1> + +QT_BEGIN_NAMESPACE + +Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_ELEMENT(QWaylandXdgShell, XdgShell, 1, 3) +Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_ELEMENT(QWaylandXdgDecorationManagerV1, + XdgDecorationManagerV1, 1, 3) +Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_ELEMENT(QWaylandXdgOutputManagerV1, XdgOutputManagerV1, + 1, 14) + +struct QWaylandXdgSurfaceForeign { + Q_GADGET + QML_FOREIGN(QWaylandXdgSurface) + QML_NAMED_ELEMENT(XdgSurface) + QML_ADDED_IN_VERSION(1, 3) +}; + +struct QWaylandXdgTopLevelForeign { + Q_GADGET + QML_FOREIGN(QWaylandXdgToplevel) + QML_NAMED_ELEMENT(XdgToplevel) + QML_ADDED_IN_VERSION(1, 3) + QML_UNCREATABLE("Cannot create instance of XdgShellToplevel") +}; + +struct QWaylandXdgPopupForeign { + Q_GADGET + QML_FOREIGN(QWaylandXdgPopup) + QML_NAMED_ELEMENT(XdgPopup) + QML_ADDED_IN_VERSION(1, 3) + QML_UNCREATABLE("Cannot create instance of XdgShellPopup") +}; + +struct QWaylandQuickXdgOutputV1Foreign { + Q_GADGET + QML_FOREIGN(QWaylandQuickXdgOutputV1) + QML_NAMED_ELEMENT(XdgOutputV1) + QML_ADDED_IN_VERSION(1, 14) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/imports/compositor-extensions/xdgshell/qwaylandcompositorxdgshellplugin.cpp b/src/imports/compositor-extensions/xdgshell/qwaylandcompositorxdgshellplugin.cpp deleted file mode 100644 index 7dd4a3307..000000000 --- a/src/imports/compositor-extensions/xdgshell/qwaylandcompositorxdgshellplugin.cpp +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (C) 2020 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only - -#include <QtQml/qqmlextensionplugin.h> -#include <QtQml/qqml.h> - -#include <QtWaylandCompositor/QWaylandQuickExtension> -#include <QtWaylandCompositor/QWaylandXdgShell> -#include <QtWaylandCompositor/QWaylandXdgDecorationManagerV1> -#include <QtWaylandCompositor/QWaylandQuickXdgOutputV1> - -QT_BEGIN_NAMESPACE - -Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandXdgShell) -Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandXdgDecorationManagerV1) -Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandXdgOutputManagerV1) - -/*! - \qmlmodule QtWayland.Compositor.XdgShell - \title Qt Wayland XdgShell Extension - \ingroup qmlmodules - \brief Provides a Qt API for the XdgShell shell extension. - - \section2 Summary - XdgShell is a shell extension providing window system features typical to - desktop systems. - - XdgShell corresponds to the Wayland interface, \c xdg_shell. - - \section2 Usage - To use this module, import it like this: - \qml - import QtWayland.Compositor.XdgShell - \endqml -*/ - -class QWaylandCompositorXdgShellPlugin : public QQmlExtensionPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) -public: - void registerTypes(const char *uri) override - { - Q_ASSERT(QLatin1String(uri) == QLatin1String("QtWayland.Compositor.XdgShell")); - defineModule(uri); - } - - static void defineModule(const char *uri) - { - qmlRegisterModule(uri, QT_VERSION_MAJOR, QT_VERSION_MINOR); - - qmlRegisterType<QWaylandXdgShellQuickExtension>(uri, 1, 3, "XdgShell"); - qmlRegisterType<QWaylandXdgSurface>(uri, 1, 3, "XdgSurface"); - qmlRegisterUncreatableType<QWaylandXdgToplevel>(uri, 1, 3, "XdgToplevel", QObject::tr("Cannot create instance of XdgShellToplevel")); - qmlRegisterUncreatableType<QWaylandXdgPopup>(uri, 1, 3, "XdgPopup", QObject::tr("Cannot create instance of XdgShellPopup")); - - qmlRegisterType<QWaylandXdgDecorationManagerV1QuickExtension>(uri, 1, 3, "XdgDecorationManagerV1"); - qmlRegisterType<QWaylandXdgOutputManagerV1QuickExtension>(uri, 1, 14, "XdgOutputManagerV1"); - qmlRegisterType<QWaylandQuickXdgOutputV1>(uri, 1, 14, "XdgOutputV1"); - } -}; - -QT_END_NAMESPACE - -#include "qwaylandcompositorxdgshellplugin.moc" diff --git a/src/plugins/platforms/qwayland-generic/CMakeLists.txt b/src/plugins/platforms/qwayland-generic/CMakeLists.txt index ef31e432f..d71d910a9 100644 --- a/src/plugins/platforms/qwayland-generic/CMakeLists.txt +++ b/src/plugins/platforms/qwayland-generic/CMakeLists.txt @@ -10,7 +10,7 @@ qt_internal_add_plugin(QWaylandIntegrationPlugin OUTPUT_NAME qwayland-generic PLUGIN_TYPE platforms - DEFAULT_IF ${QT_QPA_DEFAULT_PLATFORM} MATCHES wayland # special case + DEFAULT_IF "wayland" IN_LIST QT_QPA_PLATFORMS SOURCES main.cpp LIBRARIES diff --git a/src/plugins/shellintegration/ivi-shell/qwaylandivisurface.cpp b/src/plugins/shellintegration/ivi-shell/qwaylandivisurface.cpp index 29ce0d74e..ebdf3e800 100644 --- a/src/plugins/shellintegration/ivi-shell/qwaylandivisurface.cpp +++ b/src/plugins/shellintegration/ivi-shell/qwaylandivisurface.cpp @@ -6,7 +6,6 @@ #include <QtWaylandClient/private/qwaylanddisplay_p.h> #include <QtWaylandClient/private/qwaylandwindow_p.h> #include <QtWaylandClient/private/qwaylandscreen_p.h> -#include <QtWaylandClient/private/qwaylandextendedsurface_p.h> QT_BEGIN_NAMESPACE @@ -17,7 +16,6 @@ QWaylandIviSurface::QWaylandIviSurface(struct ::ivi_surface *ivi_surface, QWayla , QWaylandShellSurface(window) , m_window(window) { - createExtendedSurface(window); } QWaylandIviSurface::QWaylandIviSurface(struct ::ivi_surface *ivi_surface, QWaylandWindow *window, @@ -27,7 +25,6 @@ QWaylandIviSurface::QWaylandIviSurface(struct ::ivi_surface *ivi_surface, QWayla , QtWayland::ivi_controller_surface(iviControllerSurface) , m_window(window) { - createExtendedSurface(window); } QWaylandIviSurface::~QWaylandIviSurface() @@ -35,8 +32,6 @@ QWaylandIviSurface::~QWaylandIviSurface() ivi_surface::destroy(); if (QtWayland::ivi_controller_surface::object()) QtWayland::ivi_controller_surface::destroy(0); - - delete m_extendedWindow; } void QWaylandIviSurface::applyConfigure() @@ -44,12 +39,6 @@ void QWaylandIviSurface::applyConfigure() m_window->resizeFromApplyConfigure(m_pendingSize); } -void QWaylandIviSurface::createExtendedSurface(QWaylandWindow *window) -{ - if (window->display()->windowExtension()) - m_extendedWindow = new QWaylandExtendedSurface(window); -} - void QWaylandIviSurface::ivi_surface_configure(int32_t width, int32_t height) { m_pendingSize = {width, height}; diff --git a/src/plugins/shellintegration/ivi-shell/qwaylandivisurface_p.h b/src/plugins/shellintegration/ivi-shell/qwaylandivisurface_p.h index fc97a835a..9747fc7c9 100644 --- a/src/plugins/shellintegration/ivi-shell/qwaylandivisurface_p.h +++ b/src/plugins/shellintegration/ivi-shell/qwaylandivisurface_p.h @@ -14,7 +14,6 @@ namespace QtWaylandClient { class QWaylandWindow; class QWaylandInputDevice; -class QWaylandExtendedSurface; class Q_WAYLANDCLIENT_EXPORT QWaylandIviSurface : public QtWayland::ivi_surface , public QWaylandShellSurface, public QtWayland::ivi_controller_surface @@ -35,7 +34,6 @@ private: void ivi_controller_surface_visibility(int32_t visibility) override; QWaylandWindow *m_window = nullptr; - QWaylandExtendedSurface *m_extendedWindow = nullptr; QSize m_pendingSize = {0, 0}; }; diff --git a/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp b/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp index 4dc93cd98..7ffa41c91 100644 --- a/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp +++ b/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp @@ -8,7 +8,6 @@ #include <QtWaylandClient/private/qwaylandinputdevice_p.h> #include <QtWaylandClient/private/qwaylandabstractdecoration_p.h> #include <QtWaylandClient/private/qwaylandscreen_p.h> -#include <QtWaylandClient/private/qwaylandextendedsurface_p.h> #include <QtCore/QDebug> @@ -21,9 +20,6 @@ QWaylandWlShellSurface::QWaylandWlShellSurface(struct ::wl_shell_surface *shell_ , QtWayland::wl_shell_surface(shell_surface) , m_window(window) { - if (window->display()->windowExtension()) - m_extendedWindow = new QWaylandExtendedSurface(window); - Qt::WindowType type = window->window()->type(); auto *transientParent = window->transientParent(); if (type == Qt::Popup && transientParent && transientParent->wlSurface()) @@ -37,7 +33,6 @@ QWaylandWlShellSurface::QWaylandWlShellSurface(struct ::wl_shell_surface *shell_ QWaylandWlShellSurface::~QWaylandWlShellSurface() { wl_shell_surface_destroy(object()); - delete m_extendedWindow; } bool QWaylandWlShellSurface::resize(QWaylandInputDevice *inputDevice, Qt::Edges edges) @@ -64,36 +59,6 @@ void QWaylandWlShellSurface::setAppId(const QString & appId) return QtWayland::wl_shell_surface::set_class(appId); } -void QWaylandWlShellSurface::raise() -{ - if (m_extendedWindow) - m_extendedWindow->raise(); -} - -void QWaylandWlShellSurface::lower() -{ - if (m_extendedWindow) - m_extendedWindow->lower(); -} - -void QWaylandWlShellSurface::setContentOrientationMask(Qt::ScreenOrientations orientation) -{ - if (m_extendedWindow) - m_extendedWindow->setContentOrientationMask(orientation); -} - -void QWaylandWlShellSurface::setWindowFlags(Qt::WindowFlags flags) -{ - if (m_extendedWindow) - m_extendedWindow->setWindowFlags(flags); -} - -void QWaylandWlShellSurface::sendProperty(const QString &name, const QVariant &value) -{ - if (m_extendedWindow) - m_extendedWindow->updateGenericProperty(name, value); -} - void QWaylandWlShellSurface::applyConfigure() { if ((m_pending.states & (Qt::WindowMaximized|Qt::WindowFullScreen)) diff --git a/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface_p.h b/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface_p.h index 246003028..780f5f326 100644 --- a/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface_p.h +++ b/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface_p.h @@ -48,12 +48,6 @@ public: void setTitle(const QString & title) override; void setAppId(const QString &appId) override; - void raise() override; - void lower() override; - void setContentOrientationMask(Qt::ScreenOrientations orientation) override; - void setWindowFlags(Qt::WindowFlags flags) override; - void sendProperty(const QString &name, const QVariant &value) override; - void applyConfigure() override; bool wantsDecorations() const override; diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp index c7b95e0d0..6e5e47da9 100644 --- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp +++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp @@ -228,7 +228,7 @@ QtWayland::xdg_toplevel::resize_edge QWaylandXdgSurface::Toplevel::convertToResi } QWaylandXdgSurface::Popup::Popup(QWaylandXdgSurface *xdgSurface, QWaylandWindow *parent, - QtWayland::xdg_positioner *positioner) + Positioner *positioner) : m_xdgSurface(xdgSurface) , m_parentXdgSurface(qobject_cast<QWaylandXdgSurface *>(parent->shellSurface())) , m_parent(parent) @@ -293,6 +293,12 @@ void QWaylandXdgSurface::Popup::xdg_popup_popup_done() QWindowSystemInterface::handleCloseEvent(m_xdgSurface->m_window->window()); } +void QWaylandXdgSurface::Popup::xdg_popup_repositioned(uint32_t token) +{ + if (token == m_waitingForRepositionSerial) + m_waitingForReposition = false; +} + QWaylandXdgSurface::QWaylandXdgSurface(QWaylandXdgShell *shell, ::xdg_surface *surface, QWaylandWindow *window) : QWaylandShellSurface(window) , xdg_surface(surface) @@ -380,7 +386,13 @@ bool QWaylandXdgSurface::isExposed() const if (m_toplevel && m_toplevel->m_applied.suspended) return false; - return m_configured || m_pendingConfigureSerial; + // the popup repositioning specification is async + // we need to defer commits between our resize request + // and our new popup position being set + if (m_popup && m_popup->m_waitingForReposition) + return false; + + return m_configured; } bool QWaylandXdgSurface::handleExpose(const QRegion ®ion) @@ -388,11 +400,14 @@ bool QWaylandXdgSurface::handleExpose(const QRegion ®ion) if (!isExposed() && !region.isEmpty()) { return true; } + setWindowGeometry(window()->windowContentGeometry()); return false; } void QWaylandXdgSurface::applyConfigure() { + bool wasExposed = isExposed(); + // It is a redundant ack_configure, so skipped. if (m_pendingConfigureSerial == m_appliedConfigureSerial) return; @@ -405,6 +420,9 @@ void QWaylandXdgSurface::applyConfigure() m_configured = true; ack_configure(m_appliedConfigureSerial); + + if (!wasExposed && isExposed()) + m_window->sendRecursiveExposeEvent(); } bool QWaylandXdgSurface::wantsDecorations() const @@ -487,106 +505,8 @@ void QWaylandXdgSurface::setPopup(QWaylandWindow *parent) { Q_ASSERT(!m_toplevel && !m_popup); - auto positioner = new QtWayland::xdg_positioner(m_shell->m_xdgWmBase->create_positioner()); - // set_popup expects a position relative to the parent - QRect windowGeometry = m_window->windowContentGeometry(); - QMargins windowMargins = m_window->windowContentMargins() - m_window->clientSideMargins(); - QMargins parentMargins = parent->windowContentMargins() - parent->clientSideMargins(); - - // These property overrides may be removed when public API becomes available - QRect placementAnchor = m_window->window()->property("_q_waylandPopupAnchorRect").toRect(); - if (!placementAnchor.isValid()) { - placementAnchor = QRect(m_window->geometry().topLeft() - parent->geometry().topLeft(), QSize(1,1)); - } - placementAnchor.translate(windowMargins.left(), windowMargins.top()); - placementAnchor.translate(-parentMargins.left(), -parentMargins.top()); - - uint32_t anchor = QtWayland::xdg_positioner::anchor_top_right; - const QVariant anchorVariant = m_window->window()->property("_q_waylandPopupAnchor"); - if (anchorVariant.isValid()) { - switch (anchorVariant.value<Qt::Edges>()) { - case Qt::Edges(): - anchor = QtWayland::xdg_positioner::anchor_none; - break; - case Qt::TopEdge: - anchor = QtWayland::xdg_positioner::anchor_top; - break; - case Qt::TopEdge | Qt::RightEdge: - anchor = QtWayland::xdg_positioner::anchor_top_right; - break; - case Qt::RightEdge: - anchor = QtWayland::xdg_positioner::anchor_right; - break; - case Qt::BottomEdge | Qt::RightEdge: - anchor = QtWayland::xdg_positioner::anchor_bottom_right; - break; - case Qt::BottomEdge: - anchor = QtWayland::xdg_positioner::anchor_bottom; - break; - case Qt::BottomEdge | Qt::LeftEdge: - anchor = QtWayland::xdg_positioner::anchor_bottom_left; - break; - case Qt::LeftEdge: - anchor = QtWayland::xdg_positioner::anchor_left; - break; - case Qt::TopEdge | Qt::LeftEdge: - anchor = QtWayland::xdg_positioner::anchor_top_left; - break; - } - } - - uint32_t gravity = QtWayland::xdg_positioner::gravity_bottom_right; - const QVariant popupGravityVariant = m_window->window()->property("_q_waylandPopupGravity"); - if (popupGravityVariant.isValid()) { - switch (popupGravityVariant.value<Qt::Edges>()) { - case Qt::Edges(): - gravity = QtWayland::xdg_positioner::gravity_none; - break; - case Qt::TopEdge: - gravity = QtWayland::xdg_positioner::gravity_top; - break; - case Qt::TopEdge | Qt::RightEdge: - gravity = QtWayland::xdg_positioner::gravity_top_right; - break; - case Qt::RightEdge: - gravity = QtWayland::xdg_positioner::gravity_right; - break; - case Qt::BottomEdge | Qt::RightEdge: - gravity = QtWayland::xdg_positioner::gravity_bottom_right; - break; - case Qt::BottomEdge: - gravity = QtWayland::xdg_positioner::gravity_bottom; - break; - case Qt::BottomEdge | Qt::LeftEdge: - gravity = QtWayland::xdg_positioner::gravity_bottom_left; - break; - case Qt::LeftEdge: - gravity = QtWayland::xdg_positioner::gravity_left; - break; - case Qt::TopEdge | Qt::LeftEdge: - gravity = QtWayland::xdg_positioner::gravity_top_left; - break; - } - } - - uint32_t constraintAdjustment = QtWayland::xdg_positioner::constraint_adjustment_slide_x | QtWayland::xdg_positioner::constraint_adjustment_slide_y; - const QVariant constraintAdjustmentVariant = m_window->window()->property("_q_waylandPopupConstraintAdjustment"); - if (constraintAdjustmentVariant.isValid()) { - constraintAdjustment = constraintAdjustmentVariant.toUInt(); - } - - positioner->set_anchor_rect(placementAnchor.x(), - placementAnchor.y(), - placementAnchor.width(), - placementAnchor.height()); - positioner->set_anchor(anchor); - positioner->set_gravity(gravity); - positioner->set_size(windowGeometry.width(), windowGeometry.height()); - positioner->set_constraint_adjustment(constraintAdjustment); - m_popup = new Popup(this, parent, positioner); - positioner->destroy(); - - delete positioner; + std::unique_ptr<Positioner> positioner = createPositioner(parent); + m_popup = new Popup(this, parent, positioner.get()); } void QWaylandXdgSurface::setGrabPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial) @@ -616,8 +536,6 @@ void QWaylandXdgSurface::xdg_surface_configure(uint32_t serial) if (!m_configured) { // We have to do the initial applyConfigure() immediately, since that is the expose. applyConfigure(); - if (isExposed()) - m_window->sendRecursiveExposeEvent(); } else { // Later configures are probably resizes, so we have to queue them up for a time when we // are not painting to the window. @@ -743,6 +661,124 @@ QString QWaylandXdgSurface::externWindowHandle() return m_toplevel->m_exported->handle(); } +void QWaylandXdgSurface::setWindowPosition(const QPoint &position) +{ + Q_UNUSED(position); + + if (!m_popup) + return; + + if (m_popup->version() < XDG_POPUP_REPOSITIONED_SINCE_VERSION) + return; + + std::unique_ptr<Positioner> positioner = createPositioner(m_window->transientParent()); + m_popup->m_waitingForRepositionSerial++; + m_popup->reposition(positioner->object(), m_popup->m_waitingForRepositionSerial); + m_popup->m_waitingForReposition = true; +} + +std::unique_ptr<QWaylandXdgSurface::Positioner> QWaylandXdgSurface::createPositioner(QWaylandWindow *parent) +{ + std::unique_ptr<Positioner> positioner(new Positioner(m_shell)); + // set_popup expects a position relative to the parent + QRect windowGeometry = m_window->windowContentGeometry(); + QMargins windowMargins = m_window->windowContentMargins() - m_window->clientSideMargins(); + QMargins parentMargins = parent->windowContentMargins() - parent->clientSideMargins(); + + // These property overrides may be removed when public API becomes available + QRect placementAnchor = m_window->window()->property("_q_waylandPopupAnchorRect").toRect(); + if (!placementAnchor.isValid()) { + placementAnchor = QRect(m_window->geometry().topLeft() - parent->geometry().topLeft(), QSize(1,1)); + } + placementAnchor.translate(windowMargins.left(), windowMargins.top()); + placementAnchor.translate(-parentMargins.left(), -parentMargins.top()); + + uint32_t anchor = QtWayland::xdg_positioner::anchor_top_left; + const QVariant anchorVariant = m_window->window()->property("_q_waylandPopupAnchor"); + if (anchorVariant.isValid()) { + switch (anchorVariant.value<Qt::Edges>()) { + case Qt::Edges(): + anchor = QtWayland::xdg_positioner::anchor_none; + break; + case Qt::TopEdge: + anchor = QtWayland::xdg_positioner::anchor_top; + break; + case Qt::TopEdge | Qt::RightEdge: + anchor = QtWayland::xdg_positioner::anchor_top_right; + break; + case Qt::RightEdge: + anchor = QtWayland::xdg_positioner::anchor_right; + break; + case Qt::BottomEdge | Qt::RightEdge: + anchor = QtWayland::xdg_positioner::anchor_bottom_right; + break; + case Qt::BottomEdge: + anchor = QtWayland::xdg_positioner::anchor_bottom; + break; + case Qt::BottomEdge | Qt::LeftEdge: + anchor = QtWayland::xdg_positioner::anchor_bottom_left; + break; + case Qt::LeftEdge: + anchor = QtWayland::xdg_positioner::anchor_left; + break; + case Qt::TopEdge | Qt::LeftEdge: + anchor = QtWayland::xdg_positioner::anchor_top_left; + break; + } + } + + uint32_t gravity = QtWayland::xdg_positioner::gravity_bottom_right; + const QVariant popupGravityVariant = m_window->window()->property("_q_waylandPopupGravity"); + if (popupGravityVariant.isValid()) { + switch (popupGravityVariant.value<Qt::Edges>()) { + case Qt::Edges(): + gravity = QtWayland::xdg_positioner::gravity_none; + break; + case Qt::TopEdge: + gravity = QtWayland::xdg_positioner::gravity_top; + break; + case Qt::TopEdge | Qt::RightEdge: + gravity = QtWayland::xdg_positioner::gravity_top_right; + break; + case Qt::RightEdge: + gravity = QtWayland::xdg_positioner::gravity_right; + break; + case Qt::BottomEdge | Qt::RightEdge: + gravity = QtWayland::xdg_positioner::gravity_bottom_right; + break; + case Qt::BottomEdge: + gravity = QtWayland::xdg_positioner::gravity_bottom; + break; + case Qt::BottomEdge | Qt::LeftEdge: + gravity = QtWayland::xdg_positioner::gravity_bottom_left; + break; + case Qt::LeftEdge: + gravity = QtWayland::xdg_positioner::gravity_left; + break; + case Qt::TopEdge | Qt::LeftEdge: + gravity = QtWayland::xdg_positioner::gravity_top_left; + break; + } + } + + uint32_t constraintAdjustment = QtWayland::xdg_positioner::constraint_adjustment_slide_x | QtWayland::xdg_positioner::constraint_adjustment_slide_y; + const QVariant constraintAdjustmentVariant = m_window->window()->property("_q_waylandPopupConstraintAdjustment"); + if (constraintAdjustmentVariant.isValid()) { + constraintAdjustment = constraintAdjustmentVariant.toUInt(); + } + + positioner->set_anchor_rect(placementAnchor.x(), + placementAnchor.y(), + placementAnchor.width(), + placementAnchor.height()); + positioner->set_anchor(anchor); + positioner->set_gravity(gravity); + positioner->set_size(windowGeometry.width(), windowGeometry.height()); + positioner->set_constraint_adjustment(constraintAdjustment); + return positioner; +} + + QWaylandXdgShell::QWaylandXdgShell(QWaylandDisplay *display, QtWayland::xdg_wm_base *xdgWmBase) : m_display(display), m_xdgWmBase(xdgWmBase) { @@ -774,6 +810,16 @@ void QWaylandXdgShell::handleRegistryGlobal(void *data, wl_registry *registry, u } } +QWaylandXdgSurface::Positioner::Positioner(QWaylandXdgShell *xdgShell) + : QtWayland::xdg_positioner(xdgShell->m_xdgWmBase->create_positioner()) +{ +} + +QWaylandXdgSurface::Positioner::~Positioner() +{ + destroy(); +} + } QT_END_NAMESPACE diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h index fa33259f7..d18ce4d72 100644 --- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h +++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h @@ -70,6 +70,7 @@ public: void setAlertState(bool enabled) override; bool isAlertState() const override { return m_alertState; } QString externWindowHandle() override; + void setWindowPosition(const QPoint &position) override; void setSizeHints(); @@ -115,9 +116,15 @@ private: QScopedPointer<QWaylandXdgDialogV1> m_xdgDialog; }; + class Positioner : public QtWayland::xdg_positioner { + public: + Positioner(QWaylandXdgShell *xdgShell); + ~Positioner() override; + }; + class Popup : public QtWayland::xdg_popup { public: - Popup(QWaylandXdgSurface *xdgSurface, QWaylandWindow *parent, QtWayland::xdg_positioner *positioner); + Popup(QWaylandXdgSurface *xdgSurface, QWaylandWindow *parent, Positioner *positioner); ~Popup() override; void applyConfigure(); @@ -126,6 +133,7 @@ private: void grab(QWaylandInputDevice *seat, uint serial); void xdg_popup_configure(int32_t x, int32_t y, int32_t width, int32_t height) override; void xdg_popup_popup_done() override; + void xdg_popup_repositioned(uint32_t token) override; QWaylandXdgSurface *m_xdgSurface = nullptr; QWaylandXdgSurface *m_parentXdgSurface = nullptr; @@ -133,11 +141,14 @@ private: bool m_grabbing = false; QRect m_pendingGeometry; + bool m_waitingForReposition = false; + uint32_t m_waitingForRepositionSerial = 0; }; void setToplevel(); void setPopup(QWaylandWindow *parent); void setGrabPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial); + std::unique_ptr<Positioner> createPositioner(QWaylandWindow *parent); QWaylandXdgShell *m_shell = nullptr; QWaylandWindow *m_window = nullptr; diff --git a/src/shared/qwaylandinputmethodeventbuilder.cpp b/src/shared/qwaylandinputmethodeventbuilder.cpp index 0f07a6958..fc422ef04 100644 --- a/src/shared/qwaylandinputmethodeventbuilder.cpp +++ b/src/shared/qwaylandinputmethodeventbuilder.cpp @@ -278,10 +278,10 @@ int QWaylandInputMethodEventBuilder::indexFromWayland(const QString &text, int l if (length < 0) { const QByteArray &utf8 = QStringView{text}.left(base).toUtf8(); - return QString::fromUtf8(utf8.left(qMax(utf8.size() + length, 0))).size(); + return QString::fromUtf8(utf8.first(qMax(utf8.size() + length, 0))).size(); } else { const QByteArray &utf8 = QStringView{text}.mid(base).toUtf8(); - return QString::fromUtf8(utf8.left(length)).size() + base; + return QString::fromUtf8(utf8.first(qMin(length, utf8.size()))).size() + base; } } diff --git a/tests/auto/client/client/tst_client.cpp b/tests/auto/client/client/tst_client.cpp index 253a98b73..fa4a81e19 100644 --- a/tests/auto/client/client/tst_client.cpp +++ b/tests/auto/client/client/tst_client.cpp @@ -465,7 +465,6 @@ void tst_WaylandClient::mouseDrag() void tst_WaylandClient::dontCrashOnMultipleCommits() { - QSKIP("This test is flaky. See QTBUG-68756."); auto window = new TestWindow(); window->show(); diff --git a/tests/auto/client/shared/coreprotocol.cpp b/tests/auto/client/shared/coreprotocol.cpp index 833ad4b09..5d9c4e9a3 100644 --- a/tests/auto/client/shared/coreprotocol.cpp +++ b/tests/auto/client/shared/coreprotocol.cpp @@ -77,8 +77,10 @@ void Surface::surface_attach(Resource *resource, wl_resource *buffer, int32_t x, m_image = QImage(); } else { QPoint offset(x, y); + if (resource->version() < 5) + m_pending.commitSpecific.attachOffset = offset; + m_pending.buffer = fromResource<Buffer>(buffer); - m_pending.commitSpecific.attachOffset = offset; m_pending.commitSpecific.attached = true; emit attach(buffer, offset); @@ -143,6 +145,13 @@ void Surface::surface_frame(Resource *resource, uint32_t callback) } } +void Surface::surface_offset(Resource *resource, int32_t x, int32_t y) +{ + Q_UNUSED(resource); + QPoint offset(x, y); + m_pending.commitSpecific.attachOffset = offset; +} + bool WlCompositor::isClean() { for (auto *surface : std::as_const(m_surfaces)) { if (!CursorRole::fromSurface(surface)) { diff --git a/tests/auto/client/shared/coreprotocol.h b/tests/auto/client/shared/coreprotocol.h index 0f59441a3..bea39dd13 100644 --- a/tests/auto/client/shared/coreprotocol.h +++ b/tests/auto/client/shared/coreprotocol.h @@ -124,6 +124,7 @@ protected: void surface_set_buffer_scale(Resource *resource, int32_t scale) override; void surface_commit(Resource *resource) override; void surface_frame(Resource *resource, uint32_t callback) override; + void surface_offset(Resource *resource, int32_t x, int32_t y) override; }; class Region : public QtWaylandServer::wl_region @@ -145,7 +146,7 @@ class WlCompositor : public Global, public QtWaylandServer::wl_compositor { Q_OBJECT public: - explicit WlCompositor(CoreCompositor *compositor, int version = 4) + explicit WlCompositor(CoreCompositor *compositor, int version = 6) : QtWaylandServer::wl_compositor(compositor->m_display, version) , m_compositor(compositor) {} diff --git a/tests/auto/client/xdgdecorationv1/tst_xdgdecorationv1.cpp b/tests/auto/client/xdgdecorationv1/tst_xdgdecorationv1.cpp index 54b15b3bf..5ee856944 100644 --- a/tests/auto/client/xdgdecorationv1/tst_xdgdecorationv1.cpp +++ b/tests/auto/client/xdgdecorationv1/tst_xdgdecorationv1.cpp @@ -111,7 +111,7 @@ public: explicit XdgDecorationCompositor() { exec([this] { - m_config.autoConfigure = true; + m_config.autoConfigure = false; add<XdgDecorationManagerV1>(xdgDecorationVersion); }); } diff --git a/tests/manual/import-qml-modules/CMakeLists.txt b/tests/manual/import-qml-modules/CMakeLists.txt new file mode 100644 index 000000000..c99218203 --- /dev/null +++ b/tests/manual/import-qml-modules/CMakeLists.txt @@ -0,0 +1,25 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) + +project(import_wayland_qml_modules VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.4 REQUIRED + COMPONENTS + Quick + WaylandCompositor + WaylandCompositorIviapplication + WaylandCompositorPresentationTime + WaylandCompositorWLShell + WaylandCompositorXdgShell +) + +qt_standard_project_setup() + +qt_add_qml_module(import_wayland_qml_modules + URI Qml + QML_FILES Main.qml +) diff --git a/tests/manual/import-qml-modules/Main.qml b/tests/manual/import-qml-modules/Main.qml new file mode 100644 index 000000000..07b8bc482 --- /dev/null +++ b/tests/manual/import-qml-modules/Main.qml @@ -0,0 +1,18 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +import QtQuick +import QtWayland.Compositor.IviApplication +import QtWayland.Compositor.PresentationTime +import QtWayland.Compositor.QtShell +import QtWayland.Compositor.WlShell +import QtWayland.Compositor.XdgShell + + +Item { + property var p1: IviApplication {} + property var p2: PresentationTime {} + property var p3: QtShellChrome {} + property var p4: WlShellSurface {} + property var p5: XdgPopup {} +} diff --git a/tests/manual/import-qml-modules/main.cpp b/tests/manual/import-qml-modules/main.cpp new file mode 100644 index 000000000..1b0b801ff --- /dev/null +++ b/tests/manual/import-qml-modules/main.cpp @@ -0,0 +1,19 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <QtGui/QGuiApplication> +#include <QtQml/QQmlApplicationEngine> + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + const QUrl url(QStringLiteral("qrc:/Qml/Main.qml")); + QObject::connect( + &engine, &QQmlApplicationEngine::objectCreationFailed, &app, + []() { QCoreApplication::exit(-1); }, Qt::QueuedConnection); + engine.load(url); + + return app.exec(); +} |