1 /*
2 Copyright (C) 2016-2018 Chih-Hsuan Yen <yan12125@gmail.com>
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #include "touchpadconfig.h"
20 #include "touchpaddevice.h"
21
22 #include <cmath>
23 #include <QUrl>
24 #include <LXQt/AutostartEntry>
25 #include <LXQt/Settings>
26
TouchpadConfig(LXQt::Settings * _settings,QWidget * parent)27 TouchpadConfig::TouchpadConfig(LXQt::Settings* _settings, QWidget* parent):
28 QWidget(parent),
29 settings(_settings)
30 {
31 ui.setupUi(this);
32
33 devices = TouchpadDevice::enumerate_from_udev();
34 for (const TouchpadDevice& device : qAsConst(devices))
35 {
36 ui.devicesComboBox->addItem(device.name());
37 }
38
39 initControls();
40
41 connect(ui.devicesComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
42 this, [this] (int/* index*/) { initControls(); }); // update GUI on device change
43 connect(ui.tappingEnabledCheckBox, &QAbstractButton::clicked, this, &TouchpadConfig::settingsChanged);
44 connect(ui.naturalScrollingEnabledCheckBox, &QAbstractButton::clicked, this, &TouchpadConfig::settingsChanged);
45 connect(ui.tapToDragEnabledCheckBox, &QAbstractButton::clicked, this, &TouchpadConfig::settingsChanged);
46 connect(ui.accelSpeedDoubleSpinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &TouchpadConfig::settingsChanged);
47 connect(ui.noScrollingRadioButton, &QAbstractButton::clicked, this, &TouchpadConfig::settingsChanged);
48 connect(ui.twoFingerScrollingRadioButton, &QAbstractButton::clicked, this, &TouchpadConfig::settingsChanged);
49 connect(ui.edgeScrollingRadioButton, &QAbstractButton::clicked, this, &TouchpadConfig::settingsChanged);
50 connect(ui.buttonScrollingRadioButton, &QAbstractButton::clicked, this, &TouchpadConfig::settingsChanged);
51 }
52
~TouchpadConfig()53 TouchpadConfig::~TouchpadConfig()
54 {
55 }
56
initFeatureControl(QCheckBox * control,int featureEnabled)57 void TouchpadConfig::initFeatureControl(QCheckBox* control, int featureEnabled)
58 {
59 if (featureEnabled >= 0)
60 {
61 control->setEnabled(true);
62 control->setCheckState(featureEnabled ? Qt::Checked : Qt::Unchecked);
63 }
64 else
65 {
66 control->setEnabled(false);
67 }
68 }
69
initControls()70 void TouchpadConfig::initControls()
71 {
72 int curDevice = ui.devicesComboBox->currentIndex();
73 if (curDevice < 0) {
74 return;
75 }
76
77 const TouchpadDevice& device = devices[curDevice];
78 initFeatureControl(ui.tappingEnabledCheckBox, device.tappingEnabled());
79 initFeatureControl(ui.naturalScrollingEnabledCheckBox, device.naturalScrollingEnabled());
80 initFeatureControl(ui.tapToDragEnabledCheckBox, device.tapToDragEnabled());
81
82 auto ok = device.xinputDriverSupported();
83 if (!ok) {
84 ui.deviceInfoLabel->setText(
85 tr(
86 "LXQt only supports \"libinput\" as xinput driver.\n"
87 "(current value: %1)\n"
88 "\n"
89 "If this is intended, please configure xinput manually.\n"
90 "Otherwise you can get rid of this message by changing xinput driver to \"libinput\".\n")
91 .arg(device.xinputDriver()));
92 ui.deviceInfoLabel->setStyleSheet(QStringLiteral("background-color: #f88; border-color: #f33; border-size: 1px"));
93 };
94 ui.deviceInfoLabel->setVisible(!ok);
95 ui.deviceInfoLabel->setFrameStyle(QFrame::Panel | QFrame::Sunken);
96
97 float accelSpeed = device.accelSpeed();
98 if (!std::isnan(accelSpeed)) {
99 ui.accelSpeedDoubleSpinBox->setEnabled(true);
100 // prevent setAccelSpeed() from being called because the device may have changed
101 ui.accelSpeedDoubleSpinBox->blockSignals(true);
102 ui.accelSpeedDoubleSpinBox->setValue(accelSpeed);
103 ui.accelSpeedDoubleSpinBox->blockSignals(false);
104 } else {
105 ui.accelSpeedDoubleSpinBox->setEnabled(false);
106 }
107
108 int scrollMethodsAvailable = device.scrollMethodsAvailable();
109 ui.twoFingerScrollingRadioButton->setEnabled(scrollMethodsAvailable & TWO_FINGER);
110 ui.edgeScrollingRadioButton->setEnabled(scrollMethodsAvailable & EDGE);
111 ui.buttonScrollingRadioButton->setEnabled(scrollMethodsAvailable & BUTTON);
112
113 ScrollingMethod scrollingMethodEnabled = device.scrollingMethodEnabled();
114 if (scrollingMethodEnabled == TWO_FINGER)
115 {
116 ui.twoFingerScrollingRadioButton->setChecked(true);
117 }
118 else if (scrollingMethodEnabled == EDGE)
119 {
120 ui.edgeScrollingRadioButton->setChecked(true);
121 }
122 else if (scrollingMethodEnabled == BUTTON)
123 {
124 ui.buttonScrollingRadioButton->setChecked(true);
125 }
126 else
127 {
128 ui.noScrollingRadioButton->setChecked(true);
129 }
130 }
131
accept()132 void TouchpadConfig::accept()
133 {
134 for (const TouchpadDevice& device : qAsConst(devices))
135 {
136 device.saveSettings(settings);
137 }
138
139 LXQt::AutostartEntry autoStart(QStringLiteral("lxqt-config-touchpad-autostart.desktop"));
140 XdgDesktopFile desktopFile(XdgDesktopFile::ApplicationType, QStringLiteral("lxqt-config-touchpad-autostart"), QStringLiteral("lxqt-config-input --load-touchpad"));
141 desktopFile.setValue(QStringLiteral("OnlyShowIn"), QStringLiteral("LXQt"));
142 desktopFile.setValue(QStringLiteral("Comment"), QStringLiteral("Autostart touchpad settings for lxqt-config-input"));
143 autoStart.setFile(desktopFile);
144 autoStart.commit();
145 }
146
reset()147 void TouchpadConfig::reset()
148 {
149 for (const TouchpadDevice& device : qAsConst(devices))
150 {
151 device.setTappingEnabled(device.oldTappingEnabled());
152 device.setNaturalScrollingEnabled(device.oldNaturalScrollingEnabled());
153 device.setTapToDragEnabled(device.oldTapToDragEnabled());
154 device.setAccelSpeed(device.oldAccelSpeed());
155 device.setScrollingMethodEnabled(device.oldScrollingMethodEnabled());
156 }
157 initControls();
158 accept();
159 }
160
applyConfig()161 void TouchpadConfig::applyConfig()
162 {
163 int curDevice = ui.devicesComboBox->currentIndex();
164 if (curDevice < 0) {
165 return;
166 }
167
168 bool acceptSetting = false;
169 TouchpadDevice& device = devices[curDevice];
170
171 bool enable = ui.tappingEnabledCheckBox->checkState() == Qt::Checked;
172 if (enable != (device.tappingEnabled() > 0))
173 {
174 device.setTappingEnabled(enable);
175 acceptSetting = true;
176 }
177
178 enable = ui.naturalScrollingEnabledCheckBox->checkState() == Qt::Checked;
179 if (enable != (device.naturalScrollingEnabled() > 0))
180 {
181 device.setNaturalScrollingEnabled(enable);
182 acceptSetting = true;
183 }
184
185 enable = ui.tapToDragEnabledCheckBox->checkState() == Qt::Checked;
186 if (enable != (device.tapToDragEnabled() > 0))
187 {
188 device.setTapToDragEnabled(enable);
189 acceptSetting = true;
190 }
191
192 float accelSpeed = static_cast<float>(ui.accelSpeedDoubleSpinBox->value());
193 if (accelSpeed != device.accelSpeed())
194 {
195 device.setAccelSpeed(accelSpeed);
196 acceptSetting = true;
197 }
198
199 // these radio buttons are auto-exclusive
200 ScrollingMethod m = NONE;
201 if (ui.noScrollingRadioButton->isChecked())
202 m = NONE;
203 else if (ui.twoFingerScrollingRadioButton->isChecked())
204 m = TWO_FINGER;
205 else if (ui.edgeScrollingRadioButton->isChecked())
206 m = EDGE;
207 else if (ui.buttonScrollingRadioButton->isChecked())
208 m = BUTTON;
209 if (m != device.scrollingMethodEnabled())
210 {
211 device.setScrollingMethodEnabled(m);
212 acceptSetting = true;
213 }
214
215 if (acceptSetting)
216 accept();
217 }
218