From 44c08f3cc456155b960ca5a115df93109d2202ce Mon Sep 17 00:00:00 2001
From: Sine Striker <trueful@163.com>
Date: 周三, 13 12月 2023 23:22:25 +0800
Subject: [PATCH] Remove event observer

---
 src/core/kernel/nativeeventfilter.cpp |  112 +++++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 74 insertions(+), 38 deletions(-)

diff --git a/src/core/kernel/nativeeventfilter.cpp b/src/core/kernel/nativeeventfilter.cpp
index 58650db..be5666b 100644
--- a/src/core/kernel/nativeeventfilter.cpp
+++ b/src/core/kernel/nativeeventfilter.cpp
@@ -5,47 +5,83 @@
 
 namespace QWK {
 
-    // Avoid adding multiple global native event filters to QGuiApplication
-    // in this library.
-    class MasterNativeEventFilter : public QAbstractNativeEventFilter {
-    public:
-        MasterNativeEventFilter() {
-            qApp->installNativeEventFilter(this);
-        }
-
-        ~MasterNativeEventFilter() override {
-            // The base class removes automatically
-        }
-
-        bool nativeEventFilter(const QByteArray &eventType, void *message,
-                               QT_NATIVE_EVENT_RESULT_TYPE *result) override {
-            for (const auto &child : std::as_const(children)) {
-                if (child->nativeEventFilter(eventType, message, result)) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        QVector<NativeEventFilter *> children;
-
-        static MasterNativeEventFilter *instance;
-    };
-
-    MasterNativeEventFilter *MasterNativeEventFilter::instance = nullptr;
-
-    NativeEventFilter::NativeEventFilter() {
-        if (!MasterNativeEventFilter::instance) {
-            MasterNativeEventFilter::instance = new MasterNativeEventFilter();
-        }
-        MasterNativeEventFilter::instance->children.append(this);
+    NativeEventFilter::NativeEventFilter() : m_dispatcher(nullptr) {
     }
 
     NativeEventFilter::~NativeEventFilter() {
-        MasterNativeEventFilter::instance->children.removeOne(this);
-        if (MasterNativeEventFilter::instance->children.isEmpty()) {
-            delete MasterNativeEventFilter::instance;
-            MasterNativeEventFilter::instance = nullptr;
+        if (m_dispatcher)
+            m_dispatcher->removeNativeEventFilter(this);
+    }
+
+    NativeEventDispatcher::NativeEventDispatcher() = default;
+
+    NativeEventDispatcher::~NativeEventDispatcher() {
+        for (const auto &observer : std::as_const(m_nativeEventFilters)) {
+            observer->m_dispatcher = nullptr;
+        }
+    }
+
+    bool NativeEventDispatcher::dispatch(const QByteArray &eventType, void *message,
+                                         QT_NATIVE_EVENT_RESULT_TYPE *result) {
+        for (const auto &ef : std::as_const(m_nativeEventFilters)) {
+            if (ef->nativeEventFilter(eventType, message, result))
+                return true;
+        }
+        return false;
+    }
+
+    void NativeEventDispatcher::installNativeEventFilter(NativeEventFilter *filter) {
+        if (!filter || filter->m_dispatcher)
+            return;
+
+        m_nativeEventFilters.append(filter);
+        filter->m_dispatcher = this;
+    }
+
+    void NativeEventDispatcher::removeNativeEventFilter(NativeEventFilter *filter) {
+        if (!m_nativeEventFilters.removeOne(filter)) {
+            return;
+        }
+        filter->m_dispatcher = nullptr;
+    }
+
+
+    // Avoid adding multiple global native event filters to QGuiApplication
+    // in this library.
+    class AppMasterNativeEventFilter : public QAbstractNativeEventFilter,
+                                       public NativeEventDispatcher {
+    public:
+        AppMasterNativeEventFilter() {
+            qApp->installNativeEventFilter(this);
+        }
+
+        // The base class removes automatically
+        ~AppMasterNativeEventFilter() override = default;
+
+        bool nativeEventFilter(const QByteArray &eventType, void *message,
+                               QT_NATIVE_EVENT_RESULT_TYPE *result) override {
+            return dispatch(eventType, message, result);
+        }
+
+        static AppMasterNativeEventFilter *instance;
+
+        friend class AppNativeEventFilter;
+    };
+
+    AppMasterNativeEventFilter *AppMasterNativeEventFilter::instance = nullptr;
+
+    AppNativeEventFilter::AppNativeEventFilter() {
+        if (!AppMasterNativeEventFilter::instance) {
+            AppMasterNativeEventFilter::instance = new AppMasterNativeEventFilter();
+        }
+        AppMasterNativeEventFilter::instance->installNativeEventFilter(this);
+    }
+
+    AppNativeEventFilter::~AppNativeEventFilter() {
+        AppMasterNativeEventFilter::instance->removeNativeEventFilter(this);
+        if (AppMasterNativeEventFilter::instance->m_nativeEventFilters.isEmpty()) {
+            delete AppMasterNativeEventFilter::instance;
+            AppMasterNativeEventFilter::instance = nullptr;
         }
     }
 

--
Gitblit v1.9.1