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"