diff --git a/CMakeLists.txt b/CMakeLists.txt index d010538fa..7a56567ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,192 +1,196 @@ cmake_minimum_required(VERSION 3.0) project(plasma-desktop) set(PROJECT_VERSION "5.15.80") set(PROJECT_VERSION_MAJOR 5) set(QT_MIN_VERSION "5.11.0") set(KF5_MIN_VERSION "5.58.0") find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules) include(KDEInstallDirs) include(KDECMakeSettings) include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) include(ECMInstallIcons) include(ECMMarkAsTest) include(ECMMarkNonGuiExecutable) include(ECMOptionalAddSubdirectory) include(ECMQtDeclareLoggingCategory) include(FeatureSummary) include(CheckIncludeFiles) find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS Quick QuickWidgets DBus Widgets X11Extras Svg Concurrent ) find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS Auth Plasma PlasmaQuick DocTools I18n KCMUtils NewStuff KDELibs4Support Notifications NotifyConfig Attica Wallet Runner GlobalAccel Declarative People DBusAddons Activities ActivitiesStats Config ) find_package(KF5Kirigami2 ${KF5_MIN_VERSION} CONFIG) set_package_properties(KF5Kirigami2 PROPERTIES DESCRIPTION "A QtQuick based components set" PURPOSE "Required at runtime by many KCMs" TYPE RUNTIME ) find_package(KF5QQC2DeskopStyle ${KF5_MIN_VERSION} CONFIG) set_package_properties(KF5QQC2DeskopStyle PROPERTIES DESCRIPTION "QtQuickControls 2 style that uses QWidget's QStyle for painting" PURPOSE "Required at runtime by many KCMs" TYPE RUNTIME ) find_package(LibKWorkspace 5.14.90 CONFIG REQUIRED) find_package(LibNotificationManager 5.15.80 CONFIG REQUIRED) find_package(LibTaskManager 5.14.90 CONFIG REQUIRED) find_package(LibNotificationManager 5.14.90 CONFIG REQUIRED) find_package(LibColorCorrect 5.14.90 CONFIG REQUIRED) find_package(KWinDBusInterface CONFIG REQUIRED) find_package(ScreenSaverDBusInterface CONFIG REQUIRED) find_package(KRunnerAppDBusInterface CONFIG REQUIRED) find_package(KSMServerDBusInterface CONFIG REQUIRED) find_package(KF5ItemModels CONFIG REQUIRED) find_package(KF5Emoticons CONFIG REQUIRED) find_package(AppStreamQt 0.10.4) set_package_properties(AppStreamQt PROPERTIES DESCRIPTION "Appstream integration" TYPE RECOMMENDED PURPOSE "Needed to allow appstream integration from application menus" ) find_package(KF5Baloo 5.15) set_package_properties(KF5Baloo PROPERTIES DESCRIPTION "File Searching" TYPE RECOMMENDED PURPOSE "Needed to build the File Search KCM" ) find_package(Fontconfig) set_package_properties(Fontconfig PROPERTIES DESCRIPTION "Font access configuration library" URL "https://www.freedesktop.org/wiki/Software/fontconfig" TYPE OPTIONAL PURPOSE "Needed to build font configuration and installation tools" ) find_package(X11) set_package_properties(X11 PROPERTIES DESCRIPTION "X11 libraries" URL "https://www.x.org" TYPE REQUIRED PURPOSE "Required for building the X11 based workspace" ) if(X11_FOUND) set(HAVE_X11 1) endif() find_package(UDev) set_package_properties(UDev PROPERTIES DESCRIPTION "UDev library" URL "http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html" TYPE OPTIONAL PURPOSE "Required for device discovery in keyboard daemon" ) find_package(XCB REQUIRED COMPONENTS XCB SHM IMAGE OPTIONAL_COMPONENTS XKB XINPUT ) set_package_properties(XCB PROPERTIES TYPE REQUIRED) add_feature_info("XCB-XKB" XCB_XKB_FOUND "Required for building kcm/keyboard") add_feature_info("libxft" X11_Xft_FOUND "X FreeType interface library required for font installation") find_package(Evdev) set_package_properties(Evdev PROPERTIES TYPE OPTIONAL) add_feature_info("Evdev" EVDEV_FOUND "Evdev driver headers needed for mouse KCM") find_package(Synaptics) set_package_properties(Synaptics PROPERTIES TYPE OPTIONAL) add_feature_info("Synaptics" SYNAPTICS_FOUND "Synaptics libraries needed for touchpad KCM") find_package(XorgLibinput) set_package_properties(XorgLibinput PROPERTIES TYPE OPTIONAL) -add_feature_info("XorgLibinput" XORGLIBINPUT_FOUND "Libinput driver headers needed for mouse KCM") +add_feature_info("XorgLibinput" XORGLIBINPUT_FOUND "Libinput driver headers needed for mouse and touchpad KCM") + +if(XORGLIBINPUT_FOUND) + set(HAVE_XORGLIBINPUT 1) +endif() include(ConfigureChecks.cmake) find_package(Breeze ${PROJECT_VERSION} CONFIG) set_package_properties(Breeze PROPERTIES TYPE OPTIONAL PURPOSE "For setting the default window decoration plugin") if(${Breeze_FOUND}) if(${BREEZE_WITH_KDECORATION}) set(HAVE_BREEZE_DECO true) else() set(HAVE_BREEZE_DECO FALSE) endif() else() set(HAVE_BREEZE_DECO FALSE) endif() if(${AppStreamQt_FOUND}) set(HAVE_APPSTREAMQT true) endif() include_directories("${CMAKE_CURRENT_BINARY_DIR}") configure_file(config-workspace.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-workspace.h) configure_file(config-unix.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-unix.h ) configure_file(config-appstream.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-appstream.h ) configure_file(config-X11.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-X11.h) configure_file(config-runtime.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-runtime.h) plasma_install_package(desktoppackage org.kde.plasma.desktop shells shell) add_definitions(-DQT_NO_URL_CAST_FROM_STRING) add_subdirectory(layout-templates) add_subdirectory(doc) add_subdirectory(runners) add_subdirectory(containments) add_subdirectory(toolboxes) add_subdirectory(applets) add_subdirectory(dataengines) add_subdirectory(kcms) add_subdirectory(knetattach) add_subdirectory(attica-kde) add_subdirectory(imports/activitymanager/) add_subdirectory(solid-device-automounter) if(X11_Xkb_FOUND AND XCB_XKB_FOUND) add_subdirectory(kaccess) endif() install(FILES org.kde.plasmashell.metainfo.xml DESTINATION ${KDE_INSTALL_METAINFODIR}) install(FILES plasma-desktop.categories DESTINATION ${KDE_INSTALL_CONFDIR}) feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/config-X11.h.cmake b/config-X11.h.cmake index ae8978a08..20b2fd98c 100644 --- a/config-X11.h.cmake +++ b/config-X11.h.cmake @@ -1,44 +1,47 @@ /* Define if you have the XRandR extension */ #cmakedefine HAVE_XRANDR 1 /* Define if you have the XDamage extension */ #cmakedefine HAVE_XDAMAGE 1 /* Define if you have the XKB extension */ #cmakedefine HAVE_XKB 1 /* Define if you have the Xinerama extension */ #cmakedefine HAVE_XINERAMA 1 /* Define if you have the XSHM (MIT SHM) extension */ #cmakedefine HAVE_XSHM 1 /* Define if you have the XComposite extension */ #cmakedefine HAVE_XCOMPOSITE 1 /* Define to 1 if you have Xcursor */ #cmakedefine HAVE_XCURSOR 1 /* Define if you have the xf86misc extension */ #cmakedefine HAVE_XF86MISC 1 /* Define if you have the XFixes extension */ #cmakedefine HAVE_XFIXES 1 /* Define if you have the XTest extension */ #cmakedefine HAVE_XTEST 1 /* Define if your system has XRender support */ #cmakedefine HAVE_XRENDER 1 /* Define if you have OpenGL */ #cmakedefine HAVE_OPENGL 1 /* Define if you have the XSync extension */ #cmakedefine HAVE_XSYNC 1 /* Define if you have XRandR 1.3 */ #cmakedefine HAS_RANDR_1_3 1 +/* Define if you have XorgLibinput */ +#cmakedefine01 HAVE_XORGLIBINPUT + /* Define if you have X11 at all */ #cmakedefine01 HAVE_X11 diff --git a/kcms/touchpad/src/backends/libinputcommon.h b/kcms/touchpad/src/backends/libinputcommon.h index ee81288c5..c8fa48ecf 100644 --- a/kcms/touchpad/src/backends/libinputcommon.h +++ b/kcms/touchpad/src/backends/libinputcommon.h @@ -1,490 +1,490 @@ /* * Copyright 2017 Roman Gilg * Copyright 2019 Atul Bisht * * 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 LIBINPUTCOMMON_H #define LIBINPUTCOMMON_H #include #include namespace { template -T valueLoaderPart(QVariant const &reply) { Q_UNUSED(reply); return T(); } +inline T valueLoaderPart(QVariant const &reply) { Q_UNUSED(reply); return T(); } template<> -bool valueLoaderPart(QVariant const &reply) { return reply.toBool(); } +inline bool valueLoaderPart(QVariant const &reply) { return reply.toBool(); } template<> -int valueLoaderPart(QVariant const &reply) { return reply.toInt(); } +inline int valueLoaderPart(QVariant const &reply) { return reply.toInt(); } template<> -quint32 valueLoaderPart(QVariant const &reply) { return reply.toInt(); } +inline quint32 valueLoaderPart(QVariant const &reply) { return reply.toInt(); } template<> -qreal valueLoaderPart(QVariant const &reply) { return reply.toReal(); } +inline qreal valueLoaderPart(QVariant const &reply) { return reply.toReal(); } template<> -QString valueLoaderPart(QVariant const &reply) { return reply.toString(); } +inline QString valueLoaderPart(QVariant const &reply) { return reply.toString(); } template<> -Qt::MouseButtons valueLoaderPart(QVariant const &reply) { return static_cast(reply.toInt()); } +inline Qt::MouseButtons valueLoaderPart(QVariant const &reply) { return static_cast(reply.toInt()); } } class LibinputCommon : 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 supportsHorizontalScrolling READ supportsHorizontalScrolling CONSTANT) Q_PROPERTY(bool horizontalScrollingByDefault READ horizontalScrollingByDefault CONSTANT) Q_PROPERTY(bool horizontalScrolling READ horizontalScrolling WRITE setHorizontalScrolling NOTIFY horizontalScrollingChanged) 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) // Click Methods Q_PROPERTY(bool supportsClickMethodAreas READ supportsClickMethodAreas CONSTANT) Q_PROPERTY(bool defaultClickMethodAreas READ defaultClickMethodAreas CONSTANT) Q_PROPERTY(bool clickMethodAreas READ isClickMethodAreas WRITE setClickMethodAreas NOTIFY clickMethodChanged) Q_PROPERTY(bool supportsClickMethodClickfinger READ supportsClickMethodClickfinger CONSTANT) Q_PROPERTY(bool defaultClickMethodClickfinger READ defaultClickMethodClickfinger CONSTANT) Q_PROPERTY(bool clickMethodClickfinger READ isClickMethodClickfinger WRITE setClickMethodClickfinger NOTIFY clickMethodChanged) public: LibinputCommon() {} virtual ~LibinputCommon() {} virtual QString name() const = 0; virtual bool supportsDisableEvents() const = 0; virtual bool isEnabled() const = 0; virtual void setEnabled(bool set) = 0; // // advanced Qt::MouseButtons supportedButtons() const { return m_supportedButtons.val; } virtual bool supportsLeftHanded() const = 0; bool leftHandedEnabledByDefault() const { return m_leftHandedEnabledByDefault.val; } bool isLeftHanded() const { return m_leftHanded.val; } void setLeftHanded(bool set) { m_leftHanded.set(set); } virtual bool supportsDisableEventsOnExternalMouse() const = 0; virtual bool supportsDisableWhileTyping() const = 0; bool disableWhileTypingEnabledByDefault() const { return m_disableWhileTypingEnabledByDefault.val; } bool isDisableWhileTyping() const { return m_disableWhileTyping.val; } void setDisableWhileTyping(bool set) { m_disableWhileTyping.set(set); } virtual bool supportsMiddleEmulation() const = 0; bool middleEmulationEnabledByDefault() const { return m_middleEmulationEnabledByDefault.val; } bool isMiddleEmulation() const { return m_middleEmulation.val; } void setMiddleEmulation(bool set) { m_middleEmulation.set(set); } virtual bool supportsPointerAcceleration() const = 0; qreal pointerAcceleration() const { return m_pointerAcceleration.val; } void setPointerAcceleration(qreal acceleration) { m_pointerAcceleration.set(acceleration); } virtual bool supportsPointerAccelerationProfileFlat() const = 0; bool defaultPointerAccelerationProfileFlat() const { return m_defaultPointerAccelerationProfileFlat.val; } bool pointerAccelerationProfileFlat() const { return m_pointerAccelerationProfileFlat.val; } void setPointerAccelerationProfileFlat(bool set) { m_pointerAccelerationProfileFlat.set(set); } virtual bool supportsPointerAccelerationProfileAdaptive() const = 0; bool defaultPointerAccelerationProfileAdaptive() const { return m_defaultPointerAccelerationProfileAdaptive.val; } bool pointerAccelerationProfileAdaptive() const { return m_pointerAccelerationProfileAdaptive.val; } void setPointerAccelerationProfileAdaptive(bool set) { m_pointerAccelerationProfileAdaptive.set(set); } // // scrolling virtual bool supportsNaturalScroll() const = 0; bool naturalScrollEnabledByDefault() const { return m_naturalScrollEnabledByDefault.val; } bool isNaturalScroll() const { return m_naturalScroll.val; } void setNaturalScroll(bool set) { m_naturalScroll.set(set); } virtual bool supportsHorizontalScrolling() const = 0; bool horizontalScrollingByDefault() const { return true; } bool horizontalScrolling() const { return m_horizontalScrolling.val; } void setHorizontalScrolling(bool set) { m_horizontalScrolling.set(set); } virtual bool supportsScrollTwoFinger() const = 0; bool scrollTwoFingerEnabledByDefault() const { return m_scrollTwoFingerEnabledByDefault.val; } bool isScrollTwoFinger() const { return m_isScrollTwoFinger.val; } void setScrollTwoFinger(bool set) { m_isScrollTwoFinger.set(set); } virtual bool supportsScrollEdge() const = 0; bool scrollEdgeEnabledByDefault() const { return m_scrollEdgeEnabledByDefault.val; } bool isScrollEdge() const { return m_isScrollEdge.val; } void setScrollEdge(bool set) { m_isScrollEdge.set(set); } virtual bool supportsScrollOnButtonDown() const = 0; 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); } // // 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; } virtual void setLmrTapButtonMap(bool set) = 0; 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); } // // click method virtual bool supportsClickMethodAreas() const = 0; bool defaultClickMethodAreas() const { return m_defaultClickMethodAreas.val; } bool isClickMethodAreas() const { return m_clickMethodAreas.val; } void setClickMethodAreas(bool set) { m_clickMethodAreas.set(set); } virtual bool supportsClickMethodClickfinger() const = 0; bool defaultClickMethodClickfinger() const { return m_defaultClickMethodClickfinger.val; } bool isClickMethodClickfinger() const { return m_clickMethodClickfinger.val; } void setClickMethodClickfinger(bool set) { m_clickMethodClickfinger.set(set); } Q_SIGNALS: void enabledChanged(); // Tapping void tapToClickChanged(); void lmrTapButtonMapChanged(); void tapAndDragChanged(); void tapDragLockChanged(); // Advanced void leftHandedChanged(); void disableWhileTypingChanged(); void middleEmulationChanged(); // acceleration speed and profile void pointerAccelerationChanged(); void pointerAccelerationProfileChanged(); // scrolling void naturalScrollChanged(); void horizontalScrollingChanged(); void scrollMethodChanged(); void scrollButtonChanged(); // click methods void clickMethodChanged(); protected: template struct Prop { explicit Prop(const QByteArray &name) : name(name) {} 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); } // In wayland, name will be dbus name QByteArray name; bool avail; T old; T val; }; // // general Prop m_supportsDisableEvents = Prop("supportsDisableEvents"); Prop m_enabledDefault = Prop("enabledDefault"); Prop m_enabled = Prop("enabled"); // // advanced Prop m_supportedButtons = Prop("supportedButtons"); Prop m_leftHandedEnabledByDefault = Prop("leftHandedEnabledByDefault"); Prop m_leftHanded = Prop("leftHanded"); Prop m_supportsDisableEventsOnExternalMouse = Prop("supportsDisableEventsOnExternalMouse"); Prop m_disableWhileTypingEnabledByDefault = Prop("disableWhileTypingEnabledByDefault"); Prop m_disableWhileTyping = Prop("disableWhileTyping"); Prop m_middleEmulationEnabledByDefault = Prop("middleEmulationEnabledByDefault"); Prop m_middleEmulation = Prop("middleEmulation"); // // acceleration speed and profile 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_naturalScrollEnabledByDefault = Prop("naturalScrollEnabledByDefault"); Prop m_naturalScroll = Prop("naturalScroll"); Prop m_horizontalScrolling = Prop("horizontalScrolling"); 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"); // Click Method Prop m_supportsClickMethodAreas = Prop("supportsClickMethodAreas"); Prop m_defaultClickMethodAreas = Prop("defaultClickMethodAreas"); Prop m_clickMethodAreas = Prop("clickMethodAreas"); Prop m_supportsClickMethodClickfinger = Prop("supportsClickMethodClickfinger"); Prop m_defaultClickMethodClickfinger = Prop("defaultClickMethodClickfinger"); Prop m_clickMethodClickfinger = Prop("clickMethodClickfinger"); }; #endif // LIBINPUTCOMMON_H diff --git a/kcms/touchpad/src/backends/x11.cmake b/kcms/touchpad/src/backends/x11.cmake index db25da464..4468c34aa 100644 --- a/kcms/touchpad/src/backends/x11.cmake +++ b/kcms/touchpad/src/backends/x11.cmake @@ -1,46 +1,52 @@ # // krazy:excludeall=copyright,license find_package(X11 REQUIRED) find_package(X11_XCB REQUIRED) find_package(XCB REQUIRED COMPONENTS ATOM RECORD) find_package(PkgConfig REQUIRED) if(NOT X11_Xinput_FOUND) message(FATAL_ERROR "Xinput not found") endif() include_directories(${X11_Xinput_INCLUDE_PATH} ${X11_X11_INCLUDE_PATH} ${Synaptics_INCLUDE_DIRS} ${XORG_INCLUDE_DIRS} ) SET(backend_SRCS ${backend_SRCS} - backends/libinputcommon.cpp backends/x11/propertyinfo.cpp backends/x11/xlibbackend.cpp backends/x11/synapticstouchpad.cpp - backends/x11/libinputtouchpad.cpp backends/x11/xlibtouchpad.cpp backends/x11/xcbatom.cpp backends/x11/xlibnotifications.cpp backends/x11/xrecordkeyboardmonitor.cpp ) +if (HAVE_XORGLIBINPUT) + SET(backend_SRCS + ${backend_SRCS} + backends/libinputcommon.cpp + backends/x11/libinputtouchpad.cpp + ) +endif() + SET(backend_LIBS ${backend_LIBS} XCB::ATOM XCB::RECORD ${X11_X11_LIB} X11::XCB ${X11_Xinput_LIB} ) add_executable(kcm-touchpad-list-devices backends/x11/listdevices.cpp) target_link_libraries(kcm-touchpad-list-devices ${X11_X11_LIB} ${X11_Xinput_LIB} ) install(TARGETS kcm-touchpad-list-devices DESTINATION ${KDE_INSTALL_TARGETS_DEFAULT_ARGS} ) diff --git a/kcms/touchpad/src/backends/x11/libinputtouchpad.cpp b/kcms/touchpad/src/backends/x11/libinputtouchpad.cpp index 389d85961..c86026c4f 100644 --- a/kcms/touchpad/src/backends/x11/libinputtouchpad.cpp +++ b/kcms/touchpad/src/backends/x11/libinputtouchpad.cpp @@ -1,404 +1,403 @@ /* * Copyright (C) 2019 Atul Bisht * * 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 -#include - #include "libinputtouchpad.h" +#include "logging.h" #include #include -#include #include -#include "logging.h" +#include + +#include -const struct Parameter libinputProperties[] = { +const Parameter libinputProperties[] = { /* libinput disable supports property */ {"supportsDisableEvents", PT_INT, 0, 1, LIBINPUT_PROP_SENDEVENTS_AVAILABLE, 8, 0}, {"enabled", PT_INT, 0, 1, LIBINPUT_PROP_SENDEVENTS_ENABLED, 8, 0}, {"enabledDefault", PT_INT, 0, 1, LIBINPUT_PROP_SENDEVENTS_ENABLED_DEFAULT, 8, 0}, /* LeftHandSupport */ {"leftHandedEnabledByDefault", PT_INT, 0, 1, LIBINPUT_PROP_LEFT_HANDED_DEFAULT, 8, 0}, {"leftHanded", PT_INT, 0, 1, LIBINPUT_PROP_LEFT_HANDED, 8, 0}, /* Disable on external mouse */ {"supportsDisableEventsOnExternalMouse",PT_INT, 0, 1, LIBINPUT_PROP_SENDEVENTS_AVAILABLE, 8, 1}, {"disableEventsOnExternalMouse", PT_INT, 0, 1, LIBINPUT_PROP_SENDEVENTS_ENABLED, 8, 1}, {"disableEventsOnExternalMouseDefault", PT_INT, 0, 1, LIBINPUT_PROP_SENDEVENTS_ENABLED_DEFAULT, 8, 1}, /* Disable while typing */ {"disableWhileTypingEnabledByDefault", PT_INT, 0, 1, LIBINPUT_PROP_DISABLE_WHILE_TYPING_DEFAULT, 8, 0}, {"disableWhileTyping", PT_INT, 0, 1, LIBINPUT_PROP_DISABLE_WHILE_TYPING, 8, 0}, /* Middle Emulation */ {"middleEmulationEnabledByDefault", PT_INT, 0, 1, LIBINPUT_PROP_MIDDLE_EMULATION_ENABLED_DEFAULT, 8, 0}, {"middleEmulation", PT_INT, 0, 1, LIBINPUT_PROP_MIDDLE_EMULATION_ENABLED, 8, 0}, /* This is a boolean for all three fingers, no per-finger config */ {"tapToClick", PT_INT, 0, 1, LIBINPUT_PROP_TAP, 8, 0}, {"tapToClickEnabledByDefault", PT_INT, 0, 1, LIBINPUT_PROP_TAP_DEFAULT, 8, 0}, /* LMR */ {"lrmTapButtonMapEnabledByDefault", PT_INT, 0, 1, LIBINPUT_PROP_TAP_BUTTONMAP_DEFAULT, 8, 0}, {"lrmTapButtonMap", PT_INT, 0, 1, LIBINPUT_PROP_TAP_BUTTONMAP, 8, 0}, {"lmrTapButtonMapEnabledByDefault", PT_INT, 0, 1, LIBINPUT_PROP_TAP_BUTTONMAP_DEFAULT, 8, 1}, {"lmrTapButtonMap", PT_INT, 0, 1, LIBINPUT_PROP_TAP_BUTTONMAP, 8, 1}, /* Tap and Drag Enabled */ {"tapAndDragEnabledByDefault", PT_INT, 0, 1, LIBINPUT_PROP_TAP_DRAG_DEFAULT, 8, 0}, {"tapAndDrag", PT_INT, 0, 1, LIBINPUT_PROP_TAP_DRAG, 8, 0}, /* Tap and Drag Lock Enabled */ {"tapDragLockEnabledByDefault", PT_INT, 0, 1, LIBINPUT_PROP_TAP_DRAG_LOCK_DEFAULT, 8, 0}, {"tapDragLock", PT_INT, 0, 1, LIBINPUT_PROP_TAP_DRAG_LOCK, 8, 0}, /* libinput normalizes the accel to -1/1 */ {"defaultPointerAcceleration", PT_DOUBLE, -1.0, 1.0, LIBINPUT_PROP_ACCEL_DEFAULT, 0 /*float */, 0}, {"pointerAcceleration", PT_DOUBLE, -1.0, 1.0, LIBINPUT_PROP_ACCEL, 0 /*float */, 0}, /* Libinput Accel Profile */ {"supportsPointerAccelerationProfileAdaptive", PT_BOOL, 0, 1, LIBINPUT_PROP_ACCEL_PROFILES_AVAILABLE, 8, 0}, {"defaultPointerAccelerationProfileAdaptive", PT_BOOL, 0, 1, LIBINPUT_PROP_ACCEL_PROFILE_ENABLED_DEFAULT, 8, 0}, {"pointerAccelerationProfileAdaptive", PT_BOOL, 0, 1, LIBINPUT_PROP_ACCEL_PROFILE_ENABLED, 8, 0}, {"supportsPointerAccelerationProfileFlat", PT_BOOL, 0, 1, LIBINPUT_PROP_ACCEL_PROFILES_AVAILABLE, 8, 1}, {"defaultPointerAccelerationProfileFlat", PT_BOOL, 0, 1, LIBINPUT_PROP_ACCEL_PROFILE_ENABLED_DEFAULT, 8, 1}, {"pointerAccelerationProfileFlat", PT_BOOL, 0, 1, LIBINPUT_PROP_ACCEL_PROFILE_ENABLED, 8, 1}, /* Natural Scrolling */ {"naturalScrollEnabledByDefault", PT_INT, 0, 1, LIBINPUT_PROP_NATURAL_SCROLL_DEFAULT, 8, 0}, {"naturalScroll", PT_INT, 0, 1, LIBINPUT_PROP_NATURAL_SCROLL, 8, 0}, /* Horizontal scrolling */ {"horizontalScrolling", PT_INT, 0, 1, LIBINPUT_PROP_HORIZ_SCROLL_ENABLED, 8, 0}, /* Two-Finger Scrolling */ {"supportsScrollTwoFinger", PT_INT, 0, 1, LIBINPUT_PROP_SCROLL_METHODS_AVAILABLE, 8, 0}, {"scrollTwoFingerEnabledByDefault", PT_INT, 0, 1, LIBINPUT_PROP_SCROLL_METHOD_ENABLED_DEFAULT, 8, 0}, {"scrollTwoFinger", PT_INT, 0, 1, LIBINPUT_PROP_SCROLL_METHOD_ENABLED, 8, 0}, /* Edge Scrolling */ {"supportsScrollEdge", PT_INT, 0, 1, LIBINPUT_PROP_SCROLL_METHODS_AVAILABLE, 8, 1}, {"scrollEdgeEnabledByDefault", PT_INT, 0, 1, LIBINPUT_PROP_SCROLL_METHOD_ENABLED_DEFAULT, 8, 1}, {"scrollEdge", PT_INT, 0, 1, LIBINPUT_PROP_SCROLL_METHOD_ENABLED, 8, 1}, /* scroll on button */ {"supportsScrollOnButtonDown", PT_INT, 0, 1, LIBINPUT_PROP_SCROLL_METHODS_AVAILABLE, 8, 2}, {"scrollOnButtonDownEnabledByDefault", PT_INT, 0, 1, LIBINPUT_PROP_SCROLL_METHOD_ENABLED_DEFAULT, 8, 2}, {"scrollOnButtonDown", PT_INT, 0, 1, LIBINPUT_PROP_SCROLL_METHOD_ENABLED, 8, 2}, /* Scroll Button for scroll on button Down */ {"defaultScrollButton", PT_INT, 0, INT_MAX, LIBINPUT_PROP_SCROLL_BUTTON_DEFAULT, 32, 0}, {"scrollButton", PT_INT, 0, INT_MAX, LIBINPUT_PROP_SCROLL_BUTTON, 32, 0}, /* Click Methods */ {"supportsClickMethodAreas", PT_INT, 0, 1, LIBINPUT_PROP_CLICK_METHODS_AVAILABLE, 8, 0}, {"defaultClickMethodAreas", PT_INT, 0, 1, LIBINPUT_PROP_CLICK_METHOD_ENABLED_DEFAULT, 8, 0}, {"clickMethodAreas", PT_INT, 0, 1, LIBINPUT_PROP_CLICK_METHOD_ENABLED, 8, 0}, {"supportsClickMethodClickfinger", PT_INT, 0, 1, LIBINPUT_PROP_CLICK_METHODS_AVAILABLE, 8, 1}, {"defaultClickMethodClickfinger", PT_INT, 0, 1, LIBINPUT_PROP_CLICK_METHOD_ENABLED_DEFAULT, 8, 1}, {"clickMethodClickfinger", PT_INT, 0, 1, LIBINPUT_PROP_CLICK_METHOD_ENABLED, 8, 1}, /* libinput doesn't have a separate toggle for horiz scrolling */ - { NULL, PT_INT, 0, 0, 0, 0, 0 } + { nullptr, PT_INT, 0, 0, nullptr, 0, 0 } }; Qt::MouseButtons maskBtns(Display *display, XIButtonClassInfo *buttonInfo) { Qt::MouseButtons buttons = Qt::NoButton; for (int i = 0; i < buttonInfo->num_buttons; ++i) { QByteArray reply = XGetAtomName(display, buttonInfo->labels[i]); if (reply == BTN_LABEL_PROP_BTN_LEFT) { buttons |= Qt::LeftButton; } if (reply == BTN_LABEL_PROP_BTN_RIGHT) { buttons |= Qt::RightButton; } if (reply == BTN_LABEL_PROP_BTN_MIDDLE) { buttons |= Qt::MiddleButton; } if (reply == BTN_LABEL_PROP_BTN_SIDE) { buttons |= Qt::ExtraButton1; } if (reply == BTN_LABEL_PROP_BTN_EXTRA) { buttons |= Qt::ExtraButton2; } if (reply == BTN_LABEL_PROP_BTN_FORWARD) { buttons |= Qt::ForwardButton; } if (reply == BTN_LABEL_PROP_BTN_BACK) { buttons |= Qt::BackButton; } if (reply == BTN_LABEL_PROP_BTN_TASK) { buttons |= Qt::TaskButton; } } return buttons; } LibinputTouchpad::LibinputTouchpad(Display *display, int deviceId): LibinputCommon(), XlibTouchpad(display, deviceId) { loadSupportedProperties(libinputProperties); int nDevices = 0; XIDeviceInfo *deviceInfo = XIQueryDevice(m_display, m_deviceId, &nDevices); m_name = deviceInfo->name; for (int i = 0; i < deviceInfo->num_classes; ++i) { XIAnyClassInfo *classInfo = deviceInfo->classes[i]; if (classInfo->type == XIButtonClass) { XIButtonClassInfo *btnInfo = (XIButtonClassInfo*) classInfo; m_supportedButtons.avail = true; m_supportedButtons.set(maskBtns(m_display, btnInfo)); } if (classInfo->type == XITouchClass) { XITouchClassInfo *touchInfo = (XITouchClassInfo*) classInfo; m_tapFingerCount.avail = true; m_tapFingerCount.set(touchInfo->num_touches); } } XIFreeDeviceInfo(deviceInfo); /* FingerCount cannot be zero */ if (!m_tapFingerCount.val) { m_tapFingerCount.avail = true; m_tapFingerCount.set(1); } } bool LibinputTouchpad::getConfig() { bool success = true; success &= valueLoader(m_supportsDisableEvents); success &= valueLoader(m_enabled); success &= valueLoader(m_enabledDefault); success &= valueLoader(m_tapToClickEnabledByDefault); success &= valueLoader(m_tapToClick); success &= valueLoader(m_lrmTapButtonMapEnabledByDefault); success &= valueLoader(m_lrmTapButtonMap); success &= valueLoader(m_lmrTapButtonMapEnabledByDefault); success &= valueLoader(m_lmrTapButtonMap); success &= valueLoader(m_tapAndDragEnabledByDefault); success &= valueLoader(m_tapAndDrag); success &= valueLoader(m_tapDragLockEnabledByDefault); success &= valueLoader(m_tapDragLock); success &= valueLoader(m_leftHandedEnabledByDefault); success &= valueLoader(m_leftHanded); success &= valueLoader(m_supportsDisableEventsOnExternalMouse); success &= valueLoader(m_disableEventsOnExternalMouse); success &= valueLoader(m_disableEventsOnExternalMouseDefault); success &= valueLoader(m_disableWhileTypingEnabledByDefault); success &= valueLoader(m_disableWhileTyping); success &= valueLoader(m_middleEmulationEnabledByDefault); success &= valueLoader(m_middleEmulation); success &= valueLoader(m_defaultPointerAcceleration); success &= valueLoader(m_pointerAcceleration); success &= valueLoader(m_supportsPointerAccelerationProfileFlat); success &= valueLoader(m_defaultPointerAccelerationProfileFlat); success &= valueLoader(m_pointerAccelerationProfileFlat); success &= valueLoader(m_supportsPointerAccelerationProfileAdaptive); success &= valueLoader(m_defaultPointerAccelerationProfileAdaptive); success &= valueLoader(m_pointerAccelerationProfileAdaptive); success &= valueLoader(m_naturalScrollEnabledByDefault); success &= valueLoader(m_naturalScroll); success &= valueLoader(m_horizontalScrolling); success &= valueLoader(m_supportsScrollTwoFinger); success &= valueLoader(m_scrollTwoFingerEnabledByDefault); success &= valueLoader(m_isScrollTwoFinger); success &= valueLoader(m_supportsScrollEdge); success &= valueLoader(m_scrollEdgeEnabledByDefault); success &= valueLoader(m_isScrollEdge); success &= valueLoader(m_supportsScrollOnButtonDown); success &= valueLoader(m_scrollOnButtonDownEnabledByDefault); success &= valueLoader(m_isScrollOnButtonDown); success &= valueLoader(m_defaultScrollButton); success &= valueLoader(m_scrollButton); // click methods success &= valueLoader(m_supportsClickMethodAreas); success &= valueLoader(m_supportsClickMethodClickfinger); success &= valueLoader(m_defaultClickMethodAreas); success &= valueLoader(m_defaultClickMethodClickfinger); success &= valueLoader(m_clickMethodAreas); success &= valueLoader(m_clickMethodClickfinger); return success; } bool LibinputTouchpad::applyConfig() { QVector msgs; msgs << valueWriter(m_enabled) << valueWriter(m_tapToClick) << valueWriter(m_lrmTapButtonMap) << valueWriter(m_lmrTapButtonMap) << valueWriter(m_tapAndDrag) << valueWriter(m_tapDragLock) << valueWriter(m_leftHanded) << valueWriter(m_disableWhileTyping) << valueWriter(m_middleEmulation) << valueWriter(m_pointerAcceleration) << valueWriter(m_pointerAccelerationProfileFlat) << valueWriter(m_pointerAccelerationProfileAdaptive) << valueWriter(m_naturalScroll) << valueWriter(m_horizontalScrolling) << valueWriter(m_isScrollTwoFinger) << valueWriter(m_isScrollEdge) << valueWriter(m_isScrollOnButtonDown) << valueWriter(m_scrollButton) << valueWriter(m_clickMethodAreas) << valueWriter(m_clickMethodClickfinger); 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; } flush(); return success; } bool LibinputTouchpad::getDefaultConfig() { m_enabled.set(m_enabledDefault); m_tapToClick.set(m_tapToClickEnabledByDefault); m_lrmTapButtonMap.set(m_lrmTapButtonMap); m_lmrTapButtonMap.set(m_lmrTapButtonMapEnabledByDefault); m_tapAndDrag.set(m_tapAndDragEnabledByDefault); m_tapDragLock.set(m_tapDragLockEnabledByDefault); m_leftHanded.set(m_leftHandedEnabledByDefault); m_disableEventsOnExternalMouse.set(m_disableEventsOnExternalMouseDefault); m_disableWhileTyping.set(m_disableWhileTypingEnabledByDefault); m_middleEmulation.set(m_middleEmulationEnabledByDefault); m_pointerAcceleration.set(m_defaultPointerAcceleration); m_pointerAccelerationProfileFlat.set(m_defaultPointerAccelerationProfileFlat); m_pointerAccelerationProfileAdaptive.set(m_defaultPointerAccelerationProfileAdaptive); m_naturalScroll.set(m_naturalScrollEnabledByDefault); m_horizontalScrolling.set(true); m_isScrollTwoFinger.set(m_scrollTwoFingerEnabledByDefault); m_isScrollEdge.set(m_scrollEdgeEnabledByDefault); m_isScrollOnButtonDown.set(m_scrollOnButtonDownEnabledByDefault); m_scrollButton.set(m_defaultScrollButton); m_clickMethodAreas.set(m_defaultClickMethodAreas); m_clickMethodClickfinger.set(m_defaultClickMethodClickfinger); return true; } bool LibinputTouchpad::isChangedConfig() { bool changed = m_enabled.changed() || m_tapToClick.changed() || m_lrmTapButtonMap.changed() || m_lmrTapButtonMap.changed() || m_tapAndDrag.changed() || m_tapDragLock.changed() || m_leftHanded.changed() || m_disableEventsOnExternalMouse.changed() || m_disableWhileTyping.changed() || m_middleEmulation.changed() || m_pointerAcceleration.changed() || m_pointerAccelerationProfileFlat.changed() || m_pointerAccelerationProfileAdaptive.changed() || m_naturalScroll.changed() || m_horizontalScrolling.changed() || m_isScrollTwoFinger.changed() || m_isScrollEdge.changed() || m_isScrollOnButtonDown.changed() || m_scrollButton.changed() || m_clickMethodAreas.changed() || m_clickMethodClickfinger.changed(); return changed; } template bool LibinputTouchpad::valueLoader(Prop &prop) { const Parameter *p = findParameter(QString::fromAscii(prop.name)); if (!p) { qCCritical(KCM_TOUCHPAD) << "Error on read of " << QString::fromAscii(prop.name); } QVariant reply = getParameter(p); if (!reply.isValid()) { prop.avail = false; return true; } prop.avail = true; T replyValue = valueLoaderPart(reply); prop.old = replyValue; prop.val = replyValue; return true; } template QString LibinputTouchpad::valueWriter(const Prop &prop) { const Parameter *p = findParameter(QString::fromAscii(prop.name)); if (!p || !prop.changed()) { return QString(); } bool error = !setParameter( p, prop.val); if (error) { qCCritical(KCM_TOUCHPAD) << "Cannot set property " + QString::fromAscii(prop.name); return QStringLiteral("Cannot set property ") + QString::fromAscii(prop.name); } return QString(); } diff --git a/kcms/touchpad/src/backends/x11/xlibbackend.cpp b/kcms/touchpad/src/backends/x11/xlibbackend.cpp index 4d5ffa43d..03a2e693b 100644 --- a/kcms/touchpad/src/backends/x11/xlibbackend.cpp +++ b/kcms/touchpad/src/backends/x11/xlibbackend.cpp @@ -1,391 +1,400 @@ /* * Copyright (C) 2013 Alexander Mezin * * 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 #include #include #include #include #include +#include + //Includes are ordered this way because of #defines in Xorg's headers #include "xrecordkeyboardmonitor.h" // krazy:exclude=includes #include "xlibbackend.h" // krazy:exclude=includes #include "xlibnotifications.h" // krazy:exclude=includes +#if HAVE_XORGLIBINPUT #include "libinputtouchpad.h" +#endif #include "synapticstouchpad.h" #include "propertyinfo.h" #include #include #include #include #include #include struct DeviceListDeleter { static void cleanup(XDeviceInfo *p) { if (p) { XFreeDeviceList(p); } } }; void XlibBackend::XDisplayCleanup::cleanup(Display *p) { if (p) { XCloseDisplay(p); } } XlibBackend* XlibBackend::initialize(QObject *parent) { XlibBackend* backend = new XlibBackend(parent); if (!backend->m_display) { delete backend; return nullptr; } return backend; } XlibBackend::~XlibBackend() { } XlibBackend::XlibBackend(QObject *parent) : TouchpadBackend(parent), m_display(XOpenDisplay(0)), m_connection(0) { if (m_display) { m_connection = XGetXCBConnection(m_display.data()); } if (!m_connection) { m_errorString = i18n("Cannot connect to X server"); return; } m_mouseAtom.intern(m_connection, XI_MOUSE); m_keyboardAtom.intern(m_connection, XI_KEYBOARD); m_touchpadAtom.intern(m_connection, XI_TOUCHPAD); m_enabledAtom.intern(m_connection, XI_PROP_ENABLED); m_synapticsIdentifierAtom.intern(m_connection, SYNAPTICS_PROP_CAPABILITIES); m_libinputIdentifierAtom.intern(m_connection, "libinput Send Events Modes Available"); m_device.reset(findTouchpad()); if (!m_device) { m_errorString = i18n("No touchpad found"); } } XlibTouchpad* XlibBackend::findTouchpad() { int nDevices = 0; QScopedPointer deviceInfo(XListInputDevices(m_display.data(), &nDevices)); for (XDeviceInfo *info = deviceInfo.data(); info < deviceInfo.data() + nDevices; info++) { // Make sure device is touchpad if (info->type != m_touchpadAtom.atom()) { continue; } int nProperties = 0; QSharedPointer properties( XIListProperties(m_display.data(), info->id, &nProperties), XDeleter); Atom *atom = properties.data(), *atomEnd = properties.data() + nProperties; for (; atom != atomEnd; atom++) { +#if HAVE_XORGLIBINPUT if (*atom == m_libinputIdentifierAtom.atom()) { setMode(TouchpadInputBackendMode::XLibinput); return new LibinputTouchpad(m_display.data(), info->id); - } else if (*atom == m_synapticsIdentifierAtom.atom()) { + } +#endif + if (*atom == m_synapticsIdentifierAtom.atom()) { setMode(TouchpadInputBackendMode::XSynaptics); return new SynapticsTouchpad(m_display.data(), info->id); } } } return nullptr; } bool XlibBackend::applyConfig(const QVariantHash &p) { if (!m_device) { return false; } bool success = m_device->applyConfig(p); if (!success) { m_errorString = i18n("Cannot apply touchpad configuration"); } return success; } bool XlibBackend::applyConfig() { if (!m_device) { return false; } bool success = m_device->applyConfig(); if (!success) { m_errorString = i18n("Cannot apply touchpad configuration"); } return success; } bool XlibBackend::getConfig(QVariantHash &p) { if (!m_device) { return false; } bool success = m_device->getConfig(p); if (!success) { m_errorString = i18n("Cannot read touchpad configuration"); } return success; } bool XlibBackend::getConfig() { if(!m_device) { return false; } bool success = m_device->getConfig(); if (!success) { m_errorString = i18n("Cannot read touchpad configuration"); } return success; } bool XlibBackend::getDefaultConfig() { if (!m_device) { return false; } bool success = m_device->getDefaultConfig(); if (!success) { m_errorString = i18n("Cannot read default touchpad configuration"); } return success; } bool XlibBackend::isChangedConfig() const { if (!m_device) { return false; } return m_device->isChangedConfig(); } void XlibBackend::setTouchpadEnabled(bool enable) { if (!m_device) { return; } m_device->setEnabled(enable); // FIXME? This should not be needed, m_notifications should trigger // a propertyChanged signal when we enable/disable the touchpad, // that will emit touchpadStateChanged, but for some reason // XlibNotifications is not getting the property change events // so we just emit touchpadStateChanged from here as a workaround Q_EMIT touchpadStateChanged(); } void XlibBackend::setTouchpadOff(TouchpadBackend::TouchpadOffState state) { if (!m_device) { return; } int touchpadOff = 0; switch (state) { case TouchpadEnabled: touchpadOff = 0; break; case TouchpadFullyDisabled: touchpadOff = 1; break; case TouchpadTapAndScrollDisabled: touchpadOff = 2; break; default: qCritical() << "Unknown TouchpadOffState" << state; return; } m_device->setTouchpadOff(touchpadOff); } bool XlibBackend::isTouchpadAvailable() { return m_device; } bool XlibBackend::isTouchpadEnabled() { if (!m_device) { return false; } return m_device->enabled(); } TouchpadBackend::TouchpadOffState XlibBackend::getTouchpadOff() { if (!m_device) { return TouchpadFullyDisabled; } int value = m_device->touchpadOff(); switch (value) { case 0: return TouchpadEnabled; case 1: return TouchpadFullyDisabled; case 2: return TouchpadTapAndScrollDisabled; default: qCritical() << "Unknown TouchpadOff value" << value; return TouchpadFullyDisabled; } } void XlibBackend::touchpadDetached() { qWarning() << "Touchpad detached"; m_device.reset(); Q_EMIT touchpadReset(); } void XlibBackend::devicePlugged(int device) { if (!m_device) { m_device.reset(findTouchpad()); if (m_device) { qWarning() << "Touchpad reset"; m_notifications.reset(); watchForEvents(m_keyboard); Q_EMIT touchpadReset(); } } if (!m_device || device != m_device->deviceId()) { Q_EMIT mousesChanged(); } } void XlibBackend::propertyChanged(xcb_atom_t prop) { if ((m_device && prop == m_device->touchpadOffAtom().atom()) || prop == m_enabledAtom.atom()) { Q_EMIT touchpadStateChanged(); } } QStringList XlibBackend::listMouses(const QStringList &blacklist) { int nDevices = 0; QScopedPointer info(XListInputDevices(m_display.data(), &nDevices)); QStringList list; for (XDeviceInfo *i = info.data(); i != info.data() + nDevices; i++) { if (m_device && i->id == static_cast(m_device->deviceId())) { continue; } if (i->use != IsXExtensionPointer && i->use != IsXPointer) { continue; } //type = KEYBOARD && use = Pointer means usb receiver for both keyboard //and mouse if (i->type != m_mouseAtom.atom() && i->type != m_keyboardAtom.atom()) { continue; } QString name(i->name); if (blacklist.contains(name, Qt::CaseInsensitive)) { continue; } PropertyInfo enabled(m_display.data(), i->id, m_enabledAtom.atom(), 0); if (enabled.value(0) == false) { continue; } list.append(name); } return list; } QVector XlibBackend::getDevices() const { QVector touchpads; +#if HAVE_XORGLIBINPUT LibinputTouchpad* libinputtouchpad = dynamic_cast (m_device.data()); - SynapticsTouchpad* synaptics = dynamic_cast (m_device.data()); - if ( libinputtouchpad) { touchpads.push_back(libinputtouchpad); } +#endif + + SynapticsTouchpad* synaptics = dynamic_cast (m_device.data()); if (synaptics) { touchpads.push_back(synaptics); } return touchpads; } void XlibBackend::watchForEvents(bool keyboard) { if (!m_notifications) { m_notifications.reset(new XlibNotifications(m_display.data(), m_device ? m_device->deviceId() : XIAllDevices)); connect(m_notifications.data(), SIGNAL(devicePlugged(int)), SLOT(devicePlugged(int))); connect(m_notifications.data(), SIGNAL(touchpadDetached()), SLOT(touchpadDetached())); connect(m_notifications.data(), SIGNAL(propertyChanged(xcb_atom_t)), SLOT(propertyChanged(xcb_atom_t))); } if (keyboard == !m_keyboard.isNull()) { return; } if (!keyboard) { m_keyboard.reset(); return; } m_keyboard.reset(new XRecordKeyboardMonitor(m_display.data())); connect(m_keyboard.data(), SIGNAL(keyboardActivityStarted()), SIGNAL(keyboardActivityStarted())); connect(m_keyboard.data(), SIGNAL(keyboardActivityFinished()), SIGNAL(keyboardActivityFinished())); }