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.
This commit is contained in:
Arjen Hiemstra 2022-03-11 14:04:03 +01:00
parent 5f4a71904d
commit cb47df4fc4

View file

@ -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<LibInput::Device*>(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);
}