diff --git a/autotests/libinput/CMakeLists.txt b/autotests/libinput/CMakeLists.txt index 65803c93fc..5a1fb6e1bb 100644 --- a/autotests/libinput/CMakeLists.txt +++ b/autotests/libinput/CMakeLists.txt @@ -1,5 +1,6 @@ include_directories(${Libinput_INCLUDE_DIRS}) +add_definitions(-DKWIN_BUILD_TESTING) add_library(LibInputTestObjects STATIC ../../src/backends/libinput/device.cpp ../../src/backends/libinput/events.cpp ../../src/inputdevice.cpp mock_libinput.cpp) target_link_libraries(LibInputTestObjects Qt::Test Qt::Widgets Qt::DBus Qt::Gui KF5::ConfigCore) target_include_directories(LibInputTestObjects PUBLIC ${CMAKE_SOURCE_DIR}/src) diff --git a/src/backends/libinput/device.cpp b/src/backends/libinput/device.cpp index 038bcfedda..40c42ea7c3 100644 --- a/src/backends/libinput/device.cpp +++ b/src/backends/libinput/device.cpp @@ -8,6 +8,9 @@ */ #include "device.h" #include "abstract_output.h" +#include "main.h" +#include "platform.h" +#include "libinput_logging.h" #include #include @@ -105,7 +108,8 @@ enum class ConfigKey { ClickMethod, ScrollFactor, Orientation, - Calibration + Calibration, + Screen }; struct ConfigData { @@ -139,7 +143,6 @@ struct ConfigData { void (Device::*setter)(bool) = nullptr; bool (Device::*defaultValue)() const; } booleanSetter; - struct { void (Device::*setter)(quint32) = nullptr; quint32 (Device::*defaultValue)() const; @@ -179,7 +182,8 @@ static const QMap s_configData { {ConfigKey::ClickMethod, ConfigData(QByteArrayLiteral("ClickMethod"), &Device::setClickMethodFromInt, &Device::defaultClickMethodToInt)}, {ConfigKey::ScrollFactor, ConfigData(QByteArrayLiteral("ScrollFactor"), &Device::setScrollFactor, &Device::scrollFactorDefault)}, {ConfigKey::Orientation, ConfigData(QByteArrayLiteral("Orientation"), &Device::setOrientation, &Device::defaultOrientation)}, - {ConfigKey::Calibration, ConfigData(QByteArrayLiteral("CalibrationMatrix"), &Device::setCalibrationMatrix, &Device::defaultCalibrationMatrix)} + {ConfigKey::Calibration, ConfigData(QByteArrayLiteral("CalibrationMatrix"), &Device::setCalibrationMatrix, &Device::defaultCalibrationMatrix)}, + {ConfigKey::Screen, ConfigData(QByteArrayLiteral("Screen"), &Device::setScreenSlug, &Device::defaultScreenSlug)} }; namespace { @@ -615,6 +619,25 @@ void Device::setScrollFactor(qreal factor) } } +void Device::setCalibrationMatrix(QMatrix4x4 matrix) { + if (!m_supportsCalibrationMatrix || m_calibrationMatrix == matrix) { + return; + } + + if(setOrientedCalibrationMatrix(m_device, matrix, m_orientation)) { + QList list; + list.reserve(16); + for (uchar row = 0; row < 4; ++row) { + for (uchar col = 0; col < 4; ++col) { + list << matrix(row,col); + } + } + writeEntry(ConfigKey::Calibration, list); + m_calibrationMatrix = matrix; + Q_EMIT calibrationMatrixChanged(); + } +} + void Device::setOrientation(Qt::ScreenOrientation orientation) { if (!m_supportsCalibrationMatrix || m_orientation == orientation) { @@ -628,24 +651,36 @@ void Device::setOrientation(Qt::ScreenOrientation orientation) } } -void Device::setCalibrationMatrix(QMatrix4x4 matrix) { - if (!m_supportsCalibrationMatrix || m_calibrationMatrix == matrix) { +void Device::setScreenSlug(QString slug) { +#ifndef KWIN_BUILD_TESTING + if(slug.isEmpty()) { return; } - if(setOrientedCalibrationMatrix(m_device, matrix, m_orientation)) { - QList list; - for (uchar row = 0; row < 4; ++row) { - for (uchar col = 0; col < 4; ++col) { - list << matrix(row,col); - } - } - writeEntry(ConfigKey::Calibration, list); - m_calibrationMatrix = matrix; - Q_EMIT calibrationMatrixChanged(); + auto parts = slug.split(';'); + if(parts.size() != 4) { + qCWarning(KWIN_LIBINPUT) << "Malformed display slug in config:" << slug << "for device:" << m_name; + return; } - Q_EMIT calibrationMatrixChanged(); + const auto outputs = kwinApp()->platform()->enabledOutputs(); + AbstractOutput *match = nullptr; + for(auto output : outputs) { + if(output->manufacturer() == parts[1] && + output->model() == parts[2]) { + match = output; + // If neither serial (preferred) or name match we may not have the right screen and have to keep iterating. + if((!parts[3].isEmpty() && output->serialNumber() == parts[3]) || output->name() == parts[0]) { + break; + } + } + } + if(match) { + setOutput(match); + } +#else + Q_UNUSED(slug) +#endif } AbstractOutput *Device::output() const @@ -656,6 +691,9 @@ AbstractOutput *Device::output() const void Device::setOutput(AbstractOutput *output) { m_output = output; + + QString slug = output->name() + ';' + output->manufacturer() + ';' + output->model() + ';' + output->serialNumber(); + writeEntry(ConfigKey::Screen, slug); } static libinput_led toLibinputLEDS(LEDs leds) @@ -688,4 +726,3 @@ void Device::setLeds(LEDs leds) } } - diff --git a/src/backends/libinput/device.h b/src/backends/libinput/device.h index 8c294dc761..bd04374670 100644 --- a/src/backends/libinput/device.h +++ b/src/backends/libinput/device.h @@ -122,7 +122,7 @@ class KWIN_EXPORT Device : public InputDevice Q_PROPERTY(quint32 scrollButton READ scrollButton WRITE setScrollButton NOTIFY scrollButtonChanged) Q_PROPERTY(qreal scrollFactor READ scrollFactor WRITE setScrollFactor NOTIFY scrollFactorChanged) - + // // switches Q_PROPERTY(bool switchDevice READ isSwitch CONSTANT) Q_PROPERTY(bool lidSwitch READ isLidSwitch CONSTANT) @@ -461,6 +461,12 @@ public: m_config = config; } + /** + * Used to deserialize monitor data from KConfig when initializing a device + */ + void setScreenSlug(QString slug); + QString defaultScreenSlug() const { return {}; } + /** * Loads the configuration and applies it to the Device */ @@ -504,6 +510,7 @@ Q_SIGNALS: void tapButtonMapChanged(); void calibrationMatrixChanged(); void orientationChanged(); + void screenChanged(); void leftHandedChanged(); void disableWhileTypingChanged(); void pointerAccelerationChanged();