File indexing completed on 2024-05-05 03:56:28

0001 /*
0002  *  SPDX-FileCopyrightText: 2018 Marco Martin <mart@kde.org>
0003  *  SPDX-FileCopyrightText: 2021 Arjen Hiemstra <ahiemstra@heimr.nl>
0004  *  SPDX-FileCopyrightText: 2023 Harald Sitter <sitter@kde.org>
0005  *
0006  *  SPDX-License-Identifier: LGPL-2.0-or-later
0007  */
0008 
0009 #include "virtualkeyboardwatcher.h"
0010 
0011 #ifdef KIRIGAMI_ENABLE_DBUS
0012 #include "settings_interface.h"
0013 #include <QDBusConnection>
0014 #include <QDBusPendingCallWatcher>
0015 #endif
0016 
0017 #include "kirigamiplatform_logging.h"
0018 
0019 using namespace Qt::Literals::StringLiterals;
0020 
0021 namespace Kirigami
0022 {
0023 namespace Platform
0024 {
0025 Q_GLOBAL_STATIC(VirtualKeyboardWatcher, virtualKeyboardWatcherSelf)
0026 
0027 class KIRIGAMIPLATFORM_NO_EXPORT VirtualKeyboardWatcher::Private
0028 {
0029     static constexpr auto serviceName = "org.freedesktop.portal.Desktop"_L1;
0030     static constexpr auto objectName = "/org/freedesktop/portal/desktop"_L1;
0031     static constexpr auto interfaceName = "org.kde.kwin.VirtualKeyboard"_L1;
0032 
0033     static constexpr auto GROUP = "org.kde.VirtualKeyboard"_L1;
0034     static constexpr auto KEY_AVAILABLE = "available"_L1;
0035     static constexpr auto KEY_ENABLED = "enabled"_L1;
0036     static constexpr auto KEY_ACTIVE = "active"_L1;
0037     static constexpr auto KEY_VISIBLE = "visible"_L1;
0038     static constexpr auto KEY_WILL_SHOW_ON_ACTIVE = "willShowOnActive"_L1;
0039 
0040 public:
0041     Private(VirtualKeyboardWatcher *qq)
0042         : q(qq)
0043     {
0044 #ifdef KIRIGAMI_ENABLE_DBUS
0045         qDBusRegisterMetaType<VariantMapMap>();
0046         settingsInterface = new OrgFreedesktopPortalSettingsInterface(serviceName, objectName, QDBusConnection::sessionBus(), q);
0047 
0048         QObject::connect(settingsInterface,
0049                          &OrgFreedesktopPortalSettingsInterface::SettingChanged,
0050                          q,
0051                          [this](const QString &group, const QString &key, const QDBusVariant &value) {
0052                              if (group != GROUP) {
0053                                  return;
0054                              }
0055 
0056                              if (key == KEY_AVAILABLE) {
0057                                  available = value.variant().toBool();
0058                                  Q_EMIT q->availableChanged();
0059                              } else if (key == KEY_ENABLED) {
0060                                  enabled = value.variant().toBool();
0061                                  Q_EMIT q->enabledChanged();
0062                              } else if (key == KEY_ACTIVE) {
0063                                  active = value.variant().toBool();
0064                                  Q_EMIT q->activeChanged();
0065                              } else if (key == KEY_VISIBLE) {
0066                                  visible = value.variant().toBool();
0067                                  Q_EMIT q->visibleChanged();
0068                              } else if (key == KEY_WILL_SHOW_ON_ACTIVE) {
0069                                  willShowOnActive = value.variant().toBool();
0070                              }
0071                          });
0072 
0073         getAllProperties();
0074 #endif
0075     }
0076 
0077     VirtualKeyboardWatcher *q;
0078 
0079 #ifdef KIRIGAMI_ENABLE_DBUS
0080     void getAllProperties();
0081     void updateWillShowOnActive();
0082 
0083     OrgFreedesktopPortalSettingsInterface *settingsInterface = nullptr;
0084 
0085     QDBusPendingCallWatcher *willShowOnActiveCall = nullptr;
0086 #endif
0087 
0088     bool available = false;
0089     bool enabled = false;
0090     bool active = false;
0091     bool visible = false;
0092     bool willShowOnActive = false;
0093 };
0094 
0095 VirtualKeyboardWatcher::VirtualKeyboardWatcher(QObject *parent)
0096     : QObject(parent)
0097     , d(std::make_unique<Private>(this))
0098 {
0099 }
0100 
0101 VirtualKeyboardWatcher::~VirtualKeyboardWatcher() = default;
0102 
0103 bool VirtualKeyboardWatcher::available() const
0104 {
0105     return d->available;
0106 }
0107 
0108 bool VirtualKeyboardWatcher::enabled() const
0109 {
0110     return d->enabled;
0111 }
0112 
0113 bool VirtualKeyboardWatcher::active() const
0114 {
0115     return d->active;
0116 }
0117 
0118 bool VirtualKeyboardWatcher::visible() const
0119 {
0120     return d->visible;
0121 }
0122 
0123 bool VirtualKeyboardWatcher::willShowOnActive() const
0124 {
0125 #ifdef KIRIGAMI_ENABLE_DBUS
0126     d->updateWillShowOnActive();
0127 #endif
0128     return d->willShowOnActive;
0129 }
0130 
0131 VirtualKeyboardWatcher *VirtualKeyboardWatcher::self()
0132 {
0133     return virtualKeyboardWatcherSelf();
0134 }
0135 
0136 #ifdef KIRIGAMI_ENABLE_DBUS
0137 
0138 void VirtualKeyboardWatcher::Private::updateWillShowOnActive()
0139 {
0140     if (willShowOnActiveCall) {
0141         return;
0142     }
0143 
0144     willShowOnActiveCall = new QDBusPendingCallWatcher(settingsInterface->Read(GROUP, KEY_WILL_SHOW_ON_ACTIVE), q);
0145     connect(willShowOnActiveCall, &QDBusPendingCallWatcher::finished, q, [this](auto call) {
0146         QDBusPendingReply<bool> reply = *call;
0147         if (reply.isError()) {
0148             qCDebug(KirigamiPlatform) << reply.error().message();
0149         } else {
0150             if (reply.value() != willShowOnActive) {
0151                 willShowOnActive = reply.value();
0152                 Q_EMIT q->willShowOnActiveChanged();
0153             }
0154         }
0155         call->deleteLater();
0156         willShowOnActiveCall = nullptr;
0157     });
0158 }
0159 
0160 void VirtualKeyboardWatcher::Private::getAllProperties()
0161 {
0162     auto call = new QDBusPendingCallWatcher(settingsInterface->ReadAll({GROUP}), q);
0163     connect(call, &QDBusPendingCallWatcher::finished, q, [this](auto call) {
0164         QDBusPendingReply<VariantMapMap> reply = *call;
0165         if (reply.isError()) {
0166             qCDebug(KirigamiPlatform) << reply.error().message();
0167         } else {
0168             const auto groupValues = reply.value().value(GROUP);
0169             available = groupValues.value(KEY_AVAILABLE).toBool();
0170             enabled = groupValues.value(KEY_ENABLED).toBool();
0171             active = groupValues.value(KEY_ACTIVE).toBool();
0172             visible = groupValues.value(KEY_VISIBLE).toBool();
0173             willShowOnActive = groupValues.value(KEY_WILL_SHOW_ON_ACTIVE).toBool();
0174         }
0175         call->deleteLater();
0176 
0177         Q_EMIT q->availableChanged();
0178         Q_EMIT q->enabledChanged();
0179         Q_EMIT q->activeChanged();
0180         Q_EMIT q->visibleChanged();
0181     });
0182 }
0183 
0184 #endif
0185 
0186 }
0187 }
0188 
0189 #include "moc_virtualkeyboardwatcher.cpp"