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 --- /dev/null | 47 ------- src/core/contexts/win32windowcontext_p.h | 3 src/widgets/widgetwindowagent_win.cpp | 38 ++++-- src/core/kernel/nativeeventfilter.cpp | 112 ++++++++++++------ src/core/kernel/nativeeventfilter_p.h | 34 +++++ src/core/contexts/abstractwindowcontext_p.h | 6 src/core/CMakeLists.txt | 2 src/quick/quickwindowagent_win.cpp | 29 +++- src/core/contexts/win32windowcontext.cpp | 62 ++-------- 9 files changed, 171 insertions(+), 162 deletions(-) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 2123a05..718d862 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -12,8 +12,6 @@ windowagentbase.cpp windowitemdelegate_p.h windowitemdelegate.cpp - kernel/eventobserver_p.h - kernel/eventobserver.cpp kernel/nativeeventfilter_p.h kernel/nativeeventfilter.cpp contexts/abstractwindowcontext_p.h diff --git a/src/core/contexts/abstractwindowcontext_p.h b/src/core/contexts/abstractwindowcontext_p.h index 2934b4d..bcc6ae8 100644 --- a/src/core/contexts/abstractwindowcontext_p.h +++ b/src/core/contexts/abstractwindowcontext_p.h @@ -5,16 +5,16 @@ #include <memory> #include <QtCore/QSet> +#include <QtGui/QRegion> #include <QtGui/QWindow> -#include <QtGui/QPolygon> #include <QWKCore/windowagentbase.h> -#include <QWKCore/private/eventobserver_p.h> +#include <QWKCore/private/nativeeventfilter_p.h> #include <QWKCore/private/windowitemdelegate_p.h> namespace QWK { - class QWK_CORE_EXPORT AbstractWindowContext : public QObject, public EventDispatcher { + class QWK_CORE_EXPORT AbstractWindowContext : public QObject, public NativeEventDispatcher { Q_OBJECT public: AbstractWindowContext(); diff --git a/src/core/contexts/win32windowcontext.cpp b/src/core/contexts/win32windowcontext.cpp index 3f0ac32..86ec6bd 100644 --- a/src/core/contexts/win32windowcontext.cpp +++ b/src/core/contexts/win32windowcontext.cpp @@ -27,7 +27,6 @@ #include <dwmapi.h> #include <timeapi.h> -#include "nativeeventfilter_p.h" #include "qwkglobal_p.h" #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) @@ -635,7 +634,7 @@ // DefWindowProc(). Consequently, we have to add a global native filter that forwards the result // of the hook function, telling Qt whether we have filtered the events before. Since Qt only // handles Windows window messages in the main thread, it is safe to do so. - class WindowsNativeEventFilter : public NativeEventFilter { + class WindowsNativeEventFilter : public AppNativeEventFilter { public: bool nativeEventFilter(const QByteArray &eventType, void *message, QT_NATIVE_EVENT_RESULT_TYPE *result) override { @@ -933,10 +932,19 @@ return true; } - if (themeStuffHandler(hWnd, message, wParam, lParam, result)) { - return true; + // Forward to native event filter subscribers + if (!m_nativeEventFilters.isEmpty()) { + MSG msg; + msg.hwnd = hWnd; + msg.message = message; + msg.wParam = wParam; + msg.lParam = lParam; + QT_NATIVE_EVENT_RESULT_TYPE res = 0; + if (dispatch(QByteArrayLiteral("windows_generic_MSG"), &msg, &res)) { + *result = LRESULT(res); + return true; + } } - return false; // Not handled } @@ -1923,48 +1931,4 @@ return false; } - bool Win32WindowContext::themeStuffHandler(HWND hWnd, UINT message, WPARAM wParam, - LPARAM lParam, LRESULT *resul) { - switch (message) { - case WM_DPICHANGED: { - const auto dpiX = UINT(LOWORD(wParam)); - const auto dpiY = UINT(HIWORD(wParam)); - - QEvent e(QEvent::ScreenChangeInternal); - dispatch(&e); - break; - } - - case WM_THEMECHANGED: - case WM_SYSCOLORCHANGE: { - QEvent e(QEvent::UpdateLater); - dispatch(&e); - break; - } - - case WM_DWMCOLORIZATIONCOLORCHANGED: { - const QColor color = QColor::fromRgba(wParam); - const auto blendedWithOpacity = *reinterpret_cast<LPBOOL>(lParam); - - QEvent e(QEvent::UpdateLater); - dispatch(&e); - break; - } - - case WM_SETTINGCHANGE: { - if (!wParam && lParam && - std::wcscmp(reinterpret_cast<LPCWSTR>(lParam), L"ImmersiveColorSet") == 0) { - const QColor color = getAccentColor(); - - QEvent e(QEvent::UpdateLater); - dispatch(&e); - } - break; - } - - default: - break; - } - return false; - } } diff --git a/src/core/contexts/win32windowcontext_p.h b/src/core/contexts/win32windowcontext_p.h index ce51265..9303938 100644 --- a/src/core/contexts/win32windowcontext_p.h +++ b/src/core/contexts/win32windowcontext_p.h @@ -51,9 +51,6 @@ bool nonClientCalcSizeHandler(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result); - bool themeStuffHandler(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, - LRESULT *resul); - protected: WId windowId = 0; diff --git a/src/core/kernel/eventobserver.cpp b/src/core/kernel/eventobserver.cpp deleted file mode 100644 index 98b8fcc..0000000 --- a/src/core/kernel/eventobserver.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "eventobserver_p.h" - -namespace QWK { - - EventObserver::EventObserver() : m_dispatcher(nullptr) { - } - - EventObserver::~EventObserver() { - if (m_dispatcher) - m_dispatcher->removeObserver(this); - } - - EventDispatcher::EventDispatcher() = default; - - EventDispatcher::~EventDispatcher() { - for (const auto &observer : std::as_const(m_observers)) { - observer->m_dispatcher = nullptr; - } - } - - bool EventDispatcher::dispatch(QEvent *event) { - for (const auto &observer : std::as_const(m_observers)) { - if (observer->observe(event)) - return true; - } - return true; - } - - void EventDispatcher::addObserver(EventObserver *observer) { - if (!observer || observer->m_dispatcher) - return; - - m_observers.append(observer); - observer->m_dispatcher = this; - } - - void EventDispatcher::removeObserver(EventObserver *observer) { - if (!m_observers.removeOne(observer)) { - return; - } - observer->m_dispatcher = nullptr; - } - -} \ No newline at end of file diff --git a/src/core/kernel/eventobserver_p.h b/src/core/kernel/eventobserver_p.h deleted file mode 100644 index 558b549..0000000 --- a/src/core/kernel/eventobserver_p.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef EVENTFILTER_P_H -#define EVENTFILTER_P_H - -#include <QtGui/QtEvents> - -#include <QWKCore/qwkglobal.h> - -namespace QWK { - - class EventDispatcher; - - class QWK_CORE_EXPORT EventObserver { - public: - EventObserver(); - virtual ~EventObserver(); - - protected: - virtual bool observe(QEvent *event) = 0; - - protected: - EventDispatcher *m_dispatcher; - - Q_DISABLE_COPY(EventObserver) - - friend class EventDispatcher; - }; - - class QWK_CORE_EXPORT EventDispatcher { - public: - EventDispatcher(); - virtual ~EventDispatcher(); - - virtual bool dispatch(QEvent *event); - - public: - void addObserver(EventObserver *observer); - void removeObserver(EventObserver *observer); - - protected: - QVector<EventObserver *> m_observers; - - Q_DISABLE_COPY(EventDispatcher) - }; - -} - -#endif // EVENTFILTER_P_H 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; } } diff --git a/src/core/kernel/nativeeventfilter_p.h b/src/core/kernel/nativeeventfilter_p.h index b7ce167..45228df 100644 --- a/src/core/kernel/nativeeventfilter_p.h +++ b/src/core/kernel/nativeeventfilter_p.h @@ -5,6 +5,27 @@ namespace QWK { + class NativeEventFilter; + + class QWK_CORE_EXPORT NativeEventDispatcher { + public: + NativeEventDispatcher(); + virtual ~NativeEventDispatcher(); + + public: + virtual bool dispatch(const QByteArray &eventType, void *message, + QT_NATIVE_EVENT_RESULT_TYPE *result); + + public: + void installNativeEventFilter(NativeEventFilter *filter); + void removeNativeEventFilter(NativeEventFilter *filter); + + protected: + QVector<NativeEventFilter *> m_nativeEventFilters; + + Q_DISABLE_COPY(NativeEventDispatcher) + }; + class QWK_CORE_EXPORT NativeEventFilter { public: NativeEventFilter(); @@ -14,8 +35,19 @@ virtual bool nativeEventFilter(const QByteArray &eventType, void *message, QT_NATIVE_EVENT_RESULT_TYPE *result) = 0; - private: + protected: + NativeEventDispatcher *m_dispatcher; + Q_DISABLE_COPY(NativeEventFilter) + + friend class NativeEventDispatcher; + }; + + // Automatically install to QApplication at construction + class QWK_CORE_EXPORT AppNativeEventFilter : public NativeEventFilter { + public: + AppNativeEventFilter(); + ~AppNativeEventFilter() override; }; } diff --git a/src/quick/quickwindowagent_win.cpp b/src/quick/quickwindowagent_win.cpp index 2049d29..15418e2 100644 --- a/src/quick/quickwindowagent_win.cpp +++ b/src/quick/quickwindowagent_win.cpp @@ -3,11 +3,11 @@ #include <QtQuick/QQuickPaintedItem> #include <QtQuick/private/qquickitem_p.h> -#include <QWKCore/private/eventobserver_p.h> +#include <QWKCore/private/nativeeventfilter_p.h> namespace QWK { - class BorderItem : public QQuickPaintedItem, public EventObserver { + class BorderItem : public QQuickPaintedItem, public NativeEventFilter { Q_OBJECT public: explicit BorderItem(QQuickItem *parent, AbstractWindowContext *context); @@ -20,7 +20,8 @@ void itemChange(ItemChange change, const ItemChangeData &data) override; protected: - bool observe(QEvent *event) override; + bool nativeEventFilter(const QByteArray &eventType, void *message, + QT_NATIVE_EVENT_RESULT_TYPE *result) override; AbstractWindowContext *context; @@ -44,7 +45,7 @@ setZ(10); - context->addObserver(this); + context->installNativeEventFilter(this); connect(window(), &QQuickWindow::activeChanged, this, &BorderItem::_q_windowActivityChanged); updateGeometry(); @@ -80,13 +81,27 @@ } } - bool BorderItem::observe(QEvent *event) { - switch (event->type()) { - case QEvent::UpdateLater: { + bool BorderItem::nativeEventFilter(const QByteArray &eventType, void *message, + QT_NATIVE_EVENT_RESULT_TYPE *result) { + Q_UNUSED(eventType) + auto msg = reinterpret_cast<const MSG *>(message); + switch (msg->message) { + case WM_THEMECHANGED: + case WM_SYSCOLORCHANGE: + case WM_DWMCOLORIZATIONCOLORCHANGED: { update(); break; } + case WM_SETTINGCHANGE: { + if (!msg->wParam && msg->lParam && + std::wcscmp(reinterpret_cast<LPCWSTR>(msg->lParam), L"ImmersiveColorSet") == + 0) { + update(); + } + break; + } + default: break; } diff --git a/src/widgets/widgetwindowagent_win.cpp b/src/widgets/widgetwindowagent_win.cpp index d2a49a2..2a67ebb 100644 --- a/src/widgets/widgetwindowagent_win.cpp +++ b/src/widgets/widgetwindowagent_win.cpp @@ -2,19 +2,19 @@ #include <QtGui/QPainter> -#include <QWKCore/private/eventobserver_p.h> +#include <QWKCore/qwindowkit_windows.h> +#include <QWKCore/private/nativeeventfilter_p.h> namespace QWK { - class WidgetBorderHandler : public QObject, public EventObserver { + class WidgetBorderHandler : public QObject, public NativeEventFilter { Q_OBJECT public: - explicit WidgetBorderHandler(QWidget *widget, AbstractWindowContext *ctx, - QObject *parent = nullptr) - : QObject(parent), widget(widget), ctx(ctx) { + explicit WidgetBorderHandler(QWidget *widget, AbstractWindowContext *ctx) + : QObject(ctx), widget(widget), ctx(ctx) { widget->installEventFilter(this); - ctx->addObserver(this); + ctx->installNativeEventFilter(this); updateGeometry(); } @@ -32,15 +32,29 @@ } protected: - bool observe(QEvent *event) override { - switch (event->type()) { - case QEvent::UpdateLater: { + bool nativeEventFilter(const QByteArray &eventType, void *message, + QT_NATIVE_EVENT_RESULT_TYPE *result) override { + Q_UNUSED(eventType) + auto msg = reinterpret_cast<const MSG *>(message); + switch (msg->message) { + case WM_DPICHANGED: { + updateGeometry(); + break; + } + + case WM_THEMECHANGED: + case WM_SYSCOLORCHANGE: + case WM_DWMCOLORIZATIONCOLORCHANGED: { widget->update(); break; } - case QEvent::ScreenChangeInternal: { - updateGeometry(); + case WM_SETTINGCHANGE: { + if (!msg->wParam && msg->lParam && + std::wcscmp(reinterpret_cast<LPCWSTR>(msg->lParam), L"ImmersiveColorSet") == + 0) { + widget->update(); + } break; } @@ -95,7 +109,7 @@ // Install painting hook auto ctx = context.get(); if (ctx->property("needBorderPainter").toBool()) { - std::ignore = new WidgetBorderHandler(hostWidget, ctx, ctx); + std::ignore = new WidgetBorderHandler(hostWidget, ctx); } } -- Gitblit v1.9.1