[libinput] Rework device config writing and save enum of ScrollMode as integer

This is a larger patch rewriting some parts of the config saving functionality
in device.cpp in order to:

1. Make it possible to save ScrollMode as integer instead of using three booleans
2. Simplify the addition of new keys or types in the future

Changes in detail:
a) Adds new ConfigKey ScrollMethod and removed now unnecessary keys per method
b) Adds constructors to the ConfigData struct. This allows to create ConfigData
   entries for s_configData without the need of stating empty brackets and the
   useage of default values.
c) Use plain member function pointers instead of std::function, in order to
   compactify code and have better compile output in case something goes wrong.
c) Cleans up ScrollMethod functions and adds interface methods for transforming
   the saved integer into type enum libinput_config_scroll_method.
d) Adjusts auto test for loading the ScrollMethod value from the config file.

Reviewers: #kwin, graesslin

Subscribers: kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D3460
icc-effect-5.14.5
Roman Gilg 2016-11-22 19:18:15 +01:00
parent ad0647688a
commit 87150816c7
3 changed files with 84 additions and 172 deletions

View File

@ -127,12 +127,8 @@ private Q_SLOTS:
void testLoadMiddleButtonEmulation(); void testLoadMiddleButtonEmulation();
void testLoadNaturalScroll_data(); void testLoadNaturalScroll_data();
void testLoadNaturalScroll(); void testLoadNaturalScroll();
void testLoadScrollTwoFinger_data(); void testLoadScrollMethod_data();
void testLoadScrollTwoFinger(); void testLoadScrollMethod();
void testLoadScrollEdge_data();
void testLoadScrollEdge();
void testLoadScrollOnButton_data();
void testLoadScrollOnButton();
void testLoadScrollButton_data(); void testLoadScrollButton_data();
void testLoadScrollButton(); void testLoadScrollButton();
void testLoadLeftHanded_data(); void testLoadLeftHanded_data();
@ -1552,129 +1548,55 @@ void TestLibinputDevice::testLoadNaturalScroll()
} }
} }
void TestLibinputDevice::testLoadScrollTwoFinger_data() void TestLibinputDevice::testLoadScrollMethod_data()
{ {
QTest::addColumn<bool>("initValue"); QTest::addColumn<quint32>("initValue");
QTest::addColumn<bool>("configValue"); QTest::addColumn<QString>("initValuePropNameString");
QTest::addColumn<quint32>("configValue");
QTest::addColumn<QString>("configValuePropNameString");
QTest::newRow("false -> true") << false << true; QTest::newRow("scrollTwoFinger -> scrollEdge") << (quint32) LIBINPUT_CONFIG_SCROLL_2FG << "scrollTwoFinger" << (quint32) LIBINPUT_CONFIG_SCROLL_EDGE << "scrollEdge";
QTest::newRow("true -> false") << true << false; QTest::newRow("scrollOnButtonDown -> scrollTwoFinger") << (quint32) LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN << "scrollOnButtonDown" << (quint32) LIBINPUT_CONFIG_SCROLL_2FG << "scrollTwoFinger";
QTest::newRow("true -> true") << true << true; QTest::newRow("scrollEdge -> scrollEdge") << (quint32) LIBINPUT_CONFIG_SCROLL_EDGE << "scrollEdge" << (quint32) LIBINPUT_CONFIG_SCROLL_EDGE << "scrollEdge";
QTest::newRow("false -> false") << false << false;
} }
void TestLibinputDevice::testLoadScrollTwoFinger() void TestLibinputDevice::testLoadScrollMethod()
{ {
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig); auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
KConfigGroup inputConfig(config, QStringLiteral("Test")); KConfigGroup inputConfig(config, QStringLiteral("Test"));
QFETCH(bool, configValue); QFETCH(quint32, initValue);
QFETCH(bool, initValue); QFETCH(quint32, configValue);
inputConfig.writeEntry("ScrollTwoFinger", configValue); QFETCH(QString, initValuePropNameString);
QFETCH(QString, configValuePropNameString);
QByteArray initValuePropName = initValuePropNameString.toLatin1();
QByteArray configValuePropName = configValuePropNameString.toLatin1();
inputConfig.writeEntry("ScrollMethod", configValue);
libinput_device device; libinput_device device;
device.supportedScrollMethods = LIBINPUT_CONFIG_SCROLL_2FG; device.supportedScrollMethods = LIBINPUT_CONFIG_SCROLL_2FG | LIBINPUT_CONFIG_SCROLL_EDGE | LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
device.scrollMethod = initValue ? LIBINPUT_CONFIG_SCROLL_2FG : LIBINPUT_CONFIG_SCROLL_NO_SCROLL; device.scrollMethod = (libinput_config_scroll_method) initValue;
device.setScrollMethodReturnValue = false; device.setScrollMethodReturnValue = false;
Device d(&device); Device d(&device);
QCOMPARE(d.isScrollTwoFinger(), initValue); QCOMPARE(d.property(initValuePropName).toBool(), true);
QCOMPARE(d.property(configValuePropName).toBool(), initValue == configValue);
// no config group set, should not change // no config group set, should not change
d.loadConfiguration(); d.loadConfiguration();
QCOMPARE(d.isScrollTwoFinger(), initValue); QCOMPARE(d.property(initValuePropName).toBool(), true);
QCOMPARE(d.property(configValuePropName).toBool(), initValue == configValue);
// set the group // set the group
d.setConfig(inputConfig); d.setConfig(inputConfig);
d.loadConfiguration(); d.loadConfiguration();
QCOMPARE(d.isScrollTwoFinger(), configValue); QCOMPARE(d.property(initValuePropName).toBool(), initValue == configValue);
QCOMPARE(d.property(configValuePropName).toBool(), true);
// and try to store // and try to store
if (configValue != initValue) { if (configValue != initValue) {
d.setScrollTwoFinger(initValue); d.setProperty(initValuePropName, true);
QCOMPARE(inputConfig.readEntry("ScrollTwoFinger", configValue), initValue); QCOMPARE(inputConfig.readEntry("ScrollMethod", 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);
} }
} }

View File

@ -25,8 +25,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <config-kwin.h> #include <config-kwin.h>
#include <functional>
namespace KWin namespace KWin
{ {
namespace LibInput namespace LibInput
@ -80,36 +78,42 @@ enum class ConfigKey {
TapDragLock, TapDragLock,
MiddleButtonEmulation, MiddleButtonEmulation,
NaturalScroll, NaturalScroll,
ScrollTwoFinger, ScrollMethod,
ScrollEdge,
ScrollOnButton,
ScrollButton ScrollButton
}; };
struct ConfigData { struct ConfigData {
explicit ConfigData(QByteArray _key, void (Device::*_setter)(bool), bool (Device::*_defaultValue)() const = nullptr)
: key(_key)
{ booleanSetter.setter = _setter; booleanSetter.defaultValue = _defaultValue; }
explicit ConfigData(QByteArray _key, void (Device::*_setter)(quint32), quint32 (Device::*_defaultValue)() const = nullptr)
: key(_key)
{ quint32Setter.setter = _setter; quint32Setter.defaultValue = _defaultValue; }
QByteArray key; QByteArray key;
struct BooleanSetter {
std::function<void (Device*, bool)> setter; struct {
std::function<bool (Device*)> defaultValue; void (Device::*setter)(bool) = nullptr;
bool (Device::*defaultValue)() const;
} booleanSetter; } booleanSetter;
struct UintSetter {
std::function<void (Device*, quint32)> setter; struct {
std::function<quint32 (Device*)> defaultValue; void (Device::*setter)(quint32) = nullptr;
quint32 (Device::*defaultValue)() const;
} quint32Setter; } quint32Setter;
}; };
static const QMap<ConfigKey, ConfigData> s_configData { static const QMap<ConfigKey, ConfigData> s_configData {
{ConfigKey::Enabled, {QByteArrayLiteral("Enabled"), {&Device::setEnabled, std::function<bool (Device*)>()}, {}}}, {ConfigKey::Enabled, ConfigData(QByteArrayLiteral("Enabled"), &Device::setEnabled)},
{ConfigKey::LeftHanded, {QByteArrayLiteral("LeftHanded"), {&Device::setLeftHanded, &Device::leftHandedEnabledByDefault}, {}}}, {ConfigKey::LeftHanded, ConfigData(QByteArrayLiteral("LeftHanded"), &Device::setLeftHanded, &Device::leftHandedEnabledByDefault)},
{ConfigKey::TapToClick, {QByteArrayLiteral("TapToClick"), {&Device::setTapToClick, &Device::tapToClickEnabledByDefault}, {}}}, {ConfigKey::TapToClick, ConfigData(QByteArrayLiteral("TapToClick"), &Device::setTapToClick, &Device::tapToClickEnabledByDefault)},
{ConfigKey::TapAndDrag, {QByteArrayLiteral("TapAndDrag"), {&Device::setTapAndDrag, &Device::tapAndDragEnabledByDefault}, {}}}, {ConfigKey::TapAndDrag, ConfigData(QByteArrayLiteral("TapAndDrag"), &Device::setTapAndDrag, &Device::tapAndDragEnabledByDefault)},
{ConfigKey::TapDragLock, {QByteArrayLiteral("TapDragLock"), {&Device::setTapDragLock, &Device::tapDragLockEnabledByDefault}, {}}}, {ConfigKey::TapDragLock, ConfigData(QByteArrayLiteral("TapDragLock"), &Device::setTapDragLock, &Device::tapDragLockEnabledByDefault)},
{ConfigKey::MiddleButtonEmulation, {QByteArrayLiteral("MiddleButtonEmulation"), {&Device::setMiddleEmulation, &Device::middleEmulationEnabledByDefault}, {}}}, {ConfigKey::MiddleButtonEmulation, ConfigData(QByteArrayLiteral("MiddleButtonEmulation"), &Device::setMiddleEmulation, &Device::middleEmulationEnabledByDefault)},
{ConfigKey::NaturalScroll, {QByteArrayLiteral("NaturalScroll"), {&Device::setNaturalScroll, &Device::naturalScrollEnabledByDefault}, {}}}, {ConfigKey::NaturalScroll, ConfigData(QByteArrayLiteral("NaturalScroll"), &Device::setNaturalScroll, &Device::naturalScrollEnabledByDefault)},
{ConfigKey::ScrollTwoFinger, {QByteArrayLiteral("ScrollTwoFinger"), {&Device::setScrollTwoFinger, &Device::scrollTwoFingerEnabledByDefault}, {}}}, {ConfigKey::ScrollMethod, ConfigData(QByteArrayLiteral("ScrollMethod"), &Device::activateScrollMethodFromInt, &Device::defaultScrollMethodToInt)},
{ConfigKey::ScrollEdge, {QByteArrayLiteral("ScrollEdge"), {&Device::setScrollEdge, &Device::scrollEdgeEnabledByDefault}, {}}}, {ConfigKey::ScrollButton, ConfigData(QByteArrayLiteral("ScrollButton"), &Device::setScrollButton, &Device::defaultScrollButton)}
{ConfigKey::ScrollOnButton, {QByteArrayLiteral("ScrollOnButton"), {&Device::setScrollOnButtonDown, &Device::scrollOnButtonDownEnabledByDefault}, {}}},
{ConfigKey::ScrollButton, {QByteArrayLiteral("ScrollButton"), {}, {&Device::setScrollButton, &Device::defaultScrollButton}}}
}; };
Device::Device(libinput_device *device, QObject *parent) Device::Device(libinput_device *device, QObject *parent)
@ -234,7 +238,8 @@ void Device::readEntry(const QByteArray &key, const Setter &s, const T &defaultV
if (!s.setter) { if (!s.setter) {
return; return;
} }
s.setter(this, m_config.readEntry(key.constData(), s.defaultValue ? s.defaultValue(this) : defaultValue));
(this->*(s.setter))(m_config.readEntry(key.constData(), s.defaultValue ? (this->*(s.defaultValue))() : defaultValue));
} }
void Device::loadConfiguration() void Device::loadConfiguration()
@ -269,51 +274,21 @@ void Device::setPointerAcceleration(qreal acceleration)
} }
} }
bool Device::setScrollMethod(bool set, enum libinput_config_scroll_method method) void Device::setScrollMethod(bool set, enum libinput_config_scroll_method method)
{ {
if (!(m_supportedScrollMethods & method)) { bool stays_the_same = (m_scrollMethod == method) == set;
return false; if (!(m_supportedScrollMethods & method) || stays_the_same) {
return;
} }
if (set) {
if (m_scrollMethod == method) { if (!set) {
return false;
}
} else {
if (m_scrollMethod != method) {
return false;
}
method = LIBINPUT_CONFIG_SCROLL_NO_SCROLL; method = LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
} }
if (libinput_device_config_scroll_set_method(m_device, method) == LIBINPUT_CONFIG_STATUS_SUCCESS) { if (libinput_device_config_scroll_set_method(m_device, method) == LIBINPUT_CONFIG_STATUS_SUCCESS) {
m_scrollMethod = method; m_scrollMethod = method;
emit scrollMethodChanged(); emit scrollMethodChanged();
return true; writeEntry(ConfigKey::ScrollMethod, (quint32) method);
}
return false;
}
void Device::setScrollTwoFinger(bool set) {
if (setScrollMethod(set, LIBINPUT_CONFIG_SCROLL_2FG)) {
writeEntry(ConfigKey::ScrollTwoFinger, set);
writeEntry(ConfigKey::ScrollEdge, !set);
writeEntry(ConfigKey::ScrollOnButton, !set);
}
}
void Device::setScrollEdge(bool set) {
if (setScrollMethod(set, LIBINPUT_CONFIG_SCROLL_EDGE)) {
writeEntry(ConfigKey::ScrollEdge, set);
writeEntry(ConfigKey::ScrollTwoFinger, !set);
writeEntry(ConfigKey::ScrollOnButton, !set);
}
}
void Device::setScrollOnButtonDown(bool set) {
if (setScrollMethod(set, LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN)) {
writeEntry(ConfigKey::ScrollOnButton, set);
writeEntry(ConfigKey::ScrollTwoFinger, !set);
writeEntry(ConfigKey::ScrollEdge, !set);
} }
} }

View File

@ -203,6 +203,12 @@ public:
bool naturalScrollEnabledByDefault() const { bool naturalScrollEnabledByDefault() const {
return m_naturalScrollEnabledByDefault; return m_naturalScrollEnabledByDefault;
} }
enum libinput_config_scroll_method defaultScrollMethod() const {
return m_defaultScrollMethod;
}
quint32 defaultScrollMethodToInt() const {
return (quint32) m_defaultScrollMethod;
}
bool scrollTwoFingerEnabledByDefault() const { bool scrollTwoFingerEnabledByDefault() const {
return m_defaultScrollMethod == LIBINPUT_CONFIG_SCROLL_2FG; return m_defaultScrollMethod == LIBINPUT_CONFIG_SCROLL_2FG;
} }
@ -223,19 +229,28 @@ public:
return m_naturalScroll; return m_naturalScroll;
} }
void setNaturalScroll(bool set); void setNaturalScroll(bool set);
bool setScrollMethod(bool set, enum libinput_config_scroll_method method); void setScrollMethod(bool set, enum libinput_config_scroll_method method);
bool isScrollTwoFinger() const { bool isScrollTwoFinger() const {
return m_scrollMethod & LIBINPUT_CONFIG_SCROLL_2FG; return m_scrollMethod & LIBINPUT_CONFIG_SCROLL_2FG;
} }
void setScrollTwoFinger(bool set); void setScrollTwoFinger(bool set) {
setScrollMethod(set, LIBINPUT_CONFIG_SCROLL_2FG);
}
bool isScrollEdge() const { bool isScrollEdge() const {
return m_scrollMethod & LIBINPUT_CONFIG_SCROLL_EDGE; return m_scrollMethod & LIBINPUT_CONFIG_SCROLL_EDGE;
} }
void setScrollEdge(bool set); void setScrollEdge(bool set) {
setScrollMethod(set, LIBINPUT_CONFIG_SCROLL_EDGE);
}
bool isScrollOnButtonDown() const { bool isScrollOnButtonDown() const {
return m_scrollMethod & LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN; return m_scrollMethod & LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
} }
void setScrollOnButtonDown(bool set); void setScrollOnButtonDown(bool set) {
setScrollMethod(set, LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN);
}
void activateScrollMethodFromInt(quint32 method) {
setScrollMethod(true, (libinput_config_scroll_method) method);
}
quint32 scrollButton() const { quint32 scrollButton() const {
return m_scrollButton; return m_scrollButton;
} }