KWin
Loading...
Searching...
No Matches
device.cpp
Go to the documentation of this file.
1/*
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5 SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
6
7 SPDX-License-Identifier: GPL-2.0-or-later
8*/
9#include "device.h"
10
11#include <config-kwin.h>
12
13#include "core/output.h"
14#include "core/outputbackend.h"
15#include "libinput_logging.h"
16#include "main.h"
17#include "mousebuttons.h"
18#include "pointer_input.h"
19
20#include <QDBusArgument>
21#include <QDBusConnection>
22#include <QDBusMetaType>
23
24#include <linux/input.h>
25
26QDBusArgument &operator<<(QDBusArgument &argument, const QMatrix4x4 &matrix)
27{
28 argument.beginArray(qMetaTypeId<double>());
29 for (quint8 row = 0; row < 4; ++row) {
30 for (quint8 col = 0; col < 4; ++col) {
31 argument << matrix(row, col);
32 }
33 }
34 argument.endArray();
35 return argument;
36}
37
38const QDBusArgument &operator>>(const QDBusArgument &argument, QMatrix4x4 &matrix)
39{
40 argument.beginArray();
41 for (quint8 row = 0; row < 4; ++row) {
42 for (quint8 col = 0; col < 4; ++col) {
43 double val;
44 argument >> val;
45 matrix(row, col) = val;
46 }
47 }
48 argument.endArray();
49 return argument;
50}
51
52namespace KWin
53{
54namespace LibInput
55{
56
57static bool checkAlphaNumericKeyboard(libinput_device *device)
58{
59 for (uint i = KEY_1; i <= KEY_0; i++) {
60 if (libinput_device_keyboard_has_key(device, i) == 0) {
61 return false;
62 }
63 }
64 for (uint i = KEY_Q; i <= KEY_P; i++) {
65 if (libinput_device_keyboard_has_key(device, i) == 0) {
66 return false;
67 }
68 }
69 for (uint i = KEY_A; i <= KEY_L; i++) {
70 if (libinput_device_keyboard_has_key(device, i) == 0) {
71 return false;
72 }
73 }
74 for (uint i = KEY_Z; i <= KEY_M; i++) {
75 if (libinput_device_keyboard_has_key(device, i) == 0) {
76 return false;
77 }
78 }
79 return true;
80}
81
104
106{
107 ConfigDataBase(const QByteArray &_key)
108 : key(_key)
109 {
110 }
111 virtual ~ConfigDataBase() = default;
112
113 QByteArray key;
114 virtual void read(Device * /*device*/, const KConfigGroup & /*values*/) const = 0;
115};
116
117template<typename T>
119{
120 using SetterFunction = std::function<void(Device *, const T &)>;
121 using DefaultValueFunction = std::function<T(Device *)>;
122
123 explicit ConfigData(const QByteArray &_key, const SetterFunction &_setter, const DefaultValueFunction &_defaultValue)
124 : ConfigDataBase(_key)
125 , setterFunction(_setter)
126 , defaultValueFunction(_defaultValue)
127 {
128 }
129
130 void read(Device *device, const KConfigGroup &values) const override
131 {
133 return;
134 }
135
136 setterFunction(device, values.readEntry(key.constData(), defaultValueFunction(device)));
137 }
138
141};
142
143// Template specializations for some specific config types that can't be handled
144// through plain readEntry.
145//
146// This uses tagged types to avoid specialising the general type since we
147// directly call the getters/setters.
148
149using DeviceOrientation = Qt::ScreenOrientation;
150
151template<>
153{
154 explicit ConfigData()
155 : ConfigDataBase(QByteArrayLiteral("Orientation"))
156 {
157 }
158
159 void read(Device *device, const KConfigGroup &values) const override
160 {
161 int defaultValue = device->defaultOrientation();
162 device->setOrientation(static_cast<Qt::ScreenOrientation>(values.readEntry(key.constData(), defaultValue)));
163 }
164};
165
166using CalibrationMatrix = QMatrix4x4;
167
168template<>
170{
171 explicit ConfigData()
172 : ConfigDataBase(QByteArrayLiteral("CalibrationMatrix"))
173 {
174 }
175
176 void read(Device *device, const KConfigGroup &values) const override
177 {
178 if (values.hasKey(key.constData())) {
179 auto list = values.readEntry(key.constData(), QList<float>());
180 if (list.size() == 16) {
181 device->setCalibrationMatrix(QMatrix4x4{list.constData()});
182 return;
183 }
184 }
185
187 }
188};
189
190static const QMap<ConfigKey, std::shared_ptr<ConfigDataBase>> s_configData{
191 {ConfigKey::Enabled, std::make_shared<ConfigData<bool>>(QByteArrayLiteral("Enabled"), &Device::setEnabled, &Device::isEnabledByDefault)},
192 {ConfigKey::LeftHanded, std::make_shared<ConfigData<bool>>(QByteArrayLiteral("LeftHanded"), &Device::setLeftHanded, &Device::leftHandedEnabledByDefault)},
193 {ConfigKey::DisableWhileTyping, std::make_shared<ConfigData<bool>>(QByteArrayLiteral("DisableWhileTyping"), &Device::setDisableWhileTyping, &Device::disableWhileTypingEnabledByDefault)},
194 {ConfigKey::PointerAcceleration, std::make_shared<ConfigData<QString>>(QByteArrayLiteral("PointerAcceleration"), &Device::setPointerAccelerationFromString, &Device::defaultPointerAccelerationToString)},
195 {ConfigKey::PointerAccelerationProfile, std::make_shared<ConfigData<quint32>>(QByteArrayLiteral("PointerAccelerationProfile"), &Device::setPointerAccelerationProfileFromInt, &Device::defaultPointerAccelerationProfileToInt)},
196 {ConfigKey::TapToClick, std::make_shared<ConfigData<bool>>(QByteArrayLiteral("TapToClick"), &Device::setTapToClick, &Device::tapToClickEnabledByDefault)},
197 {ConfigKey::TapAndDrag, std::make_shared<ConfigData<bool>>(QByteArrayLiteral("TapAndDrag"), &Device::setTapAndDrag, &Device::tapAndDragEnabledByDefault)},
198 {ConfigKey::TapDragLock, std::make_shared<ConfigData<bool>>(QByteArrayLiteral("TapDragLock"), &Device::setTapDragLock, &Device::tapDragLockEnabledByDefault)},
199 {ConfigKey::MiddleButtonEmulation, std::make_shared<ConfigData<bool>>(QByteArrayLiteral("MiddleButtonEmulation"), &Device::setMiddleEmulation, &Device::middleEmulationEnabledByDefault)},
200 {ConfigKey::LmrTapButtonMap, std::make_shared<ConfigData<bool>>(QByteArrayLiteral("LmrTapButtonMap"), &Device::setLmrTapButtonMap, &Device::lmrTapButtonMapEnabledByDefault)},
201 {ConfigKey::NaturalScroll, std::make_shared<ConfigData<bool>>(QByteArrayLiteral("NaturalScroll"), &Device::setNaturalScroll, &Device::naturalScrollEnabledByDefault)},
202 {ConfigKey::ScrollMethod, std::make_shared<ConfigData<quint32>>(QByteArrayLiteral("ScrollMethod"), &Device::activateScrollMethodFromInt, &Device::defaultScrollMethodToInt)},
203 {ConfigKey::ScrollButton, std::make_shared<ConfigData<quint32>>(QByteArrayLiteral("ScrollButton"), &Device::setScrollButton, &Device::defaultScrollButton)},
204 {ConfigKey::ClickMethod, std::make_shared<ConfigData<quint32>>(QByteArrayLiteral("ClickMethod"), &Device::setClickMethodFromInt, &Device::defaultClickMethodToInt)},
205 {ConfigKey::ScrollFactor, std::make_shared<ConfigData<qreal>>(QByteArrayLiteral("ScrollFactor"), &Device::setScrollFactor, &Device::scrollFactorDefault)},
206 {ConfigKey::Orientation, std::make_shared<ConfigData<DeviceOrientation>>()},
207 {ConfigKey::Calibration, std::make_shared<ConfigData<CalibrationMatrix>>()},
208 {ConfigKey::OutputName, std::make_shared<ConfigData<QString>>(QByteArrayLiteral("OutputName"), &Device::setOutputName, &Device::defaultOutputName)},
209 {ConfigKey::OutputArea, std::make_shared<ConfigData<QRectF>>(QByteArrayLiteral("OutputArea"), &Device::setOutputArea, &Device::defaultOutputArea)},
210 {ConfigKey::MapToWorkspace, std::make_shared<ConfigData<bool>>(QByteArrayLiteral("MapToWorkspace"), &Device::setMapToWorkspace, &Device::defaultMapToWorkspace)},
211};
212
213namespace
214{
215QMatrix4x4 getMatrix(libinput_device *device, std::function<int(libinput_device *, float[6])> getter)
216{
217 float matrix[6];
218 if (!getter(device, matrix)) {
219 return {};
220 }
221 return QMatrix4x4{
222 matrix[0], matrix[1], matrix[2], 0.0f,
223 matrix[3], matrix[4], matrix[5], 0.0f,
224 0.0f, 0.0f, 1.0f, 0.0f,
225 0.0f, 0.0f, 0.0f, 1.0f};
226}
227
228bool setOrientedCalibrationMatrix(libinput_device *device, QMatrix4x4 matrix, Qt::ScreenOrientation orientation)
229{
230 // 90 deg cw
231 static const QMatrix4x4 portraitMatrix{
232 0.0f, -1.0f, 1.0f, 0.0f,
233 1.0f, 0.0f, 0.0f, 0.0f,
234 0.0f, 0.0f, 1.0f, 0.0f,
235 0.0f, 0.0f, 0.0f, 1.0f};
236 // 180 deg cw
237 static const QMatrix4x4 invertedLandscapeMatrix{
238 -1.0f, 0.0f, 1.0f, 0.0f,
239 0.0f, -1.0f, 1.0f, 0.0f,
240 0.0f, 0.0f, 1.0f, 0.0f,
241 0.0f, 0.0f, 0.0f, 1.0f};
242 // 270 deg cw
243 static const QMatrix4x4 invertedPortraitMatrix{
244 0.0f, 1.0f, 0.0f, 0.0f,
245 -1.0f, 0.0f, 1.0f, 0.0f,
246 0.0f, 0.0f, 1.0f, 0.0f,
247 0.0f, 0.0f, 0.0f, 1.0f};
248
249 switch (orientation) {
250 case Qt::PortraitOrientation:
251 matrix *= portraitMatrix;
252 break;
253 case Qt::InvertedLandscapeOrientation:
254 matrix *= invertedLandscapeMatrix;
255 break;
256 case Qt::InvertedPortraitOrientation:
257 matrix *= invertedPortraitMatrix;
258 break;
259 case Qt::PrimaryOrientation:
260 case Qt::LandscapeOrientation:
261 default:
262 break;
263 }
264
265 float data[6]{matrix(0, 0), matrix(0, 1), matrix(0, 2), matrix(1, 0), matrix(1, 1), matrix(1, 2)};
266 return libinput_device_config_calibration_set_matrix(device, data) == LIBINPUT_CONFIG_STATUS_SUCCESS;
267}
268}
269
270Device::Device(libinput_device *device, QObject *parent)
271 : InputDevice(parent)
272 , m_device(device)
273 , m_keyboard(libinput_device_has_capability(m_device, LIBINPUT_DEVICE_CAP_KEYBOARD))
274 , m_pointer(libinput_device_has_capability(m_device, LIBINPUT_DEVICE_CAP_POINTER))
275 , m_touch(libinput_device_has_capability(m_device, LIBINPUT_DEVICE_CAP_TOUCH))
276 , m_tabletTool(libinput_device_has_capability(m_device, LIBINPUT_DEVICE_CAP_TABLET_TOOL))
277 , m_tabletPad(libinput_device_has_capability(m_device, LIBINPUT_DEVICE_CAP_TABLET_PAD))
278 , m_supportsGesture(libinput_device_has_capability(m_device, LIBINPUT_DEVICE_CAP_GESTURE))
279 , m_switch(libinput_device_has_capability(m_device, LIBINPUT_DEVICE_CAP_SWITCH))
280 , m_lidSwitch(m_switch ? libinput_device_switch_has_switch(m_device, LIBINPUT_SWITCH_LID) : false)
281 , m_tabletSwitch(m_switch ? libinput_device_switch_has_switch(m_device, LIBINPUT_SWITCH_TABLET_MODE) : false)
282 , m_name(QString::fromLocal8Bit(libinput_device_get_name(m_device)))
283 , m_sysName(QString::fromLocal8Bit(libinput_device_get_sysname(m_device)))
284 , m_outputName(QString::fromLocal8Bit(libinput_device_get_output_name(m_device)))
285 , m_product(libinput_device_get_id_product(m_device))
286 , m_vendor(libinput_device_get_id_vendor(m_device))
287 , m_tapFingerCount(libinput_device_config_tap_get_finger_count(m_device))
288 , m_defaultTapButtonMap(libinput_device_config_tap_get_default_button_map(m_device))
289 , m_tapButtonMap(libinput_device_config_tap_get_button_map(m_device))
290 , m_tapToClickEnabledByDefault(true)
291 , m_tapToClick(libinput_device_config_tap_get_enabled(m_device))
292 , m_tapAndDragEnabledByDefault(true)
293 , m_tapAndDrag(libinput_device_config_tap_get_drag_enabled(m_device))
294 , m_tapDragLockEnabledByDefault(libinput_device_config_tap_get_default_drag_lock_enabled(m_device))
295 , m_tapDragLock(libinput_device_config_tap_get_drag_lock_enabled(m_device))
296 , m_supportsDisableWhileTyping(libinput_device_config_dwt_is_available(m_device))
297 , m_supportsPointerAcceleration(libinput_device_config_accel_is_available(m_device))
298 , m_supportsLeftHanded(libinput_device_config_left_handed_is_available(m_device))
299 , m_supportsCalibrationMatrix(libinput_device_config_calibration_has_matrix(m_device))
300 , m_supportsDisableEvents(libinput_device_config_send_events_get_modes(m_device) & LIBINPUT_CONFIG_SEND_EVENTS_DISABLED)
301 , m_supportsDisableEventsOnExternalMouse(libinput_device_config_send_events_get_modes(m_device) & LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE)
302 , m_supportsMiddleEmulation(libinput_device_config_middle_emulation_is_available(m_device))
303 , m_supportsNaturalScroll(libinput_device_config_scroll_has_natural_scroll(m_device))
304 , m_supportedScrollMethods(libinput_device_config_scroll_get_methods(m_device))
305 , m_leftHandedEnabledByDefault(libinput_device_config_left_handed_get_default(m_device))
306 , m_middleEmulationEnabledByDefault(libinput_device_config_middle_emulation_get_default_enabled(m_device) == LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED)
307 , m_naturalScrollEnabledByDefault(libinput_device_config_scroll_get_default_natural_scroll_enabled(m_device))
308 , m_defaultScrollMethod(libinput_device_config_scroll_get_default_method(m_device))
309 , m_defaultScrollButton(libinput_device_config_scroll_get_default_button(m_device))
310 , m_disableWhileTypingEnabledByDefault(libinput_device_config_dwt_get_default_enabled(m_device))
311 , m_disableWhileTyping(m_supportsDisableWhileTyping ? libinput_device_config_dwt_get_enabled(m_device) == LIBINPUT_CONFIG_DWT_ENABLED : false)
312 , m_middleEmulation(libinput_device_config_middle_emulation_get_enabled(m_device) == LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED)
313 , m_leftHanded(m_supportsLeftHanded ? libinput_device_config_left_handed_get(m_device) : false)
314 , m_naturalScroll(m_supportsNaturalScroll ? libinput_device_config_scroll_get_natural_scroll_enabled(m_device) : false)
315 , m_scrollMethod(libinput_device_config_scroll_get_method(m_device))
316 , m_scrollButton(libinput_device_config_scroll_get_button(m_device))
317 , m_defaultPointerAcceleration(libinput_device_config_accel_get_default_speed(m_device))
318 , m_pointerAcceleration(libinput_device_config_accel_get_speed(m_device))
319 , m_scrollFactor(1.0)
320 , m_supportedPointerAccelerationProfiles(libinput_device_config_accel_get_profiles(m_device))
321 , m_defaultPointerAccelerationProfile(libinput_device_config_accel_get_default_profile(m_device))
322 , m_pointerAccelerationProfile(libinput_device_config_accel_get_profile(m_device))
323 , m_enabled(m_supportsDisableEvents ? libinput_device_config_send_events_get_mode(m_device) == LIBINPUT_CONFIG_SEND_EVENTS_ENABLED : true)
324 , m_config()
325 , m_defaultCalibrationMatrix(getMatrix(m_device, &libinput_device_config_calibration_get_default_matrix))
326 , m_calibrationMatrix(getMatrix(m_device, &libinput_device_config_calibration_get_matrix))
327 , m_supportedClickMethods(libinput_device_config_click_get_methods(m_device))
328 , m_defaultClickMethod(libinput_device_config_click_get_default_method(m_device))
329 , m_clickMethod(libinput_device_config_click_get_method(m_device))
330{
331 libinput_device_ref(m_device);
332 libinput_device_set_user_data(m_device, this);
333
334 qreal width = 0;
335 qreal height = 0;
336 if (libinput_device_get_size(m_device, &width, &height) == 0) {
337 m_size = QSizeF(width, height);
338 }
339 if (m_pointer) {
340 // 0x120 is the first joystick Button
341 for (int button = BTN_LEFT; button < 0x120; ++button) {
342 if (libinput_device_pointer_has_button(m_device, button)) {
343 m_supportedButtons |= buttonToQtMouseButton(button);
344 }
345 }
346 }
347
348 if (m_keyboard) {
349 m_alphaNumericKeyboard = checkAlphaNumericKeyboard(m_device);
350 }
351
352 if (m_supportsCalibrationMatrix && m_calibrationMatrix != m_defaultCalibrationMatrix) {
353 float matrix[]{m_defaultCalibrationMatrix(0, 0),
354 m_defaultCalibrationMatrix(0, 1),
355 m_defaultCalibrationMatrix(0, 2),
356 m_defaultCalibrationMatrix(1, 0),
357 m_defaultCalibrationMatrix(1, 1),
358 m_defaultCalibrationMatrix(1, 2)};
360 m_calibrationMatrix = m_defaultCalibrationMatrix;
361 }
362
363 qDBusRegisterMetaType<QMatrix4x4>();
364
365 QDBusConnection::sessionBus().registerObject(QStringLiteral("/org/kde/KWin/InputDevice/") + m_sysName,
366 QStringLiteral("org.kde.KWin.InputDevice"),
367 this,
368 QDBusConnection::ExportAllProperties);
369}
370
372{
373 QDBusConnection::sessionBus().unregisterObject(QStringLiteral("/org/kde/KWin/InputDevice/") + m_sysName);
374 libinput_device_set_user_data(m_device, nullptr);
375 libinput_device_unref(m_device);
376}
377
379{
380 return static_cast<Device *>(libinput_device_get_user_data(native));
381}
382
383template<typename T>
384void Device::writeEntry(const ConfigKey &key, const T &value)
385{
386 if (!m_config.isValid()) {
387 return;
388 }
389 if (m_loading) {
390 return;
391 }
392 auto it = s_configData.find(key);
393 Q_ASSERT(it != s_configData.end());
394 m_config.writeEntry(it.value()->key.constData(), value);
395 m_config.sync();
396}
397
399{
400 if (!m_config.isValid() && !m_defaultConfig.isValid()) {
401 return;
402 }
403
404 m_loading = true;
405 for (auto it = s_configData.begin(), end = s_configData.end(); it != end; ++it) {
406 (*it)->read(this, m_config);
407 };
408
409 m_loading = false;
410}
411
412void Device::setPointerAcceleration(qreal acceleration)
413{
414 if (!m_supportsPointerAcceleration) {
415 return;
416 }
417 acceleration = std::clamp(acceleration, -1.0, 1.0);
418 if (libinput_device_config_accel_set_speed(m_device, acceleration) == LIBINPUT_CONFIG_STATUS_SUCCESS) {
419 if (m_pointerAcceleration != acceleration) {
420 m_pointerAcceleration = acceleration;
422 writeEntry(ConfigKey::PointerAcceleration, QString::number(acceleration, 'f', 3));
423 }
424 }
425}
426
427void Device::setScrollButton(quint32 button)
428{
429 if (!(m_supportedScrollMethods & LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN)) {
430 return;
431 }
432 if (libinput_device_config_scroll_set_button(m_device, button) == LIBINPUT_CONFIG_STATUS_SUCCESS) {
433 if (m_scrollButton != button) {
434 m_scrollButton = button;
435 writeEntry(ConfigKey::ScrollButton, m_scrollButton);
436 Q_EMIT scrollButtonChanged();
437 }
438 }
439}
440
441void Device::setPointerAccelerationProfile(bool set, enum libinput_config_accel_profile profile)
442{
443 if (!(m_supportedPointerAccelerationProfiles & profile)) {
444 return;
445 }
446 if (!set) {
447 profile = (profile == LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT) ? LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE : LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT;
448 if (!(m_supportedPointerAccelerationProfiles & profile)) {
449 return;
450 }
451 }
452
453 if (libinput_device_config_accel_set_profile(m_device, profile) == LIBINPUT_CONFIG_STATUS_SUCCESS) {
454 if (m_pointerAccelerationProfile != profile) {
455 m_pointerAccelerationProfile = profile;
457 writeEntry(ConfigKey::PointerAccelerationProfile, (quint32)profile);
458 }
459 }
460}
461
462void Device::setClickMethod(bool set, enum libinput_config_click_method method)
463{
464 if (!(m_supportedClickMethods & method)) {
465 return;
466 }
467 if (!set) {
468 method = (method == LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS) ? LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER : LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
469 if (!(m_supportedClickMethods & method)) {
470 return;
471 }
472 }
473
474 if (libinput_device_config_click_set_method(m_device, method) == LIBINPUT_CONFIG_STATUS_SUCCESS) {
475 if (m_clickMethod != method) {
476 m_clickMethod = method;
477 Q_EMIT clickMethodChanged();
478 writeEntry(ConfigKey::ClickMethod, (quint32)method);
479 }
480 }
481}
482
483void Device::setScrollMethod(bool set, enum libinput_config_scroll_method method)
484{
485 if (!(m_supportedScrollMethods & method)) {
486 return;
487 }
488
489 bool isCurrent = m_scrollMethod == method;
490 if (!set) {
491 if (isCurrent) {
492 method = LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
493 isCurrent = false;
494 } else {
495 return;
496 }
497 }
498
499 if (libinput_device_config_scroll_set_method(m_device, method) == LIBINPUT_CONFIG_STATUS_SUCCESS) {
500 if (!isCurrent) {
501 m_scrollMethod = method;
502 Q_EMIT scrollMethodChanged();
503 writeEntry(ConfigKey::ScrollMethod, (quint32)method);
504 }
505 }
506}
507
509{
510 enum libinput_config_tap_button_map map = set ? LIBINPUT_CONFIG_TAP_MAP_LMR : LIBINPUT_CONFIG_TAP_MAP_LRM;
511
512 if (m_tapFingerCount < 2) {
513 return;
514 }
515 if (!set) {
516 map = LIBINPUT_CONFIG_TAP_MAP_LRM;
517 }
518
519 if (libinput_device_config_tap_set_button_map(m_device, map) == LIBINPUT_CONFIG_STATUS_SUCCESS) {
520 if (m_tapButtonMap != map) {
521 m_tapButtonMap = map;
522 writeEntry(ConfigKey::LmrTapButtonMap, set);
523 Q_EMIT tapButtonMapChanged();
524 }
525 }
526}
527
529{
531}
532
534{
536}
537
539{
540 auto deviceGroup = libinput_device_get_device_group(m_device);
541 return libinput_device_group_get_user_data(deviceGroup);
542}
543
544#define CONFIG(method, condition, function, variable, key) \
545 void Device::method(bool set) \
546 { \
547 if (condition) { \
548 return; \
549 } \
550 if (libinput_device_config_##function(m_device, set) == LIBINPUT_CONFIG_STATUS_SUCCESS) { \
551 if (m_##variable != set) { \
552 m_##variable = set; \
553 writeEntry(ConfigKey::key, m_##variable); \
554 Q_EMIT variable##Changed(); \
555 } \
556 } \
557 }
558
559CONFIG(setLeftHanded, !m_supportsLeftHanded, left_handed_set, leftHanded, LeftHanded)
560CONFIG(setNaturalScroll, !m_supportsNaturalScroll, scroll_set_natural_scroll_enabled, naturalScroll, NaturalScroll)
561
562#undef CONFIG
563
564#define CONFIG(method, condition, function, enum, variable, key) \
565 void Device::method(bool set) \
566 { \
567 if (condition) { \
568 return; \
569 } \
570 if (libinput_device_config_##function(m_device, set ? LIBINPUT_CONFIG_##enum##_ENABLED : LIBINPUT_CONFIG_##enum##_DISABLED) == LIBINPUT_CONFIG_STATUS_SUCCESS) { \
571 if (m_##variable != set) { \
572 m_##variable = set; \
573 writeEntry(ConfigKey::key, m_##variable); \
574 Q_EMIT variable##Changed(); \
575 } \
576 } \
577 }
578
579CONFIG(setEnabled, !m_supportsDisableEvents, send_events_set_mode, SEND_EVENTS, enabled, Enabled)
580CONFIG(setDisableWhileTyping, !m_supportsDisableWhileTyping, dwt_set_enabled, DWT, disableWhileTyping, DisableWhileTyping)
581CONFIG(setTapToClick, m_tapFingerCount == 0, tap_set_enabled, TAP, tapToClick, TapToClick)
582CONFIG(setTapAndDrag, false, tap_set_drag_enabled, DRAG, tapAndDrag, TapAndDrag)
583CONFIG(setTapDragLock, false, tap_set_drag_lock_enabled, DRAG_LOCK, tapDragLock, TapDragLock)
584CONFIG(setMiddleEmulation, m_supportsMiddleEmulation == false, middle_emulation_set_enabled, MIDDLE_EMULATION, middleEmulation, MiddleButtonEmulation)
585
586#undef CONFIG
587
588void Device::setScrollFactor(qreal factor)
589{
590 if (m_scrollFactor != factor) {
591 m_scrollFactor = factor;
592 writeEntry(ConfigKey::ScrollFactor, m_scrollFactor);
593 Q_EMIT scrollFactorChanged();
594 }
595}
596
597void Device::setCalibrationMatrix(const QMatrix4x4 &matrix)
598{
599 if (!m_supportsCalibrationMatrix || m_calibrationMatrix == matrix) {
600 return;
601 }
602
603 if (setOrientedCalibrationMatrix(m_device, matrix, m_orientation)) {
604 QList<float> list;
605 list.reserve(16);
606 for (uchar row = 0; row < 4; ++row) {
607 for (uchar col = 0; col < 4; ++col) {
608 list << matrix(row, col);
609 }
610 }
611 writeEntry(ConfigKey::Calibration, list);
612 m_calibrationMatrix = matrix;
614 }
615}
616
617void Device::setOrientation(Qt::ScreenOrientation orientation)
618{
619 if (!m_supportsCalibrationMatrix || m_orientation == orientation) {
620 return;
621 }
622
623 if (setOrientedCalibrationMatrix(m_device, m_calibrationMatrix, orientation)) {
624 writeEntry(ConfigKey::Orientation, static_cast<int>(orientation));
625 m_orientation = orientation;
626 Q_EMIT orientationChanged();
627 }
628}
629
630void Device::setOutputName(const QString &name)
631{
632#ifndef KWIN_BUILD_TESTING
633 if (name == m_outputName) {
634 return;
635 }
636
637 setOutput(nullptr);
638 auto outputs = kwinApp()->outputBackend()->outputs();
639 for (int i = 0; i < outputs.count(); ++i) {
640 if (!outputs[i]->isEnabled()) {
641 continue;
642 }
643 if (outputs[i]->name() == name) {
644 setOutput(outputs[i]);
645 break;
646 }
647 }
648
649 m_outputName = name;
650 writeEntry(ConfigKey::OutputName, name);
651 Q_EMIT outputNameChanged();
652#endif
653}
654
656{
657 return m_output;
658}
659
661{
662 m_output = output;
663}
664
665static libinput_led toLibinputLEDS(LEDs leds)
666{
667 quint32 libinputLeds = 0;
668 if (leds.testFlag(LED::NumLock)) {
669 libinputLeds = libinputLeds | LIBINPUT_LED_NUM_LOCK;
670 }
671 if (leds.testFlag(LED::CapsLock)) {
672 libinputLeds = libinputLeds | LIBINPUT_LED_CAPS_LOCK;
673 }
674 if (leds.testFlag(LED::ScrollLock)) {
675 libinputLeds = libinputLeds | LIBINPUT_LED_SCROLL_LOCK;
676 }
677 return libinput_led(libinputLeds);
678}
679
680LEDs Device::leds() const
681{
682 return m_leds;
683}
684
685void Device::setLeds(LEDs leds)
686{
687 if (m_leds != leds) {
688 m_leds = leds;
689 libinput_device_led_update(m_device, toLibinputLEDS(m_leds));
690 }
691}
692
694{
695 return m_tabletTool;
696}
697
699{
700 return QRectF(0, 0, 1, 1);
701}
702
703QRectF Device::outputArea() const
704{
705 return m_outputArea;
706}
707
708void Device::setOutputArea(const QRectF &outputArea)
709{
710 if (m_outputArea != outputArea) {
711 m_outputArea = outputArea;
712 writeEntry(ConfigKey::OutputArea, m_outputArea);
713 Q_EMIT outputAreaChanged();
714 }
715}
716
717void Device::setMapToWorkspace(bool mapToWorkspace)
718{
719 if (m_mapToWorkspace != mapToWorkspace) {
720 m_mapToWorkspace = mapToWorkspace;
721 writeEntry(ConfigKey::MapToWorkspace, m_mapToWorkspace);
722 Q_EMIT mapToWorkspaceChanged();
723 }
724}
725}
726}
727
728#include "moc_device.cpp"
void setPointerAcceleration(qreal acceleration)
Definition device.cpp:412
bool tapAndDragEnabledByDefault
Definition device.h:97
quint32 defaultScrollMethodToInt() const
Definition device.h:318
void setScrollMethod(bool set, enum libinput_config_scroll_method method)
Definition device.cpp:483
quint32 defaultClickMethodToInt() const
Definition device.h:556
void setNaturalScroll(bool set)
quint32 defaultScrollButton
Definition device.h:121
bool tapDragLockEnabledByDefault
Definition device.h:99
void setLeds(LEDs leds) override
Definition device.cpp:685
void setCalibrationMatrix(const QMatrix4x4 &matrix)
Definition device.cpp:597
bool leftHandedEnabledByDefault
Definition device.h:66
QString defaultOutputName() const
Definition device.h:595
void setOutputArea(const QRectF &outputArea)
Definition device.cpp:708
void setLmrTapButtonMap(bool set)
Definition device.cpp:508
void setScrollButton(quint32 button)
Definition device.cpp:427
void setTapAndDrag(bool set)
void setTapDragLock(bool set)
void setDisableWhileTyping(bool set)
bool tapToClickEnabledByDefault
Definition device.h:90
void setScrollFactor(qreal factor)
Definition device.cpp:588
void * groupUserData() const
Definition device.cpp:538
bool disableWhileTypingEnabledByDefault
Definition device.h:72
Qt::ScreenOrientation orientation
Definition device.h:62
void setPointerAccelerationProfile(bool set, enum libinput_config_accel_profile profile)
Definition device.cpp:441
quint32 defaultPointerAccelerationProfileToInt() const
Definition device.h:511
int stripsCount() const
Definition device.cpp:528
void setClickMethod(bool set, enum libinput_config_click_method method)
Definition device.cpp:462
LEDs leds() const override
Definition device.cpp:680
void setOutputName(const QString &uuid) override
Definition device.cpp:630
void setMiddleEmulation(bool set)
void activateScrollMethodFromInt(quint32 method)
Definition device.h:389
bool isEnabledByDefault() const
Definition device.h:567
QString defaultPointerAccelerationToString() const
Definition device.h:470
int ringsCount() const
Definition device.cpp:533
static Device * get(libinput_device *native)
Definition device.cpp:378
void setOrientation(Qt::ScreenOrientation orientation)
Definition device.cpp:617
Output * output() const
Definition device.cpp:655
void setTapToClick(bool set)
void setOutput(Output *output)
Definition device.cpp:660
void setMapToWorkspace(bool mapToWorkspace)
Definition device.cpp:717
void setLeftHanded(bool set)
qreal scrollFactorDefault() const
Definition device.h:399
bool naturalScrollEnabledByDefault
Definition device.h:108
void setClickMethodFromInt(quint32 method)
Definition device.h:548
void setPointerAccelerationFromString(const QString &acceleration)
Definition device.h:466
Qt::ScreenOrientation defaultOrientation() const
Definition device.h:439
QMatrix4x4 defaultCalibrationMatrix
Definition device.h:60
Device(libinput_device *device, QObject *parent=nullptr)
Definition device.cpp:270
bool middleEmulationEnabledByDefault
Definition device.h:103
void pointerAccelerationProfileChanged()
bool lmrTapButtonMapEnabledByDefault
Definition device.h:94
void setPointerAccelerationProfileFromInt(quint32 profile)
Definition device.h:507
bool isEnabled() const override
Definition device.h:561
void setEnabled(bool enabled) override
QDBusArgument & operator<<(QDBusArgument &argument, const QMatrix4x4 &matrix)
Definition device.cpp:26
#define CONFIG(method, condition, function, variable, key)
Definition device.cpp:544
const QDBusArgument & operator>>(const QDBusArgument &argument, QMatrix4x4 &matrix)
Definition device.cpp:38
enum libinput_config_drag_lock_state libinput_device_config_tap_get_drag_lock_enabled(struct libinput_device *device)
enum libinput_config_status libinput_device_config_calibration_set_matrix(struct libinput_device *device, const float matrix[6])
int libinput_device_config_dwt_is_available(struct libinput_device *device)
int libinput_device_config_tap_get_finger_count(struct libinput_device *device)
struct libinput_device * libinput_device_unref(struct libinput_device *device)
const char * libinput_device_get_sysname(struct libinput_device *device)
enum libinput_config_status libinput_device_config_accel_set_speed(struct libinput_device *device, double speed)
enum libinput_config_accel_profile libinput_device_config_accel_get_default_profile(struct libinput_device *device)
void * libinput_device_get_user_data(struct libinput_device *device)
uint32_t libinput_device_config_click_get_methods(struct libinput_device *device)
int libinput_device_config_calibration_get_default_matrix(struct libinput_device *device, float matrix[6])
enum libinput_config_middle_emulation_state libinput_device_config_middle_emulation_get_enabled(struct libinput_device *device)
enum libinput_config_status libinput_device_config_scroll_set_method(struct libinput_device *device, enum libinput_config_scroll_method method)
enum libinput_config_dwt_state libinput_device_config_dwt_get_default_enabled(struct libinput_device *device)
enum libinput_config_scroll_method libinput_device_config_scroll_get_method(struct libinput_device *device)
enum libinput_config_tap_button_map libinput_device_config_tap_get_button_map(struct libinput_device *device)
enum libinput_config_tap_button_map libinput_device_config_tap_get_default_button_map(struct libinput_device *device)
enum libinput_config_click_method libinput_device_config_click_get_default_method(struct libinput_device *device)
void * libinput_device_group_get_user_data(struct libinput_device_group *group)
enum libinput_config_middle_emulation_state libinput_device_config_middle_emulation_get_default_enabled(struct libinput_device *device)
void libinput_device_set_user_data(struct libinput_device *device, void *user_data)
int libinput_device_tablet_pad_get_num_rings(struct libinput_device *device)
enum libinput_config_click_method libinput_device_config_click_get_method(struct libinput_device *device)
double libinput_device_config_accel_get_default_speed(struct libinput_device *device)
int libinput_device_config_left_handed_is_available(struct libinput_device *device)
int libinput_device_config_accel_is_available(struct libinput_device *device)
enum libinput_config_accel_profile libinput_device_config_accel_get_profile(struct libinput_device *device)
struct libinput_device_group * libinput_device_get_device_group(struct libinput_device *device)
int libinput_device_keyboard_has_key(struct libinput_device *device, uint32_t code)
int libinput_device_config_scroll_has_natural_scroll(struct libinput_device *device)
uint32_t libinput_device_config_scroll_get_button(struct libinput_device *device)
enum libinput_config_scroll_method libinput_device_config_scroll_get_default_method(struct libinput_device *device)
enum libinput_config_tap_state libinput_device_config_tap_get_enabled(struct libinput_device *device)
int libinput_device_config_left_handed_get(struct libinput_device *device)
uint32_t libinput_device_config_send_events_get_modes(struct libinput_device *device)
int libinput_device_tablet_pad_get_num_strips(struct libinput_device *device)
int libinput_device_config_calibration_get_matrix(struct libinput_device *device, float matrix[6])
int libinput_device_has_capability(struct libinput_device *device, enum libinput_device_capability capability)
int libinput_device_config_left_handed_get_default(struct libinput_device *device)
enum libinput_config_drag_lock_state libinput_device_config_tap_get_default_drag_lock_enabled(struct libinput_device *device)
int libinput_device_config_scroll_get_default_natural_scroll_enabled(struct libinput_device *device)
double libinput_device_config_accel_get_speed(struct libinput_device *device)
int libinput_device_pointer_has_button(struct libinput_device *device, uint32_t code)
int libinput_device_config_scroll_get_natural_scroll_enabled(struct libinput_device *device)
enum libinput_config_drag_state libinput_device_config_tap_get_drag_enabled(struct libinput_device *device)
const char * libinput_device_get_output_name(struct libinput_device *device)
int libinput_device_get_size(struct libinput_device *device, double *width, double *height)
uint32_t libinput_device_config_accel_get_profiles(struct libinput_device *device)
enum libinput_config_status libinput_device_config_accel_set_profile(struct libinput_device *device, enum libinput_config_accel_profile profile)
enum libinput_config_status libinput_device_config_scroll_set_button(struct libinput_device *device, uint32_t button)
uint32_t libinput_device_config_scroll_get_methods(struct libinput_device *device)
int libinput_device_switch_has_switch(struct libinput_device *device, enum libinput_switch sw)
enum libinput_config_status libinput_device_config_tap_set_button_map(struct libinput_device *device, enum libinput_config_tap_button_map map)
uint32_t libinput_device_config_scroll_get_default_button(struct libinput_device *device)
int libinput_device_config_middle_emulation_is_available(struct libinput_device *device)
unsigned int libinput_device_get_id_vendor(struct libinput_device *device)
int libinput_device_config_calibration_has_matrix(struct libinput_device *device)
enum libinput_config_status libinput_device_config_click_set_method(struct libinput_device *device, enum libinput_config_click_method method)
unsigned int libinput_device_get_id_product(struct libinput_device *device)
uint32_t libinput_device_config_send_events_get_mode(struct libinput_device *device)
struct libinput_device * libinput_device_ref(struct libinput_device *device)
enum libinput_config_dwt_state libinput_device_config_dwt_get_enabled(struct libinput_device *device)
const char * libinput_device_get_name(struct libinput_device *device)
void libinput_device_led_update(struct libinput_device *device, enum libinput_led leds)
Qt::ScreenOrientation DeviceOrientation
Definition device.cpp:149
QMatrix4x4 CalibrationMatrix
Definition device.cpp:166
Qt::MouseButton buttonToQtMouseButton(uint32_t button)
void read(Device *device, const KConfigGroup &values) const override
Definition device.cpp:176
void read(Device *device, const KConfigGroup &values) const override
Definition device.cpp:159
ConfigDataBase(const QByteArray &_key)
Definition device.cpp:107
virtual ~ConfigDataBase()=default
virtual void read(Device *, const KConfigGroup &) const =0
std::function< T(Device *)> DefaultValueFunction
Definition device.cpp:121
std::function< void(Device *, const T &)> SetterFunction
Definition device.cpp:120
SetterFunction setterFunction
Definition device.cpp:139
DefaultValueFunction defaultValueFunction
Definition device.cpp:140
ConfigData(const QByteArray &_key, const SetterFunction &_setter, const DefaultValueFunction &_defaultValue)
Definition device.cpp:123
void read(Device *device, const KConfigGroup &values) const override
Definition device.cpp:130