diff options
13 files changed, 150 insertions, 35 deletions
diff --git a/examples/wayland/pure-qml/qml/main.qml b/examples/wayland/pure-qml/qml/main.qml index 0fe92668a..12f6063b4 100644 --- a/examples/wayland/pure-qml/qml/main.qml +++ b/examples/wayland/pure-qml/qml/main.qml @@ -56,6 +56,13 @@ WaylandCompositor { Chrome { } } + Component { + id: surfaceComponent + WaylandSurface { + property QtObject shellSurface: null + } + } + extensions: [ DefaultShell { id: defaultShell @@ -69,6 +76,7 @@ WaylandCompositor { var item = chromeComponent.createObject(defaultOutput.surfaceArea, { "surface": surface } ); var shellSurface = shellSurfaceComponent.createObject(); shellSurface.initialize(defaultShell, surface, item.view, client, id); + surface.shellSurface = shellSurface; } Component.onCompleted: { @@ -77,6 +85,11 @@ WaylandCompositor { } ] + onCreateSurface: { + var surface = surfaceComponent.createObject(0, { } ); + surface.initialize(compositor, client, id, version); + } + Component.onCompleted: { screenComponent.createObject(0, { "outputSpace" : defaultOutputSpace } ); } diff --git a/examples/wayland/qwindow-compositor/qwindowcompositor.cpp b/examples/wayland/qwindow-compositor/qwindowcompositor.cpp index e89ec3aec..fe2738f05 100644 --- a/examples/wayland/qwindow-compositor/qwindowcompositor.cpp +++ b/examples/wayland/qwindow-compositor/qwindowcompositor.cpp @@ -67,8 +67,8 @@ QT_BEGIN_NAMESPACE class Surface : public QWaylandSurface { public: - Surface(QWaylandClient *client, quint32 id, int version, QWaylandCompositor *compositor) - : QWaylandSurface(client, id, version, compositor) + Surface() + : QWaylandSurface() , shellSurface(Q_NULLPTR) , extSurface(Q_NULLPTR) , hasSentOnScreen(false) @@ -319,9 +319,9 @@ void QWindowCompositor::adjustCursorSurface(QWaylandSurface *surface, int hotspo m_cursorHotspotY = hotspotY; } -QWaylandSurface *QWindowCompositor::createSurface(QWaylandClient *client, quint32 id, int version) +QWaylandSurface *QWindowCompositor::createDefaultSurfaceType() { - return new Surface(client, id, version, this); + return new Surface(); } QWaylandView *QWindowCompositor::viewAt(const QPointF &point, QPointF *local) diff --git a/examples/wayland/qwindow-compositor/qwindowcompositor.h b/examples/wayland/qwindow-compositor/qwindowcompositor.h index e4c4cbe66..15ff30476 100644 --- a/examples/wayland/qwindow-compositor/qwindowcompositor.h +++ b/examples/wayland/qwindow-compositor/qwindowcompositor.h @@ -80,7 +80,7 @@ private slots: void onCreateShellSurface(QWaylandSurface *s, QWaylandClient *client, uint id); protected: - QWaylandSurface *createSurface(QWaylandClient *client, quint32 id, int version) Q_DECL_OVERRIDE; + QWaylandSurface *createDefaultSurfaceType() Q_DECL_OVERRIDE; void surfaceCommitted(QWaylandSurface *surface); QWaylandView* viewAt(const QPointF &point, QPointF *local = 0); diff --git a/src/compositor/compositor_api/qwaylandcompositor.cpp b/src/compositor/compositor_api/qwaylandcompositor.cpp index b9be85335..c3c3a3179 100644 --- a/src/compositor/compositor_api/qwaylandcompositor.cpp +++ b/src/compositor/compositor_api/qwaylandcompositor.cpp @@ -241,11 +241,34 @@ void QWaylandCompositorPrivate::addPolishObject(QObject *object) } } +/*! + \fn void QWaylandCompositor::createSurface(QWaylandClient *client, uint id, int version) + + This signal is emitted when a client has created a wl_surface object on the + server side. The slot connecting to this signal has to create and initialize + a QWaylandSurface instance in the scope of the slot. Connections to this + signal has to be of Qt::DirectConnection connection type. + +*/ + void QWaylandCompositorPrivate::compositor_create_surface(Resource *resource, uint32_t id) { Q_Q(QWaylandCompositor); QWaylandClient *client = QWaylandClient::fromWlClient(q, resource->client()); - QWaylandSurface *surface = q->createSurface(client, id, resource->version()); + emit q->createSurface(client, id, resource->version()); +#ifndef QT_NO_DEBUG + Q_ASSERT_X(!QWaylandSurfacePrivate::hasUninitializedSurface(), "QWaylandCompositor", QStringLiteral("Found uninitialized QWaylandSurface after emitting QWaylandCompositor::createSurface for id %1. All surfaces has to be initialized immediately after creation. See QWaylandSurface::initialize.").arg(id).toLocal8Bit().constData()); +#endif + struct wl_resource *surfResource = wl_client_get_object(client->client(), id); + + QWaylandSurface *surface; + if (surfResource) { + surface = QWaylandSurface::fromResource(surfResource); + } else { + surface = q->createDefaultSurfaceType(); + surface->initialize(q, client, id, resource->version()); + } + Q_ASSERT(surface); all_surfaces.append(surface); emit q->surfaceCreated(surface); } @@ -472,11 +495,6 @@ uint QWaylandCompositor::currentTimeMsecs() const return d->timer.elapsed(); } -QWaylandSurface *QWaylandCompositor::createSurface(QWaylandClient *client, quint32 id, int version) -{ - return new QWaylandSurface(client, id, version, this); -} - void QWaylandCompositor::cleanupGraphicsResources() { Q_D(QWaylandCompositor); @@ -494,6 +512,16 @@ void QWaylandCompositor::processWaylandEvents() } +/*! + \internal + Used to create a fallback QWaylandSurface when no surface was + created by emitting the QWaylandCompositor::createSurface signal. +*/ +QWaylandSurface *QWaylandCompositor::createDefaultSurfaceType() +{ + return new QWaylandSurface(); +} + QWaylandInputDevice *QWaylandCompositor::createInputDevice() { return new QWaylandInputDevice(this); diff --git a/src/compositor/compositor_api/qwaylandcompositor.h b/src/compositor/compositor_api/qwaylandcompositor.h index d9098ee37..d859ab341 100644 --- a/src/compositor/compositor_api/qwaylandcompositor.h +++ b/src/compositor/compositor_api/qwaylandcompositor.h @@ -132,6 +132,7 @@ public Q_SLOTS: void processWaylandEvents(); Q_SIGNALS: + void createSurface(QWaylandClient *client, uint id, int version); void surfaceCreated(QWaylandSurface *surface); void surfaceAboutToBeDestroyed(QWaylandSurface *surface); @@ -142,13 +143,15 @@ Q_SIGNALS: void useHardwareIntegrationExtensionChanged(); protected: virtual void retainedSelectionReceived(QMimeData *mimeData); - virtual QWaylandSurface *createSurface(QWaylandClient *client, quint32 id, int version); virtual QWaylandInputDevice *createInputDevice(); virtual QWaylandPointer *createPointerDevice(QWaylandInputDevice *inputDevice); virtual QWaylandKeyboard *createKeyboardDevice(QWaylandInputDevice *inputDevice); virtual QWaylandTouch *createTouchDevice(QWaylandInputDevice *inputDevice); QWaylandCompositor(QWaylandCompositorPrivate *dptr); + +private: + virtual QWaylandSurface *createDefaultSurfaceType(); }; QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandquickcompositor.cpp b/src/compositor/compositor_api/qwaylandquickcompositor.cpp index 7f44e1a0e..42b56e40a 100644 --- a/src/compositor/compositor_api/qwaylandquickcompositor.cpp +++ b/src/compositor/compositor_api/qwaylandquickcompositor.cpp @@ -84,9 +84,9 @@ void QWaylandQuickCompositor::setInitializeLegazyQmlNames(bool init) m_initializeLegazyQmlNames = init; } -QWaylandSurface *QWaylandQuickCompositor::createSurface(QWaylandClient *client, quint32 id, int version) +QWaylandSurface *QWaylandQuickCompositor::createDefaultSurfaceType() { - return new QWaylandQuickSurface(client, id, version, this); + return new QWaylandQuickSurface(); } void QWaylandQuickCompositor::classBegin() diff --git a/src/compositor/compositor_api/qwaylandquickcompositor.h b/src/compositor/compositor_api/qwaylandquickcompositor.h index 3952b2ffe..126d299a2 100644 --- a/src/compositor/compositor_api/qwaylandquickcompositor.h +++ b/src/compositor/compositor_api/qwaylandquickcompositor.h @@ -59,14 +59,14 @@ public: bool initializeLegazyQmlNames() const; void setInitializeLegazyQmlNames(bool init); - QWaylandSurface *createSurface(QWaylandClient *client, quint32 id, int version) Q_DECL_OVERRIDE; - protected: void classBegin() Q_DECL_OVERRIDE; void componentComplete() Q_DECL_OVERRIDE; private: bool m_initializeLegazyQmlNames; + + QWaylandSurface *createDefaultSurfaceType() Q_DECL_OVERRIDE; }; QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandquicksurface.cpp b/src/compositor/compositor_api/qwaylandquicksurface.cpp index 77f16887f..10e1ed5b2 100644 --- a/src/compositor/compositor_api/qwaylandquicksurface.cpp +++ b/src/compositor/compositor_api/qwaylandquicksurface.cpp @@ -55,9 +55,8 @@ class QWaylandQuickSurfacePrivate : public QWaylandSurfacePrivate { Q_DECLARE_PUBLIC(QWaylandQuickSurface) public: - QWaylandQuickSurfacePrivate(QWaylandClient *client, quint32 id, int version, QWaylandQuickCompositor *c) - : QWaylandSurfacePrivate(client, id, version, c) - , compositor(c) + QWaylandQuickSurfacePrivate() + : QWaylandSurfacePrivate() , useTextureAlpha(true) , clientRenderingEnabled(true) { @@ -67,14 +66,19 @@ public: { } - QWaylandQuickCompositor *compositor; bool useTextureAlpha; bool clientRenderingEnabled; }; -QWaylandQuickSurface::QWaylandQuickSurface(QWaylandClient *client, quint32 id, int version, QWaylandQuickCompositor *compositor) - : QWaylandSurface(new QWaylandQuickSurfacePrivate(client, id, version, compositor)) +QWaylandQuickSurface::QWaylandQuickSurface() + : QWaylandSurface(* new QWaylandQuickSurfacePrivate()) { + +} +QWaylandQuickSurface::QWaylandQuickSurface(QWaylandCompositor *compositor, QWaylandClient *client, quint32 id, int version) + : QWaylandSurface(* new QWaylandQuickSurfacePrivate()) +{ + initialize(compositor, client, id, version); } QWaylandQuickSurface::~QWaylandQuickSurface() diff --git a/src/compositor/compositor_api/qwaylandquicksurface.h b/src/compositor/compositor_api/qwaylandquicksurface.h index 6926be2f4..e88aa588b 100644 --- a/src/compositor/compositor_api/qwaylandquicksurface.h +++ b/src/compositor/compositor_api/qwaylandquicksurface.h @@ -53,7 +53,8 @@ class Q_COMPOSITOR_EXPORT QWaylandQuickSurface : public QWaylandSurface Q_PROPERTY(bool useTextureAlpha READ useTextureAlpha WRITE setUseTextureAlpha NOTIFY useTextureAlphaChanged) Q_PROPERTY(bool clientRenderingEnabled READ clientRenderingEnabled WRITE setClientRenderingEnabled NOTIFY clientRenderingEnabledChanged) public: - QWaylandQuickSurface(QWaylandClient *client, quint32 id, int version, QWaylandQuickCompositor *compositor); + QWaylandQuickSurface(); + QWaylandQuickSurface(QWaylandCompositor *compositor, QWaylandClient *client, quint32 id, int version); ~QWaylandQuickSurface(); bool useTextureAlpha() const; diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp index 37d07515c..58312de56 100644 --- a/src/compositor/compositor_api/qwaylandsurface.cpp +++ b/src/compositor/compositor_api/qwaylandsurface.cpp @@ -113,22 +113,28 @@ static QRegion infiniteRegion() { QPoint(std::numeric_limits<int>::max(), std::numeric_limits<int>::max()))); } -QWaylandSurfacePrivate::QWaylandSurfacePrivate(QWaylandClient *client, quint32 id, int version, QWaylandCompositor *compositor) - : QtWaylandServer::wl_surface(client->client(), id, version) - , compositor(compositor) +QList<QWaylandSurfacePrivate *> QWaylandSurfacePrivate::uninitializedSurfaces; + +QWaylandSurfacePrivate::QWaylandSurfacePrivate() + : QtWaylandServer::wl_surface() + , compositor(Q_NULLPTR) , refCount(1) - , client(client) + , client(Q_NULLPTR) , buffer(0) , inputPanelSurface(0) , inputRegion(infiniteRegion()) , isCursorSurface(false) , destroyed(false) , mapped(false) + , isInitialized(false) , contentOrientation(Qt::PrimaryOrientation) { pending.buffer = 0; pending.newlyAttached = false; pending.inputRegion = infiniteRegion(); +#ifndef QT_NO_DEBUG + addUninitializedSurface(this); +#endif } QWaylandSurfacePrivate::~QWaylandSurfacePrivate() @@ -173,6 +179,27 @@ void QWaylandSurfacePrivate::notifyViewsAboutDestruction() } } +#ifndef QT_NO_DEBUG +void QWaylandSurfacePrivate::addUninitializedSurface(QWaylandSurfacePrivate *surface) +{ + Q_ASSERT(!surface->isInitialized); + Q_ASSERT(!uninitializedSurfaces.contains(surface)); + uninitializedSurfaces.append(surface); +} + +void QWaylandSurfacePrivate::removeUninitializedSurface(QWaylandSurfacePrivate *surface) +{ + Q_ASSERT(surface->isInitialized); + bool removed = uninitializedSurfaces.removeOne(surface); + Q_ASSERT(removed); +} + +bool QWaylandSurfacePrivate::hasUninitializedSurface() +{ + return uninitializedSurfaces.size(); +} +#endif + void QWaylandSurfacePrivate::surface_destroy_resource(Resource *) { Q_Q(QWaylandSurface); @@ -319,13 +346,19 @@ QtWayland::SurfaceBuffer *QWaylandSurfacePrivate::createSurfaceBuffer(struct ::w return newBuffer; } -QWaylandSurface::QWaylandSurface(QWaylandClient *client, quint32 id, int version, QWaylandCompositor *compositor) - : QObject(*new QWaylandSurfacePrivate(client, id, version, compositor)) +QWaylandSurface::QWaylandSurface() + : QObject(*new QWaylandSurfacePrivate()) { } -QWaylandSurface::QWaylandSurface(QWaylandSurfacePrivate *dptr) - : QObject(*dptr) +QWaylandSurface::QWaylandSurface(QWaylandCompositor *compositor, QWaylandClient *client, uint id, int version) + : QObject(*new QWaylandSurfacePrivate()) +{ + initialize(compositor, client, id, version); +} + +QWaylandSurface::QWaylandSurface(QWaylandSurfacePrivate &dptr) + : QObject(dptr) { } @@ -340,6 +373,24 @@ QWaylandSurface::~QWaylandSurface() } } +void QWaylandSurface::initialize(QWaylandCompositor *compositor, QWaylandClient *client, uint id, int version) +{ + Q_D(QWaylandSurface); + d->compositor = compositor; + d->client = client; + d->init(client->client(), id, version); + d->isInitialized = true; +#ifndef QT_NO_DEBUG + QWaylandSurfacePrivate::removeUninitializedSurface(d); +#endif +} + +bool QWaylandSurface::isInitialized() const +{ + Q_D(const QWaylandSurface); + return d->isInitialized; +} + QWaylandClient *QWaylandSurface::client() const { Q_D(const QWaylandSurface); diff --git a/src/compositor/compositor_api/qwaylandsurface.h b/src/compositor/compositor_api/qwaylandsurface.h index b69312d58..110285900 100644 --- a/src/compositor/compositor_api/qwaylandsurface.h +++ b/src/compositor/compositor_api/qwaylandsurface.h @@ -76,9 +76,13 @@ public: OriginBottomLeft }; - QWaylandSurface(QWaylandClient *client, quint32 id, int version, QWaylandCompositor *compositor); + QWaylandSurface(); + QWaylandSurface(QWaylandCompositor *compositor, QWaylandClient *client, uint id, int version); virtual ~QWaylandSurface(); + Q_INVOKABLE void initialize(QWaylandCompositor *compositor, QWaylandClient *client, uint id, int version); + bool isInitialized() const; + QWaylandClient *client() const; struct wl_client *waylandClient() const { return client()->client(); } @@ -117,7 +121,7 @@ public Q_SLOTS: void updateSelection(); protected: - QWaylandSurface(QWaylandSurfacePrivate *dptr); + QWaylandSurface(QWaylandSurfacePrivate &dptr); Q_SIGNALS: void mappedChanged(); diff --git a/src/compositor/compositor_api/qwaylandsurface_p.h b/src/compositor/compositor_api/qwaylandsurface_p.h index 8ed73f94a..29117852d 100644 --- a/src/compositor/compositor_api/qwaylandsurface_p.h +++ b/src/compositor/compositor_api/qwaylandsurface_p.h @@ -77,7 +77,7 @@ class Q_COMPOSITOR_EXPORT QWaylandSurfacePrivate : public QObjectPrivate, public public: static QWaylandSurfacePrivate *get(QWaylandSurface *surface); - QWaylandSurfacePrivate(QWaylandClient *client, quint32 id, int version, QWaylandCompositor *compositor); + QWaylandSurfacePrivate(); ~QWaylandSurfacePrivate(); void ref(); @@ -95,6 +95,12 @@ public: void notifyViewsAboutDestruction(); void setInputPanelSurface(QtWayland::InputPanelSurface *ips) { inputPanelSurface = ips; } + +#ifndef QT_NO_DEBUG + static void addUninitializedSurface(QWaylandSurfacePrivate *surface); + static void removeUninitializedSurface(QWaylandSurfacePrivate *surface); + static bool hasUninitializedSurface(); +#endif protected: void surface_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; @@ -149,9 +155,13 @@ protected: //member variables bool isCursorSurface; bool destroyed; bool mapped; + bool isInitialized; Qt::ScreenOrientation contentOrientation; QWindow::Visibility visibility; +#ifndef QT_NO_DEBUG + static QList<QWaylandSurfacePrivate *> uninitializedSurfaces; +#endif Q_DECLARE_PUBLIC(QWaylandSurface) Q_DISABLE_COPY(QWaylandSurfacePrivate) }; diff --git a/src/imports/compositor/qwaylandquickcompositorplugin.cpp b/src/imports/compositor/qwaylandquickcompositorplugin.cpp index 7532001a9..1c693000a 100644 --- a/src/imports/compositor/qwaylandquickcompositorplugin.cpp +++ b/src/imports/compositor/qwaylandquickcompositorplugin.cpp @@ -125,14 +125,15 @@ public: qmlRegisterType<QWaylandQuickItem>(uri, 1, 0, "WaylandQuickItem"); qmlRegisterType<QWaylandMouseTracker>(uri, 1, 0, "WaylandMouseTracker"); qmlRegisterType<QWaylandQuickOutput>(uri, 1, 0, "WaylandOutput"); + qmlRegisterType<QWaylandQuickSurface>(uri, 1, 0, "WaylandSurface"); qmlRegisterUncreatableType<QWaylandExtension>(uri, 1, 0, "WaylandExtension", QObject::tr("Cannot create instance of WaylandExtension")); - qmlRegisterUncreatableType<QWaylandSurface>(uri, 1, 0, "WaylandSurface", QObject::tr("Cannot create instance of WaylandQuickSurface")); qmlRegisterUncreatableType<QWaylandClient>(uri, 1, 0, "WaylandClient", QObject::tr("Cannot create instance of WaylandClient")); qmlRegisterUncreatableType<QWaylandOutputSpace>(uri, 1, 0, "WaylandOutputSpace", QObject::tr("Cannot create instance of WaylandOutputSpace")); qmlRegisterUncreatableType<QWaylandView>(uri, 1, 0, "WaylandView", QObject::tr("Cannot create instance of WaylandView, it can be retrieved by accessor on WaylandQuickItem")); qmlRegisterUncreatableType<QWaylandInputDevice>(uri, 1, 0, "WaylandInputDevice", QObject::tr("Cannot create instance of WaylandInputDevice")); qmlRegisterUncreatableType<QWaylandCompositor>(uri, 1, 0, "WaylandCompositorBase", QObject::tr("Cannot create instance of WaylandCompositorBase, use WaylandCompositor instead")); + qmlRegisterUncreatableType<QWaylandSurface>(uri, 1, 0, "WaylandSurfaceBase", QObject::tr("Cannot create instance of WaylandSurfaceBase, use WaylandSurface instead")); //This should probably be somewhere else qmlRegisterType<QWaylandShellQuickData>(uri, 1, 0, "DefaultShell"); |