File indexing completed on 2024-06-16 05:09:02
0001 /* 0002 SPDX-FileCopyrightText: 2017 Roman Gilg <subdiff@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "touchpadconfig.h" 0008 0009 #include "../logging.h" 0010 #include "touchpadbackend.h" 0011 #include <config-build-options.h> 0012 0013 #include <KLocalizedContext> 0014 #include <KLocalizedString> 0015 #include <KPluginFactory> 0016 #include <KWindowSystem> 0017 0018 #include <QQmlContext> 0019 #include <QQmlEngine> 0020 #include <QQmlProperty> 0021 #include <QQuickItem> 0022 #include <QVBoxLayout> 0023 0024 K_PLUGIN_CLASS_WITH_JSON(TouchpadConfig, "kcm_touchpad.json") 0025 0026 extern "C" { 0027 Q_DECL_EXPORT void kcminit() 0028 { 0029 #if BUILD_KCM_TOUCHPAD_X11 0030 if (KWindowSystem::isPlatformX11()) { 0031 TouchpadConfig::kcmInit(); 0032 } 0033 #endif 0034 } 0035 } 0036 0037 TouchpadConfig::TouchpadConfig(QObject *parent, const KPluginMetaData &data) 0038 : KCModule(parent, data) 0039 { 0040 m_backend = TouchpadBackend::implementation(); 0041 0042 m_initError = !m_backend->errorString().isNull(); 0043 0044 m_view = new QQuickWidget(widget()); 0045 0046 QVBoxLayout *layout = new QVBoxLayout(widget()); 0047 0048 layout->addWidget(m_view); 0049 widget()->setLayout(layout); 0050 0051 m_view->setResizeMode(QQuickWidget::SizeRootObjectToView); 0052 m_view->setClearColor(Qt::transparent); 0053 m_view->setAttribute(Qt::WA_AlwaysStackOnTop); 0054 0055 m_view->rootContext()->setContextProperty("backend", m_backend); 0056 m_view->rootContext()->setContextProperty("deviceModel", QVariant::fromValue(m_backend->getDevices().toList())); 0057 0058 QObject::connect(m_view, &QQuickWidget::statusChanged, [&](QQuickWidget::Status status) { 0059 if (status == QQuickWidget::Ready) { 0060 connect(m_view->rootObject(), SIGNAL(changeSignal()), this, SLOT(onChange())); 0061 } 0062 }); 0063 0064 qmlRegisterSingletonInstance("org.kde.touchpad.kcm", 1, 0, "TouchpadConfig", this); 0065 0066 m_view->engine()->rootContext()->setContextObject(new KLocalizedContext(m_view->engine())); 0067 m_view->setSource(QUrl("qrc:/libinput/touchpad.qml")); 0068 m_view->resize(QSize(500, 600)); 0069 0070 if (m_initError) { 0071 Q_EMIT showMessage(m_backend->errorString()); 0072 } else { 0073 connect(m_backend, &TouchpadBackend::touchpadAdded, this, &TouchpadConfig::onTouchpadAdded); 0074 connect(m_backend, &TouchpadBackend::touchpadRemoved, this, &TouchpadConfig::onTouchpadRemoved); 0075 } 0076 0077 setButtons(KCModule::Default | KCModule::Apply); 0078 } 0079 0080 void TouchpadConfig::kcmInit() 0081 { 0082 #if BUILD_KCM_TOUCHPAD_X11 0083 TouchpadBackend *backend = TouchpadBackend::implementation(); 0084 if (backend->getMode() == TouchpadInputBackendMode::XLibinput) { 0085 backend->getConfig(); 0086 backend->applyConfig(); 0087 } 0088 #endif 0089 } 0090 0091 void TouchpadConfig::load() 0092 { 0093 // in case of critical init error in backend, don't try 0094 if (m_initError) { 0095 return; 0096 } 0097 0098 if (!m_backend->getConfig()) { 0099 Q_EMIT showMessage(i18n("Error while loading values. See logs for more information. Please restart this configuration module.")); 0100 } else { 0101 if (!m_backend->touchpadCount()) { 0102 Q_EMIT showMessage(i18n("No touchpad found. Connect touchpad now.")); 0103 } 0104 } 0105 QMetaObject::invokeMethod(m_view->rootObject(), "syncValuesFromBackend"); 0106 } 0107 0108 void TouchpadConfig::save() 0109 { 0110 if (!m_backend->applyConfig()) { 0111 Q_EMIT showMessage(i18n("Not able to save all changes. See logs for more information. Please restart this configuration module and try again.")); 0112 } else { 0113 Q_EMIT showMessage(QString()); 0114 } 0115 0116 // load newly written values 0117 load(); 0118 // in case of error, config still in changed state 0119 setNeedsSave(m_backend->isChangedConfig()); 0120 } 0121 0122 void TouchpadConfig::defaults() 0123 { 0124 // in case of critical init error in backend, don't try 0125 if (m_initError) { 0126 return; 0127 } 0128 0129 if (!m_backend->getDefaultConfig()) { 0130 Q_EMIT showMessage(i18n("Error while loading default values. Failed to set some options to their default values.")); 0131 } 0132 QMetaObject::invokeMethod(m_view->rootObject(), "syncValuesFromBackend"); 0133 setNeedsSave(m_backend->isChangedConfig()); 0134 } 0135 0136 void TouchpadConfig::onChange() 0137 { 0138 if (!m_backend->touchpadCount()) { 0139 return; 0140 } 0141 hideErrorMessage(); 0142 setNeedsSave(m_backend->isChangedConfig()); 0143 } 0144 0145 void TouchpadConfig::onTouchpadAdded(bool success) 0146 { 0147 QQuickItem *rootObj = m_view->rootObject(); 0148 0149 if (!success) { 0150 Q_EMIT showMessage(i18n("Error while adding newly connected device. Please reconnect it and restart this configuration module.")); 0151 } 0152 0153 int activeIndex; 0154 if (m_backend->touchpadCount() == 1) { 0155 // if no touchpad was connected previously, show the new device and hide the no-device-message 0156 activeIndex = 0; 0157 hideErrorMessage(); 0158 } else { 0159 activeIndex = QQmlProperty::read(rootObj, "deviceIndex").toInt(); 0160 } 0161 m_view->rootContext()->setContextProperty("deviceModel", QVariant::fromValue(m_backend->getDevices())); 0162 QMetaObject::invokeMethod(rootObj, "resetModel", Q_ARG(QVariant, activeIndex)); 0163 QMetaObject::invokeMethod(rootObj, "syncValuesFromBackend"); 0164 } 0165 0166 void TouchpadConfig::onTouchpadRemoved(int index) 0167 { 0168 QQuickItem *rootObj = m_view->rootObject(); 0169 0170 int activeIndex = QQmlProperty::read(rootObj, "deviceIndex").toInt(); 0171 if (activeIndex == index) { 0172 if (m_backend->touchpadCount()) { 0173 Q_EMIT showMessage(i18n("Touchpad disconnected. Closed its setting dialog."), 0 /*Kirigami.MessageType.Information*/); 0174 } else { 0175 Q_EMIT showMessage(i18n("Touchpad disconnected. No other touchpads found."), 0 /*Kirigami.MessageType.Information*/); 0176 } 0177 activeIndex = 0; 0178 } else { 0179 if (index < activeIndex) { 0180 activeIndex--; 0181 } 0182 } 0183 m_view->rootContext()->setContextProperty("deviceModel", QVariant::fromValue(m_backend->getDevices())); 0184 QMetaObject::invokeMethod(m_view->rootObject(), "resetModel", Q_ARG(QVariant, activeIndex)); 0185 QMetaObject::invokeMethod(rootObj, "syncValuesFromBackend"); 0186 0187 setNeedsSave(m_backend->isChangedConfig()); 0188 } 0189 0190 void TouchpadConfig::hideErrorMessage() 0191 { 0192 Q_EMIT showMessage(QString()); 0193 } 0194 0195 #include "touchpadconfig.moc"