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

source code of qtbase/src/plugins/platforms/wayland/global/qwaylandclientextension.cpp