[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
This commit is contained in:
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 testLoadNaturalScroll_data();
void testLoadNaturalScroll();
void testLoadScrollTwoFinger_data();
void testLoadScrollTwoFinger();
void testLoadScrollEdge_data();
void testLoadScrollEdge();
void testLoadScrollOnButton_data();
void testLoadScrollOnButton();
void testLoadScrollMethod_data();
void testLoadScrollMethod();
void testLoadScrollButton_data();
void testLoadScrollButton();
void testLoadLeftHanded_data();
@ -1552,129 +1548,55 @@ void TestLibinputDevice::testLoadNaturalScroll()
}
}
void TestLibinputDevice::testLoadScrollTwoFinger_data()
void TestLibinputDevice::testLoadScrollMethod_data()
{
QTest::addColumn<bool>("initValue");
QTest::addColumn<bool>("configValue");
QTest::addColumn<quint32>("initValue");
QTest::addColumn<QString>("initValuePropNameString");
QTest::addColumn<quint32>("configValue");
QTest::addColumn<QString>("configValuePropNameString");
QTest::newRow("false -> true") << false << true;
QTest::newRow("true -> false") << true << false;
QTest::newRow("true -> true") << true << true;
QTest::newRow("false -> false") << false << false;
QTest::newRow("scrollTwoFinger -> scrollEdge") << (quint32) LIBINPUT_CONFIG_SCROLL_2FG << "scrollTwoFinger" << (quint32) LIBINPUT_CONFIG_SCROLL_EDGE << "scrollEdge";
QTest::newRow("scrollOnButtonDown -> scrollTwoFinger") << (quint32) LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN << "scrollOnButtonDown" << (quint32) LIBINPUT_CONFIG_SCROLL_2FG << "scrollTwoFinger";
QTest::newRow("scrollEdge -> scrollEdge") << (quint32) LIBINPUT_CONFIG_SCROLL_EDGE << "scrollEdge" << (quint32) LIBINPUT_CONFIG_SCROLL_EDGE << "scrollEdge";
}
void TestLibinputDevice::testLoadScrollTwoFinger()
void TestLibinputDevice::testLoadScrollMethod()
{
auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
KConfigGroup inputConfig(config, QStringLiteral("Test"));
QFETCH(bool, configValue);
QFETCH(bool, initValue);
inputConfig.writeEntry("ScrollTwoFinger", configValue);
QFETCH(quint32, initValue);
QFETCH(quint32, configValue);
QFETCH(QString, initValuePropNameString);
QFETCH(QString, configValuePropNameString);
QByteArray initValuePropName = initValuePropNameString.toLatin1();
QByteArray configValuePropName = configValuePropNameString.toLatin1();
inputConfig.writeEntry("ScrollMethod", configValue);
libinput_device device;
device.supportedScrollMethods = LIBINPUT_CONFIG_SCROLL_2FG;
device.scrollMethod = initValue ? LIBINPUT_CONFIG_SCROLL_2FG : LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
device.supportedScrollMethods = LIBINPUT_CONFIG_SCROLL_2FG | LIBINPUT_CONFIG_SCROLL_EDGE | LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
device.scrollMethod = (libinput_config_scroll_method) initValue;
device.setScrollMethodReturnValue = false;
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
d.loadConfiguration();
QCOMPARE(d.isScrollTwoFinger(), initValue);
QCOMPARE(d.property(initValuePropName).toBool(), true);
QCOMPARE(d.property(configValuePropName).toBool(), initValue == configValue);
// set the group
d.setConfig(inputConfig);
d.loadConfiguration();
QCOMPARE(d.isScrollTwoFinger(), configValue);
QCOMPARE(d.property(initValuePropName).toBool(), initValue == configValue);
QCOMPARE(d.property(configValuePropName).toBool(), true);
// 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);
d.setProperty(initValuePropName, true);
QCOMPARE(inputConfig.readEntry("ScrollMethod", 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 <functional>
namespace KWin
{
namespace LibInput
@ -80,36 +78,42 @@ enum class ConfigKey {
TapDragLock,
MiddleButtonEmulation,
NaturalScroll,
ScrollTwoFinger,
ScrollEdge,
ScrollOnButton,
ScrollMethod,
ScrollButton
};
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;
struct BooleanSetter {
std::function<void (Device*, bool)> setter;
std::function<bool (Device*)> defaultValue;
struct {
void (Device::*setter)(bool) = nullptr;
bool (Device::*defaultValue)() const;
} booleanSetter;
struct UintSetter {
std::function<void (Device*, quint32)> setter;
std::function<quint32 (Device*)> defaultValue;
struct {
void (Device::*setter)(quint32) = nullptr;
quint32 (Device::*defaultValue)() const;
} quint32Setter;
};
static const QMap<ConfigKey, ConfigData> s_configData {
{ConfigKey::Enabled, {QByteArrayLiteral("Enabled"), {&Device::setEnabled, std::function<bool (Device*)>()}, {}}},
{ConfigKey::LeftHanded, {QByteArrayLiteral("LeftHanded"), {&Device::setLeftHanded, &Device::leftHandedEnabledByDefault}, {}}},
{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}}}
{ConfigKey::Enabled, ConfigData(QByteArrayLiteral("Enabled"), &Device::setEnabled)},
{ConfigKey::LeftHanded, ConfigData(QByteArrayLiteral("LeftHanded"), &Device::setLeftHanded, &Device::leftHandedEnabledByDefault)},
{ConfigKey::TapToClick, ConfigData(QByteArrayLiteral("TapToClick"), &Device::setTapToClick, &Device::tapToClickEnabledByDefault)},
{ConfigKey::TapAndDrag, ConfigData(QByteArrayLiteral("TapAndDrag"), &Device::setTapAndDrag, &Device::tapAndDragEnabledByDefault)},
{ConfigKey::TapDragLock, ConfigData(QByteArrayLiteral("TapDragLock"), &Device::setTapDragLock, &Device::tapDragLockEnabledByDefault)},
{ConfigKey::MiddleButtonEmulation, ConfigData(QByteArrayLiteral("MiddleButtonEmulation"), &Device::setMiddleEmulation, &Device::middleEmulationEnabledByDefault)},
{ConfigKey::NaturalScroll, ConfigData(QByteArrayLiteral("NaturalScroll"), &Device::setNaturalScroll, &Device::naturalScrollEnabledByDefault)},
{ConfigKey::ScrollMethod, ConfigData(QByteArrayLiteral("ScrollMethod"), &Device::activateScrollMethodFromInt, &Device::defaultScrollMethodToInt)},
{ConfigKey::ScrollButton, ConfigData(QByteArrayLiteral("ScrollButton"), &Device::setScrollButton, &Device::defaultScrollButton)}
};
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) {
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()
@ -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)) {
return false;
bool stays_the_same = (m_scrollMethod == method) == set;
if (!(m_supportedScrollMethods & method) || stays_the_same) {
return;
}
if (set) {
if (m_scrollMethod == method) {
return false;
}
} else {
if (m_scrollMethod != method) {
return false;
}
if (!set) {
method = LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
}
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) {
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);
writeEntry(ConfigKey::ScrollMethod, (quint32) method);
}
}

View file

@ -203,6 +203,12 @@ public:
bool naturalScrollEnabledByDefault() const {
return m_naturalScrollEnabledByDefault;
}
enum libinput_config_scroll_method defaultScrollMethod() const {
return m_defaultScrollMethod;
}
quint32 defaultScrollMethodToInt() const {
return (quint32) m_defaultScrollMethod;
}
bool scrollTwoFingerEnabledByDefault() const {
return m_defaultScrollMethod == LIBINPUT_CONFIG_SCROLL_2FG;
}
@ -223,19 +229,28 @@ public:
return m_naturalScroll;
}
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 {
return m_scrollMethod & LIBINPUT_CONFIG_SCROLL_2FG;
}
void setScrollTwoFinger(bool set);
void setScrollTwoFinger(bool set) {
setScrollMethod(set, LIBINPUT_CONFIG_SCROLL_2FG);
}
bool isScrollEdge() const {
return m_scrollMethod & LIBINPUT_CONFIG_SCROLL_EDGE;
}
void setScrollEdge(bool set);
void setScrollEdge(bool set) {
setScrollMethod(set, LIBINPUT_CONFIG_SCROLL_EDGE);
}
bool isScrollOnButtonDown() const {
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 {
return m_scrollButton;
}