diff options
author | Johan Klokkhammer Helsing <johan.helsing@qt.io> | 2018-08-13 16:18:47 +0200 |
---|---|---|
committer | Paul Olav Tvete <paul.tvete@qt.io> | 2018-08-17 14:41:05 +0000 |
commit | 845839b971f6af017be77dbe1ee1541453d12c23 (patch) | |
tree | 4289e0aa931cf95586e088620bb508b17f5e26f9 /src/compositor/extensions | |
parent | 53d7bffef7fd7f2e1026ac54e5c8bdb3df761208 (diff) |
Compositor API: Add xdg-decoration unstable v1 support
And add an example with server-side window decorations.
Task-number: QTBUG-69934
Change-Id: Ic3984b50cf7574cae5135dea51eb4b1c80bb45a7
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Diffstat (limited to 'src/compositor/extensions')
-rw-r--r-- | src/compositor/extensions/extensions.pri | 4 | ||||
-rw-r--r-- | src/compositor/extensions/qwaylandxdgdecorationv1.cpp | 180 | ||||
-rw-r--r-- | src/compositor/extensions/qwaylandxdgdecorationv1.h | 69 | ||||
-rw-r--r-- | src/compositor/extensions/qwaylandxdgdecorationv1_p.h | 107 | ||||
-rw-r--r-- | src/compositor/extensions/qwaylandxdgshell.cpp | 6 | ||||
-rw-r--r-- | src/compositor/extensions/qwaylandxdgshell.h | 11 | ||||
-rw-r--r-- | src/compositor/extensions/qwaylandxdgshell_p.h | 3 |
7 files changed, 380 insertions, 0 deletions
diff --git a/src/compositor/extensions/extensions.pri b/src/compositor/extensions/extensions.pri index b2c55635a..5c708f891 100644 --- a/src/compositor/extensions/extensions.pri +++ b/src/compositor/extensions/extensions.pri @@ -11,6 +11,7 @@ WAYLANDSERVERSOURCES += \ ../3rdparty/protocol/text-input-unstable-v2.xml \ ../3rdparty/protocol/xdg-shell-unstable-v6.xml \ ../3rdparty/protocol/xdg-shell.xml \ + ../3rdparty/protocol/xdg-decoration-unstable-v1.xml \ ../3rdparty/protocol/ivi-application.xml \ HEADERS += \ @@ -32,6 +33,8 @@ HEADERS += \ extensions/qwaylandxdgshellv6_p.h \ extensions/qwaylandxdgshell.h \ extensions/qwaylandxdgshell_p.h \ + extensions/qwaylandxdgdecorationv1.h \ + extensions/qwaylandxdgdecorationv1_p.h \ extensions/qwaylandshellsurface.h \ extensions/qwaylandiviapplication.h \ extensions/qwaylandiviapplication_p.h \ @@ -49,6 +52,7 @@ SOURCES += \ extensions/qwaylandxdgshellv5.cpp \ extensions/qwaylandxdgshellv6.cpp \ extensions/qwaylandxdgshell.cpp \ + extensions/qwaylandxdgdecorationv1.cpp \ extensions/qwaylandshellsurface.cpp \ extensions/qwaylandiviapplication.cpp \ extensions/qwaylandivisurface.cpp \ diff --git a/src/compositor/extensions/qwaylandxdgdecorationv1.cpp b/src/compositor/extensions/qwaylandxdgdecorationv1.cpp new file mode 100644 index 000000000..a44d5c19d --- /dev/null +++ b/src/compositor/extensions/qwaylandxdgdecorationv1.cpp @@ -0,0 +1,180 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** 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 "qwaylandxdgdecorationv1_p.h" + +#include <QtWaylandCompositor/QWaylandXdgToplevel> +#include <QtWaylandCompositor/private/qwaylandxdgshell_p.h> + +#include <QtWaylandCompositor/QWaylandCompositor> +#include <QtCore/QObject> + +QT_BEGIN_NAMESPACE + +QWaylandXdgDecorationManagerV1::QWaylandXdgDecorationManagerV1() + : QWaylandCompositorExtensionTemplate<QWaylandXdgDecorationManagerV1>(*new QWaylandXdgDecorationManagerV1Private) +{ +} + +void QWaylandXdgDecorationManagerV1::initialize() +{ + Q_D(QWaylandXdgDecorationManagerV1); + + QWaylandCompositorExtensionTemplate::initialize(); + QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(extensionContainer()); + if (!compositor) { + qWarning() << "Failed to find QWaylandCompositor when initializing QWaylandXdgDecorationV1"; + return; + } + d->init(compositor->display(), 1); +} + +QWaylandXdgToplevel::DecorationMode QWaylandXdgDecorationManagerV1::preferredMode() const +{ + Q_D(const QWaylandXdgDecorationManagerV1); + return d->m_defaultMode; +} + +void QWaylandXdgDecorationManagerV1::setPreferredMode(QWaylandXdgToplevel::DecorationMode defaultMode) +{ + Q_D(QWaylandXdgDecorationManagerV1); + if (d->m_defaultMode == defaultMode) + return; + + d->m_defaultMode = defaultMode; + emit defaultModeChanged(); +} + +const wl_interface *QWaylandXdgDecorationManagerV1::interface() +{ + return QWaylandXdgDecorationManagerV1Private::interface(); +} + +void QWaylandXdgDecorationManagerV1Private::zxdg_decoration_manager_v1_get_toplevel_decoration( + Resource *resource, uint id, wl_resource *toplevelResource) +{ + Q_Q(QWaylandXdgDecorationManagerV1); + + auto *toplevel = QWaylandXdgToplevel::fromResource(toplevelResource); + if (!toplevel) { + qWarning() << "Couldn't find toplevel for decoration"; + return; + } + + //TODO: verify that the xdg surface is unconfigured, and post protocol error/warning + + auto *toplevelPrivate = QWaylandXdgToplevelPrivate::get(toplevel); + + if (toplevelPrivate->m_decoration) { + qWarning() << "zxdg_decoration_manager_v1.get_toplevel_decoration:" + << toplevel << "already has a decoration object, ignoring"; + //TODO: protocol error as well? + return; + } + + new QWaylandXdgToplevelDecorationV1(toplevel, q, resource->client(), id); +} + +QWaylandXdgToplevelDecorationV1::QWaylandXdgToplevelDecorationV1(QWaylandXdgToplevel *toplevel, + QWaylandXdgDecorationManagerV1 *manager, + wl_client *client, int id) + : QtWaylandServer::zxdg_toplevel_decoration_v1(client, id, /*version*/ 1) + , m_toplevel(toplevel) + , m_manager(manager) +{ + Q_ASSERT(toplevel); + auto *toplevelPrivate = QWaylandXdgToplevelPrivate::get(toplevel); + Q_ASSERT(!toplevelPrivate->m_decoration); + toplevelPrivate->m_decoration.reset(this); + sendConfigure(manager->preferredMode()); +} + +void QWaylandXdgToplevelDecorationV1::sendConfigure(QWaylandXdgToplevelDecorationV1::DecorationMode mode) +{ + if (configuredMode() == mode) + return; + + switch (mode) { + case DecorationMode::ClientSideDecoration: + send_configure(mode_client_side); + break; + case DecorationMode::ServerSideDecoration: + send_configure(mode_server_side); + break; + default: + qWarning() << "Illegal mode in QWaylandXdgToplevelDecorationV1::sendConfigure" << mode; + break; + } + + m_configuredMode = mode; + emit m_toplevel->decorationModeChanged(); +} + +void QWaylandXdgToplevelDecorationV1::zxdg_toplevel_decoration_v1_destroy_resource(Resource *resource) +{ + Q_UNUSED(resource); + auto *toplevelPrivate = QWaylandXdgToplevelPrivate::get(m_toplevel); + toplevelPrivate->m_decoration.reset(); +} + +void QWaylandXdgToplevelDecorationV1::zxdg_toplevel_decoration_v1_destroy(Resource *resource) +{ + wl_resource_destroy(resource->handle); +} + +void QWaylandXdgToplevelDecorationV1::zxdg_toplevel_decoration_v1_set_mode(Resource *resource, uint32_t mode) +{ + m_clientPreferredMode = DecorationMode(mode); + handleClientPreferredModeChanged(); +} + +void QWaylandXdgToplevelDecorationV1::zxdg_toplevel_decoration_v1_unset_mode(Resource *resource) +{ + m_clientPreferredMode = DecorationMode::DefaultDecorationMode; + handleClientPreferredModeChanged(); +} + +void QWaylandXdgToplevelDecorationV1::handleClientPreferredModeChanged() +{ + if (m_clientPreferredMode != m_configuredMode) { + if (m_clientPreferredMode == DecorationMode::DefaultDecorationMode) + sendConfigure(m_manager->preferredMode()); + else + sendConfigure(m_clientPreferredMode); + } +} + +QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandxdgdecorationv1.h b/src/compositor/extensions/qwaylandxdgdecorationv1.h new file mode 100644 index 000000000..649f3d162 --- /dev/null +++ b/src/compositor/extensions/qwaylandxdgdecorationv1.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** 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 QWAYLANDXDGDECORATIONV1_H +#define QWAYLANDXDGDECORATIONV1_H + +#include <QtWaylandCompositor/QWaylandCompositorExtension> +#include <QtWaylandCompositor/QWaylandXdgToplevel> + +QT_BEGIN_NAMESPACE + +class QWaylandXdgDecorationManagerV1Private; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgDecorationManagerV1 : public QWaylandCompositorExtensionTemplate<QWaylandXdgDecorationManagerV1> +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandXdgDecorationManagerV1) + Q_PROPERTY(QWaylandXdgToplevel::DecorationMode preferredMode READ preferredMode WRITE setPreferredMode NOTIFY defaultModeChanged) + +public: + explicit QWaylandXdgDecorationManagerV1(); + + void initialize() override; + + QWaylandXdgToplevel::DecorationMode preferredMode() const; + void setPreferredMode(QWaylandXdgToplevel::DecorationMode preferredMode); + + static const struct wl_interface *interface(); + +Q_SIGNALS: + void defaultModeChanged(); +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDXDGDECORATIONV1_H diff --git a/src/compositor/extensions/qwaylandxdgdecorationv1_p.h b/src/compositor/extensions/qwaylandxdgdecorationv1_p.h new file mode 100644 index 000000000..c09cbc12e --- /dev/null +++ b/src/compositor/extensions/qwaylandxdgdecorationv1_p.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** 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 QWAYLANDXDGDECORATIONV1_P_H +#define QWAYLANDXDGDECORATIONV1_P_H + +#include "qwaylandxdgdecorationv1.h" + +#include <QtWaylandCompositor/private/qwaylandcompositorextension_p.h> +#include <QtWaylandCompositor/private/qwayland-server-xdg-decoration-unstable-v1.h> + +#include <QtWaylandCompositor/QWaylandXdgToplevel> + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +class QWaylandXdgToplevel; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgDecorationManagerV1Private + : public QWaylandCompositorExtensionPrivate + , public QtWaylandServer::zxdg_decoration_manager_v1 +{ + Q_DECLARE_PUBLIC(QWaylandXdgDecorationManagerV1) +public: + using DecorationMode = QWaylandXdgToplevel::DecorationMode; + explicit QWaylandXdgDecorationManagerV1Private() {} + +protected: + void zxdg_decoration_manager_v1_get_toplevel_decoration(Resource *resource, uint id, ::wl_resource *toplevelResource) override; + +private: + DecorationMode m_defaultMode = DecorationMode::ClientSideDecoration; +}; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgToplevelDecorationV1 + : public QtWaylandServer::zxdg_toplevel_decoration_v1 +{ +public: + using DecorationMode = QWaylandXdgToplevel::DecorationMode; + explicit QWaylandXdgToplevelDecorationV1(QWaylandXdgToplevel *toplevel, + QWaylandXdgDecorationManagerV1 *manager, + wl_client *client, int id); + + DecorationMode configuredMode() const { return m_configuredMode; } + void sendConfigure(DecorationMode mode); + +protected: + void zxdg_toplevel_decoration_v1_destroy_resource(Resource *resource) override; + void zxdg_toplevel_decoration_v1_destroy(Resource *resource) override; + void zxdg_toplevel_decoration_v1_set_mode(Resource *resource, uint32_t mode) override; + void zxdg_toplevel_decoration_v1_unset_mode(Resource *resource) override; + +private: + void handleClientPreferredModeChanged(); + + QWaylandXdgToplevel *m_toplevel = nullptr; + QWaylandXdgDecorationManagerV1 *m_manager = nullptr; + DecorationMode m_configuredMode = DecorationMode::DefaultDecorationMode; + DecorationMode m_clientPreferredMode = DecorationMode::DefaultDecorationMode; +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDXDGDECORATIONV1_P_H diff --git a/src/compositor/extensions/qwaylandxdgshell.cpp b/src/compositor/extensions/qwaylandxdgshell.cpp index 01543135a..205269a88 100644 --- a/src/compositor/extensions/qwaylandxdgshell.cpp +++ b/src/compositor/extensions/qwaylandxdgshell.cpp @@ -904,6 +904,12 @@ bool QWaylandXdgToplevel::activated() const return d->m_lastAckedConfigure.states.contains(QWaylandXdgToplevel::State::ActivatedState); } +QWaylandXdgToplevel::DecorationMode QWaylandXdgToplevel::decorationMode() const +{ + Q_D(const QWaylandXdgToplevel); + return d->m_decoration ? d->m_decoration->configuredMode() : DecorationMode::ClientSideDecoration; +} + /*! * \qmlmethod size QtWaylandCompositor::XdgToplevel::sizeForResize(size size, point delta, uint edges) * diff --git a/src/compositor/extensions/qwaylandxdgshell.h b/src/compositor/extensions/qwaylandxdgshell.h index 5467290f6..bcc316e85 100644 --- a/src/compositor/extensions/qwaylandxdgshell.h +++ b/src/compositor/extensions/qwaylandxdgshell.h @@ -150,6 +150,7 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgToplevel : public QObject Q_PROPERTY(bool fullscreen READ fullscreen NOTIFY fullscreenChanged) Q_PROPERTY(bool resizing READ resizing NOTIFY resizingChanged) Q_PROPERTY(bool activated READ activated NOTIFY activatedChanged) + Q_PROPERTY(enum DecorationMode decorationMode READ decorationMode NOTIFY decorationModeChanged) public: enum State : uint { MaximizedState = 1, @@ -159,6 +160,13 @@ public: }; Q_ENUM(State) + enum DecorationMode { + DefaultDecorationMode, + ClientSideDecoration, + ServerSideDecoration, + }; + Q_ENUM(DecorationMode) + QWaylandXdgToplevel(QWaylandXdgSurface *xdgSurface, QWaylandResource &resource); QWaylandXdgToplevel *parentToplevel() const; @@ -172,6 +180,7 @@ public: bool fullscreen() const; bool resizing() const; bool activated() const; + DecorationMode decorationMode() const; Q_INVOKABLE QSize sizeForResize(const QSizeF &size, const QPointF &delta, Qt::Edges edges) const; uint sendConfigure(const QSize &size, const QVector<State> &states); @@ -206,6 +215,8 @@ Q_SIGNALS: void unsetFullscreen(); void setMinimized(); + void decorationModeChanged(); + private: QList<int> statesAsInts() const; }; diff --git a/src/compositor/extensions/qwaylandxdgshell_p.h b/src/compositor/extensions/qwaylandxdgshell_p.h index 04d360ee7..70def5f7a 100644 --- a/src/compositor/extensions/qwaylandxdgshell_p.h +++ b/src/compositor/extensions/qwaylandxdgshell_p.h @@ -42,6 +42,8 @@ #include <QtWaylandCompositor/QWaylandXdgShell> +#include <QtWaylandCompositor/private/qwaylandxdgdecorationv1_p.h> + #include <QtCore/QSet> // @@ -176,6 +178,7 @@ public: QString m_appId; QSize m_maxSize; QSize m_minSize; + QScopedPointer<QWaylandXdgToplevelDecorationV1> m_decoration; static QWaylandSurfaceRole s_role; }; |