Commit ce84d6ab authored by Atul Bisht's avatar Atul Bisht Committed by Nate Graham

[libinput-touchpad-kcm] Use wayland specific touchpad KCM UI when libinput is used on X11

Summary:
Earlier when libinput was used on X11, XInput specific UI was shown, due to which most of the options were grayed out.
Now we show libinput specific UI that is already used on wayland if libinput driver is used on X11.

- loaded all libinput properties that are available on X11.
- exposed all Q_PROPERTY to Libinput specific UI.

FEATURE: 387153
FEATURE: 392709
FIXED-IN: 5.16.0

Reviewers: ngraham, romangg, davidedmundson, #plasma

Reviewed By: ngraham, romangg, #plasma

Subscribers: GB_2, jriddell, knambiar, plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D20186
parent bbd7fcb3
SET(backend_SRCS
${backend_SRCS}
backends/libinputcommon.cpp
backends/kwin_wayland/kwinwaylandbackend.cpp
backends/kwin_wayland/kwinwaylandtouchpad.cpp
)
......@@ -40,6 +40,8 @@ KWinWaylandBackend::KWinWaylandBackend(QObject *parent) :
QDBusConnection::sessionBus(),
this);
setMode(TouchpadInputBackendMode::WaylandLibinput);
findTouchpads();
m_deviceManager->connection().connect(QStringLiteral("org.kde.KWin"),
......
......@@ -21,33 +21,12 @@
#include <QDBusInterface>
#include <QDBusError>
#include <QVector>
#include <backends/libinputcommon.h>
#include "logging.h"
namespace {
template<typename T>
T valueLoaderPart(QVariant const &reply) { Q_UNUSED(reply); return T(); }
template<>
bool valueLoaderPart(QVariant const &reply) { return reply.toBool(); }
template<>
int valueLoaderPart(QVariant const &reply) { return reply.toInt(); }
template<>
quint32 valueLoaderPart(QVariant const &reply) { return reply.toInt(); }
template<>
qreal valueLoaderPart(QVariant const &reply) { return reply.toReal(); }
template<>
QString valueLoaderPart(QVariant const &reply) { return reply.toString(); }
template<>
Qt::MouseButtons valueLoaderPart(QVariant const &reply) { return static_cast<Qt::MouseButtons>(reply.toInt()); }
}
KWinWaylandTouchpad::KWinWaylandTouchpad(QString dbusName)
KWinWaylandTouchpad::KWinWaylandTouchpad(QString dbusName) :
LibinputCommon()
{
m_iface = new QDBusInterface(QStringLiteral("org.kde.KWin"),
QStringLiteral("/org/kde/KWin/InputDevice/") + dbusName,
......@@ -236,7 +215,7 @@ QString KWinWaylandTouchpad::valueWriter(const Prop<T> &prop)
if (!prop.changed()) {
return QString();
}
m_iface->setProperty(prop.dbus, prop.val);
m_iface->setProperty(prop.name, prop.val);
QDBusError error = m_iface->lastError();
if (error.isValid()) {
qCCritical(KCM_TOUCHPAD) << error.message();
......@@ -248,9 +227,9 @@ QString KWinWaylandTouchpad::valueWriter(const Prop<T> &prop)
template<typename T>
bool KWinWaylandTouchpad::valueLoader(Prop<T> &prop)
{
QVariant reply = m_iface->property(prop.dbus);
QVariant reply = m_iface->property(prop.name);
if (!reply.isValid()) {
qCCritical(KCM_TOUCHPAD) << "Error on d-bus read of" << prop.dbus;
qCCritical(KCM_TOUCHPAD) << "Error on d-bus read of" << prop.name;
prop.avail = false;
return false;
}
......
/*
* Copyright 2019 Atul Bisht <atulbisht26@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "libinputcommon.h"
#include "moc_libinputcommon.cpp"
This diff is collapsed.
......@@ -16,6 +16,7 @@ include_directories(${X11_Xinput_INCLUDE_PATH}
SET(backend_SRCS
${backend_SRCS}
backends/libinputcommon.cpp
backends/x11/propertyinfo.cpp
backends/x11/xlibbackend.cpp
backends/x11/synapticstouchpad.cpp
......
/*
* Copyright (C) 2015 Weng Xuetian <wengxt@gmail.com>
* Copyright (C) 2019 Atul Bisht <atulbisht26@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -19,12 +19,112 @@
#ifndef LIBINPUTTOUCHPAD_H
#define LIBINPUTTOUCHPAD_H
#include <QObject>
#include "xlibtouchpad.h"
#include "backends/libinputcommon.h"
class LibinputTouchpad : public XlibTouchpad
class LibinputTouchpad : public LibinputCommon, public XlibTouchpad
{
Q_OBJECT
public:
LibinputTouchpad(Display *display, int deviceId);
~LibinputTouchpad() override {}
bool getConfig() override;
bool applyConfig() override;
bool getDefaultConfig() override;
bool isChangedConfig() override;
private:
template<typename T>
bool valueLoader(Prop<T> &prop);
template<typename T>
QString valueWriter(const Prop<T> &prop);
//
// general
QString name() const override {
return m_name;
}
bool supportsDisableEvents() const override {
return m_supportsDisableEvents.avail && m_supportsDisableEvents.val;
}
bool isEnabled() const override {
return !m_enabled.val;
}
void setEnabled(bool set) override {
m_enabled.set(!set);
}
//
// Tapping
void setLmrTapButtonMap(bool set) override {
m_lrmTapButtonMap.set(!set);
m_lmrTapButtonMap.set(set);
}
//
// advanced
bool supportsLeftHanded() const override {
return m_leftHanded.avail;
}
bool supportsDisableEventsOnExternalMouse() const override {
return m_supportsDisableEventsOnExternalMouse.avail && m_supportsDisableEventsOnExternalMouse.val;
}
bool supportsDisableWhileTyping() const override {
return m_disableWhileTyping.avail;
}
bool supportsMiddleEmulation() const override {
return m_middleEmulation.avail;
}
//
// acceleration speed and profile
bool supportsPointerAcceleration() const override {
return m_pointerAcceleration.avail;
}
bool supportsPointerAccelerationProfileFlat() const override {
return m_supportsPointerAccelerationProfileFlat.avail && m_supportsPointerAccelerationProfileFlat.val;
}
bool supportsPointerAccelerationProfileAdaptive() const override {
return m_supportsPointerAccelerationProfileAdaptive.avail && m_supportsPointerAccelerationProfileAdaptive.val;
}
//
// scrolling
bool supportsNaturalScroll() const override {
return m_naturalScroll.avail;
}
bool supportsHorizontalScrolling() const override {
return true;
}
bool supportsScrollTwoFinger() const override {
return m_supportsScrollTwoFinger.avail && m_supportsScrollTwoFinger.val;
}
bool supportsScrollEdge() const override {
return m_supportsScrollEdge.avail && m_supportsScrollEdge.val;
}
bool supportsScrollOnButtonDown() const override {
return m_supportsScrollOnButtonDown.avail && m_supportsScrollOnButtonDown.val;
}
//
// click method
bool supportsClickMethodAreas() const override {
return m_supportsClickMethodAreas.avail && m_supportsClickMethodAreas.val;
}
bool supportsClickMethodClickfinger() const override {
return m_supportsClickMethodClickfinger.avail && m_supportsClickMethodClickfinger.val;
}
// Tapping
Prop<bool> m_lrmTapButtonMapEnabledByDefault = Prop<bool>("lrmTapButtonMapEnabledByDefault");
Prop<bool> m_lrmTapButtonMap = Prop<bool>("lrmTapButtonMap");
//
// advanced
Prop<bool> m_disableEventsOnExternalMouse = Prop<bool>("disableEventsOnExternalMouse");
Prop<bool> m_disableEventsOnExternalMouseDefault = Prop<bool>("disableEventsOnExternalMouseDefault");
QString m_name;
};
#endif // LIBINPUTTOUCHPAD_H
......@@ -22,8 +22,10 @@
#include "xlibtouchpad.h"
#include "xcbatom.h"
class SynapticsTouchpad : public XlibTouchpad
class SynapticsTouchpad : public QObject, public XlibTouchpad
{
Q_OBJECT
public:
SynapticsTouchpad(Display *display, int deviceId);
......
......@@ -120,8 +120,10 @@ XlibTouchpad* XlibBackend::findTouchpad()
Atom *atom = properties.data(), *atomEnd = properties.data() + nProperties;
for (; atom != atomEnd; atom++) {
if (*atom == m_libinputIdentifierAtom.atom()) {
setMode(TouchpadInputBackendMode::XLibinput);
return new LibinputTouchpad(m_display.data(), info->id);
} else if (*atom == m_synapticsIdentifierAtom.atom()) {
setMode(TouchpadInputBackendMode::XSynaptics);
return new SynapticsTouchpad(m_display.data(), info->id);
}
}
......@@ -144,6 +146,20 @@ bool XlibBackend::applyConfig(const QVariantHash &p)
return success;
}
bool XlibBackend::applyConfig()
{
if (!m_device) {
return false;
}
bool success = m_device->applyConfig();
if (!success) {
m_errorString = i18n("Cannot apply touchpad configuration");
}
return success;
}
bool XlibBackend::getConfig(QVariantHash &p)
{
if (!m_device) {
......@@ -157,6 +173,41 @@ bool XlibBackend::getConfig(QVariantHash &p)
return success;
}
bool XlibBackend::getConfig()
{
if(!m_device) {
return false;
}
bool success = m_device->getConfig();
if (!success) {
m_errorString = i18n("Cannot read touchpad configuration");
}
return success;
}
bool XlibBackend::getDefaultConfig()
{
if (!m_device) {
return false;
}
bool success = m_device->getDefaultConfig();
if (!success) {
m_errorString = i18n("Cannot read default touchpad configuration");
}
return success;
}
bool XlibBackend::isChangedConfig() const
{
if (!m_device) {
return false;
}
return m_device->isChangedConfig();
}
void XlibBackend::setTouchpadEnabled(bool enable)
{
if (!m_device) {
......@@ -295,6 +346,22 @@ QStringList XlibBackend::listMouses(const QStringList &blacklist)
return list;
}
QVector<QObject *> XlibBackend::getDevices() const
{
QVector<QObject*> touchpads;
LibinputTouchpad* libinputtouchpad = dynamic_cast<LibinputTouchpad*> (m_device.data());
SynapticsTouchpad* synaptics = dynamic_cast<SynapticsTouchpad*> (m_device.data());
if ( libinputtouchpad) {
touchpads.push_back(libinputtouchpad);
}
if (synaptics) {
touchpads.push_back(synaptics);
}
return touchpads;
}
void XlibBackend::watchForEvents(bool keyboard)
{
if (!m_notifications) {
......
......@@ -29,6 +29,8 @@
#include "touchpadbackend.h"
#include "xlibtouchpad.h"
#include "libinputtouchpad.h"
#include "synapticstouchpad.h"
#include <xcb/xcb.h>
......@@ -43,12 +45,18 @@ class XlibBackend : public TouchpadBackend
{
Q_OBJECT
Q_PROPERTY(int touchpadCount READ touchpadCount CONSTANT)
public:
static XlibBackend* initialize(QObject *parent = nullptr);
~XlibBackend();
bool applyConfig(const QVariantHash &) override;
bool applyConfig() override;
bool getConfig(QVariantHash &) override;
bool getConfig() override;
bool getDefaultConfig() override;
bool isChangedConfig() const override;
QStringList supportedParameters() const override {
return m_device ? m_device->supportedParameters() : QStringList();
}
......@@ -65,6 +73,7 @@ public:
void watchForEvents(bool keyboard) override;
QStringList listMouses(const QStringList &blacklist) override;
QVector<QObject*> getDevices() const override;
private slots:
void propertyChanged(xcb_atom_t);
......
......@@ -19,6 +19,7 @@
#ifndef XLIBTOUCHPAD_H
#define XLIBTOUCHPAD_H
#include <QObject>
#include <QVariantHash>
#include <QSet>
......@@ -44,14 +45,19 @@ struct Parameter {
class XlibTouchpad
{
public:
XlibTouchpad(Display *display, int deviceId);
virtual ~XlibTouchpad() {};
virtual ~XlibTouchpad() {}
int deviceId() { return m_deviceId; }
const QStringList &supportedParameters() const { return m_supported; }
bool applyConfig(const QVariantHash &p);
bool getConfig(QVariantHash &p);
virtual bool getConfig() { return false; }
virtual bool applyConfig() { return false; }
virtual bool getDefaultConfig() { return false; }
virtual bool isChangedConfig() { return false; }
void setEnabled(bool enable);
bool enabled();
void setTouchpadOff(int touchpadOff);
......
......@@ -76,6 +76,7 @@ Kirigami.ScrollablePage {
naturalScroll.load()
rightClickMethod.load()
middleClickMethod.load()
disableHorizontalScrolling.load()
loading = false
}
......@@ -271,6 +272,7 @@ Kirigami.ScrollablePage {
enabled = touchpad.supportsPointerAccelerationProfileAdaptive
if (!enabled) {
accelProfile.visible = false
accelProfileFlat.checked = false
accelProfileAdaptive.checked = false
return
......@@ -568,6 +570,31 @@ Kirigami.ScrollablePage {
}
}
Controls.CheckBox {
id: disableHorizontalScrolling
text: i18nd("kcm_touchpad", "Disable horizontal scrolling")
function load() {
visible = touchpad.supportsHorizontalScrolling
enabled = touchpad.supportsHorizontalScrolling
checked = enabled && !touchpad.horizontalScrolling
}
onCheckedChanged: {
if (enabled && !root.loading) {
touchpad.horizontalScrolling = !checked
root.changeSignal()
}
}
hoverEnabled: true
Controls.ToolTip {
text: i18nd("kcm_touchpad", "Disable horizontal scrolling")
visible: parent.hovered
delay: 1000
}
}
Item {
Kirigami.FormData.isSection: false
}
......
......@@ -35,8 +35,8 @@
#include "version.h"
TouchpadConfigLibinput::TouchpadConfigLibinput(TouchpadConfigContainer *parent, const QVariantList &args)
: TouchpadConfigPlugin(parent)
TouchpadConfigLibinput::TouchpadConfigLibinput(TouchpadConfigContainer *parent, TouchpadBackend* backend, const QVariantList &args)
: TouchpadConfigPlugin(parent, backend)
{
KAboutData* data = new KAboutData(QStringLiteral("kcm_touchpad"),
i18n("Touchpad KCM"),
......@@ -52,7 +52,6 @@ TouchpadConfigLibinput::TouchpadConfigLibinput(TouchpadConfigContainer *parent,
m_parent->setAboutData(data);
m_backend = TouchpadBackend::implementation();
m_initError = !m_backend->errorString().isNull();
m_view = new QQuickWidget(this);
......
......@@ -32,6 +32,7 @@ class TouchpadConfigLibinput : public TouchpadConfigPlugin
public:
explicit TouchpadConfigLibinput(TouchpadConfigContainer *parent,
TouchpadBackend *backend,
const QVariantList &args = QVariantList());
virtual ~TouchpadConfigLibinput() {}
......
......@@ -20,6 +20,7 @@
#include "touchpadconfigplugin.h"
#include "kcm/libinput/touchpadconfiglibinput.h"
#include "kcm/xlib/touchpadconfigxlib.h"
#include "touchpadbackend.h"
#include <KWindowSystem/kwindowsystem.h>
......@@ -36,10 +37,16 @@ extern "C"
TouchpadConfigContainer::TouchpadConfigContainer(QWidget *parent, const QVariantList &args)
: KCModule(parent, args)
{
TouchpadBackend *backend = TouchpadBackend::implementation();
if (KWindowSystem::isPlatformX11()) {
m_plugin = new TouchpadConfigXlib(this);
if (backend->getMode() == TouchpadInputBackendMode::XLibinput) {
m_plugin = new TouchpadConfigLibinput(this, backend);
}
else if (backend->getMode() == TouchpadInputBackendMode::XSynaptics) {
m_plugin = new TouchpadConfigXlib(this, backend);
}
} else if (KWindowSystem::isPlatformWayland()) {
m_plugin = new TouchpadConfigLibinput(this);
m_plugin = new TouchpadConfigLibinput(this, backend);
}
}
......
......@@ -19,8 +19,9 @@
#include "touchpadconfigplugin.h"
#include "touchpadconfigcontainer.h"
TouchpadConfigPlugin::TouchpadConfigPlugin(QWidget *parent)
TouchpadConfigPlugin::TouchpadConfigPlugin(QWidget *parent, TouchpadBackend *backend)
: QWidget(parent),
m_parent(dynamic_cast<TouchpadConfigContainer*>(parent))
m_parent(dynamic_cast<TouchpadConfigContainer*>(parent)),
m_backend(backend)
{
}
......@@ -29,7 +29,7 @@ class TouchpadConfigPlugin : public QWidget
Q_OBJECT
public:
explicit TouchpadConfigPlugin(QWidget *parent);
TouchpadConfigPlugin(QWidget *parent, TouchpadBackend *backend);
virtual ~TouchpadConfigPlugin() {}
virtual void load() {}
......
......@@ -98,8 +98,8 @@ QWidget *addTab(QTabWidget *tabs, T &form)
return widget;
}
TouchpadConfigXlib::TouchpadConfigXlib(TouchpadConfigContainer *parent, const QVariantList &args)
: TouchpadConfigPlugin(parent),
TouchpadConfigXlib::TouchpadConfigXlib(TouchpadConfigContainer *parent, TouchpadBackend* backend, const QVariantList &args)
: TouchpadConfigPlugin(parent, backend),
m_configOutOfSync(false)
{
KAboutData* data = new KAboutData(QStringLiteral("kcm_touchpad"),
......@@ -174,8 +174,6 @@ TouchpadConfigXlib::TouchpadConfigXlib(TouchpadConfigContainer *parent, const QV
new SliderPair(m_pointerMotion.kcfg_PressureMotionMinZ,
m_pointerMotion.kcfg_PressureMotionMaxZ, this);
m_backend = TouchpadBackend::implementation();
KConfigDialogManager::changedMap()->insert("CustomSlider",
SIGNAL(valueChanged(double)));
m_manager = new CustomConfigDialogManager(this, &m_config,
......
......@@ -52,6 +52,7 @@ class TouchpadConfigXlib : public TouchpadConfigPlugin
public:
explicit TouchpadConfigXlib(TouchpadConfigContainer *parent,
TouchpadBackend* backend,
const QVariantList &args = QVariantList());
~TouchpadConfigXlib() override;
......
......@@ -28,6 +28,11 @@
#include <KWindowSystem/kwindowsystem.h>
void TouchpadBackend::setMode(TouchpadInputBackendMode mode)
{
m_mode = mode;
}
TouchpadBackend *TouchpadBackend::implementation()
{
//There are multiple possible backends
......
......@@ -24,16 +24,25 @@
#include <QVector>
#include <QVariantHash>
enum class TouchpadInputBackendMode {
WaylandLibinput = 0,
XLibinput = 1,
XSynaptics = 2
};
class Q_DECL_EXPORT TouchpadBackend : public QObject
{
Q_OBJECT
protected:
explicit TouchpadBackend(QObject *parent) : QObject(parent) {}
explicit TouchpadBackend(QObject *parent) : QObject(parent) {}
void setMode(TouchpadInputBackendMode mode);
public:
static TouchpadBackend *implementation();
TouchpadInputBackendMode getMode() const {return m_mode;}
virtual bool applyConfig(const QVariantHash &) {return false;}
virtual bool getConfig(QVariantHash &) {return false;}
......@@ -62,6 +71,9 @@ public:
virtual QStringList listMouses(const QStringList &blacklist) {return QStringList();}
private:
TouchpadInputBackendMode m_mode;
Q_SIGNALS:
void touchpadStateChanged();
void mousesChanged();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment