File fix-eis-crash.patch of Package kwin6
From 8859e63a00bd9bf1bcab3ae043db01a14c4c6ddc Mon Sep 17 00:00:00 2001
From: David Redondo <kde@david-redondo.de>
Date: Wed, 18 Feb 2026 12:27:45 +0100
Subject: [PATCH] plugins/eis: Guard against events of destroyed devices
libeis might send an event for removed devices, while a libeis bug we
need to guard against it as users see crashes in the wild.
BUG:515179
FIXED-IN: 6.6.1
---
src/plugins/eis/eiscontext.cpp | 28 ++++++++++------------------
1 file changed, 10 insertions(+), 18 deletions(-)
diff --git a/src/plugins/eis/eiscontext.cpp b/src/plugins/eis/eiscontext.cpp
index f9a0c8dcfe6..00da744f892 100644
--- a/src/plugins/eis/eiscontext.cpp
+++ b/src/plugins/eis/eiscontext.cpp
@@ -141,13 +141,19 @@ static std::chrono::microseconds currentTime()
void EisContext::handleEvents()
{
- auto eventDevice = [](eis_event *event) {
- return static_cast<EisDevice *>(eis_device_get_user_data(eis_event_get_device(event)));
- };
-
eis_dispatch(m_eisContext);
while (eis_event *const event = eis_get_event(m_eisContext)) {
+
+ auto eisDevice = eis_event_get_device(event);
+ auto device = eisDevice ? static_cast<EisDevice *>(eis_device_get_user_data(eisDevice)) : nullptr;
+
+ if (eisDevice && !device) {
+ qCWarning(KWIN_EIS) << "Event for destroyed device - ignoring";
+ eis_event_unref(event);
+ continue;
+ }
+
switch (eis_event_get_type(event)) {
case EIS_EVENT_CLIENT_CONNECT: {
auto client = eis_event_get_client(event);
@@ -207,7 +213,6 @@ void EisContext::handleEvents()
break;
}
case EIS_EVENT_DEVICE_CLOSED: {
- auto device = eventDevice(event);
qCDebug(KWIN_EIS) << "Device" << device->name() << "closed by client";
Q_EMIT m_backend->deviceRemoved(device);
auto seat = static_cast<EisClient *>(eis_seat_get_user_data(eis_device_get_seat(device->handle())));
@@ -221,7 +226,6 @@ void EisContext::handleEvents()
break;
}
case EIS_EVENT_FRAME: {
- auto device = eventDevice(event);
qCDebug(KWIN_EIS) << "Frame for device" << device->name();
if (device->isTouch()) {
Q_EMIT device->touchFrame(device);
@@ -232,17 +236,14 @@ void EisContext::handleEvents()
break;
}
case EIS_EVENT_DEVICE_START_EMULATING: {
- auto device = eventDevice(event);
qCDebug(KWIN_EIS) << "Device" << device->name() << "starts emulating";
break;
}
case EIS_EVENT_DEVICE_STOP_EMULATING: {
- auto device = eventDevice(event);
qCDebug(KWIN_EIS) << "Device" << device->name() << "stops emulating";
break;
}
case EIS_EVENT_POINTER_MOTION: {
- auto device = eventDevice(event);
const double x = eis_event_pointer_get_dx(event);
const double y = eis_event_pointer_get_dy(event);
qCDebug(KWIN_EIS) << device->name() << "pointer motion" << x << y;
@@ -251,7 +252,6 @@ void EisContext::handleEvents()
break;
}
case EIS_EVENT_POINTER_MOTION_ABSOLUTE: {
- auto device = eventDevice(event);
const double x = eis_event_pointer_get_absolute_x(event);
const double y = eis_event_pointer_get_absolute_y(event);
qCDebug(KWIN_EIS) << device->name() << "pointer motion absolute" << x << y;
@@ -259,7 +259,6 @@ void EisContext::handleEvents()
break;
}
case EIS_EVENT_BUTTON_BUTTON: {
- auto device = eventDevice(event);
const quint32 button = eis_event_button_get_button(event);
const bool press = eis_event_button_get_is_press(event);
qCDebug(KWIN_EIS) << device->name() << "button" << button << press;
@@ -277,7 +276,6 @@ void EisContext::handleEvents()
break;
}
case EIS_EVENT_SCROLL_DELTA: {
- auto device = eventDevice(event);
const auto x = eis_event_scroll_get_dx(event);
const auto y = eis_event_scroll_get_dy(event);
qCDebug(KWIN_EIS) << device->name() << "scroll" << x << y;
@@ -291,7 +289,6 @@ void EisContext::handleEvents()
}
case EIS_EVENT_SCROLL_STOP:
case EIS_EVENT_SCROLL_CANCEL: {
- auto device = eventDevice(event);
if (eis_event_scroll_get_stop_x(event)) {
qCDebug(KWIN_EIS) << device->name() << "scroll x" << (eis_event_get_type(event) == EIS_EVENT_SCROLL_STOP ? "stop" : "cancel");
Q_EMIT device->pointerAxisChanged(PointerAxis::Horizontal, 0, 0, PointerAxisSource::Unknown, false, currentTime(), device);
@@ -303,7 +300,6 @@ void EisContext::handleEvents()
break;
}
case EIS_EVENT_SCROLL_DISCRETE: {
- auto device = eventDevice(event);
const double x = eis_event_scroll_get_discrete_dx(event);
const double y = eis_event_scroll_get_discrete_dy(event);
qCDebug(KWIN_EIS) << device->name() << "scroll discrete" << x << y;
@@ -318,7 +314,6 @@ void EisContext::handleEvents()
break;
}
case EIS_EVENT_KEYBOARD_KEY: {
- auto device = eventDevice(event);
const quint32 key = eis_event_keyboard_get_key(event);
const bool press = eis_event_keyboard_get_key_is_press(event);
qCDebug(KWIN_EIS) << device->name() << "key" << key << press;
@@ -336,7 +331,6 @@ void EisContext::handleEvents()
break;
}
case EIS_EVENT_TOUCH_DOWN: {
- auto device = eventDevice(event);
const auto x = eis_event_touch_get_x(event);
const auto y = eis_event_touch_get_y(event);
const auto id = eis_event_touch_get_id(event);
@@ -346,7 +340,6 @@ void EisContext::handleEvents()
break;
}
case EIS_EVENT_TOUCH_UP: {
- auto device = eventDevice(event);
const auto id = eis_event_touch_get_id(event);
qCDebug(KWIN_EIS) << device->name() << "touch up" << id;
std::erase(device->activeTouches, id);
@@ -358,7 +351,6 @@ void EisContext::handleEvents()
break;
}
case EIS_EVENT_TOUCH_MOTION: {
- auto device = eventDevice(event);
const auto x = eis_event_touch_get_x(event);
const auto y = eis_event_touch_get_y(event);
const auto id = eis_event_touch_get_id(event);
--
GitLab