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"