From cb47df4fc494202f98a8d275b357fda5ddcf1df3 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Fri, 11 Mar 2022 14:04:03 +0100 Subject: [PATCH] Add a way to ignore devices for tablet mode The tablet mode code checks whether we are currently in tablet mode based on whether or not we have a touch screen and a pointer. For some devices, a touch screen or pointer device may be detected but we would like to ignore it, since it incorrectly influences the tablet mode. This reads the udev tag "kwin_ignore_tabletmode" from libinput devices and will skip devices with that tag when trying to determine whether we are in tablet mode or not. --- src/tabletmodemanager.cpp | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/tabletmodemanager.cpp b/src/tabletmodemanager.cpp index 56639d96c6..acd8fe17e6 100644 --- a/src/tabletmodemanager.cpp +++ b/src/tabletmodemanager.cpp @@ -6,6 +6,8 @@ */ #include "tabletmodemanager.h" + +#include "backends/libinput/device.h" #include "input.h" #include "inputdevice.h" #include "input_event.h" @@ -18,6 +20,21 @@ namespace KWin KWIN_SINGLETON_FACTORY_VARIABLE(TabletModeManager, s_manager) +static bool shouldIgnoreDevice(InputDevice *device) +{ + auto libinput_device = qobject_cast(device); + if (!libinput_device) { + return false; + } + + bool ignore = false; + if (auto udev = libinput_device_get_udev_device(libinput_device->device()); udev) { + ignore = udev_device_has_tag(udev, "kwin-ignore-tablet-mode"); + udev_device_unref(udev); + } + return ignore; +} + class TabletModeSwitchEventSpy : public QObject, public InputEventSpy { public: @@ -73,10 +90,14 @@ public: void check() { const auto devices = input()->devices(); - const bool hasTouch = std::any_of(devices.constBegin(), devices.constEnd(), [](InputDevice *device) { return device->isTouch(); }); + const bool hasTouch = std::any_of(devices.constBegin(), devices.constEnd(), [](InputDevice *device) { + return device->isTouch() && !shouldIgnoreDevice(device); + }); m_parent->setTabletModeAvailable(hasTouch); - const bool hasPointer = std::any_of(devices.constBegin(), devices.constEnd(), [](InputDevice *device) { return device->isPointer(); }); + const bool hasPointer = std::any_of(devices.constBegin(), devices.constEnd(), [](InputDevice *device) { + return device->isPointer() && !shouldIgnoreDevice(device); + }); m_parent->setIsTablet(hasTouch && !hasPointer); }