1 /*
2 SPDX-FileCopyrightText: 1997 Patrick Dowler <dowler@morgul.fsh.uvic.ca>
3 SPDX-FileCopyrightText: 1999 Dirk A. Mueller <dmuell@gmx.net>
4 SPDX-FileCopyrightText: 1999 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
5 SPDX-FileCopyrightText: 2000 David Faure <faure@kde.org>
6 SPDX-FileCopyrightText: 2000 Bernd Gehrmann
7 SPDX-FileCopyrightText: 2000 Rik Hemsley <rik@kde.org>
8 SPDX-FileCopyrightText: 2000 Brad Hughes <bhughes@trolltech.com>
9 SPDX-FileCopyrightText: 2004 Brad Hards <bradh@frogmouth.net>
10 SPDX-FileCopyrightText: 2018 Roman Gilg <subdiff@gmail.com>
11
12 SPDX-License-Identifier: GPL-2.0-or-later
13 */
14 #include "xlib_config.h"
15
16 #include "../configcontainer.h"
17 #include "backends/x11/x11_evdev_backend.h"
18
19 #include "../../../migrationlib/kdelibs4config.h"
20
21 #include <KLocalizedString>
22 #include <KToolInvocation>
23 //#include <KConfig>
24 #include <KAboutData>
25 #include <KPluginFactory>
26
27 #include <QCheckBox>
28 #include <QDoubleSpinBox>
29 #include <QFormLayout>
30 #include <QSpinBox>
31 #include <QStandardPaths>
32 #include <QTabWidget>
33 #include <QWhatsThis>
34
35 #include <KConfig>
36 #include <KConfigGroup>
37
XlibConfig(ConfigContainer * parent,InputBackend * backend)38 XlibConfig::XlibConfig(ConfigContainer *parent, InputBackend *backend)
39 : ConfigPlugin(parent)
40 , m_backend(dynamic_cast<X11EvdevBackend *>(backend))
41 {
42 setupUi(this);
43
44 handedGroup->setId(rightHanded, static_cast<int>(Handed::Right));
45 handedGroup->setId(leftHanded, static_cast<int>(Handed::Left));
46
47 connect(handedGroup, SIGNAL(buttonClicked(int)), m_parent, SLOT(changed()));
48 connect(handedGroup, SIGNAL(buttonClicked(int)), this, SLOT(slotHandedChanged(int)));
49
50 connect(cbScrollPolarity, SIGNAL(clicked()), m_parent, SLOT(changed()));
51 connect(cbScrollPolarity, SIGNAL(clicked()), this, SLOT(slotScrollPolarityChanged()));
52
53 connect(accel, SIGNAL(valueChanged(double)), m_parent, SLOT(changed()));
54 connect(thresh, SIGNAL(valueChanged(int)), m_parent, SLOT(changed()));
55 connect(thresh, SIGNAL(valueChanged(int)), this, SLOT(slotThreshChanged(int)));
56 slotThreshChanged(thresh->value());
57
58 // It would be nice if the user had a test field.
59 // Selecting such values in milliseconds is not intuitive
60 connect(doubleClickInterval, SIGNAL(valueChanged(int)), m_parent, SLOT(changed()));
61
62 connect(dragStartTime, SIGNAL(valueChanged(int)), m_parent, SLOT(changed()));
63
64 connect(dragStartDist, SIGNAL(valueChanged(int)), m_parent, SLOT(changed()));
65 connect(dragStartDist, SIGNAL(valueChanged(int)), this, SLOT(slotDragStartDistChanged(int)));
66 slotDragStartDistChanged(dragStartDist->value());
67
68 connect(wheelScrollLines, SIGNAL(valueChanged(int)), m_parent, SLOT(changed()));
69 connect(wheelScrollLines, SIGNAL(valueChanged(int)), SLOT(slotWheelScrollLinesChanged(int)));
70 slotWheelScrollLinesChanged(wheelScrollLines->value());
71
72 connect(mouseKeys, SIGNAL(clicked()), this, SLOT(checkAccess()));
73 connect(mouseKeys, SIGNAL(clicked()), m_parent, SLOT(changed()));
74 connect(mk_delay, SIGNAL(valueChanged(int)), m_parent, SLOT(changed()));
75 connect(mk_interval, SIGNAL(valueChanged(int)), m_parent, SLOT(changed()));
76 connect(mk_time_to_max, SIGNAL(valueChanged(int)), m_parent, SLOT(changed()));
77 connect(mk_max_speed, SIGNAL(valueChanged(int)), m_parent, SLOT(changed()));
78 connect(mk_curve, SIGNAL(valueChanged(int)), m_parent, SLOT(changed()));
79
80 KAboutData *about = new KAboutData(QStringLiteral("kcmmouse"),
81 i18n("Mouse"),
82 QStringLiteral("1.0"),
83 QString(),
84 KAboutLicense::GPL,
85 i18n("(c) 1997 - 2018 Mouse developers"));
86 about->addAuthor(i18n("Patrick Dowler"));
87 about->addAuthor(i18n("Dirk A. Mueller"));
88 about->addAuthor(i18n("David Faure"));
89 about->addAuthor(i18n("Bernd Gehrmann"));
90 about->addAuthor(i18n("Rik Hemsley"));
91 about->addAuthor(i18n("Brad Hughes"));
92 about->addAuthor(i18n("Brad Hards"));
93 about->addAuthor(i18n("Roman Gilg"));
94 m_parent->setAboutData(about);
95 }
96
checkAccess()97 void XlibConfig::checkAccess()
98 {
99 mk_delay->setEnabled(mouseKeys->isChecked());
100 mk_interval->setEnabled(mouseKeys->isChecked());
101 mk_time_to_max->setEnabled(mouseKeys->isChecked());
102 mk_max_speed->setEnabled(mouseKeys->isChecked());
103 mk_curve->setEnabled(mouseKeys->isChecked());
104 }
105
getAccel()106 double XlibConfig::getAccel()
107 {
108 return accel->value();
109 }
110
setAccel(double val)111 void XlibConfig::setAccel(double val)
112 {
113 accel->setValue(val);
114 }
115
getThreshold()116 int XlibConfig::getThreshold()
117 {
118 return thresh->value();
119 }
120
setThreshold(int val)121 void XlibConfig::setThreshold(int val)
122 {
123 thresh->setValue(val);
124 }
125
getHandedness()126 Handed XlibConfig::getHandedness()
127 {
128 if (rightHanded->isChecked())
129 return Handed::Right;
130 else
131 return Handed::Left;
132 }
133
setHandedness(Handed val)134 void XlibConfig::setHandedness(Handed val)
135 {
136 rightHanded->setChecked(false);
137 leftHanded->setChecked(false);
138 if (val == Handed::Right) {
139 rightHanded->setChecked(true);
140 mousePix->setPixmap(QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kcmmouse/pics/mouse_rh.png"));
141 } else {
142 leftHanded->setChecked(true);
143 mousePix->setPixmap(QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kcmmouse/pics/mouse_lh.png"));
144 }
145 m_backend->settings()->handedNeedsApply = true;
146 }
147
load()148 void XlibConfig::load()
149 {
150 EvdevSettings *settings = m_backend->settings();
151
152 m_parent->kcmLoad();
153 m_backend->load();
154
155 // Only allow setting reversing scroll polarity if we have scroll buttons
156 if (m_backend) {
157 if (m_backend->supportScrollPolarity()) {
158 cbScrollPolarity->setEnabled(true);
159 cbScrollPolarity->show();
160 } else {
161 cbScrollPolarity->setEnabled(false);
162 cbScrollPolarity->hide();
163 }
164 }
165
166 rightHanded->setEnabled(settings->handedEnabled);
167 leftHanded->setEnabled(settings->handedEnabled);
168 if (cbScrollPolarity->isEnabled())
169 cbScrollPolarity->setEnabled(settings->handedEnabled);
170 cbScrollPolarity->setChecked(settings->reverseScrollPolarity);
171
172 setAccel(settings->accelRate);
173 setThreshold(settings->thresholdMove);
174 setHandedness(settings->handed);
175
176 doubleClickInterval->setValue(settings->doubleClickInterval);
177 dragStartTime->setValue(settings->dragStartTime);
178 dragStartDist->setValue(settings->dragStartDist);
179 wheelScrollLines->setValue(settings->wheelScrollLines);
180
181 KConfig ac("kaccessrc");
182
183 KConfigGroup group = ac.group("Mouse");
184 mouseKeys->setChecked(group.readEntry("MouseKeys", false));
185 mk_delay->setValue(group.readEntry("MKDelay", 160));
186
187 int interval = group.readEntry("MKInterval", 5);
188 mk_interval->setValue(interval);
189
190 // Default time to reach maximum speed: 5000 msec
191 int time_to_max = group.readEntry("MKTimeToMax", (5000 + interval / 2) / interval);
192 time_to_max = group.readEntry("MK-TimeToMax", time_to_max * interval);
193 mk_time_to_max->setValue(time_to_max);
194
195 // Default maximum speed: 1000 pixels/sec
196 // (The old default maximum speed from KDE <= 3.4
197 // (100000 pixels/sec) was way too fast)
198 long max_speed = group.readEntry("MKMaxSpeed", interval);
199 max_speed = max_speed * 1000 / interval;
200 if (max_speed > 2000)
201 max_speed = 2000;
202 max_speed = group.readEntry("MK-MaxSpeed", int(max_speed));
203 mk_max_speed->setValue(max_speed);
204
205 mk_curve->setValue(group.readEntry("MKCurve", 0));
206
207 checkAccess();
208 Q_EMIT m_parent->changed(false);
209 }
210
save()211 void XlibConfig::save()
212 {
213 EvdevSettings *settings = m_backend->settings();
214
215 settings->accelRate = getAccel();
216 settings->thresholdMove = getThreshold();
217 settings->handed = getHandedness();
218
219 settings->doubleClickInterval = doubleClickInterval->value();
220 settings->dragStartTime = dragStartTime->value();
221 settings->dragStartDist = dragStartDist->value();
222 settings->wheelScrollLines = wheelScrollLines->value();
223 settings->reverseScrollPolarity = cbScrollPolarity->isChecked();
224
225 m_backend->apply();
226 settings->save();
227
228 KConfig ac("kaccessrc");
229
230 KConfigGroup group = ac.group("Mouse");
231
232 int interval = mk_interval->value();
233 group.writeEntry("MouseKeys", mouseKeys->isChecked());
234 group.writeEntry("MKDelay", mk_delay->value());
235 group.writeEntry("MKInterval", interval);
236 group.writeEntry("MK-TimeToMax", mk_time_to_max->value());
237 group.writeEntry("MKTimeToMax", (mk_time_to_max->value() + interval / 2) / interval);
238 group.writeEntry("MK-MaxSpeed", mk_max_speed->value());
239 group.writeEntry("MKMaxSpeed", (mk_max_speed->value() * interval + 500) / 1000);
240 group.writeEntry("MKCurve", mk_curve->value());
241 group.sync();
242
243 // restart kaccess
244 KToolInvocation::startServiceByDesktopName("kaccess");
245
246 Q_EMIT m_parent->changed(false);
247 }
248
defaults()249 void XlibConfig::defaults()
250 {
251 setThreshold(2);
252 setAccel(2);
253 setHandedness(Handed::Right);
254 cbScrollPolarity->setChecked(false);
255 doubleClickInterval->setValue(400);
256 dragStartTime->setValue(500);
257 dragStartDist->setValue(4);
258 wheelScrollLines->setValue(3);
259
260 mouseKeys->setChecked(false);
261 mk_delay->setValue(160);
262 mk_interval->setValue(5);
263 mk_time_to_max->setValue(5000);
264 mk_max_speed->setValue(1000);
265 mk_curve->setValue(0);
266
267 checkAccess();
268 m_parent->kcmDefaults();
269
270 Q_EMIT m_parent->changed(true);
271 }
272
273 /** No descriptions */
slotHandedChanged(int val)274 void XlibConfig::slotHandedChanged(int val)
275 {
276 if (val == static_cast<int>(Handed::Right))
277 mousePix->setPixmap(QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kcmmouse/pics/mouse_rh.png"));
278 else
279 mousePix->setPixmap(QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kcmmouse/pics/mouse_lh.png"));
280 m_backend->settings()->handedNeedsApply = true;
281 }
282
slotThreshChanged(int value)283 void XlibConfig::slotThreshChanged(int value)
284 {
285 thresh->setSuffix(i18np(" pixel", " pixels", value));
286 }
287
slotDragStartDistChanged(int value)288 void XlibConfig::slotDragStartDistChanged(int value)
289 {
290 dragStartDist->setSuffix(i18np(" pixel", " pixels", value));
291 }
292
slotWheelScrollLinesChanged(int value)293 void XlibConfig::slotWheelScrollLinesChanged(int value)
294 {
295 wheelScrollLines->setSuffix(i18np(" line", " lines", value));
296 }
297
slotScrollPolarityChanged()298 void XlibConfig::slotScrollPolarityChanged()
299 {
300 m_backend->settings()->handedNeedsApply = true;
301 }
302