summaryrefslogtreecommitdiff
path: root/src/compositor
diff options
context:
space:
mode:
Diffstat (limited to 'src/compositor')
-rw-r--r--src/compositor/compositor_api/qwaylandcompositor.cpp2
-rw-r--r--src/compositor/compositor_api/qwaylandcompositor_p.h4
-rw-r--r--src/compositor/compositor_api/qwaylandkeyboard.cpp7
-rw-r--r--src/compositor/compositor_api/qwaylandoutput.cpp10
-rw-r--r--src/compositor/compositor_api/qwaylandoutput_p.h5
-rw-r--r--src/compositor/compositor_api/qwaylandquickitem.cpp10
-rw-r--r--src/compositor/compositor_api/qwaylandsurface.cpp23
-rw-r--r--src/compositor/compositor_api/qwaylandsurface.h4
-rw-r--r--src/compositor/compositor_api/qwaylandsurface_p.h3
-rw-r--r--src/compositor/doc/qtwaylandcompositor.qdocconf1
-rw-r--r--src/compositor/extensions/extensions.pri10
-rw-r--r--src/compositor/extensions/qwaylandidleinhibitv1.cpp190
-rw-r--r--src/compositor/extensions/qwaylandidleinhibitv1.h62
-rw-r--r--src/compositor/extensions/qwaylandidleinhibitv1_p.h88
-rw-r--r--src/compositor/extensions/qwaylandquickxdgoutputv1.cpp73
-rw-r--r--src/compositor/extensions/qwaylandquickxdgoutputv1.h62
-rw-r--r--src/compositor/extensions/qwaylandwlscaler_p.h2
-rw-r--r--src/compositor/extensions/qwaylandxdgoutputv1.cpp595
-rw-r--r--src/compositor/extensions/qwaylandxdgoutputv1.h111
-rw-r--r--src/compositor/extensions/qwaylandxdgoutputv1_p.h112
-rw-r--r--src/compositor/wayland_wrapper/qwlclientbuffer.cpp2
21 files changed, 1370 insertions, 6 deletions
diff --git a/src/compositor/compositor_api/qwaylandcompositor.cpp b/src/compositor/compositor_api/qwaylandcompositor.cpp
index 2d10c638..e2d617c3 100644
--- a/src/compositor/compositor_api/qwaylandcompositor.cpp
+++ b/src/compositor/compositor_api/qwaylandcompositor.cpp
@@ -302,7 +302,7 @@ void QWaylandCompositorPrivate::addPolishObject(QObject *object)
if (initialized) {
QCoreApplication::postEvent(object, new QEvent(QEvent::Polish));
} else {
- polish_objects.append(object);
+ polish_objects.push_back(object);
}
}
diff --git a/src/compositor/compositor_api/qwaylandcompositor_p.h b/src/compositor/compositor_api/qwaylandcompositor_p.h
index 2c962421..2437533d 100644
--- a/src/compositor/compositor_api/qwaylandcompositor_p.h
+++ b/src/compositor/compositor_api/qwaylandcompositor_p.h
@@ -60,6 +60,8 @@
#include <QtWaylandCompositor/private/qwayland-server-wayland.h>
+#include <vector>
+
#if QT_CONFIG(xkbcommon)
#include <QtXkbCommonSupport/private/qxkbcommon_p.h>
#endif
@@ -175,7 +177,7 @@ protected:
bool retainSelection = false;
bool preInitialized = false;
bool initialized = false;
- QList<QPointer<QObject> > polish_objects;
+ std::vector<QPointer<QObject> > polish_objects;
#if QT_CONFIG(xkbcommon)
QXkbCommon::ScopedXKBContext mXkbContext;
diff --git a/src/compositor/compositor_api/qwaylandkeyboard.cpp b/src/compositor/compositor_api/qwaylandkeyboard.cpp
index 452be436..c5ec008d 100644
--- a/src/compositor/compositor_api/qwaylandkeyboard.cpp
+++ b/src/compositor/compositor_api/qwaylandkeyboard.cpp
@@ -366,6 +366,13 @@ void QWaylandKeyboardPrivate::createXKBKeymap()
QByteArray variant = keymap->variant().toLocal8Bit();
QByteArray options = keymap->options().toLocal8Bit();
+ if (!layout.isEmpty() && !layout.contains("us")) {
+ // This is needed for shortucts like "ctrl+c" to function even when
+ // user has selected only non-latin keyboard layouts, e.g. 'ru'.
+ layout.append(",us");
+ variant.append(",");
+ }
+
struct xkb_rule_names rule_names = {
rules.constData(),
model.constData(),
diff --git a/src/compositor/compositor_api/qwaylandoutput.cpp b/src/compositor/compositor_api/qwaylandoutput.cpp
index 7a02d4ca..601f692a 100644
--- a/src/compositor/compositor_api/qwaylandoutput.cpp
+++ b/src/compositor/compositor_api/qwaylandoutput.cpp
@@ -48,6 +48,7 @@
#include <QtWaylandCompositor/private/qwaylandcompositor_p.h>
#include <QtWaylandCompositor/private/qwaylandview_p.h>
#include <QtWaylandCompositor/private/qwaylandutils_p.h>
+#include <QtWaylandCompositor/private/qwaylandxdgoutputv1_p.h>
#include <QtCore/QCoreApplication>
#include <QtCore/QtMath>
@@ -162,6 +163,9 @@ void QWaylandOutputPrivate::sendGeometryInfo()
if (resource->version() >= 2)
send_done(resource->handle);
}
+
+ if (xdgOutput)
+ QWaylandXdgOutputV1Private::get(xdgOutput)->sendDone();
}
void QWaylandOutputPrivate::sendMode(const Resource *resource, const QWaylandOutputMode &mode)
@@ -185,6 +189,9 @@ void QWaylandOutputPrivate::sendModesInfo()
if (resource->version() >= 2)
send_done(resource->handle);
}
+
+ if (xdgOutput)
+ QWaylandXdgOutputV1Private::get(xdgOutput)->sendDone();
}
void QWaylandOutputPrivate::handleWindowPixelSizeChanged()
@@ -840,6 +847,9 @@ void QWaylandOutput::setScaleFactor(int scale)
}
Q_EMIT scaleFactorChanged();
+
+ if (d->xdgOutput)
+ QWaylandXdgOutputV1Private::get(d->xdgOutput)->sendDone();
}
/*!
diff --git a/src/compositor/compositor_api/qwaylandoutput_p.h b/src/compositor/compositor_api/qwaylandoutput_p.h
index 4badd379..58188ac3 100644
--- a/src/compositor/compositor_api/qwaylandoutput_p.h
+++ b/src/compositor/compositor_api/qwaylandoutput_p.h
@@ -57,6 +57,7 @@
#include <QtWaylandCompositor/QWaylandOutput>
#include <QtWaylandCompositor/QWaylandClient>
#include <QtWaylandCompositor/QWaylandSurface>
+#include <QtWaylandCompositor/QWaylandXdgOutputV1>
#include <QtWaylandCompositor/private/qwayland-server-wayland.h>
@@ -110,6 +111,8 @@ public:
void handleWindowPixelSizeChanged();
+ QPointer<QWaylandXdgOutputV1> xdgOutput;
+
protected:
void output_bind_resource(Resource *resource) override;
@@ -137,6 +140,8 @@ private:
Q_DECLARE_PUBLIC(QWaylandOutput)
Q_DISABLE_COPY(QWaylandOutputPrivate)
+
+ friend class QWaylandXdgOutputManagerV1Private;
};
diff --git a/src/compositor/compositor_api/qwaylandquickitem.cpp b/src/compositor/compositor_api/qwaylandquickitem.cpp
index 996177be..ee15a087 100644
--- a/src/compositor/compositor_api/qwaylandquickitem.cpp
+++ b/src/compositor/compositor_api/qwaylandquickitem.cpp
@@ -610,13 +610,17 @@ void QWaylandQuickItem::wheelEvent(QWheelEvent *event)
{
Q_D(QWaylandQuickItem);
if (d->shouldSendInputEvents()) {
- if (!inputRegionContains(event->pos())) {
+ if (!inputRegionContains(event->position())) {
event->ignore();
return;
}
QWaylandSeat *seat = compositor()->seatFor(event);
- seat->sendMouseWheelEvent(event->orientation(), event->delta());
+ // TODO: fix this to send a single event, when diagonal scrolling is supported
+ if (event->angleDelta().x() != 0)
+ seat->sendMouseWheelEvent(Qt::Horizontal, event->angleDelta().x());
+ if (event->angleDelta().y() != 0)
+ seat->sendMouseWheelEvent(Qt::Vertical, event->angleDelta().y());
} else {
event->ignore();
}
@@ -1324,7 +1328,7 @@ QSGNode *QWaylandQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat
if (d->view->isBufferLocked() && !bufferHasContent && d->paintEnabled)
return oldNode;
- if (!bufferHasContent || !d->paintEnabled) {
+ if (!bufferHasContent || !d->paintEnabled || !surface()) {
delete oldNode;
return nullptr;
}
diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp
index 433b5322..2265b41c 100644
--- a/src/compositor/compositor_api/qwaylandsurface.cpp
+++ b/src/compositor/compositor_api/qwaylandsurface.cpp
@@ -764,6 +764,29 @@ bool QWaylandSurface::isCursorSurface() const
return d->isCursorSurface;
}
+/*!
+ * \qmlproperty bool QtWaylandCompositor::WaylandSurface::inhibitsIdle
+ *
+ * This property holds whether this surface is intended to inhibit the idle
+ * behavior of the compositor such as screen blanking, locking and screen saving.
+ *
+ * \sa IdleInhibitManagerV1
+ */
+
+/*!
+ * \property QWaylandSurface::inhibitsIdle
+ *
+ * This property holds whether this surface is intended to inhibit the idle
+ * behavior of the compositor such as screen blanking, locking and screen saving.
+ *
+ * \sa QWaylandIdleInhibitManagerV1
+ */
+bool QWaylandSurface::inhibitsIdle() const
+{
+ Q_D(const QWaylandSurface);
+ return !d->idleInhibitors.isEmpty();
+}
+
#if QT_CONFIG(im)
QWaylandInputMethodControl *QWaylandSurface::inputMethodControl() const
{
diff --git a/src/compositor/compositor_api/qwaylandsurface.h b/src/compositor/compositor_api/qwaylandsurface.h
index 667f911c..f8cdc443 100644
--- a/src/compositor/compositor_api/qwaylandsurface.h
+++ b/src/compositor/compositor_api/qwaylandsurface.h
@@ -92,6 +92,7 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandSurface : public QWaylandObject
Q_PROPERTY(QWaylandSurface::Origin origin READ origin NOTIFY originChanged)
Q_PROPERTY(bool hasContent READ hasContent NOTIFY hasContentChanged)
Q_PROPERTY(bool cursorSurface READ isCursorSurface WRITE markAsCursorSurface NOTIFY cursorSurfaceChanged)
+ Q_PROPERTY(bool inhibitsIdle READ inhibitsIdle NOTIFY inhibitsIdleChanged REVISION 14)
public:
enum Origin {
@@ -148,6 +149,8 @@ public:
void markAsCursorSurface(bool cursorSurface);
bool isCursorSurface() const;
+ bool inhibitsIdle() const;
+
#if QT_CONFIG(im)
QWaylandInputMethodControl *inputMethodControl() const;
#endif
@@ -181,6 +184,7 @@ Q_SIGNALS:
void subsurfacePlaceBelow(QWaylandSurface *sibling);
void dragStarted(QWaylandDrag *drag);
void cursorSurfaceChanged();
+ void inhibitsIdleChanged();
void configure(bool hasBuffer);
void redraw();
diff --git a/src/compositor/compositor_api/qwaylandsurface_p.h b/src/compositor/compositor_api/qwaylandsurface_p.h
index 1637d870..97cb19d9 100644
--- a/src/compositor/compositor_api/qwaylandsurface_p.h
+++ b/src/compositor/compositor_api/qwaylandsurface_p.h
@@ -74,6 +74,7 @@
#include <QtWaylandCompositor/private/qwayland-server-wayland.h>
#include <QtWaylandCompositor/private/qwaylandviewporter_p.h>
+#include <QtWaylandCompositor/private/qwaylandidleinhibitv1_p.h>
QT_BEGIN_NAMESPACE
@@ -167,6 +168,8 @@ public: //member variables
QList<QPointer<QWaylandSurface>> subsurfaceChildren;
+ QVector<QWaylandIdleInhibitManagerV1Private::Inhibitor *> idleInhibitors;
+
QRegion inputRegion;
QRegion opaqueRegion;
diff --git a/src/compositor/doc/qtwaylandcompositor.qdocconf b/src/compositor/doc/qtwaylandcompositor.qdocconf
index 4fa9f394..45928b64 100644
--- a/src/compositor/doc/qtwaylandcompositor.qdocconf
+++ b/src/compositor/doc/qtwaylandcompositor.qdocconf
@@ -1,4 +1,5 @@
include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
+include($QT_INSTALL_DOCS/config/exampleurl-qtwayland.qdocconf)
project = QtWaylandCompositor
description = Qt Wayland Compositor Reference Documentation
diff --git a/src/compositor/extensions/extensions.pri b/src/compositor/extensions/extensions.pri
index 027ea114..61ab043e 100644
--- a/src/compositor/extensions/extensions.pri
+++ b/src/compositor/extensions/extensions.pri
@@ -14,7 +14,9 @@ WAYLANDSERVERSOURCES += \
../3rdparty/protocol/xdg-shell-unstable-v6.xml \
../3rdparty/protocol/xdg-shell.xml \
../3rdparty/protocol/xdg-decoration-unstable-v1.xml \
+ ../3rdparty/protocol/xdg-output-unstable-v1.xml \
../3rdparty/protocol/ivi-application.xml \
+ ../3rdparty/protocol/idle-inhibit-unstable-v1.xml \
HEADERS += \
extensions/qwlqttouch_p.h \
@@ -41,7 +43,11 @@ HEADERS += \
extensions/qwaylandxdgshell_p.h \
extensions/qwaylandxdgdecorationv1.h \
extensions/qwaylandxdgdecorationv1_p.h \
+ extensions/qwaylandxdgoutputv1.h \
+ extensions/qwaylandxdgoutputv1_p.h \
extensions/qwaylandshellsurface.h \
+ extensions/qwaylandidleinhibitv1.h \
+ extensions/qwaylandidleinhibitv1_p.h \
extensions/qwaylandiviapplication.h \
extensions/qwaylandiviapplication_p.h \
extensions/qwaylandivisurface.h \
@@ -61,7 +67,9 @@ SOURCES += \
extensions/qwaylandxdgshellv6.cpp \
extensions/qwaylandxdgshell.cpp \
extensions/qwaylandxdgdecorationv1.cpp \
+ extensions/qwaylandxdgoutputv1.cpp \
extensions/qwaylandshellsurface.cpp \
+ extensions/qwaylandidleinhibitv1.cpp \
extensions/qwaylandiviapplication.cpp \
extensions/qwaylandivisurface.cpp \
@@ -72,6 +80,7 @@ qtHaveModule(quick) {
extensions/qwaylandquickshellsurfaceitem_p.h \
extensions/qwaylandivisurfaceintegration_p.h \
extensions/qwaylandwlshellintegration_p.h \
+ extensions/qwaylandquickxdgoutputv1.h \
extensions/qwaylandxdgshellv5integration_p.h \
extensions/qwaylandxdgshellv6integration_p.h \
extensions/qwaylandxdgshellintegration_p.h \
@@ -81,6 +90,7 @@ qtHaveModule(quick) {
extensions/qwaylandquickshellsurfaceitem.cpp \
extensions/qwaylandivisurfaceintegration.cpp \
extensions/qwaylandwlshellintegration.cpp \
+ extensions/qwaylandquickxdgoutputv1.cpp \
extensions/qwaylandxdgshellv5integration.cpp \
extensions/qwaylandxdgshellv6integration.cpp \
extensions/qwaylandxdgshellintegration.cpp \
diff --git a/src/compositor/extensions/qwaylandidleinhibitv1.cpp b/src/compositor/extensions/qwaylandidleinhibitv1.cpp
new file mode 100644
index 00000000..b97f5813
--- /dev/null
+++ b/src/compositor/extensions/qwaylandidleinhibitv1.cpp
@@ -0,0 +1,190 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtWaylandCompositor/QWaylandCompositor>
+#include <QtWaylandCompositor/private/qwaylandsurface_p.h>
+
+#include "qwaylandidleinhibitv1_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWaylandIdleInhibitManagerV1
+ \inmodule QtWaylandCompositor
+ \since 5.14
+ \brief Provides an extension that allows to inhibit the idle behavior of the compositor
+ \sa QWaylandSurface::inhibitsIdle
+
+ The QWaylandIdleInhibitV1 extension provides a way for a client to inhibit the idle behavior of
+ the compositor when a specific surface is visually relevant to the user.
+
+ QWaylandIdleInhibitManagerV1 corresponds to the Wayland interface, \c zwp_idle_inhibit_manager_v1.
+
+ Inhibited surfaces have the QWaylandSurface::inhibitsIdle property set to \c true.
+*/
+
+/*!
+ \qmltype IdleInhibitManagerV1
+ \inqmlmodule QtWayland.Compositor
+ \since 5.14
+ \brief Provides an extension that allows to inhibit the idle behavior of the compositor
+ \sa WaylandSurface::inhibitsIdle
+
+ The IdleInhibitManagerV1 extension provides a way for a client to inhibit the idle behavior of
+ the compositor when a specific surface is visually relevant to the user.
+
+ IdleInhibitManagerV1 corresponds to the Wayland interface, \c zwp_idle_inhibit_manager_v1.
+
+ To provide the functionality of the extension in a compositor, create an instance of the
+ IdleInhibitManagerV1 component and add it to the list of extensions supported by the compositor:
+
+ \qml \QtMinorVersion
+ import QtWayland.Compositor 1.\1
+
+ WaylandCompositor {
+ IdleInhibitManagerV1 {
+ // ...
+ }
+ }
+ \endqml
+
+ Inhibited surfaces have the WaylandSurface::inhibitsIdle property set to \c true.
+*/
+
+/*!
+ Constructs a QWaylandIdleInhibitManagerV1 object.
+*/
+QWaylandIdleInhibitManagerV1::QWaylandIdleInhibitManagerV1()
+ : QWaylandCompositorExtensionTemplate<QWaylandIdleInhibitManagerV1>(*new QWaylandIdleInhibitManagerV1Private())
+{
+}
+
+/*!
+ Constructs a QWaylandIdleInhibitManagerV1 object for the provided \a compositor.
+*/
+QWaylandIdleInhibitManagerV1::QWaylandIdleInhibitManagerV1(QWaylandCompositor *compositor)
+ : QWaylandCompositorExtensionTemplate<QWaylandIdleInhibitManagerV1>(compositor, *new QWaylandIdleInhibitManagerV1Private())
+{
+}
+
+/*!
+ Destructs a QWaylandIdleInhibitManagerV1 object.
+*/
+QWaylandIdleInhibitManagerV1::~QWaylandIdleInhibitManagerV1() = default;
+
+/*!
+ Initializes the extension.
+*/
+void QWaylandIdleInhibitManagerV1::initialize()
+{
+ Q_D(QWaylandIdleInhibitManagerV1);
+
+ QWaylandCompositorExtensionTemplate::initialize();
+ QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(extensionContainer());
+ if (!compositor) {
+ qCWarning(qLcWaylandCompositor) << "Failed to find QWaylandCompositor when initializing QWaylandIdleInhibitManagerV1";
+ return;
+ }
+ d->init(compositor->display(), d->interfaceVersion());
+}
+
+/*!
+ Returns the Wayland interface for the QWaylandIdleInhibitManagerV1.
+*/
+const wl_interface *QWaylandIdleInhibitManagerV1::interface()
+{
+ return QWaylandIdleInhibitManagerV1Private::interface();
+}
+
+
+void QWaylandIdleInhibitManagerV1Private::zwp_idle_inhibit_manager_v1_create_inhibitor(Resource *resource, uint id, wl_resource *surfaceResource)
+{
+ auto *surface = QWaylandSurface::fromResource(surfaceResource);
+ if (!surface) {
+ qCWarning(qLcWaylandCompositor) << "Couldn't find surface requested for creating an inhibitor";
+ wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT,
+ "invalid wl_surface@%d", wl_resource_get_id(surfaceResource));
+ return;
+ }
+
+ auto *surfacePrivate = QWaylandSurfacePrivate::get(surface);
+ if (!surfacePrivate) {
+ wl_resource_post_no_memory(resource->handle);
+ return;
+ }
+
+ auto *inhibitor = new Inhibitor(surface, resource->client(), id, resource->version());
+ if (!inhibitor) {
+ wl_resource_post_no_memory(resource->handle);
+ return;
+ }
+ surfacePrivate->idleInhibitors.append(inhibitor);
+
+ if (surfacePrivate->idleInhibitors.size() == 1)
+ Q_EMIT surface->inhibitsIdleChanged();
+}
+
+
+QWaylandIdleInhibitManagerV1Private::Inhibitor::Inhibitor(QWaylandSurface *surface,
+ wl_client *client,
+ quint32 id, quint32 version)
+ : QtWaylandServer::zwp_idle_inhibitor_v1(client, id, qMin<quint32>(version, interfaceVersion()))
+ , m_surface(surface)
+{
+ Q_ASSERT(surface);
+}
+
+void QWaylandIdleInhibitManagerV1Private::Inhibitor::zwp_idle_inhibitor_v1_destroy_resource(Resource *resource)
+{
+ Q_UNUSED(resource);
+ delete this;
+}
+
+void QWaylandIdleInhibitManagerV1Private::Inhibitor::zwp_idle_inhibitor_v1_destroy(Resource *resource)
+{
+ if (m_surface) {
+ auto *surfacePrivate = QWaylandSurfacePrivate::get(m_surface.data());
+ Q_ASSERT(surfacePrivate->idleInhibitors.contains(this));
+ surfacePrivate->idleInhibitors.removeOne(this);
+
+ if (surfacePrivate->idleInhibitors.isEmpty())
+ Q_EMIT m_surface.data()->inhibitsIdleChanged();
+ }
+
+ wl_resource_destroy(resource->handle);
+}
+
+QT_END_NAMESPACE
diff --git a/src/compositor/extensions/qwaylandidleinhibitv1.h b/src/compositor/extensions/qwaylandidleinhibitv1.h
new file mode 100644
index 00000000..53c09d08
--- /dev/null
+++ b/src/compositor/extensions/qwaylandidleinhibitv1.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDIDLEINHIBITV1_H
+#define QWAYLANDIDLEINHIBITV1_H
+
+#include <QtWaylandCompositor/QWaylandCompositorExtension>
+
+QT_BEGIN_NAMESPACE
+
+class QWaylandIdleInhibitManagerV1Private;
+
+class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandIdleInhibitManagerV1 : public QWaylandCompositorExtensionTemplate<QWaylandIdleInhibitManagerV1>
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QWaylandIdleInhibitManagerV1)
+public:
+ QWaylandIdleInhibitManagerV1();
+ explicit QWaylandIdleInhibitManagerV1(QWaylandCompositor *compositor);
+ ~QWaylandIdleInhibitManagerV1();
+
+ void initialize() override;
+
+ static const struct wl_interface *interface();
+};
+
+QT_END_NAMESPACE
+
+#endif // QWAYLANDIDLEINHIBITV1_H
diff --git a/src/compositor/extensions/qwaylandidleinhibitv1_p.h b/src/compositor/extensions/qwaylandidleinhibitv1_p.h
new file mode 100644
index 00000000..38055180
--- /dev/null
+++ b/src/compositor/extensions/qwaylandidleinhibitv1_p.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDIDLEINHIBITV1_P_H
+#define QWAYLANDIDLEINHIBITV1_P_H
+
+#include <QtWaylandCompositor/QWaylandSurface>
+#include <QtWaylandCompositor/QWaylandIdleInhibitManagerV1>
+#include <QtWaylandCompositor/private/qwaylandcompositorextension_p.h>
+#include <QtWaylandCompositor/private/qwayland-server-idle-inhibit-unstable-v1.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_WAYLAND_COMPOSITOR_EXPORT QWaylandIdleInhibitManagerV1Private
+ : public QWaylandCompositorExtensionPrivate
+ , public QtWaylandServer::zwp_idle_inhibit_manager_v1
+{
+ Q_DECLARE_PUBLIC(QWaylandIdleInhibitManagerV1)
+public:
+ explicit QWaylandIdleInhibitManagerV1Private() = default;
+
+ class Q_WAYLAND_COMPOSITOR_EXPORT Inhibitor
+ : public QtWaylandServer::zwp_idle_inhibitor_v1
+ {
+ public:
+ explicit Inhibitor(QWaylandSurface *surface, wl_client *client, quint32 id, quint32 version);
+
+ protected:
+ void zwp_idle_inhibitor_v1_destroy_resource(Resource *resource) override;
+ void zwp_idle_inhibitor_v1_destroy(Resource *resource) override;
+
+ private:
+ QPointer<QWaylandSurface> m_surface;
+ };
+
+ static QWaylandIdleInhibitManagerV1Private *get(QWaylandIdleInhibitManagerV1 *manager) { return manager ? manager->d_func() : nullptr; }
+
+protected:
+ void zwp_idle_inhibit_manager_v1_create_inhibitor(Resource *resource, uint32_t id, wl_resource *surfaceResource) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWAYLANDIDLEINHIBITV1_P_H
diff --git a/src/compositor/extensions/qwaylandquickxdgoutputv1.cpp b/src/compositor/extensions/qwaylandquickxdgoutputv1.cpp
new file mode 100644
index 00000000..eb6717a7
--- /dev/null
+++ b/src/compositor/extensions/qwaylandquickxdgoutputv1.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QWaylandCompositor>
+#include <QWaylandOutput>
+
+#include "qwaylandquickxdgoutputv1.h"
+#include "qwaylandxdgoutputv1_p.h"
+
+QWaylandQuickXdgOutputV1::QWaylandQuickXdgOutputV1()
+ : QWaylandXdgOutputV1()
+{
+}
+
+void QWaylandQuickXdgOutputV1::componentComplete()
+{
+ // Try to find the manager from the compositor extensions
+ if (!manager()) {
+ for (auto *p = parent(); p != nullptr; p = p->parent()) {
+ if (auto *c = qobject_cast<QWaylandCompositor *>(p)) {
+ for (auto *extension : c->extensions()) {
+ if (auto *m = qobject_cast<QWaylandXdgOutputManagerV1 *>(extension)) {
+ QWaylandXdgOutputV1Private::get(this)->setManager(m);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // Try to find the output from the parents
+ if (!output()) {
+ for (auto *p = parent(); p != nullptr; p = p->parent()) {
+ if (auto *o = qobject_cast<QWaylandOutput *>(p)) {
+ QWaylandXdgOutputV1Private::get(this)->setOutput(o);
+ break;
+ }
+ }
+ }
+}
diff --git a/src/compositor/extensions/qwaylandquickxdgoutputv1.h b/src/compositor/extensions/qwaylandquickxdgoutputv1.h
new file mode 100644
index 00000000..c8b16ab8
--- /dev/null
+++ b/src/compositor/extensions/qwaylandquickxdgoutputv1.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDQUICKXDGOUTPUT_V1
+#define QWAYLANDQUICKXDGOUTPUT_V1
+
+#include <QtQml/QQmlListProperty>
+#include <QtQml/QQmlParserStatus>
+#include <QtWaylandCompositor/QWaylandXdgOutputV1>
+
+QT_BEGIN_NAMESPACE
+
+class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQuickXdgOutputV1
+ : public QWaylandXdgOutputV1
+ , public QQmlParserStatus
+{
+ Q_OBJECT
+ Q_INTERFACES(QQmlParserStatus)
+public:
+ explicit QWaylandQuickXdgOutputV1();
+
+protected:
+ void classBegin() override {}
+ void componentComplete() override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWAYLANDQUICKXDGOUTPUT_V1
diff --git a/src/compositor/extensions/qwaylandwlscaler_p.h b/src/compositor/extensions/qwaylandwlscaler_p.h
index d3c2edd7..10a66f88 100644
--- a/src/compositor/extensions/qwaylandwlscaler_p.h
+++ b/src/compositor/extensions/qwaylandwlscaler_p.h
@@ -55,6 +55,7 @@
QT_BEGIN_NAMESPACE
+#if QT_DEPRECATED_SINCE(5, 13)
class QWaylandSurface;
class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandWlScalerPrivate
@@ -87,6 +88,7 @@ private:
QPointer<QWaylandSurface> m_surface = nullptr;
};
};
+#endif
QT_END_NAMESPACE
diff --git a/src/compositor/extensions/qwaylandxdgoutputv1.cpp b/src/compositor/extensions/qwaylandxdgoutputv1.cpp
new file mode 100644
index 00000000..2ab26c16
--- /dev/null
+++ b/src/compositor/extensions/qwaylandxdgoutputv1.cpp
@@ -0,0 +1,595 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QWaylandCompositor>
+
+#include "qwaylandxdgoutputv1_p.h"
+#include "qwaylandoutput_p.h"
+
+#include <wayland-server.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ * \qmltype XdgOutputManagerV1
+ * \inqmlmodule QtWayland.Compositor
+ * \since 5.14
+ * \brief Provides an extension for describing outputs in a desktop oriented fashion
+ *
+ * The XdgOutputManagerV1 extension provides a way for a compositor to describe outputs in a way
+ * that is more in line with the concept of an output on desktop oriented systems.
+ *
+ * Some information may not make sense in other applications such as IVI systems.
+ *
+ * Typically the global compositor space on a desktop system is made of a
+ * contiguous or overlapping set of rectangular regions.
+ *
+ * XdgOutputManagerV1 corresponds to the Wayland interface, \c zxdg_output_manager_v1.
+ *
+ * To provide the functionality of the extension in a compositor, create an instance of the
+ * XdgOutputManagerV1 component and add it to the list of extensions supported by the compositor,
+ * and associated each XdgOutputV1 with its WaylandOutput:
+ *
+ * \qml \QtMinorVersion
+ * import QtWayland.Compositor 1.\1
+ *
+ * WaylandCompositor {
+ * XdgOutputManagerV1 {
+ * WaylandOutput {
+ * id: output1
+ *
+ * position: Qt.point(0, 0)
+ * window: Window {}
+ *
+ * XdgOutputV1 {
+ * name: "WL-1"
+ * logicalPosition: output1.position
+ * logicalSize: Qt.size(output1.geometry.width / output1.scaleFactor,
+ * output1.geometry.height / output1.scaleFactor)
+ * }
+ * }
+ *
+ * WaylandOutput {
+ * id: output2
+ *
+ * position: Qt.point(800, 0)
+ * window: Window {}
+ *
+ * XdgOutputV1 {
+ * name: "WL-2"
+ * logicalPosition: output2.position
+ * logicalSize: Qt.size(output2.geometry.width / output2.scaleFactor,
+ * output2.geometry.height / output2.scaleFactor)
+ * }
+ * }
+ * }
+ * }
+ * \endqml
+ */
+
+/*!
+ * \class QWaylandXdgOutputManagerV1
+ * \inmodule QtWaylandCompositor
+ * \since 5.14
+ * \brief Provides an extension for describing outputs in a desktop oriented fashion
+ *
+ * The QWaylandXdgOutputManagerV1 extension provides a way for a compositor to describe outputs in a way
+ * that is more in line with the concept of an output on desktop oriented systems.
+ *
+ * Some information may not make sense in other applications such as IVI systems.
+ *
+ * QWaylandXdgOutputManagerV1 corresponds to the Wayland interface, \c zxdg_output_manager_v1.
+ */
+
+/*!
+ * Constructs a QWaylandXdgOutputManagerV1 object.
+ */
+QWaylandXdgOutputManagerV1::QWaylandXdgOutputManagerV1()
+ : QWaylandCompositorExtensionTemplate<QWaylandXdgOutputManagerV1>(*new QWaylandXdgOutputManagerV1Private())
+{
+}
+
+/*!
+ * Constructs a QWaylandXdgOutputManagerV1 object for the provided \a compositor.
+ */
+QWaylandXdgOutputManagerV1::QWaylandXdgOutputManagerV1(QWaylandCompositor *compositor)
+ : QWaylandCompositorExtensionTemplate<QWaylandXdgOutputManagerV1>(compositor, *new QWaylandXdgOutputManagerV1Private())
+{
+}
+
+// QWaylandXdgOutputManagerV1Private
+
+/*!
+ * Initializes the extension.
+ */
+void QWaylandXdgOutputManagerV1::initialize()
+{
+ Q_D(QWaylandXdgOutputManagerV1);
+
+ QWaylandCompositorExtensionTemplate::initialize();
+ QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(extensionContainer());
+ if (!compositor) {
+ qCWarning(qLcWaylandCompositor) << "Failed to find QWaylandCompositor when initializing QWaylandXdgOutputManagerV1";
+ return;
+ }
+ d->init(compositor->display(), d->interfaceVersion());
+}
+
+/*!
+ * Returns the Wayland interface for QWaylandXdgOutputManagerV1.
+ */
+const wl_interface *QWaylandXdgOutputManagerV1::interface()
+{
+ return QWaylandXdgOutputManagerV1Private::interface();
+}
+
+// QWaylandXdgOutputManagerV1Private
+
+void QWaylandXdgOutputManagerV1Private::registerXdgOutput(QWaylandOutput *output, QWaylandXdgOutputV1 *xdgOutput)
+{
+ if (!xdgOutputs.contains(output)) {
+ xdgOutputs[output] = xdgOutput;
+ QWaylandOutputPrivate::get(output)->xdgOutput = xdgOutput;
+ }
+}
+
+void QWaylandXdgOutputManagerV1Private::unregisterXdgOutput(QWaylandOutput *output)
+{
+ xdgOutputs.remove(output);
+}
+
+void QWaylandXdgOutputManagerV1Private::zxdg_output_manager_v1_get_xdg_output(Resource *resource,
+ uint32_t id,
+ wl_resource *outputResource)
+{
+ Q_Q(QWaylandXdgOutputManagerV1);
+
+ // Verify if the associated output exist
+ auto *output = QWaylandOutput::fromResource(outputResource);
+ if (!output) {
+ qCWarning(qLcWaylandCompositor,
+ "The client is requesting a QWaylandXdgOutputV1 for a "
+ "QWaylandOutput that doesn't exist");
+ wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT, "output not found");
+ return;
+ }
+
+ // Do we have a QWaylandXdgOutputV1 for this output?
+ if (!xdgOutputs.contains(output)) {
+ qCWarning(qLcWaylandCompositor,
+ "The client is requesting a QWaylandXdgOutputV1 that the compositor "
+ "didn't create before");
+ wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT,
+ "compositor didn't create a QWaylandXdgOutputV1 for this zxdg_output_v1 object");
+ return;
+ }
+
+ // Bind QWaylandXdgOutputV1 and initialize
+ auto *xdgOutput = xdgOutputs[output];
+ auto *xdgOutputPrivate = QWaylandXdgOutputV1Private::get(xdgOutput);
+ Q_ASSERT(xdgOutputPrivate);
+ xdgOutputPrivate->setManager(q);
+ xdgOutputPrivate->setOutput(output);
+ xdgOutputPrivate->add(resource->client(), id, qMin(resource->version(), QWaylandXdgOutputV1Private::interfaceVersion()));
+}
+
+// QWaylandXdgOutputV1
+
+QWaylandXdgOutputV1::QWaylandXdgOutputV1()
+ : QObject(*new QWaylandXdgOutputV1Private)
+{
+}
+
+QWaylandXdgOutputV1::QWaylandXdgOutputV1(QWaylandOutput *output, QWaylandXdgOutputManagerV1 *manager)
+ : QObject(*new QWaylandXdgOutputV1Private)
+{
+ Q_D(QWaylandXdgOutputV1);
+
+ // Set members before emitting changed signals so that handlers will
+ // see both already set and not nullptr, avoiding potential crashes
+ d->manager = manager;
+ d->output = output;
+
+ QWaylandXdgOutputManagerV1Private::get(d->manager)->registerXdgOutput(output, this);
+
+ emit managerChanged();
+ emit outputChanged();
+}
+
+QWaylandXdgOutputV1::~QWaylandXdgOutputV1()
+{
+ Q_D(QWaylandXdgOutputV1);
+
+ if (d->manager)
+ QWaylandXdgOutputManagerV1Private::get(d->manager)->unregisterXdgOutput(d->output);
+}
+
+/*!
+ * \qmlproperty XdgOutputManagerV1 QtWaylandCompositor::XdgOutputV1::manager
+ * \readonly
+ *
+ * This property holds the object that manages this XdgOutputV1.
+ */
+/*!
+ * \property QWaylandXdgOutputV1::manager
+ * \readonly
+ *
+ * This property holds the object that manages this QWaylandXdgOutputV1.
+ */
+QWaylandXdgOutputManagerV1 *QWaylandXdgOutputV1::manager() const
+{
+ Q_D(const QWaylandXdgOutputV1);
+ return d->manager;
+}
+
+/*!
+ * \qmlproperty WaylandOutput QtWaylandCompositor::XdgOutputV1::output
+ * \readonly
+ *
+ * This property holds the WaylandOutput associated with this XdgOutputV1.
+ */
+/*!
+ * \property QWaylandXdgOutputV1::output
+ * \readonly
+ *
+ * This property holds the QWaylandOutput associated with this QWaylandXdgOutputV1.
+ */
+QWaylandOutput *QWaylandXdgOutputV1::output() const
+{
+ Q_D(const QWaylandXdgOutputV1);
+ return d->output;
+}
+
+/*!
+ * \qmlproperty string QtWaylandCompositor::XdgOutputV1::name
+ *
+ * This property holds the name of this output.
+ *
+ * The naming convention is compositor defined, but limited to alphanumeric
+ * characters and dashes ("-"). Each name is unique and will also remain
+ * consistent across sessions with the same hardware and software configuration.
+ *
+ * Examples of names include "HDMI-A-1", "WL-1", "X11-1" etc...
+ * However don't assume the name reflects the underlying technology.
+ *
+ * Changing this property after initialization doesn't take effect.
+ */
+/*!
+ * \property QWaylandXdgOutputV1::name
+ *
+ * This property holds the name of this output.
+ *
+ * The naming convention is compositor defined, but limited to alphanumeric
+ * characters and dashes ("-"). Each name is unique and will also remain
+ * consistent across sessions with the same hardware and software configuration.
+ *
+ * Examples of names include "HDMI-A-1", "WL-1", "X11-1" etc...
+ * However don't assume the name reflects the underlying technology.
+ *
+ * Changing this property after initialization doesn't take effect.
+ */
+QString QWaylandXdgOutputV1::name() const
+{
+ Q_D(const QWaylandXdgOutputV1);
+ return d->name;
+}
+
+void QWaylandXdgOutputV1::setName(const QString &name)
+{
+ Q_D(QWaylandXdgOutputV1);
+
+ if (d->name == name)
+ return;
+
+ // Can't change after clients bound to xdg-output
+ if (d->initialized) {
+ qCWarning(qLcWaylandCompositor, "QWaylandXdgOutputV1::name cannot be changed after initialization");
+ return;
+ }
+
+ d->name = name;
+ emit nameChanged();
+}
+
+/*!
+ * \qmlproperty string QtWaylandCompositor::XdgOutputV1::description
+ *
+ * This property holds the description of this output.
+ *
+ * No convention is defined for the description.
+ *
+ * Changing this property after initialization doesn't take effect.
+ */
+/*!
+ * \property QWaylandXdgOutputV1::description
+ *
+ * This property holds the description of this output.
+ *
+ * No convention is defined for the description.
+ *
+ * Changing this property after initialization doesn't take effect.
+ */
+QString QWaylandXdgOutputV1::description() const
+{
+ Q_D(const QWaylandXdgOutputV1);
+ return d->description;
+}
+
+void QWaylandXdgOutputV1::setDescription(const QString &description)
+{
+ Q_D(QWaylandXdgOutputV1);
+
+ if (d->description == description)
+ return;
+
+ // Can't change after clients bound to xdg-output
+ if (d->initialized) {
+ qCWarning(qLcWaylandCompositor, "QWaylandXdgOutputV1::description cannot be changed after initialization");
+ return;
+ }
+
+ d->description = description;
+ emit descriptionChanged();
+}
+
+/*!
+ * \qmlproperty point QtWaylandCompositor::XdgOutputV1::logicalPosition
+ *
+ * This property holds the coordinates of the output within the global compositor space.
+ *
+ * The default value is 0,0.
+ */
+/*!
+ * \property QWaylandXdgOutputV1::logicalPosition
+ *
+ * This property holds the coordinates of the output within the global compositor space.
+ *
+ * The default value is 0,0.
+ */
+QPoint QWaylandXdgOutputV1::logicalPosition() const
+{
+ Q_D(const QWaylandXdgOutputV1);
+ return d->logicalPos;
+}
+
+void QWaylandXdgOutputV1::setLogicalPosition(const QPoint &position)
+{
+ Q_D(QWaylandXdgOutputV1);
+
+ if (d->logicalPos == position)
+ return;
+
+ d->logicalPos = position;
+ if (d->initialized) {
+ d->sendLogicalPosition(position);
+ d->sendDone();
+ }
+ emit logicalPositionChanged();
+ emit logicalGeometryChanged();
+}
+
+/*!
+ * \qmlproperty size QtWaylandCompositor::XdgOutputV1::logicalSize
+ *
+ * This property holds the size of the output in the global compositor space.
+ *
+ * The default value is -1,-1 which is invalid.
+ *
+ * Please remember that this is the logical size, not the physical size.
+ * For example, for a WaylandOutput mode 3840x2160 and a scale factor 2:
+ * \list
+ * \li A compositor not scaling the surface buffers, will report a logical size of 3840x2160.
+ * \li A compositor automatically scaling the surface buffers, will report a logical size of 1920x1080.
+ * \li A compositor using a fractional scale of 1.5, will report a logical size of 2560x1620.
+ * \endlist
+ */
+/*!
+ * \property QWaylandXdgOutputV1::logicalSize
+ *
+ * This property holds the size of the output in the global compositor space.
+ *
+ * The default value is -1,-1 which is invalid.
+ *
+ * Please remember that this is the logical size, not the physical size.
+ * For example, for a WaylandOutput mode 3840x2160 and a scale factor 2:
+ * \list
+ * \li A compositor not scaling the surface buffers, will report a logical size of 3840x2160.
+ * \li A compositor automatically scaling the surface buffers, will report a logical size of 1920x1080.
+ * \li A compositor using a fractional scale of 1.5, will report a logical size of 2560x1620.
+ * \endlist
+ */
+QSize QWaylandXdgOutputV1::logicalSize() const
+{
+ Q_D(const QWaylandXdgOutputV1);
+ return d->logicalSize;
+}
+
+void QWaylandXdgOutputV1::setLogicalSize(const QSize &size)
+{
+ Q_D(QWaylandXdgOutputV1);
+
+ if (d->logicalSize == size)
+ return;
+
+ d->logicalSize = size;
+ if (d->initialized) {
+ d->sendLogicalSize(size);
+ d->sendDone();
+ }
+ emit logicalSizeChanged();
+ emit logicalGeometryChanged();
+}
+
+/*!
+ * \qmlproperty rect QtWaylandCompositor::XdgOutputV1::logicalGeometry
+ * \readonly
+ *
+ * This property holds the position and size of the output in the global compositor space.
+ * It's the combination of the logical position and logical size.
+ *
+ * \sa XdgOutputV1::logicalPosition
+ * \sa XdgOutputV1::logicalSize
+ */
+/*!
+ * \property QWaylandXdgOutputV1::logicalGeometry
+ * \readonly
+ *
+ * This property holds the position and size of the output in the global compositor space.
+ * It's the combination of the logical position and logical size.
+ *
+ * \sa QWaylandXdgOutputV1::logicalPosition
+ * \sa QWaylandXdgOutputV1::logicalSize
+ */
+QRect QWaylandXdgOutputV1::logicalGeometry() const
+{
+ Q_D(const QWaylandXdgOutputV1);
+ return QRect(d->logicalPos, d->logicalSize);
+}
+
+// QWaylandXdgOutputV1Private
+
+void QWaylandXdgOutputV1Private::sendLogicalPosition(const QPoint &position)
+{
+ const auto values = resourceMap().values();
+ for (auto *resource : values)
+ send_logical_position(resource->handle, position.x(), position.y());
+ needToSendDone = true;
+}
+
+void QWaylandXdgOutputV1Private::sendLogicalSize(const QSize &size)
+{
+ const auto values = resourceMap().values();
+ for (auto *resource : values)
+ send_logical_size(resource->handle, size.width(), size.height());
+ needToSendDone = true;
+}
+
+void QWaylandXdgOutputV1Private::sendDone()
+{
+ if (needToSendDone) {
+ const auto values = resourceMap().values();
+ for (auto *resource : values) {
+ if (resource->version() < 3)
+ send_done(resource->handle);
+ }
+ needToSendDone = false;
+ }
+}
+
+void QWaylandXdgOutputV1Private::setManager(QWaylandXdgOutputManagerV1 *_manager)
+{
+ Q_Q(QWaylandXdgOutputV1);
+
+ if (!_manager) {
+ qCWarning(qLcWaylandCompositor,
+ "Cannot associate a null QWaylandXdgOutputManagerV1 to QWaylandXdgOutputV1 %p", this);
+ return;
+ }
+
+ if (manager == _manager)
+ return;
+
+ if (manager) {
+ qCWarning(qLcWaylandCompositor,
+ "Cannot associate a different QWaylandXdgOutputManagerV1 to QWaylandXdgOutputV1 %p "
+ "after initialization", this);
+ return;
+ }
+
+ manager = _manager;
+ emit q->managerChanged();
+}
+
+void QWaylandXdgOutputV1Private::setOutput(QWaylandOutput *_output)
+{
+ Q_Q(QWaylandXdgOutputV1);
+
+ if (!_output) {
+ qCWarning(qLcWaylandCompositor,
+ "Cannot associate a null QWaylandOutput to QWaylandXdgOutputV1 %p", this);
+ return;
+ }
+
+ if (output == _output)
+ return;
+
+ if (output) {
+ qCWarning(qLcWaylandCompositor,
+ "Cannot associate a different QWaylandOutput to QWaylandXdgOutputV1 %p "
+ "after initialization", this);
+ return;
+ }
+
+ // Assign output above manager, to make both values valid in handlers
+ output = _output;
+
+ if (!manager) {
+ // Try to find the manager from the output parents
+ for (auto *p = output->parent(); p != nullptr; p = p->parent()) {
+ if (auto *m = qobject_cast<QWaylandXdgOutputManagerV1 *>(p)) {
+ manager = m;
+ emit q->managerChanged();
+ break;
+ }
+ }
+ }
+
+ emit q->outputChanged();
+
+ // Register the output
+ if (manager)
+ QWaylandXdgOutputManagerV1Private::get(manager)->registerXdgOutput(output, q);
+}
+
+void QWaylandXdgOutputV1Private::zxdg_output_v1_bind_resource(Resource *resource)
+{
+ send_logical_position(resource->handle, logicalPos.x(), logicalPos.y());
+ send_logical_size(resource->handle, logicalSize.width(), logicalSize.height());
+ if (resource->version() >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION)
+ send_name(resource->handle, name);
+ if (resource->version() >= ZXDG_OUTPUT_V1_DESCRIPTION_SINCE_VERSION)
+ send_description(resource->handle, description);
+ send_done(resource->handle);
+
+ initialized = true;
+}
+
+void QWaylandXdgOutputV1Private::zxdg_output_v1_destroy(Resource *resource)
+{
+ wl_resource_destroy(resource->handle);
+}
+
+QT_END_NAMESPACE
diff --git a/src/compositor/extensions/qwaylandxdgoutputv1.h b/src/compositor/extensions/qwaylandxdgoutputv1.h
new file mode 100644
index 00000000..c5f03758
--- /dev/null
+++ b/src/compositor/extensions/qwaylandxdgoutputv1.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDXDGOUTPUTV1_H
+#define QWAYLANDXDGOUTPUTV1_H
+
+#include <QRect>
+#include <QWaylandCompositorExtension>
+#include <QtWaylandCompositor/qwaylandquickchildren.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWaylandOutput;
+
+class QWaylandXdgOutputManagerV1Private;
+class QWaylandXdgOutputV1Private;
+
+class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgOutputManagerV1
+ : public QWaylandCompositorExtensionTemplate<QWaylandXdgOutputManagerV1>
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QWaylandXdgOutputManagerV1)
+public:
+ explicit QWaylandXdgOutputManagerV1();
+ QWaylandXdgOutputManagerV1(QWaylandCompositor *compositor);
+
+ void initialize() override;
+
+ static const wl_interface *interface();
+};
+
+class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgOutputV1 : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QWaylandXdgOutputV1)
+ Q_WAYLAND_COMPOSITOR_DECLARE_QUICK_CHILDREN(QWaylandXdgOutputV1)
+ Q_PROPERTY(QWaylandXdgOutputManagerV1 *manager READ manager NOTIFY managerChanged)
+ Q_PROPERTY(QWaylandOutput *output READ output NOTIFY outputChanged)
+ Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
+ Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY descriptionChanged)
+ Q_PROPERTY(QPoint logicalPosition READ logicalPosition WRITE setLogicalPosition NOTIFY logicalPositionChanged)
+ Q_PROPERTY(QSize logicalSize READ logicalSize WRITE setLogicalSize NOTIFY logicalSizeChanged)
+ Q_PROPERTY(QRect logicalGeometry READ logicalGeometry NOTIFY logicalGeometryChanged)
+public:
+ QWaylandXdgOutputV1();
+ QWaylandXdgOutputV1(QWaylandOutput *output, QWaylandXdgOutputManagerV1 *manager);
+ ~QWaylandXdgOutputV1() override;
+
+ QWaylandXdgOutputManagerV1 *manager() const;
+ QWaylandOutput *output() const;
+
+ QString name() const;
+ void setName(const QString &name);
+
+ QString description() const;
+ void setDescription(const QString &name);
+
+ QPoint logicalPosition() const;
+ void setLogicalPosition(const QPoint &position);
+
+ QSize logicalSize() const;
+ void setLogicalSize(const QSize &size);
+
+ QRect logicalGeometry() const;
+
+Q_SIGNALS:
+ void managerChanged();
+ void outputChanged();
+ void logicalPositionChanged();
+ void logicalSizeChanged();
+ void logicalGeometryChanged();
+ void nameChanged();
+ void descriptionChanged();
+};
+
+QT_END_NAMESPACE
+
+#endif // QWAYLANDXDGOUTPUTV1_H
diff --git a/src/compositor/extensions/qwaylandxdgoutputv1_p.h b/src/compositor/extensions/qwaylandxdgoutputv1_p.h
new file mode 100644
index 00000000..2e8a6fff
--- /dev/null
+++ b/src/compositor/extensions/qwaylandxdgoutputv1_p.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDXDGOUTPUTV1_P_H
+#define QWAYLANDXDGOUTPUTV1_P_H
+
+#include <QWaylandOutput>
+#include <QWaylandXdgOutputV1>
+#include <QtWaylandCompositor/private/qwaylandcompositorextension_p.h>
+#include <QtWaylandCompositor/private/qwayland-server-xdg-output-unstable-v1.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_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgOutputManagerV1Private
+ : public QWaylandCompositorExtensionPrivate
+ , public QtWaylandServer::zxdg_output_manager_v1
+{
+ Q_DECLARE_PUBLIC(QWaylandXdgOutputManagerV1)
+public:
+ explicit QWaylandXdgOutputManagerV1Private() = default;
+
+ void registerXdgOutput(QWaylandOutput *output, QWaylandXdgOutputV1 *xdgOutput);
+ void unregisterXdgOutput(QWaylandOutput *output);
+
+ static QWaylandXdgOutputManagerV1Private *get(QWaylandXdgOutputManagerV1 *manager) { return manager ? manager->d_func() : nullptr; }
+
+protected:
+ void zxdg_output_manager_v1_get_xdg_output(Resource *resource, uint32_t id,
+ wl_resource *outputResource) override;
+
+private:
+ QHash<QWaylandOutput *, QWaylandXdgOutputV1 *> xdgOutputs;
+};
+
+class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgOutputV1Private
+ : public QObjectPrivate
+ , public QtWaylandServer::zxdg_output_v1
+{
+ Q_DECLARE_PUBLIC(QWaylandXdgOutputV1)
+public:
+ explicit QWaylandXdgOutputV1Private() = default;
+
+ void sendLogicalPosition(const QPoint &position);
+ void sendLogicalSize(const QSize &size);
+ void sendDone();
+
+ void setManager(QWaylandXdgOutputManagerV1 *manager);
+ void setOutput(QWaylandOutput *output);
+
+ static QWaylandXdgOutputV1Private *get(QWaylandXdgOutputV1 *xdgOutput) { return xdgOutput ? xdgOutput->d_func() : nullptr; }
+
+ bool initialized = false;
+ QWaylandOutput *output = nullptr;
+ QWaylandXdgOutputManagerV1 *manager = nullptr;
+ QPoint logicalPos;
+ QSize logicalSize;
+ QString name;
+ QString description;
+ bool needToSendDone = false;
+
+protected:
+ void zxdg_output_v1_bind_resource(Resource *resource) override;
+ void zxdg_output_v1_destroy(Resource *resource) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWAYLANDXDGOUTPUTV1_P_H
diff --git a/src/compositor/wayland_wrapper/qwlclientbuffer.cpp b/src/compositor/wayland_wrapper/qwlclientbuffer.cpp
index cb1ee3da..ef6b2648 100644
--- a/src/compositor/wayland_wrapper/qwlclientbuffer.cpp
+++ b/src/compositor/wayland_wrapper/qwlclientbuffer.cpp
@@ -81,7 +81,7 @@ void ClientBuffer::setDestroyed()
m_committed = false;
m_buffer = nullptr;
- if (!m_refCount)
+ if (!m_refCount.loadAcquire())
delete this;
}