From 3cfe15a9c3db0993d8b8fef5d148625840e5a75c Mon Sep 17 00:00:00 2001
From: Sine Striker <trueful@163.com>
Date: 周二, 05 12月 2023 15:43:39 +0800
Subject: [PATCH] Add host interface

---
 src/core/windowitemdelegate.h               |    7 ++-
 src/widgets/widgetitemdelegate.cpp          |    8 ++++
 src/widgets/widgetitemdelegate_p.h          |    4 +
 src/core/contexts/abstractwindowcontext.cpp |   17 ++------
 src/core/contexts/abstractwindowcontext_p.h |   11 ++++-
 src/quick/quickitemdelegate.cpp             |    8 ++++
 src/core/contexts/qtwindowcontext_p.h       |    2 
 src/core/contexts/win32windowcontext.cpp    |   16 +++++--
 src/core/corewindowagent.cpp                |   18 +++------
 src/core/corewindowagent_p.h                |    2 
 src/core/contexts/win32windowcontext_p.h    |    2 
 src/widgets/widgetwindowagent.cpp           |    2 
 src/quick/quickitemdelegate_p.h             |    4 +
 src/core/contexts/qtwindowcontext.cpp       |    7 ++-
 14 files changed, 65 insertions(+), 43 deletions(-)

diff --git a/src/core/contexts/abstractwindowcontext.cpp b/src/core/contexts/abstractwindowcontext.cpp
index 5329634..5150203 100644
--- a/src/core/contexts/abstractwindowcontext.cpp
+++ b/src/core/contexts/abstractwindowcontext.cpp
@@ -2,20 +2,11 @@
 
 namespace QWK {
 
-    AbstractWindowContext::AbstractWindowContext(QWindow *window, WindowItemDelegate *delegate)
-        : m_windowHandle(window), m_delegate(delegate) {
+    AbstractWindowContext::AbstractWindowContext(QObject *host, WindowItemDelegate *delegate)
+        : m_host(host), m_delegate(delegate), m_windowHandle(delegate->hostWindow(host)) {
     }
 
-    AbstractWindowContext::~AbstractWindowContext() {
-    }
-
-    void AbstractWindowContext::setupWindow(QWindow *window) {
-        Q_ASSERT(window);
-        if (!window) {
-            return;
-        }
-        m_windowHandle = window;
-    }
+    AbstractWindowContext::~AbstractWindowContext() = default;
 
     bool AbstractWindowContext::setHitTestVisible(QObject *obj, bool visible) {
         Q_ASSERT(obj);
@@ -140,7 +131,7 @@
             }
         }
 
-        if (hitTestShape().contains(pos)) {
+        if (!m_hitTestVisibleRects.isEmpty() && hitTestShape().contains(pos)) {
             return false;
         }
 
diff --git a/src/core/contexts/abstractwindowcontext_p.h b/src/core/contexts/abstractwindowcontext_p.h
index a92d91d..996a0e3 100644
--- a/src/core/contexts/abstractwindowcontext_p.h
+++ b/src/core/contexts/abstractwindowcontext_p.h
@@ -16,14 +16,14 @@
     class QWK_CORE_EXPORT AbstractWindowContext : public QObject {
         Q_OBJECT
     public:
-        AbstractWindowContext(QWindow *window, WindowItemDelegate *delegate);
+        AbstractWindowContext(QObject *host, WindowItemDelegate *delegate);
         ~AbstractWindowContext() override;
 
     public:
         virtual bool setup() = 0;
 
+        inline QObject *host() const;
         inline QWindow *window() const;
-        void setupWindow(QWindow *window);
 
         inline bool isHitTestVisible(QObject *obj) const;
         bool setHitTestVisible(QObject *obj, bool visible);
@@ -42,8 +42,9 @@
         bool isInTitleBarDraggableArea(const QPoint &pos) const;
 
     protected:
-        QWindow *m_windowHandle;
+        QObject *m_host;
         std::unique_ptr<WindowItemDelegate> m_delegate;
+        QWindow *m_windowHandle;
 
         QSet<QObject *> m_hitTestVisibleItems;
         QList<QRect> m_hitTestVisibleRects;
@@ -56,6 +57,10 @@
         mutable QRegion hitTestVisibleShape;
     };
 
+    inline QObject *AbstractWindowContext::host() const {
+        return m_host;
+    }
+
     inline QWindow *AbstractWindowContext::window() const {
         return m_windowHandle;
     }
diff --git a/src/core/contexts/qtwindowcontext.cpp b/src/core/contexts/qtwindowcontext.cpp
index a9740f1..732ecf1 100644
--- a/src/core/contexts/qtwindowcontext.cpp
+++ b/src/core/contexts/qtwindowcontext.cpp
@@ -40,14 +40,17 @@
 #endif
     }
 
-    QtWindowContext::QtWindowContext(QWindow *window, WindowItemDelegate *delegate)
-        : AbstractWindowContext(window, delegate) {
+    QtWindowContext::QtWindowContext(QObject *host, WindowItemDelegate *delegate)
+        : AbstractWindowContext(host, delegate) {
     }
 
     QtWindowContext::~QtWindowContext() {
     }
 
     bool QtWindowContext::setup() {
+        if (!m_windowHandle) {
+            return false;
+        }
         return false;
     }
 
diff --git a/src/core/contexts/qtwindowcontext_p.h b/src/core/contexts/qtwindowcontext_p.h
index 6daccb8..9a78813 100644
--- a/src/core/contexts/qtwindowcontext_p.h
+++ b/src/core/contexts/qtwindowcontext_p.h
@@ -8,7 +8,7 @@
     class QWK_CORE_EXPORT QtWindowContext : public AbstractWindowContext {
         Q_OBJECT
     public:
-        QtWindowContext(QWindow *window, WindowItemDelegate *delegate);
+        QtWindowContext(QObject *host, WindowItemDelegate *delegate);
         ~QtWindowContext();
 
     public:
diff --git a/src/core/contexts/win32windowcontext.cpp b/src/core/contexts/win32windowcontext.cpp
index 49a6d69..dcb6eb8 100644
--- a/src/core/contexts/win32windowcontext.cpp
+++ b/src/core/contexts/win32windowcontext.cpp
@@ -46,7 +46,8 @@
 
             QSystemLibrary dwmapi(QStringLiteral("dwmapi.dll"));
             pDwmFlush = reinterpret_cast<decltype(pDwmFlush)>(dwmapi.resolve("DwmFlush"));
-            pDwmIsCompositionEnabled = reinterpret_cast<decltype(pDwmIsCompositionEnabled)>(dwmapi.resolve("DwmIsCompositionEnabled"));
+            pDwmIsCompositionEnabled = reinterpret_cast<decltype(pDwmIsCompositionEnabled)>(
+                dwmapi.resolve("DwmIsCompositionEnabled"));
         }
 
         ~DynamicApis() = default;
@@ -175,7 +176,9 @@
         if (!hwnd) {
             return;
         }
-        ::SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
+        ::SetWindowPos(hwnd, nullptr, 0, 0, 0, 0,
+                       SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER |
+                           SWP_FRAMECHANGED);
     }
 
     static inline quint32 getDpiForWindow(HWND hwnd) {
@@ -452,8 +455,8 @@
         return ::CallWindowProcW(g_qtWindowProc, hWnd, message, wParam, lParam);
     }
 
-    Win32WindowContext::Win32WindowContext(QWindow *window, WindowItemDelegate *delegate)
-        : AbstractWindowContext(window, delegate) {
+    Win32WindowContext::Win32WindowContext(QObject *host, WindowItemDelegate *delegate)
+        : AbstractWindowContext(host, delegate) {
     }
 
     Win32WindowContext::~Win32WindowContext() {
@@ -469,9 +472,12 @@
     }
 
     bool Win32WindowContext::setup() {
-        auto winId = m_windowHandle->winId();
+        if (!m_windowHandle) {
+            return false;
+        }
 
         // Install window hook
+        auto winId = m_windowHandle->winId();
         auto hWnd = reinterpret_cast<HWND>(winId);
 
         // Store original window proc
diff --git a/src/core/contexts/win32windowcontext_p.h b/src/core/contexts/win32windowcontext_p.h
index b61ac01..269530e 100644
--- a/src/core/contexts/win32windowcontext_p.h
+++ b/src/core/contexts/win32windowcontext_p.h
@@ -9,7 +9,7 @@
     class QWK_CORE_EXPORT Win32WindowContext : public AbstractWindowContext {
         Q_OBJECT
     public:
-        Win32WindowContext(QWindow *window, WindowItemDelegate *delegate);
+        Win32WindowContext(QObject *host, WindowItemDelegate *delegate);
         ~Win32WindowContext() override;
 
         enum WindowPart {
diff --git a/src/core/corewindowagent.cpp b/src/core/corewindowagent.cpp
index 78ed335..bea2239 100644
--- a/src/core/corewindowagent.cpp
+++ b/src/core/corewindowagent.cpp
@@ -21,24 +21,18 @@
     void CoreWindowAgentPrivate::init() {
     }
 
-    bool CoreWindowAgentPrivate::setup(QWindow *window, WindowItemDelegate *delegate) {
-        Q_ASSERT(window);
-        if (!window) {
-            return false;
-        }
-
-        auto handler =
+    bool CoreWindowAgentPrivate::setup(QObject *host, WindowItemDelegate *delegate) {
+        auto ctx =
 #ifdef Q_OS_WINDOWS
-            new Win32WindowContext(window, delegate)
+            std::make_unique<Win32WindowContext>(host, delegate)
 #else
-            new QtWindowContext(window, delegate)
+            std::make_unique<QtWindowContext>(host, window, delegate)
 #endif
             ;
-        if (!handler->setup()) {
-            delete handler;
+        if (!ctx->setup()) {
             return false;
         }
-        context.reset(handler);
+        context = std::move(ctx);
         return true;
     }
 
diff --git a/src/core/corewindowagent_p.h b/src/core/corewindowagent_p.h
index 5916d89..faa61f8 100644
--- a/src/core/corewindowagent_p.h
+++ b/src/core/corewindowagent_p.h
@@ -16,7 +16,7 @@
 
         CoreWindowAgent *q_ptr; // no need to initialize
 
-        bool setup(QWindow *window, WindowItemDelegate *delegate);
+        bool setup(QObject *host, WindowItemDelegate *delegate);
 
         std::unique_ptr<AbstractWindowContext> context;
 
diff --git a/src/core/windowitemdelegate.h b/src/core/windowitemdelegate.h
index 5794851..498216d 100644
--- a/src/core/windowitemdelegate.h
+++ b/src/core/windowitemdelegate.h
@@ -15,13 +15,16 @@
         virtual ~WindowItemDelegate();
 
     public:
+        // Item property query
         virtual QWindow *window(QObject *obj) const = 0;
-
-        // Property query
         virtual bool isEnabled(QObject *obj) const = 0;
         virtual bool isVisible(QObject *obj) const = 0;
         virtual QRect mapGeometryToScene(const QObject *obj) const = 0;
 
+        // Host property query
+        virtual QWindow *hostWindow(QObject *host) const = 0;
+        virtual bool isHostSizeFixed(QObject *host) const = 0;
+
         // Callbacks
         virtual bool resetQtGrabbedControl() const;
 
diff --git a/src/quick/quickitemdelegate.cpp b/src/quick/quickitemdelegate.cpp
index 1dff54d..aa85204 100644
--- a/src/quick/quickitemdelegate.cpp
+++ b/src/quick/quickitemdelegate.cpp
@@ -33,4 +33,12 @@
         return QRectF(originPoint, size).toRect();
     }
 
+    QWindow *QuickItemDelegate::hostWindow(QObject *host) const {
+        return static_cast<QQuickWindow *>(host);
+    }
+
+    bool QuickItemDelegate::isHostSizeFixed(QObject *host) const {
+        return false;
+    }
+
 }
\ No newline at end of file
diff --git a/src/quick/quickitemdelegate_p.h b/src/quick/quickitemdelegate_p.h
index 51463ee..b8bd84d 100644
--- a/src/quick/quickitemdelegate_p.h
+++ b/src/quick/quickitemdelegate_p.h
@@ -16,10 +16,12 @@
 
     public:
         QWindow *window(QObject *obj) const override;
-
         bool isEnabled(QObject *obj) const override;
         bool isVisible(QObject *obj) const override;
         QRect mapGeometryToScene(const QObject *obj) const override;
+
+        QWindow * hostWindow(QObject *host) const override;
+        bool isHostSizeFixed(QObject *host) const override;
     };
 
 }
diff --git a/src/widgets/widgetitemdelegate.cpp b/src/widgets/widgetitemdelegate.cpp
index 08b3804..9d338c1 100644
--- a/src/widgets/widgetitemdelegate.cpp
+++ b/src/widgets/widgetitemdelegate.cpp
@@ -31,6 +31,14 @@
         return {originPoint, size};
     }
 
+    QWindow *WidgetItemDelegate::hostWindow(QObject *host) const {
+        return static_cast<QWidget *>(host)->windowHandle();
+    }
+
+    bool WidgetItemDelegate::isHostSizeFixed(QObject *host) const {
+        return false;
+    }
+
     bool WidgetItemDelegate::resetQtGrabbedControl() const {
         if (qt_button_down) {
             static constexpr const auto invalidPos = QPoint{-99999, -99999};
diff --git a/src/widgets/widgetitemdelegate_p.h b/src/widgets/widgetitemdelegate_p.h
index cc11c54..11d60fd 100644
--- a/src/widgets/widgetitemdelegate_p.h
+++ b/src/widgets/widgetitemdelegate_p.h
@@ -16,11 +16,13 @@
 
     public:
         QWindow *window(QObject *obj) const override;
-
         bool isEnabled(QObject *obj) const override;
         bool isVisible(QObject *obj) const override;
         QRect mapGeometryToScene(const QObject *obj) const override;
 
+        QWindow * hostWindow(QObject *host) const override;
+        bool isHostSizeFixed(QObject *host) const override;
+
         bool resetQtGrabbedControl() const override;
     };
 
diff --git a/src/widgets/widgetwindowagent.cpp b/src/widgets/widgetwindowagent.cpp
index 73a4334..6dd9015 100644
--- a/src/widgets/widgetwindowagent.cpp
+++ b/src/widgets/widgetwindowagent.cpp
@@ -33,7 +33,7 @@
         }
 
         std::ignore = w->winId(); // Make sure the window handle is created
-        if (!d->setup(w->windowHandle(), new WidgetItemDelegate())) {
+        if (!d->setup(w, new WidgetItemDelegate())) {
             return false;
         }
         d->hostWidget = w;

--
Gitblit v1.9.1