Recommended backport of [1] by the kde community[2] to avoid several crashes
when unplugging a tablet (missed the 6.8.1 window, will be in 6.8.2).

[1] https://github.com/qt/qtwayland/commit/24002ac6cbd01dbde4944b63c1f7c87ed2bd72b5
[2] https://mail.kde.org/pipermail/distributions/2024-November/001550.html
--- a/src/client/qwaylandtabletv2.cpp
+++ b/src/client/qwaylandtabletv2.cpp
@@ -188,10 +188,4 @@
 QWaylandTabletSeatV2::~QWaylandTabletSeatV2()
 {
-    for (auto *tablet : m_tablets)
-        tablet->destroy();
-    for (auto *tool : m_tools)
-        tool->destroy();
-    for (auto *pad : m_pads)
-        pad->destroy();
     qDeleteAll(m_tablets);
     qDeleteAll(m_tools);
@@ -255,4 +249,9 @@
 }
 
+QWaylandTabletV2::~QWaylandTabletV2()
+{
+    destroy();
+}
+
 void QWaylandTabletV2::zwp_tablet_v2_name(const QString &name)
 {
@@ -293,5 +292,4 @@
 void QWaylandTabletV2::zwp_tablet_v2_removed()
 {
-    destroy();
     deleteLater();
 }
@@ -317,5 +315,8 @@
 }
 
-QWaylandTabletToolV2::~QWaylandTabletToolV2() = default;
+QWaylandTabletToolV2::~QWaylandTabletToolV2()
+{
+    destroy();
+}
 
 void QWaylandTabletToolV2::zwp_tablet_tool_v2_type(uint32_t tool_type)
@@ -411,5 +412,4 @@
 void QWaylandTabletToolV2::zwp_tablet_tool_v2_removed()
 {
-    destroy();
     m_tabletSeat->toolRemoved(this);
 }
@@ -603,4 +603,9 @@
 }
 
+QWaylandTabletPadV2::~QWaylandTabletPadV2()
+{
+    destroy();
+}
+
 void QWaylandTabletPadV2::zwp_tablet_pad_v2_path(const QString &path)
 {
@@ -622,5 +627,4 @@
 void QWaylandTabletPadV2::zwp_tablet_pad_v2_removed()
 {
-    destroy();
     delete this;
 }
--- a/src/client/qwaylandtabletv2_p.h
+++ b/src/client/qwaylandtabletv2_p.h
@@ -84,4 +84,5 @@
 public:
     explicit QWaylandTabletV2(::zwp_tablet_v2 *tablet, const QString &seatName);
+    ~QWaylandTabletV2();
 
 protected:
@@ -99,5 +100,5 @@
 public:
     QWaylandTabletToolV2(QWaylandTabletSeatV2 *tabletSeat, ::zwp_tablet_tool_v2 *tool);
-    ~QWaylandTabletToolV2() override;
+    ~QWaylandTabletToolV2();
 
     void updateCursor();
@@ -182,4 +183,5 @@
 public:
     explicit QWaylandTabletPadV2(::zwp_tablet_pad_v2 *pad);
+    ~QWaylandTabletPadV2();
 
 protected:
--- a/tests/auto/client/tabletv2/tst_tabletv2.cpp
+++ b/tests/auto/client/tabletv2/tst_tabletv2.cpp
@@ -187,7 +187,7 @@
     QList<TabletV2 *> m_tabletsWaitingForDestroy;
     QList<TabletToolV2 *> m_tools;
-    QList<TabletToolV2 *> m_toolsWaitingForDestroy;
+    QList<TabletToolV2::Resource *> m_toolsWaitingForDestroy;
     QList<TabletPadV2 *> m_pads;
-    QList<TabletPadV2 *> m_padsWaitingForDestroy;
+    QList<TabletPadV2::Resource *> m_padsWaitingForDestroy;
 
 protected:
@@ -275,9 +275,10 @@
 void TabletToolV2::sendRemoved()
 {
-    for (auto *resource : resourceMap())
+    for (auto *resource : resourceMap()) {
         zwp_tablet_tool_v2_send_removed(resource->handle);
+        m_tabletSeat->m_toolsWaitingForDestroy.append(resource);
+    }
     bool removed = m_tabletSeat->m_tools.removeOne(this);
     QVERIFY(removed);
-    m_tabletSeat->m_toolsWaitingForDestroy.append(this);
 }
 
@@ -334,6 +335,5 @@
 {
     if (m_tabletSeat) {
-        bool removed = m_tabletSeat->m_toolsWaitingForDestroy.removeOne(this);
-        QVERIFY(removed);
+        m_tabletSeat->m_toolsWaitingForDestroy.removeOne(resource);
     }
     wl_resource_destroy(resource->handle);
@@ -342,9 +342,10 @@
 void TabletPadV2::sendRemoved()
 {
-    for (auto *resource : resourceMap())
+    for (auto *resource : resourceMap()) {
         zwp_tablet_pad_v2_send_removed(resource->handle);
+        m_tabletSeat->m_padsWaitingForDestroy.append(resource);
+    }
     bool removed = m_tabletSeat->m_pads.removeOne(this);
     QVERIFY(removed);
-    m_tabletSeat->m_padsWaitingForDestroy.append(this);
 }
 
@@ -352,6 +353,5 @@
 {
     if (m_tabletSeat) {
-        bool removed = m_tabletSeat->m_padsWaitingForDestroy.removeOne(this);
-        QVERIFY(removed);
+        m_tabletSeat->m_padsWaitingForDestroy.removeOne(resource);
     }
     wl_resource_destroy(resource->handle);
@@ -406,4 +406,6 @@
     void destroysTool();
     void destroysPad();
+    void removeTabletBeforeTool();
+    void removeTabletBeforePad();
     void proximityEvents();
     void moveEvent();
@@ -503,4 +505,5 @@
     QCOMPOSITOR_TRY_VERIFY(tabletSeat());
     exec([&] {
+        tabletSeat()->addTablet();
         tabletSeat()->addTool();
     });
@@ -509,4 +512,5 @@
     exec([&] {
         tabletTool()->sendRemoved();
+        tablet()->sendRemoved();
     });
 
@@ -529,4 +533,40 @@
     QCOMPOSITOR_TRY_VERIFY(!tabletPad());
     QCOMPOSITOR_TRY_VERIFY(tabletSeat()->m_padsWaitingForDestroy.empty());
+}
+
+void tst_tabletv2::removeTabletBeforeTool()
+{
+    QCOMPOSITOR_TRY_VERIFY(tabletSeat());
+    exec([&] {
+        tabletSeat()->addTablet();
+        tabletSeat()->addTool();
+    });
+    QCOMPOSITOR_TRY_VERIFY(tablet());
+    QCOMPOSITOR_TRY_VERIFY(tabletTool());
+
+    exec([&] { tablet()->sendRemoved(); });
+    QCOMPOSITOR_TRY_VERIFY(tabletSeat()->m_tabletsWaitingForDestroy.empty());
+
+    exec([&] { tabletTool()->sendRemoved(); });
+    QCOMPOSITOR_TRY_VERIFY(!tabletTool());
+    QCOMPOSITOR_TRY_VERIFY(tabletSeat()->m_toolsWaitingForDestroy.empty());
+}
+
+void tst_tabletv2::removeTabletBeforePad()
+{
+    QCOMPOSITOR_TRY_VERIFY(tabletSeat());
+    exec([&] {
+        tabletSeat()->addTablet();
+        tabletSeat()->addPad();
+    });
+    QCOMPOSITOR_TRY_VERIFY(tablet());
+    QCOMPOSITOR_TRY_VERIFY(tabletPad());
+
+    exec([&] { tablet()->sendRemoved(); });
+    QCOMPOSITOR_TRY_VERIFY(tabletSeat()->m_tabletsWaitingForDestroy.empty());
+
+    exec([&] { tabletPad()->sendRemoved(); });
+    QCOMPOSITOR_TRY_VERIFY(!tabletPad());
+    QCOMPOSITOR_TRY_VERIFY(tabletSeat()->m_padsWaitingForDestroy.empty());
 }
 
