diff --git a/kcms/CMakeLists.txt b/kcms/CMakeLists.txt --- a/kcms/CMakeLists.txt +++ b/kcms/CMakeLists.txt @@ -58,6 +58,7 @@ add_subdirectory(cursortheme) if (SYNAPTICS_FOUND AND X11_Xinput_FOUND) + add_subdirectory(touchpadx) add_subdirectory(touchpad) endif() diff --git a/kcms/touchpad/CMakeLists.txt b/kcms/touchpad/CMakeLists.txt --- a/kcms/touchpad/CMakeLists.txt +++ b/kcms/touchpad/CMakeLists.txt @@ -1,13 +1,24 @@ -find_package(KDED ${KF5_MIN_VERSION} CONFIG REQUIRED) - +# KI18N Translation Domain for this library add_definitions(-DTRANSLATION_DOMAIN=\"kcm_touchpad\") -set(CMAKE_MODULE_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules - ${CMAKE_MODULE_PATH} +########### next target ############### +set(kcm_touchpad_SRCS + kcm.cpp +) + +add_library(kcm_touchpad MODULE ${kcm_touchpad_SRCS}) + +target_link_libraries(kcm_touchpad + KF5::QuickAddons + KF5::I18n + KF5::ConfigWidgets + KF5::Declarative ) -set(CMAKE_INCLUDE_CURRENT_DIR true) -set(TOUCHPAD_KCM_VERSION ${PROJECT_VERSION}) -add_subdirectory(src) -add_subdirectory(icon) +kcoreaddons_desktop_to_json(kcm_touchpad "kcm_touchpad.desktop" SERVICE_TYPES kcmodule.desktop) + +########### install files ############### +install( FILES kcm_touchpad.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}) +install(TARGETS kcm_touchpad DESTINATION ${KDE_INSTALL_PLUGINDIR}/kcms) + +kpackage_install_package(package kcm_touchpad kcms) diff --git a/kcms/touchpad/README.md b/kcms/touchpad/README.md --- a/kcms/touchpad/README.md +++ b/kcms/touchpad/README.md @@ -1,10 +1,4 @@ Touchpad KCM ============ -* KCModule (Wayland + X) -* Daemon (X only) - - Automatically enable/disable touchpad when typing and/or when mouse is plugged in - - Enable/disable touchpad with keyboard shortcuts -* Applet (X only) - - Shows touchpad's state - - Toggle touchpad with single click +* KCModule diff --git a/kcms/touchpad/src/backends/kwin_wayland.cmake b/kcms/touchpad/src/backends/kwin_wayland.cmake deleted file mode 100644 --- a/kcms/touchpad/src/backends/kwin_wayland.cmake +++ /dev/null @@ -1,5 +0,0 @@ -SET(backend_SRCS - ${backend_SRCS} - backends/kwin_wayland/kwinwaylandbackend.cpp - backends/kwin_wayland/kwinwaylandtouchpad.cpp -) diff --git a/kcms/touchpad/src/backends/kwin_wayland/kwinwaylandbackend.h b/kcms/touchpad/src/backends/kwin_wayland/kwinwaylandbackend.h deleted file mode 100644 --- a/kcms/touchpad/src/backends/kwin_wayland/kwinwaylandbackend.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2017 Roman Gilg - * - * 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. - */ - -#ifndef KWINWAYLANDBACKEND_H -#define KWINWAYLANDBACKEND_H - -#include "touchpadbackend.h" - -#include - -class KWinWaylandTouchpad; -class QDBusInterface; - -class KWinWaylandBackend : public TouchpadBackend -{ - Q_OBJECT - - Q_PROPERTY(int touchpadCount READ touchpadCount CONSTANT) - -public: - explicit KWinWaylandBackend(QObject *parent = 0); - ~KWinWaylandBackend(); - - bool applyConfig() override; - bool getConfig() override; - bool getDefaultConfig() override; - bool isChangedConfig() const override; - QString errorString() const override { return m_errorString; } - - virtual int touchpadCount() const override { return m_devices.count(); } - virtual QVector getDevices() const override { return m_devices; } - -private Q_SLOTS: - void onDeviceAdded(QString); - void onDeviceRemoved(QString); - -private: - void findTouchpads(); - - QDBusInterface* m_deviceManager; - QVector m_devices; - - QString m_errorString = QString(); -}; - -#endif // KWINWAYLANDBACKEND_H diff --git a/kcms/touchpad/src/backends/kwin_wayland/kwinwaylandbackend.cpp b/kcms/touchpad/src/backends/kwin_wayland/kwinwaylandbackend.cpp deleted file mode 100644 --- a/kcms/touchpad/src/backends/kwin_wayland/kwinwaylandbackend.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2017 Roman Gilg - * - * 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 "kwinwaylandbackend.h" -#include "kwinwaylandtouchpad.h" - -#include - -#include - -#include -#include -#include -#include - -#include "logging.h" - -KWinWaylandBackend::KWinWaylandBackend(QObject *parent) : - TouchpadBackend(parent) -{ - - m_deviceManager = new QDBusInterface (QStringLiteral("org.kde.KWin"), - QStringLiteral("/org/kde/KWin/InputDevice"), - QStringLiteral("org.kde.KWin.InputDeviceManager"), - QDBusConnection::sessionBus(), - this); - - findTouchpads(); - - m_deviceManager->connection().connect(QStringLiteral("org.kde.KWin"), - QStringLiteral("/org/kde/KWin/InputDevice"), - QStringLiteral("org.kde.KWin.InputDeviceManager"), - QStringLiteral("deviceAdded"), - this, - SLOT(onDeviceAdded(QString))); - m_deviceManager->connection().connect(QStringLiteral("org.kde.KWin"), - QStringLiteral("/org/kde/KWin/InputDevice"), - QStringLiteral("org.kde.KWin.InputDeviceManager"), - QStringLiteral("deviceRemoved"), - this, - SLOT(onDeviceRemoved(QString))); -} - -KWinWaylandBackend::~KWinWaylandBackend() -{ - qDeleteAll(m_devices); - delete m_deviceManager; -} - -void KWinWaylandBackend::findTouchpads() -{ - QStringList devicesSysNames; - const QVariant reply = m_deviceManager->property("devicesSysNames"); - if (reply.isValid()) { - qCDebug(KCM_TOUCHPAD) << "Devices list received successfully from KWin."; - devicesSysNames = reply.toStringList(); - } - else { - qCCritical(KCM_TOUCHPAD) << "Error on receiving device list from KWin."; - m_errorString = i18n("Querying input devices failed. Please reopen this settings module."); - return; - } - - bool touchpadFound = false; - for (QString sn : devicesSysNames) { - QDBusInterface deviceIface(QStringLiteral("org.kde.KWin"), - QStringLiteral("/org/kde/KWin/InputDevice/") + sn, - QStringLiteral("org.kde.KWin.InputDevice"), - QDBusConnection::sessionBus(), - this); - const QVariant reply = deviceIface.property("touchpad"); - if (reply.isValid() && reply.toBool()) { - KWinWaylandTouchpad* tp = new KWinWaylandTouchpad(sn); - if (!tp->init()) { - qCCritical(KCM_TOUCHPAD) << "Error on creating touchpad object" << sn; - m_errorString = i18n("Critical error on reading fundamental device infos for touchpad %1.", sn); - return; - } - m_devices.append(tp); - touchpadFound = true; - qCDebug(KCM_TOUCHPAD).nospace() << "Touchpad found: " << tp->name() << " (" << tp->sysName() << ")"; - } - } -} - -bool KWinWaylandBackend::applyConfig() -{ - return std::all_of(m_devices.constBegin(), m_devices.constEnd(), - [] (QObject *t) { return static_cast(t)->applyConfig(); }); -} - -bool KWinWaylandBackend::getConfig() -{ - return std::all_of(m_devices.constBegin(), m_devices.constEnd(), - [] (QObject *t) { return static_cast(t)->getConfig(); }); -} - -bool KWinWaylandBackend::getDefaultConfig() -{ - return std::all_of(m_devices.constBegin(), m_devices.constEnd(), - [] (QObject *t) { return static_cast(t)->getDefaultConfig(); }); -} - -bool KWinWaylandBackend::isChangedConfig() const -{ - return std::any_of(m_devices.constBegin(), m_devices.constEnd(), - [] (QObject *t) { return static_cast(t)->isChangedConfig(); }); -} - -void KWinWaylandBackend::onDeviceAdded(QString sysName) -{ - if (std::any_of(m_devices.constBegin(), m_devices.constEnd(), - [sysName] (QObject *t) { return static_cast(t)->sysName() == sysName; })) { - return; - } - - QDBusInterface deviceIface(QStringLiteral("org.kde.KWin"), - QStringLiteral("/org/kde/KWin/InputDevice/") + sysName, - QStringLiteral("org.kde.KWin.InputDevice"), - QDBusConnection::sessionBus(), - this); - QVariant reply = deviceIface.property("touchpad"); - if (reply.isValid() && reply.toBool()) { - KWinWaylandTouchpad* tp = new KWinWaylandTouchpad(sysName); - if (!tp->init() || !tp->getConfig()) { - emit touchpadAdded(false); - return; - } - m_devices.append(tp); - qCDebug(KCM_TOUCHPAD).nospace() << "Touchpad connected: " << tp->name() << " (" << tp->sysName() << ")"; - emit touchpadAdded(true); - } -} - -void KWinWaylandBackend::onDeviceRemoved(QString sysName) -{ - QVector::const_iterator it = std::find_if(m_devices.constBegin(), m_devices.constEnd(), - [sysName] (QObject *t) { return static_cast(t)->sysName() == sysName; }); - if (it == m_devices.cend()) { - return; - } - - KWinWaylandTouchpad *tp = static_cast(*it); - qCDebug(KCM_TOUCHPAD).nospace() << "Touchpad disconnected: " << tp->name() << " (" << tp->sysName() << ")"; - - int index = it - m_devices.cbegin(); - m_devices.removeAt(index); - emit touchpadRemoved(index); -} diff --git a/kcms/touchpad/src/backends/kwin_wayland/kwinwaylandtouchpad.h b/kcms/touchpad/src/backends/kwin_wayland/kwinwaylandtouchpad.h deleted file mode 100644 --- a/kcms/touchpad/src/backends/kwin_wayland/kwinwaylandtouchpad.h +++ /dev/null @@ -1,458 +0,0 @@ -/* - * Copyright 2017 Roman Gilg - * - * 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. - */ - -#ifndef KWINWAYLANDTOUCHPAD_H -#define KWINWAYLANDTOUCHPAD_H - -#include -#include - -class QDBusInterface; - -class KWinWaylandTouchpad : public QObject -{ - Q_OBJECT - - // - // general - Q_PROPERTY(QString name READ name CONSTANT) - Q_PROPERTY(bool supportsDisableEvents READ supportsDisableEvents CONSTANT) - Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged) - - // - // advanced - Q_PROPERTY(Qt::MouseButtons supportedButtons READ supportedButtons CONSTANT) - - Q_PROPERTY(bool supportsLeftHanded READ supportsLeftHanded CONSTANT) - Q_PROPERTY(bool leftHandedEnabledByDefault READ leftHandedEnabledByDefault CONSTANT) - Q_PROPERTY(bool leftHanded READ isLeftHanded WRITE setLeftHanded NOTIFY leftHandedChanged) - - Q_PROPERTY(bool supportsDisableEventsOnExternalMouse READ supportsDisableEventsOnExternalMouse CONSTANT) - - Q_PROPERTY(bool supportsDisableWhileTyping READ supportsDisableWhileTyping CONSTANT) - Q_PROPERTY(bool disableWhileTypingEnabledByDefault READ disableWhileTypingEnabledByDefault CONSTANT) - Q_PROPERTY(bool disableWhileTyping READ isDisableWhileTyping WRITE setDisableWhileTyping NOTIFY disableWhileTypingChanged) - - Q_PROPERTY(bool supportsMiddleEmulation READ supportsMiddleEmulation CONSTANT) - Q_PROPERTY(bool middleEmulationEnabledByDefault READ middleEmulationEnabledByDefault CONSTANT) - Q_PROPERTY(bool middleEmulation READ isMiddleEmulation WRITE setMiddleEmulation NOTIFY middleEmulationChanged) - - // - // acceleration speed and profile - Q_PROPERTY(bool supportsPointerAcceleration READ supportsPointerAcceleration CONSTANT) - Q_PROPERTY(qreal pointerAcceleration READ pointerAcceleration WRITE setPointerAcceleration NOTIFY pointerAccelerationChanged) - - Q_PROPERTY(bool supportsPointerAccelerationProfileFlat READ supportsPointerAccelerationProfileFlat CONSTANT) - Q_PROPERTY(bool defaultPointerAccelerationProfileFlat READ defaultPointerAccelerationProfileFlat CONSTANT) - Q_PROPERTY(bool pointerAccelerationProfileFlat READ pointerAccelerationProfileFlat WRITE setPointerAccelerationProfileFlat NOTIFY pointerAccelerationProfileChanged) - - Q_PROPERTY(bool supportsPointerAccelerationProfileAdaptive READ supportsPointerAccelerationProfileAdaptive CONSTANT) - Q_PROPERTY(bool defaultPointerAccelerationProfileAdaptive READ defaultPointerAccelerationProfileAdaptive CONSTANT) - Q_PROPERTY(bool pointerAccelerationProfileAdaptive READ pointerAccelerationProfileAdaptive WRITE setPointerAccelerationProfileAdaptive NOTIFY pointerAccelerationProfileChanged) - - // - // tapping - Q_PROPERTY(int tapFingerCount READ tapFingerCount CONSTANT) - Q_PROPERTY(bool tapToClickEnabledByDefault READ tapToClickEnabledByDefault CONSTANT) - Q_PROPERTY(bool tapToClick READ isTapToClick WRITE setTapToClick NOTIFY tapToClickChanged) - - Q_PROPERTY(bool supportsLmrTapButtonMap READ supportsLmrTapButtonMap CONSTANT) - Q_PROPERTY(bool lmrTapButtonMapEnabledByDefault READ lmrTapButtonMapEnabledByDefault CONSTANT) - Q_PROPERTY(bool lmrTapButtonMap READ lmrTapButtonMap WRITE setLmrTapButtonMap NOTIFY lmrTapButtonMapChanged) - - Q_PROPERTY(bool tapAndDragEnabledByDefault READ tapAndDragEnabledByDefault CONSTANT) - Q_PROPERTY(bool tapAndDrag READ isTapAndDrag WRITE setTapAndDrag NOTIFY tapAndDragChanged) - - Q_PROPERTY(bool tapDragLockEnabledByDefault READ tapDragLockEnabledByDefault CONSTANT) - Q_PROPERTY(bool tapDragLock READ isTapDragLock WRITE setTapDragLock NOTIFY tapDragLockChanged) - - // - // scrolling - Q_PROPERTY(bool supportsNaturalScroll READ supportsNaturalScroll CONSTANT) - Q_PROPERTY(bool naturalScrollEnabledByDefault READ naturalScrollEnabledByDefault CONSTANT) - Q_PROPERTY(bool naturalScroll READ isNaturalScroll WRITE setNaturalScroll NOTIFY naturalScrollChanged) - - Q_PROPERTY(bool supportsScrollTwoFinger READ supportsScrollTwoFinger CONSTANT) - Q_PROPERTY(bool scrollTwoFingerEnabledByDefault READ scrollTwoFingerEnabledByDefault CONSTANT) - Q_PROPERTY(bool scrollTwoFinger READ isScrollTwoFinger WRITE setScrollTwoFinger NOTIFY scrollMethodChanged) - - Q_PROPERTY(bool supportsScrollEdge READ supportsScrollEdge CONSTANT) - Q_PROPERTY(bool scrollEdgeEnabledByDefault READ scrollEdgeEnabledByDefault CONSTANT) - Q_PROPERTY(bool scrollEdge READ isScrollEdge WRITE setScrollEdge NOTIFY scrollMethodChanged) - - Q_PROPERTY(bool supportsScrollOnButtonDown READ supportsScrollOnButtonDown CONSTANT) - Q_PROPERTY(bool scrollOnButtonDownEnabledByDefault READ scrollOnButtonDownEnabledByDefault CONSTANT) - Q_PROPERTY(bool scrollOnButtonDown READ isScrollOnButtonDown WRITE setScrollOnButtonDown NOTIFY scrollMethodChanged) - - Q_PROPERTY(quint32 defaultScrollButton READ defaultScrollButton CONSTANT) - Q_PROPERTY(quint32 scrollButton READ scrollButton WRITE setScrollButton NOTIFY scrollButtonChanged) - -public: - KWinWaylandTouchpad(QString dbusName); - ~KWinWaylandTouchpad() override; - - bool init(); - - bool getConfig(); - bool getDefaultConfig(); - bool applyConfig(); - bool isChangedConfig() const; - - // - // general - QString name() const { - return m_name.val; - } - QString sysName() const { - return m_sysName.val; - } - bool supportsDisableEvents() const { - return m_supportsDisableEvents.val; - } - void setEnabled(bool enabled) { - m_enabled.set(enabled); - } - bool isEnabled() const { - return m_enabled.val; - } - Qt::MouseButtons supportedButtons() const { - return m_supportedButtons.val; - } - - // - // advanced - bool supportsLeftHanded() const { - return m_supportsLeftHanded.val; - } - bool leftHandedEnabledByDefault() const { - return m_leftHandedEnabledByDefault.val; - } - bool isLeftHanded() const { - return m_leftHanded.val; - } - void setLeftHanded(bool set) { - m_leftHanded.set(set); - } - - bool supportsDisableEventsOnExternalMouse() const { - return m_supportsDisableEventsOnExternalMouse.val; - } - - bool supportsDisableWhileTyping() const { - return m_supportsDisableWhileTyping.val; - } - bool disableWhileTypingEnabledByDefault() const { - return m_disableWhileTypingEnabledByDefault.val; - } - bool isDisableWhileTyping() const { - return m_disableWhileTyping.val; - } - void setDisableWhileTyping(bool set) { - m_disableWhileTyping.set(set); - } - - bool supportsMiddleEmulation() const { - return m_supportsMiddleEmulation.val; - } - bool middleEmulationEnabledByDefault() const { - return m_middleEmulationEnabledByDefault.val; - } - bool isMiddleEmulation() const { - return m_middleEmulation.val; - } - void setMiddleEmulation(bool set) { - m_middleEmulation.set(set); - } - - // - // acceleration speed and profile - bool supportsPointerAcceleration() const { - return m_supportsPointerAcceleration.val; - } - qreal pointerAcceleration() const { - return m_pointerAcceleration.val; - } - void setPointerAcceleration(qreal acceleration) { - m_pointerAcceleration.set(acceleration); - } - - bool supportsPointerAccelerationProfileFlat() const { - return m_supportsPointerAccelerationProfileFlat.val; - } - bool defaultPointerAccelerationProfileFlat() const { - return m_defaultPointerAccelerationProfileFlat.val; - } - bool pointerAccelerationProfileFlat() const { - return m_pointerAccelerationProfileFlat.val; - } - void setPointerAccelerationProfileFlat(bool set) { - m_pointerAccelerationProfileFlat.set(set); - } - - bool supportsPointerAccelerationProfileAdaptive() const { - return m_supportsPointerAccelerationProfileAdaptive.val; - } - bool defaultPointerAccelerationProfileAdaptive() const { - return m_defaultPointerAccelerationProfileAdaptive.val; - } - bool pointerAccelerationProfileAdaptive() const { - return m_pointerAccelerationProfileAdaptive.val; - } - void setPointerAccelerationProfileAdaptive(bool set) { - m_pointerAccelerationProfileAdaptive.set(set); - } - - // - // tapping - int tapFingerCount() const { - return m_tapFingerCount.val; - } - bool tapToClickEnabledByDefault() const { - return m_tapToClickEnabledByDefault.val; - } - bool isTapToClick() const { - return m_tapToClick.val; - } - void setTapToClick(bool set) { - m_tapToClick.set(set); - } - - bool supportsLmrTapButtonMap() const { - return m_tapFingerCount.val > 1; - } - bool lmrTapButtonMapEnabledByDefault() const { - return m_lmrTapButtonMapEnabledByDefault.val; - } - bool lmrTapButtonMap() const { - return m_lmrTapButtonMap.val; - } - void setLmrTapButtonMap(bool set) { - m_lmrTapButtonMap.set(set); - } - - bool tapAndDragEnabledByDefault() const { - return m_tapAndDragEnabledByDefault.val; - } - bool isTapAndDrag() const { - return m_tapAndDrag.val; - } - void setTapAndDrag(bool set) { - m_tapAndDrag.set(set); - } - - bool tapDragLockEnabledByDefault() const { - return m_tapDragLockEnabledByDefault.val; - } - bool isTapDragLock() const { - return m_tapDragLock.val; - } - void setTapDragLock(bool set) { - m_tapDragLock.set(set); - } - - // - // scrolling - bool supportsNaturalScroll() const { - return m_supportsNaturalScroll.val; - } - bool naturalScrollEnabledByDefault() const { - return m_naturalScrollEnabledByDefault.val; - } - bool isNaturalScroll() const { - return m_naturalScroll.val; - } - void setNaturalScroll(bool set) { - m_naturalScroll.set(set); - } - - bool supportsScrollTwoFinger() const { - return m_supportsScrollTwoFinger.val; - } - bool scrollTwoFingerEnabledByDefault() const { - return m_scrollTwoFingerEnabledByDefault.val; - } - bool isScrollTwoFinger() const { - return m_isScrollTwoFinger.val; - } - void setScrollTwoFinger(bool set) { - m_isScrollTwoFinger.set(set); - } - - bool supportsScrollEdge() const { - return m_supportsScrollEdge.val; - } - bool scrollEdgeEnabledByDefault() const { - return m_scrollEdgeEnabledByDefault.val; - } - bool isScrollEdge() const { - return m_isScrollEdge.val; - } - void setScrollEdge(bool set) { - m_isScrollEdge.set(set); - } - - bool supportsScrollOnButtonDown() const { - return m_supportsScrollOnButtonDown.val; - } - bool scrollOnButtonDownEnabledByDefault() const { - return m_scrollOnButtonDownEnabledByDefault.val; - } - bool isScrollOnButtonDown() const { - return m_isScrollOnButtonDown.val; - } - void setScrollOnButtonDown(bool set) { - m_isScrollOnButtonDown.set(set); - } - - quint32 defaultScrollButton() const { - return m_defaultScrollButton.val; - } - quint32 scrollButton() const { - return m_scrollButton.val; - } - void setScrollButton(quint32 button) { - m_scrollButton.set(button); - } - -Q_SIGNALS: - void leftHandedChanged(); - void pointerAccelerationChanged(); - void pointerAccelerationProfileChanged(); - void enabledChanged(); - void tapToClickChanged(); - void tapAndDragChanged(); - void tapDragLockChanged(); - void lmrTapButtonMapChanged(); - void disableWhileTypingChanged(); - void middleEmulationChanged(); - void naturalScrollChanged(); - void scrollMethodChanged(); - void scrollButtonChanged(); - -private: - template - struct Prop { - explicit Prop(const QByteArray &dbusName) - : dbus(dbusName) - {} - - void set(T newVal) { - if (avail && val != newVal) { - val = newVal; - } - } - void set(const Prop &p) { - if (avail && val != p.val) { - val = p.val; - } - } - bool changed() const { - return avail && (old != val); - } - - QByteArray dbus; - bool avail; - T old; - T val; - }; - - template - bool valueLoader(Prop &prop); - - template - QString valueWriter(const Prop &prop); - - // - // general - Prop m_name = Prop("name"); - Prop m_sysName = Prop("sysName"); - Prop m_supportsDisableEvents = Prop("supportsDisableEvents"); - Prop m_enabled = Prop("enabled"); - - // - // advanced - Prop m_supportedButtons = Prop("supportedButtons"); - - Prop m_supportsLeftHanded = Prop("supportsLeftHanded"); - Prop m_leftHandedEnabledByDefault = Prop("leftHandedEnabledByDefault"); - Prop m_leftHanded = Prop("leftHanded"); - - Prop m_supportsDisableEventsOnExternalMouse = Prop("supportsDisableEventsOnExternalMouse"); - - Prop m_supportsDisableWhileTyping = Prop("supportsDisableWhileTyping"); - Prop m_disableWhileTypingEnabledByDefault = Prop("disableWhileTypingEnabledByDefault"); - Prop m_disableWhileTyping = Prop("disableWhileTyping"); - - Prop m_supportsMiddleEmulation = Prop("supportsMiddleEmulation"); - Prop m_middleEmulationEnabledByDefault = Prop("middleEmulationEnabledByDefault"); - Prop m_middleEmulation = Prop("middleEmulation"); - - // - // acceleration speed and profile - Prop m_supportsPointerAcceleration = Prop("supportsPointerAcceleration"); - Prop m_defaultPointerAcceleration = Prop("defaultPointerAcceleration"); - Prop m_pointerAcceleration = Prop("pointerAcceleration"); - - Prop m_supportsPointerAccelerationProfileFlat = Prop("supportsPointerAccelerationProfileFlat"); - Prop m_defaultPointerAccelerationProfileFlat = Prop("defaultPointerAccelerationProfileFlat"); - Prop m_pointerAccelerationProfileFlat = Prop("pointerAccelerationProfileFlat"); - - Prop m_supportsPointerAccelerationProfileAdaptive = Prop("supportsPointerAccelerationProfileAdaptive"); - Prop m_defaultPointerAccelerationProfileAdaptive = Prop("defaultPointerAccelerationProfileAdaptive"); - Prop m_pointerAccelerationProfileAdaptive = Prop("pointerAccelerationProfileAdaptive"); - - // - // tapping - Prop m_tapFingerCount = Prop("tapFingerCount"); - Prop m_tapToClickEnabledByDefault = Prop("tapToClickEnabledByDefault"); - Prop m_tapToClick = Prop("tapToClick"); - - Prop m_lmrTapButtonMapEnabledByDefault = Prop("lmrTapButtonMapEnabledByDefault"); - Prop m_lmrTapButtonMap = Prop("lmrTapButtonMap"); - - Prop m_tapAndDragEnabledByDefault = Prop("tapAndDragEnabledByDefault"); - Prop m_tapAndDrag = Prop("tapAndDrag"); - Prop m_tapDragLockEnabledByDefault = Prop("tapDragLockEnabledByDefault"); - Prop m_tapDragLock = Prop("tapDragLock"); - - // - // scrolling - Prop m_supportsNaturalScroll = Prop("supportsNaturalScroll"); - Prop m_naturalScrollEnabledByDefault = Prop("naturalScrollEnabledByDefault"); - Prop m_naturalScroll = Prop("naturalScroll"); - - Prop m_supportsScrollTwoFinger = Prop("supportsScrollTwoFinger"); - Prop m_scrollTwoFingerEnabledByDefault = Prop("scrollTwoFingerEnabledByDefault"); - Prop m_isScrollTwoFinger = Prop("scrollTwoFinger"); - - Prop m_supportsScrollEdge = Prop("supportsScrollEdge"); - Prop m_scrollEdgeEnabledByDefault = Prop("scrollEdgeEnabledByDefault"); - Prop m_isScrollEdge = Prop("scrollEdge"); - - Prop m_supportsScrollOnButtonDown = Prop("supportsScrollOnButtonDown"); - Prop m_scrollOnButtonDownEnabledByDefault = Prop("scrollOnButtonDownEnabledByDefault"); - Prop m_isScrollOnButtonDown = Prop("scrollOnButtonDown"); - - Prop m_defaultScrollButton = Prop("defaultScrollButton"); - Prop m_scrollButton = Prop("scrollButton"); - - - QDBusInterface *m_iface; -}; - -#endif diff --git a/kcms/touchpad/src/backends/kwin_wayland/kwinwaylandtouchpad.cpp b/kcms/touchpad/src/backends/kwin_wayland/kwinwaylandtouchpad.cpp deleted file mode 100644 --- a/kcms/touchpad/src/backends/kwin_wayland/kwinwaylandtouchpad.cpp +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright 2017 Roman Gilg - * - * 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 "kwinwaylandtouchpad.h" - -#include -#include -#include - -#include "logging.h" - -namespace { -template -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(reply.toInt()); } -} - -KWinWaylandTouchpad::KWinWaylandTouchpad(QString dbusName) -{ - m_iface = new QDBusInterface(QStringLiteral("org.kde.KWin"), - QStringLiteral("/org/kde/KWin/InputDevice/") + dbusName, - QStringLiteral("org.kde.KWin.InputDevice"), - QDBusConnection::sessionBus(), - this); -} - -KWinWaylandTouchpad::~KWinWaylandTouchpad() -{ - delete m_iface; -} - -bool KWinWaylandTouchpad::init() -{ - // need to do it here in order to populate combobox and handle events - return valueLoader(m_name) && valueLoader(m_sysName); -} - -bool KWinWaylandTouchpad::getConfig() -{ - bool success = true; - - // general - success &= valueLoader(m_supportsDisableEvents); - success &= valueLoader(m_supportsLeftHanded); - success &= valueLoader(m_supportedButtons); - success &= valueLoader(m_leftHandedEnabledByDefault); - success &= valueLoader(m_enabled); - success &= valueLoader(m_leftHanded); - // advanced - success &= valueLoader(m_supportsPointerAcceleration); - success &= valueLoader(m_supportsPointerAccelerationProfileFlat); - success &= valueLoader(m_supportsPointerAccelerationProfileAdaptive); - success &= valueLoader(m_supportsDisableWhileTyping); - success &= valueLoader(m_supportsDisableEventsOnExternalMouse); - success &= valueLoader(m_defaultPointerAcceleration); - success &= valueLoader(m_defaultPointerAccelerationProfileFlat); - success &= valueLoader(m_defaultPointerAccelerationProfileAdaptive); - success &= valueLoader(m_disableWhileTypingEnabledByDefault); - success &= valueLoader(m_leftHandedEnabledByDefault); - success &= valueLoader(m_pointerAcceleration); - success &= valueLoader(m_pointerAccelerationProfileFlat); - success &= valueLoader(m_pointerAccelerationProfileAdaptive); - success &= valueLoader(m_disableWhileTyping); - // tapping - success &= valueLoader(m_tapFingerCount); - success &= valueLoader(m_supportsMiddleEmulation); - success &= valueLoader(m_tapToClickEnabledByDefault); - success &= valueLoader(m_tapAndDragEnabledByDefault); - success &= valueLoader(m_tapDragLockEnabledByDefault); - success &= valueLoader(m_middleEmulationEnabledByDefault); - success &= valueLoader(m_tapToClick); - success &= valueLoader(m_tapAndDrag); - success &= valueLoader(m_tapDragLock); - success &= valueLoader(m_middleEmulation); - success &= valueLoader(m_lmrTapButtonMapEnabledByDefault); - success &= valueLoader(m_lmrTapButtonMap); - // scrolling modes avail - success &= valueLoader(m_supportsNaturalScroll); - success &= valueLoader(m_supportsScrollTwoFinger); - success &= valueLoader(m_supportsScrollEdge); - success &= valueLoader(m_supportsScrollOnButtonDown); - // default scrolling modes - success &= valueLoader(m_naturalScrollEnabledByDefault); - success &= valueLoader(m_scrollTwoFingerEnabledByDefault); - success &= valueLoader(m_scrollEdgeEnabledByDefault); - success &= valueLoader(m_scrollOnButtonDownEnabledByDefault); - success &= valueLoader(m_defaultScrollButton); - // current scrolling mode - success &= valueLoader(m_naturalScroll); - success &= valueLoader(m_isScrollTwoFinger); - success &= valueLoader(m_isScrollEdge); - success &= valueLoader(m_isScrollOnButtonDown); - success &= valueLoader(m_scrollButton); - - return success; -} - -bool KWinWaylandTouchpad::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_disableWhileTyping.set(m_disableWhileTypingEnabledByDefault); - - m_tapToClick.set(m_tapToClickEnabledByDefault); - m_tapAndDrag.set(m_tapAndDragEnabledByDefault); - m_tapDragLock.set(m_tapDragLockEnabledByDefault); - m_middleEmulation.set(m_middleEmulationEnabledByDefault); - - m_naturalScroll.set(m_naturalScrollEnabledByDefault); - m_isScrollTwoFinger.set(m_scrollTwoFingerEnabledByDefault); - m_isScrollEdge.set(m_scrollEdgeEnabledByDefault); - m_isScrollOnButtonDown.set(m_scrollOnButtonDownEnabledByDefault); - - return true; -} - -bool KWinWaylandTouchpad::applyConfig() -{ - QVector msgs; - - msgs << valueWriter(m_enabled) - << valueWriter(m_leftHanded) - << valueWriter(m_pointerAcceleration) - << valueWriter(m_defaultPointerAccelerationProfileFlat) - << valueWriter(m_defaultPointerAccelerationProfileAdaptive) - - << valueWriter(m_disableWhileTyping) - << valueWriter(m_middleEmulation) - - << valueWriter(m_tapToClick) - << valueWriter(m_tapAndDrag) - << valueWriter(m_tapDragLock) - << valueWriter(m_lmrTapButtonMap) - - << valueWriter(m_naturalScroll) - << valueWriter(m_isScrollTwoFinger) - << valueWriter(m_isScrollEdge) - << valueWriter(m_isScrollOnButtonDown) - << valueWriter(m_scrollButton); - - bool success = true; - QString error_msg; - - for (QString m : msgs) { - if (!m.isNull()) { - qCCritical(KCM_TOUCHPAD) << "in error:" << m; - if (!success) { - error_msg.append("\n"); - } - error_msg.append(m); - success = false; - } - } - - if (!success) { - qCCritical(KCM_TOUCHPAD) << error_msg; - } - return success; -} - -bool KWinWaylandTouchpad::isChangedConfig() const -{ - return m_enabled.changed() || - m_leftHanded.changed() || - m_pointerAcceleration.changed() || - m_pointerAccelerationProfileFlat.changed() || - m_pointerAccelerationProfileAdaptive.changed() || - m_disableWhileTyping.changed() || - m_middleEmulation.changed() || - m_tapToClick.changed() || - m_tapAndDrag.changed() || - m_tapDragLock.changed() || - m_lmrTapButtonMap.changed() || - m_naturalScroll.changed() || - m_isScrollTwoFinger.changed() || - m_isScrollEdge.changed() || - m_isScrollOnButtonDown.changed() || - m_scrollButton.changed(); -} - -template -QString KWinWaylandTouchpad::valueWriter(const Prop &prop) -{ - if (!prop.changed()) { - return QString(); - } - m_iface->setProperty(prop.dbus, prop.val); - QDBusError error = m_iface->lastError(); - if (error.isValid()) { - qCCritical(KCM_TOUCHPAD) << error.message(); - return error.message(); - } - return QString(); -} - -template -bool KWinWaylandTouchpad::valueLoader(Prop &prop) -{ - QVariant reply = m_iface->property(prop.dbus); - if (!reply.isValid()) { - qCCritical(KCM_TOUCHPAD) << "Error on d-bus read of" << prop.dbus; - prop.avail = false; - return false; - } - prop.avail = true; - - T replyValue = valueLoaderPart(reply); - - prop.old = replyValue; - prop.val = replyValue; - return true; -} diff --git a/kcms/touchpad/src/kcm/libinput/main.qml b/kcms/touchpad/src/kcm/libinput/main.qml deleted file mode 100644 --- a/kcms/touchpad/src/kcm/libinput/main.qml +++ /dev/null @@ -1,562 +0,0 @@ -/* - * Copyright 2017 Roman Gilg - * Copyright 2018 Furkan Tokac - * - * 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. - */ - -import QtQuick 2.7 -import QtQuick.Controls 2.0 as Controls -import QtQuick.Layouts 1.3 as Layouts - -import org.kde.kcm 1.1 as KCM -import org.kde.kirigami 2.4 as Kirigami - -// TODO: Change ScrollablePage as KCM.SimpleKCM -// after rewrite the KCM in KConfigModule. -Kirigami.ScrollablePage { - id: root - - spacing: Kirigami.Units.smallSpacing - - property size minimumSizeHint: Qt.size(formLayout.width/2, deviceSelector.height) - - property alias deviceIndex: deviceSelector.currentIndex - signal changeSignal() - - property QtObject touchpad - property int touchpadCount: backend.touchpadCount - - property bool loading: false - - function resetModel(index) { - touchpadCount = backend.touchpadCount - formLayout.enabled = touchpadCount - deviceSelector.enabled = touchpadCount > 1 - - loading = true - if (touchpadCount) { - touchpad = deviceModel[index] - deviceSelector.model = deviceModel - deviceSelector.currentIndex = index - console.log("Touchpad configuration of device '" + - (index + 1) + " : " + touchpad.name + "' opened") - } else { - deviceSelector.model = [""] - console.log("No touchpad found") - } - loading = false - } - - function syncValuesFromBackend() { - loading = true - - deviceEnabled.load() - dwt.load() - leftHanded.load() - accelSpeed.load() - accelProfile.load() - tapToClick.load() - tapAndDrag.load() - tapAndDragLock.load() - multiTap.load() - scrollMethod.load() - naturalScroll.load() - - loading = false - } - - Kirigami.FormLayout { - id: formLayout - - // Device - Controls.ComboBox { - Kirigami.FormData.label: i18n("Device:") - id: deviceSelector - - enabled: touchpadCount > 1 - Layouts.Layout.fillWidth: true - model: deviceModel - textRole: "name" - - onCurrentIndexChanged: { - if (touchpadCount) { - touchpad = deviceModel[currentIndex] - if (!loading) { - changeSignal() - } - console.log("Touchpad configuration of device '" + - (currentIndex+1) + " : " + touchpad.name + "' opened") - } - root.syncValuesFromBackend() - } - } - - Kirigami.Separator { - } - - // General settings - Controls.CheckBox { - Kirigami.FormData.label: i18n("General:") - id: deviceEnabled - text: i18n("Device enabled") - - hoverEnabled: true - Controls.ToolTip { - text: i18n("Accept input through this device.") - visible: parent.hovered - delay: 1000 - } - - function load() { - if (!formLayout.enabled) { - checked = false - return - } - enabled = touchpad.supportsDisableEvents - checked = enabled && touchpad.enabled - } - - onCheckedChanged: { - if (enabled && !root.loading) { - touchpad.enabled = checked - root.changeSignal() - } - } - } - - Controls.CheckBox { - id: dwt - text: i18n("Disable while typing") - - hoverEnabled: true - Controls.ToolTip { - text: i18n("Disable touchpad while typing to prevent accidental inputs.") - visible: parent.hovered - delay: 1000 - } - - function load() { - if (!formLayout.enabled) { - checked = false - return - } - enabled = touchpad.supportsDisableWhileTyping - checked = enabled && touchpad.disableWhileTyping - } - - onCheckedChanged: { - if (enabled && !root.loading) { - touchpad.disableWhileTyping = checked - root.changeSignal() - } - } - } - - Controls.CheckBox { - id: leftHanded - text: i18n("Left handed mode") - - hoverEnabled: true - Controls.ToolTip { - text: i18n("Swap left and right buttons.") - visible: parent.hovered - delay: 1000 - } - - function load() { - if (!formLayout.enabled) { - checked = false - return - } - enabled = touchpad.supportsLeftHanded - checked = enabled && touchpad.leftHanded - } - - onCheckedChanged: { - if (enabled && !root.loading) { - touchpad.leftHanded = checked - root.changeSignal() - } - } - } - - Controls.CheckBox { - id: middleEmulation - text: i18n("Press left and right buttons for middle click") - - hoverEnabled: true - Controls.ToolTip { - text: i18n("Clicking left and right button simultaneously sends middle button click.") - visible: parent.hovered - delay: 1000 - } - - function load() { - if (!formLayout.enabled) { - checked = false - return - } - enabled = touchpad.supportsMiddleEmulation - checked = enabled && touchpad.middleEmulation - } - - onCheckedChanged: { - if (enabled && !root.loading) { - touchpad.middleEmulation = checked - root.changeSignal() - } - } - } - - Kirigami.Separator { - } - - // Acceleration - Controls.Slider { - Kirigami.FormData.label: i18n("Pointer speed:") - id: accelSpeed - - from: 1 - to: 11 - stepSize: 1 - - function load() { - enabled = touchpad.supportsPointerAcceleration - if (!enabled) { - value = 0.1 - return - } - // transform libinput's pointer acceleration range [-1, 1] to slider range [1, 11] - value = 6 + touchpad.pointerAcceleration / 0.2 - } - - onValueChanged: { - if (touchpad != undefined && enabled && !root.loading) { - // transform slider range [1, 11] to libinput's pointer acceleration range [-1, 1] - // by *10 and /10, we ignore the floating points after 1 digit. This prevents from - // having a libinput value like 0.60000001 - touchpad.pointerAcceleration = Math.round(((value-6) * 0.2) * 10) / 10 - root.changeSignal() - } - } - } - - Layouts.ColumnLayout { - Kirigami.FormData.label: i18n("Acceleration profile:") - Kirigami.FormData.buddyFor: accelProfileFlat - id: accelProfile - spacing: Kirigami.Units.smallSpacing - - function load() { - enabled = touchpad.supportsPointerAccelerationProfileAdaptive - - if (!enabled) { - accelProfileFlat.checked = false - accelProfileAdaptive.checked = false - return - } - - if(touchpad.pointerAccelerationProfileAdaptive) { - accelProfileAdaptive.checked = true - } else { - accelProfileFlat.checked = true - } - } - - function syncCurrent() { - if (enabled && !root.loading) { - touchpad.pointerAccelerationProfileFlat = accelProfileFlat.checked - touchpad.pointerAccelerationProfileAdaptive = accelProfileAdaptive.checked - root.changeSignal() - } - } - - Controls.RadioButton { - id: accelProfileFlat - text: i18n("Flat") - - hoverEnabled: true - Controls.ToolTip { - text: i18n("Cursor moves the same distance as finger.") - visible: parent.hovered - delay: 1000 - } - onCheckedChanged: accelProfile.syncCurrent() - } - - Controls.RadioButton { - id: accelProfileAdaptive - text: i18n("Adaptive") - - hoverEnabled: true - Controls.ToolTip { - text: i18n("Cursor travel distance depends on movement speed of finger.") - visible: parent.hovered - delay: 1000 - } - onCheckedChanged: accelProfile.syncCurrent() - } - } - - Kirigami.Separator { - } - - // Tapping - Controls.CheckBox { - Kirigami.FormData.label: i18n("Tapping:") - id: tapToClick - text: i18n("Tap-to-click") - - hoverEnabled: true - Controls.ToolTip { - text: i18n("Single tap is left button click.") - visible: parent.hovered - delay: 1000 - } - - function load() { - enabled = touchpad.tapFingerCount > 0 - checked = enabled && touchpad.tapToClick - } - - function updateDependents() { - loading = true - tapAndDrag.load() - tapAndDragLock.load() - multiTap.load() - loading = false - } - - onCheckedChanged: { - if (enabled && !root.loading) { - touchpad.tapToClick = checked - updateDependents() - root.changeSignal() - } - } - } - - Controls.CheckBox { - id: tapAndDrag - text: i18n("Tap-and-drag") - - hoverEnabled: true - Controls.ToolTip { - text: i18n("Sliding over touchpad directly after tap drags.") - visible: parent.hovered - delay: 1000 - } - - function load() { - enabled = touchpad.tapFingerCount > 0 && tapToClick.checked - checked = enabled && touchpad.tapAndDrag - } - - function updateDependents() { - loading = true - tapAndDragLock.load() - loading = false - } - - onCheckedChanged: { - if (enabled && !root.loading) { - touchpad.tapAndDrag = checked - updateDependents() - root.changeSignal() - } - } - } - - Controls.CheckBox { - id: tapAndDragLock - text: i18n("Tap-and-drag lock") - - hoverEnabled: true - Controls.ToolTip { - text: i18n("Dragging continues after a short finger lift.") - visible: parent.hovered - delay: 1000 - } - - function load() { - enabled = touchpad.tapFingerCount > 0 && tapAndDrag.checked - checked = enabled && touchpad.tapDragLock - } - - onCheckedChanged: { - if (enabled && !root.loading) { - touchpad.tapDragLock = checked - root.changeSignal() - } - } - } - - Layouts.ColumnLayout { - Kirigami.FormData.label: i18n("Two-finger tap:") - Kirigami.FormData.buddyFor: multiTapRightClick - id: multiTap - - spacing: Kirigami.Units.smallSpacing - - function load() { - enabled = touchpad.supportsLmrTapButtonMap && tapToClick.checked - if (touchpad.tapFingerCount > 2) { - multiTapRightClick.text = i18n("Right-click (three-finger tap to middle-click)") - multiTapRightClickToolTip.text = i18n("Tap with two fingers to right-click, tap with three fingers to middle-click.") - - multiTapMiddleClick.text = i18n("Middle-click (three-finger tap right-click)") - multiTapMiddleClickToolTip.text = i18n("Tap with two fingers to middle-click, tap with three fingers to right-click.") - } else { - multiTapRightClick.text = i18n("Righ-click") - multiTapRightClickToolTip.text = i18n("Tap with two fingers to right-click.") - - multiTapMiddleClick.text = i18n("Middle-click") - multiTapMiddleClickToolTip.text = i18n("Tap with two fingers to middle-click.") - } - - if (!enabled) { - multiTapRightClick.checked = false - multiTapMiddleClick.checked = false - return - } - - if(touchpad.lmrTapButtonMap) { - multiTapMiddleClick.checked = true - } else { - multiTapRightClick.checked = true - } - } - - function syncCurrent() { - if (enabled && !root.loading) { - touchpad.lmrTapButtonMap = multiTapMiddleClick.checked - root.changeSignal() - } - } - - Controls.RadioButton { - id: multiTapRightClick - // text: is handled dynamically on load. - - hoverEnabled: true - Controls.ToolTip { - id: multiTapRightClickToolTip - visible: parent.hovered - delay: 1000 - // text: is handled dynamically on load. - } - onCheckedChanged: multiTap.syncCurrent() - } - - Controls.RadioButton { - id: multiTapMiddleClick - // text: is handled dynamically on load. - - hoverEnabled: true - Controls.ToolTip { - id: multiTapMiddleClickToolTip - visible: parent.hovered - delay: 1000 - // text: is handled dynamically on load. - } - onCheckedChanged: multiTap.syncCurrent() - } - } - - Kirigami.Separator { - } - - // Scrolling - Layouts.ColumnLayout { - Kirigami.FormData.label: i18n("Scrolling:") - Kirigami.FormData.buddyFor: scrollMethodTwoFingers - id: scrollMethod - - spacing: Kirigami.Units.smallSpacing - - function load() { - scrollMethodTwoFingers.enabled = touchpad.supportsScrollTwoFinger - scrollMethodTouchpadEdges.enabled = touchpad.supportsScrollEdge - - if(scrollMethodTouchpadEdges.enabled && touchpad.scrollEdge) { - scrollMethodTouchpadEdges.checked = formLayout.enabled - } else { - scrollMethodTwoFingers.checked = formLayout.enabled - } - } - - function syncCurrent() { - if (enabled && !root.loading) { - touchpad.scrollTwoFinger = scrollMethodTwoFingers.checked - touchpad.scrollEdge = scrollMethodTouchpadEdges.checked - root.changeSignal() - } - loading = true - naturalScroll.load() - loading = false - } - - Controls.RadioButton { - id: scrollMethodTwoFingers - text: i18n("Two fingers") - - hoverEnabled: true - Controls.ToolTip { - text: i18n("Slide with two fingers scrolls.") - visible: parent.hovered - delay: 1000 - } - } - - Controls.RadioButton { - id: scrollMethodTouchpadEdges - text: i18n("Touchpad edges") - - hoverEnabled: true - Controls.ToolTip { - text: i18n("Slide on the touchpad edges scrolls.") - visible: parent.hovered - delay: 1000 - } - onCheckedChanged: scrollMethod.syncCurrent() - } - } - - Controls.CheckBox { - id: naturalScroll - text: i18n("Invert scroll direction (Natural scrolling)") - - function load() { - enabled = touchpad.supportsNaturalScroll - checked = enabled && touchpad.naturalScroll - } - - onCheckedChanged: { - if (enabled && !root.loading) { - touchpad.naturalScroll = checked - root.changeSignal() - } - } - - hoverEnabled: true - Controls.ToolTip { - text: i18n("Touchscreen like scrolling.") - visible: parent.hovered - delay: 1000 - } - } - } // END Kirigami.FormLayout -} // END Kirigami.ScrollablePage diff --git a/kcms/touchpad/src/kcm/libinput/touchpadconfiglibinput.h b/kcms/touchpad/src/kcm/libinput/touchpadconfiglibinput.h deleted file mode 100644 --- a/kcms/touchpad/src/kcm/libinput/touchpadconfiglibinput.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2017 Roman Gilg - * - * 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. - */ - -#ifndef TOUCHPADCONFIGLIBINPUT_H -#define TOUCHPADCONFIGLIBINPUT_H - -#include "../touchpadconfigplugin.h" - -class TouchpadBackend; -class QHideEvent; -class QQuickWidget; -class KMessageWidget; - -class TouchpadConfigLibinput : public TouchpadConfigPlugin -{ - Q_OBJECT - -public: - explicit TouchpadConfigLibinput(TouchpadConfigContainer *parent, - const QVariantList &args = QVariantList()); - virtual ~TouchpadConfigLibinput() {} - - void load() override; - void save() override; - void defaults() override; - - QSize sizeHint() const override; - QSize minimumSizeHint() const override; - - void hideEvent(QHideEvent *) override {} - -private Q_SLOTS: - void onChange(); - void onTouchpadAdded(bool success); - void onTouchpadRemoved(int index); - -private: - void hideErrorMessage(); - - QQuickWidget *m_view; - KMessageWidget *m_errorMessage; - - bool m_initError; -}; - -#endif // TOUCHPADCONFIGLIBINPUT_H diff --git a/kcms/touchpad/src/kcm/libinput/touchpadconfiglibinput.cpp b/kcms/touchpad/src/kcm/libinput/touchpadconfiglibinput.cpp deleted file mode 100644 --- a/kcms/touchpad/src/kcm/libinput/touchpadconfiglibinput.cpp +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright 2017 Roman Gilg - * - * 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 "touchpadconfiglibinput.h" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "../touchpadconfigcontainer.h" -#include "touchpadbackend.h" - -#include "version.h" - -TouchpadConfigLibinput::TouchpadConfigLibinput(TouchpadConfigContainer *parent, const QVariantList &args) - : TouchpadConfigPlugin(parent) -{ - KAboutData* data = new KAboutData(QStringLiteral("kcm_touchpad"), - i18n("Touchpad KCM"), - TOUCHPAD_KCM_VERSION, - i18n("System Settings module for managing your touchpad"), - KAboutLicense::GPL_V2, - i18n("Copyright © 2016 Roman Gilg"), - QString()); - - data->addAuthor(i18n("Roman Gilg"), - i18n("Developer"), - QStringLiteral("subdiff@gmail.com")); - - m_parent->setAboutData(data); - - m_backend = TouchpadBackend::implementation(); - m_initError = !m_backend->errorString().isNull(); - - m_view = new QQuickWidget(this); - - m_errorMessage = new KMessageWidget(this); - m_errorMessage->setCloseButtonVisible(false); - m_errorMessage->setWordWrap(true); - m_errorMessage->setVisible(false); - - QVBoxLayout *layout = new QVBoxLayout(parent); - - layout->addWidget(m_errorMessage); - layout->addWidget(m_view); - parent->setLayout(layout); - - m_view->setResizeMode(QQuickWidget::SizeRootObjectToView); - m_view->setClearColor(Qt::transparent); - m_view->setAttribute(Qt::WA_AlwaysStackOnTop); - - m_view->rootContext()->setContextProperty("backend", m_backend); - m_view->rootContext()->setContextProperty("deviceModel", QVariant::fromValue(m_backend->getDevices().toList())); - - KDeclarative::KDeclarative kdeclarative; - kdeclarative.setDeclarativeEngine(m_view->engine()); - kdeclarative.setupBindings(); - m_view->setSource(QUrl("qrc:/libinput/main.qml")); - - if (m_initError) { - m_errorMessage->setMessageType(KMessageWidget::Error); - m_errorMessage->setText(m_backend->errorString()); - QMetaObject::invokeMethod(m_errorMessage, "animatedShow", - Qt::QueuedConnection); - } else { - connect(m_backend, SIGNAL(touchpadAdded(bool)), this, SLOT(onTouchpadAdded(bool))); - connect(m_backend, SIGNAL(touchpadRemoved(int)), this, SLOT(onTouchpadRemoved(int))); - connect(m_view->rootObject(), SIGNAL(changeSignal()), this, SLOT(onChange())); - } - - m_view->show(); -} - -QSize TouchpadConfigLibinput::sizeHint() const -{ - return QQmlProperty::read(m_view->rootObject(), "sizeHint").toSize(); -} - -QSize TouchpadConfigLibinput::minimumSizeHint() const -{ - return QQmlProperty::read(m_view->rootObject(), "minimumSizeHint").toSize(); -} - -void TouchpadConfigLibinput::load() -{ - // in case of critical init error in backend, don't try - if (m_initError) { - return; - } - - if (!m_backend->getConfig()) { - m_errorMessage->setMessageType(KMessageWidget::Error); - m_errorMessage->setText(i18n("Error while loading values. See logs for more informations. Please restart this configuration module.")); - m_errorMessage->animatedShow(); - } else { - if (!m_backend->touchpadCount()) { - m_errorMessage->setMessageType(KMessageWidget::Information); - m_errorMessage->setText(i18n("No touchpad found. Connect touchpad now.")); - m_errorMessage->animatedShow(); - } - } - QMetaObject::invokeMethod(m_view->rootObject(), "syncValuesFromBackend"); -} - -void TouchpadConfigLibinput::save() -{ - if (!m_backend->applyConfig()) { - m_errorMessage->setMessageType(KMessageWidget::Error); - m_errorMessage->setText(i18n("Not able to save all changes. See logs for more informations. Please restart this configuration module and try again.")); - m_errorMessage->animatedShow(); - } else { - hideErrorMessage(); - } - // load newly written values - load(); - // in case of error, config still in changed state - emit m_parent->changed(m_backend->isChangedConfig()); -} - -void TouchpadConfigLibinput::defaults() -{ - // in case of critical init error in backend, don't try - if (m_initError) { - return; - } - - if (!m_backend->getDefaultConfig()) { - m_errorMessage->setMessageType(KMessageWidget::Error); - m_errorMessage->setText(i18n("Error while loading default values. Failed to set some options to their default values.")); - m_errorMessage->animatedShow(); - } - QMetaObject::invokeMethod(m_view->rootObject(), "syncValuesFromBackend"); - emit m_parent->changed(m_backend->isChangedConfig()); -} - -void TouchpadConfigLibinput::onChange() -{ - if (!m_backend->touchpadCount()) { - return; - } - hideErrorMessage(); - emit m_parent->changed(m_backend->isChangedConfig()); -} - -void TouchpadConfigLibinput::onTouchpadAdded(bool success) -{ - QQuickItem *rootObj = m_view->rootObject(); - - if (!success) { - m_errorMessage->setMessageType(KMessageWidget::Error); - m_errorMessage->setText(i18n("Error while adding newly connected device. Please reconnect it and restart this configuration module.")); - } - - int activeIndex; - if (m_backend->touchpadCount() == 1) { - // if no touchpad was connected previously, show the new device and hide the no-device-message - activeIndex = 0; - hideErrorMessage(); - } else { - activeIndex = QQmlProperty::read(rootObj, "deviceIndex").toInt(); - } - m_view->rootContext()->setContextProperty("deviceModel", QVariant::fromValue(m_backend->getDevices())); - QMetaObject::invokeMethod(rootObj, "resetModel", Q_ARG(QVariant, activeIndex)); - QMetaObject::invokeMethod(rootObj, "syncValuesFromBackend"); -} - -void TouchpadConfigLibinput::onTouchpadRemoved(int index) -{ - QQuickItem *rootObj = m_view->rootObject(); - - int activeIndex = QQmlProperty::read(rootObj, "deviceIndex").toInt(); - if (activeIndex == index) { - m_errorMessage->setMessageType(KMessageWidget::Information); - if (m_backend->touchpadCount()) { - m_errorMessage->setText(i18n("Touchpad disconnected. Closed its setting dialog.")); - } else { - m_errorMessage->setText(i18n("Touchpad disconnected. No other touchpads found.")); - } - m_errorMessage->animatedShow(); - activeIndex = 0; - } else { - if (index < activeIndex) { - activeIndex--; - } - } - m_view->rootContext()->setContextProperty("deviceModel", QVariant::fromValue(m_backend->getDevices())); - QMetaObject::invokeMethod(m_view->rootObject(), "resetModel", Q_ARG(QVariant, activeIndex)); - QMetaObject::invokeMethod(rootObj, "syncValuesFromBackend"); - - emit m_parent->changed(m_backend->isChangedConfig()); -} - -void TouchpadConfigLibinput::hideErrorMessage() -{ - if (m_errorMessage->isVisible()) { - m_errorMessage->animatedHide(); - } -} diff --git a/kcms/touchpad/src/kcm/resources.qrc b/kcms/touchpad/src/kcm/resources.qrc deleted file mode 100644 --- a/kcms/touchpad/src/kcm/resources.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - libinput/main.qml - - diff --git a/kcms/touchpad/CMakeLists.txt b/kcms/touchpadx/CMakeLists.txt copy from kcms/touchpad/CMakeLists.txt copy to kcms/touchpadx/CMakeLists.txt --- a/kcms/touchpad/CMakeLists.txt +++ b/kcms/touchpadx/CMakeLists.txt @@ -1,6 +1,6 @@ find_package(KDED ${KF5_MIN_VERSION} CONFIG REQUIRED) -add_definitions(-DTRANSLATION_DOMAIN=\"kcm_touchpad\") +add_definitions(-DTRANSLATION_DOMAIN=\"kcm_touchpadx\") set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules diff --git a/kcms/touchpadx/COPYING b/kcms/touchpadx/COPYING new file mode 100644 --- /dev/null +++ b/kcms/touchpadx/COPYING @@ -0,0 +1,347 @@ +NOTE! The GPL below is copyrighted by the Free Software Foundation, but +the instance of code that it refers to (the kde programs) are copyrighted +by the authors who actually wrote it. + +--------------------------------------------------------------------------- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + 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 + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + diff --git a/kcms/touchpadx/Messages.sh b/kcms/touchpadx/Messages.sh new file mode 100644 --- /dev/null +++ b/kcms/touchpadx/Messages.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +$EXTRACTRC `find src -path src/applet -prune -o \( -name \*.rc -o -name \*.ui -o -name \*.kcfg \) -print` >> rc.cpp +$XGETTEXT rc.cpp `find src -path src/applet -prune -o \( -name \*.cpp -o -name \*.h \) -print` -o $podir/kcm_touchpadx.pot + +$XGETTEXT `find src/applet -name \*.qml -o -name \*.js` -o $podir/plasma_applet_touchpad.pot diff --git a/kcms/touchpad/README.md b/kcms/touchpadx/README.md copy from kcms/touchpad/README.md copy to kcms/touchpadx/README.md --- a/kcms/touchpad/README.md +++ b/kcms/touchpadx/README.md @@ -1,10 +1,10 @@ -Touchpad KCM +TouchpadX KCM ============ -* KCModule (Wayland + X) -* Daemon (X only) +* KCModule +* Daemon - Automatically enable/disable touchpad when typing and/or when mouse is plugged in - Enable/disable touchpad with keyboard shortcuts -* Applet (X only) +* Applet - Shows touchpad's state - Toggle touchpad with single click diff --git a/kcms/touchpad/cmake/modules/COPYING-CMAKE-SCRIPTS b/kcms/touchpadx/cmake/modules/COPYING-CMAKE-SCRIPTS rename from kcms/touchpad/cmake/modules/COPYING-CMAKE-SCRIPTS rename to kcms/touchpadx/cmake/modules/COPYING-CMAKE-SCRIPTS diff --git a/kcms/touchpad/cmake/modules/FindX11_XCB.cmake b/kcms/touchpadx/cmake/modules/FindX11_XCB.cmake rename from kcms/touchpad/cmake/modules/FindX11_XCB.cmake rename to kcms/touchpadx/cmake/modules/FindX11_XCB.cmake diff --git a/kcms/touchpad/cmake/modules/FindXCB.cmake b/kcms/touchpadx/cmake/modules/FindXCB.cmake rename from kcms/touchpad/cmake/modules/FindXCB.cmake rename to kcms/touchpadx/cmake/modules/FindXCB.cmake diff --git a/kcms/touchpad/icon/128-devices-input-touchpad.png b/kcms/touchpadx/icon/128-devices-input-touchpad.png rename from kcms/touchpad/icon/128-devices-input-touchpad.png rename to kcms/touchpadx/icon/128-devices-input-touchpad.png index ffc3d8707ac1167d6709d5415121029203bb919b..ffc3d8707ac1167d6709d5415121029203bb919b GIT binary patch literal 5303 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 literal 5303 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 diff --git a/kcms/touchpad/icon/16-devices-input-touchpad.png b/kcms/touchpadx/icon/16-devices-input-touchpad.png rename from kcms/touchpad/icon/16-devices-input-touchpad.png rename to kcms/touchpadx/icon/16-devices-input-touchpad.png index 329422dd83c9401707101e4949410e8bb995763c..329422dd83c9401707101e4949410e8bb995763c GIT binary patch literal 920 zc%17D@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>dl)sZ{50e$BrF9GB!3gIXQXJqD4TXjvhUF@#4ixmoA++ zaboi1$unlmNKH+xudiRVYSsGn>swn}OG-+BW_EOR01fx@@&X#((9lp120(LygM)!0 zKq(+uP*4DLBm)dQdi3bcn>VjtzkdGw`GW@!UcP+!>eZ{KPoKVh`}Y0&_a8od`1tYT zyLazCfByXS>(_7JzJ2-f<y|BBHfz?b{{DWT?|^PTdGh4`{riDVU9x1!ym|AUJb422&i(uM@7=q1_3Bli zGkm_JuK-dGB|(0`Xp!;q^HE*`G;#a+3+FBX(fJEIzJ3OQmmg28{SI`=*YB5ap4@f! z?uE5?@1C^koG@WxWy{hfOJ;d9GBXK#x}}1mCCS^}g`tC0)&t1lEbxdd2Bw4GAk4^J zZaNz%c-zy(F+}2Wa)JZ9&lw$$hN-=cbDM=Z3kr=tSXfvoHW=$O&+lHndiG>x0SjPE z?)uEkdS{M}&E7qG_wKE+nR9@t&+gv7x_|%vF*e58Dd;-d#qIldP*HK=!MetIiA+3A zd8kxvX14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>dl)sZ{50e$BrF9GB!3gIXQXJqD4TXjvhUF@#4ixmoA++ zaboi1$unlmNKH+xudiRVYSsGn>swn}OG-+BW_EOR01fx@@&X#((9lp120(LygM)!0 zKq(+uP*4DLBm)dQdi3bcn>VjtzkdGw`GW@!UcP+!>eZ{KPoKVh`}Y0&_a8od`1tYT zyLazCfByXS>(_7JzJ2-f<y|BBHfz?b{{DWT?|^PTdGh4`{riDVU9x1!ym|AUJb422&i(uM@7=q1_3Bli zGkm_JuK-dGB|(0`Xp!;q^HE*`G;#a+3+FBX(fJEIzJ3OQmmg28{SI`=*YB5ap4@f! z?uE5?@1C^koG@WxWy{hfOJ;d9GBXK#x}}1mCCS^}g`tC0)&t1lEbxdd2Bw4GAk4^J zZaNz%c-zy(F+}2Wa)JZ9&lw$$hN-=cbDM=Z3kr=tSXfvoHW=$O&+lHndiG>x0SjPE z?)uEkdS{M}&E7qG_wKE+nR9@t&+gv7x_|%vF*e58Dd;-d#qIldP*HK=!MetIiA+3A zd8kxvX!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$Ysfq`*$fKP}kP=SGgft#CK zR8&+G}*zyp`f4usAj^135ymj+OT26 zjvYI8?%cU?<3=F2q@<*xq5`NMs0+xQGG$6@Yim_iRb^$Rlao_GK*03r(-$sW7!eT> z7#P^m(b3b>E2|6!Dk>`4+S+=0dRkgqnwpvrL7@4UFJHcR@gmS|Cr+Gr^XAQ~SFc{b zetrG=_2b8nzkK=f+O=zM-@bkS{{4p!A3lEk`03N9&!0bk`SRuK*RS8cef$3X`;Q+# ze*XOV?%lgzzkdDx{rk_KKR0jQ{QLLsjT<+P9Xqys`Ep>e0DU)S&K#fzySuxao11~* z1`L+Pix=nT=U=*X>Ey|ihYlTj`t<4J$B)mPIRlIrzdPB%Kq|Z>$S;^dv3>sBx$`FK z_pjc$YsW4i*tu)Y=TA`Z?A_Xyx9=d}!@d*$AYj$3ix+nR@x+T4cQ~DU`t-&2ywf(ZY}vVkrPT+j!t)Euf86#d-^rr)koo*{v-8$7J(qL*?OyR> z#*H2KkEp9GT2lMpk>%gvlqo_7VpvpWbk(>&xpCC=-rFb9&aBTQXE=yld%zNy)WPI! z{pb=%hRlCo0!?+flR=m%Zqd>IzM|CL2sQsJG`3{o{m_ptZ} zp15GZ-`)^w`^oKwlR=%l?C%fLoa~NYJo4nqmeXh6-1)1GpWnkcaC!-2QLvDUbW?Cg~4OWd8jsZ1Df;0r@rERK(!v>gTe~DWM4fb_)>; literal 1115 zc%17D@N?(olHy`uVBq!ia0vp^Vj#@H3?x5i&EW)6Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$Ysfq`*$fKP}kP=SGgft#CK zR8&+G}*zyp`f4usAj^135ymj+OT26 zjvYI8?%cU?<3=F2q@<*xq5`NMs0+xQGG$6@Yim_iRb^$Rlao_GK*03r(-$sW7!eT> z7#P^m(b3b>E2|6!Dk>`4+S+=0dRkgqnwpvrL7@4UFJHcR@gmS|Cr+Gr^XAQ~SFc{b zetrG=_2b8nzkK=f+O=zM-@bkS{{4p!A3lEk`03N9&!0bk`SRuK*RS8cef$3X`;Q+# ze*XOV?%lgzzkdDx{rk_KKR0jQ{QLLsjT<+P9Xqys`Ep>e0DU)S&K#fzySuxao11~* z1`L+Pix=nT=U=*X>Ey|ihYlTj`t<4J$B)mPIRlIrzdPB%Kq|Z>$S;^dv3>sBx$`FK z_pjc$YsW4i*tu)Y=TA`Z?A_Xyx9=d}!@d*$AYj$3ix+nR@x+T4cQ~DU`t-&2ywf(ZY}vVkrPT+j!t)Euf86#d-^rr)koo*{v-8$7J(qL*?OyR> z#*H2KkEp9GT2lMpk>%gvlqo_7VpvpWbk(>&xpCC=-rFb9&aBTQXE=yld%zNy)WPI! z{pb=%hRlCo0!?+flR=m%Zqd>IzM|CL2sQsJG`3{o{m_ptZ} zp15GZ-`)^w`^oKwlR=%l?C%fLoa~NYJo4nqmeXh6-1)1GpWnkcaC!-2QLvDUbW?Cg~4OWd8jsZ1Df;0r@rERK(!v>gTe~DWM4fb_)>; diff --git a/kcms/touchpad/icon/24-devices-input-touchpad.png b/kcms/touchpadx/icon/24-devices-input-touchpad.png rename from kcms/touchpad/icon/24-devices-input-touchpad.png rename to kcms/touchpadx/icon/24-devices-input-touchpad.png index 72bf9b36f18d38cc7c51336b17886e9d19b1a9da..72bf9b36f18d38cc7c51336b17886e9d19b1a9da GIT binary patch literal 1304 zc${@pYfO_@7(QHsR41~bU?4->rZOn~R*Tvp3bwOcN(yZ)Wq{CfmkN{?ECxaiqF6VW z+0+2r5|kjwl#2rf4Yvuw!dIYJlx9OvQ0{0!RZ|d!FYx=PO_Z z9o=NT-5MdZ$&Wz`foT7BSee21K_#w&U>@(o^g*b$kYI?mfVs1f5yC_$>kEW(^AK8t zrQ9imq$Gr9q7b59MQB@UX>+g_LMC&pKn@)?T)cRZNF-tycJScALx&D|dwY|~WOsLW z3WXw*$Sp`l@6VG$7#k&%(%;o)9hUeKYcs_N#=o3*vIjg5^; zrLwcLv%9-nrBbQY>cPRmfq{X5fB;WVPdc5>WHO;cQc}|C)2E?%VPRoWQISHSkjv#_ zu{bR)?d;jJd3kx++1Zc_g+dO8110|c{!s4g>swh_IW#o%@ZrPp@$sptsfC4w=g*(d z&(A-5_AEa?A6hXO3^)ZSUA}xdFfb7E%*;%wR0SM3SDK4rF*d9#~=i0hX4Qj*gD5uC7i_PLA(jXJ=PeS65$O-`v~` zOy=h1KrhIjot>SYo}QVR0b+}bi@@;3ix+ymeraiGd3pKe%a^ZSy;@mWSzTRy{rWYS zv$nQoFc`q7_4V~PZ{8SBqWH9 z&_dqxo=l_Y0$(9Y|PxjR1LOd}JAPYtAvS9sjevq~uDWiQam}eubd8fE^B& zqwuopR;K>`?Y3uZ3NDoyG)g5%P%1TsGTSC|R#UaI%+}mh)vMPloNZU><+4dTu9iai zokG!a?IsULL=|WZO1-M8Sl0~xH|H16sPszZH#>@GiF`Vjc_e}juYjF>gvq7z`3e%t zWwT50Bi-=mu=P(HUCQC(TcfZ#aSE=;+ttOUO z+6KQpi4Ob&G7Eb7t%YAkTa6n&-o-o?#|q}M9}L{r3=e9D_FWYu#3T!n;!a}POC2g* z_po}jWAL7=STVb7FgTForJwYvGlZ$XvX4b-S&ul!OBToZqq;C2`v)F}`asdqLT+CROL!<`|da)uo$F38tpoh+%s_?fLnS-Mh~3*#FsHH#bMCP8XMJ zWkP{KAa^Eu%jFoh$H6otWJp7Hb|w=tT})6ce%Bm7Rw0GE`dmT}mBd6#VyQxLEClow z2_w5>BzNopheV-bo>a>IFG>5TBvQa%30eOs5T(Q<#>xJ_fGQv8h60DT1?-eKNoKS- j7QydIOgwoaT^OAjOH2{Rmn?W~hfT literal 1304 zc${@pYfO_@7(QHsR41~bU?4->rZOn~R*Tvp3bwOcN(yZ)Wq{CfmkN{?ECxaiqF6VW z+0+2r5|kjwl#2rf4Yvuw!dIYJlx9OvQ0{0!RZ|d!FYx=PO_Z z9o=NT-5MdZ$&Wz`foT7BSee21K_#w&U>@(o^g*b$kYI?mfVs1f5yC_$>kEW(^AK8t zrQ9imq$Gr9q7b59MQB@UX>+g_LMC&pKn@)?T)cRZNF-tycJScALx&D|dwY|~WOsLW z3WXw*$Sp`l@6VG$7#k&%(%;o)9hUeKYcs_N#=o3*vIjg5^; zrLwcLv%9-nrBbQY>cPRmfq{X5fB;WVPdc5>WHO;cQc}|C)2E?%VPRoWQISHSkjv#_ zu{bR)?d;jJd3kx++1Zc_g+dO8110|c{!s4g>swh_IW#o%@ZrPp@$sptsfC4w=g*(d z&(A-5_AEa?A6hXO3^)ZSUA}xdFfb7E%*;%wR0SM3SDK4rF*d9#~=i0hX4Qj*gD5uC7i_PLA(jXJ=PeS65$O-`v~` zOy=h1KrhIjot>SYo}QVR0b+}bi@@;3ix+ymeraiGd3pKe%a^ZSy;@mWSzTRy{rWYS zv$nQoFc`q7_4V~PZ{8SBqWH9 z&_dqxo=l_Y0$(9Y|PxjR1LOd}JAPYtAvS9sjevq~uDWiQam}eubd8fE^B& zqwuopR;K>`?Y3uZ3NDoyG)g5%P%1TsGTSC|R#UaI%+}mh)vMPloNZU><+4dTu9iai zokG!a?IsULL=|WZO1-M8Sl0~xH|H16sPszZH#>@GiF`Vjc_e}juYjF>gvq7z`3e%t zWwT50Bi-=mu=P(HUCQC(TcfZ#aSE=;+ttOUO z+6KQpi4Ob&G7Eb7t%YAkTa6n&-o-o?#|q}M9}L{r3=e9D_FWYu#3T!n;!a}POC2g* z_po}jWAL7=STVb7FgTForJwYvGlZ$XvX4b-S&ul!OBToZqq;C2`v)F}`asdqLT+CROL!<`|da)uo$F38tpoh+%s_?fLnS-Mh~3*#FsHH#bMCP8XMJ zWkP{KAa^Eu%jFoh$H6otWJp7Hb|w=tT})6ce%Bm7Rw0GE`dmT}mBd6#VyQxLEClow z2_w5>BzNopheV-bo>a>IFG>5TBvQa%30eOs5T(Q<#>xJ_fGQv8h60DT1?-eKNoKS- j7QydIOgwoaT^OAjOH2{Rmn?W~hfT diff --git a/kcms/touchpad/icon/256-devices-input-touchpad.png b/kcms/touchpadx/icon/256-devices-input-touchpad.png rename from kcms/touchpad/icon/256-devices-input-touchpad.png rename to kcms/touchpadx/icon/256-devices-input-touchpad.png index 0e56a21e2efffe4f69ed20226266a88780d5ecb7..0e56a21e2efffe4f69ed20226266a88780d5ecb7 GIT binary patch literal 13212 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 U^evn*IRKXsTPsImjfH38ADe6CR{#J2 literal 1580 zc${@pX;4#F6n-E~MR-ap7F;^Ej-l)%VNn7jTM&>fkWi`M2!?q0lDsW0(m9f{BTVsj2CS6DPE_wIL9X$Ain#($d=6+S%FJ z-QAr=qXh;AhK7blM@J_lBwW6HIXO8wB_)N!;jr0kIE;yjiHwYd%t1jxbUNMB)6>n( zjYJ~Z+1U|^M92?0u~@8=lM{o%U^1Dpv9VcMSw%%fRaI47F1N0(uD-s$xVShqHPyqz zgG!~Al$6}Od9$LTqO7c}u&^*YJ3A>U2{iio`MJ2bKsHTHO*nyyiHV6I8MeTO#bN~P$&fQlarGok!WUS zW_EUVZfxfB$}Xc(|>t zEh8ht!omVN3@S!OM#jg-1p>k7=;*}6L~d?wUtizAz(9U}es_2G!-o&y!@(2k_VFfy zNnp7+lEF%wuro6)rq0A|AW62GuYk7$5%jtfv=IDMV$rC6JIhZ)Z(J z*s@>Qz(y{}=KB!%kJh(_lzg~BA+Xf7C7M%?zkG0Qg}m2XsZ}u0$VQ`-xhv9QoisFR z79*}v^A=pH&+ivuJmpdpEfnQ(y`S_42k0%q!@5~F4hIH~tvA%Kk3F`W_|#QOt$cNs z`TBu-cz4-&*^45|@?_@P5_%M6}aqj zvLNzTF_+YH%WG4QIxCzyXs-AT`Vvn~`x(m{sl6*vl96suD6I~rxXvpbIe%^_LWSwt zg?8zqmI8{bf_;@PTV_%(xit@Ut6-4qH9t!jQYKN_F1BV8J@_P*Lq}Z4*AqwN^QKSw z`FXVBQ3o1+r_fO$f#+0k zoWAhGt>omcvAhq zqYE4F^ppC;dG~Fu`xw>T;;tBnscQFgS*llr_I9Gwvlqf6*f#bCX0@#84?jJ=5zxv- zT`RDTlI!w!q)YKPuDx)J9^BN8_DHjrJA7;>ZFIAS)GVVPHsq<_k$-YTgzVd0`po)^ zrwWQPc;TC}*5;I^)12=54-+lzX7 zz7eGP+Knfl8V991pOn194E;I)?+L@Qa$|XWv1kM;lLiLCV{v-gIIK3#h=MgB;0y@{ zMw-}T1T1#?Hucqi0xmMV={^zvA5bLjXF|aKtpGB^hZXL{q#@zq;X3p{{}8HI5KV`{ U^evn*IRKXsTPsImjfH38ADe6CR{#J2 diff --git a/kcms/touchpad/icon/48-devices-input-touchpad.png b/kcms/touchpadx/icon/48-devices-input-touchpad.png rename from kcms/touchpad/icon/48-devices-input-touchpad.png rename to kcms/touchpadx/icon/48-devices-input-touchpad.png index 3357a1c0b5cb6147110aa709b9a3748a8c017af5..3357a1c0b5cb6147110aa709b9a3748a8c017af5 GIT binary patch literal 1735 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 literal 2236 zc${@sc{tSF7yk~1$*4w_coRkl#XHEp4-;c6!>A!;8xqDcBkMcHm=+{UgDj~;$;3#u zOty%mNO*ZIuZbEWS!Zm~Z~FcB`{Q??bMEK4_uS7p&vVXm@3|>woo)Av{viqgz<#uy z4Tg`FzZD|PpDThQ{^f&Epp}yq06fot{`3L!*NT327$*RTQw0DD4FI z@yk7(i0c!Mh)s5vguu&~w@=#x0>-VQS@9JNw@>mq71&^9?66~ob=R68JiWr>)5fm+ zHX1Kz8>#$TR(YZz%87GT1K1LPMa{`xwX)iyD3_h@|GZf5yJymvu(kT|Q%iPw`u>U5Lvl8t|1RlR{_}RM!V#CY~5&b zrXajcXhD!^K?JGLzQ^gGzyzG89OxXbQtGt5o=(GMKL1l7#F9~aX+$c4;?=)_>@0>< zCvmxY;3WZE9$nSul&YnO2e|2-)O+&yYlh`cY2VTn32*A~zHqaRqz&%Y&sGiTIlmz| zGYdRgdl5U{=Kk_Ext4IG!@ykyq&oLlXedH(9gP#b&!*B$)C2G*wSI@ZFv$41ZR5Oz^IyR=U&xe+&O<`VxB~DIET%hp|meOUxRur{V z7-~RrneQ=af5-B#d297+UeQ{HS{bsH5~1Q~u0vW4 zLI2$she5ub+6O;&8uAb@S4*9?hIg98Q6N;HJ44~V29ZcKy!u^+!{NZXwWkfW&@Rx! zNP59tM^(E)$)Ez?`1m6;D>6X^O8sjn^{*Q!7fC1-y42vIY2#ueIdJRw(=;d;lOA-W zK~1zY$QV4z3E*FPz+7ZmLA6W_lu)GHv(rGB^yMd0D+$pBLy7Za)G@D2uIKQgdI#!! z3;Y|#-`qKVW_kKe8nMzH>fqq;gfP*VM4ast|ElrMi>@*^cFr#V=YBgMkHgVlj?;*@ z<2Qa>YreSTs*W$GdcT$F;4X{|5E>j5^aKklL$_;t^P~VI#JSish0Bc!ArO4YWO=^l z-rior#J!(GmFeF^IgJ&g0*`_n-q(onUywO&oGXhmr1vA0U1i=Js^vD7J!JAOl8#bA zQw?vo%M>bEDhy75)yh~`Ax9JLWgIsKv1*?PWVAret@;rz)!%YtVm)!Rt@jg$xLfne zNT-&A#{B~IXes!%i7`ZXrCN$TLebB6tZr`h64o=L7M@!%_x;fFc-rY&Xj{~p>jN*L zM(O-nqtlPXuXn(^X0(Nqtz?@+XPQoZx6dxfbcvP0lmvIZx~Ly~ABVBe!prhcZSR^3 zCxc}CWYSOL=_B1WmECwRr}h!0Ht8G&A^I;5*Ke1LXJN>lR%xcF&m$c6_qgKSdQ=Khc zB=I_r4wWa<$*mdW)=O1c(x@y^c*}>HlkuC&J})yLznMt>3w1P{q}iJC+NgV`J40JO zLxmy^^c0)LtMWSn`E!wlm#62>=8s8MdtLBIbz@_UV)QB<^Nh)y;aAVqq<3w$e`Rjq z(NovLeo?PP*0#~?9Le~+r>Au;{uprIL0#m_{4fKsETi`Vd$L09f#~ecID$p+=b}3& zdrRr7VMS{+*lLC{+C~zkD?4>ZIIYKD=OKMhwyhQ92mvnt3gswMW{TDD8db` zu*)tT9dH*?%)-cz=4seJ1rW-#x6V(9X9wkavgCS}9QQ;rwAha)$)-X4&aFa1ohSMG zknqNSk$64;ItXoDO>Kmxwvih`&sbaESkLGL!oV1TSY-J1{SP5D%s(g~_Wu)#c;k_L wg6waCYghm&+9whZL`O$!1rdUYem>!Nt+2?z!XKu8{QgLwQO-71NN?(Y09nrpmjD0& diff --git a/kcms/touchpad/icon/96-devices-input-touchpad.png b/kcms/touchpadx/icon/96-devices-input-touchpad.png rename from kcms/touchpad/icon/96-devices-input-touchpad.png rename to kcms/touchpadx/icon/96-devices-input-touchpad.png index b780218c21100466d54b25c65f2c704ac7c5fd28..b780218c21100466d54b25c65f2c704ac7c5fd28 GIT binary patch literal 3806 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 literal 3806 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 diff --git a/kcms/touchpad/icon/CMakeLists.txt b/kcms/touchpadx/icon/CMakeLists.txt rename from kcms/touchpad/icon/CMakeLists.txt rename to kcms/touchpadx/icon/CMakeLists.txt diff --git a/kcms/touchpad/icon/makeicons.sh b/kcms/touchpadx/icon/makeicons.sh rename from kcms/touchpad/icon/makeicons.sh rename to kcms/touchpadx/icon/makeicons.sh diff --git a/kcms/touchpad/icon/sc-devices-input-touchpad.svgz b/kcms/touchpadx/icon/sc-devices-input-touchpad.svgz rename from kcms/touchpad/icon/sc-devices-input-touchpad.svgz rename to kcms/touchpadx/icon/sc-devices-input-touchpad.svgz index ad8bd2284994acfd7e610576d3eca4be7d45aa99..ad8bd2284994acfd7e610576d3eca4be7d45aa99 GIT binary patch literal 11660 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 WFEtiFp5ML0pZ^aF^DUdf(*OWf(AQxA literal 11660 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 WFEtiFp5ML0pZ^aF^DUdf(*OWf(AQxA diff --git a/kcms/touchpad/src/CMakeLists.txt b/kcms/touchpadx/src/CMakeLists.txt rename from kcms/touchpad/src/CMakeLists.txt rename to kcms/touchpadx/src/CMakeLists.txt --- a/kcms/touchpad/src/CMakeLists.txt +++ b/kcms/touchpadx/src/CMakeLists.txt @@ -1,5 +1,5 @@ # KI18N Translation Domain for this library -add_definitions(-DTRANSLATION_DOMAIN=\"kcm_touchpad\") +add_definitions(-DTRANSLATION_DOMAIN=\"kcm_touchpadx\") configure_file("${CMAKE_CURRENT_SOURCE_DIR}/version.h.cmake" "${CMAKE_CURRENT_BINARY_DIR}/version.h" @@ -12,13 +12,11 @@ ) include(backends/x11.cmake) -include(backends/kwin_wayland.cmake) set(SRCS ${SRCS} kcm/touchpadconfigcontainer.cpp kcm/touchpadconfigplugin.cpp - kcm/libinput/touchpadconfiglibinput.cpp kcm/xlib/customslider.cpp kcm/xlib/sliderpair.cpp kcm/xlib/testarea.cpp @@ -32,8 +30,6 @@ ${CMAKE_CURRENT_BINARY_DIR}/org.kde.touchpad.xml ) -qt5_add_resources( SRCS kcm/resources.qrc ) - kconfig_add_kcfg_files(SRCS kcm/xlib/touchpadparameters.kcfgc) ki18n_wrap_ui(SRCS @@ -83,7 +79,7 @@ add_subdirectory(applet) -install(FILES kcm/kcm_touchpad.desktop +install(FILES kcm/kcm_touchpadx.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) diff --git a/kcms/touchpad/src/applet/CMakeLists.txt b/kcms/touchpadx/src/applet/CMakeLists.txt rename from kcms/touchpad/src/applet/CMakeLists.txt rename to kcms/touchpadx/src/applet/CMakeLists.txt --- a/kcms/touchpad/src/applet/CMakeLists.txt +++ b/kcms/touchpadx/src/applet/CMakeLists.txt @@ -1,4 +1,4 @@ -remove_definitions(-DTRANSLATION_DOMAIN="kcm_touchpad") +remove_definitions(-DTRANSLATION_DOMAIN="kcm_touchpadx") add_definitions(-DTRANSLATION_DOMAIN="plasma_applet_touchpad") plasma_install_package(qml touchpad) diff --git a/kcms/touchpad/src/applet/dataengine.desktop b/kcms/touchpadx/src/applet/dataengine.desktop rename from kcms/touchpad/src/applet/dataengine.desktop rename to kcms/touchpadx/src/applet/dataengine.desktop diff --git a/kcms/touchpad/src/applet/qml/contents/ui/touchpad.qml b/kcms/touchpadx/src/applet/qml/contents/ui/touchpad.qml rename from kcms/touchpad/src/applet/qml/contents/ui/touchpad.qml rename to kcms/touchpadx/src/applet/qml/contents/ui/touchpad.qml diff --git a/kcms/touchpad/src/applet/qml/metadata.desktop b/kcms/touchpadx/src/applet/qml/metadata.desktop rename from kcms/touchpad/src/applet/qml/metadata.desktop rename to kcms/touchpadx/src/applet/qml/metadata.desktop --- a/kcms/touchpad/src/applet/qml/metadata.desktop +++ b/kcms/touchpadx/src/applet/qml/metadata.desktop @@ -136,6 +136,6 @@ X-KDE-PluginInfo-Website=https://projects.kde.org/projects/playground/utils/kcm-touchpad/ X-KDE-ServiceTypes=Plasma/Applet X-Plasma-API=declarativeappletscript -X-Plasma-ConfigPlugins=kcm_touchpad +X-Plasma-ConfigPlugins=kcm_touchpadx X-Plasma-MainScript=ui/touchpad.qml X-Plasma-NotificationArea=true diff --git a/kcms/touchpad/src/applet/touchpad.operations b/kcms/touchpadx/src/applet/touchpad.operations rename from kcms/touchpad/src/applet/touchpad.operations rename to kcms/touchpadx/src/applet/touchpad.operations diff --git a/kcms/touchpad/src/applet/touchpad.svg b/kcms/touchpadx/src/applet/touchpad.svg rename from kcms/touchpad/src/applet/touchpad.svg rename to kcms/touchpadx/src/applet/touchpad.svg diff --git a/kcms/touchpad/src/applet/touchpadengine.h b/kcms/touchpadx/src/applet/touchpadengine.h rename from kcms/touchpad/src/applet/touchpadengine.h rename to kcms/touchpadx/src/applet/touchpadengine.h diff --git a/kcms/touchpad/src/applet/touchpadengine.cpp b/kcms/touchpadx/src/applet/touchpadengine.cpp rename from kcms/touchpad/src/applet/touchpadengine.cpp rename to kcms/touchpadx/src/applet/touchpadengine.cpp diff --git a/kcms/touchpad/src/applet/touchpadservice.h b/kcms/touchpadx/src/applet/touchpadservice.h rename from kcms/touchpad/src/applet/touchpadservice.h rename to kcms/touchpadx/src/applet/touchpadservice.h diff --git a/kcms/touchpad/src/applet/touchpadservice.cpp b/kcms/touchpadx/src/applet/touchpadservice.cpp rename from kcms/touchpad/src/applet/touchpadservice.cpp rename to kcms/touchpadx/src/applet/touchpadservice.cpp diff --git a/kcms/touchpad/src/backends/x11.cmake b/kcms/touchpadx/src/backends/x11.cmake rename from kcms/touchpad/src/backends/x11.cmake rename to kcms/touchpadx/src/backends/x11.cmake diff --git a/kcms/touchpad/src/backends/x11/libinputtouchpad.h b/kcms/touchpadx/src/backends/x11/libinputtouchpad.h rename from kcms/touchpad/src/backends/x11/libinputtouchpad.h rename to kcms/touchpadx/src/backends/x11/libinputtouchpad.h diff --git a/kcms/touchpad/src/backends/x11/libinputtouchpad.cpp b/kcms/touchpadx/src/backends/x11/libinputtouchpad.cpp rename from kcms/touchpad/src/backends/x11/libinputtouchpad.cpp rename to kcms/touchpadx/src/backends/x11/libinputtouchpad.cpp diff --git a/kcms/touchpad/src/backends/x11/listdevices.cpp b/kcms/touchpadx/src/backends/x11/listdevices.cpp rename from kcms/touchpad/src/backends/x11/listdevices.cpp rename to kcms/touchpadx/src/backends/x11/listdevices.cpp diff --git a/kcms/touchpad/src/backends/x11/propertyinfo.h b/kcms/touchpadx/src/backends/x11/propertyinfo.h rename from kcms/touchpad/src/backends/x11/propertyinfo.h rename to kcms/touchpadx/src/backends/x11/propertyinfo.h diff --git a/kcms/touchpad/src/backends/x11/propertyinfo.cpp b/kcms/touchpadx/src/backends/x11/propertyinfo.cpp rename from kcms/touchpad/src/backends/x11/propertyinfo.cpp rename to kcms/touchpadx/src/backends/x11/propertyinfo.cpp diff --git a/kcms/touchpad/src/backends/x11/synapticstouchpad.h b/kcms/touchpadx/src/backends/x11/synapticstouchpad.h rename from kcms/touchpad/src/backends/x11/synapticstouchpad.h rename to kcms/touchpadx/src/backends/x11/synapticstouchpad.h diff --git a/kcms/touchpad/src/backends/x11/synapticstouchpad.cpp b/kcms/touchpadx/src/backends/x11/synapticstouchpad.cpp rename from kcms/touchpad/src/backends/x11/synapticstouchpad.cpp rename to kcms/touchpadx/src/backends/x11/synapticstouchpad.cpp diff --git a/kcms/touchpad/src/backends/x11/xcbatom.h b/kcms/touchpadx/src/backends/x11/xcbatom.h rename from kcms/touchpad/src/backends/x11/xcbatom.h rename to kcms/touchpadx/src/backends/x11/xcbatom.h diff --git a/kcms/touchpad/src/backends/x11/xcbatom.cpp b/kcms/touchpadx/src/backends/x11/xcbatom.cpp rename from kcms/touchpad/src/backends/x11/xcbatom.cpp rename to kcms/touchpadx/src/backends/x11/xcbatom.cpp diff --git a/kcms/touchpad/src/backends/x11/xlibbackend.h b/kcms/touchpadx/src/backends/x11/xlibbackend.h rename from kcms/touchpad/src/backends/x11/xlibbackend.h rename to kcms/touchpadx/src/backends/x11/xlibbackend.h diff --git a/kcms/touchpad/src/backends/x11/xlibbackend.cpp b/kcms/touchpadx/src/backends/x11/xlibbackend.cpp rename from kcms/touchpad/src/backends/x11/xlibbackend.cpp rename to kcms/touchpadx/src/backends/x11/xlibbackend.cpp diff --git a/kcms/touchpad/src/backends/x11/xlibnotifications.h b/kcms/touchpadx/src/backends/x11/xlibnotifications.h rename from kcms/touchpad/src/backends/x11/xlibnotifications.h rename to kcms/touchpadx/src/backends/x11/xlibnotifications.h diff --git a/kcms/touchpad/src/backends/x11/xlibnotifications.cpp b/kcms/touchpadx/src/backends/x11/xlibnotifications.cpp rename from kcms/touchpad/src/backends/x11/xlibnotifications.cpp rename to kcms/touchpadx/src/backends/x11/xlibnotifications.cpp diff --git a/kcms/touchpad/src/backends/x11/xlibtouchpad.h b/kcms/touchpadx/src/backends/x11/xlibtouchpad.h rename from kcms/touchpad/src/backends/x11/xlibtouchpad.h rename to kcms/touchpadx/src/backends/x11/xlibtouchpad.h diff --git a/kcms/touchpad/src/backends/x11/xlibtouchpad.cpp b/kcms/touchpadx/src/backends/x11/xlibtouchpad.cpp rename from kcms/touchpad/src/backends/x11/xlibtouchpad.cpp rename to kcms/touchpadx/src/backends/x11/xlibtouchpad.cpp diff --git a/kcms/touchpad/src/backends/x11/xrecordkeyboardmonitor.h b/kcms/touchpadx/src/backends/x11/xrecordkeyboardmonitor.h rename from kcms/touchpad/src/backends/x11/xrecordkeyboardmonitor.h rename to kcms/touchpadx/src/backends/x11/xrecordkeyboardmonitor.h diff --git a/kcms/touchpad/src/backends/x11/xrecordkeyboardmonitor.cpp b/kcms/touchpadx/src/backends/x11/xrecordkeyboardmonitor.cpp rename from kcms/touchpad/src/backends/x11/xrecordkeyboardmonitor.cpp rename to kcms/touchpadx/src/backends/x11/xrecordkeyboardmonitor.cpp diff --git a/kcms/touchpad/src/kcm/kcm_touchpad.desktop b/kcms/touchpadx/src/kcm/kcm_touchpadx.desktop rename from kcms/touchpad/src/kcm/kcm_touchpad.desktop rename to kcms/touchpadx/src/kcm/kcm_touchpadx.desktop --- a/kcms/touchpad/src/kcm/kcm_touchpad.desktop +++ b/kcms/touchpadx/src/kcm/kcm_touchpadx.desktop @@ -1,5 +1,5 @@ [Desktop Entry] -Exec=kcmshell5 kcm_touchpad +Exec=kcmshell5 kcm_touchpadx Icon=input-touchpad Type=Service Categories=Qt;KDE;X-KDE-settings-hardware; @@ -12,6 +12,7 @@ X-KDE-PluginKeyword=kcm X-KDE-ParentApp=kcontrol X-KDE-System-Settings-Parent-Category=input-devices +X-KDE-OnlyShowOnQtPlatforms=xcb Name=Touchpad Name[ar]=لوحة اللمس diff --git a/kcms/touchpad/src/kcm/touchpadconfigcontainer.h b/kcms/touchpadx/src/kcm/touchpadconfigcontainer.h rename from kcms/touchpad/src/kcm/touchpadconfigcontainer.h rename to kcms/touchpadx/src/kcm/touchpadconfigcontainer.h --- a/kcms/touchpad/src/kcm/touchpadconfigcontainer.h +++ b/kcms/touchpadx/src/kcm/touchpadconfigcontainer.h @@ -22,15 +22,13 @@ #include class TouchpadConfigPlugin; -class TouchpadConfigLibinput; class TouchpadConfigXlib; class TouchpadConfigContainer : public KCModule { Q_OBJECT friend TouchpadConfigXlib; - friend TouchpadConfigLibinput; public: explicit TouchpadConfigContainer(QWidget *parent, diff --git a/kcms/touchpad/src/kcm/touchpadconfigcontainer.cpp b/kcms/touchpadx/src/kcm/touchpadconfigcontainer.cpp rename from kcms/touchpad/src/kcm/touchpadconfigcontainer.cpp rename to kcms/touchpadx/src/kcm/touchpadconfigcontainer.cpp --- a/kcms/touchpad/src/kcm/touchpadconfigcontainer.cpp +++ b/kcms/touchpadx/src/kcm/touchpadconfigcontainer.cpp @@ -18,7 +18,6 @@ #include "touchpadconfigcontainer.h" #include "touchpadconfigplugin.h" -#include "kcm/libinput/touchpadconfiglibinput.h" #include "kcm/xlib/touchpadconfigxlib.h" #include @@ -38,8 +37,6 @@ { if (KWindowSystem::isPlatformX11()) { m_plugin = new TouchpadConfigXlib(this); - } else if (KWindowSystem::isPlatformWayland()) { - m_plugin = new TouchpadConfigLibinput(this); } } diff --git a/kcms/touchpad/src/kcm/touchpadconfigplugin.h b/kcms/touchpadx/src/kcm/touchpadconfigplugin.h rename from kcms/touchpad/src/kcm/touchpadconfigplugin.h rename to kcms/touchpadx/src/kcm/touchpadconfigplugin.h diff --git a/kcms/touchpad/src/kcm/touchpadconfigplugin.cpp b/kcms/touchpadx/src/kcm/touchpadconfigplugin.cpp rename from kcms/touchpad/src/kcm/touchpadconfigplugin.cpp rename to kcms/touchpadx/src/kcm/touchpadconfigplugin.cpp diff --git a/kcms/touchpad/src/kcm/xlib/customconfigdialogmanager.h b/kcms/touchpadx/src/kcm/xlib/customconfigdialogmanager.h rename from kcms/touchpad/src/kcm/xlib/customconfigdialogmanager.h rename to kcms/touchpadx/src/kcm/xlib/customconfigdialogmanager.h diff --git a/kcms/touchpad/src/kcm/xlib/customconfigdialogmanager.cpp b/kcms/touchpadx/src/kcm/xlib/customconfigdialogmanager.cpp rename from kcms/touchpad/src/kcm/xlib/customconfigdialogmanager.cpp rename to kcms/touchpadx/src/kcm/xlib/customconfigdialogmanager.cpp diff --git a/kcms/touchpad/src/kcm/xlib/customslider.h b/kcms/touchpadx/src/kcm/xlib/customslider.h rename from kcms/touchpad/src/kcm/xlib/customslider.h rename to kcms/touchpadx/src/kcm/xlib/customslider.h diff --git a/kcms/touchpad/src/kcm/xlib/customslider.cpp b/kcms/touchpadx/src/kcm/xlib/customslider.cpp rename from kcms/touchpad/src/kcm/xlib/customslider.cpp rename to kcms/touchpadx/src/kcm/xlib/customslider.cpp diff --git a/kcms/touchpad/src/kcm/xlib/sliderpair.h b/kcms/touchpadx/src/kcm/xlib/sliderpair.h rename from kcms/touchpad/src/kcm/xlib/sliderpair.h rename to kcms/touchpadx/src/kcm/xlib/sliderpair.h diff --git a/kcms/touchpad/src/kcm/xlib/sliderpair.cpp b/kcms/touchpadx/src/kcm/xlib/sliderpair.cpp rename from kcms/touchpad/src/kcm/xlib/sliderpair.cpp rename to kcms/touchpadx/src/kcm/xlib/sliderpair.cpp diff --git a/kcms/touchpad/src/kcm/xlib/testarea.h b/kcms/touchpadx/src/kcm/xlib/testarea.h rename from kcms/touchpad/src/kcm/xlib/testarea.h rename to kcms/touchpadx/src/kcm/xlib/testarea.h diff --git a/kcms/touchpad/src/kcm/xlib/testarea.cpp b/kcms/touchpadx/src/kcm/xlib/testarea.cpp rename from kcms/touchpad/src/kcm/xlib/testarea.cpp rename to kcms/touchpadx/src/kcm/xlib/testarea.cpp diff --git a/kcms/touchpad/src/kcm/xlib/testbutton.h b/kcms/touchpadx/src/kcm/xlib/testbutton.h rename from kcms/touchpad/src/kcm/xlib/testbutton.h rename to kcms/touchpadx/src/kcm/xlib/testbutton.h diff --git a/kcms/touchpad/src/kcm/xlib/testbutton.cpp b/kcms/touchpadx/src/kcm/xlib/testbutton.cpp rename from kcms/touchpad/src/kcm/xlib/testbutton.cpp rename to kcms/touchpadx/src/kcm/xlib/testbutton.cpp diff --git a/kcms/touchpad/src/kcm/xlib/touchpad.kcfg b/kcms/touchpadx/src/kcm/xlib/touchpad.kcfg rename from kcms/touchpad/src/kcm/xlib/touchpad.kcfg rename to kcms/touchpadx/src/kcm/xlib/touchpad.kcfg diff --git a/kcms/touchpad/src/kcm/xlib/touchpadconfigxlib.h b/kcms/touchpadx/src/kcm/xlib/touchpadconfigxlib.h rename from kcms/touchpad/src/kcm/xlib/touchpadconfigxlib.h rename to kcms/touchpadx/src/kcm/xlib/touchpadconfigxlib.h diff --git a/kcms/touchpad/src/kcm/xlib/touchpadconfigxlib.cpp b/kcms/touchpadx/src/kcm/xlib/touchpadconfigxlib.cpp rename from kcms/touchpad/src/kcm/xlib/touchpadconfigxlib.cpp rename to kcms/touchpadx/src/kcm/xlib/touchpadconfigxlib.cpp --- a/kcms/touchpad/src/kcm/xlib/touchpadconfigxlib.cpp +++ b/kcms/touchpadx/src/kcm/xlib/touchpadconfigxlib.cpp @@ -102,8 +102,8 @@ : TouchpadConfigPlugin(parent), m_configOutOfSync(false) { - KAboutData* data = new KAboutData(QStringLiteral("kcm_touchpad"), - i18n("Touchpad KCM"), + KAboutData* data = new KAboutData(QStringLiteral("kcm_touchpadx"), + i18n("TouchpadX KCM"), TOUCHPAD_KCM_VERSION, i18n("System Settings module, daemon and Plasma applet for managing your touchpad"), KAboutLicense::GPL_V2, diff --git a/kcms/touchpad/src/kcm/xlib/touchpadparameters.kcfgc b/kcms/touchpadx/src/kcm/xlib/touchpadparameters.kcfgc rename from kcms/touchpad/src/kcm/xlib/touchpadparameters.kcfgc rename to kcms/touchpadx/src/kcm/xlib/touchpadparameters.kcfgc diff --git a/kcms/touchpad/src/kcm/xlib/touchpadparametersbase.h b/kcms/touchpadx/src/kcm/xlib/touchpadparametersbase.h rename from kcms/touchpad/src/kcm/xlib/touchpadparametersbase.h rename to kcms/touchpadx/src/kcm/xlib/touchpadparametersbase.h diff --git a/kcms/touchpad/src/kcm/xlib/touchpadparametersbase.cpp b/kcms/touchpadx/src/kcm/xlib/touchpadparametersbase.cpp rename from kcms/touchpad/src/kcm/xlib/touchpadparametersbase.cpp rename to kcms/touchpadx/src/kcm/xlib/touchpadparametersbase.cpp diff --git a/kcms/touchpad/src/kcm/xlib/ui/kded.ui b/kcms/touchpadx/src/kcm/xlib/ui/kded.ui rename from kcms/touchpad/src/kcm/xlib/ui/kded.ui rename to kcms/touchpadx/src/kcm/xlib/ui/kded.ui diff --git a/kcms/touchpad/src/kcm/xlib/ui/pointermotion.ui b/kcms/touchpadx/src/kcm/xlib/ui/pointermotion.ui rename from kcms/touchpad/src/kcm/xlib/ui/pointermotion.ui rename to kcms/touchpadx/src/kcm/xlib/ui/pointermotion.ui diff --git a/kcms/touchpad/src/kcm/xlib/ui/scroll.ui b/kcms/touchpadx/src/kcm/xlib/ui/scroll.ui rename from kcms/touchpad/src/kcm/xlib/ui/scroll.ui rename to kcms/touchpadx/src/kcm/xlib/ui/scroll.ui diff --git a/kcms/touchpad/src/kcm/xlib/ui/sensitivity.ui b/kcms/touchpadx/src/kcm/xlib/ui/sensitivity.ui rename from kcms/touchpad/src/kcm/xlib/ui/sensitivity.ui rename to kcms/touchpadx/src/kcm/xlib/ui/sensitivity.ui diff --git a/kcms/touchpad/src/kcm/xlib/ui/tap.ui b/kcms/touchpadx/src/kcm/xlib/ui/tap.ui rename from kcms/touchpad/src/kcm/xlib/ui/tap.ui rename to kcms/touchpadx/src/kcm/xlib/ui/tap.ui diff --git a/kcms/touchpad/src/kcm/xlib/ui/testarea.ui b/kcms/touchpadx/src/kcm/xlib/ui/testarea.ui rename from kcms/touchpad/src/kcm/xlib/ui/testarea.ui rename to kcms/touchpadx/src/kcm/xlib/ui/testarea.ui diff --git a/kcms/touchpad/src/kded/kcm_touchpad.notifyrc b/kcms/touchpadx/src/kded/kcm_touchpad.notifyrc rename from kcms/touchpad/src/kded/kcm_touchpad.notifyrc rename to kcms/touchpadx/src/kded/kcm_touchpad.notifyrc diff --git a/kcms/touchpad/src/kded/kded.h b/kcms/touchpadx/src/kded/kded.h rename from kcms/touchpad/src/kded/kded.h rename to kcms/touchpadx/src/kded/kded.h diff --git a/kcms/touchpad/src/kded/kded.cpp b/kcms/touchpadx/src/kded/kded.cpp rename from kcms/touchpad/src/kded/kded.cpp rename to kcms/touchpadx/src/kded/kded.cpp diff --git a/kcms/touchpad/src/kded/kded_touchpad.desktop b/kcms/touchpadx/src/kded/kded_touchpad.desktop rename from kcms/touchpad/src/kded/kded_touchpad.desktop rename to kcms/touchpadx/src/kded/kded_touchpad.desktop diff --git a/kcms/touchpad/src/kded/kdedactions.h b/kcms/touchpadx/src/kded/kdedactions.h rename from kcms/touchpad/src/kded/kdedactions.h rename to kcms/touchpadx/src/kded/kdedactions.h diff --git a/kcms/touchpad/src/kded/kdedactions.cpp b/kcms/touchpadx/src/kded/kdedactions.cpp rename from kcms/touchpad/src/kded/kdedactions.cpp rename to kcms/touchpadx/src/kded/kdedactions.cpp diff --git a/kcms/touchpad/src/kded/kdedsettings.kcfgc b/kcms/touchpadx/src/kded/kdedsettings.kcfgc rename from kcms/touchpad/src/kded/kdedsettings.kcfgc rename to kcms/touchpadx/src/kded/kdedsettings.kcfgc diff --git a/kcms/touchpad/src/kded/touchpaddaemon.kcfg b/kcms/touchpadx/src/kded/touchpaddaemon.kcfg rename from kcms/touchpad/src/kded/touchpaddaemon.kcfg rename to kcms/touchpadx/src/kded/touchpaddaemon.kcfg diff --git a/kcms/touchpad/src/logging.h b/kcms/touchpadx/src/logging.h rename from kcms/touchpad/src/logging.h rename to kcms/touchpadx/src/logging.h --- a/kcms/touchpad/src/logging.h +++ b/kcms/touchpadx/src/logging.h @@ -21,5 +21,5 @@ #include -Q_DECLARE_LOGGING_CATEGORY(KCM_TOUCHPAD) +Q_DECLARE_LOGGING_CATEGORY(KCM_TOUCHPADX) #endif diff --git a/kcms/touchpad/src/logging.cpp b/kcms/touchpadx/src/logging.cpp rename from kcms/touchpad/src/logging.cpp rename to kcms/touchpadx/src/logging.cpp --- a/kcms/touchpad/src/logging.cpp +++ b/kcms/touchpadx/src/logging.cpp @@ -17,4 +17,4 @@ */ #include "logging.h" -Q_LOGGING_CATEGORY(KCM_TOUCHPAD, "kcm_touchpad") +Q_LOGGING_CATEGORY(KCM_TOUCHPADX, "kcm_touchpadx") diff --git a/kcms/touchpad/src/plugins.h b/kcms/touchpadx/src/plugins.h rename from kcms/touchpad/src/plugins.h rename to kcms/touchpadx/src/plugins.h diff --git a/kcms/touchpad/src/plugins.cpp b/kcms/touchpadx/src/plugins.cpp rename from kcms/touchpad/src/plugins.cpp rename to kcms/touchpadx/src/plugins.cpp diff --git a/kcms/touchpad/src/touchpadbackend.h b/kcms/touchpadx/src/touchpadbackend.h rename from kcms/touchpad/src/touchpadbackend.h rename to kcms/touchpadx/src/touchpadbackend.h diff --git a/kcms/touchpad/src/touchpadbackend.cpp b/kcms/touchpadx/src/touchpadbackend.cpp rename from kcms/touchpad/src/touchpadbackend.cpp rename to kcms/touchpadx/src/touchpadbackend.cpp --- a/kcms/touchpad/src/touchpadbackend.cpp +++ b/kcms/touchpadx/src/touchpadbackend.cpp @@ -20,7 +20,6 @@ #include "touchpadbackend.h" #include "backends/x11/xlibbackend.h" -#include "backends/kwin_wayland/kwinwaylandbackend.h" #include "logging.h" #include @@ -34,18 +33,13 @@ if (KWindowSystem::isPlatformX11()) { static QThreadStorage > backend; if (!backend.hasLocalData()) { - qCDebug(KCM_TOUCHPAD) << "Using X11 backend"; + qCDebug(KCM_TOUCHPADX) << "Using X11 backend"; backend.setLocalData(QSharedPointer(XlibBackend::initialize())); } return backend.localData().data(); } - // TODO: test on kwin_wayland specifically? What about possibly other compositors under Wayland? - else if (KWindowSystem::isPlatformWayland()) { - qCDebug(KCM_TOUCHPAD) << "Using KWin+Wayland backend"; - return (new KWinWaylandBackend()); - } else { - qCCritical(KCM_TOUCHPAD) << "Not able to select appropriate backend."; + qCCritical(KCM_TOUCHPADX) << "Not able to select appropriate backend."; return nullptr; } } diff --git a/kcms/touchpad/src/version.h.cmake b/kcms/touchpadx/src/version.h.cmake rename from kcms/touchpad/src/version.h.cmake rename to kcms/touchpadx/src/version.h.cmake diff --git a/kcms/workspaceoptions/package/contents/ui/main.qml b/kcms/workspaceoptions/package/contents/ui/main.qml --- a/kcms/workspaceoptions/package/contents/ui/main.qml +++ b/kcms/workspaceoptions/package/contents/ui/main.qml @@ -1,4 +1,5 @@ /* + * Copyright 2017 Roman Gilg * Copyright 2018 Furkan Tokac * * This program is free software; you can redistribute it and/or modify @@ -15,71 +16,547 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + import QtQuick 2.7 -import QtQuick.Controls 1.4 as Controls +import QtQuick.Controls 2.0 as Controls import QtQuick.Layouts 1.3 as Layouts -import org.kde.kirigami 2.4 as Kirigami -import org.kde.kcm 1.1 as KCM -import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.kcm 1.1 as KCM +import org.kde.kirigami 2.4 as Kirigami -KCM.SimpleKCM { +// TODO: Change ScrollablePage as KCM.SimpleKCM +// after rewrite the KCM in KConfigModule. +Kirigami.ScrollablePage { id: root + spacing: Kirigami.Units.smallSpacing + + property size minimumSizeHint: Qt.size(formLayout.width/2, deviceSelector.height) + + property alias deviceIndex: deviceSelector.currentIndex + signal changeSignal() + + property QtObject touchpad + property int touchpadCount: backend.touchpadCount + + property bool loading: false + + function resetModel(index) { + touchpadCount = backend.touchpadCount + formLayout.enabled = touchpadCount + deviceSelector.enabled = touchpadCount > 1 + + loading = true + if (touchpadCount) { + touchpad = deviceModel[index] + deviceSelector.model = deviceModel + deviceSelector.currentIndex = index + console.log("Touchpad configuration of device '" + + (index + 1) + " : " + touchpad.name + "' opened") + } else { + deviceSelector.model = [""] + console.log("No touchpad found") + } + loading = false + } + + function syncValuesFromBackend() { + loading = true + + deviceEnabled.load() + dwt.load() + leftHanded.load() + accelSpeed.load() + accelProfile.load() + tapToClick.load() + tapAndDrag.load() + tapAndDragLock.load() + multiTap.load() + scrollMethod.load() + naturalScroll.load() + + loading = false + } + Kirigami.FormLayout { id: formLayout - // Visaul behavior settings + // Device + Controls.ComboBox { + Kirigami.FormData.label: i18n("Device:") + id: deviceSelector + + enabled: touchpadCount > 1 + Layouts.Layout.fillWidth: true + model: deviceModel + textRole: "name" + + onCurrentIndexChanged: { + if (touchpadCount) { + touchpad = deviceModel[currentIndex] + if (!loading) { + changeSignal() + } + console.log("Touchpad configuration of device '" + + (currentIndex+1) + " : " + touchpad.name + "' opened") + } + root.syncValuesFromBackend() + } + } + + Kirigami.Separator { + } + + // General settings + Controls.CheckBox { + Kirigami.FormData.label: i18n("General:") + id: deviceEnabled + text: i18n("Device enabled") + + hoverEnabled: true + Controls.ToolTip { + text: i18n("Accept input through this device.") + visible: parent.hovered + delay: 1000 + } + + function load() { + if (!formLayout.enabled) { + checked = false + return + } + enabled = touchpad.supportsDisableEvents + checked = enabled && touchpad.enabled + } + + onCheckedChanged: { + if (enabled && !root.loading) { + touchpad.enabled = checked + root.changeSignal() + } + } + } + + Controls.CheckBox { + id: dwt + text: i18n("Disable while typing") + + hoverEnabled: true + Controls.ToolTip { + text: i18n("Disable touchpad while typing to prevent accidental inputs.") + visible: parent.hovered + delay: 1000 + } + + function load() { + if (!formLayout.enabled) { + checked = false + return + } + enabled = touchpad.supportsDisableWhileTyping + checked = enabled && touchpad.disableWhileTyping + } + + onCheckedChanged: { + if (enabled && !root.loading) { + touchpad.disableWhileTyping = checked + root.changeSignal() + } + } + } + Controls.CheckBox { - id: showToolTips - Kirigami.FormData.label: i18n("Visual behavior:") - text: i18n("Display informational tooltips on mouse hover") - checked: kcm.toolTip - onCheckedChanged: kcm.toolTip = checked + id: leftHanded + text: i18n("Left handed mode") + + hoverEnabled: true + Controls.ToolTip { + text: i18n("Swap left and right buttons.") + visible: parent.hovered + delay: 1000 + } + + function load() { + if (!formLayout.enabled) { + checked = false + return + } + enabled = touchpad.supportsLeftHanded + checked = enabled && touchpad.leftHanded + } + + onCheckedChanged: { + if (enabled && !root.loading) { + touchpad.leftHanded = checked + root.changeSignal() + } + } } Controls.CheckBox { - id: showVisualFeedback - text: i18n("Display visual feedback for status changes") - checked: kcm.visualFeedback - onCheckedChanged: kcm.visualFeedback = checked + id: middleEmulation + text: i18n("Press left and right buttons for middle click") + + hoverEnabled: true + Controls.ToolTip { + text: i18n("Clicking left and right button simultaneously sends middle button click.") + visible: parent.hovered + delay: 1000 + } + + function load() { + if (!formLayout.enabled) { + checked = false + return + } + enabled = touchpad.supportsMiddleEmulation + checked = enabled && touchpad.middleEmulation + } + + onCheckedChanged: { + if (enabled && !root.loading) { + touchpad.middleEmulation = checked + root.changeSignal() + } + } + } + + Kirigami.Separator { + } + + // Acceleration + Controls.Slider { + Kirigami.FormData.label: i18n("Pointer speed:") + id: accelSpeed + + from: 1 + to: 11 + stepSize: 1 + + function load() { + enabled = touchpad.supportsPointerAcceleration + if (!enabled) { + value = 0.1 + return + } + // transform libinput's pointer acceleration range [-1, 1] to slider range [1, 11] + value = 6 + touchpad.pointerAcceleration / 0.2 + } + + onValueChanged: { + if (touchpad != undefined && enabled && !root.loading) { + // transform slider range [1, 11] to libinput's pointer acceleration range [-1, 1] + // by *10 and /10, we ignore the floating points after 1 digit. This prevents from + // having a libinput value like 0.60000001 + touchpad.pointerAcceleration = Math.round(((value-6) * 0.2) * 10) / 10 + root.changeSignal() + } + } } - Connections { - target: kcm - onToolTipChanged: showToolTips.checked = kcm.toolTip - onVisualFeedbackChanged: showVisualFeedback.checked = kcm.visualFeedback + Layouts.ColumnLayout { + Kirigami.FormData.label: i18n("Acceleration profile:") + Kirigami.FormData.buddyFor: accelProfileFlat + id: accelProfile + spacing: Kirigami.Units.smallSpacing + + function load() { + enabled = touchpad.supportsPointerAccelerationProfileAdaptive + + if (!enabled) { + accelProfileFlat.checked = false + accelProfileAdaptive.checked = false + return + } + + if(touchpad.pointerAccelerationProfileAdaptive) { + accelProfileAdaptive.checked = true + } else { + accelProfileFlat.checked = true + } + } + + function syncCurrent() { + if (enabled && !root.loading) { + touchpad.pointerAccelerationProfileFlat = accelProfileFlat.checked + touchpad.pointerAccelerationProfileAdaptive = accelProfileAdaptive.checked + root.changeSignal() + } + } + + Controls.RadioButton { + id: accelProfileFlat + text: i18n("Flat") + + hoverEnabled: true + Controls.ToolTip { + text: i18n("Cursor moves the same distance as finger.") + visible: parent.hovered + delay: 1000 + } + onCheckedChanged: accelProfile.syncCurrent() + } + + Controls.RadioButton { + id: accelProfileAdaptive + text: i18n("Adaptive") + + hoverEnabled: true + Controls.ToolTip { + text: i18n("Cursor travel distance depends on movement speed of finger.") + visible: parent.hovered + delay: 1000 + } + onCheckedChanged: accelProfile.syncCurrent() + } } Kirigami.Separator { } - // Click behavior settings - Controls.ExclusiveGroup { - id: clickBehaviorGroup + // Tapping + Controls.CheckBox { + Kirigami.FormData.label: i18n("Tapping:") + id: tapToClick + text: i18n("Tap-to-click") + + hoverEnabled: true + Controls.ToolTip { + text: i18n("Single tap is left button click.") + visible: parent.hovered + delay: 1000 + } + + function load() { + enabled = touchpad.tapFingerCount > 0 + checked = enabled && touchpad.tapToClick + } + + function updateDependents() { + loading = true + tapAndDrag.load() + tapAndDragLock.load() + multiTap.load() + loading = false + } + + onCheckedChanged: { + if (enabled && !root.loading) { + touchpad.tapToClick = checked + updateDependents() + root.changeSignal() + } + } + } + + Controls.CheckBox { + id: tapAndDrag + text: i18n("Tap-and-drag") + + hoverEnabled: true + Controls.ToolTip { + text: i18n("Sliding over touchpad directly after tap drags.") + visible: parent.hovered + delay: 1000 + } + + function load() { + enabled = touchpad.tapFingerCount > 0 && tapToClick.checked + checked = enabled && touchpad.tapAndDrag + } + + function updateDependents() { + loading = true + tapAndDragLock.load() + loading = false + } + + onCheckedChanged: { + if (enabled && !root.loading) { + touchpad.tapAndDrag = checked + updateDependents() + root.changeSignal() + } + } + } + + Controls.CheckBox { + id: tapAndDragLock + text: i18n("Tap-and-drag lock") + + hoverEnabled: true + Controls.ToolTip { + text: i18n("Dragging continues after a short finger lift.") + visible: parent.hovered + delay: 1000 + } + + function load() { + enabled = touchpad.tapFingerCount > 0 && tapAndDrag.checked + checked = enabled && touchpad.tapDragLock + } + + onCheckedChanged: { + if (enabled && !root.loading) { + touchpad.tapDragLock = checked + root.changeSignal() + } + } + } + + Layouts.ColumnLayout { + Kirigami.FormData.label: i18n("Two-finger tap:") + Kirigami.FormData.buddyFor: multiTapRightClick + id: multiTap + + spacing: Kirigami.Units.smallSpacing + + function load() { + enabled = touchpad.supportsLmrTapButtonMap && tapToClick.checked + if (touchpad.tapFingerCount > 2) { + multiTapRightClick.text = i18n("Right-click (three-finger tap to middle-click)") + multiTapRightClickToolTip.text = i18n("Tap with two fingers to right-click, tap with three fingers to middle-click.") + + multiTapMiddleClick.text = i18n("Middle-click (three-finger tap right-click)") + multiTapMiddleClickToolTip.text = i18n("Tap with two fingers to middle-click, tap with three fingers to right-click.") + } else { + multiTapRightClick.text = i18n("Righ-click") + multiTapRightClickToolTip.text = i18n("Tap with two fingers to right-click.") + + multiTapMiddleClick.text = i18n("Middle-click") + multiTapMiddleClickToolTip.text = i18n("Tap with two fingers to middle-click.") + } + + if (!enabled) { + multiTapRightClick.checked = false + multiTapMiddleClick.checked = false + return + } + + if(touchpad.lmrTapButtonMap) { + multiTapMiddleClick.checked = true + } else { + multiTapRightClick.checked = true + } + } + + function syncCurrent() { + if (enabled && !root.loading) { + touchpad.lmrTapButtonMap = multiTapMiddleClick.checked + root.changeSignal() + } + } + + Controls.RadioButton { + id: multiTapRightClick + // text: is handled dynamically on load. + + hoverEnabled: true + Controls.ToolTip { + id: multiTapRightClickToolTip + visible: parent.hovered + delay: 1000 + // text: is handled dynamically on load. + } + onCheckedChanged: multiTap.syncCurrent() + } + + Controls.RadioButton { + id: multiTapMiddleClick + // text: is handled dynamically on load. + + hoverEnabled: true + Controls.ToolTip { + id: multiTapMiddleClickToolTip + visible: parent.hovered + delay: 1000 + // text: is handled dynamically on load. + } + onCheckedChanged: multiTap.syncCurrent() + } } - Controls.RadioButton { - id: singleClick - Kirigami.FormData.label: i18n("Click behavior:") - text: i18n("Single-click to open files and folders") - checked: kcm.singleClick - exclusiveGroup: clickBehaviorGroup - onCheckedChanged: kcm.singleClick = checked + Kirigami.Separator { } - Controls.RadioButton { - id: doubleClick - text: i18n("Double-click to open files and folders (single click to select)") - exclusiveGroup: clickBehaviorGroup + // Scrolling + Layouts.ColumnLayout { + Kirigami.FormData.label: i18n("Scrolling:") + Kirigami.FormData.buddyFor: scrollMethodTwoFingers + id: scrollMethod + + spacing: Kirigami.Units.smallSpacing + + function load() { + scrollMethodTwoFingers.enabled = touchpad.supportsScrollTwoFinger + scrollMethodTouchpadEdges.enabled = touchpad.supportsScrollEdge + + if(scrollMethodTouchpadEdges.enabled && touchpad.scrollEdge) { + scrollMethodTouchpadEdges.checked = formLayout.enabled + } else { + scrollMethodTwoFingers.checked = formLayout.enabled + } + } + + function syncCurrent() { + if (enabled && !root.loading) { + touchpad.scrollTwoFinger = scrollMethodTwoFingers.checked + touchpad.scrollEdge = scrollMethodTouchpadEdges.checked + root.changeSignal() + } + loading = true + naturalScroll.load() + loading = false + } + + Controls.RadioButton { + id: scrollMethodTwoFingers + text: i18n("Two fingers") + + hoverEnabled: true + Controls.ToolTip { + text: i18n("Slide with two fingers scrolls.") + visible: parent.hovered + delay: 1000 + } + } + + Controls.RadioButton { + id: scrollMethodTouchpadEdges + text: i18n("Touchpad edges") + + hoverEnabled: true + Controls.ToolTip { + text: i18n("Slide on the touchpad edges scrolls.") + visible: parent.hovered + delay: 1000 + } + onCheckedChanged: scrollMethod.syncCurrent() + } } - Connections { - target: kcm - onSingleClickChanged: { - singleClick.checked = kcm.singleClick - doubleClick.checked = !singleClick.checked + Controls.CheckBox { + id: naturalScroll + text: i18n("Invert scroll direction (Natural scrolling)") + + function load() { + enabled = touchpad.supportsNaturalScroll + checked = enabled && touchpad.naturalScroll + } + + onCheckedChanged: { + if (enabled && !root.loading) { + touchpad.naturalScroll = checked + root.changeSignal() + } + } + + hoverEnabled: true + Controls.ToolTip { + text: i18n("Touchscreen like scrolling.") + visible: parent.hovered + delay: 1000 } } - } -} + } // END Kirigami.FormLayout +} // END Kirigami.ScrollablePage