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 "kwinwaylandbackend.h" 0008 #include "kwinwaylandtouchpad.h" 0009 0010 #include <algorithm> 0011 0012 #include <KLocalizedString> 0013 0014 #include <QDBusInterface> 0015 #include <QDBusMessage> 0016 #include <QDBusReply> 0017 #include <QStringList> 0018 0019 #include "logging.h" 0020 0021 KWinWaylandBackend::KWinWaylandBackend(QObject *parent) 0022 : TouchpadBackend(parent) 0023 { 0024 m_deviceManager = new QDBusInterface(QStringLiteral("org.kde.KWin"), 0025 QStringLiteral("/org/kde/KWin/InputDevice"), 0026 QStringLiteral("org.kde.KWin.InputDeviceManager"), 0027 QDBusConnection::sessionBus(), 0028 this); 0029 0030 setMode(TouchpadInputBackendMode::WaylandLibinput); 0031 0032 findTouchpads(); 0033 0034 m_deviceManager->connection().connect(QStringLiteral("org.kde.KWin"), 0035 QStringLiteral("/org/kde/KWin/InputDevice"), 0036 QStringLiteral("org.kde.KWin.InputDeviceManager"), 0037 QStringLiteral("deviceAdded"), 0038 this, 0039 SLOT(onDeviceAdded(QString))); 0040 m_deviceManager->connection().connect(QStringLiteral("org.kde.KWin"), 0041 QStringLiteral("/org/kde/KWin/InputDevice"), 0042 QStringLiteral("org.kde.KWin.InputDeviceManager"), 0043 QStringLiteral("deviceRemoved"), 0044 this, 0045 SLOT(onDeviceRemoved(QString))); 0046 } 0047 0048 KWinWaylandBackend::~KWinWaylandBackend() 0049 { 0050 qDeleteAll(m_devices); 0051 delete m_deviceManager; 0052 } 0053 0054 void KWinWaylandBackend::findTouchpads() 0055 { 0056 const QVariant reply = m_deviceManager->property("devicesSysNames"); 0057 if (!reply.isValid()) { 0058 qCCritical(KCM_TOUCHPAD) << "Error on receiving device list from KWin."; 0059 m_errorString = i18n("Querying input devices failed. Please reopen this settings module."); 0060 return; 0061 } 0062 const auto devicesSysNames = reply.toStringList(); 0063 for (const QString &sn : devicesSysNames) { 0064 QDBusInterface deviceIface(QStringLiteral("org.kde.KWin"), 0065 QStringLiteral("/org/kde/KWin/InputDevice/") + sn, 0066 QStringLiteral("org.kde.KWin.InputDevice"), 0067 QDBusConnection::sessionBus(), 0068 this); 0069 const QVariant reply = deviceIface.property("touchpad"); 0070 if (reply.isValid() && reply.toBool()) { 0071 KWinWaylandTouchpad *tp = new KWinWaylandTouchpad(sn); 0072 if (!tp->init() || !tp->getConfig()) { 0073 qCCritical(KCM_TOUCHPAD) << "Error on creating touchpad object" << sn; 0074 m_errorString = i18n("Critical error on reading fundamental device infos for touchpad %1.", sn); 0075 return; 0076 } 0077 m_devices.append(tp); 0078 qCInfo(KCM_TOUCHPAD).nospace() << "Touchpad found: " << tp->name() << " (" << tp->sysName() << ")"; 0079 } 0080 } 0081 if (m_devices.isEmpty()) { 0082 qCInfo(KCM_TOUCHPAD) << "No Devices found."; 0083 } 0084 } 0085 0086 bool KWinWaylandBackend::applyConfig() 0087 { 0088 return std::all_of(m_devices.constBegin(), m_devices.constEnd(), [](QObject *t) { 0089 return static_cast<KWinWaylandTouchpad *>(t)->applyConfig(); 0090 }); 0091 } 0092 0093 bool KWinWaylandBackend::getConfig() 0094 { 0095 return std::all_of(m_devices.constBegin(), m_devices.constEnd(), [](QObject *t) { 0096 return static_cast<KWinWaylandTouchpad *>(t)->getConfig(); 0097 }); 0098 } 0099 0100 bool KWinWaylandBackend::getDefaultConfig() 0101 { 0102 return std::all_of(m_devices.constBegin(), m_devices.constEnd(), [](QObject *t) { 0103 return static_cast<KWinWaylandTouchpad *>(t)->getDefaultConfig(); 0104 }); 0105 } 0106 0107 bool KWinWaylandBackend::isChangedConfig() const 0108 { 0109 return std::any_of(m_devices.constBegin(), m_devices.constEnd(), [](QObject *t) { 0110 return static_cast<KWinWaylandTouchpad *>(t)->isChangedConfig(); 0111 }); 0112 } 0113 0114 void KWinWaylandBackend::onDeviceAdded(QString sysName) 0115 { 0116 if (std::any_of(m_devices.constBegin(), m_devices.constEnd(), [sysName](QObject *t) { 0117 return static_cast<KWinWaylandTouchpad *>(t)->sysName() == sysName; 0118 })) { 0119 return; 0120 } 0121 0122 QDBusInterface deviceIface(QStringLiteral("org.kde.KWin"), 0123 QStringLiteral("/org/kde/KWin/InputDevice/") + sysName, 0124 QStringLiteral("org.kde.KWin.InputDevice"), 0125 QDBusConnection::sessionBus(), 0126 this); 0127 QVariant reply = deviceIface.property("touchpad"); 0128 if (reply.isValid() && reply.toBool()) { 0129 KWinWaylandTouchpad *tp = new KWinWaylandTouchpad(sysName); 0130 if (!tp->init() || !tp->getConfig()) { 0131 Q_EMIT touchpadAdded(false); 0132 return; 0133 } 0134 m_devices.append(tp); 0135 qCDebug(KCM_TOUCHPAD).nospace() << "Touchpad connected: " << tp->name() << " (" << tp->sysName() << ")"; 0136 Q_EMIT touchpadAdded(true); 0137 } 0138 } 0139 0140 void KWinWaylandBackend::onDeviceRemoved(QString sysName) 0141 { 0142 QList<QObject *>::const_iterator it = std::find_if(m_devices.constBegin(), m_devices.constEnd(), [sysName](QObject *t) { 0143 return static_cast<KWinWaylandTouchpad *>(t)->sysName() == sysName; 0144 }); 0145 if (it == m_devices.cend()) { 0146 return; 0147 } 0148 0149 KWinWaylandTouchpad *tp = static_cast<KWinWaylandTouchpad *>(*it); 0150 qCDebug(KCM_TOUCHPAD).nospace() << "Touchpad disconnected: " << tp->name() << " (" << tp->sysName() << ")"; 0151 0152 int index = it - m_devices.cbegin(); 0153 m_devices.removeAt(index); 0154 Q_EMIT touchpadRemoved(index); 0155 }