summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJørgen Lind <jorgen.lind@theqtcompany.com>2015-07-30 12:05:12 +0200
committerJørgen Lind <jorgen.lind@theqtcompany.com>2015-08-28 13:09:41 +0200
commitab6980d57609b1e4bdb164d3413faa2f7cb7e1e4 (patch)
treeef68f66511347c0545559df6a81b6d56c6448eb4 /src
parente88c2f37097901e228de70c62a0220386038a51a (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/compositor/compositor_api/compositor_api.pri1
-rw-r--r--src/compositor/compositor_api/qwaylandbufferref.cpp13
-rw-r--r--src/compositor/compositor_api/qwaylandbufferref.h1
-rw-r--r--src/compositor/compositor_api/qwaylandcompositor.cpp21
-rw-r--r--src/compositor/compositor_api/qwaylandcompositor.h5
-rw-r--r--src/compositor/compositor_api/qwaylandoutput.cpp38
-rw-r--r--src/compositor/compositor_api/qwaylandoutput.h9
-rw-r--r--src/compositor/compositor_api/qwaylandquickoutput.cpp2
-rw-r--r--src/compositor/compositor_api/qwaylandquicksurface.cpp12
-rw-r--r--src/compositor/compositor_api/qwaylandquicksurface.h6
-rw-r--r--src/compositor/compositor_api/qwaylandsurface.cpp47
-rw-r--r--src/compositor/compositor_api/qwaylandsurface.h13
-rw-r--r--src/compositor/compositor_api/qwaylandsurfaceitem.cpp37
-rw-r--r--src/compositor/compositor_api/qwaylandsurfaceitem.h8
-rw-r--r--src/compositor/compositor_api/qwaylandsurfaceview.cpp83
-rw-r--r--src/compositor/compositor_api/qwaylandsurfaceview.h8
-rw-r--r--src/compositor/compositor_api/qwaylandsurfaceview_p.h76
-rw-r--r--src/compositor/wayland_wrapper/qwlcompositor.cpp12
-rw-r--r--src/compositor/wayland_wrapper/qwlcompositor_p.h4
-rw-r--r--src/compositor/wayland_wrapper/qwloutput.cpp75
-rw-r--r--src/compositor/wayland_wrapper/qwloutput_p.h25
-rw-r--r--src/compositor/wayland_wrapper/qwlsurface.cpp90
-rw-r--r--src/compositor/wayland_wrapper/qwlsurface_p.h15
-rw-r--r--src/imports/compositor/WaylandSurfaceChrome.qml2
24 files changed, 393 insertions, 210 deletions
diff --git a/src/compositor/compositor_api/compositor_api.pri b/src/compositor/compositor_api/compositor_api.pri
index ac356b8fa..b134b5ef4 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 7b5b3cd2b..2d073e5ee 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 fa978fe80..37166ebe6 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 a94abffcf..bcb373761 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 a203fa265..dd1ce0abd 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 470b5b54b..dffda876e 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 2b5c6ad69..bc92fe5a4 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 0c743c4f3..d8341d60a 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 ebefb3bc3..96e9ca484 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 3f262a402..7e079471d 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 5ffe58e0a..9defe06f1 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 9dce15a6b..5aa4232b2 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 4c3615c9f..c690521ba 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 4c5db4ad5..c8eea8973 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 b8f7c0d1a..74698ac07 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 c6bd288aa..17951d08d 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 000000000..cdcd91f03
--- /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 98f5aa1d4..22573b1a2 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 1eee9dc45..a9d7f99f9 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 1ff52ad5f..32a42b74e 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 18c3801a5..30052c3b3 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 9ac0293ab..375a0f054 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 2ba1b1428..b7299d2b4 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 69525d87e..7f9ae8025 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;
}