diff options
Diffstat (limited to 'src')
56 files changed, 843 insertions, 1528 deletions
diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index 4916af81e..6bb8a891f 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 @@ -42,6 +41,7 @@ qt_internal_add_module(WaylandClient qwaylandinputmethodcontext.cpp qwaylandinputmethodcontext_p.h qwaylandintegration.cpp qwaylandintegration_p.h qwaylandnativeinterface.cpp qwaylandnativeinterface_p.h + qwaylandplatformservices.cpp qwaylandplatformservices_p.h qwaylandpointergestures.cpp qwaylandpointergestures_p.h qwaylandqtkey.cpp qwaylandqtkey_p.h qwaylandscreen.cpp qwaylandscreen_p.h diff --git a/src/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/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp index 265f0bb3f..e6ed0772f 100644 --- a/src/client/qwaylanddisplay.cpp +++ b/src/client/qwaylanddisplay.cpp @@ -312,7 +312,7 @@ QWaylandClientBufferIntegration * QWaylandDisplay::clientBufferIntegration() con QWaylandWindowManagerIntegration *QWaylandDisplay::windowManagerIntegration() const { - return mWindowManagerIntegration.data(); + return mGlobals.windowManagerIntegration.get(); } QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration) @@ -335,8 +335,6 @@ void QWaylandDisplay::setupConnection() struct ::wl_registry *registry = wl_display_get_registry(mDisplay); init(registry); - mWindowManagerIntegration.reset(new QWaylandWindowManagerIntegration(this)); - #if QT_CONFIG(xkbcommon) mXkbContext.reset(xkb_context_new(XKB_CONTEXT_NO_FLAGS)); if (!mXkbContext) @@ -373,7 +371,6 @@ QWaylandDisplay::~QWaylandDisplay(void) // Reset the globals manually since they need to be destroyed before the wl_display mGlobals = {}; - mWindowManagerIntegration.reset(); if (object()) wl_registry_destroy(object()); @@ -781,6 +778,9 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin mGlobals.xdgToplevelDragManager.reset( new WithDestructor<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 +891,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..2fd176d84 100644 --- a/src/client/qwaylanddisplay_p.h +++ b/src/client/qwaylanddisplay_p.h @@ -316,8 +316,6 @@ private: QScopedPointer<QWaylandCursor> mCursor; #endif - QScopedPointer<QWaylandWindowManagerIntegration> mWindowManagerIntegration; - struct GlobalHolder { std::unique_ptr<QtWayland::wl_compositor> compositor; @@ -346,6 +344,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/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/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/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/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/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/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/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; } } |