diff options
33 files changed, 650 insertions, 170 deletions
diff --git a/examples/wayland/pure-qml/qml/main.qml b/examples/wayland/pure-qml/qml/main.qml index 8030f8efe..391f683e3 100644 --- a/examples/wayland/pure-qml/qml/main.qml +++ b/examples/wayland/pure-qml/qml/main.qml @@ -62,7 +62,7 @@ WaylandCompositor { function addScreen() { var screen = screenComponent.createObject(0, { "compositor" : compositor } ); - var output = compositor.addOutput(screen); + var output = compositor.primaryOutputSpace.addOutputWindow(screen); output.automaticFrameCallbacks = true; } diff --git a/examples/wayland/qml-compositor/main.cpp b/examples/wayland/qml-compositor/main.cpp index 489fac6e8..4cd1e791d 100644 --- a/examples/wayland/qml-compositor/main.cpp +++ b/examples/wayland/qml-compositor/main.cpp @@ -44,6 +44,7 @@ #include <QtCompositor/qwaylandsurfaceitem.h> #include <QtCompositor/qwaylandoutput.h> +#include <QtCompositor/qwaylandoutputspace.h> #include <QGuiApplication> #include <QTimer> @@ -63,6 +64,7 @@ class QmlCompositor : public QQuickView public: QmlCompositor() : m_fullscreenSurface(0) + , m_output(0) { m_compositor.setExtensionFlags(QWaylandCompositor::DefaultExtensions | QWaylandCompositor::SubSurfaceExtension); m_compositor.create(); @@ -72,7 +74,7 @@ public: setColor(Qt::black); winId(); m_compositor.addDefaultShell(); - m_compositor.createOutput(this, "", ""); + m_output = m_compositor.primaryOutputSpace()->addOutputWindow(this, "", ""); connect(this, SIGNAL(afterRendering()), this, SLOT(sendCallbacks())); connect(&m_compositor, &QWaylandCompositor::surfaceCreated, this, &QmlCompositor::onSurfaceCreated); @@ -124,9 +126,10 @@ private slots: void sendCallbacks() { if (m_fullscreenSurface) - m_compositor.sendFrameCallbacks(QList<QWaylandSurface *>() << m_fullscreenSurface); + m_fullscreenSurface->sendFrameCallbacks(); + else - m_compositor.sendFrameCallbacks(m_compositor.surfaces()); + m_output->sendFrameCallbacks(); } void onSurfaceCreated(QWaylandSurface *surface) { @@ -151,6 +154,7 @@ protected: private: QWaylandQuickCompositor m_compositor; QWaylandQuickSurface *m_fullscreenSurface; + QWaylandOutput *m_output; }; int main(int argc, char *argv[]) diff --git a/examples/wayland/qwindow-compositor/qwindowcompositor.cpp b/examples/wayland/qwindow-compositor/qwindowcompositor.cpp index 5e7c8136c..50d24cffc 100644 --- a/examples/wayland/qwindow-compositor/qwindowcompositor.cpp +++ b/examples/wayland/qwindow-compositor/qwindowcompositor.cpp @@ -57,6 +57,7 @@ #include <QtCompositor/qwaylandbufferref.h> #include <QtCompositor/qwaylandsurfaceview.h> #include <QtCompositor/qwaylandoutput.h> +#include <QtCompositor/qwaylandoutputspace.h> QT_BEGIN_NAMESPACE @@ -122,7 +123,8 @@ QWindowCompositor::QWindowCompositor(CompositorWindow *window) setRetainedSelectionEnabled(true); - createOutput(window, "", ""); + primaryOutputSpace()->addOutputWindow(window, "", ""); + addDefaultShell(); } @@ -303,7 +305,7 @@ QWaylandSurfaceView *QWindowCompositor::viewAt(const QPointF &point, QPointF *lo void QWindowCompositor::render() { m_window->makeCurrent(); - frameStarted(); + primaryOutput()->frameStarted(); cleanupGraphicsResources(); @@ -324,7 +326,7 @@ void QWindowCompositor::render() } m_textureBlitter->release(); - sendFrameCallbacks(surfaces()); + primaryOutput()->sendFrameCallbacks(); // N.B. Never call glFinish() here as the busylooping with vsync 'feature' of the nvidia binary driver is not desirable. m_window->swapBuffers(); diff --git a/examples/wayland/server-buffer/compositor/main.cpp b/examples/wayland/server-buffer/compositor/main.cpp index 50fc9d390..b34db1630 100644 --- a/examples/wayland/server-buffer/compositor/main.cpp +++ b/examples/wayland/server-buffer/compositor/main.cpp @@ -42,6 +42,7 @@ #include "qwaylandquickcompositor.h" #include "qwaylandsurface.h" #include "qwaylandsurfaceitem.h" +#include "qwaylandoutputspace.h" #include <QGuiApplication> #include <QTimer> @@ -83,7 +84,7 @@ public: m_view.setResizeMode(QQuickView::SizeRootObjectToView); m_view.setColor(Qt::black); m_view.create(); - createOutput(&m_view, "", ""); + m_output = primaryOutputSpace()->addOutputWindow(&m_view, "", ""); addDefaultShell(); connect(&m_view, &QQuickView::afterRendering, this, &QmlCompositor::sendCallbacks); @@ -131,7 +132,7 @@ private slots: } void sendCallbacks() { - sendFrameCallbacks(surfaces()); + m_output->sendFrameCallbacks(); } void initiateServerBuffer() @@ -237,6 +238,7 @@ protected: private: QQuickView m_view; + QWaylandOutput *m_output; QtWayland::ServerBuffer *m_server_buffer_32_bit; ServerBufferItem *m_server_buffer_item_32_bit; QtWayland::ServerBuffer *m_server_buffer_8_bit; diff --git a/src/compositor/compositor_api/compositor_api.pri b/src/compositor/compositor_api/compositor_api.pri index b134b5ef4..656f2e0c5 100644 --- a/src/compositor/compositor_api/compositor_api.pri +++ b/src/compositor/compositor_api/compositor_api.pri @@ -13,7 +13,9 @@ HEADERS += \ compositor_api/qwaylandsurfaceview.h \ compositor_api/qwaylandsurfaceview_p.h \ compositor_api/qwaylandglobalinterface.h \ - compositor_api/qwaylandsurfaceinterface.h + compositor_api/qwaylandsurfaceinterface.h \ + compositor_api/qwaylandoutputspace.h \ + compositor_api/qwaylandoutputspace_p.h SOURCES += \ compositor_api/qwaylandcompositor.cpp \ @@ -26,7 +28,8 @@ SOURCES += \ compositor_api/qwaylandbufferref.cpp \ compositor_api/qwaylandsurfaceview.cpp \ compositor_api/qwaylandglobalinterface.cpp \ - compositor_api/qwaylandsurfaceinterface.cpp + compositor_api/qwaylandsurfaceinterface.cpp \ + compositor_api/qwaylandoutputspace.cpp QT += core-private diff --git a/src/compositor/compositor_api/qwaylandcompositor.cpp b/src/compositor/compositor_api/qwaylandcompositor.cpp index bcb373761..0c7342329 100644 --- a/src/compositor/compositor_api/qwaylandcompositor.cpp +++ b/src/compositor/compositor_api/qwaylandcompositor.cpp @@ -137,53 +137,57 @@ void QWaylandCompositor::destroyClient(QWaylandClient *client) m_compositor->destroyClient(client); } -#if QT_DEPRECATED_SINCE(5, 5) -void QWaylandCompositor::frameStarted() +QList<QWaylandSurface *> QWaylandCompositor::surfacesForClient(QWaylandClient* client) const { - foreach (QWaylandOutput *output, outputs()) - output->frameStarted(); + QList<QWaylandSurface *> surfs; + foreach (QWaylandSurface *surface, m_compositor->m_all_surfaces) { + if (surface->client() == client) + surfs.append(surface); + } + return surfs; } -void QWaylandCompositor::sendFrameCallbacks(QList<QWaylandSurface *> visibleSurfaces) +QList<QWaylandSurface *> QWaylandCompositor::surfaces() const { - Q_FOREACH (QWaylandSurface *surface, visibleSurfaces) { - surface->handle()->sendFrameCallback(); - } + return m_compositor->m_all_surfaces; } -QList<QWaylandSurface *> QWaylandCompositor::surfacesForClient(QWaylandClient* client) const +QWaylandOutput *QWaylandCompositor::output(QWindow *window) const { - QList<QWaylandSurface *> surfs; - foreach (QWaylandOutput *output, outputs()) - surfs.append(output->surfacesForClient(client)); - return surfs; + return m_compositor->output(window); } -#endif //QT_DEPRECATED_SINCE(5, 5) +QWaylandOutput *QWaylandCompositor::primaryOutput() const +{ + return m_compositor->primaryOutput(); +} -QList<QWaylandSurface *> QWaylandCompositor::surfaces() const +QWaylandOutputSpace *QWaylandCompositor::primaryOutputSpace() const { - return m_compositor->m_all_surfaces; + return m_compositor->primaryOutputSpace(); } -QList<QWaylandOutput *> QWaylandCompositor::outputs() const +void QWaylandCompositor::setPrimaryOutputSpace(QWaylandOutputSpace *outputSpace) { - return m_compositor->outputs(); + m_compositor->setPrimaryOutputSpace(outputSpace); } -QWaylandOutput *QWaylandCompositor::output(QWindow *window) +void QWaylandCompositor::addOutputSpace(QWaylandOutputSpace *outputSpace) { - return m_compositor->output(window); + m_compositor->addOutputSpace(outputSpace); } -QWaylandOutput *QWaylandCompositor::primaryOutput() const +void QWaylandCompositor::removeOutputSpace(QWaylandOutputSpace *outputSpace) { - return m_compositor->primaryOutput(); + m_compositor->removeOutputSpace(outputSpace); } -void QWaylandCompositor::setPrimaryOutput(QWaylandOutput *output) +QWaylandOutput *QWaylandCompositor::createOutput(QWaylandOutputSpace *outputSpace, + QWindow *window, + const QString &manufacturer, + const QString &model) { - m_compositor->setPrimaryOutput(output); + return new QWaylandOutput(outputSpace, window, manufacturer, model); } QWaylandSurface *QWaylandCompositor::createSurface(QWaylandClient *client, quint32 id, int version) @@ -201,25 +205,6 @@ QWaylandSurfaceView *QWaylandCompositor::createView() return new QWaylandSurfaceView(); } -#if QT_DEPRECATED_SINCE(5, 5) -QWaylandSurfaceView *QWaylandCompositor::pickView(const QPointF &globalPosition) const -{ - Q_FOREACH (QWaylandOutput *output, outputs()) { - // Skip coordinates not in output - if (!QRectF(output->geometry()).contains(globalPosition)) - continue; - output->pickView(globalPosition); - } - - return Q_NULLPTR; -} - -QPointF QWaylandCompositor::mapToView(QWaylandSurfaceView *surface, const QPointF &globalPosition) const -{ - return globalPosition - surface->requestedPosition(); -} -#endif //QT_DEPRECATED_SINCE(5, 5) - /*! Override this to handle QDesktopServices::openUrl() requests from the clients. @@ -379,11 +364,4 @@ QWaylandInputDevice *QWaylandCompositor::inputDeviceFor(QInputEvent *inputEvent) return m_compositor->inputDeviceFor(inputEvent); } -QWaylandOutput *QWaylandCompositor::createOutput(QWindow *window, - const QString &manufacturer, - const QString &model) -{ - return new QWaylandOutput(this, window, manufacturer, model); -} - QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandcompositor.h b/src/compositor/compositor_api/qwaylandcompositor.h index dd1ce0abd..462f381c6 100644 --- a/src/compositor/compositor_api/qwaylandcompositor.h +++ b/src/compositor/compositor_api/qwaylandcompositor.h @@ -60,6 +60,7 @@ class QWaylandDrag; class QWaylandGlobalInterface; class QWaylandSurfaceView; class QWaylandOutput; +class QWaylandOutputSpace; namespace QtWayland { @@ -72,7 +73,8 @@ class Q_COMPOSITOR_EXPORT QWaylandCompositor : public QObject Q_PROPERTY(QByteArray socketName READ socketName WRITE setSocketName) Q_PROPERTY(QWaylandCompositor::ExtensionFlags extensionFlags READ extensionFlags WRITE setExtensionFlags) Q_PROPERTY(bool retainedSelection READ retainedSelectionEnabled WRITE setRetainedSelectionEnabled) - Q_PROPERTY(QWaylandOutput *primaryOutput READ primaryOutput WRITE setPrimaryOutput NOTIFY primaryOutputChanged) + Q_PROPERTY(QWaylandOutputSpace *primaryOutputSpace READ primaryOutputSpace WRITE setPrimaryOutputSpace NOTIFY primaryOutputSpaceChanged) + Q_PROPERTY(QWaylandOutput *primaryOutput READ primaryOutput NOTIFY primaryOutputChanged); public: enum ExtensionFlag { @@ -108,25 +110,16 @@ public: Q_INVOKABLE void destroyClientForSurface(QWaylandSurface *surface); Q_INVOKABLE void destroyClient(QWaylandClient *client); -#if QT_DEPRECATED_SINCE(5, 5) - QT_DEPRECATED void frameStarted(); - QT_DEPRECATED void sendFrameCallbacks(QList<QWaylandSurface *> visibleSurfaces); - - QT_DEPRECATED QList<QWaylandSurface *> surfacesForClient(QWaylandClient* client) const; -#endif //QT_DEPRECATED_SINCE(5, 5) - - QT_DEPRECATED QList<QWaylandSurface *> surfaces() const; + QList<QWaylandSurface *> surfaces() const; + QList<QWaylandSurface *> surfacesForClient(QWaylandClient* client) const; - Q_INVOKABLE QList<QWaylandOutput *> outputs() const; - Q_INVOKABLE QWaylandOutput *output(QWindow *window); + QWaylandOutput *output(QWindow *window) const; QWaylandOutput *primaryOutput() const; - void setPrimaryOutput(QWaylandOutput *output); - -#if QT_DEPRECATED_SINCE(5, 5) - Q_INVOKABLE virtual QWaylandSurfaceView *pickView(const QPointF &globalPosition) const; - Q_INVOKABLE virtual QPointF mapToView(QWaylandSurfaceView *view, const QPointF &surfacePosition) const; -#endif // QT_DEPRECATED_SINCE(5 5) + QWaylandOutputSpace *primaryOutputSpace() const; + void setPrimaryOutputSpace(QWaylandOutputSpace *outputSpace); + void addOutputSpace(QWaylandOutputSpace *outputSpace); + void removeOutputSpace(QWaylandOutputSpace *outputSpace); virtual bool openUrl(QWaylandClient *client, const QUrl &url); @@ -179,18 +172,22 @@ signals: void currentCurserSurfaceRequest(QWaylandSurface *surface, int hotspotX, int hotspotY); + void primaryOutputSpaceChanged(); void primaryOutputChanged(); + void outputSpacesChanged(); protected: QWaylandCompositor(QtWayland::Compositor *dptr); virtual void retainedSelectionReceived(QMimeData *mimeData); - virtual QWaylandOutput *createOutput(QWindow *window, + virtual QWaylandOutput *createOutput(QWaylandOutputSpace *outputSpace, + QWindow *window, const QString &manufacturer, const QString &model); virtual QWaylandSurface *createSurface(QWaylandClient *client, quint32 id, int version); virtual QWaylandSurfaceView *createView(); friend class QtWayland::Compositor; + friend class QWaylandOutputSpacePrivate; QtWayland::Compositor *m_compositor; }; diff --git a/src/compositor/compositor_api/qwaylandinput.cpp b/src/compositor/compositor_api/qwaylandinput.cpp index 305cbc2e5..34d4ac8ba 100644 --- a/src/compositor/compositor_api/qwaylandinput.cpp +++ b/src/compositor/compositor_api/qwaylandinput.cpp @@ -174,6 +174,16 @@ void QWaylandInputDevice::setMouseFocus(QWaylandSurfaceView *surface, const QPoi d->setMouseFocus(surface,localPos,globalPos); } +QWaylandOutputSpace *QWaylandInputDevice::outputSpace() const +{ + return d->outputSpace(); +} + +void QWaylandInputDevice::setOutputSpace(QWaylandOutputSpace *outputSpace) +{ + d->setOutputSpace(outputSpace); +} + QWaylandCompositor *QWaylandInputDevice::compositor() const { return d->compositor()->waylandCompositor(); diff --git a/src/compositor/compositor_api/qwaylandinput.h b/src/compositor/compositor_api/qwaylandinput.h index a6e295929..013f6d789 100644 --- a/src/compositor/compositor_api/qwaylandinput.h +++ b/src/compositor/compositor_api/qwaylandinput.h @@ -51,6 +51,7 @@ class QKeyEvent; class QTouchEvent; class QWaylandSurfaceView; class QInputEvent; +class QWaylandOutputSpace; namespace QtWayland { class InputDevice; @@ -119,6 +120,9 @@ public: QWaylandSurfaceView *mouseFocus() const; void setMouseFocus(QWaylandSurfaceView *surface, const QPointF &local_pos, const QPointF &global_pos = QPointF()); + QWaylandOutputSpace *outputSpace() const; + void setOutputSpace(QWaylandOutputSpace *outputSpace); + QWaylandCompositor *compositor() const; QtWayland::InputDevice *handle() const; diff --git a/src/compositor/compositor_api/qwaylandoutput.cpp b/src/compositor/compositor_api/qwaylandoutput.cpp index dffda876e..d94f38878 100644 --- a/src/compositor/compositor_api/qwaylandoutput.cpp +++ b/src/compositor/compositor_api/qwaylandoutput.cpp @@ -51,15 +51,13 @@ QT_BEGIN_NAMESPACE -QWaylandOutput::QWaylandOutput(QWaylandCompositor *compositor, QWindow *window, +QWaylandOutput::QWaylandOutput(QWaylandOutputSpace *outputSpace, QWindow *window, const QString &manufacturer, const QString &model) : QObject() - , d_ptr(new QtWayland::Output(compositor->handle(), window)) + , d_ptr(new QtWayland::Output(this, outputSpace, window)) { - d_ptr->m_output = this; d_ptr->setManufacturer(manufacturer); d_ptr->setModel(model); - d_ptr->compositor()->addOutput(this); QObject::connect(window, &QWindow::widthChanged, this, &QWaylandOutput::setWidth); QObject::connect(window, &QWindow::heightChanged, this, &QWaylandOutput::setHeight); QObject::connect(window, &QObject::destroyed, this, &QWaylandOutput::windowDestroyed); @@ -67,7 +65,7 @@ QWaylandOutput::QWaylandOutput(QWaylandCompositor *compositor, QWindow *window, QWaylandOutput::~QWaylandOutput() { - d_ptr->compositor()->removeOutput(this); + d_ptr->outputSpace()->removeOutput(this); } QWaylandOutput *QWaylandOutput::fromResource(wl_resource *resource) @@ -81,7 +79,18 @@ QWaylandOutput *QWaylandOutput::fromResource(wl_resource *resource) if (!output) return Q_NULLPTR; - return output->output(); + return output->waylandOutput(); +} + +void QWaylandOutput::setOutputSpace(QWaylandOutputSpace *outputSpace) +{ + Q_ASSERT(outputSpace); + d_ptr->setOutputSpace(outputSpace, true); +} + +QWaylandOutputSpace *QWaylandOutput::outputSpace() const +{ + return d_ptr->outputSpace(); } void QWaylandOutput::update() @@ -94,7 +103,7 @@ void QWaylandOutput::update() QWaylandCompositor *QWaylandOutput::compositor() const { - return d_ptr->compositor()->waylandCompositor(); + return d_ptr->outputSpace()->compositor(); } QString QWaylandOutput::manufacturer() const @@ -263,11 +272,6 @@ void QWaylandOutput::sendFrameCallbacks() d_ptr->sendFrameCallbacks(); } -QList<QWaylandSurface *> QWaylandOutput::surfacesForClient(QWaylandClient *client) const -{ - return d_ptr->surfacesForClient(client); -} - QtWayland::Output *QWaylandOutput::handle() const { return d_ptr.data(); diff --git a/src/compositor/compositor_api/qwaylandoutput.h b/src/compositor/compositor_api/qwaylandoutput.h index bc92fe5a4..c602bf223 100644 --- a/src/compositor/compositor_api/qwaylandoutput.h +++ b/src/compositor/compositor_api/qwaylandoutput.h @@ -53,6 +53,7 @@ class QWindow; class QWaylandSurface; class QWaylandSurfaceView; class QWaylandClient; +class QWaylandOutputSpace; namespace QtWayland { class Output; @@ -74,6 +75,7 @@ class Q_COMPOSITOR_EXPORT QWaylandOutput : public QObject Q_PROPERTY(QWaylandCompositor *compositor READ compositor CONSTANT) Q_PROPERTY(QWindow *window READ window CONSTANT) Q_PROPERTY(bool sizeFollowsWindow READ sizeFollowsWindow WRITE setSizeFollowsWindow NOTIFY sizeFollowsWindowChanged) + Q_PROPERTY(QWaylandOutputSpace *outputSpace READ outputSpace WRITE setOutputSpace NOTIFY outputSpaceChanged) Q_ENUMS(Subpixel Transform) public: @@ -103,12 +105,15 @@ public: int refreshRate; }; - QWaylandOutput(QWaylandCompositor *compositor, QWindow *window, + QWaylandOutput(QWaylandOutputSpace *outputSpace, QWindow *window, const QString &manufacturer, const QString &model); ~QWaylandOutput(); static QWaylandOutput *fromResource(wl_resource *resource); + void setOutputSpace(QWaylandOutputSpace *outputSpace); + QWaylandOutputSpace *outputSpace() const; + virtual void update(); QWaylandCompositor *compositor() const; @@ -154,8 +159,6 @@ public: void frameStarted(); void sendFrameCallbacks(); - QList<QWaylandSurface *> surfacesForClient(QWaylandClient *client) const; - QtWayland::Output *handle() const; Q_INVOKABLE virtual QWaylandSurfaceView *pickView(const QPointF &outputPosition) const; @@ -172,6 +175,7 @@ Q_SIGNALS: void transformChanged(); void sizeFollowsWindowChanged(); void physicalSizeFollowsSizeChanged(); + void outputSpaceChanged(); protected: QScopedPointer<QtWayland::Output> d_ptr; diff --git a/src/compositor/compositor_api/qwaylandoutputspace.cpp b/src/compositor/compositor_api/qwaylandoutputspace.cpp new file mode 100644 index 000000000..3f78158d0 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandoutputspace.cpp @@ -0,0 +1,191 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). +** 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 "qwaylandoutputspace.h" +#include "qwaylandoutputspace_p.h" +#include "qwaylandcompositor.h" +#include <QtCompositor/QWaylandSurfaceView> +#include <QtCompositor/QWaylandOutput> + +QT_BEGIN_NAMESPACE + +QWaylandOutputSpace::QWaylandOutputSpace(QWaylandCompositor *compositor) + : QObject(*new QWaylandOutputSpacePrivate(compositor), compositor) +{ + +} + +QWaylandCompositor *QWaylandOutputSpace::compositor() const +{ + Q_D(const QWaylandOutputSpace); + return d->compositor; +} + +QRect QWaylandOutputSpace::geometry() const +{ + Q_D(const QWaylandOutputSpace); + return d->geometry; +} + +void QWaylandOutputSpace::setGeometry(const QRect &geometry) +{ + Q_D(QWaylandOutputSpace); + if (d->geometry == geometry || d->geometryConstraint == QWaylandOutputSpace::AutomaticBoundingRect) + return; + d->geometry = geometry; + emit geometryChanged(); +} + +void QWaylandOutputSpace::setGeometryConstraint(QWaylandOutputSpace::GeometryConstraint geometryConstraint) +{ + Q_D(QWaylandOutputSpace); + if (d->geometryConstraint == geometryConstraint) + return; + d->geometryConstraint = geometryConstraint; + emit geometryConstraintChanged(); +} + +QWaylandOutputSpace::GeometryConstraint QWaylandOutputSpace::geometryConstraint() const +{ + Q_D(const QWaylandOutputSpace); + return d->geometryConstraint; +} + +QWaylandOutput *QWaylandOutputSpace::addOutputWindow(QWindow *outputWindow, + const QString &manufacturer, + const QString &model) +{ + Q_D(QWaylandOutputSpace); + return d->createAndAddOutput(outputWindow, manufacturer, model, false); +} + +QWaylandOutput *QWaylandOutputSpace::addPrimaryOutputWindow(QWindow *outputWindow, + const QString &manufacturer, + const QString &model) +{ + Q_D(QWaylandOutputSpace); + return d->createAndAddOutput(outputWindow, manufacturer, model, true); +} + +void QWaylandOutputSpace::addOutput(QWaylandOutput *output) +{ + Q_D(QWaylandOutputSpace); + d->addOutput(output, false); +} + +void QWaylandOutputSpace::addPrimaryOutput(QWaylandOutput *output) +{ + Q_D(QWaylandOutputSpace); + d->addOutput(output, true); +} + +void QWaylandOutputSpace::removeOutput(QWaylandOutput *output) +{ + Q_ASSERT(output); + Q_D(QWaylandOutputSpace); + if ( d->outputs.removeOne(output)) { + output->setOutputSpace(Q_NULLPTR); + d->adjustGeometry(); + outputsChanged(); + } +} + +void QWaylandOutputSpace::setPrimaryOutput(QWaylandOutput *output) +{ + Q_D(QWaylandOutputSpace); + if (d->outputs.isEmpty() || d->outputs.first() == output) + return; + + if (d->outputs.removeOne(output)) { + d->outputs.prepend(output); + primaryOutputChanged(); + } +} + +QWaylandOutput *QWaylandOutputSpace::output(QWindow *window) const +{ + Q_D(const QWaylandOutputSpace); + foreach (QWaylandOutput *output, d->outputs) { + if (output->window() == window) + return output; + } + return Q_NULLPTR; +} + +QWaylandOutput *QWaylandOutputSpace::primaryOutput() const +{ + Q_D(const QWaylandOutputSpace); + if (d->outputs.isEmpty()) + return Q_NULLPTR; + + return d->outputs.first(); +} + +QList<QWaylandOutput *>QWaylandOutputSpace::outputs() const +{ + Q_D(const QWaylandOutputSpace); + return d->outputs; +} + +QList<QWaylandOutput *>QWaylandOutputSpace::outputs(const QPoint &point) const +{ + Q_D(const QWaylandOutputSpace); + QList<QWaylandOutput *> retOutputs; + foreach (QWaylandOutput *output, d->outputs) { + if (output->geometry().contains(point)) + retOutputs.append(output); + } + return retOutputs; +} + +QWaylandSurfaceView *QWaylandOutputSpace::pickView(const QPointF &globalPosition) const +{ + Q_D(const QWaylandOutputSpace); + foreach (QWaylandOutput *output, d->outputs) { + if (!QRectF(output->geometry()).contains(globalPosition)) + continue; + output->pickView(globalPosition); + } + + return 0; +} + +QPointF QWaylandOutputSpace::mapToView(QWaylandSurfaceView *view, const QPointF &globalPosition) const +{ + return globalPosition - (view->requestedPosition() + view->output()->geometry().topLeft()); +} + +QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandoutputspace.h b/src/compositor/compositor_api/qwaylandoutputspace.h new file mode 100644 index 000000000..d8c40cf0c --- /dev/null +++ b/src/compositor/compositor_api/qwaylandoutputspace.h @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). +** 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 QWAYLANDOUTPUTSPACE_H +#define QWAYLANDOUTPUTSPACE_H + +#include <QtCore/QObject> + +#include "qwaylandoutput.h" + +QT_BEGIN_NAMESPACE + +class QWaylandOutputSpacePrivate; + +class Q_COMPOSITOR_EXPORT QWaylandOutputSpace : public QObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandOutputSpace) + + Q_ENUMS(GeometryConstraint) + Q_PROPERTY(GeometryConstraint geometryConstraint READ geometryConstraint WRITE setGeometryConstraint NOTIFY geometryConstraintChanged) + Q_PROPERTY(QRect geometry READ geometry WRITE setGeometry NOTIFY geometryChanged) + Q_PROPERTY(QWaylandOutput *primaryOutput READ primaryOutput WRITE setPrimaryOutput NOTIFY primaryOutputChanged) + Q_PROPERTY(QList<QWaylandOutput *> outputs READ outputs NOTIFY outputsChanged) +public: + enum GeometryConstraint { + AutomaticBoundingRect, + FixedSize + }; + + QWaylandOutputSpace(QWaylandCompositor *compositor); + + QWaylandCompositor *compositor() const; + + QRect geometry() const; + void setGeometry(const QRect &geometry); + + void setGeometryConstraint(GeometryConstraint geometryConstraint); + GeometryConstraint geometryConstraint() const; + + Q_INVOKABLE QWaylandOutput *addOutputWindow(QWindow *outputWindow, const QString &manufacturer, const QString &model); + Q_INVOKABLE QWaylandOutput *addPrimaryOutputWindow(QWindow *outputWindow, const QString &manufacturer, const QString &model); + Q_INVOKABLE void addOutput(QWaylandOutput *output); + Q_INVOKABLE void addPrimaryOutput(QWaylandOutput *output); + Q_INVOKABLE void removeOutput(QWaylandOutput *output); + + Q_INVOKABLE QWaylandOutput *output(QWindow *window) const; + + QWaylandOutput *primaryOutput() const; + void setPrimaryOutput(QWaylandOutput *output); + + Q_INVOKABLE QList<QWaylandOutput *>outputs() const; + Q_INVOKABLE QList<QWaylandOutput *>outputs(const QPoint &point) const; + + Q_INVOKABLE QWaylandSurfaceView *pickView(const QPointF &globalPosition) const; + Q_INVOKABLE QPointF mapToView(QWaylandSurfaceView *view, const QPointF &surfacePosition) const; + +signals: + void surfaceRequestedPositionChanged(QWaylandSurface *surface, const QPointF &point); + + void geometryConstraintChanged(); + void geometryChanged(); + + void outputsChanged(); + void primaryOutputChanged(); + +private: + Q_DISABLE_COPY(QWaylandOutputSpace) +}; + +QT_END_NAMESPACE + +#endif /*QWAYLANDOUTPUTSPACE_H*/ diff --git a/src/compositor/compositor_api/qwaylandoutputspace_p.h b/src/compositor/compositor_api/qwaylandoutputspace_p.h new file mode 100644 index 000000000..b0f33efbd --- /dev/null +++ b/src/compositor/compositor_api/qwaylandoutputspace_p.h @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). +** 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 QWAYLANDOUTPUTSPACE_P_H +#define QWAYLANDOUTPUTSPACE_P_H + +#include <QtCore/private/qobject_p.h> + +#include "qwaylandoutputspace.h" +#include "qwaylandcompositor.h" +#include "wayland_wrapper/qwloutput_p.h" + +QT_BEGIN_NAMESPACE + +class QWaylandOutputSpacePrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QWaylandOutputSpace) + +public: + QWaylandOutputSpacePrivate(QWaylandCompositor *compositor) + : QObjectPrivate() + , compositor(compositor) + , geometryConstraint(QWaylandOutputSpace::AutomaticBoundingRect) + { + + } + + void emitSurfacePositionChanged(QWaylandSurface *surface, const QPointF &point) + { + Q_Q(QWaylandOutputSpace); + q->surfaceRequestedPositionChanged(surface, point); + } + + void adjustGeometry() + { + if (geometryConstraint != QWaylandOutputSpace::AutomaticBoundingRect) + return; + + QRect completeRect; + foreach(QWaylandOutput *output, outputs) { + if (completeRect.isNull()) + completeRect = output->geometry(); + else + completeRect = completeRect.united(output->geometry()); + } + geometry = completeRect; + } + + QWaylandOutput *createAndAddOutput(QWindow *window, + const QString &manufacturer, + const QString &model, + bool primary) + { + Q_Q(QWaylandOutputSpace); + QWaylandOutput *output = compositor->createOutput(q, window, manufacturer, model); + addOutput(output, primary); + return output; + } + + void addOutput(QWaylandOutput *output, bool primary) + { + Q_Q(QWaylandOutputSpace); + Q_ASSERT(output); + Q_ASSERT(!outputs.contains(output)); + + output->handle()->setOutputSpace(q, false); + + if (primary) + outputs.prepend(output); + else + outputs.append(output); + adjustGeometry(); + q->outputsChanged(); + + } + + static QWaylandOutputSpacePrivate *get(QWaylandOutputSpace *outputSpace) { return outputSpace->d_func(); } + +private: + QWaylandCompositor *compositor; + QRect geometry; + QWaylandOutputSpace::GeometryConstraint geometryConstraint; + QList<QWaylandOutput *> outputs; +}; + +QT_END_NAMESPACE + +#endif /*QWAYLANDOUTPUTSPACE_P_H*/ diff --git a/src/compositor/compositor_api/qwaylandquickcompositor.cpp b/src/compositor/compositor_api/qwaylandquickcompositor.cpp index 7c37e6c59..39dae9461 100644 --- a/src/compositor/compositor_api/qwaylandquickcompositor.cpp +++ b/src/compositor/compositor_api/qwaylandquickcompositor.cpp @@ -99,7 +99,8 @@ void QWaylandQuickCompositor::setExposeDefaultShell(bool defaultShell) m_exposeDefaultShell = defaultShell; } -QWaylandOutput *QWaylandQuickCompositor::createOutput(QWindow *window, +QWaylandOutput *QWaylandQuickCompositor::createOutput(QWaylandOutputSpace *outputSpace, + QWindow *window, const QString &manufacturer, const QString &model) { @@ -109,7 +110,7 @@ QWaylandOutput *QWaylandQuickCompositor::createOutput(QWindow *window, if (!quickWindow) qFatal("%s: couldn't cast QWindow to QQuickWindow. All output windows must " "be QQuickWindow derivates when using QWaylandQuickCompositor", Q_FUNC_INFO); - QWaylandQuickOutput *output = new QWaylandQuickOutput(this, quickWindow, manufacturer, model); + QWaylandQuickOutput *output = new QWaylandQuickOutput(outputSpace, quickWindow, manufacturer, model); QQmlEngine::setObjectOwnership(output, QQmlEngine::CppOwnership); return output; } diff --git a/src/compositor/compositor_api/qwaylandquickcompositor.h b/src/compositor/compositor_api/qwaylandquickcompositor.h index de4b2f2b7..defb04984 100644 --- a/src/compositor/compositor_api/qwaylandquickcompositor.h +++ b/src/compositor/compositor_api/qwaylandquickcompositor.h @@ -59,7 +59,8 @@ public: bool exposeDefaultShell() const; void setExposeDefaultShell(bool defaultShell); - QWaylandOutput *createOutput(QWindow *window, + QWaylandOutput *createOutput(QWaylandOutputSpace *outputSpace, + QWindow *window, const QString &manufacturer, const QString &model) Q_DECL_OVERRIDE; QWaylandSurfaceView *createView() Q_DECL_OVERRIDE; diff --git a/src/compositor/compositor_api/qwaylandquickoutput.cpp b/src/compositor/compositor_api/qwaylandquickoutput.cpp index d8341d60a..e51c8fd44 100644 --- a/src/compositor/compositor_api/qwaylandquickoutput.cpp +++ b/src/compositor/compositor_api/qwaylandquickoutput.cpp @@ -40,9 +40,9 @@ QT_BEGIN_NAMESPACE -QWaylandQuickOutput::QWaylandQuickOutput(QWaylandCompositor *compositor, QQuickWindow *window, +QWaylandQuickOutput::QWaylandQuickOutput(QWaylandOutputSpace *outputSpace, QQuickWindow *window, const QString &manufacturer, const QString &model) - : QWaylandOutput(compositor, window, manufacturer, model) + : QWaylandOutput(outputSpace, window, manufacturer, model) , m_updateScheduled(false) , m_automaticFrameCallbacks(false) { diff --git a/src/compositor/compositor_api/qwaylandquickoutput.h b/src/compositor/compositor_api/qwaylandquickoutput.h index ea89d52ce..2de24f2f5 100644 --- a/src/compositor/compositor_api/qwaylandquickoutput.h +++ b/src/compositor/compositor_api/qwaylandquickoutput.h @@ -51,7 +51,7 @@ class Q_COMPOSITOR_EXPORT QWaylandQuickOutput : public QWaylandOutput Q_OBJECT Q_PROPERTY(bool automaticFrameCallbacks READ automaticFrameCallbacks WRITE setAutomaticFrameCallbacks) public: - QWaylandQuickOutput(QWaylandCompositor *compositor, QQuickWindow *window, + QWaylandQuickOutput(QWaylandOutputSpace *outputSpace, QQuickWindow *window, const QString &manufacturer, const QString &model); QQuickWindow *quickWindow() const; diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp index 9defe06f1..0f722f334 100644 --- a/src/compositor/compositor_api/qwaylandsurface.cpp +++ b/src/compositor/compositor_api/qwaylandsurface.cpp @@ -349,6 +349,12 @@ void QWaylandSurface::ping() } } +void QWaylandSurface::sendFrameCallbacks() +{ + Q_D(QWaylandSurface); + d->sendFrameCallback(); +} + void QWaylandSurface::sendOnScreenVisibilityChange(bool visible) { setVisibility(visible ? QWindow::AutomaticVisibility : QWindow::Hidden); diff --git a/src/compositor/compositor_api/qwaylandsurface.h b/src/compositor/compositor_api/qwaylandsurface.h index 5aa4232b2..30005e3f7 100644 --- a/src/compositor/compositor_api/qwaylandsurface.h +++ b/src/compositor/compositor_api/qwaylandsurface.h @@ -196,6 +196,8 @@ public: Q_INVOKABLE void destroySurface(); Q_INVOKABLE void ping(); + Q_INVOKABLE void sendFrameCallbacks(); + void ref(); void deref(); void setMapped(bool mapped); diff --git a/src/compositor/compositor_api/qwaylandsurfaceview.cpp b/src/compositor/compositor_api/qwaylandsurfaceview.cpp index 74698ac07..cfb9aa2ea 100644 --- a/src/compositor/compositor_api/qwaylandsurfaceview.cpp +++ b/src/compositor/compositor_api/qwaylandsurfaceview.cpp @@ -123,6 +123,11 @@ QWaylandCompositor *QWaylandSurfaceView::compositor() const void QWaylandSurfaceView::setRequestedPosition(const QPointF &pos) { d->requestedPos = pos; + if (d->shouldBroadcastRequestedPositionChanged()) { + Q_ASSERT(d->output->outputSpace()); + QWaylandOutputSpacePrivate *outputSpacePriv = QWaylandOutputSpacePrivate::get(d->output->outputSpace()); + outputSpacePriv->emitSurfacePositionChanged(d->surface, pos); + } } QPointF QWaylandSurfaceView::requestedPosition() const @@ -170,6 +175,16 @@ void QWaylandSurfaceView::setLockedBuffer(bool locked) d->lockedBuffer = locked; } +bool QWaylandSurfaceView::broadcastRequestedPositionChanged() const +{ + return d->broadcastRequestedPositionChanged; +} + +void QWaylandSurfaceView::setBroadcastRequestedPositionChanged(bool broadcast) +{ + d->broadcastRequestedPositionChanged = broadcast; +} + void QWaylandSurfaceView::waylandSurfaceChanged(QWaylandSurface *newSurface, QWaylandSurface *oldSurface) { if (d->output) diff --git a/src/compositor/compositor_api/qwaylandsurfaceview.h b/src/compositor/compositor_api/qwaylandsurfaceview.h index 17951d08d..07e8e661c 100644 --- a/src/compositor/compositor_api/qwaylandsurfaceview.h +++ b/src/compositor/compositor_api/qwaylandsurfaceview.h @@ -71,6 +71,9 @@ public: bool lockedBuffer() const; void setLockedBuffer(bool locked); + + bool broadcastRequestedPositionChanged() const; + void setBroadcastRequestedPositionChanged(bool broadcast); protected: virtual void waylandSurfaceChanged(QWaylandSurface *newSurface, QWaylandSurface *oldSurface); virtual void waylandSurfaceDestroyed(); diff --git a/src/compositor/compositor_api/qwaylandsurfaceview_p.h b/src/compositor/compositor_api/qwaylandsurfaceview_p.h index cdcd91f03..3537ad679 100644 --- a/src/compositor/compositor_api/qwaylandsurfaceview_p.h +++ b/src/compositor/compositor_api/qwaylandsurfaceview_p.h @@ -61,6 +61,11 @@ public: void markSurfaceAsDestroyed(QWaylandSurface *surface); + bool shouldBroadcastRequestedPositionChanged() const + { + return broadcastRequestedPositionChanged && output && surface && surface->primaryOutput() == output; + } + QWaylandSurfaceView *q_ptr; QWaylandSurface *surface; QWaylandOutput *output; @@ -69,6 +74,7 @@ public: QWaylandBufferRef currentBuffer; QWaylandBufferRef nextBuffer; bool lockedBuffer; + bool broadcastRequestedPositionChanged; }; QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlcompositor.cpp b/src/compositor/wayland_wrapper/qwlcompositor.cpp index 22573b1a2..e58c6e999 100644 --- a/src/compositor/wayland_wrapper/qwlcompositor.cpp +++ b/src/compositor/wayland_wrapper/qwlcompositor.cpp @@ -178,6 +178,7 @@ Compositor::Compositor(QWaylandCompositor *qt_compositor) , m_retainSelection(false) , m_initialized(false) { + m_outputSpaces.append(new QWaylandOutputSpace(qt_compositor)); m_timer.start(); compositor = this; @@ -237,7 +238,7 @@ Compositor::~Compositor() qWarning("QWaylandCompositor::cleanupGraphicsResources() must be called manually"); qDeleteAll(m_clients); - qDeleteAll(m_outputs); + qDeleteAll(m_outputSpaces); delete m_surfaceExtension; delete m_subSurfaceExtension; @@ -256,56 +257,50 @@ uint Compositor::currentTimeMsecs() const return m_timer.elapsed(); } -QList<QWaylandOutput *> Compositor::outputs() const -{ - return m_outputs; -} - QWaylandOutput *Compositor::output(QWindow *window) const { - Q_FOREACH (QWaylandOutput *output, m_outputs) { - if (output->window() == window) + foreach (QWaylandOutputSpace *outputSpace, m_outputSpaces) { + QWaylandOutput *output = outputSpace->output(window); + if (output) return output; } return Q_NULLPTR; } -void Compositor::addOutput(QWaylandOutput *output) +QWaylandOutput *Compositor::primaryOutput() const { - Q_ASSERT(output->handle()); - - if (m_outputs.contains(output)) - return; - - m_outputs.append(output); + return primaryOutputSpace()->primaryOutput(); } -void Compositor::removeOutput(QWaylandOutput *output) +QWaylandOutputSpace *Compositor::primaryOutputSpace() const { - Q_ASSERT(output->handle()); - - m_outputs.removeOne(output); + Q_ASSERT(!m_outputSpaces.isEmpty()); + return m_outputSpaces.first(); } -QWaylandOutput *Compositor::primaryOutput() const +void Compositor::setPrimaryOutputSpace(QWaylandOutputSpace *outputSpace) { - if (m_outputs.size() == 0) - return Q_NULLPTR; - return m_outputs.at(0); + Q_ASSERT(!m_outputSpaces.isEmpty()); + if (m_outputSpaces.first() == outputSpace) + return; + if (m_outputSpaces.removeOne(outputSpace)) { + m_outputSpaces.prepend(outputSpace); + waylandCompositor()->primaryOutputSpaceChanged(); + } } -void Compositor::setPrimaryOutput(QWaylandOutput *output) +void Compositor::addOutputSpace(QWaylandOutputSpace *outputSpace) { - Q_ASSERT(output->handle()); - - int i = m_outputs.indexOf(output); - if (i <= 0) - return; + Q_ASSERT(!m_outputSpaces.contains(outputSpace)); + m_outputSpaces.append(outputSpace); + waylandCompositor()->outputSpacesChanged(); +} - m_outputs.removeAt(i); - m_outputs.prepend(output); - emit m_qt_compositor->primaryOutputChanged(); +void Compositor::removeOutputSpace(QWaylandOutputSpace *outputSpace) +{ + if (m_outputSpaces.removeOne(outputSpace)) + waylandCompositor()->outputSpacesChanged(); } void Compositor::processWaylandEvents() diff --git a/src/compositor/wayland_wrapper/qwlcompositor_p.h b/src/compositor/wayland_wrapper/qwlcompositor_p.h index a9d7f99f9..304cb94f7 100644 --- a/src/compositor/wayland_wrapper/qwlcompositor_p.h +++ b/src/compositor/wayland_wrapper/qwlcompositor_p.h @@ -105,14 +105,13 @@ public: uint currentTimeMsecs() const; - QList<QWaylandOutput *> outputs() const; QWaylandOutput *output(QWindow *window) const; - void addOutput(QWaylandOutput *output); - void removeOutput(QWaylandOutput *output); - QWaylandOutput *primaryOutput() const; - void setPrimaryOutput(QWaylandOutput *output); + QWaylandOutputSpace *primaryOutputSpace() const; + void setPrimaryOutputSpace(QWaylandOutputSpace *outputSpace); + void addOutputSpace(QWaylandOutputSpace *outputSpace); + void removeOutputSpace(QWaylandOutputSpace *outputSpace); ClientBufferIntegration *clientBufferIntegration() const; ServerBufferIntegration *serverBufferIntegration() const; @@ -183,7 +182,7 @@ protected: QList<QWaylandInputDevice *> m_inputDevices; /* Output */ - QList<QWaylandOutput *> m_outputs; + QList<QWaylandOutputSpace *> m_outputSpaces; QList<QWaylandSurface *> m_all_surfaces; diff --git a/src/compositor/wayland_wrapper/qwldatadevice.cpp b/src/compositor/wayland_wrapper/qwldatadevice.cpp index 73a93a8c8..c3a059f74 100644 --- a/src/compositor/wayland_wrapper/qwldatadevice.cpp +++ b/src/compositor/wayland_wrapper/qwldatadevice.cpp @@ -131,10 +131,10 @@ void DataDevice::sourceDestroyed(DataSource *source) void DataDevice::focus() { - QWaylandSurfaceView *focus = m_compositor->waylandCompositor()->pickView(m_pointer->currentPosition()); + QWaylandSurfaceView *focus = outputSpace()->pickView(m_pointer->currentPosition()); if (focus != m_dragFocus) - setDragFocus(focus, m_compositor->waylandCompositor()->mapToView(focus, m_pointer->currentPosition())); + setDragFocus(focus, outputSpace()->mapToView(focus, m_pointer->currentPosition())); } void DataDevice::motion(uint32_t time) @@ -144,8 +144,7 @@ void DataDevice::motion(uint32_t time) } if (m_dragFocusResource && m_dragFocus) { - const QPointF &surfacePoint = m_compositor->waylandCompositor()->mapToView(m_dragFocus, m_pointer->currentPosition()); - qDebug() << Q_FUNC_INFO << m_pointer->currentPosition() << surfacePoint; + const QPointF &surfacePoint = outputSpace()->mapToView(m_dragFocus, m_pointer->currentPosition()); send_motion(m_dragFocusResource->handle, time, wl_fixed_from_double(surfacePoint.x()), wl_fixed_from_double(surfacePoint.y())); } diff --git a/src/compositor/wayland_wrapper/qwldatadevice_p.h b/src/compositor/wayland_wrapper/qwldatadevice_p.h index 051e1eb3e..59a9d2b27 100644 --- a/src/compositor/wayland_wrapper/qwldatadevice_p.h +++ b/src/compositor/wayland_wrapper/qwldatadevice_p.h @@ -38,7 +38,9 @@ #define WLDATADEVICE_H #include <QtCompositor/private/qwayland-server-wayland.h> +#include <qwlinputdevice_p.h> #include <qwlpointer_p.h> +#include <QtCompositor/QWaylandOutputSpace> QT_BEGIN_NAMESPACE @@ -72,6 +74,7 @@ protected: void data_device_set_selection(Resource *resource, struct ::wl_resource *source, uint32_t serial) Q_DECL_OVERRIDE; private: + QWaylandOutputSpace *outputSpace() const { return m_inputDevice->handle()->outputSpace(); } Compositor *m_compositor; InputDevice *m_inputDevice; diff --git a/src/compositor/wayland_wrapper/qwlinputdevice.cpp b/src/compositor/wayland_wrapper/qwlinputdevice.cpp index 5986b66ba..a4af463f7 100644 --- a/src/compositor/wayland_wrapper/qwlinputdevice.cpp +++ b/src/compositor/wayland_wrapper/qwlinputdevice.cpp @@ -60,6 +60,7 @@ InputDevice::InputDevice(QWaylandInputDevice *handle, Compositor *compositor, QW , m_handle(handle) , m_dragHandle(new QWaylandDrag(this)) , m_compositor(compositor) + , m_outputSpace(compositor->primaryOutputSpace()) , m_capabilities(caps) , m_pointer(m_capabilities & QWaylandInputDevice::Pointer ? new Pointer(m_compositor, this) : 0) , m_keyboard(m_capabilities & QWaylandInputDevice::Keyboard ? new Keyboard(m_compositor, this) : 0) @@ -366,6 +367,16 @@ const DataDevice *InputDevice::dataDevice() const return m_data_device.data(); } +QWaylandOutputSpace *InputDevice::outputSpace() const +{ + return m_outputSpace; +} + +void InputDevice::setOutputSpace(QWaylandOutputSpace *outputSpace) +{ + m_outputSpace = outputSpace; +} + } QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlinputdevice_p.h b/src/compositor/wayland_wrapper/qwlinputdevice_p.h index b6637eaa2..da59dd208 100644 --- a/src/compositor/wayland_wrapper/qwlinputdevice_p.h +++ b/src/compositor/wayland_wrapper/qwlinputdevice_p.h @@ -103,6 +103,9 @@ public: void clientRequestedDataDevice(DataDeviceManager *dndSelection, struct wl_client *client, uint32_t id); const DataDevice *dataDevice() const; + QWaylandOutputSpace *outputSpace() const; + void setOutputSpace(QWaylandOutputSpace *outputSpace); + Compositor *compositor() const; QWaylandInputDevice *handle() const; QWaylandDrag *dragHandle() const; @@ -128,6 +131,7 @@ private: QWaylandInputDevice *m_handle; QScopedPointer<QWaylandDrag> m_dragHandle; Compositor *m_compositor; + QWaylandOutputSpace *m_outputSpace; QWaylandInputDevice::CapabilityFlags m_capabilities; QScopedPointer<Pointer> m_pointer; diff --git a/src/compositor/wayland_wrapper/qwloutput.cpp b/src/compositor/wayland_wrapper/qwloutput.cpp index 32a42b74e..76acfb2b5 100644 --- a/src/compositor/wayland_wrapper/qwloutput.cpp +++ b/src/compositor/wayland_wrapper/qwloutput.cpp @@ -99,11 +99,11 @@ static QtWaylandServer::wl_output::transform toWlTransform(const QWaylandOutput: return QtWaylandServer::wl_output::transform_normal; } -Output::Output(Compositor *compositor, QWindow *window) - : QtWaylandServer::wl_output(compositor->wl_display(), 2) - , m_compositor(compositor) +Output::Output(QWaylandOutput *output, QWaylandOutputSpace *outputSpace, QWindow *window) + : QtWaylandServer::wl_output(outputSpace->compositor()->waylandDisplay(), 2) , m_window(window) - , m_output(Q_NULLPTR) + , m_output(output) + , m_outputSpace(Q_NULLPTR) , m_position(QPoint()) , m_availableGeometry(QRect()) , m_physicalSize(QSize()) @@ -114,6 +114,7 @@ Output::Output(Compositor *compositor, QWindow *window) { m_mode.size = window ? window->size() : QSize(); m_mode.refreshRate = 60; + setOutputSpace(outputSpace, false); qRegisterMetaType<QWaylandOutput::Mode>("WaylandOutput::Mode"); } @@ -289,6 +290,24 @@ void Output::setScaleFactor(int scale) } } +void Output::setOutputSpace(QWaylandOutputSpace *outputSpace, bool setOutputSpace) +{ + if (m_outputSpace == outputSpace) + return; + + if (m_outputSpace) { + m_outputSpace->removeOutput(waylandOutput()); + } + + m_outputSpace = outputSpace; + + if (outputSpace && setOutputSpace) { + outputSpace->addOutput(waylandOutput()); + } + + waylandOutput()->outputSpaceChanged(); +} + OutputResource *Output::outputForClient(wl_client *client) const { return static_cast<OutputResource *>(resourceMap().value(client)); @@ -327,20 +346,7 @@ void Output::sendFrameCallbacks() || surfacemapper.surface->primaryOutput()->handle() == this)) surfacemapper.surface->handle()->sendFrameCallback(); } - wl_display_flush_clients(m_compositor->wl_display()); -} - -QList<QWaylandSurface *> Output::surfacesForClient(QWaylandClient *client) const -{ - QList<QWaylandSurface *> result; - - for (int i = 0; i < m_surfaceViews.size(); i ++) { - if (m_surfaceViews.at(i).surface - && m_surfaceViews.at(i).surface->client() == client) - result.append(result); - } - - return result; + wl_display_flush_clients(compositor()->waylandDisplay()); } void Output::addView(QWaylandSurfaceView *view) diff --git a/src/compositor/wayland_wrapper/qwloutput_p.h b/src/compositor/wayland_wrapper/qwloutput_p.h index 30052c3b3..917240c1f 100644 --- a/src/compositor/wayland_wrapper/qwloutput_p.h +++ b/src/compositor/wayland_wrapper/qwloutput_p.h @@ -44,6 +44,8 @@ #include <QtCore/QList> #include <QtCore/QVector> +#include <QtCompositor/QWaylandOutputSpace> + #include <QtCompositor/private/qwayland-server-wayland.h> #include <QtCompositor/qwaylandoutput.h> @@ -74,11 +76,11 @@ struct OutputResource : public QtWaylandServer::wl_output::Resource class Output : public QtWaylandServer::wl_output { public: - explicit Output(Compositor *compositor, QWindow *window = 0); + Output(QWaylandOutput *output, QWaylandOutputSpace *outputSpace, QWindow *window); - Compositor *compositor() const { return m_compositor; } + QWaylandCompositor *compositor() const { return m_outputSpace->compositor(); } - QWaylandOutput *output() const { return m_output; } + QWaylandOutput *waylandOutput() const { return m_output; } QString manufacturer() const { return m_manufacturer; } void setManufacturer(const QString &manufacturer); @@ -115,11 +117,12 @@ public: int scaleFactor() const { return m_scaleFactor; } void setScaleFactor(int scale); + void setOutputSpace(QWaylandOutputSpace *outputSpace, bool setOutputSpace); + QWaylandOutputSpace *outputSpace() const { return m_outputSpace; } + void frameStarted(); void sendFrameCallbacks(); - QList<QWaylandSurface *> surfacesForClient(QWaylandClient *client) const; - void addView(QWaylandSurfaceView *view); void addView(QWaylandSurfaceView *view, QWaylandSurface *surface); void removeView(QWaylandSurfaceView *view); @@ -130,8 +133,6 @@ public: OutputResource *outputForClient(struct wl_client *client) const; - QWaylandOutput *waylandOutput() const { return m_output; } - void output_bind_resource(Resource *resource) Q_DECL_OVERRIDE; Resource *output_allocate() Q_DECL_OVERRIDE { return new OutputResource; } @@ -139,9 +140,9 @@ public: private: friend class QT_PREPEND_NAMESPACE(QWaylandOutput); - Compositor *m_compositor; QWindow *m_window; QWaylandOutput *m_output; + QWaylandOutputSpace *m_outputSpace; QString m_manufacturer; QString m_model; QPoint m_position; diff --git a/src/compositor/wayland_wrapper/qwlshellsurface.cpp b/src/compositor/wayland_wrapper/qwlshellsurface.cpp index bc75ab4c3..2fe666442 100644 --- a/src/compositor/wayland_wrapper/qwlshellsurface.cpp +++ b/src/compositor/wayland_wrapper/qwlshellsurface.cpp @@ -295,7 +295,7 @@ void ShellSurface::shell_surface_set_fullscreen(Resource *resource, : Q_NULLPTR; if (!output) { // Look for an output that can contain this surface - Q_FOREACH (QWaylandOutput *curOutput, m_surface->compositor()->outputs()) { + Q_FOREACH (QWaylandOutput *curOutput, m_surface->compositor()->primaryOutputSpace()->outputs()) { if (curOutput->geometry().size().width() >= m_surface->size().width() && curOutput->geometry().size().height() >= m_surface->size().height()) { output = curOutput; @@ -343,7 +343,7 @@ void ShellSurface::shell_surface_set_maximized(Resource *resource, : Q_NULLPTR; if (!output) { // Look for an output that can contain this surface - Q_FOREACH (QWaylandOutput *curOutput, m_surface->compositor()->outputs()) { + Q_FOREACH (QWaylandOutput *curOutput, m_surface->compositor()->primaryOutputSpace()->outputs()) { if (curOutput->geometry().size().width() >= m_surface->size().width() && curOutput->geometry().size().height() >= m_surface->size().height()) { output = curOutput; diff --git a/src/imports/compositor/qwaylandquickcompositorplugin.cpp b/src/imports/compositor/qwaylandquickcompositorplugin.cpp index c73f9a1e0..1ed4c1392 100644 --- a/src/imports/compositor/qwaylandquickcompositorplugin.cpp +++ b/src/imports/compositor/qwaylandquickcompositorplugin.cpp @@ -44,6 +44,7 @@ #include <QtCompositor/QWaylandQuickSurface> #include <QtCompositor/QWaylandClient> #include <QtCompositor/QWaylandOutput> +#include <QtCompositor/QWaylandOutputSpace> #include <QtCompositor/private/qwlcompositor_p.h> @@ -153,6 +154,7 @@ public: qmlRegisterUncreatableType<QWaylandQuickSurface>(uri, 1, 0, "WaylandQuickSurface", QObject::tr("Cannot create instance of WaylandQuickSurface")); qmlRegisterUncreatableType<QWaylandClient>(uri, 1, 0, "WaylandClient", QObject::tr("Cannot create instance of WaylandClient")); qmlRegisterUncreatableType<QWaylandOutput>(uri, 1, 0, "WaylandOutput", QObject::tr("Cannot create instance of WaylandOutput")); + qmlRegisterUncreatableType<QWaylandOutputSpace>(uri, 1, 0, "WaylandOutputSpace", QObject::tr("Cannot create instance of WaylandOutputSpace")); } }; //![class decl] |