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