1// Copyright (C) 2017 Erik Larsson.
2// Copyright (C) 2021 David Redondo <qt@david-redondo.de>
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include "qwaylandclientextension.h"
6#include "qwaylandclientextension_p.h"
7#include <QtWaylandClient/private/qwaylanddisplay_p.h>
8#include <QtWaylandClient/private/qwaylandintegration_p.h>
9
10QT_BEGIN_NAMESPACE
11
12using RegistryGlobal = QtWaylandClient::QWaylandDisplay::RegistryGlobal;
13
14QWaylandClientExtensionPrivate::QWaylandClientExtensionPrivate()
15{
16 // Keep the possibility to use a custom waylandIntegration as a plugin,
17 // but also add the possibility to run it as a QML component.
18 waylandIntegration = QtWaylandClient::QWaylandIntegration::instance();
19 if (!waylandIntegration)
20 waylandIntegration = new QtWaylandClient::QWaylandIntegration();
21}
22
23void QWaylandClientExtensionPrivate::globalAdded(const RegistryGlobal &global)
24{
25 Q_Q(QWaylandClientExtension);
26 if (!active && global.interface == QLatin1String(q->extensionInterface()->name)) {
27 q->bind(registry: global.registry, id: global.id, version: global.version);
28 active = true;
29 emit q->activeChanged();
30 }
31}
32
33void QWaylandClientExtensionPrivate::globalRemoved(const RegistryGlobal &global)
34{
35 Q_Q(QWaylandClientExtension);
36 if (active && global.interface == QLatin1String(q->extensionInterface()->name)) {
37 active = false;
38 emit q->activeChanged();
39 }
40}
41
42void QWaylandClientExtension::initialize()
43{
44 Q_D(QWaylandClientExtension);
45 if (d->active) {
46 return;
47 }
48 const QtWaylandClient::QWaylandDisplay *display = d->waylandIntegration->display();
49 const auto globals = display->globals();
50 auto global =
51 std::find_if(first: globals.cbegin(), last: globals.cend(), pred: [this](const RegistryGlobal &global) {
52 return global.interface == QLatin1String(extensionInterface()->name);
53 });
54 if (global != globals.cend()) {
55 bind(registry: global->registry, id: global->id, version: global->version);
56 d->active = true;
57 emit activeChanged();
58 }
59}
60
61QWaylandClientExtension::QWaylandClientExtension(const int ver)
62 : QObject(*new QWaylandClientExtensionPrivate())
63{
64 Q_D(QWaylandClientExtension);
65 d->version = ver;
66 auto display = d->waylandIntegration->display();
67 QObjectPrivate::connect(sender: display, signal: &QtWaylandClient::QWaylandDisplay::globalAdded, receiverPrivate: d,
68 slot: &QWaylandClientExtensionPrivate::globalAdded);
69 QObjectPrivate::connect(sender: display, signal: &QtWaylandClient::QWaylandDisplay::globalRemoved, receiverPrivate: d,
70 slot: &QWaylandClientExtensionPrivate::globalRemoved);
71 // This function uses virtual functions and we don't want it to be called from the constructor.
72 QMetaObject::invokeMethod(obj: this, member: "initialize", c: Qt::QueuedConnection);
73}
74
75QWaylandClientExtension::~QWaylandClientExtension()
76{
77}
78
79QtWaylandClient::QWaylandIntegration *QWaylandClientExtension::integration() const
80{
81 Q_D(const QWaylandClientExtension);
82 return d->waylandIntegration;
83}
84
85int QWaylandClientExtension::version() const
86{
87 Q_D(const QWaylandClientExtension);
88 return d->version;
89}
90
91void QWaylandClientExtension::setVersion(const int ver)
92{
93 Q_D(QWaylandClientExtension);
94 if (d->version != ver) {
95 d->version = ver;
96 emit versionChanged();
97 }
98}
99
100bool QWaylandClientExtension::isActive() const
101{
102 Q_D(const QWaylandClientExtension);
103 return d->active;
104}
105
106QT_END_NAMESPACE
107
108#include "moc_qwaylandclientextension.cpp"
109

source code of qtwayland/src/client/global/qwaylandclientextension.cpp