diff options
Diffstat (limited to 'src/imports')
47 files changed, 3678 insertions, 2420 deletions
diff --git a/src/imports/CMakeLists.txt b/src/imports/CMakeLists.txt new file mode 100644 index 000000000..417b6bce8 --- /dev/null +++ b/src/imports/CMakeLists.txt @@ -0,0 +1,12 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +# Generated from imports.pro. + +if(TARGET Qt::Quick AND TARGET Qt::WaylandCompositor) + add_subdirectory(compositor-extensions) +endif() +if(QT_FEATURE_opengl AND TARGET Qt::Quick AND TARGET Qt::WaylandClient AND TARGET Qt::WaylandCompositor) + add_subdirectory(texture-sharing) + add_subdirectory(texture-sharing-extension) +endif() diff --git a/src/imports/compositor-extensions/CMakeLists.txt b/src/imports/compositor-extensions/CMakeLists.txt new file mode 100644 index 000000000..28d187ab4 --- /dev/null +++ b/src/imports/compositor-extensions/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +# Generated from compositor-extensions.pro. + +add_subdirectory(xdgshell) +add_subdirectory(iviapplication) +add_subdirectory(wlshell) +add_subdirectory(qtshell) +add_subdirectory(presentationtime) diff --git a/src/imports/compositor-extensions/iviapplication/CMakeLists.txt b/src/imports/compositor-extensions/iviapplication/CMakeLists.txt new file mode 100644 index 000000000..a2899fa27 --- /dev/null +++ b/src/imports/compositor-extensions/iviapplication/CMakeLists.txt @@ -0,0 +1,28 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +# Generated from iviapplication.pro. + +##################################################################### +## qwaylandcompositoriviapplicationplugin Plugin: +##################################################################### + +qt_internal_add_qml_module(WaylandCompositorIviapplication + URI "QtWayland.Compositor.IviApplication" + VERSION "${PROJECT_VERSION}" + SOURCES + 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) + +#### Keys ignored in scope 1:.:.:iviapplication.pro:<TRUE>: +# CXX_MODULE = "qml" +# QML_IMPORT_VERSION = "$$QT_VERSION" +# TARGETPATH = "QtWayland/Compositor/IviApplication" 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/presentationtime/CMakeLists.txt b/src/imports/compositor-extensions/presentationtime/CMakeLists.txt new file mode 100644 index 000000000..2a817c012 --- /dev/null +++ b/src/imports/compositor-extensions/presentationtime/CMakeLists.txt @@ -0,0 +1,29 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +##################################################################### +## 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}" + SOURCES + 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 + WaylandCompositor) diff --git a/src/imports/compositor-extensions/presentationtime/qwaylandcompositorpresentationtimeforeign.cpp b/src/imports/compositor-extensions/presentationtime/qwaylandcompositorpresentationtimeforeign.cpp new file mode 100644 index 000000000..05807e74f --- /dev/null +++ b/src/imports/compositor-extensions/presentationtime/qwaylandcompositorpresentationtimeforeign.cpp @@ -0,0 +1,32 @@ +// Copyright (C) 2021 LG Electronics Inc. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "qwaylandcompositorpresentationtimeforeign_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmlmodule QtWayland.Compositor.PresentationTime + \title Qt Wayland Presentation Time Extension + \ingroup qmlmodules + \since 6.3 + \brief Provides tracking the timing when a frame is presented on screen. + + \section2 Summary + The PresentationTime extension provides a way to track rendering timing + for a surface. Client can request feedbacks associated with a surface, + then compositor send events for the feedback with the time when the surface + is presented on-screen. + + PresentationTime corresponds to the Wayland \c wp_presentation interface. + + \section2 Usage + To use this module, import it like this: + \qml + import QtWayland.Compositor.PresentationTime + \endqml +*/ + +QT_END_NAMESPACE + +#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 new file mode 100644 index 000000000..429d0c26b --- /dev/null +++ b/src/imports/compositor-extensions/qtshell/CMakeLists.txt @@ -0,0 +1,33 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +##################################################################### +## qwaylandqtshellplugin Plugin: +##################################################################### + +qt_internal_add_qml_module(WaylandCompositorQtShell + URI "QtWayland.Compositor.QtShell" + VERSION "${PROJECT_VERSION}" + PLUGIN_TARGET WaylandCompositorQtShell + SOURCES + 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 + Qt::Quick + Qt::QuickPrivate + Qt::WaylandCompositor + Qt::WaylandCompositorPrivate + PAST_MAJOR_VERSIONS 1 +) + +qt6_generate_wayland_protocol_server_sources(WaylandCompositorQtShell + FILES + ${CMAKE_CURRENT_SOURCE_DIR}/../../../extensions/qt-shell-unstable-v1.xml +) + +qt_internal_add_autogen_sync_header_dependencies(WaylandCompositorQtShell WaylandCompositor) diff --git a/src/imports/compositor-extensions/qtshell/qwaylandqtshell.cpp b/src/imports/compositor-extensions/qtshell/qwaylandqtshell.cpp new file mode 100644 index 000000000..0e918e734 --- /dev/null +++ b/src/imports/compositor-extensions/qtshell/qwaylandqtshell.cpp @@ -0,0 +1,847 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "qwaylandqtshell.h" +#include "qwaylandqtshell_p.h" +#include "qwaylandqtshellchrome.h" + +#include <QtWaylandCompositor/QWaylandCompositor> +#include <QtWaylandCompositor/QWaylandSurface> +#include "qwaylandqtshell.h" +#include <QtWaylandCompositor/QWaylandResource> + +#if QT_CONFIG(wayland_compositor_quick) +# include "qwaylandqtshellintegration_p.h" +#endif + +#include <QtWaylandCompositor/QWaylandResource> +#include <QDebug> +#include <compositor/compositor_api/qwaylandseat.h> + +#include <QtWaylandCompositor/private/qwaylandutils_p.h> + +QT_BEGIN_NAMESPACE + +/*! + * \qmltype QtShell + * \instantiates QWaylandQtShell + * \inqmlmodule QtWayland.Compositor.QtShell + * \since 6.3 + * \brief Provides a shell extension for Qt applications running on a Qt Wayland Compositor. + * + * 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. + * + * \qml + * import QtWayland.Compositor.QtShell + * + * WaylandCompositor { + * property ListModel shellSurfaces: ListModel {} + * QtShell { + * onQtShellSurfaceCreated: { + * shellSurfaces.append({shellSurface: qtShellSurface}) + * } + * } + * } + * \endqml + */ +QWaylandQtShell::QWaylandQtShell() + : QWaylandCompositorExtensionTemplate<QWaylandQtShell>(*new QWaylandQtShellPrivate()) +{ +} + +QWaylandQtShell::QWaylandQtShell(QWaylandCompositor *compositor) + : QWaylandCompositorExtensionTemplate<QWaylandQtShell>(compositor, *new QWaylandQtShellPrivate()) +{ +} + +bool QWaylandQtShell::moveChromeToFront(QWaylandQtShellChrome *chrome) +{ + Q_D(QWaylandQtShell); + for (int i = 0; i < d->m_chromes.size(); ++i) { + if (d->m_chromes.at(i) == chrome) { + if (i > 0) { + QWaylandQtShellChrome *currentActive = d->m_chromes.first(); + d->m_chromes.move(i, 0); + chrome->activate(); + currentActive->deactivate(); + } + return true; + } + } + + return false; +} + +void QWaylandQtShell::registerChrome(QWaylandQtShellChrome *chrome) +{ + Q_D(QWaylandQtShell); + if (moveChromeToFront(chrome)) + return; + + QWaylandQtShellChrome *currentActive = d->m_chromes.isEmpty() ? nullptr : d->m_chromes.first(); + + d->m_chromes.prepend(chrome); + chrome->activate(); + + if (currentActive != nullptr) + currentActive->deactivate(); + + connect(chrome, &QWaylandQtShellChrome::activated, this, &QWaylandQtShell::chromeActivated); + connect(chrome, &QWaylandQtShellChrome::deactivated, this, &QWaylandQtShell::chromeDeactivated); +} + +void QWaylandQtShell::unregisterChrome(QWaylandQtShellChrome *chrome) +{ + Q_D(QWaylandQtShell); + + chrome->disconnect(this); + int index = d->m_chromes.indexOf(chrome); + if (index >= 0) { + d->m_chromes.removeAt(index); + if (index == 0 && d->m_chromes.size() > 0) + d->m_chromes.at(0)->activate(); + } +} + +void QWaylandQtShell::chromeActivated() +{ + QWaylandQtShellChrome *c = qobject_cast<QWaylandQtShellChrome *>(sender()); + if (c != nullptr) { + moveChromeToFront(c); + } +} + +void QWaylandQtShell::chromeDeactivated() +{ + Q_D(QWaylandQtShell); + QWaylandQtShellChrome *c = qobject_cast<QWaylandQtShellChrome *>(sender()); + if (d->m_chromes.size() > 1 && d->m_chromes.at(0) == c) { + d->m_chromes.move(0, 1); + d->m_chromes.at(0)->activate(); + } else if (d->m_chromes.size() == 1) { // One window must be active + d->m_chromes.at(0)->activate(); + } +} + +void QWaylandQtShell::initialize() +{ + Q_D(QWaylandQtShell); + QWaylandCompositorExtensionTemplate::initialize(); + + QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(extensionContainer()); + if (!compositor) { + qWarning() << "Failed to find QWaylandCompositor when initializing QWaylandQtShell"; + return; + } + + d->init(compositor->display(), 1); +} + +const struct wl_interface *QWaylandQtShell::interface() +{ + return QWaylandQtShellPrivate::interface(); +} + +/*! + * \internal + */ +QByteArray QWaylandQtShell::interfaceName() +{ + return QWaylandQtShellPrivate::interfaceName(); +} + +/*! + * \qmlsignal void QtShell::qtShellSurfaceRequested(WaylandSurface surface, WaylandResource resource) + * + * This signal is emitted when the client has requested a QtShellSurface to be associated + * with \a surface. The handler for this signal is expected to create the QtShellSurface for + * \a resource and initialize it within the scope of the signal emission. If no QtShellSurface is + * created, a default one will be created instead. + */ + +/*! + * \qmlsignal void QtShell::qtShellSurfaceCreated(QtShellSurface *qtShellSurface) + * + * This signal is emitted when an QtShellSurface has been created. The supplied \a qtShellSurface is + * most commonly used to instantiate a ShellSurfaceItem. + */ + +QWaylandQtShellPrivate::QWaylandQtShellPrivate() +{ +} + +void QWaylandQtShellPrivate::unregisterQtShellSurface(QWaylandQtShellSurface *qtShellSurface) +{ + Q_UNUSED(qtShellSurface) +} + +void QWaylandQtShellPrivate::zqt_shell_v1_surface_create(QtWaylandServer::zqt_shell_v1::Resource *resource, wl_resource *surfaceResource, uint32_t id) +{ + Q_Q(QWaylandQtShell); + QWaylandSurface *surface = QWaylandSurface::fromResource(surfaceResource); + + if (!surface->setRole(QWaylandQtShellSurface::role(), resource->handle, ZQT_SHELL_V1_ERROR_ROLE)) + return; + + QWaylandResource qtShellSurfaceResource(wl_resource_create(resource->client(), &zqt_shell_surface_v1_interface, + wl_resource_get_version(resource->handle), id)); + + emit q->qtShellSurfaceRequested(surface, qtShellSurfaceResource); + + QWaylandQtShellSurface *qtShellSurface = QWaylandQtShellSurface::fromResource(qtShellSurfaceResource.resource()); + + if (!qtShellSurface) + qtShellSurface = new QWaylandQtShellSurface(q, surface, qtShellSurfaceResource); + + emit q->qtShellSurfaceCreated(qtShellSurface); +} + +QWaylandSurfaceRole QWaylandQtShellSurfacePrivate::s_role("qt_shell_surface"); + +/*! + * \qmltype QtShellSurface + * \instantiates QWaylandQtShellSurface + * \inqmlmodule QtWayland.Compositor.QtShell + * \since 6.3 + * \brief Provides a simple way to identify and resize a surface. + * + * This type is part of the \l{QtShell} extension and provides a way to extend + * the functionality of an existing WaylandSurface with window management functionality. + * + * The QtShellSurface type holds the core functionality needed to create a compositor that supports + * the QtShell extension. It can be used directly, or via the QtShellChrome type, depending on what + * the needs of the compositor are. The QtShellChrome type has default behaviors and convenience + * APIs for working with QtShellSurface objects. + */ + +/*! + \qmlsignal void QtShellSurface::startMove() + + The client has requested an interactive move operation in the compositor by calling + \l{QWindow::startSystemMove()}. + + \sa capabilities +*/ + +/*! + \qmlsignal void QtShellSurface::startResize(enum edges) + + The client has requested an interactive resize operation in the compositor by calling + \l{QWindow::startSystemResize()}. + + The \a edges provides information about which edge of the window should be moved during the + resize. It is a mask of the following values: + \list + \li Qt.TopEdge + \li Qt.LeftEdge + \li Qt.RightEdge + \li Qt.BottomEdge + \endlist + + \sa capabilities +*/ + +QWaylandQtShellSurface::QWaylandQtShellSurface() + : QWaylandShellSurfaceTemplate<QWaylandQtShellSurface>(*new QWaylandQtShellSurfacePrivate()) +{ +} + +QWaylandQtShellSurface::QWaylandQtShellSurface(QWaylandQtShell *application, QWaylandSurface *surface, const QWaylandResource &resource) + : QWaylandShellSurfaceTemplate<QWaylandQtShellSurface>(*new QWaylandQtShellSurfacePrivate()) +{ + initialize(application, surface, resource); +} + +/*! + * \qmlmethod void QtShellSurface::initialize(QtShell qtShell, WaylandSurface surface, WaylandResource resource) + * + * Initializes the QtShellSurface, associating it with the given \a qtShell, \a surface, and + * \a resource. + */ +void QWaylandQtShellSurface::initialize(QWaylandQtShell *qtShell, QWaylandSurface *surface, const QWaylandResource &resource) +{ + Q_D(QWaylandQtShellSurface); + + d->m_qtShell = qtShell; + d->m_surface = surface; + + connect(d->m_surface, &QWaylandSurface::damaged, this, &QWaylandQtShellSurface::surfaceCommitted); + + d->init(resource.resource()); + setExtensionContainer(surface); + + emit surfaceChanged(); + + QWaylandCompositorExtension::initialize(); +} + +/*! + * \qmlproperty WaylandSurface QtShellSurface::surface + * + * This property holds the surface associated with this QtShellSurface. + */ +QWaylandSurface *QWaylandQtShellSurface::surface() const +{ + Q_D(const QWaylandQtShellSurface); + return d->m_surface; +} + +QWaylandQtShell *QWaylandQtShellSurface::shell() const +{ + Q_D(const QWaylandQtShellSurface); + return d->m_qtShell; +} + +/*! + * \qmlproperty point QtShellSurface::windowPosition + * + * This property holds the position of the shell surface relative to its output. + */ +QPoint QWaylandQtShellSurface::windowPosition() const +{ + Q_D(const QWaylandQtShellSurface); + return d->m_windowGeometry.topLeft(); +} + +void QWaylandQtShellSurface::setWindowPosition(const QPoint &position) +{ + Q_D(QWaylandQtShellSurface); + + // We don't care about the ack in this case, so use UINT_MAX as serial + d->send_set_position(UINT32_MAX, position.x(), position.y()); + d->send_configure(UINT32_MAX); + + d->m_windowGeometry.moveTopLeft(position); + d->m_positionSet = true; + emit positionAutomaticChanged(); + emit windowGeometryChanged(); +} + +/*! + * \qmlproperty rect QtShellSurface::windowGeometry + * + * This property holds the window geometry of the shell surface. + */ +QRect QWaylandQtShellSurface::windowGeometry() const +{ + Q_D(const QWaylandQtShellSurface); + return d->m_windowGeometry; +} + +/*! + * \qmlproperty size QtShellSurface::minimumSize + * + * The minimum size of the window if the client has specified one. Otherwise an invalid size. + */ +QSize QWaylandQtShellSurface::minimumSize() const +{ + Q_D(const QWaylandQtShellSurface); + return d->m_minimumSize; +} + +/*! + * \qmlproperty size QtShellSurface::maximumSize + * + * The maximum size of the window if the client has specified one. Otherwise an invalid size. + */ +QSize QWaylandQtShellSurface::maximumSize() const +{ + Q_D(const QWaylandQtShellSurface); + return d->m_maximumSize; +} + +/*! + * \qmlmethod void QtShellSurface::requestWindowGeometry(int windowState, rect windowGeometry) + * + * Requests a new \a windowState and \a windowGeometry for the QtShellSurface. The state and + * geometry is updated when the client has acknowledged the request (at which point it is safe to + * assume that the surface's buffer has been resized if necessary). + */ +void QWaylandQtShellSurface::requestWindowGeometry(uint windowState, const QRect &windowGeometry) +{ + Q_D(QWaylandQtShellSurface); + if (!windowGeometry.isValid()) + return; + + d->configure(windowState, windowGeometry); +} + +void QWaylandQtShellSurfacePrivate::configure(uint windowState, const QRect &newGeometry) +{ + QWaylandCompositor *compositor = m_surface != nullptr ? m_surface->compositor() : nullptr; + if (!compositor) { + qWarning() << "Failed to find QWaylandCompositor when configuring QWaylandQtShell"; + return; + } + + uint32_t serial = compositor->nextSerial(); + m_pendingConfigures[serial] = qMakePair(windowState, newGeometry); + + send_set_position(serial, newGeometry.x(), newGeometry.y()); + send_resize(serial, newGeometry.width(), newGeometry.height()); + send_set_window_state(serial, windowState & ~Qt::WindowActive); + send_configure(serial); +} + +void QWaylandQtShellSurface::setFrameMargins(const QMargins &margins) +{ + Q_D(QWaylandQtShellSurface); + if (d->m_frameMargins == margins) + return; + + d->m_frameMargins = margins; + d->updateFrameMargins(); + + emit frameMarginChanged(); +} + +/*! + * \qmlproperty int QtShellSurface::frameMarginLeft + * + * This holds the window frame margin to the left of the surface. + */ +void QWaylandQtShellSurface::setFrameMarginLeft(int left) +{ + Q_D(QWaylandQtShellSurface); + if (d->m_frameMargins.left() == left) + return; + + d->m_frameMargins.setLeft(left); + d->updateFrameMargins(); + + emit frameMarginChanged(); +} + +int QWaylandQtShellSurface::frameMarginLeft() const +{ + Q_D(const QWaylandQtShellSurface); + return d->m_frameMargins.left(); +} + +/*! + * \qmlproperty int QtShellSurface::frameMarginRight + * + * This holds the window frame margin to the right of the surface. + */ +void QWaylandQtShellSurface::setFrameMarginRight(int right) +{ + Q_D(QWaylandQtShellSurface); + if (d->m_frameMargins.right() == right) + return; + + d->m_frameMargins.setRight(right); + d->updateFrameMargins(); + + emit frameMarginChanged(); +} + +int QWaylandQtShellSurface::frameMarginRight() const +{ + Q_D(const QWaylandQtShellSurface); + return d->m_frameMargins.right(); +} + +/*! + * \qmlproperty int QtShellSurface::frameMarginTop + * + * This holds the window frame margin above the surface. + */ + +void QWaylandQtShellSurface::setFrameMarginTop(int top) +{ + Q_D(QWaylandQtShellSurface); + if (d->m_frameMargins.top() == top) + return; + d->m_frameMargins.setTop(top); + d->updateFrameMargins(); + + emit frameMarginChanged(); +} + +int QWaylandQtShellSurface::frameMarginTop() const +{ + Q_D(const QWaylandQtShellSurface); + return d->m_frameMargins.top(); +} + +/*! + * \qmlproperty int QtShellSurface::frameMarginBottom + * + * This holds the window frame margin below the surface. + */ +void QWaylandQtShellSurface::setFrameMarginBottom(int bottom) +{ + Q_D(QWaylandQtShellSurface); + if (d->m_frameMargins.bottom() == bottom) + return; + d->m_frameMargins.setBottom(bottom); + d->updateFrameMargins(); + + emit frameMarginChanged(); +} + +bool QWaylandQtShellSurface::positionAutomatic() const +{ + Q_D(const QWaylandQtShellSurface); + return !d->m_positionSet; +} + +int QWaylandQtShellSurface::frameMarginBottom() const +{ + Q_D(const QWaylandQtShellSurface); + return d->m_frameMargins.bottom(); +} + +/*! + * \qmlproperty int QtShellSurface::windowFlags + * + * This property holds the window flags of the QtShellSurface. + */ +uint QWaylandQtShellSurface::windowFlags() const +{ + Q_D(const QWaylandQtShellSurface); + return d->m_windowFlags; +} + +/*! + * \qmlmethod void QtShellSurface::sendClose() + * + * Requests that the client application closes itself. + */ +void QWaylandQtShellSurface::sendClose() +{ + Q_D(QWaylandQtShellSurface); + d->send_close(); +} + +/*! + * \qmlproperty string QtShellSurface::windowTitle + * + * This property holds the window title of the QtShellSurface. + */ +QString QWaylandQtShellSurface::windowTitle() const +{ + Q_D(const QWaylandQtShellSurface); + return d->m_windowTitle; +} + +/*! + * \qmlproperty bool QtShellSurface::active + * + * This property holds whether the surface is currently considered active. + * + * \note There are no restrictions in QtShellSurface that prevents multiple surfaces from being + * active simultaneously. Such logic must either be implemented by the compositor itself, or by + * using the QtShellChrome type, which will automatically manage the activation state of surfaces. + */ +void QWaylandQtShellSurface::setActive(bool active) +{ + Q_D(QWaylandQtShellSurface); + if (d->m_active == active) + return; + + d->m_active = active; + QWaylandCompositor *compositor = d->m_surface ? d->m_surface->compositor() : nullptr; + QWaylandSeat *seat = compositor ? compositor->defaultSeat() : nullptr; + if (seat && active) + seat->setKeyboardFocus(surface()); + emit activeChanged(); +} + +bool QWaylandQtShellSurface::active() const +{ + Q_D(const QWaylandQtShellSurface); + return d->m_active; +} + +/*! + * \qmlproperty enum QtShellSurface::capabilities + * + * This property holds the capabilities of the compositor. By default, no special capabilities are + * enabled. + * + * \list + * \li QtShellSurface.InteractiveMove The client can trigger a server-side interactive move + * operation using \l{QWindow::startSystemMove()}. The compositor will be notified of this + * through the \l{startMove()} signal. + * \li QtShellSurface.InteractiveResize The client can trigger a server-side interactive resize + * operation using \l{QWindow::startSystemResize()}. The compositor will be notified of this + * through the \l{startResize()} signal. + * \endlist + */ +void QWaylandQtShellSurface::setCapabilities(CapabilityFlags capabilities) +{ + Q_D(QWaylandQtShellSurface); + if (d->m_capabilities == capabilities) + return; + + d->m_capabilities = capabilities; + d->send_set_capabilities(capabilities); + + emit capabilitiesChanged(); +} + +QWaylandQtShellSurface::CapabilityFlags QWaylandQtShellSurface::capabilities() const +{ + Q_D(const QWaylandQtShellSurface); + return d->m_capabilities; +} + +/*! + * \qmlproperty int QtShellSurface::windowState + * + * This property holds the window state of the QtShellSurface. + * + * \note When \l{requestWindowGeometry()} is called to update state of the surface, the + * \c windowState property will not be updated until the client has acknowledged the state change. + */ +uint QWaylandQtShellSurface::windowState() const +{ + Q_D(const QWaylandQtShellSurface); + return d->m_windowState; +} + +void QWaylandQtShellSurface::surfaceCommitted() +{ + Q_D(QWaylandQtShellSurface); + if (d->m_lastAckedConfigure < UINT32_MAX) { + QRect targetRect = d->m_windowGeometry; + uint windowState = d->m_windowState; + for (auto it = d->m_pendingConfigures.begin(); it != d->m_pendingConfigures.end(); ) { + if (it.key() == d->m_lastAckedConfigure) { + targetRect = it.value().second; + windowState = it.value().first; + } + + if (it.key() <= d->m_lastAckedConfigure) + it = d->m_pendingConfigures.erase(it); + else + break; + } + + if (d->m_windowState != windowState) { + d->m_windowState = windowState; + emit windowStateChanged(); + } + + if (d->m_windowGeometry != targetRect) { + d->m_windowGeometry = targetRect; + d->m_positionSet = true; + emit positionAutomaticChanged(); + emit windowGeometryChanged(); + } + + d->m_lastAckedConfigure = UINT32_MAX; + d->m_pendingPosition = QPoint{}; + d->m_pendingPositionValid = false; + d->m_pendingSize = QSize{}; + } else { + QRect oldRect = d->m_windowGeometry; + if (d->m_pendingPositionValid) { + d->m_windowGeometry.moveTopLeft(d->m_pendingPosition); + d->m_pendingPosition = QPoint{}; + d->m_pendingPositionValid = false; + d->m_positionSet = true; + emit positionAutomaticChanged(); + } + + if (d->m_pendingSize.isValid()) { + d->m_windowGeometry.setSize(d->m_pendingSize); + d->m_pendingSize = QSize{}; + } + + if (d->m_windowGeometry != oldRect) + emit windowGeometryChanged(); + } +} + +/*! + * Returns the Wayland interface for the QWaylandQtShellSurface. + */ +const wl_interface *QWaylandQtShellSurface::interface() +{ + return QWaylandQtShellSurfacePrivate::interface(); +} + +QByteArray QWaylandQtShellSurface::interfaceName() +{ + return QWaylandQtShellSurfacePrivate::interfaceName(); +} + +/*! + * Returns the surface role for the QWaylandQtShellSurface. + */ +QWaylandSurfaceRole *QWaylandQtShellSurface::role() +{ + return &QWaylandQtShellSurfacePrivate::s_role; +} + +/*! + * Returns the QWaylandQtShellSurface corresponding to the \a resource. + */ +QWaylandQtShellSurface *QWaylandQtShellSurface::fromResource(wl_resource *resource) +{ + if (auto p = QtWayland::fromResource<QWaylandQtShellSurfacePrivate *>(resource)) + return p->q_func(); + return nullptr; +} + +#if QT_CONFIG(wayland_compositor_quick) +QWaylandQuickShellIntegration *QWaylandQtShellSurface::createIntegration(QWaylandQuickShellSurfaceItem *item) +{ + return new QtWayland::QtShellIntegration(item); +} +#endif + +/*! + * \internal + */ +void QWaylandQtShellSurface::initialize() +{ + QWaylandShellSurfaceTemplate::initialize(); +} + +QWaylandQtShellSurfacePrivate::QWaylandQtShellSurfacePrivate() +{ +} + +void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_ack_configure(Resource *resource, uint32_t serial) +{ + Q_UNUSED(resource); + Q_Q(QWaylandQtShellSurface); + if (serial < UINT32_MAX) + m_lastAckedConfigure = serial; + + // Fake a surface commit because we won't get one as long as the window is unexposed + if (m_windowState & Qt::WindowMinimized) + q->surfaceCommitted(); +} + +void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_reposition(Resource *resource, int32_t x, int32_t y) +{ + Q_UNUSED(resource); + + m_pendingPosition = QPoint(x, y); + m_pendingPositionValid = true; + m_lastAckedConfigure = UINT32_MAX; +} + +void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_set_size(Resource *resource, int32_t width, int32_t height) +{ + Q_UNUSED(resource); + + m_pendingSize = QSize(width, height); + m_lastAckedConfigure = UINT32_MAX; +} + +void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_set_minimum_size(Resource *resource, int32_t width, int32_t height) +{ + Q_UNUSED(resource); + Q_Q(QWaylandQtShellSurface); + m_minimumSize = QSize{width, height}; + emit q->minimumSizeChanged(); +} + +void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_set_maximum_size(Resource *resource, int32_t width, int32_t height) +{ + Q_UNUSED(resource); + Q_Q(QWaylandQtShellSurface); + m_maximumSize = QSize{width, height}; + emit q->maximumSizeChanged(); +} + +void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_destroy_resource(QtWaylandServer::zqt_shell_surface_v1::Resource *resource) +{ + Q_UNUSED(resource); + Q_Q(QWaylandQtShellSurface); + QWaylandQtShellPrivate::get(m_qtShell)->unregisterQtShellSurface(q); + delete q; +} + +void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_destroy(QtWaylandServer::zqt_shell_surface_v1::Resource *resource) +{ + wl_resource_destroy(resource->handle); +} + +void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_set_window_flags(Resource *resource, uint32_t flags) +{ + Q_UNUSED(resource); + Q_Q(QWaylandQtShellSurface); + m_windowFlags = flags; + emit q->windowFlagsChanged(); +} + +void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_change_window_state(Resource *resource, uint32_t state) +{ + Q_UNUSED(resource); + Q_Q(QWaylandQtShellSurface); + uint oldWindowState = m_windowState; + m_windowState = state & ~Qt::WindowActive; + + if (oldWindowState != m_windowState) + emit q->windowStateChanged(); +} + +void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_start_system_resize(Resource *resource, uint32_t serial, uint32_t edge) +{ + Q_UNUSED(resource); + Q_UNUSED(serial); + Q_Q(QWaylandQtShellSurface); + emit q->startResize(Qt::Edges(edge)); +} + +void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_start_system_move(Resource *resource, uint32_t serial) +{ + Q_UNUSED(resource); + Q_UNUSED(serial); + Q_Q(QWaylandQtShellSurface); + emit q->startMove(); +} + +void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_set_window_title(Resource *resource, + const QString &title) +{ + Q_UNUSED(resource); + Q_Q(QWaylandQtShellSurface); + m_windowTitle = title; + emit q->windowTitleChanged(); +} + +void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_request_activate(Resource *resource) + +{ + Q_UNUSED(resource); + Q_Q(QWaylandQtShellSurface); + q->setActive(true); +} + +void QWaylandQtShellSurfacePrivate::updateFrameMargins() +{ + send_set_frame_margins(m_frameMargins.left(), m_frameMargins.right(), + m_frameMargins.top(), m_frameMargins.bottom()); +} + + +void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_raise(Resource *resource) +{ + Q_UNUSED(resource); + Q_Q(QWaylandQtShellSurface); + emit q->raiseRequested(); +} + +void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_lower(Resource *resource) +{ + Q_UNUSED(resource); + Q_Q(QWaylandQtShellSurface); + emit q->lowerRequested(); +} + +QT_END_NAMESPACE + +#include "moc_qwaylandqtshell_p.cpp" diff --git a/src/imports/compositor-extensions/qtshell/qwaylandqtshell.h b/src/imports/compositor-extensions/qtshell/qwaylandqtshell.h new file mode 100644 index 000000000..d322b9415 --- /dev/null +++ b/src/imports/compositor-extensions/qtshell/qwaylandqtshell.h @@ -0,0 +1,181 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef QWAYLANDQTSHELL_H +#define QWAYLANDQTSHELL_H + +#include <QtWaylandCompositor/QWaylandCompositorExtension> +#include <QtWaylandCompositor/QWaylandSurface> +#include <QtWaylandCompositor/QWaylandResource> +#include <QtCore/QSize> + +#include <QtWaylandCompositor/QWaylandShellSurface> +#include <QtWaylandCompositor/qwaylandquickchildren.h> +#include <QtWaylandCompositor/qwaylandquickextension.h> + +struct wl_resource; +struct wl_interface; + +QT_BEGIN_NAMESPACE + +class QWaylandQtShellPrivate; +class QWaylandQtShellSurface; +class QWaylandQtShellChrome; + +class Q_WAYLANDCOMPOSITOR_EXPORT QWaylandQtShell : public QWaylandCompositorExtensionTemplate<QWaylandQtShell> +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandQtShell) + +public: + QWaylandQtShell(); + QWaylandQtShell(QWaylandCompositor *compositor); + + void initialize() override; + + static const struct wl_interface *interface(); + static QByteArray interfaceName(); + + void registerChrome(QWaylandQtShellChrome *chrome); + void unregisterChrome(QWaylandQtShellChrome *chrome); + +private Q_SLOTS: + void chromeActivated(); + void chromeDeactivated(); + +Q_SIGNALS: + void qtShellSurfaceRequested(QWaylandSurface *surface, const QWaylandResource &resource); + void qtShellSurfaceCreated(QWaylandQtShellSurface *qtShellSurface); + +private: + bool moveChromeToFront(QWaylandQtShellChrome *chrome); +}; + +Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_NAMED_ELEMENT(QWaylandQtShell, QtShell, 1, 0) + + +class QWaylandQtShellSurfacePrivate; +class QWaylandSurfaceRole; +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) + Q_PROPERTY(uint windowFlags READ windowFlags NOTIFY windowFlagsChanged) + Q_PROPERTY(uint windowState READ windowState NOTIFY windowStateChanged) + Q_PROPERTY(QString windowTitle READ windowTitle READ windowTitle NOTIFY windowTitleChanged) + Q_PROPERTY(QRect windowGeometry READ windowGeometry NOTIFY windowGeometryChanged) + Q_PROPERTY(QPoint windowPosition READ windowPosition WRITE setWindowPosition NOTIFY windowGeometryChanged) + Q_PROPERTY(bool positionAutomatic READ positionAutomatic NOTIFY positionAutomaticChanged) + Q_PROPERTY(QSize minimumSize READ minimumSize NOTIFY minimumSizeChanged) + Q_PROPERTY(QSize maximumSize READ maximumSize NOTIFY maximumSizeChanged) + Q_PROPERTY(int frameMarginLeft READ frameMarginLeft WRITE setFrameMarginLeft NOTIFY frameMarginChanged) + Q_PROPERTY(int frameMarginRight READ frameMarginRight WRITE setFrameMarginRight NOTIFY frameMarginChanged) + Q_PROPERTY(int frameMarginTop READ frameMarginTop WRITE setFrameMarginTop NOTIFY frameMarginChanged) + Q_PROPERTY(int frameMarginBottom READ frameMarginBottom WRITE setFrameMarginBottom NOTIFY frameMarginChanged) + Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged) + Q_PROPERTY(CapabilityFlags capabilities READ capabilities WRITE setCapabilities NOTIFY capabilitiesChanged) + Q_MOC_INCLUDE("qwaylandsurface.h") + +public: + // Matches the "capabilities" enum in the protocol xml + enum CapabilityFlag { + InteractiveMove = 1, + InteractiveResize = 2 + }; + Q_DECLARE_FLAGS(CapabilityFlags, CapabilityFlag) + Q_ENUM(CapabilityFlag) + + QWaylandQtShellSurface(); + QWaylandQtShellSurface(QWaylandQtShell *application, QWaylandSurface *surface, const QWaylandResource &resource); + + void initialize(QWaylandQtShell *qtShell, QWaylandSurface *surface, + const QWaylandResource &resource); + + QWaylandSurface *surface() const; + + static const wl_interface *interface(); + static QByteArray interfaceName(); + static QWaylandSurfaceRole *role(); + static QWaylandQtShellSurface *fromResource(::wl_resource *resource); + + QRect windowGeometry() const; + + void setWindowPosition(const QPoint &position); + QPoint windowPosition() const; + + Q_INVOKABLE void requestWindowGeometry(uint windowState, const QRect &windowGeometry); + + QSize minimumSize() const; + QSize maximumSize() const; + + void setFrameMargins(const QMargins &margins); + + int frameMarginLeft() const; + void setFrameMarginLeft(int left); + + int frameMarginRight() const; + void setFrameMarginRight(int right); + + int frameMarginTop() const; + void setFrameMarginTop(int top); + + int frameMarginBottom() const; + void setFrameMarginBottom(int bottom); + + bool positionAutomatic() const; + + bool active() const; + void setActive(bool active); + + QString windowTitle() const; + + uint windowFlags() const; + + Q_INVOKABLE void sendClose(); + + uint windowState() const; + void setWindowState(uint windowState); +#if QT_CONFIG(wayland_compositor_quick) + QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) override; +#endif + + CapabilityFlags capabilities() const; + void setCapabilities(CapabilityFlags capabilities); + +Q_SIGNALS: + void surfaceChanged(); + void windowFlagsChanged(); + void windowStateChanged(); + void windowGeometryChanged(); + void minimumSizeChanged(); + void maximumSizeChanged(); + void positionAutomaticChanged(); + void startMove(); + void startResize(Qt::Edges edges); + void windowTitleChanged(); + void frameMarginChanged(); + void raiseRequested(); + void lowerRequested(); + void activeChanged(); + void capabilitiesChanged(); + +private Q_SLOTS: + void surfaceCommitted(); + +private: + friend class QWaylandQtShellChrome; + + void initialize() override; + + QWaylandQtShell *shell() const; +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDQTSHELL_H 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/qwaylandqtshell_p.h b/src/imports/compositor-extensions/qtshell/qwaylandqtshell_p.h new file mode 100644 index 000000000..ad93dee1a --- /dev/null +++ b/src/imports/compositor-extensions/qtshell/qwaylandqtshell_p.h @@ -0,0 +1,108 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef QWAYLANDQTSHELL_P_H +#define QWAYLANDQTSHELL_P_H + +#include <QtWaylandCompositor/private/qwaylandshellsurface_p.h> +#include <QtWaylandCompositor/QWaylandSurfaceRole> + +#include <QHash> + +#include "qwayland-server-qt-shell-unstable-v1.h" +#include "qwaylandqtshell.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. +// + +QT_BEGIN_NAMESPACE + +class Q_WAYLANDCOMPOSITOR_EXPORT QWaylandQtShellPrivate + : public QWaylandCompositorExtensionPrivate + , public QtWaylandServer::zqt_shell_v1 +{ + Q_DECLARE_PUBLIC(QWaylandQtShell) + +public: + QWaylandQtShellPrivate(); + static QWaylandQtShellPrivate *get(QWaylandQtShell *qtShell) { return qtShell->d_func(); } + void unregisterQtShellSurface(QWaylandQtShellSurface *qtShellSurface); + + QList<QWaylandQtShellChrome *> m_chromes; + +protected: + void zqt_shell_v1_surface_create(Resource *resource, wl_resource *surface, uint32_t id) override; +}; + +class Q_WAYLANDCOMPOSITOR_EXPORT QWaylandQtShellSurfacePrivate + : public QWaylandShellSurfacePrivate + , public QtWaylandServer::zqt_shell_surface_v1 +{ + Q_DECLARE_PUBLIC(QWaylandQtShellSurface) + +public: + QWaylandQtShellSurfacePrivate(); + static QWaylandQtShellSurfacePrivate *get(QWaylandQtShellSurface *qtShellSurface) + { + return qtShellSurface->d_func(); + } + + void updateFrameMargins(); + void configure(uint windowState, const QRect &newGeometry); + +protected: + void zqt_shell_surface_v1_destroy_resource(Resource *resource) override; + void zqt_shell_surface_v1_destroy(Resource *resource) override; + void zqt_shell_surface_v1_reposition(Resource *resource, int32_t x, int32_t y) override; + void zqt_shell_surface_v1_set_size(Resource *resource, int32_t width, int32_t height) override; + void zqt_shell_surface_v1_set_minimum_size(Resource *resource, int32_t width, int32_t height) override; + void zqt_shell_surface_v1_set_maximum_size(Resource *resource, int32_t width, int32_t height) override; + void zqt_shell_surface_v1_set_window_title(Resource *resource, const QString &title) override; + void zqt_shell_surface_v1_set_window_flags(Resource *resource, uint32_t flags) override; + void zqt_shell_surface_v1_change_window_state(Resource *resource, uint32_t state) override; + void zqt_shell_surface_v1_ack_configure(Resource *resource, uint32_t serial) override; + + void zqt_shell_surface_v1_start_system_resize(Resource *resource, uint32_t serial, uint32_t edge) override; + void zqt_shell_surface_v1_start_system_move(Resource *resource, uint32_t serial) override; + + void zqt_shell_surface_v1_raise(Resource *resource) override; + void zqt_shell_surface_v1_lower(Resource *resource) override; + + void zqt_shell_surface_v1_request_activate(Resource *resource) override; + +private: + QWaylandQtShell *m_qtShell = nullptr; + QWaylandSurface *m_surface = nullptr; + QRect m_windowGeometry; + QSize m_minimumSize; + QSize m_maximumSize; + uint m_windowFlags = 0; + uint m_windowState = 0; + QString m_windowTitle; + QMargins m_frameMargins; + bool m_positionSet = false; + bool m_active = false; + + QPoint m_pendingPosition; + bool m_pendingPositionValid = false; + QSize m_pendingSize; + + uint32_t m_lastAckedConfigure = UINT32_MAX; + QMap<uint32_t, QPair<uint, QRect> > m_pendingConfigures; + + QWaylandQtShellSurface::CapabilityFlags m_capabilities; + + static QWaylandSurfaceRole s_role; +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDQTSHELL_P_H diff --git a/src/imports/compositor-extensions/qtshell/qwaylandqtshellchrome.cpp b/src/imports/compositor-extensions/qtshell/qwaylandqtshellchrome.cpp new file mode 100644 index 000000000..ffccf5d21 --- /dev/null +++ b/src/imports/compositor-extensions/qtshell/qwaylandqtshellchrome.cpp @@ -0,0 +1,1500 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "qwaylandqtshellchrome.h" +#include "qwaylandqtshellchrome_p.h" +#include "qwaylandqtshell.h" + +#include <QtWaylandCompositor/qwaylandquickshellsurfaceitem.h> + +QT_BEGIN_NAMESPACE + +QPointF QWaylandQtShellChromePrivate::constrainPoint(const QPointF &point) const +{ + float x0 = maximizedRect.left(); + float y0 = maximizedRect.top(); + float x1 = maximizedRect.right(); + float y1 = maximizedRect.bottom(); + return QPoint(qBound(x0, point.x(), x1), + qBound(y0, point.y(), y1)); +} + +void QWaylandQtShellChromePrivate::updateDecorationInteraction(quint8 flags, + const QQuickHandlerPoint ¢roid) +{ + if (shellSurface == nullptr) + return; + + if (decorationInteraction == quint8(DecorationInteraction::None)) { + decorationInteraction = flags; + decorationInteractionPosition = centroid.scenePressPosition(); + decorationInteractionGeometry = shellSurface->windowGeometry(); + } + + if (decorationInteraction != flags) + return; + + QPointF position = constrainPoint(centroid.scenePosition()); + float dx = position.x() - decorationInteractionPosition.x(); + float dy = position.y() - decorationInteractionPosition.y(); + + float minWidth = qMax(0, shellSurface->minimumSize().width()); + float minHeight = qMax(0, shellSurface->minimumSize().height()); + + float maxWidth = shellSurface->maximumSize().width(); + float maxHeight = shellSurface->maximumSize().height(); + + float minX = maxWidth >= 0.0f + ? decorationInteractionGeometry.right() - maxWidth + : -FLT_MAX; + float minY = maxHeight >= 0.0f + ? decorationInteractionGeometry.bottom() - maxHeight + : -FLT_MAX; + float maxX = maxWidth >= 0 + ? decorationInteractionGeometry.left() + maxWidth + : FLT_MAX; + float maxY = maxHeight >= 0.0f + ? decorationInteractionGeometry.top() + maxHeight + : FLT_MAX; + + float newLeft = decorationInteractionGeometry.left(); + if (flags & quint8(DecorationInteraction::WestBound)) { + newLeft = qBound(minX, + newLeft + dx, + float(decorationInteractionGeometry.right() - minWidth)); + } + + float newTop = decorationInteractionGeometry.top(); + if (flags & quint8(DecorationInteraction::NorthBound)) { + newTop = qBound(minY, + newTop + dy, + decorationInteractionGeometry.bottom() + minHeight); + } + + float newRight = decorationInteractionGeometry.right(); + if (flags & quint8(DecorationInteraction::EastBound)) { + newRight = qBound(decorationInteractionGeometry.left() + minWidth, + newRight + dx, + maxX); + } + + float newBottom = decorationInteractionGeometry.bottom(); + if (flags & quint8(DecorationInteraction::SouthBound)) { + newBottom = qBound(decorationInteractionGeometry.top() + minHeight, + newBottom + dy, + maxY); + } + + shellSurface->requestWindowGeometry(shellSurface->windowState(), + QRect(int(newLeft), int(newTop), + int(newRight - newLeft), int(newBottom - newTop))); +} + +/*! + * \qmltype QtShellChrome + * \instantiates QWaylandQtShellChrome + * \inqmlmodule QtWayland.Compositor.QtShell + * \since 6.3 + * \brief Provides default window manager functionality for use with the \c qt-shell extension. + * + * The QtShellChrome is a convenience type that can be used to provide window manager functionality + * to the interaction with clients over the \c qt-shell + * \l{Shell Extensions - Qt Wayland Compositor}{shell extension protocol}. + * + * Given a ShellSurfaceItem with an associated QtShellSurface, the item will automatically adapt + * its size to match the surface. It will also provide automatic handling of: + * \list + * \li Window states, such as maximized, minimized and fullscreen. + * \li Window activation. + * \li Window resizing using with resize handles (if the appropriate properties are set.) + * \li Window repositioning using title bar interaction (if the \l titleBar property is set.) + * \endlist + * + * The QtShellChrome is intended to be used together with QtShell and QtShellSurface. + * + * \sa {QtShell Compositor} + */ +QWaylandQtShellChrome::QWaylandQtShellChrome(QQuickItem *parent) + : QQuickItem(*new QWaylandQtShellChromePrivate{}, parent) +{ + init(); +} + +QWaylandQtShellChrome::QWaylandQtShellChrome(QWaylandQtShellChromePrivate &dd, + QQuickItem *parent) + : QQuickItem(dd, parent) +{ + init(); +} + +QWaylandQtShellChrome::~QWaylandQtShellChrome() +{ + Q_D(QWaylandQtShellChrome); + if (d->shell != nullptr) + d->shell->unregisterChrome(this); +} + +void QWaylandQtShellChrome::init() +{ + connect(this, &QWaylandQtShellChrome::currentWindowStateChanged, + this, &QWaylandQtShellChrome::windowMetaInfoChanged); + + connect(this, &QWaylandQtShellChrome::currentWindowFlagsChanged, + this, &QWaylandQtShellChrome::windowMetaInfoChanged); + + connect(this, &QWaylandQtShellChrome::windowMetaInfoChanged, + this, &QWaylandQtShellChrome::updateDecorations); + + connect(this, &QWaylandQtShellChrome::leftResizeHandleChanged, + this, &QWaylandQtShellChrome::updateDecorations); + + connect(this, &QWaylandQtShellChrome::rightResizeHandleChanged, + this, &QWaylandQtShellChrome::updateDecorations); + + connect(this, &QWaylandQtShellChrome::topResizeHandleChanged, + this, &QWaylandQtShellChrome::updateDecorations); + + connect(this, &QWaylandQtShellChrome::bottomResizeHandleChanged, + this, &QWaylandQtShellChrome::updateDecorations); + + connect(this, &QWaylandQtShellChrome::topLeftResizeHandleChanged, + this, &QWaylandQtShellChrome::updateDecorations); + + connect(this, &QWaylandQtShellChrome::bottomLeftResizeHandleChanged, + this, &QWaylandQtShellChrome::updateDecorations); + + connect(this, &QWaylandQtShellChrome::topRightResizeHandleChanged, + this, &QWaylandQtShellChrome::updateDecorations); + + connect(this, &QWaylandQtShellChrome::bottomRightResizeHandleChanged, + this, &QWaylandQtShellChrome::updateDecorations); +} + +/*! + * \qmlmethod void QtShellChrome::toggleFullScreen() + * + * Toggles between fullscreen and normal window states. This method also clears the minimized + * or maximized window states if either is set. + */ +void QWaylandQtShellChrome::toggleFullScreen() +{ + Q_D(QWaylandQtShellChrome); + if (d->shellSurface == nullptr) + return; + + uint newState; + if ((d->shellSurface->windowState() & Qt::WindowFullScreen) == Qt::WindowFullScreen) + newState = d->currentState & ~Qt::WindowFullScreen; + else + newState = d->currentState | Qt::WindowFullScreen; + + if ((newState & (Qt::WindowMinimized | Qt::WindowMaximized)) != 0) + newState &= ~(Qt::WindowMinimized | Qt::WindowMaximized); + + setWindowState(newState); +} + +/*! + * \qmlmethod void QtShellChrome::toggleMaximized() + * + * Toggles between maximized and normal states. This method also clears the minimized + * window state if it is set. + */ +void QWaylandQtShellChrome::toggleMaximized() +{ + Q_D(QWaylandQtShellChrome); + if (d->shellSurface == nullptr) + return; + + uint newState; + if ((d->shellSurface->windowState() & Qt::WindowMaximized) == Qt::WindowMaximized) + newState = d->currentState & ~Qt::WindowMaximized; + else + newState = d->currentState | Qt::WindowMaximized; + + if ((newState & Qt::WindowMinimized) == Qt::WindowMinimized) + newState &= ~Qt::WindowMinimized; + + setWindowState(newState); +} + +/*! + * \qmlmethod void QtShellChrome::toggleMinimized() + * + * Toggles between minimized and normal states. This method also clears the maximized + * window state if it is set. + */ +void QWaylandQtShellChrome::toggleMinimized() +{ + Q_D(QWaylandQtShellChrome); + if (d->shellSurface == nullptr) + return; + + uint newState; + if ((d->shellSurface->windowState() & Qt::WindowMinimized) == Qt::WindowMinimized) + newState = d->currentState & ~Qt::WindowMinimized; + else + newState = d->currentState | Qt::WindowMinimized; + + if ((newState & Qt::WindowMaximized) == Qt::WindowMaximized) + newState &= ~Qt::WindowMaximized; + + setWindowState(newState); +} + +/*! + * \qmlproperty ShellSurfaceItem QtShellChrome::shellSurfaceItem + * + * This property holds the shell surface item associated with this QtShellChrome. It will + * in turn manage the \c shellSurface of this item. The \c shellSurface of the item is expected to + * be of the type QtShellSurface. + * + * \qml + * QtShellChrome { + * id: chrome + * ShellSurfaceItem { + * id: sfi + * anchors.fill: parent + * moveItem: chrome + * } + * shellSurfaceItem: sfi + * } + * \endqml + */ +void QWaylandQtShellChrome::setShellSurfaceItem(QWaylandQuickShellSurfaceItem *shellSurfaceItem) +{ + Q_D(QWaylandQtShellChrome); + if (d->shellSurfaceItem == shellSurfaceItem) + return; + + if (d->shellSurfaceItem != nullptr) + d->shellSurfaceItem->disconnect(this); + + d->shellSurfaceItem = shellSurfaceItem; + + if (d->shellSurfaceItem != nullptr) { + connect(d->shellSurfaceItem, &QWaylandQuickShellSurfaceItem::shellSurfaceChanged, + this, &QWaylandQtShellChrome::updateShellSurface); + connect(d->shellSurfaceItem, &QWaylandQuickShellSurfaceItem::surfaceDestroyed, + this, &QWaylandQtShellChrome::clientDestroyed); + } + + updateShellSurface(); + emit shellSurfaceItemChanged(); +} + +QWaylandQuickShellSurfaceItem *QWaylandQtShellChrome::shellSurfaceItem() const +{ + Q_D(const QWaylandQtShellChrome); + return d->shellSurfaceItem; +} + +void QWaylandQtShellChrome::stopGrab() +{ + Q_D(QWaylandQtShellChrome); + d->decorationInteraction = quint8(QWaylandQtShellChromePrivate::DecorationInteraction::None); +} + +void QWaylandQtShellChrome::leftResize() +{ + Q_D(QWaylandQtShellChrome); + if (!d->leftResizeHandleHandler->active()) + return; + + d->updateDecorationInteraction(quint8(QWaylandQtShellChromePrivate::DecorationInteraction::WestBound), + d->leftResizeHandleHandler->centroid()); +} + +void QWaylandQtShellChrome::rightResize() +{ + Q_D(QWaylandQtShellChrome); + if (!d->rightResizeHandleHandler->active()) + return; + + d->updateDecorationInteraction(quint8(QWaylandQtShellChromePrivate::DecorationInteraction::EastBound), + d->rightResizeHandleHandler->centroid()); +} + +void QWaylandQtShellChrome::topResize() +{ + Q_D(QWaylandQtShellChrome); + if (!d->topResizeHandleHandler->active()) + return; + + d->updateDecorationInteraction(quint8(QWaylandQtShellChromePrivate::DecorationInteraction::NorthBound), + d->topResizeHandleHandler->centroid()); +} + +void QWaylandQtShellChrome::bottomResize() +{ + Q_D(QWaylandQtShellChrome); + if (!d->bottomResizeHandleHandler->active()) + return; + + d->updateDecorationInteraction(quint8(QWaylandQtShellChromePrivate::DecorationInteraction::SouthBound), + d->bottomResizeHandleHandler->centroid()); +} + +void QWaylandQtShellChrome::topLeftResize() +{ + Q_D(QWaylandQtShellChrome); + if (!d->topLeftResizeHandleHandler->active()) + return; + + d->updateDecorationInteraction(quint8(QWaylandQtShellChromePrivate::DecorationInteraction::WestBound) + | quint8(QWaylandQtShellChromePrivate::DecorationInteraction::NorthBound), + d->topLeftResizeHandleHandler->centroid()); +} + +void QWaylandQtShellChrome::topRightResize() +{ + Q_D(QWaylandQtShellChrome); + if (!d->topRightResizeHandleHandler->active()) + return; + + d->updateDecorationInteraction(quint8(QWaylandQtShellChromePrivate::DecorationInteraction::EastBound) + | quint8(QWaylandQtShellChromePrivate::DecorationInteraction::NorthBound), + d->topRightResizeHandleHandler->centroid()); +} + +void QWaylandQtShellChrome::bottomLeftResize() +{ + Q_D(QWaylandQtShellChrome); + if (!d->bottomLeftResizeHandleHandler->active()) + return; + + d->updateDecorationInteraction(quint8(QWaylandQtShellChromePrivate::DecorationInteraction::WestBound) + | quint8(QWaylandQtShellChromePrivate::DecorationInteraction::SouthBound), + d->bottomLeftResizeHandleHandler->centroid()); +} + +void QWaylandQtShellChrome::bottomRightResize() +{ + Q_D(QWaylandQtShellChrome); + if (!d->bottomRightResizeHandleHandler->active()) + return; + + d->updateDecorationInteraction(quint8(QWaylandQtShellChromePrivate::DecorationInteraction::EastBound) + | quint8(QWaylandQtShellChromePrivate::DecorationInteraction::SouthBound), + d->bottomRightResizeHandleHandler->centroid()); +} + +void QWaylandQtShellChrome::titleBarMove() +{ + Q_D(QWaylandQtShellChrome); + if (!d->titleBarHandler->active()) + return; + + quint8 flags = quint8(QWaylandQtShellChromePrivate::DecorationInteraction::TitleBar); + QQuickHandlerPoint centroid = d->titleBarHandler->centroid(); + if (d->decorationInteraction == quint8(QWaylandQtShellChromePrivate::DecorationInteraction::None)) { + d->decorationInteraction = flags; + d->decorationInteractionPosition = d->shellSurface->windowPosition() - centroid.scenePressPosition(); + + activate(); + } + + if (d->decorationInteraction != flags) + return; + + QPointF position = d->constrainPoint(centroid.scenePosition()); + d->shellSurface->setWindowPosition((position + d->decorationInteractionPosition).toPoint()); +} + +/*! + * \qmlproperty Item QtShellChrome::titleBar + * + * This property holds the default title bar item of the QtShellChrome. If set, a \l DragHandler + * will be installed on the title bar which moves the window around on user interaction. In + * addition, the window will automatically be activated if the title bar is clicked. + * + * The title bar will automatically hide and show, depending on the window flags and the + * window's full screen state. + * + * \qml + * QtShellChrome { + * Rectangle { + * id: tb + * anchors.top: parent.top + * anchors.right: parent.right + * anchors.left: parent.left + * height: 50 + * color: "black" + * + * Text { + * color: "white" + * anchors.centerIn: parent + * text: shellSurfaceItem.shellSurface.windowTitle + * font.pixelSize: 25 + * } + * } + * titleBar: tb + * } + * \endqml + * + * \note Unless explicit frame margins are set, the title bar's height will be included in the + * window's top frame margin. + */ +QQuickItem *QWaylandQtShellChrome::titleBar() const +{ + Q_D(const QWaylandQtShellChrome); + return d->titleBar; +} + +void QWaylandQtShellChrome::setTitleBar(QQuickItem *item) +{ + Q_D(QWaylandQtShellChrome); + if (d->titleBar == item) + return; + + if (d->titleBar != nullptr) { + d->titleBar->disconnect(this); + + delete d->titleBarHandler; + d->titleBarHandler = nullptr; + } + + d->titleBar = item; + + if (d->titleBar != nullptr) { + connect(d->titleBar, &QQuickItem::heightChanged, + this, &QWaylandQtShellChrome::updateDecorations); + + d->titleBarHandler = new QQuickDragHandler(d->titleBar); + d->titleBarHandler->setTarget(nullptr); + + connect(d->titleBarHandler, &QQuickPointerHandler::grabChanged, + this, &QWaylandQtShellChrome::stopGrab); + connect(d->titleBarHandler, &QQuickPointerHandler::grabChanged, + this, &QWaylandQtShellChrome::activateOnGrab); + connect(d->titleBarHandler, &QQuickMultiPointHandler::centroidChanged, + this, &QWaylandQtShellChrome::titleBarMove); + } + + emit titleBarChanged(); +} + +/*! + * \qmlproperty Item QtShellChrome::leftResizeHandle + * + * This property holds the default left resize handle of the QtShellChrome. If set, a \l DragHandler + * will be installed on the resize handle which resizes the window by moving its left edge. + * + * The handle will automatically hide and show, depending on the window flags and the window's full + * screen state. + * + * \qml + * QtShellChrome { + * Rectangle { + * id: lrh + * anchors.left: parent.left + * anchors.top: parent.top + * anchors.bottom: parent.bottom + * width: 5 + * color: "white" + * } + * leftResizeHandle: lrh + * } + * \endqml + * + * \note Unless explicit frame margins are set, the handle's width will be included in the + * window's left frame margin. + */ +QQuickItem *QWaylandQtShellChrome::leftResizeHandle() const +{ + Q_D(const QWaylandQtShellChrome); + return d->leftResizeHandle; +} + +void QWaylandQtShellChrome::setLeftResizeHandle(QQuickItem *item) +{ + Q_D(QWaylandQtShellChrome); + if (d->leftResizeHandle == item) + return; + + if (d->leftResizeHandle != nullptr) { + d->leftResizeHandle->disconnect(this); + + delete d->leftResizeHandleHandler; + d->leftResizeHandleHandler = nullptr; + } + + d->leftResizeHandle = item; + + if (d->leftResizeHandle != nullptr) { + connect(d->leftResizeHandle, &QQuickItem::widthChanged, + this, &QWaylandQtShellChrome::updateDecorations); + + d->leftResizeHandleHandler = new QQuickDragHandler(d->leftResizeHandle); + d->leftResizeHandleHandler->setCursorShape(Qt::SizeHorCursor); + d->leftResizeHandleHandler->setTarget(nullptr); + + connect(d->leftResizeHandleHandler, &QQuickPointerHandler::grabChanged, + this, &QWaylandQtShellChrome::stopGrab); + connect(d->leftResizeHandleHandler, &QQuickMultiPointHandler::centroidChanged, + this, &QWaylandQtShellChrome::leftResize); + } + + emit leftResizeHandleChanged(); +} + +/*! + * \qmlproperty Item QtShellChrome::rightResizeHandle + * + * This property holds the default right resize handle of the QtShellChrome. If set, a \l DragHandler + * will be installed on the resize handle which resizes the window by moving its right edge. + * + * The handle will automatically hide and show, depending on the window flags and the window's full + * screen state. + * + * \qml + * QtShellChrome { + * Rectangle { + * id: rrh + * anchors.right: parent.right + * anchors.top: parent.top + * anchors.bottom: parent.bottom + * width: 5 + * color: "white" + * } + * rightResizeHandle: rrh + * } + * \endqml + * + * \note Unless explicit frame margins are set, the handle's width will be included in the + * window's right frame margin. + */ +QQuickItem *QWaylandQtShellChrome::rightResizeHandle() const +{ + Q_D(const QWaylandQtShellChrome); + return d->rightResizeHandle; +} + +void QWaylandQtShellChrome::setRightResizeHandle(QQuickItem *item) +{ + Q_D(QWaylandQtShellChrome); + if (d->rightResizeHandle == item) + return; + + if (d->rightResizeHandle != nullptr) { + d->rightResizeHandle->disconnect(this); + + delete d->rightResizeHandleHandler; + d->rightResizeHandleHandler = nullptr; + } + + d->rightResizeHandle = item; + + if (d->rightResizeHandle != nullptr) { + connect(d->rightResizeHandle, &QQuickItem::widthChanged, + this, &QWaylandQtShellChrome::updateDecorations); + + d->rightResizeHandleHandler = new QQuickDragHandler(d->rightResizeHandle); + d->rightResizeHandleHandler->setCursorShape(Qt::SizeHorCursor); + d->rightResizeHandleHandler->setTarget(nullptr); + + connect(d->rightResizeHandleHandler, &QQuickPointerHandler::grabChanged, + this, &QWaylandQtShellChrome::stopGrab); + connect(d->rightResizeHandleHandler, &QQuickMultiPointHandler::centroidChanged, + this, &QWaylandQtShellChrome::rightResize); + } + + emit rightResizeHandleChanged(); +} + +/*! + * \qmlproperty Item QtShellChrome::topResizeHandle + * + * This property holds the default top resize handle of the QtShellChrome. If set, a \l DragHandler + * will be installed on the resize handle which resizes the window by moving its top edge. + * + * The handle will automatically hide and show, depending on the window flags and the window's full + * screen state. + * + * \qml + * QtShellChrome { + * Rectangle { + * id: trh + * anchors.top: parent.top + * anchors.left: parent.left + * anchors.right: parent.right + * height: 5 + * color: "white" + * } + * topResizeHandle: trh + * } + * \endqml + * + * \note Unless explicit frame margins are set, the handle's height will be included in the + * window's top frame margin. + */ +QQuickItem *QWaylandQtShellChrome::topResizeHandle() const +{ + Q_D(const QWaylandQtShellChrome); + return d->topResizeHandle; +} + +void QWaylandQtShellChrome::setTopResizeHandle(QQuickItem *item) +{ + Q_D(QWaylandQtShellChrome); + if (d->topResizeHandle == item) + return; + + if (d->topResizeHandle != nullptr) { + d->topResizeHandle->disconnect(this); + + delete d->topResizeHandleHandler; + d->topResizeHandleHandler = nullptr; + } + + d->topResizeHandle = item; + + if (d->topResizeHandle != nullptr) { + connect(d->topResizeHandle, &QQuickItem::heightChanged, + this, &QWaylandQtShellChrome::updateDecorations); + + d->topResizeHandleHandler = new QQuickDragHandler(d->topResizeHandle); + d->topResizeHandleHandler->setCursorShape(Qt::SizeVerCursor); + d->topResizeHandleHandler->setTarget(nullptr); + + connect(d->topResizeHandleHandler, &QQuickPointerHandler::grabChanged, + this, &QWaylandQtShellChrome::stopGrab); + connect(d->topResizeHandleHandler, &QQuickMultiPointHandler::centroidChanged, + this, &QWaylandQtShellChrome::topResize); + } + + emit topResizeHandleChanged(); +} + +/*! + * \qmlproperty Item QtShellChrome::bottomResizeHandle + * + * This property holds the default bottom resize handle of the QtShellChrome. If set, a \l DragHandler + * will be installed on the resize handle which resizes the window by moving its bottom edge. + * + * The handle will automatically hide and show, depending on the window flags and the window's full + * screen state. + * + * \qml + * QtShellChrome { + * Rectangle { + * id: brh + * anchors.bottom: parent.bottom + * anchors.left: parent.left + * anchors.right: parent.right + * height: 5 + * color: "white" + * } + * bottomResizeHandle: brh + * } + * \endqml + * + * \note Unless explicit frame margins are set, the handle's height will be included in the + * window's bottom frame margin. + */ +QQuickItem *QWaylandQtShellChrome::bottomResizeHandle() const +{ + Q_D(const QWaylandQtShellChrome); + return d->bottomResizeHandle; +} + +void QWaylandQtShellChrome::setBottomResizeHandle(QQuickItem *item) +{ + Q_D(QWaylandQtShellChrome); + if (d->bottomResizeHandle == item) + return; + + if (d->bottomResizeHandle != nullptr) { + d->bottomResizeHandle->disconnect(this); + + delete d->bottomResizeHandleHandler; + d->bottomResizeHandleHandler = nullptr; + } + + d->bottomResizeHandle = item; + + if (d->bottomResizeHandle != nullptr) { + connect(d->bottomResizeHandle, &QQuickItem::heightChanged, + this, &QWaylandQtShellChrome::updateDecorations); + + d->bottomResizeHandleHandler = new QQuickDragHandler(d->bottomResizeHandle); + d->bottomResizeHandleHandler->setCursorShape(Qt::SizeVerCursor); + d->bottomResizeHandleHandler->setTarget(nullptr); + + connect(d->bottomResizeHandleHandler, &QQuickPointerHandler::grabChanged, + this, &QWaylandQtShellChrome::stopGrab); + connect(d->bottomResizeHandleHandler, &QQuickMultiPointHandler::centroidChanged, + this, &QWaylandQtShellChrome::bottomResize); + + } + + emit bottomResizeHandleChanged(); +} + +/*! + * \qmlproperty Item QtShellChrome::topLeftResizeHandle + * + * This property holds the default top-left resize handle of the QtShellChrome. If set, a \l DragHandler + * will be installed on the resize handle which resizes the window by moving its top and left edges + * in equal amounts. + * + * The handle will automatically hide and show, depending on the window flags and the window's full + * screen state. + * + * \qml + * QtShellChrome { + * Rectangle { + * id: tlrh + * anchors.top: parent.top + * anchors.left: parent.left + * height: 5 + * width: 5 + * color: "white" + * } + * topLeftResizeHandle: tlrh + * } + * \endqml + */ +QQuickItem *QWaylandQtShellChrome::topLeftResizeHandle() const +{ + Q_D(const QWaylandQtShellChrome); + return d->topLeftResizeHandle; +} + +void QWaylandQtShellChrome::setTopLeftResizeHandle(QQuickItem *item) +{ + Q_D(QWaylandQtShellChrome); + if (d->topLeftResizeHandle == item) + return; + + if (d->topLeftResizeHandle != nullptr) { + delete d->topLeftResizeHandleHandler; + d->topLeftResizeHandleHandler = nullptr; + } + + d->topLeftResizeHandle = item; + + if (d->topLeftResizeHandle != nullptr) { + d->topLeftResizeHandleHandler = new QQuickDragHandler(d->topLeftResizeHandle); + d->topLeftResizeHandleHandler->setCursorShape(Qt::SizeFDiagCursor); + d->topLeftResizeHandleHandler->setTarget(nullptr); + + connect(d->topLeftResizeHandleHandler, &QQuickPointerHandler::grabChanged, + this, &QWaylandQtShellChrome::stopGrab); + connect(d->topLeftResizeHandleHandler, &QQuickMultiPointHandler::centroidChanged, + this, &QWaylandQtShellChrome::topLeftResize); + } + + emit topLeftResizeHandleChanged(); +} + +/*! + * \qmlproperty Item QtShellChrome::bottomLeftResizeHandle + * + * This property holds the default bottom-left resize handle of the QtShellChrome. If set, a \l DragHandler + * will be installed on the resize handle which resizes the window by moving its bottom and left edges + * in equal amounts. + * + * The handle will automatically hide and show, depending on the window flags and the window's full + * screen state. + * + * \qml + * QtShellChrome { + * Rectangle { + * id: blrh + * anchors.bottom: parent.bottom + * anchors.left: parent.left + * height: 5 + * width: 5 + * color: "white" + * } + * bottomLeftResizeHandle: blrh + * } + * \endqml + */ +QQuickItem *QWaylandQtShellChrome::bottomLeftResizeHandle() const +{ + Q_D(const QWaylandQtShellChrome); + return d->bottomLeftResizeHandle; +} + +void QWaylandQtShellChrome::setBottomLeftResizeHandle(QQuickItem *item) +{ + Q_D(QWaylandQtShellChrome); + if (d->bottomLeftResizeHandle == item) + return; + + if (d->bottomLeftResizeHandle != nullptr) { + delete d->bottomLeftResizeHandleHandler; + d->bottomLeftResizeHandleHandler = nullptr; + } + + d->bottomLeftResizeHandle = item; + + if (d->bottomLeftResizeHandle != nullptr) { + d->bottomLeftResizeHandleHandler = new QQuickDragHandler(d->bottomLeftResizeHandle); + d->bottomLeftResizeHandleHandler->setCursorShape(Qt::SizeBDiagCursor); + d->bottomLeftResizeHandleHandler->setTarget(nullptr); + + connect(d->bottomLeftResizeHandleHandler, &QQuickPointerHandler::grabChanged, + this, &QWaylandQtShellChrome::stopGrab); + connect(d->bottomLeftResizeHandleHandler, &QQuickMultiPointHandler::centroidChanged, + this, &QWaylandQtShellChrome::bottomLeftResize); + } + + emit bottomLeftResizeHandleChanged(); +} + +/*! + * \qmlproperty Item QtShellChrome::topRightResizeHandle + * + * This property holds the default top-right resize handle of the QtShellChrome. If set, a \l DragHandler + * will be installed on the resize handle which resizes the window by moving its top and right edges + * in equal amounts. + * + * The handle will automatically hide and show, depending on the window flags and the window's full + * screen state. + * + * \qml + * QtShellChrome { + * Rectangle { + * id: trrh + * anchors.top: parent.top + * anchors.right: parent.right + * height: 5 + * width: 5 + * color: "white" + * } + * topRightResizeHandle: trrh + * } + * \endqml + */ +QQuickItem *QWaylandQtShellChrome::topRightResizeHandle() const +{ + Q_D(const QWaylandQtShellChrome); + return d->topRightResizeHandle; +} + +void QWaylandQtShellChrome::setTopRightResizeHandle(QQuickItem *item) +{ + Q_D(QWaylandQtShellChrome); + if (d->topRightResizeHandle == item) + return; + + if (d->topRightResizeHandle != nullptr) { + delete d->topRightResizeHandleHandler; + d->topRightResizeHandleHandler = nullptr; + } + + d->topRightResizeHandle = item; + + if (d->topRightResizeHandle != nullptr) { + d->topRightResizeHandleHandler = new QQuickDragHandler(d->topRightResizeHandle); + d->topRightResizeHandleHandler->setCursorShape(Qt::SizeBDiagCursor); + d->topRightResizeHandleHandler->setTarget(nullptr); + + connect(d->topRightResizeHandleHandler, &QQuickPointerHandler::grabChanged, + this, &QWaylandQtShellChrome::stopGrab); + connect(d->topRightResizeHandleHandler, &QQuickMultiPointHandler::centroidChanged, + this, &QWaylandQtShellChrome::topRightResize); + } + + emit topRightResizeHandleChanged(); +} + +/*! + * \qmlproperty Item QtShellChrome::bottomRightResizeHandle + * + * This property holds the default bottom-right resize handle of the QtShellChrome. If set, a \l DragHandler + * will be installed on the resize handle which resizes the window by moving its bottom and right edges + * in equal amounts. + * + * The handle will automatically hide and show, depending on the window flags and the window's full + * screen state. + * + * \qml + * QtShellChrome { + * Rectangle { + * id: brrh + * anchors.bottom: parent.bottom + * anchors.right: parent.right + * height: 5 + * width: 5 + * color: "white" + * } + * bottomRightResizeHandle: brrh + * } + * \endqml + */ +QQuickItem *QWaylandQtShellChrome::bottomRightResizeHandle() const +{ + Q_D(const QWaylandQtShellChrome); + return d->bottomRightResizeHandle; +} + +void QWaylandQtShellChrome::setBottomRightResizeHandle(QQuickItem *item) +{ + Q_D(QWaylandQtShellChrome); + if (d->bottomRightResizeHandle == item) + return; + + if (d->bottomRightResizeHandle != nullptr) { + delete d->bottomRightResizeHandleHandler; + d->bottomRightResizeHandleHandler = nullptr; + } + + d->bottomRightResizeHandle = item; + + if (d->bottomRightResizeHandle != nullptr) { + d->bottomRightResizeHandleHandler = new QQuickDragHandler(d->bottomRightResizeHandle); + d->bottomRightResizeHandleHandler->setCursorShape(Qt::SizeFDiagCursor); + d->bottomRightResizeHandleHandler->setTarget(nullptr); + + connect(d->bottomRightResizeHandleHandler, &QQuickPointerHandler::grabChanged, + this, &QWaylandQtShellChrome::stopGrab); + connect(d->bottomRightResizeHandleHandler, &QQuickMultiPointHandler::centroidChanged, + this, &QWaylandQtShellChrome::bottomRightResize); + } + + emit bottomRightResizeHandleChanged(); +} + +/*! + * \qmlproperty rect QtShellChrome::maximizedRect + * + * This property holds the are of the WaylandOutput which is available to be filled by the + * window when it is in maximized state. By default, the window will fill the entire geometry + * of the WaylandOutput when it is maximized. Changing it can be useful for example when the + * compositor has other system UI which should not be obscured by maximized applications, such as + * a task bar. + */ +void QWaylandQtShellChrome::setMaximizedRect(const QRect &rect) +{ + Q_D(QWaylandQtShellChrome); + if (d->maximizedRect == rect) + return; + + d->maximizedRect = rect; + emit maximizedRectChanged(); +} + +QRect QWaylandQtShellChrome::maximizedRect() const +{ + Q_D(const QWaylandQtShellChrome); + if (d->maximizedRect.isValid()) + return d->maximizedRect; + else if (d->shellSurfaceItem != nullptr && d->shellSurfaceItem->output() != nullptr) + return d->shellSurfaceItem->output()->geometry(); + + return QRect{}; +} + +void QWaylandQtShellChrome::updateDecorations() +{ + Q_D(QWaylandQtShellChrome); + if (d->shellSurface == nullptr) + return; + + bool decorations = hasDecorations(); + bool titleBarShowing = hasTitleBar(); + + QMargins margins; + if (d->automaticFrameMargins) { + if (d->leftResizeHandle != nullptr && decorations) + margins.setLeft(d->leftResizeHandle->width()); + if (d->rightResizeHandle != nullptr && decorations) + margins.setRight(d->rightResizeHandle->width()); + if (d->bottomResizeHandle != nullptr && decorations) + margins.setBottom(d->bottomResizeHandle->height()); + + margins.setTop((decorations && d->topResizeHandle != nullptr ? d->topResizeHandle->height() : 0) + + (titleBarShowing && d->titleBar != nullptr ? d->titleBar->height() : 0)); + } else { + margins = d->explicitFrameMargins; + } + d->shellSurface->setFrameMargins(margins); + + if (d->titleBar != nullptr) + d->titleBar->setVisible(titleBarShowing); + if (d->leftResizeHandle != nullptr) + d->leftResizeHandle->setVisible(decorations); + if (d->rightResizeHandle != nullptr) + d->rightResizeHandle->setVisible(decorations); + if (d->topResizeHandle != nullptr) + d->topResizeHandle->setVisible(decorations); + if (d->bottomResizeHandle != nullptr) + d->bottomResizeHandle->setVisible(decorations); + if (d->bottomLeftResizeHandle != nullptr) + d->bottomLeftResizeHandle->setVisible(decorations); + if (d->topLeftResizeHandle != nullptr) + d->topLeftResizeHandle->setVisible(decorations); + if (d->bottomRightResizeHandle != nullptr) + d->bottomRightResizeHandle->setVisible(decorations); + if (d->topRightResizeHandle != nullptr) + d->topRightResizeHandle->setVisible(decorations); + + bool minimizedOrMaximized = (d->currentState & (Qt::WindowMaximized|Qt::WindowMinimized)) != 0; + if (d->leftResizeHandleHandler != nullptr) + d->leftResizeHandleHandler->setEnabled(decorations && !minimizedOrMaximized); + if (d->rightResizeHandleHandler != nullptr) + d->rightResizeHandleHandler->setEnabled(decorations && !minimizedOrMaximized); + if (d->bottomResizeHandleHandler != nullptr) + d->bottomResizeHandleHandler->setEnabled(decorations && !minimizedOrMaximized); + if (d->topResizeHandleHandler != nullptr) + d->topResizeHandleHandler->setEnabled(decorations && !minimizedOrMaximized); + if (d->bottomLeftResizeHandleHandler != nullptr) + d->bottomLeftResizeHandleHandler->setEnabled(decorations && !minimizedOrMaximized); + if (d->bottomRightResizeHandleHandler != nullptr) + d->bottomRightResizeHandleHandler->setEnabled(decorations && !minimizedOrMaximized); + if (d->topLeftResizeHandleHandler != nullptr) + d->topLeftResizeHandleHandler->setEnabled(decorations && !minimizedOrMaximized); + if (d->topRightResizeHandleHandler != nullptr) + d->topRightResizeHandleHandler->setEnabled(decorations && !minimizedOrMaximized); + if (d->titleBarHandler != nullptr) + d->titleBarHandler->setEnabled(titleBarShowing && !minimizedOrMaximized); +} + +void QWaylandQtShellChrome::updateGeometry() +{ + Q_D(QWaylandQtShellChrome); + if (d->shellSurface == nullptr) + return; + + QRect windowGeometry = d->shellSurface->windowGeometry(); + + QPointF position = windowGeometry.topLeft(); + position.rx() -= d->shellSurface->frameMarginLeft(); + position.ry() -= d->shellSurface->frameMarginTop(); + + QSizeF size = windowGeometry.size(); + size.rwidth() += d->shellSurface->frameMarginLeft() + d->shellSurface->frameMarginRight(); + size.rheight() += d->shellSurface->frameMarginTop() + d->shellSurface->frameMarginBottom(); + + setPosition(position); + setSize(size); +} + +void QWaylandQtShellChrome::updateSurface() +{ + Q_D(QWaylandQtShellChrome); + QWaylandSurface *surface = d->shellSurface != nullptr ? d->shellSurface->surface() : nullptr; + if (d->surface == surface) + return; + + if (d->surface != nullptr) + d->surface->disconnect(this); + + d->surface = surface; + + if (d->surface != nullptr) { + connect(d->surface, &QWaylandSurface::hasContentChanged, + this, &QWaylandQtShellChrome::updateAutomaticPosition); + } +} + +void QWaylandQtShellChrome::updateShellSurface() +{ + Q_D(QWaylandQtShellChrome); + QWaylandQtShellSurface *sf = d->shellSurfaceItem != nullptr + ? qobject_cast<QWaylandQtShellSurface *>(d->shellSurfaceItem->shellSurface()) + : nullptr; + if (d->shellSurface == sf) + return; + + if (d->shellSurface != nullptr) { + d->shellSurface->disconnect(this); + if (d->shell != nullptr) + d->shell->unregisterChrome(this); + d->shell = nullptr; + } + + d->shellSurface = sf; + if (d->shellSurface != nullptr) { + d->shell = d->shellSurface->shell(); + if (d->shell != nullptr) + d->shell->registerChrome(this); + + updateWindowFlags(); + connect(d->shellSurface, &QWaylandQtShellSurface::windowFlagsChanged, + this, &QWaylandQtShellChrome::updateWindowFlags); + connect(d->shellSurface, &QWaylandQtShellSurface::windowStateChanged, + this, &QWaylandQtShellChrome::updateWindowState); + connect(d->shellSurface, &QWaylandQtShellSurface::frameMarginChanged, + this, &QWaylandQtShellChrome::updateGeometry); + connect(d->shellSurface, &QWaylandQtShellSurface::windowGeometryChanged, + this, &QWaylandQtShellChrome::updateGeometry); + connect(d->shellSurface, &QWaylandQtShellSurface::raiseRequested, + this, &QWaylandQtShellChrome::raise); + connect(d->shellSurface, &QWaylandQtShellSurface::lowerRequested, + this, &QWaylandQtShellChrome::lower); + connect(d->shellSurface, &QWaylandQtShellSurface::activeChanged, + this, &QWaylandQtShellChrome::updateActiveState); + connect(d->shellSurface, &QWaylandQtShellSurface::surfaceChanged, + this, &QWaylandQtShellChrome::updateSurface); + } + + updateDecorations(); + updateSurface(); +} + +void QWaylandQtShellChrome::updateWindowState() +{ + Q_D(QWaylandQtShellChrome); + if (d->shellSurface == nullptr) + return; + + setWindowState(d->shellSurface->windowState()); +} + +void QWaylandQtShellChrome::updateWindowFlags() +{ + Q_D(QWaylandQtShellChrome); + + uint nextFlags = d->shellSurface == nullptr || d->shellSurface->windowFlags() == Qt::Window + ? d->defaultFlags + : d->shellSurface->windowFlags(); + + if (d->currentFlags != nextFlags) { + d->currentFlags = nextFlags; + emit currentWindowFlagsChanged(); + } +} + +/*! + * \qmlproperty int QtShellChrome::windowFlags + * + * This property holds the window flags of the QtShellChrome. They will match the \c windowFlags + * property of the associated QtShellSurface, except when this is equal to Qt.Window. In this case, + * a set of default window flags will be used instead. The default window flags are Qt.Window, + * Qt.WindowMaximizeButtonHint, Qt.WindowMinimizeButtonHint and Qt.WindowCloseButtonHint. + */ +uint QWaylandQtShellChrome::currentWindowFlags() const +{ + Q_D(const QWaylandQtShellChrome); + return d->currentFlags; +} + +/*! + * \qmlproperty int QtShellChrome::windowState + * + * This property holds the window state of the shell surface. It will be updated immediately when + * the window state is requested on the compositor-side, before this has been acknowledged by the + * client. Therefore, it may in brief periods differ from the shell surface's \c windowState + * property, which will be updated when the client has acknowledged the request. + */ +uint QWaylandQtShellChrome::currentWindowState() const +{ + Q_D(const QWaylandQtShellChrome); + return d->currentState; +} + +bool QWaylandQtShellChrome::hasTitleBar() const +{ + Q_D(const QWaylandQtShellChrome); + + bool frameless = (d->currentFlags & Qt::FramelessWindowHint) == Qt::FramelessWindowHint + || ((d->currentFlags & Qt::Popup) == Qt::Popup + && (d->currentFlags & Qt::Tool) != Qt::Tool) + || (d->currentState & Qt::WindowFullScreen) == Qt::WindowFullScreen; + return !frameless; +} + +/*! + * \qmlproperty bool QtShellChrome::hasDecorations + * + * This property is true if the QtShellChrome's decorations should be visible, based on its window + * state and window flags. + */ +bool QWaylandQtShellChrome::hasDecorations() const +{ + Q_D(const QWaylandQtShellChrome); + + return hasTitleBar() && (d->currentFlags & Qt::Window) == Qt::Window; +} + +QRect QWaylandQtShellChrome::maxContentRect() const +{ + Q_D(const QWaylandQtShellChrome); + if (d->shellSurface == nullptr) + return QRect{}; + + int x0 = d->maximizedRect.x() + d->shellSurface->frameMarginLeft(); + int x1 = d->maximizedRect.x() + d->maximizedRect.width() - d->shellSurface->frameMarginRight(); + int y0 = d->maximizedRect.y() + d->shellSurface->frameMarginTop(); + int y1 = d->maximizedRect.y() + d->maximizedRect.height() - d->shellSurface->frameMarginBottom(); + + return QRect(x0, y0, x1 - x0, y1 - y0); +} + +static int randomPos(int windowSize, int screenSize) +{ + return (windowSize >= screenSize) ? 0 : rand() % (screenSize - windowSize); +} + +void QWaylandQtShellChrome::setWindowState(uint nextState) +{ + Q_D(QWaylandQtShellChrome); + + if (d->currentState == nextState) + return; + + if (d->shellSurface == nullptr || d->shellSurfaceItem == nullptr) + return; + + QWaylandOutput *output = d->shellSurfaceItem->output(); + if (output == nullptr) + return; + + if ((d->currentState & (Qt::WindowMinimized | Qt::WindowMaximized | Qt::WindowFullScreen)) == 0) { + d->restoreGeometry = d->shellSurface->windowGeometry(); + } + + d->currentState = nextState; + emit currentWindowStateChanged(); + + if ((nextState & Qt::WindowMinimized) != 0) { + d->shellSurface->requestWindowGeometry(nextState, QRect(0, 0, 1, 1)); + d->shellSurfaceItem->setVisible(false); + deactivate(); + } else if ((nextState & Qt::WindowFullScreen) != 0) { + d->shellSurfaceItem->setVisible(true); + d->shellSurface->requestWindowGeometry(nextState, QRect(QPoint(0, 0), output->window()->size())); + activate(); + } else if ((nextState & Qt::WindowMaximized) != 0) { + d->shellSurfaceItem->setVisible(true); + d->shellSurface->requestWindowGeometry(nextState, maxContentRect()); + activate(); + } else { + d->shellSurfaceItem->setVisible(true); + d->shellSurface->requestWindowGeometry(nextState, d->restoreGeometry); + activate(); + } +} + +void QWaylandQtShellChrome::updateAutomaticPosition() +{ + Q_D(QWaylandQtShellChrome); + if (!d->positionSet && d->shellSurface != nullptr) { + bool randomize = d->shellSurface->positionAutomatic(); + QRect rect = d->shellSurface->windowGeometry(); + QRect space = maxContentRect(); + + int xpos = randomize ? randomPos(rect.width(), space.width()) + space.x() + : qMax(rect.x(), space.x()); + int ypos = randomize ? randomPos(rect.height(), space.height()) + space.y() + : qMax(rect.y(), space.y()); + + d->shellSurface->setWindowPosition(QPoint(xpos, ypos)); + d->positionSet = true; + } +} + +/*! + * \qmlmethod void QtShellChrome::deactivate() + * + * Manually deactivates this window. If the window was active, this will activate the next window in + * the stack instead. + */ +void QWaylandQtShellChrome::deactivate() +{ + Q_D(QWaylandQtShellChrome); + if (d->shellSurface != nullptr) + d->shellSurface->setActive(false); +} + +void QWaylandQtShellChrome::activateOnGrab(QPointingDevice::GrabTransition transition) +{ + Q_D(QWaylandQtShellChrome); + if (d->titleBarHandler != nullptr) { + switch (transition) { + case QPointingDevice::GrabPassive: + case QPointingDevice::OverrideGrabPassive: + case QPointingDevice::GrabExclusive: + activate(); + break; + default: + break; + } + } +} + +/*! + * \qmlmethod void QtShellChrome::activate() + * + * Manually activate this window. This will also raise the window. + * + * \sa raise() + */ +void QWaylandQtShellChrome::activate() +{ + Q_D(QWaylandQtShellChrome); + if (d->shellSurface != nullptr) + d->shellSurface->setActive(true); + raise(); +} + +/*! + * \qmlmethod void QtShellChrome::raise() + * + * Raise this window, so that it stacks on top of other windows (except if the other window's + * flags prohibit this.) + */ +void QWaylandQtShellChrome::raise() +{ + Q_D(QWaylandQtShellChrome); + if (d->shellSurfaceItem != nullptr) + d->shellSurfaceItem->raise(); +} + +/*! + * \qmlmethod void QtShellChrome::lower() + * + * Lower this window, so that it stacks underneath other windows (except if the other window's + * window flags prohibit this.) + */ +void QWaylandQtShellChrome::lower() +{ + Q_D(QWaylandQtShellChrome); + if (d->shellSurfaceItem != nullptr) + d->shellSurfaceItem->lower(); +} + +void QWaylandQtShellChrome::updateActiveState() +{ + Q_D(QWaylandQtShellChrome); + if (d->shellSurface == nullptr) + return; + + if (d->shellSurface->active()) { + raise(); + emit activated(); + } else { + emit deactivated(); + } +} + +/*! + * \qmlproperty int QtShellChrome::frameMarginLeft + * + * Sets the size of the left margin of the QtShellChrome which is reserved for window decorations. + * By default, this will equal the width of the \l leftResizeHandle if it is set. Otherwise it will + * be 0. + * + * \note By setting this property explicitly, all default frame margins will be overridden with + * their corresponding properties. + */ +void QWaylandQtShellChrome::setFrameMarginLeft(int left) +{ + Q_D(QWaylandQtShellChrome); + if (d->explicitFrameMargins.left() == left) + return; + + d->explicitFrameMargins.setLeft(left); + d->automaticFrameMargins = false; + updateDecorations(); + + emit frameMarginChanged(); +} + +int QWaylandQtShellChrome::frameMarginLeft() const +{ + Q_D(const QWaylandQtShellChrome); + if (d->shellSurface == nullptr) + return 0; + return d->shellSurface->frameMarginLeft(); +} + +/*! + * \qmlproperty int QtShellChrome::frameMarginRight + * + * Sets the size of the right margin of the QtShellChrome which is reserved for window decorations. + * By default, this will equal the width of the \l rightResizeHandle if it is set. Otherwise it will + * be 0. + * + * \note By setting this property explicitly, all default frame margins will be overridden with + * their corresponding properties. + */ +void QWaylandQtShellChrome::setFrameMarginRight(int right) +{ + Q_D(QWaylandQtShellChrome); + if (d->explicitFrameMargins.right() == right) + return; + + d->explicitFrameMargins.setRight(right); + d->automaticFrameMargins = false; + updateDecorations(); + + emit frameMarginChanged(); +} + +int QWaylandQtShellChrome::frameMarginRight() const +{ + Q_D(const QWaylandQtShellChrome); + if (d->shellSurface == nullptr) + return 0; + return d->shellSurface->frameMarginRight(); +} + +/*! + * \qmlproperty int QtShellChrome::frameMarginTop + * + * Sets the size of the top margin of the QtShellChrome which is reserved for window decorations. + * By default, this will equal the sum of the \l leftResizeHandle and the \l{titleBar}'s heights, + * if they are set. Otherwise it will be 0. + * + * \note By setting this property explicitly, all default frame margins will be overridden with + * their corresponding properties. + */ +void QWaylandQtShellChrome::setFrameMarginTop(int top) +{ + Q_D(QWaylandQtShellChrome); + if (d->explicitFrameMargins.top() == top) + return; + d->explicitFrameMargins.setTop(top); + d->automaticFrameMargins = false; + updateDecorations(); + + emit frameMarginChanged(); +} + +int QWaylandQtShellChrome::frameMarginTop() const +{ + Q_D(const QWaylandQtShellChrome); + if (d->shellSurface == nullptr) + return 0; + return d->shellSurface->frameMarginTop(); +} + +/*! + * \qmlproperty int QtShellChrome::frameMarginBottom + * + * Sets the size of the bottom margin of the QtShellChrome which is reserved for window decorations. + * By default, this will equal the height of the \l bottomResizeHandle if it is set. Otherwise it will + * be 0. + * + * \note By setting this property explicitly, all default frame margins will be overridden with + * their corresponding properties. + */ +void QWaylandQtShellChrome::setFrameMarginBottom(int bottom) +{ + Q_D(QWaylandQtShellChrome); + if (d->explicitFrameMargins.bottom() == bottom) + return; + d->explicitFrameMargins.setBottom(bottom); + d->automaticFrameMargins = false; + updateDecorations(); + + emit frameMarginChanged(); +} + +int QWaylandQtShellChrome::frameMarginBottom() const +{ + Q_D(const QWaylandQtShellChrome); + if (d->shellSurface == nullptr) + return 0; + return d->shellSurface->frameMarginBottom(); +} + +QT_END_NAMESPACE + +#include "moc_qwaylandqtshellchrome.cpp" diff --git a/src/imports/compositor-extensions/qtshell/qwaylandqtshellchrome.h b/src/imports/compositor-extensions/qtshell/qwaylandqtshellchrome.h new file mode 100644 index 000000000..4fb98008c --- /dev/null +++ b/src/imports/compositor-extensions/qtshell/qwaylandqtshellchrome.h @@ -0,0 +1,157 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef QWAYLANDQTSHELLCHROME_H +#define QWAYLANDQTSHELLCHROME_H + +#include <QtQuick/qquickitem.h> +#include <QtWaylandCompositor/qwaylandquickshellsurfaceitem.h> + +QT_BEGIN_NAMESPACE + +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) + Q_PROPERTY(uint windowFlags READ currentWindowFlags NOTIFY currentWindowFlagsChanged) + Q_PROPERTY(QWaylandQuickShellSurfaceItem *shellSurfaceItem READ shellSurfaceItem WRITE setShellSurfaceItem NOTIFY shellSurfaceItemChanged) + Q_PROPERTY(QRect maximizedRect READ maximizedRect WRITE setMaximizedRect NOTIFY maximizedRectChanged) + + Q_PROPERTY(int frameMarginLeft READ frameMarginLeft WRITE setFrameMarginLeft NOTIFY frameMarginChanged) + Q_PROPERTY(int frameMarginRight READ frameMarginRight WRITE setFrameMarginRight NOTIFY frameMarginChanged) + Q_PROPERTY(int frameMarginTop READ frameMarginTop WRITE setFrameMarginTop NOTIFY frameMarginChanged) + Q_PROPERTY(int frameMarginBottom READ frameMarginBottom WRITE setFrameMarginBottom NOTIFY frameMarginChanged) + + Q_PROPERTY(QQuickItem *titleBar READ titleBar WRITE setTitleBar NOTIFY titleBarChanged); + Q_PROPERTY(QQuickItem *leftResizeHandle READ leftResizeHandle WRITE setLeftResizeHandle NOTIFY leftResizeHandleChanged); + Q_PROPERTY(QQuickItem *rightResizeHandle READ rightResizeHandle WRITE setRightResizeHandle NOTIFY rightResizeHandleChanged); + Q_PROPERTY(QQuickItem *topResizeHandle READ topResizeHandle WRITE setTopResizeHandle NOTIFY topResizeHandleChanged); + Q_PROPERTY(QQuickItem *bottomResizeHandle READ bottomResizeHandle WRITE setBottomResizeHandle NOTIFY bottomResizeHandleChanged); + Q_PROPERTY(QQuickItem *topLeftResizeHandle READ topLeftResizeHandle WRITE setTopLeftResizeHandle NOTIFY topLeftResizeHandleChanged); + Q_PROPERTY(QQuickItem *topRightResizeHandle READ topRightResizeHandle WRITE setTopRightResizeHandle NOTIFY topRightResizeHandleChanged); + Q_PROPERTY(QQuickItem *bottomLeftResizeHandle READ bottomLeftResizeHandle WRITE setBottomLeftResizeHandle NOTIFY bottomLeftResizeHandleChanged); + Q_PROPERTY(QQuickItem *bottomRightResizeHandle READ bottomRightResizeHandle WRITE setBottomRightResizeHandle NOTIFY bottomRightResizeHandleChanged); +public: + QWaylandQtShellChrome(QQuickItem *parent = nullptr); + ~QWaylandQtShellChrome() override; + + bool hasTitleBar() const; + bool hasDecorations() const; + uint currentWindowState() const; + uint currentWindowFlags() const; + + void setMaximizedRect(const QRect &rect); + QRect maximizedRect() const; + + void setShellSurfaceItem(QWaylandQuickShellSurfaceItem *shellSurfaceItem); + QWaylandQuickShellSurfaceItem *shellSurfaceItem() const; + + void setTitleBar(QQuickItem *item); + QQuickItem *titleBar() const; + + void setLeftResizeHandle(QQuickItem *item); + QQuickItem *leftResizeHandle() const; + + void setRightResizeHandle(QQuickItem *item); + QQuickItem *rightResizeHandle() const; + + void setTopResizeHandle(QQuickItem *item); + QQuickItem *topResizeHandle() const; + + void setBottomResizeHandle(QQuickItem *item); + QQuickItem *bottomResizeHandle() const; + + void setTopLeftResizeHandle(QQuickItem *item); + QQuickItem *topLeftResizeHandle() const; + + void setBottomLeftResizeHandle(QQuickItem *item); + QQuickItem *bottomLeftResizeHandle() const; + + void setTopRightResizeHandle(QQuickItem *item); + QQuickItem *topRightResizeHandle() const; + + void setBottomRightResizeHandle(QQuickItem *item); + QQuickItem *bottomRightResizeHandle() const; + + int frameMarginLeft() const; + void setFrameMarginLeft(int left); + + int frameMarginRight() const; + void setFrameMarginRight(int right); + + int frameMarginTop() const; + void setFrameMarginTop(int top); + + int frameMarginBottom() const; + void setFrameMarginBottom(int bottom); + +Q_SIGNALS: + void currentWindowStateChanged(); + void currentWindowFlagsChanged(); + void windowMetaInfoChanged(); + void shellSurfaceItemChanged(); + void maximizedRectChanged(); + + void titleBarChanged(); + void leftResizeHandleChanged(); + void rightResizeHandleChanged(); + void topResizeHandleChanged(); + void bottomResizeHandleChanged(); + void topLeftResizeHandleChanged(); + void bottomLeftResizeHandleChanged(); + void topRightResizeHandleChanged(); + void bottomRightResizeHandleChanged(); + + void activated(); + void deactivated(); + + void clientDestroyed(); + void frameMarginChanged(); + +public Q_SLOTS: + void raise(); + void lower(); + void toggleMaximized(); + void toggleMinimized(); + void toggleFullScreen(); + void activate(); + void deactivate(); + +private Q_SLOTS: + void activateOnGrab(QPointingDevice::GrabTransition transition); + void updateSurface(); + void updateShellSurface(); + void updateWindowFlags(); + void updateWindowState(); + void updateGeometry(); + void updateDecorations(); + void updateActiveState(); + void updateAutomaticPosition(); + void stopGrab(); + void leftResize(); + void rightResize(); + void topResize(); + void bottomResize(); + void topLeftResize(); + void topRightResize(); + void bottomLeftResize(); + void bottomRightResize(); + void titleBarMove(); + +protected: + QWaylandQtShellChrome(QWaylandQtShellChromePrivate &dd, QQuickItem *parent); + +private: + void setWindowState(uint nextState); + void init(); + QRect maxContentRect() const; +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDQTSHELLSURFACEITEM_H diff --git a/src/imports/compositor-extensions/qtshell/qwaylandqtshellchrome_p.h b/src/imports/compositor-extensions/qtshell/qwaylandqtshellchrome_p.h new file mode 100644 index 000000000..b62225794 --- /dev/null +++ b/src/imports/compositor-extensions/qtshell/qwaylandqtshellchrome_p.h @@ -0,0 +1,87 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef QWAYLANDQTSHELLCHROME_P_H +#define QWAYLANDQTSHELLCHROME_P_H + +#include "qwaylandqtshell.h" + +#include <QtCore/qpointer.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/private/qquickdraghandler_p.h> + +#include <QtWaylandCompositor/qwaylandquickshellsurfaceitem.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. +// + +QT_BEGIN_NAMESPACE + +class QWaylandQtShellChromePrivate : public QQuickItemPrivate +{ +public: + void updateDecorationInteraction(quint8 flags, const QQuickHandlerPoint ¢roid); + QPointF constrainPoint(const QPointF &point) const; + + bool positionSet = false; + bool automaticFrameMargins = true; + QMargins explicitFrameMargins; + + uint currentState = Qt::WindowNoState; + uint defaultFlags = Qt::Window + | Qt::WindowMaximizeButtonHint + | Qt::WindowMinimizeButtonHint + | Qt::WindowCloseButtonHint; + uint currentFlags = defaultFlags; + QRect restoreGeometry = QRect(0, 0, 100, 100); + QRect maximizedRect; + QPointer<QWaylandQuickShellSurfaceItem> shellSurfaceItem; + QPointer<QWaylandQtShellSurface> shellSurface; + QPointer<QWaylandSurface> surface; + QPointer<QWaylandQtShell> shell; + + enum class DecorationInteraction : quint8 { + None = 0, + WestBound = 1, + EastBound = 2, + NorthBound = 4, + SouthBound = 8, + TitleBar = 16 + }; + + quint8 decorationInteraction = quint8(DecorationInteraction::None); + QPointF decorationInteractionPosition; + QRect decorationInteractionGeometry; + + QQuickItem *leftResizeHandle = nullptr; + QQuickDragHandler *leftResizeHandleHandler = nullptr; + QQuickDragHandler *rightResizeHandleHandler = nullptr; + QQuickDragHandler *topResizeHandleHandler = nullptr; + QQuickDragHandler *bottomResizeHandleHandler = nullptr; + QQuickDragHandler *topLeftResizeHandleHandler = nullptr; + QQuickDragHandler *topRightResizeHandleHandler = nullptr; + QQuickDragHandler *bottomLeftResizeHandleHandler = nullptr; + QQuickDragHandler *bottomRightResizeHandleHandler = nullptr; + QQuickDragHandler *titleBarHandler = nullptr; + + QQuickItem *rightResizeHandle = nullptr; + QQuickItem *topResizeHandle = nullptr; + QQuickItem *bottomResizeHandle = nullptr; + QQuickItem *topLeftResizeHandle = nullptr; + QQuickItem *bottomLeftResizeHandle = nullptr; + QQuickItem *topRightResizeHandle = nullptr; + QQuickItem *bottomRightResizeHandle = nullptr; + QQuickItem *titleBar = nullptr; +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDQTSHELLCHROME_P_H diff --git a/src/imports/compositor-extensions/qtshell/qwaylandqtshellintegration.cpp b/src/imports/compositor-extensions/qtshell/qwaylandqtshellintegration.cpp new file mode 100644 index 000000000..07a936322 --- /dev/null +++ b/src/imports/compositor-extensions/qtshell/qwaylandqtshellintegration.cpp @@ -0,0 +1,39 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "qwaylandqtshellintegration_p.h" + +#include <QtWaylandCompositor/QWaylandCompositor> +#include <QtWaylandCompositor/QWaylandQuickShellSurfaceItem> +#include <QtWaylandCompositor/QWaylandSeat> +#include "qwaylandqtshell.h" + +QT_BEGIN_NAMESPACE + +namespace QtWayland { + +QtShellIntegration::QtShellIntegration(QWaylandQuickShellSurfaceItem *item) + : QWaylandQuickShellIntegration(item) + , m_item(item) + , m_shellSurface(qobject_cast<QWaylandQtShellSurface *>(item->shellSurface())) +{ + m_item->setSurface(m_shellSurface->surface()); + connect(m_shellSurface, &QWaylandQtShellSurface::destroyed, + this, &QtShellIntegration::handleQtShellSurfaceDestroyed); +} + +QtShellIntegration::~QtShellIntegration() +{ + m_item->setSurface(nullptr); +} + +void QtShellIntegration::handleQtShellSurfaceDestroyed() +{ + m_shellSurface = nullptr; +} + +} + +QT_END_NAMESPACE + +#include "moc_qwaylandqtshellintegration_p.cpp" diff --git a/src/imports/compositor-extensions/qtshell/qwaylandqtshellintegration_p.h b/src/imports/compositor-extensions/qtshell/qwaylandqtshellintegration_p.h new file mode 100644 index 000000000..ea9cac634 --- /dev/null +++ b/src/imports/compositor-extensions/qtshell/qwaylandqtshellintegration_p.h @@ -0,0 +1,45 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef QWAYLANDQTSHELLINTEGRATION_H +#define QWAYLANDQTSHELLINTEGRATION_H + +#include <QtWaylandCompositor/private/qwaylandquickshellsurfaceitem_p.h> + +#include "qwaylandqtshell.h" + +QT_BEGIN_NAMESPACE + +// +// 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. +// + +namespace QtWayland { + +class QtShellIntegration : public QWaylandQuickShellIntegration +{ + Q_OBJECT +public: + QtShellIntegration(QWaylandQuickShellSurfaceItem *item); + ~QtShellIntegration() override; + +private Q_SLOTS: + void handleQtShellSurfaceDestroyed(); + +private: + QWaylandQuickShellSurfaceItem *m_item = nullptr; + QWaylandQtShellSurface *m_shellSurface = nullptr; +}; + +} + +QT_END_NAMESPACE + +#endif // QWAYLANDQTSHELLINTEGRATION_H diff --git a/src/imports/compositor-extensions/wlshell/CMakeLists.txt b/src/imports/compositor-extensions/wlshell/CMakeLists.txt new file mode 100644 index 000000000..8987621d3 --- /dev/null +++ b/src/imports/compositor-extensions/wlshell/CMakeLists.txt @@ -0,0 +1,17 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +qt_internal_add_qml_module(WaylandCompositorWLShell + URI "QtWayland.Compositor.WlShell" + VERSION "${PROJECT_VERSION}" + SOURCES + 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) 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/xdgshell/CMakeLists.txt b/src/imports/compositor-extensions/xdgshell/CMakeLists.txt new file mode 100644 index 000000000..32f032d93 --- /dev/null +++ b/src/imports/compositor-extensions/xdgshell/CMakeLists.txt @@ -0,0 +1,18 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +qt_internal_add_qml_module(WaylandCompositorXdgShell + URI "QtWayland.Compositor.XdgShell" + VERSION "${PROJECT_VERSION}" + SOURCES + 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) 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/WaylandCursorItem.qml b/src/imports/compositor/WaylandCursorItem.qml deleted file mode 100644 index bb0a840a4..000000000 --- a/src/imports/compositor/WaylandCursorItem.qml +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtWaylandCompositor module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 -import QtWayland.Compositor 1.0 -import QtQuick.Window 2.11 - -WaylandQuickItem { - id: cursorItem - property QtObject seat - property int hotspotX: 0 - property int hotspotY: 0 - - visible: cursorItem.surface != null - inputEventsEnabled: false - enabled: false - transform: Translate { - // If we've set an output scale factor different from the device pixel ratio - // then the item will be rendered scaled, so we need to shift the hotspot accordingly - x: -hotspotX * (output ? output.scaleFactor / Screen.devicePixelRatio : 1) - y: -hotspotY * (output ? output.scaleFactor / Screen.devicePixelRatio : 1) - } - - Connections { - target: seat - onCursorSurfaceRequest: { - cursorItem.surface = surface; - cursorItem.hotspotX = hotspotX; - cursorItem.hotspotY = hotspotY; - } - } - - WaylandQuickItem { - id: dragIcon - property point offset - - x: cursorItem.hotspotX + offset.x - y: cursorItem.hotspotY + offset.y - z: -1 - surface: cursorItem.seat ? cursorItem.seat.drag.icon : null - - Connections { - target: dragIcon.surface - onOffsetForNextFrame: dragIcon.offset = offset; - } - } -} diff --git a/src/imports/compositor/WaylandOutputWindow.qml b/src/imports/compositor/WaylandOutputWindow.qml deleted file mode 100644 index d75a20c98..000000000 --- a/src/imports/compositor/WaylandOutputWindow.qml +++ /dev/null @@ -1,48 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtWaylandCompositor module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 -import QtQuick.Window 2.2 - -Window { - id: window - property QtObject compositor - property QtObject output - property bool automaticFrameCallback: false - - Component.onCompleted: { - if (!compositor) { - console.warn("WaylandOutputWindow initiated without compositor. This leads to undefined behavior"); - return; - } - output = compositor.addOutput(window); - output.automaticFrameCallbacks = window.automaticFrameCallback; - } -} - diff --git a/src/imports/compositor/compositor.pro b/src/imports/compositor/compositor.pro deleted file mode 100644 index 59dd7824c..000000000 --- a/src/imports/compositor/compositor.pro +++ /dev/null @@ -1,45 +0,0 @@ -CXX_MODULE = qml -TARGET = qwaylandcompositorplugin -TARGETPATH = QtWayland/Compositor -IMPORT_VERSION = 1.$$QT_MINOR_VERSION - -HEADERS += \ - qwaylandmousetracker_p.h - -SOURCES += \ - qwaylandquickcompositorplugin.cpp \ - qwaylandmousetracker.cpp - -COMPOSITOR_QML_FILES += \ - WaylandOutputWindow.qml \ - WaylandCursorItem.qml - -# Create the resource file -GENERATED_RESOURCE_FILE = $$OUT_PWD/compositor.qrc - -RESOURCE_CONTENT = \ - "<RCC>" \ - "<qresource prefix=\"/QtWayland/Compositor\">" - -for(resourcefile, COMPOSITOR_QML_FILES) { - resourcefileabsolutepath = $$absolute_path($$resourcefile) - relativepath_in = $$relative_path($$resourcefileabsolutepath, $$_PRO_FILE_PWD_) - relativepath_out = $$relative_path($$resourcefileabsolutepath, $$OUT_PWD) - RESOURCE_CONTENT += "<file alias=\"$$relativepath_in\">$$relativepath_out</file>" -} - -RESOURCE_CONTENT += \ - "</qresource>" \ - "</RCC>" - -write_file($$GENERATED_RESOURCE_FILE, RESOURCE_CONTENT)|error("Aborting.") - -RESOURCES += $$GENERATED_RESOURCE_FILE - -# In case of a debug build, deploy the QML files too -CONFIG(debug, debug|release): QML_FILES += $$COMPOSITOR_QML_FILES - -QT += quick-private qml-private gui-private core-private waylandcompositor waylandcompositor-private - -QMAKE_QMLPLUGINDUMP_FLAGS = -defaultplatform -load(qml_plugin) diff --git a/src/imports/compositor/plugins.qmltypes b/src/imports/compositor/plugins.qmltypes deleted file mode 100644 index d05cf3c13..000000000 --- a/src/imports/compositor/plugins.qmltypes +++ /dev/null @@ -1,1363 +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 1.14' - -Module { - dependencies: ["QtQuick 2.0", "QtQuick.Window 2.11"] - Component { - name: "QWaylandClient" - prototype: "QObject" - exports: ["QtWayland.Compositor/WaylandClient 1.0"] - isCreatable: false - exportMetaObjectRevisions: [0] - Property { name: "compositor"; type: "QWaylandCompositor"; isReadonly: true; isPointer: true } - Property { name: "userId"; type: "qlonglong"; isReadonly: true } - Property { name: "groupId"; type: "qlonglong"; isReadonly: true } - Property { name: "processId"; type: "qlonglong"; isReadonly: true } - Method { name: "close" } - Method { - name: "kill" - Parameter { name: "signal"; type: "int" } - } - Method { name: "kill" } - } - Component { - name: "QWaylandCompositor" - prototype: "QWaylandObject" - exports: ["QtWayland.Compositor/WaylandCompositorBase 1.0"] - isCreatable: false - exportMetaObjectRevisions: [0] - Property { name: "socketName"; type: "QByteArray" } - Property { name: "created"; type: "bool"; isReadonly: true } - Property { name: "retainedSelection"; type: "bool" } - Property { name: "defaultOutput"; type: "QWaylandOutput"; isPointer: true } - Property { name: "useHardwareIntegrationExtension"; type: "bool" } - Property { name: "defaultSeat"; type: "QWaylandSeat"; isReadonly: true; isPointer: true } - Signal { - name: "socketNameChanged" - Parameter { name: "socketName"; type: "QByteArray" } - } - Signal { - name: "retainedSelectionChanged" - Parameter { name: "retainedSelection"; type: "bool" } - } - Signal { - name: "surfaceRequested" - Parameter { name: "client"; type: "QWaylandClient"; isPointer: true } - Parameter { name: "id"; type: "uint" } - Parameter { name: "version"; type: "int" } - } - Signal { - name: "surfaceCreated" - Parameter { name: "surface"; type: "QWaylandSurface"; isPointer: true } - } - Signal { - name: "surfaceAboutToBeDestroyed" - Parameter { name: "surface"; type: "QWaylandSurface"; isPointer: true } - } - Signal { - name: "subsurfaceChanged" - Parameter { name: "child"; type: "QWaylandSurface"; isPointer: true } - Parameter { name: "parent"; type: "QWaylandSurface"; isPointer: true } - } - Signal { - name: "defaultSeatChanged" - Parameter { name: "newDevice"; type: "QWaylandSeat"; isPointer: true } - Parameter { name: "oldDevice"; type: "QWaylandSeat"; isPointer: true } - } - Signal { - name: "outputAdded" - Parameter { name: "output"; type: "QWaylandOutput"; isPointer: true } - } - Signal { - name: "outputRemoved" - Parameter { name: "output"; type: "QWaylandOutput"; isPointer: true } - } - Method { name: "processWaylandEvents" } - Method { - name: "addSocketDescriptor" - Parameter { name: "fd"; type: "int" } - } - Method { - name: "destroyClientForSurface" - Parameter { name: "surface"; type: "QWaylandSurface"; isPointer: true } - } - Method { - name: "destroyClient" - Parameter { name: "client"; type: "QWaylandClient"; isPointer: true } - } - Method { - name: "outputFor" - type: "QWaylandOutput*" - Parameter { name: "window"; type: "QWindow"; isPointer: true } - } - } - Component { - name: "QWaylandCompositorExtension" - prototype: "QWaylandObject" - exports: ["QtWayland.Compositor/WaylandExtension 1.0"] - isCreatable: false - exportMetaObjectRevisions: [0] - } - Component { - name: "QWaylandDrag" - prototype: "QObject" - exports: ["QtWayland.Compositor/WaylandDrag 1.0"] - isCreatable: false - exportMetaObjectRevisions: [0] - Property { name: "icon"; type: "QWaylandSurface"; isReadonly: true; isPointer: true } - Property { name: "visible"; type: "bool"; isReadonly: true } - Signal { name: "dragStarted" } - Method { - name: "dragMove" - Parameter { name: "target"; type: "QWaylandSurface"; isPointer: true } - Parameter { name: "pos"; type: "QPointF" } - } - Method { name: "drop" } - Method { name: "cancelDrag" } - } - Component { name: "QWaylandIdleInhibitManagerV1"; prototype: "QWaylandCompositorExtension" } - Component { - name: "QWaylandIdleInhibitManagerV1QuickExtension" - defaultProperty: "data" - prototype: "QWaylandIdleInhibitManagerV1" - exports: ["QtWayland.Compositor/IdleInhibitManagerV1 1.14"] - exportMetaObjectRevisions: [0] - Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } - } - 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 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } - } - Component { - name: "QWaylandIviSurface" - defaultProperty: "data" - prototype: "QWaylandShellSurface" - exports: ["QtWayland.Compositor/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: "QWaylandKeymap" - defaultProperty: "data" - prototype: "QObject" - exports: ["QtWayland.Compositor/WaylandKeymap 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } - Property { name: "layout"; type: "string" } - Property { name: "variant"; type: "string" } - Property { name: "options"; type: "string" } - Property { name: "rules"; type: "string" } - Property { name: "model"; type: "string" } - } - Component { - name: "QWaylandMouseTracker" - defaultProperty: "data" - prototype: "QQuickItem" - exports: ["QtWayland.Compositor/WaylandMouseTracker 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "mouseX"; type: "double"; isReadonly: true } - Property { name: "mouseY"; type: "double"; isReadonly: true } - Property { name: "containsMouse"; type: "bool"; isReadonly: true } - Property { name: "windowSystemCursorEnabled"; type: "bool" } - Signal { name: "hoveredChanged" } - } - Component { name: "QWaylandObject"; prototype: "QObject" } - Component { - name: "QWaylandOutput" - prototype: "QWaylandObject" - exports: ["QtWayland.Compositor/WaylandOutputBase 1.0"] - isCreatable: false - exportMetaObjectRevisions: [0] - Enum { - name: "Subpixel" - values: { - "SubpixelUnknown": 0, - "SubpixelNone": 1, - "SubpixelHorizontalRgb": 2, - "SubpixelHorizontalBgr": 3, - "SubpixelVerticalRgb": 4, - "SubpixelVerticalBgr": 5 - } - } - Enum { - name: "Transform" - values: { - "TransformNormal": 0, - "Transform90": 1, - "Transform180": 2, - "Transform270": 3, - "TransformFlipped": 4, - "TransformFlipped90": 5, - "TransformFlipped180": 6, - "TransformFlipped270": 7 - } - } - Property { name: "compositor"; type: "QWaylandCompositor"; isPointer: true } - Property { name: "window"; type: "QWindow"; isPointer: true } - Property { name: "manufacturer"; type: "string" } - Property { name: "model"; type: "string" } - Property { name: "position"; type: "QPoint" } - Property { name: "geometry"; type: "QRect"; isReadonly: true } - Property { name: "availableGeometry"; type: "QRect" } - Property { name: "physicalSize"; type: "QSize" } - Property { name: "subpixel"; type: "QWaylandOutput::Subpixel" } - Property { name: "transform"; type: "QWaylandOutput::Transform" } - Property { name: "scaleFactor"; type: "int" } - Property { name: "sizeFollowsWindow"; type: "bool" } - Signal { name: "modeAdded" } - Signal { name: "currentModeChanged" } - Signal { name: "physicalSizeFollowsSizeChanged" } - Signal { name: "windowDestroyed" } - } - Component { - name: "QWaylandQtWindowManager" - prototype: "QWaylandCompositorExtension" - Property { name: "showIsFullScreen"; type: "bool" } - Signal { - name: "openUrl" - Parameter { name: "client"; type: "QWaylandClient"; isPointer: true } - Parameter { name: "url"; type: "QUrl" } - } - } - Component { - name: "QWaylandQtWindowManagerQuickExtension" - defaultProperty: "data" - prototype: "QWaylandQtWindowManager" - exports: ["QtWayland.Compositor/QtWindowManager 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } - } - Component { name: "QWaylandQuickCompositor"; prototype: "QWaylandCompositor" } - Component { - name: "QWaylandQuickCompositorQuickExtensionContainer" - defaultProperty: "data" - prototype: "QWaylandQuickCompositor" - exports: ["QtWayland.Compositor/WaylandCompositor 1.0"] - exportMetaObjectRevisions: [0] - Property { - name: "extensions" - type: "QWaylandCompositorExtension" - isList: true - isReadonly: true - } - Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } - } - Component { - name: "QWaylandQuickHardwareLayer" - prototype: "QObject" - exports: ["QtWayland.Compositor/WaylandHardwareLayer 1.2"] - exportMetaObjectRevisions: [0] - Property { name: "stackingLevel"; type: "int" } - } - Component { - name: "QWaylandQuickItem" - defaultProperty: "data" - prototype: "QQuickItem" - exports: [ - "QtWayland.Compositor/WaylandQuickItem 1.0", - "QtWayland.Compositor/WaylandQuickItem 1.13" - ] - exportMetaObjectRevisions: [0, 13] - Property { name: "compositor"; type: "QWaylandCompositor"; isReadonly: true; isPointer: true } - Property { name: "surface"; type: "QWaylandSurface"; isPointer: true } - Property { name: "paintEnabled"; type: "bool" } - Property { name: "touchEventsEnabled"; type: "bool" } - Property { name: "origin"; type: "QWaylandSurface::Origin"; isReadonly: true } - Property { name: "inputEventsEnabled"; type: "bool" } - Property { name: "focusOnClick"; type: "bool" } - Property { name: "sizeFollowsSurface"; type: "bool" } - Property { name: "subsurfaceHandler"; type: "QObject"; isPointer: true } - Property { name: "output"; type: "QWaylandOutput"; isPointer: true } - Property { name: "bufferLocked"; type: "bool" } - Property { name: "allowDiscardFrontBuffer"; type: "bool" } - Signal { name: "surfaceDestroyed" } - Signal { - name: "mouseMove" - Parameter { name: "windowPosition"; type: "QPointF" } - } - Signal { name: "mouseRelease" } - Method { - name: "takeFocus" - Parameter { name: "device"; type: "QWaylandSeat"; isPointer: true } - } - Method { name: "takeFocus" } - Method { - name: "setPaintEnabled" - Parameter { name: "paintEnabled"; type: "bool" } - } - Method { name: "raise" } - Method { name: "lower" } - Method { - name: "sendMouseMoveEvent" - Parameter { name: "position"; type: "QPointF" } - Parameter { name: "seat"; type: "QWaylandSeat"; isPointer: true } - } - Method { - name: "sendMouseMoveEvent" - Parameter { name: "position"; type: "QPointF" } - } - Method { - name: "mapToSurface" - type: "QPointF" - Parameter { name: "point"; type: "QPointF" } - } - Method { - name: "mapFromSurface" - revision: 13 - type: "QPointF" - Parameter { name: "point"; type: "QPointF" } - } - Method { - name: "inputMethodQuery" - type: "QVariant" - Parameter { name: "query"; type: "Qt::InputMethodQuery" } - Parameter { name: "argument"; type: "QVariant" } - } - Method { name: "setPrimary" } - } - Component { - name: "QWaylandQuickOutput" - defaultProperty: "data" - prototype: "QWaylandOutput" - exports: ["QtWayland.Compositor/WaylandOutput 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } - Property { name: "automaticFrameCallback"; type: "bool" } - Method { name: "updateStarted" } - } - Component { - name: "QWaylandQuickShellSurfaceItem" - defaultProperty: "data" - prototype: "QWaylandQuickItem" - exports: ["QtWayland.Compositor/ShellSurfaceItem 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "shellSurface"; type: "QWaylandShellSurface"; isPointer: true } - Property { name: "moveItem"; type: "QQuickItem"; isPointer: true } - Property { name: "autoCreatePopupItems"; type: "bool" } - } - Component { - name: "QWaylandQuickSurface" - defaultProperty: "data" - prototype: "QWaylandSurface" - exports: [ - "QtWayland.Compositor/WaylandSurface 1.0", - "QtWayland.Compositor/WaylandSurface 1.13" - ] - exportMetaObjectRevisions: [0, 13] - Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } - Property { name: "useTextureAlpha"; type: "bool" } - Property { name: "clientRenderingEnabled"; type: "bool" } - } - Component { - name: "QWaylandQuickXdgOutputV1" - defaultProperty: "data" - prototype: "QWaylandXdgOutputV1" - exports: ["QtWayland.Compositor/XdgOutputV1 1.14"] - exportMetaObjectRevisions: [0] - } - Component { - name: "QWaylandResource" - exports: ["QtWayland.Compositor/WaylandResource 1.0"] - isCreatable: false - exportMetaObjectRevisions: [0] - } - Component { - name: "QWaylandSeat" - prototype: "QWaylandObject" - exports: ["QtWayland.Compositor/WaylandSeat 1.0"] - isCreatable: false - exportMetaObjectRevisions: [0] - Enum { - name: "CapabilityFlags" - values: { - "Pointer": 1, - "Keyboard": 2, - "Touch": 4, - "DefaultCapabilities": 7 - } - } - Property { name: "drag"; type: "QWaylandDrag"; isReadonly: true; isPointer: true } - Property { name: "keymap"; type: "QWaylandKeymap"; isReadonly: true; isPointer: true } - Signal { - name: "mouseFocusChanged" - Parameter { name: "newFocus"; type: "QWaylandView"; isPointer: true } - Parameter { name: "oldFocus"; type: "QWaylandView"; isPointer: true } - } - Signal { - name: "keyboardFocusChanged" - Parameter { name: "newFocus"; type: "QWaylandSurface"; isPointer: true } - Parameter { name: "oldFocus"; type: "QWaylandSurface"; isPointer: true } - } - Signal { - name: "cursorSurfaceRequest" - Parameter { name: "surface"; type: "QWaylandSurface"; isPointer: true } - Parameter { name: "hotspotX"; type: "int" } - Parameter { name: "hotspotY"; type: "int" } - } - Method { - name: "sendKeyEvent" - Parameter { name: "qtKey"; type: "int" } - Parameter { name: "pressed"; type: "bool" } - } - Method { - name: "sendTouchPointPressed" - type: "uint" - Parameter { name: "surface"; type: "QWaylandSurface"; isPointer: true } - Parameter { name: "id"; type: "int" } - Parameter { name: "position"; type: "QPointF" } - } - Method { - name: "sendTouchPointReleased" - type: "uint" - Parameter { name: "surface"; type: "QWaylandSurface"; isPointer: true } - Parameter { name: "id"; type: "int" } - Parameter { name: "position"; type: "QPointF" } - } - Method { - name: "sendTouchPointMoved" - type: "uint" - Parameter { name: "surface"; type: "QWaylandSurface"; isPointer: true } - Parameter { name: "id"; type: "int" } - Parameter { name: "position"; type: "QPointF" } - } - Method { - name: "sendTouchFrameEvent" - Parameter { name: "client"; type: "QWaylandClient"; isPointer: true } - } - Method { - name: "sendTouchCancelEvent" - Parameter { name: "client"; type: "QWaylandClient"; isPointer: true } - } - } - Component { - name: "QWaylandShell" - prototype: "QWaylandCompositorExtension" - exports: ["QtWayland.Compositor/Shell 1.0"] - isCreatable: false - exportMetaObjectRevisions: [0] - Enum { - name: "FocusPolicy" - values: { - "AutomaticFocus": 0, - "ManualFocus": 1 - } - } - Property { name: "focusPolicy"; type: "FocusPolicy" } - } - Component { - name: "QWaylandShellSurface" - prototype: "QWaylandCompositorExtension" - exports: ["QtWayland.Compositor/ShellSurface 1.0"] - isCreatable: false - exportMetaObjectRevisions: [0] - Property { name: "windowType"; type: "Qt::WindowType"; isReadonly: true } - } - Component { - name: "QWaylandSurface" - prototype: "QWaylandObject" - exports: ["QtWayland.Compositor/WaylandSurfaceBase 1.0"] - isCreatable: false - exportMetaObjectRevisions: [0] - Enum { - name: "Origin" - values: { - "OriginTopLeft": 0, - "OriginBottomLeft": 1 - } - } - Property { name: "client"; type: "QWaylandClient"; isReadonly: true; isPointer: true } - Property { name: "sourceGeometry"; revision: 13; type: "QRectF"; isReadonly: true } - Property { name: "destinationSize"; revision: 13; type: "QSize"; isReadonly: true } - Property { name: "bufferSize"; revision: 13; type: "QSize"; isReadonly: true } - Property { name: "size"; type: "QSize"; isReadonly: true } - Property { name: "bufferScale"; type: "int"; isReadonly: true } - Property { name: "contentOrientation"; type: "Qt::ScreenOrientation"; isReadonly: true } - Property { name: "origin"; type: "QWaylandSurface::Origin"; isReadonly: true } - Property { name: "hasContent"; type: "bool"; isReadonly: true } - Property { name: "cursorSurface"; type: "bool" } - Property { name: "inhibitsIdle"; revision: 14; type: "bool"; isReadonly: true } - Signal { - name: "damaged" - Parameter { name: "rect"; type: "QRegion" } - } - Signal { - name: "parentChanged" - Parameter { name: "newParent"; type: "QWaylandSurface"; isPointer: true } - Parameter { name: "oldParent"; type: "QWaylandSurface"; isPointer: true } - } - Signal { - name: "childAdded" - Parameter { name: "child"; type: "QWaylandSurface"; isPointer: true } - } - Signal { name: "sourceGeometryChanged"; revision: 13 } - Signal { name: "destinationSizeChanged"; revision: 13 } - Signal { name: "bufferSizeChanged"; revision: 13 } - Signal { - name: "offsetForNextFrame" - Parameter { name: "offset"; type: "QPoint" } - } - Signal { name: "surfaceDestroyed" } - Signal { - name: "subsurfacePositionChanged" - Parameter { name: "position"; type: "QPoint" } - } - Signal { - name: "subsurfacePlaceAbove" - Parameter { name: "sibling"; type: "QWaylandSurface"; isPointer: true } - } - Signal { - name: "subsurfacePlaceBelow" - Parameter { name: "sibling"; type: "QWaylandSurface"; isPointer: true } - } - Signal { - name: "dragStarted" - Parameter { name: "drag"; type: "QWaylandDrag"; isPointer: true } - } - Signal { name: "inhibitsIdleChanged"; revision: 14 } - Signal { - name: "configure" - Parameter { name: "hasBuffer"; type: "bool" } - } - Signal { name: "redraw" } - Method { name: "updateSelection" } - Method { - name: "initialize" - Parameter { name: "compositor"; type: "QWaylandCompositor"; isPointer: true } - Parameter { name: "client"; type: "QWaylandClient"; isPointer: true } - Parameter { name: "id"; type: "uint" } - Parameter { name: "version"; type: "int" } - } - Method { name: "destroy" } - Method { name: "isDestroyed"; type: "bool" } - Method { name: "frameStarted" } - Method { name: "sendFrameCallbacks" } - } - Component { name: "QWaylandTextInputManager"; prototype: "QWaylandCompositorExtension" } - Component { - name: "QWaylandTextInputManagerQuickExtension" - defaultProperty: "data" - prototype: "QWaylandTextInputManager" - exports: ["QtWayland.Compositor/TextInputManager 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } - } - Component { name: "QWaylandWlScaler"; prototype: "QWaylandCompositorExtension" } - Component { - name: "QWaylandWlScalerQuickExtension" - defaultProperty: "data" - prototype: "QWaylandWlScaler" - exports: ["QtWayland.Compositor/WlScaler 1.13"] - exportMetaObjectRevisions: [0] - Property { name: "data"; type: "QObject"; isList: true; 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 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } - } - Component { - name: "QWaylandWlShellSurface" - defaultProperty: "data" - prototype: "QWaylandShellSurface" - exports: ["QtWayland.Compositor/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" } - } - Component { - name: "QWaylandXdgDecorationManagerV1" - prototype: "QWaylandCompositorExtension" - Property { name: "preferredMode"; type: "QWaylandXdgToplevel::DecorationMode" } - } - Component { - name: "QWaylandXdgDecorationManagerV1QuickExtension" - defaultProperty: "data" - prototype: "QWaylandXdgDecorationManagerV1" - exports: ["QtWayland.Compositor/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/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/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: 14 } - } - Component { - name: "QWaylandXdgPopupV5" - defaultProperty: "data" - prototype: "QWaylandShellSurface" - exports: ["QtWayland.Compositor/XdgPopupV5 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } - Property { name: "shell"; type: "QWaylandXdgShellV5"; isReadonly: true; isPointer: true } - Property { name: "surface"; type: "QWaylandSurface"; isReadonly: true; isPointer: true } - Property { name: "parentSurface"; type: "QWaylandSurface"; isReadonly: true; isPointer: true } - Property { name: "position"; type: "QPoint"; isReadonly: true } - Method { - name: "initialize" - Parameter { name: "shell"; type: "QWaylandXdgShellV5"; isPointer: true } - Parameter { name: "surface"; type: "QWaylandSurface"; isPointer: true } - Parameter { name: "parentSurface"; type: "QWaylandSurface"; isPointer: true } - Parameter { name: "position"; type: "QPoint" } - Parameter { name: "resource"; type: "QWaylandResource" } - } - Method { name: "sendPopupDone" } - } - Component { - name: "QWaylandXdgPopupV6" - prototype: "QObject" - exports: ["QtWayland.Compositor/XdgPopupV6 1.1"] - isCreatable: false - exportMetaObjectRevisions: [0] - Property { name: "xdgSurface"; type: "QWaylandXdgSurfaceV6"; isReadonly: true; isPointer: true } - Property { - name: "parentXdgSurface" - type: "QWaylandXdgSurfaceV6" - 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: 14 } - } - 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 1.3"] - exportMetaObjectRevisions: [0] - Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } - } - Component { - name: "QWaylandXdgShellV5" - prototype: "QWaylandShell" - exports: ["QtWayland.Compositor/XdgShellV5Base 1.0"] - isCreatable: false - exportMetaObjectRevisions: [0] - Signal { - name: "xdgSurfaceRequested" - Parameter { name: "surface"; type: "QWaylandSurface"; isPointer: true } - Parameter { name: "resource"; type: "QWaylandResource" } - } - Signal { - name: "xdgSurfaceCreated" - Parameter { name: "xdgSurface"; type: "QWaylandXdgSurfaceV5"; isPointer: true } - } - Signal { - name: "xdgPopupCreated" - Parameter { name: "xdgPopup"; type: "QWaylandXdgPopupV5"; isPointer: true } - } - Signal { - name: "xdgPopupRequested" - Parameter { name: "surface"; type: "QWaylandSurface"; isPointer: true } - Parameter { name: "parent"; type: "QWaylandSurface"; isPointer: true } - Parameter { name: "seat"; type: "QWaylandSeat"; isPointer: true } - Parameter { name: "position"; type: "QPoint" } - Parameter { name: "resource"; type: "QWaylandResource" } - } - Signal { - name: "pong" - Parameter { name: "serial"; type: "uint" } - } - Method { - name: "ping" - type: "uint" - Parameter { name: "client"; type: "QWaylandClient"; isPointer: true } - } - Method { name: "closeAllPopups" } - } - Component { - name: "QWaylandXdgShellV5QuickExtension" - defaultProperty: "data" - prototype: "QWaylandXdgShellV5" - exports: ["QtWayland.Compositor/XdgShellV5 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } - } - Component { - name: "QWaylandXdgShellV6" - prototype: "QWaylandShell" - Signal { - name: "xdgSurfaceCreated" - Parameter { name: "xdgSurface"; type: "QWaylandXdgSurfaceV6"; isPointer: true } - } - Signal { - name: "toplevelCreated" - Parameter { name: "toplevel"; type: "QWaylandXdgToplevelV6"; isPointer: true } - Parameter { name: "xdgSurface"; type: "QWaylandXdgSurfaceV6"; isPointer: true } - } - Signal { - name: "popupCreated" - Parameter { name: "popup"; type: "QWaylandXdgPopupV6"; isPointer: true } - Parameter { name: "xdgSurface"; type: "QWaylandXdgSurfaceV6"; isPointer: true } - } - Signal { - name: "pong" - Parameter { name: "serial"; type: "uint" } - } - Method { - name: "ping" - type: "uint" - Parameter { name: "client"; type: "QWaylandClient"; isPointer: true } - } - } - Component { - name: "QWaylandXdgShellV6QuickExtension" - defaultProperty: "data" - prototype: "QWaylandXdgShellV6" - exports: ["QtWayland.Compositor/XdgShellV6 1.1"] - exportMetaObjectRevisions: [0] - Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } - } - Component { - name: "QWaylandXdgSurface" - defaultProperty: "data" - prototype: "QWaylandShellSurface" - exports: ["QtWayland.Compositor/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: "QWaylandXdgSurfaceV5" - defaultProperty: "data" - prototype: "QWaylandShellSurface" - exports: ["QtWayland.Compositor/XdgSurfaceV5 1.0"] - exportMetaObjectRevisions: [0] - Enum { - name: "State" - values: { - "MaximizedState": 1, - "FullscreenState": 2, - "ResizingState": 3, - "ActivatedState": 4 - } - } - 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: "shell"; type: "QWaylandXdgShellV5"; isReadonly: true; isPointer: true } - Property { name: "surface"; type: "QWaylandSurface"; isReadonly: true; isPointer: true } - Property { - name: "parentSurface" - type: "QWaylandXdgSurfaceV5" - isReadonly: true - isPointer: true - } - Property { name: "title"; type: "string"; isReadonly: true } - Property { name: "appId"; type: "string"; isReadonly: true } - Property { name: "windowGeometry"; type: "QRect"; 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 } - Signal { - name: "showWindowMenu" - Parameter { name: "seat"; type: "QWaylandSeat"; isPointer: true } - Parameter { name: "localSurfacePosition"; type: "QPoint" } - } - 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: "setTopLevel" } - Signal { name: "setTransient" } - Signal { name: "setMaximized" } - Signal { name: "unsetMaximized" } - Signal { - name: "setFullscreen" - Parameter { name: "output"; type: "QWaylandOutput"; isPointer: true } - } - Signal { name: "unsetFullscreen" } - Signal { name: "setMinimized" } - Signal { - name: "ackConfigure" - Parameter { name: "serial"; type: "uint" } - } - Method { - name: "initialize" - Parameter { name: "xdgShell"; type: "QWaylandXdgShellV5"; 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: "edge"; type: "ResizeEdge" } - } - Method { - name: "sendConfigure" - type: "uint" - Parameter { name: "size"; type: "QSize" } - Parameter { name: "states"; type: "QVector<uint>" } - } - Method { - name: "sendConfigure" - type: "uint" - Parameter { name: "size"; type: "QSize" } - Parameter { name: "states"; type: "QVector<State>" } - } - 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" } - } - } - Component { - name: "QWaylandXdgSurfaceV6" - defaultProperty: "data" - prototype: "QWaylandShellSurface" - exports: ["QtWayland.Compositor/XdgSurfaceV6 1.1"] - exportMetaObjectRevisions: [0] - Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } - Property { name: "shell"; type: "QWaylandXdgShellV6"; isReadonly: true; isPointer: true } - Property { name: "surface"; type: "QWaylandSurface"; isReadonly: true; isPointer: true } - Property { name: "toplevel"; type: "QWaylandXdgToplevelV6"; isReadonly: true; isPointer: true } - Property { name: "popup"; type: "QWaylandXdgPopupV6"; isReadonly: true; isPointer: true } - Property { name: "windowGeometry"; type: "QRect"; isReadonly: true } - Signal { name: "toplevelCreated" } - Signal { name: "popupCreated" } - Method { - name: "initialize" - Parameter { name: "xdgShell"; type: "QWaylandXdgShellV6"; isPointer: true } - Parameter { name: "surface"; type: "QWaylandSurface"; isPointer: true } - Parameter { name: "resource"; type: "QWaylandResource" } - } - } - Component { - name: "QWaylandXdgToplevel" - prototype: "QObject" - exports: ["QtWayland.Compositor/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: "QVector<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" } - } - } - Component { - name: "QWaylandXdgToplevelV6" - prototype: "QObject" - exports: ["QtWayland.Compositor/XdgToplevelV6 1.1"] - isCreatable: false - exportMetaObjectRevisions: [0] - Enum { - name: "State" - values: { - "MaximizedState": 1, - "FullscreenState": 2, - "ResizingState": 3, - "ActivatedState": 4 - } - } - Property { - name: "parentToplevel" - type: "QWaylandXdgToplevelV6" - 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 } - 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: "QVector<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" } - } - } - Component { - prototype: "QQuickItem" - name: "QtWayland.Compositor/WaylandCursorItem 1.0" - exports: ["QtWayland.Compositor/WaylandCursorItem 1.0"] - exportMetaObjectRevisions: [0] - isComposite: true - defaultProperty: "data" - Property { name: "seat"; type: "QObject"; isPointer: true } - Property { name: "hotspotX"; type: "int" } - Property { name: "hotspotY"; type: "int" } - Property { name: "compositor"; type: "QWaylandCompositor"; isReadonly: true; isPointer: true } - Property { name: "surface"; type: "QWaylandSurface"; isPointer: true } - Property { name: "paintEnabled"; type: "bool" } - Property { name: "touchEventsEnabled"; type: "bool" } - Property { name: "origin"; type: "QWaylandSurface::Origin"; isReadonly: true } - Property { name: "inputEventsEnabled"; type: "bool" } - Property { name: "focusOnClick"; type: "bool" } - Property { name: "sizeFollowsSurface"; type: "bool" } - Property { name: "subsurfaceHandler"; type: "QObject"; isPointer: true } - Property { name: "output"; type: "QWaylandOutput"; isPointer: true } - Property { name: "bufferLocked"; type: "bool" } - Property { name: "allowDiscardFrontBuffer"; type: "bool" } - Signal { name: "surfaceDestroyed" } - Signal { - name: "mouseMove" - Parameter { name: "windowPosition"; type: "QPointF" } - } - Signal { name: "mouseRelease" } - Method { - name: "takeFocus" - Parameter { name: "device"; type: "QWaylandSeat"; isPointer: true } - } - Method { name: "takeFocus" } - Method { - name: "setPaintEnabled" - Parameter { name: "paintEnabled"; type: "bool" } - } - Method { name: "raise" } - Method { name: "lower" } - Method { - name: "sendMouseMoveEvent" - Parameter { name: "position"; type: "QPointF" } - Parameter { name: "seat"; type: "QWaylandSeat"; isPointer: true } - } - Method { - name: "sendMouseMoveEvent" - Parameter { name: "position"; type: "QPointF" } - } - Method { - name: "mapToSurface" - type: "QPointF" - Parameter { name: "point"; type: "QPointF" } - } - Method { - name: "mapFromSurface" - revision: 13 - type: "QPointF" - Parameter { name: "point"; type: "QPointF" } - } - Method { - name: "inputMethodQuery" - type: "QVariant" - Parameter { name: "query"; type: "Qt::InputMethodQuery" } - Parameter { name: "argument"; type: "QVariant" } - } - Method { name: "setPrimary" } - } - Component { - prototype: "QQuickWindowQmlImpl" - name: "QtWayland.Compositor/WaylandOutputWindow 1.0" - exports: ["QtWayland.Compositor/WaylandOutputWindow 1.0"] - exportMetaObjectRevisions: [0] - isComposite: true - defaultProperty: "data" - Property { name: "compositor"; type: "QObject"; isPointer: true } - Property { name: "output"; type: "QObject"; isPointer: true } - Property { name: "automaticFrameCallback"; type: "bool" } - } -} diff --git a/src/imports/compositor/qmldir b/src/imports/compositor/qmldir deleted file mode 100644 index 6307e1a80..000000000 --- a/src/imports/compositor/qmldir +++ /dev/null @@ -1,3 +0,0 @@ -module QtWayland.Compositor -plugin qwaylandcompositorplugin -classname QWaylandCompositorPlugin diff --git a/src/imports/compositor/qwaylandmousetracker.cpp b/src/imports/compositor/qwaylandmousetracker.cpp deleted file mode 100644 index e7af567af..000000000 --- a/src/imports/compositor/qwaylandmousetracker.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWaylandCompositor module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwaylandmousetracker_p.h" - -#include <QtQuick/private/qquickitem_p.h> - -QT_BEGIN_NAMESPACE - -class QWaylandMouseTrackerPrivate : public QQuickItemPrivate -{ - Q_DECLARE_PUBLIC(QWaylandMouseTracker) -public: - QWaylandMouseTrackerPrivate() - { - QImage cursorImage(64,64,QImage::Format_ARGB32); - cursorImage.fill(Qt::transparent); - cursorPixmap = QPixmap::fromImage(cursorImage); - } - void handleMousePos(const QPointF &mousePos) - { - Q_Q(QWaylandMouseTracker); - bool xChanged = mousePos.x() != this->mousePos.x(); - bool yChanged = mousePos.y() != this->mousePos.y(); - if (xChanged || yChanged) { - this->mousePos = mousePos; - if (xChanged) - emit q->mouseXChanged(); - if (yChanged) - emit q->mouseYChanged(); - } - } - - void setHovered(bool hovered) - { - Q_Q(QWaylandMouseTracker); - if (this->hovered == hovered) - return; - this->hovered = hovered; - emit q->hoveredChanged(); - } - - QPointF mousePos; - bool windowSystemCursorEnabled = false; - QPixmap cursorPixmap; - bool hovered = false; -}; - -QWaylandMouseTracker::QWaylandMouseTracker(QQuickItem *parent) - : QQuickItem(*(new QWaylandMouseTrackerPrivate), parent) -{ - Q_D(QWaylandMouseTracker); - setFiltersChildMouseEvents(true); - setAcceptHoverEvents(true); - setAcceptedMouseButtons(Qt::AllButtons); -#if QT_CONFIG(cursor) - setCursor(QCursor(d->cursorPixmap)); -#endif -} - -qreal QWaylandMouseTracker::mouseX() const -{ - Q_D(const QWaylandMouseTracker); - return d->mousePos.x(); -} -qreal QWaylandMouseTracker::mouseY() const -{ - Q_D(const QWaylandMouseTracker); - return d->mousePos.y(); -} - -#if QT_CONFIG(cursor) -void QWaylandMouseTracker::setWindowSystemCursorEnabled(bool enable) -{ - Q_D(QWaylandMouseTracker); - if (d->windowSystemCursorEnabled != enable) { - d->windowSystemCursorEnabled = enable; - if (enable) { - unsetCursor(); - } else { - setCursor(QCursor(d->cursorPixmap)); - } - emit windowSystemCursorEnabledChanged(); - } -} - -bool QWaylandMouseTracker::windowSystemCursorEnabled() const -{ - Q_D(const QWaylandMouseTracker); - return d->windowSystemCursorEnabled; -} -#endif - -bool QWaylandMouseTracker::hovered() const -{ - Q_D(const QWaylandMouseTracker); - return d->hovered; -} - -bool QWaylandMouseTracker::childMouseEventFilter(QQuickItem *item, QEvent *event) -{ - Q_D(QWaylandMouseTracker); - if (event->type() == QEvent::MouseMove) { - QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event); - d->handleMousePos(mapFromItem(item, mouseEvent->localPos())); - } else if (event->type() == QEvent::HoverMove) { - QHoverEvent *hoverEvent = static_cast<QHoverEvent *>(event); - d->handleMousePos(mapFromItem(item, hoverEvent->posF())); - } - return false; -} - -void QWaylandMouseTracker::mouseMoveEvent(QMouseEvent *event) -{ - Q_D(QWaylandMouseTracker); - QQuickItem::mouseMoveEvent(event); - d->handleMousePos(event->localPos()); -} - -void QWaylandMouseTracker::hoverMoveEvent(QHoverEvent *event) -{ - Q_D(QWaylandMouseTracker); - QQuickItem::hoverMoveEvent(event); - d->handleMousePos(event->posF()); -} - -void QWaylandMouseTracker::hoverEnterEvent(QHoverEvent *event) -{ - Q_D(QWaylandMouseTracker); - Q_UNUSED(event); - d->setHovered(true); -} - -void QWaylandMouseTracker::hoverLeaveEvent(QHoverEvent *event) -{ - Q_D(QWaylandMouseTracker); - Q_UNUSED(event); - d->setHovered(false); -} - -QT_END_NAMESPACE diff --git a/src/imports/compositor/qwaylandmousetracker_p.h b/src/imports/compositor/qwaylandmousetracker_p.h deleted file mode 100644 index abc0942d3..000000000 --- a/src/imports/compositor/qwaylandmousetracker_p.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWaylandCompositor module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWAYLANDMOUSETRACKER_P_H -#define QWAYLANDMOUSETRACKER_P_H - -#include <QtQuick/private/qquickmousearea_p.h> - -#include <QtWaylandCompositor/qtwaylandcompositorglobal.h> - -QT_BEGIN_NAMESPACE - -class QWaylandMouseTrackerPrivate; - -class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandMouseTracker : public QQuickItem -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QWaylandMouseTracker) - Q_PROPERTY(qreal mouseX READ mouseX NOTIFY mouseXChanged) - Q_PROPERTY(qreal mouseY READ mouseY NOTIFY mouseYChanged) - Q_PROPERTY(bool containsMouse READ hovered NOTIFY hoveredChanged) - - Q_PROPERTY(bool windowSystemCursorEnabled READ windowSystemCursorEnabled WRITE setWindowSystemCursorEnabled NOTIFY windowSystemCursorEnabledChanged) -public: - QWaylandMouseTracker(QQuickItem *parent = nullptr); - - qreal mouseX() const; - qreal mouseY() const; - - void setWindowSystemCursorEnabled(bool enable); - bool windowSystemCursorEnabled() const; - bool hovered() const; - -signals: - void mouseXChanged(); - void mouseYChanged(); - void windowSystemCursorEnabledChanged(); - void hoveredChanged(); - -protected: - bool childMouseEventFilter(QQuickItem *item, QEvent *event) override; - void mouseMoveEvent(QMouseEvent *event) override; - void hoverMoveEvent(QHoverEvent *event) override; - void hoverEnterEvent(QHoverEvent *event) override; - void hoverLeaveEvent(QHoverEvent *event) override; -}; - -QT_END_NAMESPACE - -#endif /*QWAYLANDMOUSETRACKER_P_H*/ diff --git a/src/imports/compositor/qwaylandquickcompositorplugin.cpp b/src/imports/compositor/qwaylandquickcompositorplugin.cpp deleted file mode 100644 index 73e21eb93..000000000 --- a/src/imports/compositor/qwaylandquickcompositorplugin.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWaylandCompositor module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include <QtCore/QDir> - -#include <QtQml/qqmlextensionplugin.h> - -#include <QtQuick/QQuickItem> - -#include <QtWaylandCompositor/QWaylandQuickCompositor> -#include <QtWaylandCompositor/QWaylandQuickItem> -#include <QtWaylandCompositor/private/qwaylandquickhardwarelayer_p.h> -#include <QtWaylandCompositor/QWaylandQuickSurface> -#include <QtWaylandCompositor/QWaylandClient> -#include <QtWaylandCompositor/QWaylandQuickOutput> -#include <QtWaylandCompositor/QWaylandCompositorExtension> -#include <QtWaylandCompositor/QWaylandQuickExtension> -#include <QtWaylandCompositor/QWaylandSeat> -#if QT_CONFIG(draganddrop) -#include <QtWaylandCompositor/QWaylandDrag> -#endif -#include <QtWaylandCompositor/QWaylandKeymap> -#include <QtWaylandCompositor/QWaylandQuickShellSurfaceItem> -#include <QtWaylandCompositor/QWaylandResource> - -#include <QtWaylandCompositor/QWaylandQtWindowManager> -#include <QtWaylandCompositor/QWaylandWlScaler> -#include <QtWaylandCompositor/QWaylandWlShell> -#include <QtWaylandCompositor/QWaylandTextInputManager> -#include <QtWaylandCompositor/QWaylandXdgShellV5> -#include <QtWaylandCompositor/QWaylandXdgShellV6> -#include <QtWaylandCompositor/QWaylandXdgShell> -#include <QtWaylandCompositor/QWaylandXdgDecorationManagerV1> -#include <QtWaylandCompositor/QWaylandIdleInhibitManagerV1> -#include <QtWaylandCompositor/QWaylandQuickXdgOutputV1> -#include <QtWaylandCompositor/QWaylandIviApplication> -#include <QtWaylandCompositor/QWaylandIviSurface> - -#include <QtWaylandCompositor/qtwaylandcompositorglobal.h> -#include "qwaylandmousetracker_p.h" - -QT_BEGIN_NAMESPACE - -Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CONTAINER_CLASS(QWaylandQuickCompositor) -Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandQtWindowManager) -Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandIdleInhibitManagerV1) -Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandIviApplication) -#if QT_DEPRECATED_SINCE(5, 13) -Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandWlScaler) -#endif -Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandWlShell) -Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandXdgShellV5) -Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandXdgShellV6) -Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandXdgShell) -Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandXdgDecorationManagerV1) -Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandXdgOutputManagerV1) -Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandTextInputManager) - -class QmlUrlResolver -{ -public: - QmlUrlResolver(bool useResource, const QDir &qmlDir, const QString &qrcPath) - : m_useResource(useResource) - , m_qmlDir(qmlDir) - , m_qrcPath(qrcPath) - { } - - QUrl get(const QString &fileName) - { - return m_useResource ? QUrl(m_qrcPath + fileName) : - QUrl::fromLocalFile(m_qmlDir.filePath(fileName)); - } -private: - bool m_useResource; - const QDir m_qmlDir; - const QString m_qrcPath; -}; - - -//![class decl] -class QWaylandCompositorPlugin : public QQmlExtensionPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) -public: - void registerTypes(const char *uri) override - { - Q_ASSERT(QLatin1String(uri) == QLatin1String("QtWayland.Compositor")); - defineModule(uri); - - bool useResource = true; - QDir qmlDir(baseUrl().toLocalFile()); - if (qmlDir.exists(QStringLiteral("WaylandCursorItem.qml"))) - useResource = false; - - QmlUrlResolver resolver(useResource, qmlDir, QStringLiteral("qrc:/QtWayland/Compositor/")); - - qmlRegisterType(resolver.get(QStringLiteral("WaylandOutputWindow.qml")), uri, 1, 0, "WaylandOutputWindow"); - qmlRegisterType(resolver.get(QStringLiteral("WaylandCursorItem.qml")), uri, 1, 0, "WaylandCursorItem"); - } - - static void defineModule(const char *uri) - { - // This is needed so to guarantee that the import is available with the current - // Qt minor version even if no new types have been added since the last release. - qmlRegisterModule(uri, 1, QT_VERSION_MINOR); - - qmlRegisterType<QWaylandQuickCompositorQuickExtensionContainer>(uri, 1, 0, "WaylandCompositor"); - qmlRegisterType<QWaylandQuickItem>(uri, 1, 0, "WaylandQuickItem"); - qmlRegisterType<QWaylandQuickItem, 13>(uri, 1, 13, "WaylandQuickItem"); -#if QT_CONFIG(opengl) - qmlRegisterType<QWaylandQuickHardwareLayer>(uri, 1, 2, "WaylandHardwareLayer"); -#endif - qmlRegisterType<QWaylandMouseTracker>(uri, 1, 0, "WaylandMouseTracker"); - qmlRegisterType<QWaylandQuickOutput>(uri, 1, 0, "WaylandOutput"); - qmlRegisterType<QWaylandQuickSurface>(uri, 1, 0, "WaylandSurface"); - qmlRegisterType<QWaylandQuickSurface, 13>(uri, 1, 13, "WaylandSurface"); - qmlRegisterType<QWaylandKeymap>(uri, 1, 0, "WaylandKeymap"); - - qmlRegisterUncreatableType<QWaylandCompositorExtension>(uri, 1, 0, "WaylandExtension", QObject::tr("Cannot create instance of WaylandExtension")); - qmlRegisterUncreatableType<QWaylandClient>(uri, 1, 0, "WaylandClient", QObject::tr("Cannot create instance of WaylandClient")); - qmlRegisterUncreatableType<QWaylandOutput>(uri, 1, 0, "WaylandOutputBase", QObject::tr("Cannot create instance of WaylandOutputBase, use WaylandOutput instead")); - qmlRegisterUncreatableType<QWaylandSeat>(uri, 1, 0, "WaylandSeat", QObject::tr("Cannot create instance of WaylandSeat")); -#if QT_CONFIG(draganddrop) - qmlRegisterUncreatableType<QWaylandDrag>(uri, 1, 0, "WaylandDrag", QObject::tr("Cannot create instance of WaylandDrag")); -#endif - qmlRegisterUncreatableType<QWaylandCompositor>(uri, 1, 0, "WaylandCompositorBase", QObject::tr("Cannot create instance of WaylandCompositorBase, use WaylandCompositor instead")); - qmlRegisterUncreatableType<QWaylandSurface>(uri, 1, 0, "WaylandSurfaceBase", QObject::tr("Cannot create instance of WaylandSurfaceBase, use WaylandSurface instead")); - qmlRegisterUncreatableType<QWaylandShell>(uri, 1, 0, "Shell", QObject::tr("Cannot create instance of Shell")); - qmlRegisterUncreatableType<QWaylandShellSurface>(uri, 1, 0, "ShellSurface", QObject::tr("Cannot create instance of ShellSurface")); - qmlRegisterUncreatableType<QWaylandResource>(uri, 1, 0, "WaylandResource", QObject::tr("Cannot create instance of WaylandResource")); - - //This should probably be somewhere else - qmlRegisterType<QWaylandQtWindowManagerQuickExtension>(uri, 1, 0, "QtWindowManager"); - qmlRegisterType<QWaylandIviApplicationQuickExtension>(uri, 1, 0, "IviApplication"); - qmlRegisterType<QWaylandIviSurface>(uri, 1, 0, "IviSurface"); - qmlRegisterType<QWaylandWlShellQuickExtension>(uri, 1, 0, "WlShell"); - qmlRegisterType<QWaylandWlShellSurface>(uri, 1, 0, "WlShellSurface"); - qmlRegisterType<QWaylandQuickShellSurfaceItem>(uri, 1, 0, "ShellSurfaceItem"); - qmlRegisterUncreatableType<QWaylandXdgShellV5>(uri, 1, 0, "XdgShellV5Base", QObject::tr("Cannot create instance of XdgShellV5Base")); - qmlRegisterType<QWaylandXdgShellV5QuickExtension>(uri, 1, 0, "XdgShellV5"); - qmlRegisterType<QWaylandXdgSurfaceV5>(uri, 1, 0, "XdgSurfaceV5"); - qmlRegisterType<QWaylandXdgPopupV5>(uri, 1, 0, "XdgPopupV5"); - qmlRegisterType<QWaylandTextInputManagerQuickExtension>(uri, 1, 0, "TextInputManager"); - - qmlRegisterType<QWaylandXdgShellV6QuickExtension>(uri, 1, 1, "XdgShellV6"); - qmlRegisterType<QWaylandXdgSurfaceV6>(uri, 1, 1, "XdgSurfaceV6"); - qmlRegisterUncreatableType<QWaylandXdgToplevelV6>(uri, 1, 1, "XdgToplevelV6", QObject::tr("Cannot create instance of XdgShellToplevelV6")); - qmlRegisterUncreatableType<QWaylandXdgPopupV6>(uri, 1, 1, "XdgPopupV6", QObject::tr("Cannot create instance of XdgShellPopupV6")); - - 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"); - -#if QT_DEPRECATED_SINCE(5, 13) - qmlRegisterType<QWaylandWlScalerQuickExtension>(uri, 1, 13, "WlScaler"); -#endif - - qmlRegisterType<QWaylandIdleInhibitManagerV1QuickExtension>(uri, 1, 14, "IdleInhibitManagerV1"); - - qmlRegisterType<QWaylandXdgOutputManagerV1QuickExtension>(uri, 1, 14, "XdgOutputManagerV1"); - qmlRegisterType<QWaylandQuickXdgOutputV1>(uri, 1, 14, "XdgOutputV1"); - } -}; -//![class decl] - -QT_END_NAMESPACE - -#include "qwaylandquickcompositorplugin.moc" diff --git a/src/imports/imports.pro b/src/imports/imports.pro deleted file mode 100644 index 7452a9283..000000000 --- a/src/imports/imports.pro +++ /dev/null @@ -1,12 +0,0 @@ -TEMPLATE = subdirs - -qtHaveModule(quick):qtHaveModule(waylandcompositor) { - SUBDIRS += \ - compositor - - qtConfig(opengl):qtHaveModule(waylandclient) { - SUBDIRS += \ - texture-sharing \ - texture-sharing-extension - } -} diff --git a/src/imports/texture-sharing-extension/CMakeLists.txt b/src/imports/texture-sharing-extension/CMakeLists.txt new file mode 100644 index 000000000..564bb6402 --- /dev/null +++ b/src/imports/texture-sharing-extension/CMakeLists.txt @@ -0,0 +1,37 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +# Generated from texture-sharing-extension.pro. + +##################################################################### +## qwaylandtexturesharingextension Plugin: +##################################################################### + +qt_internal_add_qml_module(WaylandTextureSharingExtension + URI "QtWayland.Compositor.TextureSharingExtension" + VERSION "1.${PROJECT_VERSION_MINOR}" + CLASS_NAME QWaylandTextureSharingExtensionPlugin + NO_PLUGIN_OPTIONAL + NO_GENERATE_PLUGIN_SOURCE + NO_GENERATE_QMLTYPES + PLUGIN_TARGET WaylandTextureSharingExtension + # misses a plugin.qmltypes files, so nothing to install + SOURCES + plugin.cpp + LIBRARIES + Qt::Core + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::Qml + Qt::QuickPrivate + Qt::WaylandCompositor + Qt::WaylandCompositorPrivate + NO_GENERATE_CPP_EXPORTS +) + +qt_internal_add_autogen_sync_header_dependencies(WaylandTextureSharingExtension WaylandCompositor) +#### Keys ignored in scope 1:.:.:texture-sharing-extension.pro:<TRUE>: +# CXX_MODULE = "qml" +# IMPORT_VERSION = "1.$$QT_MINOR_VERSION" +# TARGETPATH = "QtWayland/Compositor/TextureSharingExtension" diff --git a/src/imports/texture-sharing-extension/plugin.cpp b/src/imports/texture-sharing-extension/plugin.cpp index 42dcd8e2d..6fd6032ac 100644 --- a/src/imports/texture-sharing-extension/plugin.cpp +++ b/src/imports/texture-sharing-extension/plugin.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWaylandCompositor module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2019 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 <QtQml/qqmlextensionplugin.h> #include <QtQml/qqmlengine.h> @@ -43,6 +7,7 @@ #include "QtWaylandCompositor/private/qwltexturesharingextension_p.h" /*! + \internal \qmlmodule QtWayland.Compositor.TextureSharingExtension 1 \title Qt Wayland Shared Texture Provider \ingroup qmlmodules @@ -53,6 +18,9 @@ This module lets the compositor export graphical resources that can be used by clients, without allocating any graphics memory in the client. + \note The texture sharing functionality is considered experimental and + currently unsupported in Qt 6. + \section2 Usage This module is imported like this: diff --git a/src/imports/texture-sharing-extension/qmldir b/src/imports/texture-sharing-extension/qmldir deleted file mode 100644 index 182e5c0ee..000000000 --- a/src/imports/texture-sharing-extension/qmldir +++ /dev/null @@ -1,3 +0,0 @@ -module QtWayland.Compositor.TextureSharingExtension -plugin qwaylandtexturesharingextension -classname QWaylandTextureSharingExtensionPlugin diff --git a/src/imports/texture-sharing-extension/texture-sharing-extension.pro b/src/imports/texture-sharing-extension/texture-sharing-extension.pro deleted file mode 100644 index 68a8cf757..000000000 --- a/src/imports/texture-sharing-extension/texture-sharing-extension.pro +++ /dev/null @@ -1,11 +0,0 @@ -CXX_MODULE = qml -TARGET = qwaylandtexturesharingextension -TARGETPATH = QtWayland/Compositor/TextureSharingExtension -IMPORT_VERSION = 1.$$QT_MINOR_VERSION - -SOURCES += \ - plugin.cpp - -QT += quick-private qml gui-private core-private waylandcompositor waylandcompositor-private - -load(qml_plugin) diff --git a/src/imports/texture-sharing/CMakeLists.txt b/src/imports/texture-sharing/CMakeLists.txt new file mode 100644 index 000000000..61d6690e6 --- /dev/null +++ b/src/imports/texture-sharing/CMakeLists.txt @@ -0,0 +1,48 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +# Generated from texture-sharing.pro. + +##################################################################### +## qwaylandtexturesharing Plugin: +##################################################################### + +qt_internal_add_qml_module(WaylandTextureSharing + URI "QtWayland.Client.TextureSharing" + VERSION "1.${PROJECT_VERSION_MINOR}" + NO_PLUGIN_OPTIONAL + NO_GENERATE_PLUGIN_SOURCE + NO_GENERATE_QMLTYPES + PLUGIN_TARGET WaylandTextureSharing + # no qmltypes file available, so nothing to install + CLASS_NAME QWaylandTextureSharingPlugin + SOURCES + plugin.cpp + sharedtextureprovider.cpp sharedtextureprovider_p.h + texturesharingextension.cpp texturesharingextension_p.h + LIBRARIES + Qt::Core + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::OpenGL + Qt::Qml + Qt::QuickPrivate + Qt::WaylandClient + Qt::WaylandClientPrivate + PRIVATE_HEADER_FILTERS + "^qwayland-.*\.h|^wayland-.*-protocol\.h" + NO_GENERATE_CPP_EXPORTS +) + +qt6_generate_wayland_protocol_client_sources(WaylandTextureSharing + FILES + ${CMAKE_CURRENT_SOURCE_DIR}/../../extensions/qt-texture-sharing-unstable-v1.xml +) + +qt_internal_add_autogen_sync_header_dependencies(WaylandTextureSharing WaylandCompositor) + +#### Keys ignored in scope 1:.:.:texture-sharing.pro:<TRUE>: +# CXX_MODULE = "qml" +# IMPORT_VERSION = "1.$$QT_MINOR_VERSION" +# TARGETPATH = "QtWayland/Client/TextureSharing" diff --git a/src/imports/texture-sharing/plugin.cpp b/src/imports/texture-sharing/plugin.cpp index 9cf6bbca1..0f1f61369 100644 --- a/src/imports/texture-sharing/plugin.cpp +++ b/src/imports/texture-sharing/plugin.cpp @@ -1,48 +1,13 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWaylandClient module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2019 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 <QtQml/qqmlextensionplugin.h> #include <QtQml/qqmlengine.h> -#include "sharedtextureprovider.h" +#include "sharedtextureprovider_p.h" /*! + \internal \qmlmodule QtWayland.Client.TextureSharing 1 \title Qt Wayland Shared Texture Provider \ingroup qmlmodules @@ -52,6 +17,10 @@ This module allows Qt Wayland clients to use graphical resources exported by the compositor, without allocating any graphics memory in the client. + + \note The texture sharing functionality is considered experimental and + currently unsupported in Qt 6. + \section2 Usage To use this module, import it like this: diff --git a/src/imports/texture-sharing/qmldir b/src/imports/texture-sharing/qmldir deleted file mode 100644 index cf3b74c48..000000000 --- a/src/imports/texture-sharing/qmldir +++ /dev/null @@ -1,3 +0,0 @@ -module QtWayland.Client.TextureSharing -plugin qwaylandtexturesharing -classname QWaylandTextureSharingPlugin diff --git a/src/imports/texture-sharing/sharedtextureprovider.cpp b/src/imports/texture-sharing/sharedtextureprovider.cpp index 707e94ae6..ded29b44e 100644 --- a/src/imports/texture-sharing/sharedtextureprovider.cpp +++ b/src/imports/texture-sharing/sharedtextureprovider.cpp @@ -1,44 +1,8 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "sharedtextureprovider.h" +// Copyright (C) 2019 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 "sharedtextureprovider_p.h" #include <QFile> #include <QDebug> @@ -49,58 +13,19 @@ #include <QtWaylandClient/private/qwaylandserverbufferintegration_p.h> #include <QtGui/QGuiApplication> #include <QtGui/private/qguiapplication_p.h> +#include <QtQuick/private/qsgrhisupport_p.h> #include <QtGui/qpa/qplatformnativeinterface.h> #include <QtGui/QWindow> #include <QOpenGLTexture> #include <QImageReader> +#include <QtCore/qpointer.h> #include <QTimer> -#include "texturesharingextension.h" +#include "texturesharingextension_p.h" QT_BEGIN_NAMESPACE -SharedTexture::SharedTexture(QtWaylandClient::QWaylandServerBuffer *buffer) - : m_buffer(buffer), m_tex(nullptr) -{ -} - -int SharedTexture::textureId() const -{ - updateGLTexture(); - return m_tex ? m_tex->textureId() : 0; -} - -QSize SharedTexture::textureSize() const -{ - updateGLTexture(); - return m_tex ? QSize(m_tex->width(), m_tex->height()) : QSize(); -} - -bool SharedTexture::hasAlphaChannel() const -{ - return true; -} - -bool SharedTexture::hasMipmaps() const -{ - updateGLTexture(); - return m_tex ? (m_tex->mipLevels() > 1) : false; -} - -void SharedTexture::bind() -{ - updateGLTexture(); - if (m_tex) - m_tex->bind(); -} - -inline void SharedTexture::updateGLTexture() const -{ - if (!m_tex && m_buffer) - m_tex = m_buffer->toOpenGlTexture(); -} - class SharedTextureFactory : public QQuickTextureFactory { public: @@ -128,9 +53,16 @@ public: return m_buffer ? (m_buffer->size().width() * m_buffer->size().height() * 4) : 0; } - QSGTexture *createTexture(QQuickWindow *) const override + QSGTexture *createTexture(QQuickWindow *window) const override { - return new SharedTexture(const_cast<QtWaylandClient::QWaylandServerBuffer *>(m_buffer)); + if (m_buffer != nullptr) { + QOpenGLTexture *texture = const_cast<QtWaylandClient::QWaylandServerBuffer *>(m_buffer)->toOpenGlTexture(); + return QNativeInterface::QSGOpenGLTexture::fromNative(texture->textureId(), + window, + m_buffer->size(), + QQuickWindow::TextureHasAlphaChannel); + } + return nullptr; } private: @@ -184,6 +116,11 @@ void SharedTextureRegistry::handleExtensionActive() bool SharedTextureRegistry::preinitialize() { + if (QSGRhiSupport::instance()->rhiBackend() != QRhi::OpenGLES2) { + qWarning() << "The shared-texture extension is only supported on OpenGL. Use QQuickWindow::setSceneGraphBackend() to override the default."; + return false; + } + auto *serverBufferIntegration = QGuiApplicationPrivate::platformIntegration()->nativeInterface()->nativeResourceForIntegration("server_buffer_integration"); if (!serverBufferIntegration) { @@ -270,7 +207,7 @@ public: } -public slots: +public Q_SLOTS: void doResponse(const QString &key) { if (key != m_id) return; // not our buffer @@ -319,4 +256,6 @@ QQuickImageResponse *SharedTextureProvider::requestImageResponse(const QString & QT_END_NAMESPACE +#include "moc_sharedtextureprovider_p.cpp" + #include "sharedtextureprovider.moc" diff --git a/src/imports/texture-sharing/sharedtextureprovider.h b/src/imports/texture-sharing/sharedtextureprovider.h deleted file mode 100644 index f25c7de9c..000000000 --- a/src/imports/texture-sharing/sharedtextureprovider.h +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SHAREDTEXTUREPROVIDER_H -#define SHAREDTEXTUREPROVIDER_H - -#include <QOpenGLFunctions> -#include <QQuickImageProvider> -#include <QtQuick/QSGTexture> -#include <QScopedPointer> -#include <QHash> - -#include <QtWaylandClient/private/qwaylandserverbufferintegration_p.h> - -QT_BEGIN_NAMESPACE - -class TextureSharingExtension; - -class SharedTextureRegistry : public QObject -{ - Q_OBJECT -public: - SharedTextureRegistry(); - ~SharedTextureRegistry() override; - - const QtWaylandClient::QWaylandServerBuffer *bufferForId(const QString &id) const; - void requestBuffer(const QString &id); - void abandonBuffer(const QString &id); - - static bool preinitialize(); - -public slots: - void receiveBuffer(QtWaylandClient::QWaylandServerBuffer *buffer, const QString &id); - -signals: - void replyReceived(const QString &id); - -private slots: - void handleExtensionActive(); - -private: - TextureSharingExtension *m_extension = nullptr; - QHash<QString, QtWaylandClient::QWaylandServerBuffer *> m_buffers; - QStringList m_pendingBuffers; -}; - -class SharedTextureProvider : public QQuickAsyncImageProvider -{ -public: - SharedTextureProvider(); - ~SharedTextureProvider() override; - - QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize) override; - -private: - SharedTextureRegistry *m_registry = nullptr; - bool m_sharingAvailable = false; -}; - -class SharedTexture : public QSGTexture -{ - Q_OBJECT -public: - SharedTexture(QtWaylandClient::QWaylandServerBuffer *buffer); - - int textureId() const override; - QSize textureSize() const override; - bool hasAlphaChannel() const override; - bool hasMipmaps() const override; - - void bind() override; - -private: - void updateGLTexture() const; - QtWaylandClient::QWaylandServerBuffer *m_buffer = nullptr; - mutable QOpenGLTexture *m_tex = nullptr; -}; - - -QT_END_NAMESPACE - -#endif // SHAREDTEXTUREPROVIDER_H diff --git a/src/imports/texture-sharing/sharedtextureprovider_p.h b/src/imports/texture-sharing/sharedtextureprovider_p.h new file mode 100644 index 000000000..aac772619 --- /dev/null +++ b/src/imports/texture-sharing/sharedtextureprovider_p.h @@ -0,0 +1,73 @@ +// Copyright (C) 2019 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 + +// +// 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. +// + +#ifndef SHAREDTEXTUREPROVIDER_H +#define SHAREDTEXTUREPROVIDER_H + +#include <QOpenGLFunctions> +#include <QQuickImageProvider> +#include <QtQuick/QSGTexture> +#include <QScopedPointer> +#include <QHash> + +#include <QtWaylandClient/private/qwaylandserverbufferintegration_p.h> + +QT_BEGIN_NAMESPACE + +class TextureSharingExtension; + +class SharedTextureRegistry : public QObject +{ + Q_OBJECT +public: + SharedTextureRegistry(); + ~SharedTextureRegistry() override; + + const QtWaylandClient::QWaylandServerBuffer *bufferForId(const QString &id) const; + void requestBuffer(const QString &id); + void abandonBuffer(const QString &id); + + static bool preinitialize(); + +public Q_SLOTS: + void receiveBuffer(QtWaylandClient::QWaylandServerBuffer *buffer, const QString &id); + +Q_SIGNALS: + void replyReceived(const QString &id); + +private Q_SLOTS: + void handleExtensionActive(); + +private: + TextureSharingExtension *m_extension = nullptr; + QHash<QString, QtWaylandClient::QWaylandServerBuffer *> m_buffers; + QStringList m_pendingBuffers; +}; + +class SharedTextureProvider : public QQuickAsyncImageProvider +{ +public: + SharedTextureProvider(); + ~SharedTextureProvider() override; + + QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize) override; + +private: + SharedTextureRegistry *m_registry = nullptr; + bool m_sharingAvailable = false; +}; + +QT_END_NAMESPACE + +#endif // SHAREDTEXTUREPROVIDER_H diff --git a/src/imports/texture-sharing/texture-sharing.pro b/src/imports/texture-sharing/texture-sharing.pro deleted file mode 100644 index bec769ecb..000000000 --- a/src/imports/texture-sharing/texture-sharing.pro +++ /dev/null @@ -1,21 +0,0 @@ -CXX_MODULE = qml -TARGET = qwaylandtexturesharing -TARGETPATH = QtWayland/Client/TextureSharing -IMPORT_VERSION = 1.$$QT_MINOR_VERSION - -HEADERS += \ - sharedtextureprovider.h \ - texturesharingextension.h - -SOURCES += \ - plugin.cpp \ - sharedtextureprovider.cpp \ - texturesharingextension.cpp - -QT += quick-private qml gui-private core-private waylandclient waylandclient-private -CONFIG += wayland-scanner - -WAYLANDCLIENTSOURCES += ../../extensions/qt-texture-sharing-unstable-v1.xml - - -load(qml_plugin) diff --git a/src/imports/texture-sharing/texturesharingextension.cpp b/src/imports/texture-sharing/texturesharingextension.cpp index 31106d694..4a2360078 100644 --- a/src/imports/texture-sharing/texturesharingextension.cpp +++ b/src/imports/texture-sharing/texturesharingextension.cpp @@ -1,44 +1,7 @@ +// Copyright (C) 2019 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 -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "texturesharingextension.h" +#include "texturesharingextension_p.h" #include <QtWaylandClient/private/qwaylanddisplay_p.h> #include <QtWaylandClient/private/qwaylandintegration_p.h> #include <QtWaylandClient/private/qwaylandserverbufferintegration_p.h> @@ -84,3 +47,5 @@ void TextureSharingExtension::abandonImage(const QString &key) } QT_END_NAMESPACE + +#include "moc_texturesharingextension_p.cpp" diff --git a/src/imports/texture-sharing/texturesharingextension.h b/src/imports/texture-sharing/texturesharingextension.h deleted file mode 100644 index 7b864fbc8..000000000 --- a/src/imports/texture-sharing/texturesharingextension.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef TEXTURESHARINGEXTENSION_H -#define TEXTURESHARINGEXTENSION_H - -#include <qpa/qwindowsysteminterface.h> -#include <QtWaylandClient/private/qwayland-wayland.h> -#include <QtWaylandClient/qwaylandclientextension.h> -#include "qwayland-qt-texture-sharing-unstable-v1.h" - -QT_BEGIN_NAMESPACE - -namespace QtWaylandClient { - class QWaylandServerBuffer; - class QWaylandServerBufferIntegration; -}; - -class TextureSharingExtension : public QWaylandClientExtensionTemplate<TextureSharingExtension> - , public QtWayland::zqt_texture_sharing_v1 -{ - Q_OBJECT -public: - TextureSharingExtension(); - -public slots: - void requestImage(const QString &key); - void abandonImage(const QString &key); - -signals: - void bufferReceived(QtWaylandClient::QWaylandServerBuffer *buffer, const QString &key); - -private: - void zqt_texture_sharing_v1_provide_buffer(struct ::qt_server_buffer *buffer, const QString &key) override; - void zqt_texture_sharing_v1_image_failed(const QString &key, const QString &message) override; - QtWaylandClient::QWaylandServerBufferIntegration *m_server_buffer_integration = nullptr; -}; - -QT_END_NAMESPACE - -#endif // TEXTURESHARINGEXTENSION_H diff --git a/src/imports/texture-sharing/texturesharingextension_p.h b/src/imports/texture-sharing/texturesharingextension_p.h new file mode 100644 index 000000000..4a00de8eb --- /dev/null +++ b/src/imports/texture-sharing/texturesharingextension_p.h @@ -0,0 +1,53 @@ +// 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 + +// +// 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. +// + +#ifndef TEXTURESHARINGEXTENSION_H +#define TEXTURESHARINGEXTENSION_H + +#include <qpa/qwindowsysteminterface.h> +#include <QtWaylandClient/private/qwayland-wayland.h> +#include <QtWaylandClient/qwaylandclientextension.h> +#include "qwayland-qt-texture-sharing-unstable-v1.h" +#include "private/qglobal_p.h" + +QT_BEGIN_NAMESPACE + +namespace QtWaylandClient { + class QWaylandServerBuffer; + class QWaylandServerBufferIntegration; +}; + +class TextureSharingExtension : public QWaylandClientExtensionTemplate<TextureSharingExtension> + , public QtWayland::zqt_texture_sharing_v1 +{ + Q_OBJECT +public: + TextureSharingExtension(); + +public Q_SLOTS: + void requestImage(const QString &key); + void abandonImage(const QString &key); + +Q_SIGNALS: + void bufferReceived(QtWaylandClient::QWaylandServerBuffer *buffer, const QString &key); + +private: + void zqt_texture_sharing_v1_provide_buffer(struct ::qt_server_buffer *buffer, const QString &key) override; + void zqt_texture_sharing_v1_image_failed(const QString &key, const QString &message) override; + QtWaylandClient::QWaylandServerBufferIntegration *m_server_buffer_integration = nullptr; +}; + +QT_END_NAMESPACE + +#endif // TEXTURESHARINGEXTENSION_H |