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

openSUSE Build Service is sponsored by