File indexing completed on 2024-05-12 15:42:39

0001 /*
0002  *  SPDX-FileCopyrightText: 2018 Marco Martin <mart@kde.org>
0003  *  SPDX-FileCopyrightText: 2021 Arjen Hiemstra <ahiemstra@heimr.nl>
0004  *
0005  *  SPDX-License-Identifier: LGPL-2.0-or-later
0006  */
0007 
0008 #include "virtualkeyboardwatcher.h"
0009 
0010 #ifdef KIRIGAMI_ENABLE_DBUS
0011 #include "virtualkeyboard_interface.h"
0012 #include <QDBusConnection>
0013 #include <QDBusPendingCallWatcher>
0014 #endif
0015 
0016 #include "loggingcategory.h"
0017 
0018 namespace Kirigami
0019 {
0020 Q_GLOBAL_STATIC(VirtualKeyboardWatcher, virtualKeyboardWatcherSelf)
0021 
0022 class Q_DECL_HIDDEN VirtualKeyboardWatcher::Private
0023 {
0024 public:
0025     Private(VirtualKeyboardWatcher *qq)
0026         : q(qq)
0027     {
0028     }
0029 
0030     VirtualKeyboardWatcher *q;
0031 
0032 #ifdef KIRIGAMI_ENABLE_DBUS
0033     void getAllProperties();
0034     void getProperty(const QString &propertyName);
0035     void updateWillShowOnActive();
0036 
0037     OrgKdeKwinVirtualKeyboardInterface *keyboardInterface = nullptr;
0038     OrgFreedesktopDBusPropertiesInterface *propertiesInterface = nullptr;
0039 
0040     QDBusPendingCallWatcher *willShowOnActiveCall = nullptr;
0041 #endif
0042 
0043     bool available = false;
0044     bool enabled = false;
0045     bool active = false;
0046     bool visible = false;
0047     bool willShowOnActive = false;
0048 
0049     static const QString serviceName;
0050     static const QString objectName;
0051     static const QString interfaceName;
0052 };
0053 
0054 const QString VirtualKeyboardWatcher::Private::serviceName = QStringLiteral("org.kde.KWin");
0055 const QString VirtualKeyboardWatcher::Private::objectName = QStringLiteral("/VirtualKeyboard");
0056 const QString VirtualKeyboardWatcher::Private::interfaceName = QStringLiteral("org.kde.kwin.VirtualKeyboard");
0057 
0058 VirtualKeyboardWatcher::VirtualKeyboardWatcher(QObject *parent)
0059     : QObject(parent)
0060     , d(std::make_unique<Private>(this))
0061 {
0062 #ifdef KIRIGAMI_ENABLE_DBUS
0063     d->keyboardInterface = new OrgKdeKwinVirtualKeyboardInterface(Private::serviceName, Private::objectName, QDBusConnection::sessionBus(), this);
0064     d->propertiesInterface = new OrgFreedesktopDBusPropertiesInterface(Private::serviceName, Private::objectName, QDBusConnection::sessionBus(), this);
0065 
0066     connect(d->keyboardInterface, &OrgKdeKwinVirtualKeyboardInterface::availableChanged, this, [this]() {
0067         d->getProperty(QStringLiteral("available"));
0068     });
0069     connect(d->keyboardInterface, &OrgKdeKwinVirtualKeyboardInterface::enabledChanged, this, [this]() {
0070         d->getProperty(QStringLiteral("enabled"));
0071     });
0072     connect(d->keyboardInterface, &OrgKdeKwinVirtualKeyboardInterface::activeChanged, this, [this]() {
0073         d->getProperty(QStringLiteral("active"));
0074     });
0075     connect(d->keyboardInterface, &OrgKdeKwinVirtualKeyboardInterface::visibleChanged, this, [this]() {
0076         d->getProperty(QStringLiteral("visible"));
0077     });
0078 
0079     d->getAllProperties();
0080 #endif
0081 }
0082 
0083 VirtualKeyboardWatcher::~VirtualKeyboardWatcher() = default;
0084 
0085 bool VirtualKeyboardWatcher::available() const
0086 {
0087     return d->available;
0088 }
0089 
0090 bool VirtualKeyboardWatcher::enabled() const
0091 {
0092     return d->enabled;
0093 }
0094 
0095 void VirtualKeyboardWatcher::setEnabled(bool newEnabled)
0096 {
0097     if (newEnabled == d->enabled) {
0098         return;
0099     }
0100 
0101     d->enabled = newEnabled;
0102 
0103 #ifdef KIRIGAMI_ENABLE_DBUS
0104     d->propertiesInterface->Set(Private::interfaceName, QStringLiteral("enabled"), QDBusVariant(newEnabled));
0105 #else
0106     Q_EMIT enabledChanged();
0107 #endif
0108 }
0109 
0110 bool VirtualKeyboardWatcher::active() const
0111 {
0112     return d->active;
0113 }
0114 
0115 void VirtualKeyboardWatcher::setActive(bool newActive)
0116 {
0117     if (newActive == d->active) {
0118         return;
0119     }
0120 
0121     d->active = newActive;
0122 
0123 #ifdef KIRIGAMI_ENABLE_DBUS
0124     d->propertiesInterface->Set(Private::interfaceName, QStringLiteral("active"), QDBusVariant(newActive));
0125 #else
0126     Q_EMIT activeChanged();
0127 #endif
0128 }
0129 
0130 bool VirtualKeyboardWatcher::visible() const
0131 {
0132     return d->visible;
0133 }
0134 
0135 bool VirtualKeyboardWatcher::willShowOnActive() const
0136 {
0137 #ifdef KIRIGAMI_ENABLE_DBUS
0138     d->updateWillShowOnActive();
0139 #endif
0140     return d->willShowOnActive;
0141 }
0142 
0143 VirtualKeyboardWatcher *VirtualKeyboardWatcher::self()
0144 {
0145     return virtualKeyboardWatcherSelf();
0146 }
0147 
0148 #ifdef KIRIGAMI_ENABLE_DBUS
0149 
0150 void VirtualKeyboardWatcher::Private::updateWillShowOnActive()
0151 {
0152     if (willShowOnActiveCall) {
0153         return;
0154     }
0155 
0156     willShowOnActiveCall = new QDBusPendingCallWatcher(keyboardInterface->willShowOnActive(), q);
0157     connect(willShowOnActiveCall, &QDBusPendingCallWatcher::finished, q, [this](auto call) {
0158         QDBusPendingReply<bool> reply = *call;
0159         if (reply.isError()) {
0160             qCDebug(KirigamiLog) << reply.error().message();
0161         } else {
0162             if (reply.value() != willShowOnActive) {
0163                 willShowOnActive = reply.value();
0164                 Q_EMIT q->willShowOnActiveChanged();
0165             }
0166         }
0167         call->deleteLater();
0168         willShowOnActiveCall = nullptr;
0169     });
0170 }
0171 
0172 void VirtualKeyboardWatcher::Private::getAllProperties()
0173 {
0174     auto call = new QDBusPendingCallWatcher(propertiesInterface->GetAll(interfaceName), q);
0175     connect(call, &QDBusPendingCallWatcher::finished, q, [this](auto call) {
0176         QDBusPendingReply<QVariantMap> reply = *call;
0177         if (reply.isError()) {
0178             qCDebug(KirigamiLog) << reply.error().message();
0179         } else {
0180             auto value = reply.value();
0181             available = value.value(QStringLiteral("available")).toBool();
0182             enabled = value.value(QStringLiteral("enabled")).toBool();
0183             active = value.value(QStringLiteral("active")).toBool();
0184             visible = value.value(QStringLiteral("visible")).toBool();
0185         }
0186         call->deleteLater();
0187 
0188         Q_EMIT q->availableChanged();
0189         Q_EMIT q->enabledChanged();
0190         Q_EMIT q->activeChanged();
0191         Q_EMIT q->visibleChanged();
0192     });
0193 }
0194 
0195 void VirtualKeyboardWatcher::Private::getProperty(const QString &propertyName)
0196 {
0197     auto call = new QDBusPendingCallWatcher(propertiesInterface->Get(interfaceName, propertyName), q);
0198     connect(call, &QDBusPendingCallWatcher::finished, q, [this, propertyName](auto call) {
0199         QDBusPendingReply<QDBusVariant> reply = *call;
0200         if (reply.isError()) {
0201             qCDebug(KirigamiLog) << reply.error().message();
0202         } else {
0203             auto value = reply.value();
0204             if (propertyName == QStringLiteral("available")) {
0205                 available = value.variant().toBool();
0206                 Q_EMIT q->availableChanged();
0207             } else if (propertyName == QStringLiteral("enabled")) {
0208                 enabled = value.variant().toBool();
0209                 Q_EMIT q->enabledChanged();
0210             } else if (propertyName == QStringLiteral("active")) {
0211                 active = value.variant().toBool();
0212                 Q_EMIT q->activeChanged();
0213             } else if (propertyName == QStringLiteral("visible")) {
0214                 visible = value.variant().toBool();
0215                 Q_EMIT q->visibleChanged();
0216             }
0217         }
0218         call->deleteLater();
0219     });
0220 }
0221 
0222 #endif
0223 }
0224 
0225 #include "moc_virtualkeyboardwatcher.cpp"