src/core/CMakeLists.txt | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/core/contexts/abstractwindowcontext_p.h | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/core/contexts/win32windowcontext.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/core/contexts/win32windowcontext_p.h | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/core/kernel/eventobserver.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/core/kernel/eventobserver_p.h | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/core/kernel/nativeeventfilter.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/core/kernel/nativeeventfilter_p.h | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/quick/quickwindowagent_win.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/widgets/widgetwindowagent_win.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
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 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(); 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)) { // 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; } } 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; src/core/kernel/eventobserver.cpp
File was deleted src/core/kernel/eventobserver_p.h
File was deleted 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); NativeEventFilter::NativeEventFilter() : m_dispatcher(nullptr) { } ~MasterNativeEventFilter() override { // The base class removes automatically NativeEventFilter::~NativeEventFilter() { if (m_dispatcher) m_dispatcher->removeNativeEventFilter(this); } 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)) { 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; } QVector<NativeEventFilter *> children; void NativeEventDispatcher::installNativeEventFilter(NativeEventFilter *filter) { if (!filter || filter->m_dispatcher) return; static MasterNativeEventFilter *instance; 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; }; MasterNativeEventFilter *MasterNativeEventFilter::instance = nullptr; AppMasterNativeEventFilter *AppMasterNativeEventFilter::instance = nullptr; NativeEventFilter::NativeEventFilter() { if (!MasterNativeEventFilter::instance) { MasterNativeEventFilter::instance = new MasterNativeEventFilter(); AppNativeEventFilter::AppNativeEventFilter() { if (!AppMasterNativeEventFilter::instance) { AppMasterNativeEventFilter::instance = new AppMasterNativeEventFilter(); } MasterNativeEventFilter::instance->children.append(this); AppMasterNativeEventFilter::instance->installNativeEventFilter(this); } NativeEventFilter::~NativeEventFilter() { MasterNativeEventFilter::instance->children.removeOne(this); if (MasterNativeEventFilter::instance->children.isEmpty()) { delete MasterNativeEventFilter::instance; MasterNativeEventFilter::instance = nullptr; AppNativeEventFilter::~AppNativeEventFilter() { AppMasterNativeEventFilter::instance->removeNativeEventFilter(this); if (AppMasterNativeEventFilter::instance->m_nativeEventFilters.isEmpty()) { delete AppMasterNativeEventFilter::instance; AppMasterNativeEventFilter::instance = nullptr; } } 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; }; } 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; } 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); } }