SPDX-FileCopyrightText: 2018 Roman Gilg <subdiff@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "kwin_wl_device.h"
#include <QDBusConnection>
#include <QDBusError>
#include <QDBusMessage>
#include <QDBusReply>
#include <QVector>
#include "logging.h"
namespace
{
template<typename T>
T valueLoaderPart(QVariant const &reply)
{
return reply.value<T>();
}
template<>
Qt::MouseButtons valueLoaderPart(QVariant const &reply)
{
return static_cast<Qt::MouseButtons>(reply.toInt());
}
}
KWinWaylandDevice::KWinWaylandDevice(const QString &dbusName)
: m_dbusName(dbusName)
{
}
KWinWaylandDevice::~KWinWaylandDevice()
{
}
bool KWinWaylandDevice::init()
{
bool success = true;
auto message = QDBusMessage::createMethodCall(QStringLiteral("org.kde.KWin"),
QStringLiteral("/org/kde/KWin/InputDevice/") + m_dbusName,
QStringLiteral("org.freedesktop.DBus.Properties"),
QStringLiteral("GetAll"));
message << QStringLiteral("org.kde.KWin.InputDevice");
QDBusReply<QVariantMap> reply = QDBusConnection::sessionBus().call(message);
if (!reply.isValid()) {
return false;
}
auto valueLoader = [properties = reply.value(), this](auto &prop) {
if (QVariant variant = properties.value(prop.dbus); variant.isValid()) {
prop.avail = true;
prop.old = valueLoaderPart<typename std::remove_reference_t<decltype(prop)>::value_type>(variant);
prop.val = prop.old;
return true;
}
qCCritical(KCM_MOUSE) << "Device" << m_dbusName << "does not have property on d-bus read of" << prop.dbus;
prop.avail = false;
return false;
};
success &= valueLoader(m_name);
success &= valueLoader(m_sysName);
success &= valueLoader(m_supportsDisableEvents);
success &= valueLoader(m_enabled);
success &= valueLoader(m_supportedButtons);
success &= valueLoader(m_supportsLeftHanded);
success &= valueLoader(m_leftHandedEnabledByDefault);
success &= valueLoader(m_leftHanded);
success &= valueLoader(m_supportsMiddleEmulation);
success &= valueLoader(m_middleEmulationEnabledByDefault);
success &= valueLoader(m_middleEmulation);
success &= valueLoader(m_supportsPointerAcceleration);
success &= valueLoader(m_supportsPointerAccelerationProfileFlat);
success &= valueLoader(m_supportsPointerAccelerationProfileAdaptive);
success &= valueLoader(m_defaultPointerAcceleration);
success &= valueLoader(m_defaultPointerAccelerationProfileFlat);
success &= valueLoader(m_defaultPointerAccelerationProfileAdaptive);
success &= valueLoader(m_pointerAcceleration);
success &= valueLoader(m_pointerAccelerationProfileFlat);
success &= valueLoader(m_pointerAccelerationProfileAdaptive);
success &= valueLoader(m_supportsNaturalScroll);
success &= valueLoader(m_naturalScrollEnabledByDefault);
success &= valueLoader(m_naturalScroll);
success &= valueLoader(m_scrollFactor);
return success;
}
bool KWinWaylandDevice::getDefaultConfig()
{
m_enabled.set(true);
m_leftHanded.set(false);
m_pointerAcceleration.set(m_defaultPointerAcceleration);
m_pointerAccelerationProfileFlat.set(m_defaultPointerAccelerationProfileFlat);
m_pointerAccelerationProfileAdaptive.set(m_defaultPointerAccelerationProfileAdaptive);
m_middleEmulation.set(m_middleEmulationEnabledByDefault);
m_naturalScroll.set(m_naturalScrollEnabledByDefault);
m_scrollFactor.set(1.0);
return true;
}
bool KWinWaylandDevice::applyConfig()
{
QVector<QString> msgs;
msgs << valueWriter(m_enabled) << valueWriter(m_leftHanded) << valueWriter(m_pointerAcceleration) << valueWriter(m_pointerAccelerationProfileFlat)
<< valueWriter(m_pointerAccelerationProfileAdaptive) << valueWriter(m_middleEmulation) << valueWriter(m_naturalScroll) << valueWriter(m_scrollFactor);
bool success = true;
QString error_msg;
for (QString m : msgs) {
if (!m.isNull()) {
qCCritical(KCM_MOUSE) << "in error:" << m;
if (!success) {
error_msg.append("\n");
}
error_msg.append(m);
success = false;
}
}
if (!success) {
qCCritical(KCM_MOUSE) << error_msg;
}
return success;
}
bool KWinWaylandDevice::isChangedConfig() const
{
return m_enabled.changed() || m_leftHanded.changed() || m_pointerAcceleration.changed() || m_pointerAccelerationProfileFlat.changed()
|| m_pointerAccelerationProfileAdaptive.changed() || m_middleEmulation.changed() || m_scrollFactor.changed() || m_naturalScroll.changed();
}
template<typename T>
QString KWinWaylandDevice::valueWriter(const Prop<T> &prop)
{
if (!prop.changed()) {
return QString();
}
auto message = QDBusMessage::createMethodCall(QStringLiteral("org.kde.KWin"),
QStringLiteral("/org/kde/KWin/InputDevice/") + m_dbusName,
QStringLiteral("org.freedesktop.DBus.Properties"),
QStringLiteral("Set"));
message << QStringLiteral("org.kde.KWin.InputDevice") << prop.dbus << QVariant::fromValue(QDBusVariant(prop.val));
QDBusReply<void> reply = QDBusConnection::sessionBus().call(message);
if (reply.error().isValid()) {
qCCritical(KCM_MOUSE) << reply.error().message();
return reply.error().message();
}
return QString();
}