File indexing completed on 2024-11-24 05:00:46

0001 /*
0002     SPDX-FileCopyrightText: 2017 Roman Gilg <subdiff@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "kwinwaylandtouchpad.h"
0008 
0009 #include <QDBusError>
0010 #include <QDBusInterface>
0011 #include <QList>
0012 
0013 #include "logging.h"
0014 
0015 KWinWaylandTouchpad::KWinWaylandTouchpad(QString dbusName)
0016     : LibinputCommon()
0017 {
0018     m_iface = new QDBusInterface(QStringLiteral("org.kde.KWin"),
0019                                  QStringLiteral("/org/kde/KWin/InputDevice/") + dbusName,
0020                                  QStringLiteral("org.kde.KWin.InputDevice"),
0021                                  QDBusConnection::sessionBus(),
0022                                  this);
0023 }
0024 
0025 KWinWaylandTouchpad::~KWinWaylandTouchpad()
0026 {
0027     delete m_iface;
0028 }
0029 
0030 bool KWinWaylandTouchpad::init()
0031 {
0032     // need to do it here in order to populate combobox and handle events
0033     return valueLoader(m_name) && valueLoader(m_sysName);
0034 }
0035 
0036 bool KWinWaylandTouchpad::getConfig()
0037 {
0038     bool success = true;
0039 
0040     // general
0041     success &= valueLoader(m_supportsDisableEvents);
0042     success &= valueLoader(m_supportsLeftHanded);
0043     success &= valueLoader(m_supportedButtons);
0044     success &= valueLoader(m_leftHandedEnabledByDefault);
0045     success &= valueLoader(m_enabled);
0046     success &= valueLoader(m_leftHanded);
0047     // advanced
0048     success &= valueLoader(m_supportsPointerAcceleration);
0049     success &= valueLoader(m_supportsPointerAccelerationProfileFlat);
0050     success &= valueLoader(m_supportsPointerAccelerationProfileAdaptive);
0051     success &= valueLoader(m_supportsDisableWhileTyping);
0052     success &= valueLoader(m_supportsDisableEventsOnExternalMouse);
0053     success &= valueLoader(m_defaultPointerAcceleration);
0054     success &= valueLoader(m_defaultPointerAccelerationProfileFlat);
0055     success &= valueLoader(m_defaultPointerAccelerationProfileAdaptive);
0056     success &= valueLoader(m_disableWhileTypingEnabledByDefault);
0057     success &= valueLoader(m_leftHandedEnabledByDefault);
0058     success &= valueLoader(m_pointerAcceleration);
0059     success &= valueLoader(m_pointerAccelerationProfileFlat);
0060     success &= valueLoader(m_pointerAccelerationProfileAdaptive);
0061     success &= valueLoader(m_disableWhileTyping);
0062     // tapping
0063     success &= valueLoader(m_tapFingerCount);
0064     success &= valueLoader(m_supportsMiddleEmulation);
0065     success &= valueLoader(m_tapToClickEnabledByDefault);
0066     success &= valueLoader(m_tapAndDragEnabledByDefault);
0067     success &= valueLoader(m_tapDragLockEnabledByDefault);
0068     success &= valueLoader(m_middleEmulationEnabledByDefault);
0069     success &= valueLoader(m_tapToClick);
0070     success &= valueLoader(m_tapAndDrag);
0071     success &= valueLoader(m_tapDragLock);
0072     success &= valueLoader(m_middleEmulation);
0073     success &= valueLoader(m_lmrTapButtonMapEnabledByDefault);
0074     success &= valueLoader(m_lmrTapButtonMap);
0075     // scrolling modes avail
0076     success &= valueLoader(m_supportsNaturalScroll);
0077     success &= valueLoader(m_supportsScrollTwoFinger);
0078     success &= valueLoader(m_supportsScrollEdge);
0079     success &= valueLoader(m_supportsScrollOnButtonDown);
0080     // default scrolling modes
0081     success &= valueLoader(m_naturalScrollEnabledByDefault);
0082     success &= valueLoader(m_scrollTwoFingerEnabledByDefault);
0083     success &= valueLoader(m_scrollEdgeEnabledByDefault);
0084     success &= valueLoader(m_scrollOnButtonDownEnabledByDefault);
0085     success &= valueLoader(m_defaultScrollButton);
0086     // current scrolling mode
0087     success &= valueLoader(m_naturalScroll);
0088     success &= valueLoader(m_isScrollTwoFinger);
0089     success &= valueLoader(m_isScrollEdge);
0090     success &= valueLoader(m_isScrollOnButtonDown);
0091     success &= valueLoader(m_scrollButton);
0092     // scroll speed
0093     success &= valueLoader(m_scrollFactor);
0094     // click methods
0095     success &= valueLoader(m_supportsClickMethodAreas);
0096     success &= valueLoader(m_supportsClickMethodClickfinger);
0097     success &= valueLoader(m_defaultClickMethodAreas);
0098     success &= valueLoader(m_defaultClickMethodClickfinger);
0099     success &= valueLoader(m_clickMethodAreas);
0100     success &= valueLoader(m_clickMethodClickfinger);
0101 
0102     return success;
0103 }
0104 
0105 bool KWinWaylandTouchpad::getDefaultConfig()
0106 {
0107     m_enabled.set(true);
0108     m_leftHanded.set(false);
0109 
0110     m_pointerAcceleration.set(m_defaultPointerAcceleration);
0111     m_pointerAccelerationProfileFlat.set(m_defaultPointerAccelerationProfileFlat);
0112     m_pointerAccelerationProfileAdaptive.set(m_defaultPointerAccelerationProfileAdaptive);
0113 
0114     m_disableWhileTyping.set(m_disableWhileTypingEnabledByDefault);
0115 
0116     m_tapToClick.set(m_tapToClickEnabledByDefault);
0117     m_tapAndDrag.set(m_tapAndDragEnabledByDefault);
0118     m_tapDragLock.set(m_tapDragLockEnabledByDefault);
0119     m_middleEmulation.set(m_middleEmulationEnabledByDefault);
0120 
0121     m_naturalScroll.set(m_naturalScrollEnabledByDefault);
0122     m_isScrollTwoFinger.set(m_scrollTwoFingerEnabledByDefault);
0123     m_isScrollEdge.set(m_scrollEdgeEnabledByDefault);
0124     m_isScrollOnButtonDown.set(m_scrollOnButtonDownEnabledByDefault);
0125 
0126     m_clickMethodAreas.set(m_defaultClickMethodAreas);
0127     m_clickMethodClickfinger.set(m_defaultClickMethodClickfinger);
0128     m_scrollFactor.set(1.0);
0129 
0130     return true;
0131 }
0132 
0133 bool KWinWaylandTouchpad::applyConfig()
0134 {
0135     QList<QString> msgs;
0136 
0137     msgs << valueWriter(m_enabled) << valueWriter(m_leftHanded) << valueWriter(m_pointerAcceleration) << valueWriter(m_pointerAccelerationProfileFlat)
0138          << valueWriter(m_pointerAccelerationProfileAdaptive)
0139 
0140          << valueWriter(m_disableWhileTyping) << valueWriter(m_middleEmulation)
0141 
0142          << valueWriter(m_tapToClick) << valueWriter(m_tapAndDrag) << valueWriter(m_tapDragLock) << valueWriter(m_lmrTapButtonMap)
0143 
0144          << valueWriter(m_naturalScroll) << valueWriter(m_isScrollTwoFinger) << valueWriter(m_isScrollEdge) << valueWriter(m_isScrollOnButtonDown)
0145          << valueWriter(m_scrollButton) << valueWriter(m_scrollFactor)
0146 
0147          << valueWriter(m_clickMethodAreas) << valueWriter(m_clickMethodClickfinger);
0148 
0149     bool success = true;
0150     QString error_msg;
0151 
0152     for (const QString &m : std::as_const(msgs)) {
0153         if (!m.isNull()) {
0154             qCCritical(KCM_TOUCHPAD) << "in error:" << m;
0155             if (!success) {
0156                 error_msg.append("\n");
0157             }
0158             error_msg.append(m);
0159             success = false;
0160         }
0161     }
0162 
0163     if (!success) {
0164         qCCritical(KCM_TOUCHPAD) << error_msg;
0165     }
0166     return success;
0167 }
0168 
0169 bool KWinWaylandTouchpad::isChangedConfig() const
0170 {
0171     // clang-format off
0172     return m_enabled.changed() ||
0173             m_leftHanded.changed() ||
0174             m_pointerAcceleration.changed() ||
0175             m_pointerAccelerationProfileFlat.changed() ||
0176             m_pointerAccelerationProfileAdaptive.changed() ||
0177             m_disableWhileTyping.changed() ||
0178             m_middleEmulation.changed() ||
0179             m_tapToClick.changed() ||
0180             m_tapAndDrag.changed() ||
0181             m_tapDragLock.changed() ||
0182             m_lmrTapButtonMap.changed() ||
0183             m_naturalScroll.changed() ||
0184             m_isScrollTwoFinger.changed() ||
0185             m_isScrollEdge.changed() ||
0186             m_isScrollOnButtonDown.changed() ||
0187             m_scrollFactor.changed() ||
0188             m_scrollButton.changed() ||
0189             m_clickMethodAreas.changed() ||
0190             m_clickMethodClickfinger.changed();
0191     // clang-format on
0192 }
0193 
0194 template<typename T>
0195 QString KWinWaylandTouchpad::valueWriter(const Prop<T> &prop)
0196 {
0197     if (!prop.changed()) {
0198         return QString();
0199     }
0200     m_iface->setProperty(prop.name, prop.val);
0201     QDBusError error = m_iface->lastError();
0202     if (error.isValid()) {
0203         qCCritical(KCM_TOUCHPAD) << error.message();
0204         return error.message();
0205     }
0206     return QString();
0207 }
0208 
0209 template<typename T>
0210 bool KWinWaylandTouchpad::valueLoader(Prop<T> &prop)
0211 {
0212     QVariant reply = m_iface->property(prop.name);
0213     if (!reply.isValid()) {
0214         qCCritical(KCM_TOUCHPAD) << "Error on d-bus read of" << prop.name;
0215         prop.avail = false;
0216         return false;
0217     }
0218     prop.avail = true;
0219 
0220     T replyValue = valueLoaderPart<T>(reply);
0221 
0222     prop.old = replyValue;
0223     prop.val = replyValue;
0224     return true;
0225 }