From fcd376a4ffb4a2efc8352ce1777e9f869e4e5206 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Thu, 30 Jul 2015 12:06:24 +0200 Subject: Introducing QWaylandOutputSpace Its purpose is to make it possible to have multiscreen environments, and also multiple multioutput environments It is also an abstraction to make it clear that outputs are arranged in a 2d space Change-Id: I418509996a03b2ca1a12aec9c9e25e143a15a10f --- examples/wayland/pure-qml/qml/main.qml | 2 +- examples/wayland/qml-compositor/main.cpp | 10 +- .../qwindow-compositor/qwindowcompositor.cpp | 8 +- examples/wayland/server-buffer/compositor/main.cpp | 6 +- src/compositor/compositor_api/compositor_api.pri | 7 +- .../compositor_api/qwaylandcompositor.cpp | 78 +++------ src/compositor/compositor_api/qwaylandcompositor.h | 33 ++-- src/compositor/compositor_api/qwaylandinput.cpp | 10 ++ src/compositor/compositor_api/qwaylandinput.h | 4 + src/compositor/compositor_api/qwaylandoutput.cpp | 28 +-- src/compositor/compositor_api/qwaylandoutput.h | 10 +- .../compositor_api/qwaylandoutputspace.cpp | 191 +++++++++++++++++++++ .../compositor_api/qwaylandoutputspace.h | 106 ++++++++++++ .../compositor_api/qwaylandoutputspace_p.h | 121 +++++++++++++ .../compositor_api/qwaylandquickcompositor.cpp | 5 +- .../compositor_api/qwaylandquickcompositor.h | 3 +- .../compositor_api/qwaylandquickoutput.cpp | 4 +- .../compositor_api/qwaylandquickoutput.h | 2 +- src/compositor/compositor_api/qwaylandsurface.cpp | 6 + src/compositor/compositor_api/qwaylandsurface.h | 2 + .../compositor_api/qwaylandsurfaceview.cpp | 15 ++ .../compositor_api/qwaylandsurfaceview.h | 3 + .../compositor_api/qwaylandsurfaceview_p.h | 6 + src/compositor/wayland_wrapper/qwlcompositor.cpp | 59 +++---- src/compositor/wayland_wrapper/qwlcompositor_p.h | 11 +- src/compositor/wayland_wrapper/qwldatadevice.cpp | 7 +- src/compositor/wayland_wrapper/qwldatadevice_p.h | 3 + src/compositor/wayland_wrapper/qwlinputdevice.cpp | 11 ++ src/compositor/wayland_wrapper/qwlinputdevice_p.h | 4 + src/compositor/wayland_wrapper/qwloutput.cpp | 42 +++-- src/compositor/wayland_wrapper/qwloutput_p.h | 17 +- src/compositor/wayland_wrapper/qwlshellsurface.cpp | 4 +- .../compositor/qwaylandquickcompositorplugin.cpp | 2 + 33 files changed, 650 insertions(+), 170 deletions(-) create mode 100644 src/compositor/compositor_api/qwaylandoutputspace.cpp create mode 100644 src/compositor/compositor_api/qwaylandoutputspace.h create mode 100644 src/compositor/compositor_api/qwaylandoutputspace_p.h 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 #include +#include #include #include @@ -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() << 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 #include #include +#include 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 #include @@ -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 QWaylandCompositor::surfacesForClient(QWaylandClient* client) const { - foreach (QWaylandOutput *output, outputs()) - output->frameStarted(); + QList surfs; + foreach (QWaylandSurface *surface, m_compositor->m_all_surfaces) { + if (surface->client() == client) + surfs.append(surface); + } + return surfs; } -void QWaylandCompositor::sendFrameCallbacks(QList visibleSurfaces) +QList QWaylandCompositor::surfaces() const { - Q_FOREACH (QWaylandSurface *surface, visibleSurfaces) { - surface->handle()->sendFrameCallback(); - } + return m_compositor->m_all_surfaces; } -QList QWaylandCompositor::surfacesForClient(QWaylandClient* client) const +QWaylandOutput *QWaylandCompositor::output(QWindow *window) const { - QList 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 QWaylandCompositor::surfaces() const +QWaylandOutputSpace *QWaylandCompositor::primaryOutputSpace() const { - return m_compositor->m_all_surfaces; + return m_compositor->primaryOutputSpace(); } -QList 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 visibleSurfaces); - - QT_DEPRECATED QList surfacesForClient(QWaylandClient* client) const; -#endif //QT_DEPRECATED_SINCE(5, 5) - - QT_DEPRECATED QList surfaces() const; + QList surfaces() const; + QList surfacesForClient(QWaylandClient* client) const; - Q_INVOKABLE QList 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 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 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 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 +#include + +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(); +} + +QListQWaylandOutputSpace::outputs() const +{ + Q_D(const QWaylandOutputSpace); + return d->outputs; +} + +QListQWaylandOutputSpace::outputs(const QPoint &point) const +{ + Q_D(const QWaylandOutputSpace); + QList 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 + +#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 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 QListoutputs() const; + Q_INVOKABLE QListoutputs(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 + +#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 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 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 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 m_inputDevices; /* Output */ - QList m_outputs; + QList m_outputSpaces; QList 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 +#include #include +#include 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 m_dragHandle; Compositor *m_compositor; + QWaylandOutputSpace *m_outputSpace; QWaylandInputDevice::CapabilityFlags m_capabilities; QScopedPointer 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("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(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 Output::surfacesForClient(QWaylandClient *client) const -{ - QList 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 #include +#include + #include #include @@ -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 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 #include #include +#include #include @@ -153,6 +154,7 @@ public: qmlRegisterUncreatableType(uri, 1, 0, "WaylandQuickSurface", QObject::tr("Cannot create instance of WaylandQuickSurface")); qmlRegisterUncreatableType(uri, 1, 0, "WaylandClient", QObject::tr("Cannot create instance of WaylandClient")); qmlRegisterUncreatableType(uri, 1, 0, "WaylandOutput", QObject::tr("Cannot create instance of WaylandOutput")); + qmlRegisterUncreatableType(uri, 1, 0, "WaylandOutputSpace", QObject::tr("Cannot create instance of WaylandOutputSpace")); } }; //![class decl] -- cgit v1.2.3