diff options
author | Jørgen Lind <jorgen.lind@theqtcompany.com> | 2015-07-30 12:05:12 +0200 |
---|---|---|
committer | Jørgen Lind <jorgen.lind@theqtcompany.com> | 2015-08-28 13:09:41 +0200 |
commit | ab6980d57609b1e4bdb164d3413faa2f7cb7e1e4 (patch) | |
tree | ef68f66511347c0545559df6a81b6d56c6448eb4 | |
parent | e88c2f37097901e228de70c62a0220386038a51a (diff) | |
download | qtwayland-ab6980d57609b1e4bdb164d3413faa2f7cb7e1e4.tar.gz |
Move the output from QWaylandSurface to the QWaylandSurfaceView
and add a property called primaryOutput on the QWaylandSurface.
Also add some bookkeeping in QtWayland::Output so it knows what surfaces
and views it currently holds, sending the enter and leave events
automatically.
Change-Id: Ib6efbc6f8157657fb4451b751bba1cb5345b7906
25 files changed, 397 insertions, 210 deletions
diff --git a/examples/wayland/pure-qml/qml/Chrome.qml b/examples/wayland/pure-qml/qml/Chrome.qml index 0f82a44e..0ecb99b5 100644 --- a/examples/wayland/pure-qml/qml/Chrome.qml +++ b/examples/wayland/pure-qml/qml/Chrome.qml @@ -57,7 +57,11 @@ Item { onSurfaceDestroyed: { destroyAnimation.start(); + if (view) { + view.lockedBuffer = true; + } } + } SequentialAnimation { diff --git a/src/compositor/compositor_api/compositor_api.pri b/src/compositor/compositor_api/compositor_api.pri index ac356b8f..b134b5ef 100644 --- a/src/compositor/compositor_api/compositor_api.pri +++ b/src/compositor/compositor_api/compositor_api.pri @@ -11,6 +11,7 @@ HEADERS += \ compositor_api/qwaylanddrag.h \ compositor_api/qwaylandbufferref.h \ compositor_api/qwaylandsurfaceview.h \ + compositor_api/qwaylandsurfaceview_p.h \ compositor_api/qwaylandglobalinterface.h \ compositor_api/qwaylandsurfaceinterface.h diff --git a/src/compositor/compositor_api/qwaylandbufferref.cpp b/src/compositor/compositor_api/qwaylandbufferref.cpp index 7b5b3cd2..2d073e5e 100644 --- a/src/compositor/compositor_api/qwaylandbufferref.cpp +++ b/src/compositor/compositor_api/qwaylandbufferref.cpp @@ -110,7 +110,12 @@ bool QWaylandBufferRef::isNull() const bool QWaylandBufferRef::hasBuffer() const { - return d->buffer && !d->buffer->isDestroyed(); + return d->buffer; +} + +bool QWaylandBufferRef::isDestroyed() const +{ + return d->buffer && d->buffer->isDestroyed(); } struct ::wl_resource *QWaylandBufferRef::wl_buffer() const @@ -128,10 +133,10 @@ QSize QWaylandBufferRef::size() const QWaylandSurface::Origin QWaylandBufferRef::origin() const { - if (d->nullOrDestroyed()) - return QWaylandSurface::OriginBottomLeft; + if (d->buffer) + return d->buffer->origin(); - return d->buffer->origin(); + return QWaylandSurface::OriginBottomLeft; } bool QWaylandBufferRef::isShm() const diff --git a/src/compositor/compositor_api/qwaylandbufferref.h b/src/compositor/compositor_api/qwaylandbufferref.h index fa978fe8..37166ebe 100644 --- a/src/compositor/compositor_api/qwaylandbufferref.h +++ b/src/compositor/compositor_api/qwaylandbufferref.h @@ -66,6 +66,7 @@ public: QWaylandBufferRef &operator=(const QWaylandBufferRef &ref); bool isNull() const; bool hasBuffer() const; + bool isDestroyed() const; bool operator==(const QWaylandBufferRef &ref); bool operator!=(const QWaylandBufferRef &ref); diff --git a/src/compositor/compositor_api/qwaylandcompositor.cpp b/src/compositor/compositor_api/qwaylandcompositor.cpp index a94abffc..bcb37376 100644 --- a/src/compositor/compositor_api/qwaylandcompositor.cpp +++ b/src/compositor/compositor_api/qwaylandcompositor.cpp @@ -159,18 +159,12 @@ QList<QWaylandSurface *> QWaylandCompositor::surfacesForClient(QWaylandClient* c return surfs; } +#endif //QT_DEPRECATED_SINCE(5, 5) + QList<QWaylandSurface *> QWaylandCompositor::surfaces() const { - QList<QWaylandSurface *> surfs; - foreach (QWaylandOutput *output, outputs()) { - foreach (QWaylandSurface *surface, output->surfaces()) { - if (!surfs.contains(surface)) - surfs.append(surface); - } - } - return surfs; + return m_compositor->m_all_surfaces; } -#endif //QT_DEPRECATED_SINCE(5, 5) QList<QWaylandOutput *> QWaylandCompositor::outputs() const { @@ -207,18 +201,14 @@ 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; - Q_FOREACH (QWaylandSurface *surface, output->surfaces()) { - Q_FOREACH (QWaylandSurfaceView *view, surface->views()) { - if (QRectF(view->requestedPosition(), surface->size()).contains(globalPosition)) - return view; - } - } + output->pickView(globalPosition); } return Q_NULLPTR; @@ -228,6 +218,7 @@ QPointF QWaylandCompositor::mapToView(QWaylandSurfaceView *surface, const QPoint { return globalPosition - surface->requestedPosition(); } +#endif //QT_DEPRECATED_SINCE(5, 5) /*! Override this to handle QDesktopServices::openUrl() requests from the clients. diff --git a/src/compositor/compositor_api/qwaylandcompositor.h b/src/compositor/compositor_api/qwaylandcompositor.h index a203fa26..dd1ce0ab 100644 --- a/src/compositor/compositor_api/qwaylandcompositor.h +++ b/src/compositor/compositor_api/qwaylandcompositor.h @@ -113,17 +113,20 @@ public: QT_DEPRECATED void sendFrameCallbacks(QList<QWaylandSurface *> visibleSurfaces); QT_DEPRECATED QList<QWaylandSurface *> surfacesForClient(QWaylandClient* client) const; - QT_DEPRECATED QList<QWaylandSurface *> surfaces() const; #endif //QT_DEPRECATED_SINCE(5, 5) + QT_DEPRECATED QList<QWaylandSurface *> surfaces() const; + Q_INVOKABLE QList<QWaylandOutput *> outputs() const; Q_INVOKABLE QWaylandOutput *output(QWindow *window); 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) virtual bool openUrl(QWaylandClient *client, const QUrl &url); diff --git a/src/compositor/compositor_api/qwaylandoutput.cpp b/src/compositor/compositor_api/qwaylandoutput.cpp index 470b5b54..dffda876 100644 --- a/src/compositor/compositor_api/qwaylandoutput.cpp +++ b/src/compositor/compositor_api/qwaylandoutput.cpp @@ -35,6 +35,11 @@ ** ****************************************************************************/ +#include "qwaylandoutput.h" + +#include "qwaylandcompositor.h" +#include "qwaylandsurfaceview.h" + #include <QtCore/QCoreApplication> #include <QtCore/QtMath> #include <QtGui/QWindow> @@ -43,9 +48,6 @@ #include "wayland_wrapper/qwlcompositor_p.h" #include "wayland_wrapper/qwloutput_p.h" -#include "qwaylandcompositor.h" -#include "qwaylandoutput.h" -#include "qwaylandsurface.h" QT_BEGIN_NAMESPACE @@ -256,14 +258,9 @@ void QWaylandOutput::frameStarted() d_ptr->frameStarted(); } -void QWaylandOutput::sendFrameCallbacks(QList<QWaylandSurface *> visibleSurfaces) -{ - d_ptr->sendFrameCallbacks(visibleSurfaces); -} - -QList<QWaylandSurface *> QWaylandOutput::surfaces() const +void QWaylandOutput::sendFrameCallbacks() { - return d_ptr->surfaces(); + d_ptr->sendFrameCallbacks(); } QList<QWaylandSurface *> QWaylandOutput::surfacesForClient(QWaylandClient *client) const @@ -271,19 +268,28 @@ QList<QWaylandSurface *> QWaylandOutput::surfacesForClient(QWaylandClient *clien return d_ptr->surfacesForClient(client); } -void QWaylandOutput::addSurface(QWaylandSurface *surface) +QtWayland::Output *QWaylandOutput::handle() const { - d_ptr->addSurface(surface); + return d_ptr.data(); } -void QWaylandOutput::removeSurface(QWaylandSurface *surface) +QWaylandSurfaceView *QWaylandOutput::pickView(const QPointF &outputPosition) const { - d_ptr->removeSurface(surface); + const QVector<QtWayland::SurfaceViewMapper> surfaceViewMappers = d_ptr->surfaceMappers(); + for (int nSurface = 0; surfaceViewMappers.size(); nSurface++) { + const QWaylandSurface *surface = surfaceViewMappers.at(nSurface).surface; + const QVector<QWaylandSurfaceView *> views = surfaceViewMappers.at(nSurface).views; + for (int nView = 0; views.size(); nView++) { + if (QRectF(views.at(nView)->requestedPosition(), surface->size()).contains(outputPosition)) + return views.at(nView); + } + } + return Q_NULLPTR; } -QtWayland::Output *QWaylandOutput::handle() const +QPointF QWaylandOutput::mapToView(QWaylandSurfaceView *view, const QPointF &outputPosition) const { - return d_ptr.data(); + return outputPosition - view->requestedPosition(); } void QWaylandOutput::setWidth(int newWidth) diff --git a/src/compositor/compositor_api/qwaylandoutput.h b/src/compositor/compositor_api/qwaylandoutput.h index 2b5c6ad6..bc92fe5a 100644 --- a/src/compositor/compositor_api/qwaylandoutput.h +++ b/src/compositor/compositor_api/qwaylandoutput.h @@ -51,6 +51,7 @@ struct wl_resource; class QWaylandCompositor; class QWindow; class QWaylandSurface; +class QWaylandSurfaceView; class QWaylandClient; namespace QtWayland { @@ -151,15 +152,15 @@ public: void setPhysicalSizeFollowsSize(bool follow); void frameStarted(); - void sendFrameCallbacks(QList<QWaylandSurface *> visibleSurfaces); + void sendFrameCallbacks(); - QList<QWaylandSurface *> surfaces() const; QList<QWaylandSurface *> surfacesForClient(QWaylandClient *client) const; - void addSurface(QWaylandSurface *surface); - void removeSurface(QWaylandSurface *surface); QtWayland::Output *handle() const; + Q_INVOKABLE virtual QWaylandSurfaceView *pickView(const QPointF &outputPosition) const; + Q_INVOKABLE virtual QPointF mapToView(QWaylandSurfaceView *view, const QPointF &surfacePosition) const; + Q_SIGNALS: void positionChanged(); void geometryChanged(); diff --git a/src/compositor/compositor_api/qwaylandquickoutput.cpp b/src/compositor/compositor_api/qwaylandquickoutput.cpp index 0c743c4f..d8341d60 100644 --- a/src/compositor/compositor_api/qwaylandquickoutput.cpp +++ b/src/compositor/compositor_api/qwaylandquickoutput.cpp @@ -87,6 +87,6 @@ void QWaylandQuickOutput::updateStarted() void QWaylandQuickOutput::doFrameCallbacks() { if (m_automaticFrameCallbacks) - sendFrameCallbacks(surfaces()); + sendFrameCallbacks(); } QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandquicksurface.cpp b/src/compositor/compositor_api/qwaylandquicksurface.cpp index ebefb3bc..96e9ca48 100644 --- a/src/compositor/compositor_api/qwaylandquicksurface.cpp +++ b/src/compositor/compositor_api/qwaylandquicksurface.cpp @@ -70,8 +70,10 @@ public: { QWaylandSurfacePrivate::surface_commit(resource); - Q_FOREACH (QtWayland::Output *output, outputs()) - output->waylandOutput()->update(); + Q_FOREACH (QWaylandSurfaceView *view, views) { + if (view->output()) + view->output()->update(); + } } QWaylandQuickCompositor *compositor; @@ -85,7 +87,7 @@ QWaylandQuickSurface::QWaylandQuickSurface(wl_client *client, quint32 id, int ve { Q_D(QWaylandQuickSurface); connect(this, &QWaylandSurface::shellViewCreated, this, &QWaylandQuickSurface::shellViewCreated); - connect(this, &QWaylandSurface::outputChanged, this, &QWaylandQuickSurface::outputWindowChanged); + connect(this, &QWaylandSurface::primaryOutputChanged, this, &QWaylandQuickSurface::primaryOutputWindowChanged); connect(this, &QWaylandSurface::windowPropertyChanged, d->windowPropertyMap, &QQmlPropertyMap::insert); connect(d->windowPropertyMap, &QQmlPropertyMap::valueChanged, this, &QWaylandSurface::setWindowProperty); @@ -126,9 +128,9 @@ QWaylandSurfaceItem *QWaylandQuickSurface::shellView() const return static_cast<QWaylandSurfaceItem *>(QWaylandSurface::shellView()); } -QWindow *QWaylandQuickSurface::outputWindow() const +QWindow *QWaylandQuickSurface::primaryOutputWindow() const { - return output() ? output()->window() : Q_NULLPTR; + return primaryOutput() ? primaryOutput()->window() : Q_NULLPTR; } bool QWaylandQuickSurface::event(QEvent *e) diff --git a/src/compositor/compositor_api/qwaylandquicksurface.h b/src/compositor/compositor_api/qwaylandquicksurface.h index 3f262a40..7e079471 100644 --- a/src/compositor/compositor_api/qwaylandquicksurface.h +++ b/src/compositor/compositor_api/qwaylandquicksurface.h @@ -55,7 +55,7 @@ class Q_COMPOSITOR_EXPORT QWaylandQuickSurface : public QWaylandSurface Q_PROPERTY(bool clientRenderingEnabled READ clientRenderingEnabled WRITE setClientRenderingEnabled NOTIFY clientRenderingEnabledChanged) Q_PROPERTY(QObject *windowProperties READ windowPropertyMap CONSTANT) Q_PROPERTY(QWaylandSurfaceItem *shellView READ shellView NOTIFY shellViewCreated) - Q_PROPERTY(QWindow *outputWindow READ outputWindow NOTIFY outputWindowChanged) + Q_PROPERTY(QWindow *primaryOutputWindow READ primaryOutputWindow NOTIFY primaryOutputWindowChanged) public: QWaylandQuickSurface(wl_client *client, quint32 id, int version, QWaylandQuickCompositor *compositor); ~QWaylandQuickSurface(); @@ -72,13 +72,13 @@ public: private: bool event(QEvent *event) Q_DECL_OVERRIDE; - QWindow *outputWindow() const; + QWindow *primaryOutputWindow() const; Q_SIGNALS: void useTextureAlphaChanged(); void clientRenderingEnabledChanged(); void shellViewCreated(); - void outputWindowChanged(); + void primaryOutputWindowChanged(); }; QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp index 5ffe58e0..9defe06f 100644 --- a/src/compositor/compositor_api/qwaylandsurface.cpp +++ b/src/compositor/compositor_api/qwaylandsurface.cpp @@ -53,6 +53,7 @@ #include "qwaylandsurface_p.h" #include "qwaylandbufferref.h" #include "qwaylandsurfaceinterface.h" +#include "qwaylandoutput.h" #include <QtGui/QGuiApplication> #include <QtGui/QScreen> @@ -143,6 +144,8 @@ QWaylandSurface::~QWaylandSurface() { Q_D(QWaylandSurface); qDeleteAll(d->interfaces); + d->m_compositor->unregisterSurface(this); + d->notifyViewsAboutDestruction(); } QWaylandClient *QWaylandSurface::client() const @@ -286,34 +289,18 @@ QWaylandCompositor *QWaylandSurface::compositor() const return d->compositor()->waylandCompositor(); } -QWaylandOutput *QWaylandSurface::mainOutput() const +QWaylandOutput *QWaylandSurface::primaryOutput() const { Q_D(const QWaylandSurface); - - // Returns the output that contains the most if not all - // the surface (window managers will take care of setting - // this, defaults to the first output) - return d->mainOutput()->waylandOutput(); + if (!d->primaryOutput()) + return Q_NULLPTR; + return d->primaryOutput()->waylandOutput(); } -void QWaylandSurface::setMainOutput(QWaylandOutput *mainOutput) +void QWaylandSurface::setPrimaryOutput(QWaylandOutput *output) { Q_D(QWaylandSurface); - - if (mainOutput) - d->setMainOutput(mainOutput->handle()); -} - -QList<QWaylandOutput *> QWaylandSurface::outputs() const -{ - Q_D(const QWaylandSurface); - - QList<QWaylandOutput *> list; - const QList<QtWayland::Output *> outputs = d->outputs(); - list.reserve(outputs.count()); - Q_FOREACH (QtWayland::Output *output, outputs) - list.append(output->waylandOutput()); - return list; + d->setPrimaryOutput(output->handle()); } QWindow::Visibility QWaylandSurface::visibility() const @@ -413,6 +400,22 @@ void QWaylandSurface::destroySurface() emit surfaceDestroyed(); } +void QWaylandSurface::enter(QWaylandOutput *output) +{ + Q_D(QWaylandSurface); + QtWayland::OutputResource *outputResource = output->handle()->outputForClient(d->resource()->client()); + if (outputResource) + handle()->send_enter(outputResource->handle); +} + +void QWaylandSurface::leave(QWaylandOutput *output) +{ + Q_D(QWaylandSurface); + QtWayland::OutputResource *outputResource = output->handle()->outputForClient(d->resource()->client()); + if (outputResource) + d->send_leave(outputResource->handle); +} + /*! Updates the surface with the compositor's retained clipboard selection. While this is done automatically when the surface receives keyboard focus, this function is diff --git a/src/compositor/compositor_api/qwaylandsurface.h b/src/compositor/compositor_api/qwaylandsurface.h index 9dce15a6..5aa4232b 100644 --- a/src/compositor/compositor_api/qwaylandsurface.h +++ b/src/compositor/compositor_api/qwaylandsurface.h @@ -113,7 +113,7 @@ class Q_COMPOSITOR_EXPORT QWaylandSurface : public QObject Q_PROPERTY(QWindow::Visibility visibility READ visibility WRITE setVisibility NOTIFY visibilityChanged) Q_PROPERTY(QWaylandSurface *transientParent READ transientParent) Q_PROPERTY(QPointF transientOffset READ transientOffset) - Q_PROPERTY(QWaylandOutput *output READ output NOTIFY outputChanged) + Q_PROPERTY(QWaylandOutput *primaryOutput READ primaryOutput WRITE setPrimaryOutput NOTIFY primaryOutputChanged) Q_PROPERTY(QWaylandSurface::Origin origin READ origin NOTIFY originChanged); Q_ENUMS(WindowFlag WindowType) @@ -179,10 +179,8 @@ public: QWaylandCompositor *compositor() const; - QWaylandOutput *mainOutput() const; - void setMainOutput(QWaylandOutput *mainOutput); - - QList<QWaylandOutput *> outputs() const; + QWaylandOutput *primaryOutput() const; + void setPrimaryOutput(QWaylandOutput *output); QString className() const; @@ -211,6 +209,9 @@ public: static QWaylandSurface *fromResource(::wl_resource *resource); + void enter(QWaylandOutput *output); + void leave(QWaylandOutput *output); + public Q_SLOTS: void updateSelection(); @@ -238,7 +239,7 @@ Q_SIGNALS: void pong(); void surfaceDestroyed(); void shellViewCreated(); - void outputChanged(QWaylandOutput *newOutput, QWaylandOutput *oldOutput); + void primaryOutputChanged(QWaylandOutput *newOutput, QWaylandOutput *oldOutput); void originChanged(); void configure(bool hasBuffer); diff --git a/src/compositor/compositor_api/qwaylandsurfaceitem.cpp b/src/compositor/compositor_api/qwaylandsurfaceitem.cpp index 4c3615c9..c690521b 100644 --- a/src/compositor/compositor_api/qwaylandsurfaceitem.cpp +++ b/src/compositor/compositor_api/qwaylandsurfaceitem.cpp @@ -333,10 +333,10 @@ void QWaylandSurfaceItem::mouseUngrabEvent() void QWaylandSurfaceItem::waylandSurfaceChanged(QWaylandSurface *newSurface, QWaylandSurface *oldSurface) { + QWaylandSurfaceView::waylandSurfaceChanged(newSurface, oldSurface); if (oldSurface) { disconnect(oldSurface, &QWaylandSurface::mapped, this, &QWaylandSurfaceItem::surfaceMapped); disconnect(oldSurface, &QWaylandSurface::unmapped, this, &QWaylandSurfaceItem::surfaceUnmapped); - disconnect(oldSurface, &QWaylandSurface::surfaceDestroyed, this, &QWaylandSurfaceItem::handleSurfaceDestroyed); disconnect(oldSurface, &QWaylandSurface::parentChanged, this, &QWaylandSurfaceItem::parentChanged); disconnect(oldSurface, &QWaylandSurface::sizeChanged, this, &QWaylandSurfaceItem::updateSize); disconnect(oldSurface, &QWaylandSurface::configure, this, &QWaylandSurfaceItem::updateBuffer); @@ -345,7 +345,6 @@ void QWaylandSurfaceItem::waylandSurfaceChanged(QWaylandSurface *newSurface, QWa if (newSurface) { connect(newSurface, &QWaylandSurface::mapped, this, &QWaylandSurfaceItem::surfaceMapped); connect(newSurface, &QWaylandSurface::unmapped, this, &QWaylandSurfaceItem::surfaceUnmapped); - connect(newSurface, &QWaylandSurface::surfaceDestroyed, this, &QWaylandSurfaceItem::handleSurfaceDestroyed); connect(newSurface, &QWaylandSurface::parentChanged, this, &QWaylandSurfaceItem::parentChanged); connect(newSurface, &QWaylandSurface::sizeChanged, this, &QWaylandSurfaceItem::updateSize); connect(newSurface, &QWaylandSurface::configure, this, &QWaylandSurfaceItem::updateBuffer); @@ -361,6 +360,11 @@ void QWaylandSurfaceItem::waylandSurfaceChanged(QWaylandSurface *newSurface, QWa emit surfaceChanged(); } +void QWaylandSurfaceItem::waylandSurfaceDestroyed() +{ + emit surfaceDestroyed(); +} + void QWaylandSurfaceItem::takeFocus(QWaylandInputDevice *device) { setFocus(true); @@ -475,6 +479,19 @@ void QWaylandSurfaceItem::syncGraphicsState() } +bool QWaylandSurfaceItem::lockedBuffer() const +{ + return QWaylandSurfaceView::lockedBuffer(); +} + +void QWaylandSurfaceItem::setLockedBuffer(bool locked) +{ + if (locked != lockedBuffer()) { + QWaylandSurfaceView::setLockedBuffer(locked); + lockedBufferChanged(); + } +} + /*! \qmlproperty bool QtWayland::QWaylandSurfaceItem::paintEnabled @@ -514,6 +531,12 @@ void QWaylandSurfaceItem::updateWindow() if (m_connectedWindow) { connect(m_connectedWindow, &QQuickWindow::beforeSynchronizing, this, &QWaylandSurfaceItem::beforeSync, Qt::DirectConnection); } + + if (compositor() && m_connectedWindow) { + QWaylandOutput *output = compositor()->output(m_connectedWindow); + Q_ASSERT(output); + setOutput(output); + } } void QWaylandSurfaceItem::beforeSync() @@ -526,7 +549,8 @@ void QWaylandSurfaceItem::beforeSync() QSGNode *QWaylandSurfaceItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) { - bool mapped = surface() && surface()->isMapped() && currentBuffer().hasBuffer(); + bool mapped = (surface() && surface()->isMapped() && currentBuffer().hasBuffer()) + || (lockedBuffer() && m_provider); if (!mapped || !m_paintEnabled) { delete oldNode; @@ -542,6 +566,7 @@ QSGNode *QWaylandSurfaceItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeD m_provider = new QWaylandSurfaceTextureProvider(); if (m_newTexture) { + m_newTexture = false; m_provider->setBufferRef(this, currentBuffer()); node->setTexture(m_provider->texture()); } @@ -582,10 +607,4 @@ void QWaylandSurfaceItem::setInputEventsEnabled(bool enabled) } } -void QWaylandSurfaceItem::handleSurfaceDestroyed() -{ - emit surfaceDestroyed(); - setSurface(Q_NULLPTR); -} - QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandsurfaceitem.h b/src/compositor/compositor_api/qwaylandsurfaceitem.h index 4c5db4ad..c8eea897 100644 --- a/src/compositor/compositor_api/qwaylandsurfaceitem.h +++ b/src/compositor/compositor_api/qwaylandsurfaceitem.h @@ -67,6 +67,7 @@ class Q_COMPOSITOR_EXPORT QWaylandSurfaceItem : public QQuickItem, public QWayla Q_PROPERTY(qreal requestedXPosition READ requestedXPosition WRITE setRequestedXPosition NOTIFY requestedXPositionChanged) Q_PROPERTY(qreal requestedYPosition READ requestedYPosition WRITE setRequestedYPosition NOTIFY requestedYPositionChanged) Q_PROPERTY(bool inputEventsEnabled READ inputEventsEnabled WRITE setInputEventsEnabled NOTIFY inputEventsEnabledChanged) + Q_PROPERTY(bool lockedBuffer READ lockedBuffer WRITE setLockedBuffer NOTIFY lockedBufferChanged) public: QWaylandSurfaceItem(QQuickItem *parent = 0); @@ -102,7 +103,9 @@ public: Q_INVOKABLE void syncGraphicsState(); - void markForNewBuffer(); + bool lockedBuffer() const; + void setLockedBuffer(bool locked); + protected: void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); @@ -118,6 +121,7 @@ protected: void mouseUngrabEvent() Q_DECL_OVERRIDE; void waylandSurfaceChanged(QWaylandSurface *newSurface, QWaylandSurface *oldSurface) Q_DECL_OVERRIDE; + void waylandSurfaceDestroyed() Q_DECL_OVERRIDE; void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE; @@ -144,6 +148,7 @@ Q_SIGNALS: void requestedXPositionChanged(); void requestedYPositionChanged(); void inputEventsEnabledChanged(); + void lockedBufferChanged(); protected: QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *); @@ -152,7 +157,6 @@ private: friend class QWaylandSurfaceNode; friend class QWaylandQuickSurface; bool shouldSendInputEvents() const { return surface() && m_inputEventsEnabled; } - void handleSurfaceDestroyed(); static QMutex *mutex; diff --git a/src/compositor/compositor_api/qwaylandsurfaceview.cpp b/src/compositor/compositor_api/qwaylandsurfaceview.cpp index b8f7c0d1..74698ac0 100644 --- a/src/compositor/compositor_api/qwaylandsurfaceview.cpp +++ b/src/compositor/compositor_api/qwaylandsurfaceview.cpp @@ -35,42 +35,41 @@ ****************************************************************************/ #include "qwaylandsurfaceview.h" +#include "qwaylandsurfaceview_p.h" #include "qwaylandsurface.h" #include "qwaylandsurface_p.h" -#include "qwaylandcompositor.h" -#include "qwaylandinput.h" #include <QtCore/QMutex> QT_BEGIN_NAMESPACE -class QWaylandSurfaceViewPrivate +QWaylandSurfaceViewPrivate *QWaylandSurfaceViewPrivate::get(QWaylandSurfaceView *view) { -public: - QWaylandSurfaceViewPrivate() - : surface(Q_NULLPTR) - { } - QWaylandSurface *surface; - QPointF requestedPos; - QMutex bufferMutex; - QWaylandBufferRef currentBuffer; - QWaylandBufferRef nextBuffer; -}; + return view->d; +} + +void QWaylandSurfaceViewPrivate::markSurfaceAsDestroyed(QWaylandSurface *surface) +{ + Q_ASSERT(surface == this->surface); + + q_ptr->waylandSurfaceDestroyed(); + q_ptr->setSurface(Q_NULLPTR); +} QWaylandSurfaceView::QWaylandSurfaceView() - : d(new QWaylandSurfaceViewPrivate) + : d(new QWaylandSurfaceViewPrivate(this)) { } QWaylandSurfaceView::~QWaylandSurfaceView() { + if (d->output) + d->output->handle()->removeView(this); if (d->surface) { QWaylandInputDevice *i = d->surface->compositor()->defaultInputDevice(); if (i->mouseFocus() == this) i->setMouseFocus(Q_NULLPTR, QPointF()); - d->surface->destroy(); - d->surface->d_func()->views.removeOne(this); d->surface->deref(); } @@ -94,10 +93,28 @@ void QWaylandSurfaceView::setSurface(QWaylandSurface *newSurface) QWaylandSurfacePrivate::get(newSurface)->refView(this); waylandSurfaceChanged(newSurface, oldSurface); - d->currentBuffer = QWaylandBufferRef(); + if (!d->lockedBuffer) + d->currentBuffer = QWaylandBufferRef(); + d->nextBuffer = QWaylandBufferRef(); } +QWaylandOutput *QWaylandSurfaceView::output() const +{ + return d->output; +} + +void QWaylandSurfaceView::setOutput(QWaylandOutput *newOutput) +{ + if (d->output == newOutput) + return; + + QWaylandOutput *oldOutput = d->output; + d->output = newOutput; + + waylandOutputChanged(newOutput, oldOutput); +} + QWaylandCompositor *QWaylandSurfaceView::compositor() const { return d->surface ? d->surface->compositor() : 0; @@ -126,10 +143,13 @@ void QWaylandSurfaceView::attach(const QWaylandBufferRef &ref) bool QWaylandSurfaceView::advance() { - QMutexLocker locker(&d->bufferMutex); if (d->currentBuffer == d->nextBuffer) return false; + if (d->lockedBuffer) + return false; + + QMutexLocker locker(&d->bufferMutex); d->currentBuffer = d->nextBuffer; return true; } @@ -140,10 +160,33 @@ QWaylandBufferRef QWaylandSurfaceView::currentBuffer() return d->currentBuffer; } +bool QWaylandSurfaceView::lockedBuffer() const +{ + return d->lockedBuffer; +} + +void QWaylandSurfaceView::setLockedBuffer(bool locked) +{ + d->lockedBuffer = locked; +} + void QWaylandSurfaceView::waylandSurfaceChanged(QWaylandSurface *newSurface, QWaylandSurface *oldSurface) { - Q_UNUSED(newSurface); - Q_UNUSED(oldSurface); + if (d->output) + d->output->handle()->updateSurfaceForView(this, newSurface, oldSurface); +} + +void QWaylandSurfaceView::waylandSurfaceDestroyed() +{ +} + +void QWaylandSurfaceView::waylandOutputChanged(QWaylandOutput *newOutput, QWaylandOutput *oldOutput) +{ + if (oldOutput) + oldOutput->handle()->removeView(this); + + if (newOutput) + newOutput->handle()->addView(this); } QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandsurfaceview.h b/src/compositor/compositor_api/qwaylandsurfaceview.h index c6bd288a..17951d08 100644 --- a/src/compositor/compositor_api/qwaylandsurfaceview.h +++ b/src/compositor/compositor_api/qwaylandsurfaceview.h @@ -58,6 +58,9 @@ public: QWaylandSurface *surface() const; void setSurface(QWaylandSurface *surface); + QWaylandOutput *output() const; + void setOutput(QWaylandOutput *output); + virtual void setRequestedPosition(const QPointF &pos); virtual QPointF requestedPosition() const; virtual QPointF pos() const; @@ -65,8 +68,13 @@ public: virtual void attach(const QWaylandBufferRef &ref); virtual bool advance(); virtual QWaylandBufferRef currentBuffer(); + + bool lockedBuffer() const; + void setLockedBuffer(bool locked); protected: virtual void waylandSurfaceChanged(QWaylandSurface *newSurface, QWaylandSurface *oldSurface); + virtual void waylandSurfaceDestroyed(); + virtual void waylandOutputChanged(QWaylandOutput *newOutput, QWaylandOutput *oldOutput); private: class QWaylandSurfaceViewPrivate *const d; diff --git a/src/compositor/compositor_api/qwaylandsurfaceview_p.h b/src/compositor/compositor_api/qwaylandsurfaceview_p.h new file mode 100644 index 00000000..cdcd91f0 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandsurfaceview_p.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** 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 QWAYLANDSURFACEVIEW_P_H +#define QWAYLANDSURFACEVIEW_P_H + +#include <QtCore/QPoint> +#include <QtCore/QMutex> + +#include <QtCompositor/QWaylandBufferRef> + +QT_BEGIN_NAMESPACE + +class QWaylandSurface; +class QWaylandOutput; + +class QWaylandSurfaceViewPrivate +{ +public: + static QWaylandSurfaceViewPrivate *get(QWaylandSurfaceView *view); + + QWaylandSurfaceViewPrivate(QWaylandSurfaceView *view) + : q_ptr(view) + , surface(Q_NULLPTR) + , output(Q_NULLPTR) + , lockedBuffer(false) + { } + + void markSurfaceAsDestroyed(QWaylandSurface *surface); + + QWaylandSurfaceView *q_ptr; + QWaylandSurface *surface; + QWaylandOutput *output; + QPointF requestedPos; + QMutex bufferMutex; + QWaylandBufferRef currentBuffer; + QWaylandBufferRef nextBuffer; + bool lockedBuffer; +}; + +QT_END_NAMESPACE + +#endif /*QWAYLANDSURFACEVIEW_P_H*/ diff --git a/src/compositor/wayland_wrapper/qwlcompositor.cpp b/src/compositor/wayland_wrapper/qwlcompositor.cpp index 98f5aa1d..22573b1a 100644 --- a/src/compositor/wayland_wrapper/qwlcompositor.cpp +++ b/src/compositor/wayland_wrapper/qwlcompositor.cpp @@ -318,8 +318,6 @@ void Compositor::processWaylandEvents() void Compositor::destroySurface(Surface *surface) { - surface->removeFromOutput(); - waylandCompositor()->surfaceAboutToBeDestroyed(surface->waylandSurface()); m_destroyed_surfaces << surface->waylandSurface(); @@ -335,6 +333,12 @@ void Compositor::resetInputDevice(Surface *surface) } } +void Compositor::unregisterSurface(QWaylandSurface *surface) +{ + if (!m_all_surfaces.removeOne(surface)) + qWarning("%s Unexpected state. Cant find registered surface\n", Q_FUNC_INFO); +} + void Compositor::cleanupGraphicsResources() { qDeleteAll(m_destroyed_surfaces); @@ -345,7 +349,9 @@ void Compositor::compositor_create_surface(Resource *resource, uint32_t id) { QWaylandClient *client = QWaylandClient::fromWlClient(resource->client()); QWaylandSurface *surface = m_qt_compositor->createSurface(client, id, resource->version()); - primaryOutput()->addSurface(surface); + m_all_surfaces.append(surface); + if (primaryOutput()) + surface->setPrimaryOutput(primaryOutput()); emit m_qt_compositor->surfaceCreated(surface); } diff --git a/src/compositor/wayland_wrapper/qwlcompositor_p.h b/src/compositor/wayland_wrapper/qwlcompositor_p.h index 1eee9dc4..a9d7f99f 100644 --- a/src/compositor/wayland_wrapper/qwlcompositor_p.h +++ b/src/compositor/wayland_wrapper/qwlcompositor_p.h @@ -157,6 +157,8 @@ public: static void bindGlobal(wl_client *client, void *data, uint32_t version, uint32_t id); void resetInputDevice(Surface *surface); + void unregisterSurface(QWaylandSurface *surface); + public slots: void cleanupGraphicsResources(); @@ -183,6 +185,8 @@ protected: /* Output */ QList<QWaylandOutput *> m_outputs; + QList<QWaylandSurface *> m_all_surfaces; + DataDeviceManager *m_data_device_manager; QElapsedTimer m_timer; diff --git a/src/compositor/wayland_wrapper/qwloutput.cpp b/src/compositor/wayland_wrapper/qwloutput.cpp index 1ff52ad5..32a42b74 100644 --- a/src/compositor/wayland_wrapper/qwloutput.cpp +++ b/src/compositor/wayland_wrapper/qwloutput.cpp @@ -47,6 +47,7 @@ #include <QtCompositor/QWaylandSurface> #include <QtCompositor/QWaylandClient> +#include <QtCompositor/QWaylandSurfaceView> QT_BEGIN_NAMESPACE @@ -309,14 +310,22 @@ void Output::sendGeometryInfo() void Output::frameStarted() { - foreach (QWaylandSurface *surface, m_surfaces) - surface->handle()->frameStarted(); + for (int i = 0; i < m_surfaceViews.size(); i++) { + SurfaceViewMapper &surfacemapper = m_surfaceViews[i]; + if (surfacemapper.surface && (!surfacemapper.surface->primaryOutput() + || surfacemapper.surface->primaryOutput()->handle() == this)) + surfacemapper.surface->handle()->frameStarted(); + } } -void Output::sendFrameCallbacks(QList<QWaylandSurface *> visibleSurfaces) +void Output::sendFrameCallbacks() { - foreach (QWaylandSurface *surface, visibleSurfaces) { - surface->handle()->sendFrameCallback(); + for (int i = 0; i < m_surfaceViews.size(); i++) { + const SurfaceViewMapper &surfacemapper = m_surfaceViews.at(i); + if (surfacemapper.surface && surfacemapper.surface->isMapped() + && (!surfacemapper.surface->primaryOutput() + || surfacemapper.surface->primaryOutput()->handle() == this)) + surfacemapper.surface->handle()->sendFrameCallback(); } wl_display_flush_clients(m_compositor->wl_display()); } @@ -325,32 +334,64 @@ QList<QWaylandSurface *> Output::surfacesForClient(QWaylandClient *client) const { QList<QWaylandSurface *> result; - foreach (QWaylandSurface *surface, m_surfaces) { - if (surface->client() == client) + 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; } -void Output::addSurface(QWaylandSurface *surface) +void Output::addView(QWaylandSurfaceView *view) { - if (m_surfaces.contains(surface)) - return; + addView(view, view->surface()); +} - m_surfaces.append(surface); +void Output::addView(QWaylandSurfaceView *view, QWaylandSurface *surface) +{ + for (int i = 0; i < m_surfaceViews.size(); i++) { + if (surface == m_surfaceViews.at(i).surface) { + if (!m_surfaceViews.at(i).views.contains(view)) { + m_surfaceViews[i].views.append(view); + } + return; + } + } - surface->handle()->addToOutput(this); + SurfaceViewMapper surfaceViewMapper; + surfaceViewMapper.surface = surface; + surfaceViewMapper.views.append(view); + m_surfaceViews.append(surfaceViewMapper); + if (surface) + surface->enter(waylandOutput()); } -void Output::removeSurface(QWaylandSurface *surface) +void Output::removeView(QWaylandSurfaceView *view) { - if (!m_surfaces.contains(surface)) - return; + removeView(view, view->surface()); +} - m_surfaces.removeOne(surface); +void Output::removeView(QWaylandSurfaceView *view, QWaylandSurface *surface) +{ + for (int i = 0; i < m_surfaceViews.size(); i++) { + if (surface == m_surfaceViews.at(i).surface) { + bool removed = m_surfaceViews[i].views.removeOne(view); + if (m_surfaceViews.at(i).views.isEmpty() && removed) { + m_surfaceViews.remove(i); + if (surface) + surface->leave(waylandOutput()); + } + return; + } + } + qWarning("%s Could not find view %p for surface %p to remove. Possible invalid state", Q_FUNC_INFO, view, surface); +} - surface->handle()->removeFromOutput(this); +void Output::updateSurfaceForView(QWaylandSurfaceView *view, QWaylandSurface *newSurface, QWaylandSurface *oldSurface) +{ + removeView(view, oldSurface); + addView(view, newSurface); } } // namespace Wayland diff --git a/src/compositor/wayland_wrapper/qwloutput_p.h b/src/compositor/wayland_wrapper/qwloutput_p.h index 18c3801a..30052c3b 100644 --- a/src/compositor/wayland_wrapper/qwloutput_p.h +++ b/src/compositor/wayland_wrapper/qwloutput_p.h @@ -42,6 +42,7 @@ #include <QtCore/QRect> #include <QtCore/QList> +#include <QtCore/QVector> #include <QtCompositor/private/qwayland-server-wayland.h> #include <QtCompositor/qwaylandoutput.h> @@ -54,6 +55,17 @@ namespace QtWayland { class Compositor; +struct SurfaceViewMapper +{ + SurfaceViewMapper() + : surface(0) + , views() + {} + + QWaylandSurface *surface; + QVector<QWaylandSurfaceView *> views; +}; + struct OutputResource : public QtWaylandServer::wl_output::Resource { OutputResource() {} @@ -104,12 +116,15 @@ public: void setScaleFactor(int scale); void frameStarted(); - void sendFrameCallbacks(QList<QWaylandSurface *> visibleSurfaces); + void sendFrameCallbacks(); - QList<QWaylandSurface *> surfaces() const { return m_surfaces; } QList<QWaylandSurface *> surfacesForClient(QWaylandClient *client) const; - void addSurface(QWaylandSurface *surface); - void removeSurface(QWaylandSurface *surface); + + void addView(QWaylandSurfaceView *view); + void addView(QWaylandSurfaceView *view, QWaylandSurface *surface); + void removeView(QWaylandSurfaceView *view); + void removeView(QWaylandSurfaceView *view, QWaylandSurface *surface); + void updateSurfaceForView(QWaylandSurfaceView *view, QWaylandSurface *newSurface, QWaylandSurface *oldSurface); QWindow *window() const { return m_window; } @@ -120,6 +135,7 @@ public: void output_bind_resource(Resource *resource) Q_DECL_OVERRIDE; Resource *output_allocate() Q_DECL_OVERRIDE { return new OutputResource; } + const QVector<SurfaceViewMapper> surfaceMappers() const { return m_surfaceViews; } private: friend class QT_PREPEND_NAMESPACE(QWaylandOutput); @@ -131,6 +147,7 @@ private: QPoint m_position; QWaylandOutput::Mode m_mode; QRect m_availableGeometry; + QVector<SurfaceViewMapper> m_surfaceViews; QSize m_physicalSize; QWaylandOutput::Subpixel m_subpixel; QWaylandOutput::Transform m_transform; diff --git a/src/compositor/wayland_wrapper/qwlsurface.cpp b/src/compositor/wayland_wrapper/qwlsurface.cpp index 9ac0293a..375a0f05 100644 --- a/src/compositor/wayland_wrapper/qwlsurface.cpp +++ b/src/compositor/wayland_wrapper/qwlsurface.cpp @@ -37,6 +37,9 @@ #include "qwlsurface_p.h" #include "qwaylandsurface.h" +#include "qwaylandsurface_p.h" +#include "qwaylandsurfaceview_p.h" +#include "qwaylandoutput.h" #include "qwlcompositor_p.h" #include "qwlinputdevice_p.h" #include "qwlextendedsurface_p.h" @@ -113,7 +116,7 @@ Surface::Surface(struct wl_client *client, uint32_t id, int version, QWaylandCom : QtWaylandServer::wl_surface(client, id, version) , m_compositor(compositor->handle()) , m_waylandSurface(surface) - , m_mainOutput(0) + , m_primaryOutput(0) , m_buffer(0) , m_surfaceMapped(false) , m_shellSurface(0) @@ -279,79 +282,21 @@ Compositor *Surface::compositor() const return m_compositor; } -Output *Surface::mainOutput() const -{ - if (!m_mainOutput) - return m_compositor->primaryOutput()->handle(); - return m_mainOutput; -} - -void Surface::setMainOutput(Output *output) -{ - m_mainOutput = output; -} - -QList<Output *> Surface::outputs() const -{ - return m_outputs; -} - -void Surface::addToOutput(Output *output) -{ - if (!output) - return; - - if (!m_mainOutput) - m_mainOutput = output; - - if (m_outputs.contains(output)) - return; - - m_outputs.append(output); - - output->addSurface(waylandSurface()); - - QWaylandSurfaceEnterEvent event(output->waylandOutput()); - QCoreApplication::sendEvent(waylandSurface(), &event); - - // Send surface enter event - Q_FOREACH (Resource *resource, resourceMap().values()) { - QList<Output::Resource *> outputs = output->resourceMap().values(); - for (int i = 0; i < outputs.size(); i++) - send_enter(resource->handle, outputs.at(i)->handle); - } -} - -void Surface::removeFromOutput(Output *output) +void Surface::setPrimaryOutput(Output *output) { - if (!output) - return; - - if (!m_outputs.contains(output)) + if (m_primaryOutput == output) return; - m_outputs.removeOne(output); - - if (m_mainOutput == output) - setMainOutput(Q_NULLPTR); + QWaylandOutput *new_output = output ? output->waylandOutput() : Q_NULLPTR; + QWaylandOutput *old_output = m_primaryOutput ? m_primaryOutput->waylandOutput() : Q_NULLPTR; + m_primaryOutput = output; - output->removeSurface(waylandSurface()); - QWaylandSurfaceLeaveEvent event(output->waylandOutput()); - QCoreApplication::sendEvent(waylandSurface(), &event); - - // Send surface leave event - Q_FOREACH (Resource *resource, resourceMap().values()) { - QList<Output::Resource *> outputs = output->resourceMap().values(); - for (int i = 0; i < outputs.size(); i++) - send_leave(resource->handle, outputs.at(i)->handle); - } + waylandSurface()->primaryOutputChanged(new_output, old_output); } -void Surface::removeFromOutput() +Output *Surface::primaryOutput() const { - Q_FOREACH (Output *output, m_outputs) { - removeFromOutput(output); - } + return m_primaryOutput; } /*! @@ -440,6 +385,12 @@ Qt::ScreenOrientation Surface::contentOrientation() const return m_contentOrientation; } +void Surface::notifyViewsAboutDestruction() +{ + foreach (QWaylandSurfaceView *view, m_waylandSurface->views()) { + QWaylandSurfaceViewPrivate::get(view)->markSurfaceAsDestroyed(m_waylandSurface); + } +} void Surface::surface_destroy_resource(Resource *) { @@ -448,6 +399,8 @@ void Surface::surface_destroy_resource(Resource *) m_extendedSurface = 0; } + notifyViewsAboutDestruction(); + m_destroyed = true; m_waylandSurface->destroy(); emit m_waylandSurface->surfaceDestroyed(); @@ -512,6 +465,9 @@ void Surface::surface_commit(Resource *) m_inputRegion = m_pending.inputRegion.intersected(QRect(QPoint(), m_size)); emit m_waylandSurface->redraw(); + + if (primaryOutput()) + primaryOutput()->waylandOutput()->update(); } void Surface::surface_set_buffer_transform(Resource *resource, int32_t orientation) diff --git a/src/compositor/wayland_wrapper/qwlsurface_p.h b/src/compositor/wayland_wrapper/qwlsurface_p.h index 2ba1b142..b7299d2b 100644 --- a/src/compositor/wayland_wrapper/qwlsurface_p.h +++ b/src/compositor/wayland_wrapper/qwlsurface_p.h @@ -120,14 +120,8 @@ public: Compositor *compositor() const; - Output *mainOutput() const; - void setMainOutput(Output *output); - - QList<Output *> outputs() const; - - void addToOutput(Output *output); - void removeFromOutput(Output *output); - void removeFromOutput(); + Output *primaryOutput() const; + void setPrimaryOutput(Output *output); QString className() const { return m_className; } void setClassName(const QString &className); @@ -161,6 +155,8 @@ public: QWaylandSurface::Origin origin() const { return m_buffer ? m_buffer->origin() : QWaylandSurface::OriginTopLeft; } QWaylandBufferRef currentBufferRef() const { return m_bufferRef; } + + void notifyViewsAboutDestruction(); protected: void surface_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; @@ -182,8 +178,7 @@ protected: Compositor *m_compositor; QWaylandSurface *m_waylandSurface; - Output *m_mainOutput; - QList<Output *> m_outputs; + Output *m_primaryOutput; QRegion m_damage; SurfaceBuffer *m_buffer; diff --git a/src/imports/compositor/WaylandSurfaceChrome.qml b/src/imports/compositor/WaylandSurfaceChrome.qml index 69525d87..7f9ae802 100644 --- a/src/imports/compositor/WaylandSurfaceChrome.qml +++ b/src/imports/compositor/WaylandSurfaceChrome.qml @@ -60,7 +60,6 @@ Item { } onSurfaceDestroyed: { - chrome.surfaceDestroyed(); if (automaticDestroyOnSurfaceDestroy) chrome.destroy(); } @@ -78,6 +77,7 @@ Item { chrome.visible = Qt.binding(function() { return view.visible; }); chrome.requestedXPosition = Qt.binding(function() { return view.requestedXPosition; }); chrome.requestedYPosition = Qt.binding(function() { return view.requestedYPosition; }); + view.surfaceDestroyed.connect(function() { chrome.surfaceDestroyed(); }); } else { chrome.visible = false; } |