From 09287f3d9e9e88271de2bfd5388dae5a53e8c6f5 Mon Sep 17 00:00:00 2001 From: Sine Striker <trueful@163.com> Date: ćšć, 07 12æ 2023 15:03:24 +0800 Subject: [PATCH] Add host event filter --- src/core/contexts/abstractwindowcontext.cpp | 38 ++++++++++++ src/core/contexts/win32windowcontext_p.h | 5 + src/widgets/contexts/widgetwindowcontext_p.h | 34 +++++++++++ src/quick/contexts/quickwindowcontext.cpp | 9 +++ src/widgets/CMakeLists.txt | 2 src/core/contexts/abstractwindowcontext_p.h | 6 + src/quick/CMakeLists.txt | 2 src/core/contexts/qtwindowcontext.cpp | 9 +-- src/quick/contexts/quickwindowcontext_p.h | 34 +++++++++++ src/widgets/contexts/widgetwindowcontext.cpp | 9 +++ src/core/contexts/qtwindowcontext_p.h | 6 - src/core/contexts/win32windowcontext.cpp | 6 - 12 files changed, 142 insertions(+), 18 deletions(-) diff --git a/src/core/contexts/abstractwindowcontext.cpp b/src/core/contexts/abstractwindowcontext.cpp index 679a9ee..c7a5c85 100644 --- a/src/core/contexts/abstractwindowcontext.cpp +++ b/src/core/contexts/abstractwindowcontext.cpp @@ -8,6 +8,24 @@ AbstractWindowContext::~AbstractWindowContext() = default; + class EventFilterForwarder : public QObject { + public: + using EventProc = bool (*)(QEvent *, void *); + + EventFilterForwarder(EventProc proc, void *user, QObject *parent = nullptr) + : QObject(parent), proc(proc), user(user) { + } + + bool eventFilter(QObject *obj, QEvent *event) override { + Q_UNUSED(obj) + return proc(event, user); + } + + protected: + EventProc proc; + void *user; + }; + bool AbstractWindowContext::setup(QObject *host, WindowItemDelegate *delegate) { if (!host || !delegate) { return false; @@ -21,6 +39,21 @@ m_host = host; m_delegate.reset(delegate); m_windowHandle = windowHandle; + + if (!setupHost()) { + m_host = nullptr; + m_delegate = nullptr; + m_windowHandle = nullptr; + return false; + } + + // Install specific event filter + host->installEventFilter(new EventFilterForwarder( + [](QEvent *event, void *user) { + return reinterpret_cast<AbstractWindowContext *>(user)->hostEventFilter(event); + }, + this, this)); + return true; } @@ -157,4 +190,9 @@ return true; } + bool AbstractWindowContext::hostEventFilter(QEvent *event) { + Q_UNUSED(event) + return false; + } + } \ No newline at end of file diff --git a/src/core/contexts/abstractwindowcontext_p.h b/src/core/contexts/abstractwindowcontext_p.h index a73f7c4..30ea3c1 100644 --- a/src/core/contexts/abstractwindowcontext_p.h +++ b/src/core/contexts/abstractwindowcontext_p.h @@ -20,7 +20,7 @@ ~AbstractWindowContext() override; public: - virtual bool setup(QObject *host, WindowItemDelegate *delegate); + bool setup(QObject *host, WindowItemDelegate *delegate); inline QObject *host() const; inline QWindow *window() const; @@ -42,6 +42,10 @@ bool isInTitleBarDraggableArea(const QPoint &pos) const; protected: + virtual bool setupHost() = 0; + virtual bool hostEventFilter(QEvent *event); + + protected: QObject *m_host; std::unique_ptr<WindowItemDelegate> m_delegate; QWindow *m_windowHandle; diff --git a/src/core/contexts/qtwindowcontext.cpp b/src/core/contexts/qtwindowcontext.cpp index 4f4764e..5fa7787 100644 --- a/src/core/contexts/qtwindowcontext.cpp +++ b/src/core/contexts/qtwindowcontext.cpp @@ -46,15 +46,12 @@ QtWindowContext::~QtWindowContext() { } - bool QtWindowContext::setup(QObject *host, WindowItemDelegate *delegate) { - if (!AbstractWindowContext::setup(host, delegate)) { - return false; - } + bool QtWindowContext::setupHost() { return false; } - bool QtWindowContext::eventFilter(QObject *obj, QEvent *event) { - return AbstractWindowContext::eventFilter(obj, event); + bool QtWindowContext::hostEventFilter(QEvent *event) { + return false; } } \ No newline at end of file diff --git a/src/core/contexts/qtwindowcontext_p.h b/src/core/contexts/qtwindowcontext_p.h index 242dcd2..6046633 100644 --- a/src/core/contexts/qtwindowcontext_p.h +++ b/src/core/contexts/qtwindowcontext_p.h @@ -11,11 +11,9 @@ QtWindowContext(); ~QtWindowContext(); - public: - bool setup(QObject *host, WindowItemDelegate *delegate) override; - protected: - bool eventFilter(QObject *obj, QEvent *event) override; + bool setupHost() override; + bool hostEventFilter(QEvent *event) override; }; } diff --git a/src/core/contexts/win32windowcontext.cpp b/src/core/contexts/win32windowcontext.cpp index 538188d..c5c1cbd 100644 --- a/src/core/contexts/win32windowcontext.cpp +++ b/src/core/contexts/win32windowcontext.cpp @@ -525,11 +525,7 @@ } } - bool Win32WindowContext::setup(QObject *host, WindowItemDelegate *delegate) { - if (!AbstractWindowContext::setup(host, delegate)) { - return false; - } - + bool Win32WindowContext::setupHost() { // Install window hook auto winId = m_windowHandle->winId(); auto hWnd = reinterpret_cast<HWND>(winId); diff --git a/src/core/contexts/win32windowcontext_p.h b/src/core/contexts/win32windowcontext_p.h index 0d7b14b..dd506aa 100644 --- a/src/core/contexts/win32windowcontext_p.h +++ b/src/core/contexts/win32windowcontext_p.h @@ -21,9 +21,10 @@ TitleBar, }; - public: - bool setup(QObject *host, WindowItemDelegate *delegate) override; + protected: + bool setupHost() override; + public: bool windowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result); // In order to perfectly apply Windows 11 Snap Layout into the Qt window, we need to diff --git a/src/quick/CMakeLists.txt b/src/quick/CMakeLists.txt index f5feb3e..7381738 100644 --- a/src/quick/CMakeLists.txt +++ b/src/quick/CMakeLists.txt @@ -10,6 +10,8 @@ quickwindowagent.h quickwindowagent_p.h quickwindowagent.cpp + contexts/quickwindowcontext_p.h + contexts/quickwindowcontext.cpp ) qwk_add_library(${PROJECT_NAME} AUTOGEN diff --git a/src/quick/contexts/quickwindowcontext.cpp b/src/quick/contexts/quickwindowcontext.cpp new file mode 100644 index 0000000..4014ef1 --- /dev/null +++ b/src/quick/contexts/quickwindowcontext.cpp @@ -0,0 +1,9 @@ +#include "quickwindowcontext_p.h" + +namespace QWK { + + bool QuickWindowContext::hostEventFilter(QEvent *event) { + return false; + } + +} \ No newline at end of file diff --git a/src/quick/contexts/quickwindowcontext_p.h b/src/quick/contexts/quickwindowcontext_p.h new file mode 100644 index 0000000..9479f3d --- /dev/null +++ b/src/quick/contexts/quickwindowcontext_p.h @@ -0,0 +1,34 @@ +#ifndef QUICKWINDOWCONTEXT_P_H +#define QUICKWINDOWCONTEXT_P_H + +#include <QtGlobal> + +#ifdef Q_OS_WINDOWS +# include <QWKCore/private/win32windowcontext_p.h> +#else +# include <QWKCore/private/qtwindowcontext_p.h> +#endif + +namespace QWK { + + using CoreWindowContext = +#ifdef Q_OS_WINDOWS + Win32WindowContext +#else + QtWindowContext +#endif + ; + + class QuickWindowContext : public CoreWindowContext { + Q_OBJECT + public: + QuickWindowContext() = default; + ~QuickWindowContext() override = default; + + protected: + bool hostEventFilter(QEvent *event) override; + }; + +} + +#endif // QUICKWINDOWCONTEXT_P_H diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt index 8543997..f74a6b0 100644 --- a/src/widgets/CMakeLists.txt +++ b/src/widgets/CMakeLists.txt @@ -10,6 +10,8 @@ widgetwindowagent.h widgetwindowagent_p.h widgetwindowagent.cpp + contexts/widgetwindowcontext_p.h + contexts/widgetwindowcontext.cpp ) qwk_add_library(${PROJECT_NAME} AUTOGEN diff --git a/src/widgets/contexts/widgetwindowcontext.cpp b/src/widgets/contexts/widgetwindowcontext.cpp new file mode 100644 index 0000000..3aa91f2 --- /dev/null +++ b/src/widgets/contexts/widgetwindowcontext.cpp @@ -0,0 +1,9 @@ +#include "widgetwindowcontext_p.h" + +namespace QWK { + + bool WidgetWindowContext::hostEventFilter(QEvent *event) { + return false; + } + +} \ No newline at end of file diff --git a/src/widgets/contexts/widgetwindowcontext_p.h b/src/widgets/contexts/widgetwindowcontext_p.h new file mode 100644 index 0000000..ce50acc --- /dev/null +++ b/src/widgets/contexts/widgetwindowcontext_p.h @@ -0,0 +1,34 @@ +#ifndef WIDGETWINDOWCONTEXT_P_H +#define WIDGETWINDOWCONTEXT_P_H + +#include <QtGlobal> + +#ifdef Q_OS_WINDOWS +# include <QWKCore/private/win32windowcontext_p.h> +#else +# include <QWKCore/private/qtwindowcontext_p.h> +#endif + +namespace QWK { + + using CoreWindowContext = +#ifdef Q_OS_WINDOWS + Win32WindowContext +#else + QtWindowContext +#endif + ; + + class WidgetWindowContext : public CoreWindowContext { + Q_OBJECT + public: + WidgetWindowContext() = default; + ~WidgetWindowContext() override = default; + + protected: + bool hostEventFilter(QEvent *event) override; + }; + +} + +#endif // WIDGETWINDOWCONTEXT_P_H -- Gitblit v1.9.1