From 19d018dd6c7023dff7f7dcbaa7c38e486897495c Mon Sep 17 00:00:00 2001 From: Giulio Camuffo Date: Mon, 8 Feb 2016 19:31:59 +0200 Subject: Add surface roles back Task-number: QTBUG-49809 Change-Id: Id62ddea68c89b6999b66d3df8eeeffd858ae844f Reviewed-by: Paul Olav Tvete --- src/compositor/compositor_api/compositor_api.pri | 2 + src/compositor/compositor_api/qwaylandpointer.cpp | 16 +++++- src/compositor/compositor_api/qwaylandpointer_p.h | 2 + src/compositor/compositor_api/qwaylandresource.cpp | 51 +++++++++++++++++ src/compositor/compositor_api/qwaylandresource.h | 64 ++++++++++++++++++++++ src/compositor/compositor_api/qwaylandsurface.cpp | 26 +++++++++ src/compositor/compositor_api/qwaylandsurface.h | 13 +++++ src/compositor/compositor_api/qwaylandsurface_p.h | 1 + src/compositor/extensions/qwaylandshell.cpp | 35 +++++++++--- src/compositor/extensions/qwaylandshell.h | 9 ++- src/compositor/extensions/qwaylandshell_p.h | 1 + .../compositor/qwaylandquickcompositorplugin.cpp | 3 +- 12 files changed, 208 insertions(+), 15 deletions(-) create mode 100644 src/compositor/compositor_api/qwaylandresource.cpp create mode 100644 src/compositor/compositor_api/qwaylandresource.h (limited to 'src') diff --git a/src/compositor/compositor_api/compositor_api.pri b/src/compositor/compositor_api/compositor_api.pri index 70f3e3a12..d5ea9a9a4 100644 --- a/src/compositor/compositor_api/compositor_api.pri +++ b/src/compositor/compositor_api/compositor_api.pri @@ -22,6 +22,7 @@ HEADERS += \ compositor_api/qwaylanddestroylistener_p.h \ compositor_api/qwaylandview.h \ compositor_api/qwaylandview_p.h \ + compositor_api/qwaylandresource.h \ SOURCES += \ compositor_api/qwaylandcompositor.cpp \ @@ -37,6 +38,7 @@ SOURCES += \ compositor_api/qwaylandbufferref.cpp \ compositor_api/qwaylanddestroylistener.cpp \ compositor_api/qwaylandview.cpp \ + compositor_api/qwaylandresource.cpp \ QT += core-private diff --git a/src/compositor/compositor_api/qwaylandpointer.cpp b/src/compositor/compositor_api/qwaylandpointer.cpp index 550464544..a789c4c8c 100644 --- a/src/compositor/compositor_api/qwaylandpointer.cpp +++ b/src/compositor/compositor_api/qwaylandpointer.cpp @@ -41,6 +41,8 @@ QT_BEGIN_NAMESPACE +QWaylandSurfaceRole QWaylandPointerPrivate::s_role("wl_pointer"); + QWaylandPointerPrivate::QWaylandPointerPrivate(QWaylandPointer *pointer, QWaylandInputDevice *seat) : QObjectPrivate() , wl_pointer() @@ -75,8 +77,18 @@ void QWaylandPointerPrivate::pointer_set_cursor(wl_pointer::Resource *resource, } QWaylandSurface *s = QWaylandSurface::fromResource(surface); - s->markAsCursorSurface(true); - seat->cursorSurfaceRequest(s, hotspot_x, hotspot_y); + // XXX FIXME + // The role concept was formalized in wayland 1.7, so that release adds one error + // code for each interface that implements a role, and we are supposed to pass here + // the newly constructed resource and the correct error code so that if setting the + // role fails, a proper error can be sent to the client. + // However we're still using wayland 1.4, which doesn't have interface specific role + // errors, so the best we can do is to use wl_display's object_id error. + wl_resource *displayRes = wl_client_get_object(resource->client(), 1); + if (s->setRole(&QWaylandPointerPrivate::s_role, displayRes, WL_DISPLAY_ERROR_INVALID_OBJECT)) { + s->markAsCursorSurface(true); + seat->cursorSurfaceRequest(s, hotspot_x, hotspot_y); + } } /*! diff --git a/src/compositor/compositor_api/qwaylandpointer_p.h b/src/compositor/compositor_api/qwaylandpointer_p.h index d7a6335a3..7748f98df 100644 --- a/src/compositor/compositor_api/qwaylandpointer_p.h +++ b/src/compositor/compositor_api/qwaylandpointer_p.h @@ -98,6 +98,8 @@ private: int buttonCount; QWaylandDestroyListener focusDestroyListener; + + static QWaylandSurfaceRole s_role; }; QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandresource.cpp b/src/compositor/compositor_api/qwaylandresource.cpp new file mode 100644 index 000000000..aea8c3778 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandresource.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandresource.h" + +QT_BEGIN_NAMESPACE + +QWaylandResource::QWaylandResource() + : m_resource(0) +{ +} + +QWaylandResource::QWaylandResource(wl_resource *resource) + : m_resource(resource) +{ +} + +QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandresource.h b/src/compositor/compositor_api/qwaylandresource.h new file mode 100644 index 000000000..1987c1106 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandresource.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Klarälvdalens Datakonsult AB (KDAB). +** 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 QWAYLANDRESOURCE_H +#define QWAYLANDRESOURCE_H + +#include +#include + +struct wl_resource; + +QT_BEGIN_NAMESPACE + +class Q_COMPOSITOR_EXPORT QWaylandResource +{ + Q_GADGET +public: + QWaylandResource(); + explicit QWaylandResource(wl_resource *resource); + + wl_resource *resource() const { return m_resource; } + +private: + wl_resource *m_resource; +}; + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QWaylandResource) + +#endif /*QWAYLANDRESOURCE_H*/ diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp index ed028824f..3ea2bc87c 100644 --- a/src/compositor/compositor_api/qwaylandsurface.cpp +++ b/src/compositor/compositor_api/qwaylandsurface.cpp @@ -123,6 +123,7 @@ QWaylandSurfacePrivate::QWaylandSurfacePrivate() , refCount(1) , client(Q_NULLPTR) , buffer(0) + , role(0) , inputPanelSurface(0) , inputRegion(infiniteRegion()) , isCursorSurface(false) @@ -742,6 +743,31 @@ struct wl_resource *QWaylandSurface::resource() const return d->resource()->handle; } +/*! + * Sets a role on the surface. A role defines how a surface will be mapped on screen, without a role + * a surface is supposed to be hidden. Only one role at all times can be set on a surface. Attempting + * to change the role of a surface will trigger a protocol error to the client, while setting the same + * role many times is allowed. + * + * \param errorResource The resource the error will be sent to if the role is being changed. + * \param errorCode The error code that will be sent to the client. + */ +bool QWaylandSurface::setRole(QWaylandSurfaceRole *role, wl_resource *errorResource, uint32_t errorCode) +{ + Q_D(QWaylandSurface); + + if (d->role && d->role != role) { + wl_resource_post_error(errorResource, errorCode, + "Cannot assign role %s to wl_surface@%d, already has role %s\n", + role->name().constData(), wl_resource_get_id(resource()), + d->role->name().constData()); + return false; + } + + d->role = role; + return true; +} + QWaylandSurfacePrivate *QWaylandSurfacePrivate::get(QWaylandSurface *surface) { return surface ? surface->d_func() : Q_NULLPTR; diff --git a/src/compositor/compositor_api/qwaylandsurface.h b/src/compositor/compositor_api/qwaylandsurface.h index bb034080a..1ca689c6c 100644 --- a/src/compositor/compositor_api/qwaylandsurface.h +++ b/src/compositor/compositor_api/qwaylandsurface.h @@ -60,6 +60,17 @@ class QWaylandBufferRef; class QWaylandView; class QWaylandSurfaceOp; +class QWaylandSurfaceRole +{ +public: + QWaylandSurfaceRole(const QByteArray &n) : m_name(n) {} + + const QByteArray name() { return m_name; } + +private: + QByteArray m_name; +}; + class Q_COMPOSITOR_EXPORT QWaylandSurface : public QWaylandObject { Q_OBJECT @@ -88,6 +99,8 @@ public: QWaylandClient *client() const; struct wl_client *waylandClient() const { return client()->client(); } + bool setRole(QWaylandSurfaceRole *role, wl_resource *errorResource, uint32_t errorCode); + bool isMapped() const; QSize size() const; diff --git a/src/compositor/compositor_api/qwaylandsurface_p.h b/src/compositor/compositor_api/qwaylandsurface_p.h index de71b7fe3..32b5c181f 100644 --- a/src/compositor/compositor_api/qwaylandsurface_p.h +++ b/src/compositor/compositor_api/qwaylandsurface_p.h @@ -145,6 +145,7 @@ protected: //member variables QRegion damage; QtWayland::SurfaceBuffer *buffer; QWaylandBufferRef bufferRef; + QWaylandSurfaceRole *role; struct { QtWayland::SurfaceBuffer *buffer; diff --git a/src/compositor/extensions/qwaylandshell.cpp b/src/compositor/extensions/qwaylandshell.cpp index e06dc9264..8bd3e6adb 100644 --- a/src/compositor/extensions/qwaylandshell.cpp +++ b/src/compositor/extensions/qwaylandshell.cpp @@ -48,6 +48,8 @@ QT_BEGIN_NAMESPACE +QWaylandSurfaceRole QWaylandShellSurfacePrivate::s_role("wl_shell_surface"); + QWaylandShellPrivate::QWaylandShellPrivate() : QWaylandExtensionTemplatePrivate() , wl_shell() @@ -58,8 +60,19 @@ void QWaylandShellPrivate::shell_get_shell_surface(Resource *resource, uint32_t { Q_Q(QWaylandShell); QWaylandSurface *surface = QWaylandSurface::fromResource(surface_res); - QWaylandCompositor *compositor = static_cast(q->extensionContainer()); - emit q_func()->createShellSurface(surface, QWaylandClient::fromWlClient(compositor, resource->client()), id); + + wl_resource *res = wl_resource_create(resource->client(), &wl_shell_surface_interface, + wl_resource_get_version(resource->handle), id); + // XXX FIXME + // The role concept was formalized in wayland 1.7, so that release adds one error + // code for each interface that implements a role, and we are supposed to pass here + // the newly constructed resource and the correct error code so that if setting the + // role fails, a proper error can be sent to the client. + // However we're still using wayland 1.4, which doesn't have interface specific role + // errors, so the best we can do is to use wl_display's object_id error. + wl_resource *displayRes = wl_client_get_object(resource->client(), 1); + if (surface->setRole(QWaylandShellSurface::role(), displayRes, WL_DISPLAY_ERROR_INVALID_OBJECT)) + emit q->createShellSurface(surface, QWaylandResource(res)); } QWaylandShellSurfacePrivate::QWaylandShellSurfacePrivate() @@ -352,13 +365,12 @@ QWaylandShellSurface::QWaylandShellSurface() } /*! - * Constructs a QWaylandShellSurface for \a surface and initializes it with the given \a shell, \a client, - * and \a id. + * Constructs a QWaylandShellSurface for \a surface and initializes it with the given \a shell and \a resource. */ -QWaylandShellSurface::QWaylandShellSurface(QWaylandShell *shell, QWaylandSurface *surface, QWaylandClient *client, uint id) +QWaylandShellSurface::QWaylandShellSurface(QWaylandShell *shell, QWaylandSurface *surface, const QWaylandResource &res) : QWaylandExtensionTemplate(*new QWaylandShellSurfacePrivate) { - initialize(shell, surface, client, id); + initialize(shell, surface, res); } /*! @@ -368,14 +380,14 @@ QWaylandShellSurface::QWaylandShellSurface(QWaylandShell *shell, QWaylandSurface */ /*! - * Initializes the QWaylandShellSurface, associating it with the given \a shell, \a surface, \a client, and \a id. + * Initializes the QWaylandShellSurface, associating it with the given \a shell, \a surface and \a resource. */ -void QWaylandShellSurface::initialize(QWaylandShell *shell, QWaylandSurface *surface, QWaylandClient *client, uint id) +void QWaylandShellSurface::initialize(QWaylandShell *shell, QWaylandSurface *surface, const QWaylandResource &resource) { Q_D(QWaylandShellSurface); d->m_shell = shell; d->m_surface = surface; - d->init(client->client(), id, 1); + d->init(resource.resource()); setExtensionContainer(surface); emit surfaceChanged(); QWaylandExtension::initialize(); @@ -549,4 +561,9 @@ QString QWaylandShellSurface::className() const return d->m_className; } +QWaylandSurfaceRole *QWaylandShellSurface::role() +{ + return &QWaylandShellSurfacePrivate::s_role; +} + QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandshell.h b/src/compositor/extensions/qwaylandshell.h index 3794a11da..225aeeb4e 100644 --- a/src/compositor/extensions/qwaylandshell.h +++ b/src/compositor/extensions/qwaylandshell.h @@ -38,6 +38,7 @@ #define QWAYLANDSHELL_H #include +#include #include @@ -49,6 +50,7 @@ class QWaylandSurface; class QWaylandClient; class QWaylandInputDevice; class QWaylandOutput; +class QWaylandSurfaceRole; class Q_COMPOSITOR_EXPORT QWaylandShell : public QWaylandExtensionTemplate { @@ -64,7 +66,7 @@ public: static QByteArray interfaceName(); Q_SIGNALS: - void createShellSurface(QWaylandSurface *surface, QWaylandClient *client, uint id); + void createShellSurface(QWaylandSurface *surface, const QWaylandResource &resource); }; class Q_COMPOSITOR_EXPORT QWaylandShellSurface : public QWaylandExtensionTemplate @@ -105,9 +107,9 @@ public: Q_ENUM(FocusPolicy) QWaylandShellSurface(); - QWaylandShellSurface(QWaylandShell *shell, QWaylandSurface *surface, QWaylandClient *client, uint id); + QWaylandShellSurface(QWaylandShell *shell, QWaylandSurface *surface, const QWaylandResource &resource); - Q_INVOKABLE void initialize(QWaylandShell *shell, QWaylandSurface *surface, QWaylandClient *client, uint id); + Q_INVOKABLE void initialize(QWaylandShell *shell, QWaylandSurface *surface, const QWaylandResource &resource); QString title() const; QString className() const; @@ -118,6 +120,7 @@ public: static const struct wl_interface *interface(); static QByteArray interfaceName(); + static QWaylandSurfaceRole *role(); Q_INVOKABLE QSize sizeForResize(const QSizeF &size, const QPointF &delta, ResizeEdge edges); Q_INVOKABLE void sendConfigure(const QSize &size, ResizeEdge edges); diff --git a/src/compositor/extensions/qwaylandshell_p.h b/src/compositor/extensions/qwaylandshell_p.h index 27dbb335a..9243eb97e 100644 --- a/src/compositor/extensions/qwaylandshell_p.h +++ b/src/compositor/extensions/qwaylandshell_p.h @@ -143,6 +143,7 @@ private: void shell_surface_set_class(Resource *resource, const QString &class_) Q_DECL_OVERRIDE; + static QWaylandSurfaceRole s_role; }; QT_END_NAMESPACE diff --git a/src/imports/compositor/qwaylandquickcompositorplugin.cpp b/src/imports/compositor/qwaylandquickcompositorplugin.cpp index b380f575c..0f609b0fa 100644 --- a/src/imports/compositor/qwaylandquickcompositorplugin.cpp +++ b/src/imports/compositor/qwaylandquickcompositorplugin.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #include @@ -135,7 +136,7 @@ public: qmlRegisterUncreatableType(uri, 1, 0, "WaylandCompositorBase", QObject::tr("Cannot create instance of WaylandCompositorBase, use WaylandCompositor instead")); qmlRegisterUncreatableType(uri, 1, 0, "WaylandSurfaceBase", QObject::tr("Cannot create instance of WaylandSurfaceBase, use WaylandSurface instead")); qmlRegisterUncreatableType(uri, 1, 0, "ShellSurfaceBase", QObject::tr("Cannot create instance of ShellSurfaceBase, use ShellSurface instead")); - + qmlRegisterUncreatableType(uri, 1, 0, "WaylandResource", QObject::tr("Cannot create instance of WaylandResource")); //This should probably be somewhere else qmlRegisterType(uri, 1, 0, "Shell"); -- cgit v1.2.3