[libinput] Load/store device configuration

Summary:
Device gets a KConfigGroup injected and supports loading device-specific
settings. This is invoked from Libinput::Connection when adding a new
Device.

Whenever a Device option is changed successfully through the DBus
interface it gets synced into the KConfigGroup, thus on next loading of
the Device it gets restored.

The config group follows a pattern of:
[libinput][vendor][product][name]

Thus every device has a specific and persistent configuration.

Test Plan: So far only tested through autotests

Reviewers: #kwin, #plasma_on_wayland

Subscribers: plasma-devel, kwin

Tags: #plasma_on_wayland, #kwin

Differential Revision: https://phabricator.kde.org/D3264
icc-effect-5.14.5
Martin Gräßlin 2016-11-04 15:31:35 +01:00
parent b6af777230
commit de89176cd2
5 changed files with 579 additions and 16 deletions

View File

@ -5,7 +5,7 @@ include_directories(${UDEV_INCLUDE_DIR})
########################################################
set( testLibinputDevice_SRCS device_test.cpp mock_libinput.cpp ../../libinput/device.cpp )
add_executable(testLibinputDevice ${testLibinputDevice_SRCS})
target_link_libraries( testLibinputDevice Qt5::Test Qt5::DBus)
target_link_libraries( testLibinputDevice Qt5::Test Qt5::DBus KF5::ConfigCore)
add_test(kwin-testLibinputDevice testLibinputDevice)
ecm_mark_as_test(testLibinputDevice)
@ -94,6 +94,6 @@ ecm_mark_as_test(testLibinputContext)
########################################################
set( testInputEvents_SRCS input_event_test.cpp mock_libinput.cpp ../../libinput/device.cpp ../../input_event.cpp )
add_executable(testInputEvents ${testInputEvents_SRCS})
target_link_libraries( testInputEvents Qt5::Test Qt5::DBus Qt5::Gui)
target_link_libraries( testInputEvents Qt5::Test Qt5::DBus Qt5::Gui KF5::ConfigCore)
add_test(kwin-testInputEvents testInputEvents)
ecm_mark_as_test(testInputEvents)

View File

@ -21,6 +21,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "../../libinput/device.h"
#include <config-kwin.h>
#include <KSharedConfig>
#include <QtTest/QtTest>
#include <linux/input.h>
@ -111,6 +113,26 @@ private Q_SLOTS:
void testScrollButtonDown();
void testScrollButton_data();
void testScrollButton();
void testLoadEnabled_data();
void testLoadEnabled();
void testLoadTapToClick_data();
void testLoadTapToClick();
void testLoadTapAndDrag_data();
void testLoadTapAndDrag();
void testLoadTapDragLock_data();
void testLoadTapDragLock();
void testLoadMiddleButtonEmulation_data();
void testLoadMiddleButtonEmulation();
void testLoadNaturalScroll_data();
void testLoadNaturalScroll();
void testLoadScrollTwoFinger_data();
void testLoadScrollTwoFinger();
void testLoadScrollEdge_data();
void testLoadScrollEdge();
void testLoadScrollOnButton_data();
void testLoadScrollOnButton();
void testLoadScrollButton_data();
void testLoadScrollButton();
};
void TestLibinputDevice::testStaticGetter()
@ -1257,5 +1279,425 @@ void TestLibinputDevice::testScrollButton()
QCOMPARE(scrollButtonChangedSpy.isEmpty(), initValue == expectedValue);
}
void TestLibinputDevice::testLoadEnabled_data()
{
QTest::addColumn<bool>("initValue");
QTest::addColumn<bool>("configValue");
QTest::newRow("false -> true") << false << true;
QTest::newRow("true -> false") << true << false;
QTest::newRow("true -> true") << true << true;
QTest::newRow("false -> false") << false << false;
}
void TestLibinputDevice::testLoadEnabled()
{
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
KConfigGroup inputConfig(config, QStringLiteral("Test"));
QFETCH(bool, configValue);
QFETCH(bool, initValue);
inputConfig.writeEntry("Enabled", configValue);
libinput_device device;
device.supportsDisableEvents = true;
device.enabled = initValue;
device.setEnableModeReturnValue = false;
Device d(&device);
QCOMPARE(d.isEnabled(), initValue);
// no config group set, should not change
d.loadConfiguration();
QCOMPARE(d.isEnabled(), initValue);
// set the group
d.setConfig(inputConfig);
d.loadConfiguration();
QCOMPARE(d.isEnabled(), configValue);
// and try to store
if (configValue != initValue) {
d.setEnabled(initValue);
QCOMPARE(inputConfig.readEntry("Enabled", configValue), initValue);
}
}
void TestLibinputDevice::testLoadTapToClick_data()
{
QTest::addColumn<bool>("initValue");
QTest::addColumn<bool>("configValue");
QTest::newRow("false -> true") << false << true;
QTest::newRow("true -> false") << true << false;
QTest::newRow("true -> true") << true << true;
QTest::newRow("false -> false") << false << false;
}
void TestLibinputDevice::testLoadTapToClick()
{
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
KConfigGroup inputConfig(config, QStringLiteral("Test"));
QFETCH(bool, configValue);
QFETCH(bool, initValue);
inputConfig.writeEntry("TapToClick", configValue);
libinput_device device;
device.tapFingerCount = 2;
device.tapToClick = initValue;
device.setTapToClickReturnValue = false;
Device d(&device);
QCOMPARE(d.isTapToClick(), initValue);
// no config group set, should not change
d.loadConfiguration();
QCOMPARE(d.isTapToClick(), initValue);
// set the group
d.setConfig(inputConfig);
d.loadConfiguration();
QCOMPARE(d.isTapToClick(), configValue);
// and try to store
if (configValue != initValue) {
d.setTapToClick(initValue);
QCOMPARE(inputConfig.readEntry("TapToClick", configValue), initValue);
}
}
void TestLibinputDevice::testLoadTapAndDrag_data()
{
QTest::addColumn<bool>("initValue");
QTest::addColumn<bool>("configValue");
QTest::newRow("false -> true") << false << true;
QTest::newRow("true -> false") << true << false;
QTest::newRow("true -> true") << true << true;
QTest::newRow("false -> false") << false << false;
}
void TestLibinputDevice::testLoadTapAndDrag()
{
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
KConfigGroup inputConfig(config, QStringLiteral("Test"));
QFETCH(bool, configValue);
QFETCH(bool, initValue);
inputConfig.writeEntry("TapAndDrag", configValue);
libinput_device device;
device.tapAndDrag = initValue;
device.setTapAndDragReturnValue = false;
Device d(&device);
QCOMPARE(d.isTapAndDrag(), initValue);
// no config group set, should not change
d.loadConfiguration();
QCOMPARE(d.isTapAndDrag(), initValue);
// set the group
d.setConfig(inputConfig);
d.loadConfiguration();
QCOMPARE(d.isTapAndDrag(), configValue);
// and try to store
if (configValue != initValue) {
d.setTapAndDrag(initValue);
QCOMPARE(inputConfig.readEntry("TapAndDrag", configValue), initValue);
}
}
void TestLibinputDevice::testLoadTapDragLock_data()
{
QTest::addColumn<bool>("initValue");
QTest::addColumn<bool>("configValue");
QTest::newRow("false -> true") << false << true;
QTest::newRow("true -> false") << true << false;
QTest::newRow("true -> true") << true << true;
QTest::newRow("false -> false") << false << false;
}
void TestLibinputDevice::testLoadTapDragLock()
{
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
KConfigGroup inputConfig(config, QStringLiteral("Test"));
QFETCH(bool, configValue);
QFETCH(bool, initValue);
inputConfig.writeEntry("TapDragLock", configValue);
libinput_device device;
device.tapDragLock = initValue;
device.setTapDragLockReturnValue = false;
Device d(&device);
QCOMPARE(d.isTapDragLock(), initValue);
// no config group set, should not change
d.loadConfiguration();
QCOMPARE(d.isTapDragLock(), initValue);
// set the group
d.setConfig(inputConfig);
d.loadConfiguration();
QCOMPARE(d.isTapDragLock(), configValue);
// and try to store
if (configValue != initValue) {
d.setTapDragLock(initValue);
QCOMPARE(inputConfig.readEntry("TapDragLock", configValue), initValue);
}
}
void TestLibinputDevice::testLoadMiddleButtonEmulation_data()
{
QTest::addColumn<bool>("initValue");
QTest::addColumn<bool>("configValue");
QTest::newRow("false -> true") << false << true;
QTest::newRow("true -> false") << true << false;
QTest::newRow("true -> true") << true << true;
QTest::newRow("false -> false") << false << false;
}
void TestLibinputDevice::testLoadMiddleButtonEmulation()
{
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
KConfigGroup inputConfig(config, QStringLiteral("Test"));
QFETCH(bool, configValue);
QFETCH(bool, initValue);
inputConfig.writeEntry("MiddleButtonEmulation", configValue);
libinput_device device;
device.supportsMiddleEmulation = true;
device.middleEmulation = initValue;
device.setMiddleEmulationReturnValue = false;
Device d(&device);
QCOMPARE(d.isMiddleEmulation(), initValue);
// no config group set, should not change
d.loadConfiguration();
QCOMPARE(d.isMiddleEmulation(), initValue);
// set the group
d.setConfig(inputConfig);
d.loadConfiguration();
QCOMPARE(d.isMiddleEmulation(), configValue);
// and try to store
if (configValue != initValue) {
d.setMiddleEmulation(initValue);
QCOMPARE(inputConfig.readEntry("MiddleButtonEmulation", configValue), initValue);
}
}
void TestLibinputDevice::testLoadNaturalScroll_data()
{
QTest::addColumn<bool>("initValue");
QTest::addColumn<bool>("configValue");
QTest::newRow("false -> true") << false << true;
QTest::newRow("true -> false") << true << false;
QTest::newRow("true -> true") << true << true;
QTest::newRow("false -> false") << false << false;
}
void TestLibinputDevice::testLoadNaturalScroll()
{
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
KConfigGroup inputConfig(config, QStringLiteral("Test"));
QFETCH(bool, configValue);
QFETCH(bool, initValue);
inputConfig.writeEntry("NaturalScroll", configValue);
libinput_device device;
device.supportsNaturalScroll = true;
device.naturalScroll = initValue;
device.setNaturalScrollReturnValue = false;
Device d(&device);
QCOMPARE(d.isNaturalScroll(), initValue);
// no config group set, should not change
d.loadConfiguration();
QCOMPARE(d.isNaturalScroll(), initValue);
// set the group
d.setConfig(inputConfig);
d.loadConfiguration();
QCOMPARE(d.isNaturalScroll(), configValue);
// and try to store
if (configValue != initValue) {
d.setNaturalScroll(initValue);
QCOMPARE(inputConfig.readEntry("NaturalScroll", configValue), initValue);
}
}
void TestLibinputDevice::testLoadScrollTwoFinger_data()
{
QTest::addColumn<bool>("initValue");
QTest::addColumn<bool>("configValue");
QTest::newRow("false -> true") << false << true;
QTest::newRow("true -> false") << true << false;
QTest::newRow("true -> true") << true << true;
QTest::newRow("false -> false") << false << false;
}
void TestLibinputDevice::testLoadScrollTwoFinger()
{
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
KConfigGroup inputConfig(config, QStringLiteral("Test"));
QFETCH(bool, configValue);
QFETCH(bool, initValue);
inputConfig.writeEntry("ScrollTwoFinger", configValue);
libinput_device device;
device.supportedScrollMethods = LIBINPUT_CONFIG_SCROLL_2FG;
device.scrollMethod = initValue ? LIBINPUT_CONFIG_SCROLL_2FG : LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
device.setScrollMethodReturnValue = false;
Device d(&device);
QCOMPARE(d.isScrollTwoFinger(), initValue);
// no config group set, should not change
d.loadConfiguration();
QCOMPARE(d.isScrollTwoFinger(), initValue);
// set the group
d.setConfig(inputConfig);
d.loadConfiguration();
QCOMPARE(d.isScrollTwoFinger(), configValue);
// and try to store
if (configValue != initValue) {
d.setScrollTwoFinger(initValue);
QCOMPARE(inputConfig.readEntry("ScrollTwoFinger", configValue), initValue);
}
}
void TestLibinputDevice::testLoadScrollEdge_data()
{
QTest::addColumn<bool>("initValue");
QTest::addColumn<bool>("configValue");
QTest::newRow("false -> true") << false << true;
QTest::newRow("true -> false") << true << false;
QTest::newRow("true -> true") << true << true;
QTest::newRow("false -> false") << false << false;
}
void TestLibinputDevice::testLoadScrollEdge()
{
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
KConfigGroup inputConfig(config, QStringLiteral("Test"));
QFETCH(bool, configValue);
QFETCH(bool, initValue);
inputConfig.writeEntry("ScrollEdge", configValue);
libinput_device device;
device.supportedScrollMethods = LIBINPUT_CONFIG_SCROLL_EDGE;
device.scrollMethod = initValue ? LIBINPUT_CONFIG_SCROLL_EDGE : LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
device.setScrollMethodReturnValue = false;
Device d(&device);
QCOMPARE(d.isScrollEdge(), initValue);
// no config group set, should not change
d.loadConfiguration();
QCOMPARE(d.isScrollEdge(), initValue);
// set the group
d.setConfig(inputConfig);
d.loadConfiguration();
QCOMPARE(d.isScrollEdge(), configValue);
// and try to store
if (configValue != initValue) {
d.setScrollEdge(initValue);
QCOMPARE(inputConfig.readEntry("ScrollEdge", configValue), initValue);
}
}
void TestLibinputDevice::testLoadScrollOnButton_data()
{
QTest::addColumn<bool>("initValue");
QTest::addColumn<bool>("configValue");
QTest::newRow("false -> true") << false << true;
QTest::newRow("true -> false") << true << false;
QTest::newRow("true -> true") << true << true;
QTest::newRow("false -> false") << false << false;
}
void TestLibinputDevice::testLoadScrollOnButton()
{
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
KConfigGroup inputConfig(config, QStringLiteral("Test"));
QFETCH(bool, configValue);
QFETCH(bool, initValue);
inputConfig.writeEntry("ScrollOnButton", configValue);
libinput_device device;
device.supportedScrollMethods = LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
device.scrollMethod = initValue ? LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN : LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
device.setScrollMethodReturnValue = false;
Device d(&device);
QCOMPARE(d.isScrollOnButtonDown(), initValue);
// no config group set, should not change
d.loadConfiguration();
QCOMPARE(d.isScrollOnButtonDown(), initValue);
// set the group
d.setConfig(inputConfig);
d.loadConfiguration();
QCOMPARE(d.isScrollOnButtonDown(), configValue);
// and try to store
if (configValue != initValue) {
d.setScrollOnButtonDown(initValue);
QCOMPARE(inputConfig.readEntry("ScrollOnButton", configValue), initValue);
}
}
void TestLibinputDevice::testLoadScrollButton_data()
{
QTest::addColumn<quint32>("initValue");
QTest::addColumn<quint32>("configValue");
QTest::newRow("BTN_LEFT -> BTN_RIGHT") << quint32(BTN_LEFT) << quint32(BTN_RIGHT);
QTest::newRow("BTN_LEFT -> BTN_LEFT") << quint32(BTN_LEFT) << quint32(BTN_LEFT);
}
void TestLibinputDevice::testLoadScrollButton()
{
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
KConfigGroup inputConfig(config, QStringLiteral("Test"));
QFETCH(quint32, configValue);
QFETCH(quint32, initValue);
inputConfig.writeEntry("ScrollButton", configValue);
libinput_device device;
device.supportedScrollMethods = LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
device.scrollMethod = LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
device.scrollButton = initValue;
device.setScrollButtonReturnValue = false;
Device d(&device);
QCOMPARE(d.isScrollOnButtonDown(), true);
QCOMPARE(d.scrollButton(), initValue);
// no config group set, should not change
d.loadConfiguration();
QCOMPARE(d.isScrollOnButtonDown(), true);
QCOMPARE(d.scrollButton(), initValue);
// set the group
d.setConfig(inputConfig);
d.loadConfiguration();
QCOMPARE(d.isScrollOnButtonDown(), true);
QCOMPARE(d.scrollButton(), configValue);
// and try to store
if (configValue != initValue) {
d.setScrollButton(initValue);
QCOMPARE(inputConfig.readEntry("ScrollButton", configValue), initValue);
}
}
QTEST_GUILESS_MAIN(TestLibinputDevice)
#include "device_test.moc"

View File

@ -471,6 +471,10 @@ bool Connection::isSuspended() const
void Connection::applyDeviceConfig(Device *device)
{
// pass configuration to Device
device->setConfig(m_config->group("Libinput").group(QString::number(device->vendor())).group(QString::number(device->product())).group(device->name()));
device->loadConfiguration();
if (device->isPointer()) {
const KConfigGroup group = m_config->group("Mouse");
device->setLeftHanded(group.readEntry("MouseButtonMapping", "RightHanded") == QLatin1String("LeftHanded"));

View File

@ -25,6 +25,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <config-kwin.h>
#include <functional>
namespace KWin
{
namespace LibInput
@ -70,6 +72,44 @@ Device *Device::getDevice(libinput_device *native)
return nullptr;
}
enum class ConfigKey {
Enabled,
TapToClick,
TapAndDrag,
TapDragLock,
MiddleButtonEmulation,
NaturalScroll,
ScrollTwoFinger,
ScrollEdge,
ScrollOnButton,
ScrollButton
};
struct ConfigData {
QByteArray key;
struct BooleanSetter {
std::function<void (Device*, bool)> setter;
std::function<bool (Device*)> defaultValue;
} booleanSetter;
struct UintSetter {
std::function<void (Device*, quint32)> setter;
std::function<quint32 (Device*)> defaultValue;
} quint32Setter;
};
static const QMap<ConfigKey, ConfigData> s_configData {
{ConfigKey::Enabled, {QByteArrayLiteral("Enabled"), {&Device::setEnabled, std::function<bool (Device*)>()}, {}}},
{ConfigKey::TapToClick, {QByteArrayLiteral("TapToClick"), {&Device::setTapToClick, &Device::tapToClickEnabledByDefault}, {}}},
{ConfigKey::TapAndDrag, {QByteArrayLiteral("TapAndDrag"), {&Device::setTapAndDrag, &Device::tapAndDragEnabledByDefault}, {}}},
{ConfigKey::TapDragLock, {QByteArrayLiteral("TapDragLock"), {&Device::setTapDragLock, &Device::tapDragLockEnabledByDefault}, {}}},
{ConfigKey::MiddleButtonEmulation, {QByteArrayLiteral("MiddleButtonEmulation"), {&Device::setMiddleEmulation, &Device::middleEmulationEnabledByDefault}, {}}},
{ConfigKey::NaturalScroll, {QByteArrayLiteral("NaturalScroll"), {&Device::setNaturalScroll, &Device::naturalScrollEnabledByDefault}, {}}},
{ConfigKey::ScrollTwoFinger, {QByteArrayLiteral("ScrollTwoFinger"), {&Device::setScrollTwoFinger, &Device::scrollTwoFingerEnabledByDefault}, {}}},
{ConfigKey::ScrollEdge, {QByteArrayLiteral("ScrollEdge"), {&Device::setScrollEdge, &Device::scrollEdgeEnabledByDefault}, {}}},
{ConfigKey::ScrollOnButton, {QByteArrayLiteral("ScrollOnButton"), {&Device::setScrollOnButtonDown, &Device::scrollOnButtonDownEnabledByDefault}, {}}},
{ConfigKey::ScrollButton, {QByteArrayLiteral("ScrollButton"), {}, {&Device::setScrollButton, &Device::defaultScrollButton}}}
};
Device::Device(libinput_device *device, QObject *parent)
: QObject(parent)
, m_device(device)
@ -116,6 +156,7 @@ Device::Device(libinput_device *device, QObject *parent)
, m_scrollButton(libinput_device_config_scroll_get_button(m_device))
, m_pointerAcceleration(libinput_device_config_accel_get_speed(m_device))
, m_enabled(m_supportsDisableEvents ? libinput_device_config_send_events_get_mode(m_device) == LIBINPUT_CONFIG_SEND_EVENTS_ENABLED : true)
, m_config()
{
libinput_device_ref(m_device);
@ -169,6 +210,48 @@ Device::~Device()
libinput_device_unref(m_device);
}
template <typename T>
void Device::writeEntry(const ConfigKey &key, const T &value)
{
if (!m_config.isValid()) {
return;
}
if (m_loading) {
return;
}
auto it = s_configData.find(key);
Q_ASSERT(it != s_configData.end());
m_config.writeEntry(it.value().key.constData(), value);
m_config.sync();
}
template <typename T, typename Setter>
void Device::readEntry(const QByteArray &key, const Setter &s, const T &defaultValue)
{
if (!s.setter) {
return;
}
s.setter(this, m_config.readEntry(key.constData(), s.defaultValue ? s.defaultValue(this) : defaultValue));
}
void Device::loadConfiguration()
{
if (!m_config.isValid()) {
return;
}
m_loading = true;
for (auto it = s_configData.begin(), end = s_configData.end(); it != end; ++it) {
const auto key = it.value().key;
if (!m_config.hasKey(key.constData())) {
continue;
}
readEntry(key, it.value().booleanSetter, true);
readEntry(key, it.value().quint32Setter, 0);
};
m_loading = false;
}
void Device::setLeftHanded(bool set)
{
if (!m_supportsLeftHanded) {
@ -204,23 +287,24 @@ void Device::setNaturalScroll(bool set)
if (libinput_device_config_scroll_set_natural_scroll_enabled(m_device, set) == LIBINPUT_CONFIG_STATUS_SUCCESS) {
if (m_naturalScroll != set) {
m_naturalScroll = set;
writeEntry(ConfigKey::NaturalScroll, m_naturalScroll);
emit naturalScrollChanged();
}
}
}
void Device::setScrollMethod(bool set, enum libinput_config_scroll_method method)
bool Device::setScrollMethod(bool set, enum libinput_config_scroll_method method)
{
if (!(m_supportedScrollMethods & method)) {
return;
return false;
}
if (set) {
if (m_scrollMethod == method) {
return;
return false;
}
} else {
if (m_scrollMethod != method) {
return;
return false;
}
method = LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
}
@ -228,19 +312,27 @@ void Device::setScrollMethod(bool set, enum libinput_config_scroll_method method
if (libinput_device_config_scroll_set_method(m_device, method) == LIBINPUT_CONFIG_STATUS_SUCCESS) {
m_scrollMethod = method;
emit scrollMethodChanged();
return true;
}
return false;
}
void Device::setScrollTwoFinger(bool set) {
setScrollMethod(set, LIBINPUT_CONFIG_SCROLL_2FG);
if (setScrollMethod(set, LIBINPUT_CONFIG_SCROLL_2FG)) {
writeEntry(ConfigKey::ScrollTwoFinger, set);
}
}
void Device::setScrollEdge(bool set) {
setScrollMethod(set, LIBINPUT_CONFIG_SCROLL_EDGE);
if (setScrollMethod(set, LIBINPUT_CONFIG_SCROLL_EDGE)) {
writeEntry(ConfigKey::ScrollEdge, set);
}
}
void Device::setScrollOnButtonDown(bool set) {
setScrollMethod(set, LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN);
if (setScrollMethod(set, LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN)) {
writeEntry(ConfigKey::ScrollOnButton, set);
}
}
void Device::setScrollButton(quint32 button)
@ -251,12 +343,13 @@ void Device::setScrollButton(quint32 button)
if (libinput_device_config_scroll_set_button(m_device, button) == LIBINPUT_CONFIG_STATUS_SUCCESS) {
if (m_scrollButton != button) {
m_scrollButton = button;
writeEntry(ConfigKey::ScrollButton, m_scrollButton);
emit scrollButtonChanged();
}
}
}
#define CONFIG(method, condition, function, enum, variable) \
#define CONFIG(method, condition, function, enum, variable, key) \
void Device::method(bool set) \
{ \
if (condition) { \
@ -265,16 +358,17 @@ void Device::method(bool set) \
if (libinput_device_config_##function(m_device, set ? LIBINPUT_CONFIG_##enum##_ENABLED : LIBINPUT_CONFIG_##enum##_DISABLED) == LIBINPUT_CONFIG_STATUS_SUCCESS) { \
if (m_##variable != set) { \
m_##variable = set; \
writeEntry(ConfigKey::key, m_##variable); \
emit variable##Changed(); \
}\
} \
}
CONFIG(setEnabled, !m_supportsDisableEvents, send_events_set_mode, SEND_EVENTS, enabled)
CONFIG(setTapToClick, m_tapFingerCount == 0, tap_set_enabled, TAP, tapToClick)
CONFIG(setTapAndDrag, false, tap_set_drag_enabled, DRAG, tapAndDrag)
CONFIG(setTapDragLock, false, tap_set_drag_lock_enabled, DRAG_LOCK, tapDragLock)
CONFIG(setMiddleEmulation, m_supportsMiddleEmulation == false, middle_emulation_set_enabled, MIDDLE_EMULATION, middleEmulation)
CONFIG(setEnabled, !m_supportsDisableEvents, send_events_set_mode, SEND_EVENTS, enabled, Enabled)
CONFIG(setTapToClick, m_tapFingerCount == 0, tap_set_enabled, TAP, tapToClick, TapToClick)
CONFIG(setTapAndDrag, false, tap_set_drag_enabled, DRAG, tapAndDrag, TapAndDrag)
CONFIG(setTapDragLock, false, tap_set_drag_lock_enabled, DRAG_LOCK, tapDragLock, TapDragLock)
CONFIG(setMiddleEmulation, m_supportsMiddleEmulation == false, middle_emulation_set_enabled, MIDDLE_EMULATION, middleEmulation, MiddleButtonEmulation)
#undef CONFIG

View File

@ -22,6 +22,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <libinput.h>
#include <KConfigGroup>
#include <QObject>
#include <QSizeF>
#include <QVector>
@ -32,6 +34,7 @@ namespace KWin
{
namespace LibInput
{
enum class ConfigKey;
class Device : public QObject
{
@ -216,7 +219,7 @@ public:
return m_naturalScroll;
}
void setNaturalScroll(bool set);
void setScrollMethod(bool set, enum libinput_config_scroll_method method);
bool setScrollMethod(bool set, enum libinput_config_scroll_method method);
bool isScrollTwoFinger() const {
return m_scrollMethod & LIBINPUT_CONFIG_SCROLL_2FG;
}
@ -260,6 +263,19 @@ public:
return m_device;
}
/**
* Sets the @p config to load the Device configuration from and to store each
* successful Device configuration.
**/
void setConfig(const KConfigGroup &config) {
m_config = config;
}
/**
* Loads the configuration and applies it to the Device
**/
void loadConfiguration();
/**
* All created Devices
**/
@ -284,6 +300,10 @@ Q_SIGNALS:
void scrollButtonChanged();
private:
template <typename T>
void writeEntry(const ConfigKey &key, const T &value);
template <typename T, typename Setter>
void readEntry(const QByteArray &key, const Setter &s, const T &defaultValue = T());
libinput_device *m_device;
bool m_keyboard;
bool m_alphaNumericKeyboard = false;
@ -329,6 +349,9 @@ private:
qreal m_pointerAcceleration;
bool m_enabled;
KConfigGroup m_config;
bool m_loading = false;
static QVector<Device*> s_devices;
};