File indexing completed on 2024-06-23 05:29:34

0001 /*
0002     SPDX-FileCopyrightText: 2018 Roman Gilg <subdiff@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "kwin_wl_device.h"
0008 
0009 #include <QDBusConnection>
0010 #include <QDBusError>
0011 #include <QDBusMessage>
0012 #include <QDBusReply>
0013 #include <QList>
0014 
0015 #include "logging.h"
0016 
0017 namespace
0018 {
0019 template<typename T>
0020 T valueLoaderPart(QVariant const &reply)
0021 {
0022     return reply.value<T>();
0023 }
0024 
0025 template<>
0026 Qt::MouseButtons valueLoaderPart(QVariant const &reply)
0027 {
0028     return static_cast<Qt::MouseButtons>(reply.toInt());
0029 }
0030 
0031 }
0032 
0033 KWinWaylandDevice::KWinWaylandDevice(const QString &dbusName)
0034     : m_dbusName(dbusName)
0035 {
0036 }
0037 
0038 KWinWaylandDevice::~KWinWaylandDevice()
0039 {
0040 }
0041 
0042 bool KWinWaylandDevice::init()
0043 {
0044     bool success = true;
0045 
0046     auto message = QDBusMessage::createMethodCall(QStringLiteral("org.kde.KWin"),
0047                                                   QStringLiteral("/org/kde/KWin/InputDevice/") + m_dbusName,
0048                                                   QStringLiteral("org.freedesktop.DBus.Properties"),
0049                                                   QStringLiteral("GetAll"));
0050     message << QStringLiteral("org.kde.KWin.InputDevice");
0051     QDBusReply<QVariantMap> reply = QDBusConnection::sessionBus().call(message);
0052 
0053     if (!reply.isValid()) {
0054         return false;
0055     }
0056 
0057     auto valueLoader = [properties = reply.value(), this](auto &prop) {
0058         if (QVariant variant = properties.value(prop.dbus); variant.isValid()) {
0059             prop.avail = true;
0060             prop.old = valueLoaderPart<typename std::remove_reference_t<decltype(prop)>::value_type>(variant);
0061             prop.val = prop.old;
0062             return true;
0063         }
0064         qCCritical(KCM_MOUSE) << "Device" << m_dbusName << "does not have property on d-bus read of" << prop.dbus;
0065         prop.avail = false;
0066         return false;
0067     };
0068 
0069     // general
0070     success &= valueLoader(m_name);
0071     success &= valueLoader(m_sysName);
0072     success &= valueLoader(m_supportsDisableEvents);
0073     success &= valueLoader(m_enabled);
0074     // advanced
0075     success &= valueLoader(m_supportedButtons);
0076     success &= valueLoader(m_supportsLeftHanded);
0077     success &= valueLoader(m_leftHandedEnabledByDefault);
0078     success &= valueLoader(m_leftHanded);
0079     success &= valueLoader(m_supportsMiddleEmulation);
0080     success &= valueLoader(m_middleEmulationEnabledByDefault);
0081     success &= valueLoader(m_middleEmulation);
0082     // acceleration
0083     success &= valueLoader(m_supportsPointerAcceleration);
0084     success &= valueLoader(m_supportsPointerAccelerationProfileFlat);
0085     success &= valueLoader(m_supportsPointerAccelerationProfileAdaptive);
0086     success &= valueLoader(m_defaultPointerAcceleration);
0087     success &= valueLoader(m_defaultPointerAccelerationProfileFlat);
0088     success &= valueLoader(m_defaultPointerAccelerationProfileAdaptive);
0089     success &= valueLoader(m_pointerAcceleration);
0090     success &= valueLoader(m_pointerAccelerationProfileFlat);
0091     success &= valueLoader(m_pointerAccelerationProfileAdaptive);
0092     // natural scroll
0093     success &= valueLoader(m_supportsNaturalScroll);
0094     success &= valueLoader(m_naturalScrollEnabledByDefault);
0095     success &= valueLoader(m_naturalScroll);
0096 
0097     success &= valueLoader(m_scrollFactor);
0098 
0099     return success;
0100 }
0101 
0102 bool KWinWaylandDevice::getDefaultConfig()
0103 {
0104     m_enabled.set(true);
0105     m_leftHanded.set(false);
0106 
0107     m_pointerAcceleration.set(m_defaultPointerAcceleration);
0108     m_pointerAccelerationProfileFlat.set(m_defaultPointerAccelerationProfileFlat);
0109     m_pointerAccelerationProfileAdaptive.set(m_defaultPointerAccelerationProfileAdaptive);
0110 
0111     m_middleEmulation.set(m_middleEmulationEnabledByDefault);
0112     m_naturalScroll.set(m_naturalScrollEnabledByDefault);
0113 
0114     m_scrollFactor.set(1.0);
0115 
0116     return true;
0117 }
0118 
0119 bool KWinWaylandDevice::applyConfig()
0120 {
0121     QList<QString> msgs;
0122 
0123     msgs << valueWriter(m_enabled) << valueWriter(m_leftHanded) << valueWriter(m_pointerAcceleration) << valueWriter(m_pointerAccelerationProfileFlat)
0124          << valueWriter(m_pointerAccelerationProfileAdaptive) << valueWriter(m_middleEmulation) << valueWriter(m_naturalScroll) << valueWriter(m_scrollFactor);
0125     bool success = true;
0126     QString error_msg;
0127 
0128     for (QString m : msgs) {
0129         if (!m.isNull()) {
0130             qCCritical(KCM_MOUSE) << "in error:" << m;
0131             if (!success) {
0132                 error_msg.append("\n");
0133             }
0134             error_msg.append(m);
0135             success = false;
0136         }
0137     }
0138 
0139     if (!success) {
0140         qCCritical(KCM_MOUSE) << error_msg;
0141     }
0142     return success;
0143 }
0144 
0145 bool KWinWaylandDevice::isChangedConfig() const
0146 {
0147     return m_enabled.changed() || m_leftHanded.changed() || m_pointerAcceleration.changed() || m_pointerAccelerationProfileFlat.changed()
0148         || m_pointerAccelerationProfileAdaptive.changed() || m_middleEmulation.changed() || m_scrollFactor.changed() || m_naturalScroll.changed();
0149 }
0150 
0151 template<typename T>
0152 QString KWinWaylandDevice::valueWriter(const Prop<T> &prop)
0153 {
0154     if (!prop.changed()) {
0155         return QString();
0156     }
0157     auto message = QDBusMessage::createMethodCall(QStringLiteral("org.kde.KWin"),
0158                                                   QStringLiteral("/org/kde/KWin/InputDevice/") + m_dbusName,
0159                                                   QStringLiteral("org.freedesktop.DBus.Properties"),
0160                                                   QStringLiteral("Set"));
0161     message << QStringLiteral("org.kde.KWin.InputDevice") << prop.dbus << QVariant::fromValue(QDBusVariant(prop.val));
0162     QDBusReply<void> reply = QDBusConnection::sessionBus().call(message);
0163     if (reply.error().isValid()) {
0164         qCCritical(KCM_MOUSE) << reply.error().message();
0165         return reply.error().message();
0166     }
0167     return QString();
0168 }