From d3d7430ec9afb94abaf78fa2c9edd9d9f946881c Mon Sep 17 00:00:00 2001
From: Sine Striker <trueful@163.com>
Date: 周一, 18 12月 2023 01:29:07 +0800
Subject: [PATCH] Add QtContext WinIdChange workaround

---
 src/core/contexts/abstractwindowcontext.cpp |    9 +++++----
 src/core/contexts/win32windowcontext_p.h    |    2 +-
 src/core/contexts/cocoawindowcontext.mm     |    4 ++--
 examples/mainwindow/main.cpp                |    1 -
 src/core/contexts/abstractwindowcontext_p.h |    3 +--
 src/core/contexts/cocoawindowcontext_p.h    |    2 ++
 src/core/contexts/qtwindowcontext.cpp       |   11 ++++++-----
 README.md                                   |    2 +-
 src/core/contexts/qtwindowcontext_p.h       |    5 ++++-
 src/core/contexts/win32windowcontext.cpp    |   13 ++++---------
 10 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/README.md b/README.md
index a13178a..760f6f0 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@
 + Fix `isFixedSize` code
 + Support customized system button area on Mac
 + Make Linux system move/resize more robust
-+ Fix unhandled WinIdChange when adding a QWebEngineView as sub-widget
++ Fix unhandled WinIdChange when adding a QWebEngineView as sub-widget (Win32 and Qt fixed)
 
 ## Supported Platforms
 
diff --git a/examples/mainwindow/main.cpp b/examples/mainwindow/main.cpp
index 8bbaab3..b0c9d25 100644
--- a/examples/mainwindow/main.cpp
+++ b/examples/mainwindow/main.cpp
@@ -7,7 +7,6 @@
 int main(int argc, char *argv[]) {
     qputenv("QT_WIN_DEBUG_CONSOLE", "1");
     qputenv("QSG_INFO", "1");
-    qputenv("QT_WIDGETS_HIGHDPI_DOWNSCALE", "1");
 #if 0
     qputenv("QT_WIDGETS_RHI", "1");
     qputenv("QSG_RHI_BACKEND", "d3d12");
diff --git a/src/core/contexts/abstractwindowcontext.cpp b/src/core/contexts/abstractwindowcontext.cpp
index d69ab75..ef1efbf 100644
--- a/src/core/contexts/abstractwindowcontext.cpp
+++ b/src/core/contexts/abstractwindowcontext.cpp
@@ -19,8 +19,7 @@
         m_delegate.reset(delegate);
         m_windowHandle = m_delegate->hostWindow(m_host);
         if (m_windowHandle) {
-            m_windowHandleGuard = m_windowHandle;
-            winIdChanged(nullptr, false);
+            winIdChanged(nullptr);
         }
     }
 
@@ -176,7 +175,9 @@
     void AbstractWindowContext::notifyWinIdChange() {
         auto oldWindow = m_windowHandle;
         m_windowHandle = m_delegate->window(m_host);
-        winIdChanged(oldWindow, oldWindow && m_windowHandleGuard.isNull());
+        if (oldWindow == m_windowHandle)
+            return;
+        winIdChanged(oldWindow);
     }
 
-}
\ No newline at end of file
+}
diff --git a/src/core/contexts/abstractwindowcontext_p.h b/src/core/contexts/abstractwindowcontext_p.h
index 29f6749..3938d75 100644
--- a/src/core/contexts/abstractwindowcontext_p.h
+++ b/src/core/contexts/abstractwindowcontext_p.h
@@ -60,13 +60,12 @@
         void notifyWinIdChange();
 
     protected:
-        virtual void winIdChanged(QWindow *oldWindow, bool destroyed) = 0;
+        virtual void winIdChanged(QWindow *oldWindow) = 0;
 
     protected:
         QObject *m_host{};
         std::unique_ptr<WindowItemDelegate> m_delegate;
         QWindow *m_windowHandle{};
-        QPointer<QWindow> m_windowHandleGuard;
 
         QSet<const QObject *> m_hitTestVisibleItems;
 #ifdef Q_OS_MAC
diff --git a/src/core/contexts/cocoawindowcontext.mm b/src/core/contexts/cocoawindowcontext.mm
index a12be53..edd2c3a 100644
--- a/src/core/contexts/cocoawindowcontext.mm
+++ b/src/core/contexts/cocoawindowcontext.mm
@@ -390,10 +390,10 @@
         AbstractWindowContext::virtual_hook(id, data);
     }
 
-    bool CocoaWindowContext::winIdChanged(QWindow *oldWindow) {
+    void CocoaWindowContext::winIdChanged(QWindow *oldWindow, bool destroyed) {
         windowId = m_windowHandle->winId();
         ensureWindowProxy(windowId)->setSystemTitleBarVisible(false);
-        std::ignore = new CocoaWindowEventFilter(this, this);
+        cocoaWindowEventFilter = std::make_unique<CocoaWindowEventFilter>(this, this);
         return true;
     }
 
diff --git a/src/core/contexts/cocoawindowcontext_p.h b/src/core/contexts/cocoawindowcontext_p.h
index c257adf..c6c8e13 100644
--- a/src/core/contexts/cocoawindowcontext_p.h
+++ b/src/core/contexts/cocoawindowcontext_p.h
@@ -19,6 +19,8 @@
 
     protected:
         WId windowId = 0;
+
+        std::unique_ptr<QObject> cocoaWindowEventFilter;
     };
 
 }
diff --git a/src/core/contexts/qtwindowcontext.cpp b/src/core/contexts/qtwindowcontext.cpp
index 45aed07..35fc2d1 100644
--- a/src/core/contexts/qtwindowcontext.cpp
+++ b/src/core/contexts/qtwindowcontext.cpp
@@ -253,10 +253,11 @@
         AbstractWindowContext::virtual_hook(id, data);
     }
 
-    bool QtWindowContext::winIdChanged() {
-        m_delegate->setWindowFlags(m_host, Qt::FramelessWindowHint);
-        std::ignore = new QtWindowEventFilter(this, this);
-        return true;
+    void QtWindowContext::winIdChanged(QWindow *oldWindow) {
+        Q_UNUSED(oldWindow)
+        m_delegate->setWindowFlags(m_host,
+                                   m_delegate->getWindowFlags(m_host) | Qt::FramelessWindowHint);
+        qtWindowEventFilter = std::make_unique<QtWindowEventFilter>(this);
     }
 
-}
\ No newline at end of file
+}
diff --git a/src/core/contexts/qtwindowcontext_p.h b/src/core/contexts/qtwindowcontext_p.h
index ff62b4a..dc19f0a 100644
--- a/src/core/contexts/qtwindowcontext_p.h
+++ b/src/core/contexts/qtwindowcontext_p.h
@@ -15,7 +15,10 @@
         void virtual_hook(int id, void *data) override;
 
     protected:
-        bool winIdChanged() override;
+        void winIdChanged(QWindow *oldWindow) override;
+
+    protected:
+        std::unique_ptr<QObject> qtWindowEventFilter;
     };
 
 }
diff --git a/src/core/contexts/win32windowcontext.cpp b/src/core/contexts/win32windowcontext.cpp
index 2cfd8b1..cda9058 100644
--- a/src/core/contexts/win32windowcontext.cpp
+++ b/src/core/contexts/win32windowcontext.cpp
@@ -780,7 +780,7 @@
         g_wndProcHash->insert(hWnd, ctx);
     }
 
-    static inline void removeManagedWindow(HWND hWnd, bool restore) {
+    static inline void removeManagedWindow(HWND hWnd) {
         // Remove window handle mapping
         if (!g_wndProcHash->remove(hWnd))
             return;
@@ -789,11 +789,6 @@
         if (g_wndProcHash->empty()) {
             WindowsNativeEventFilter::uninstall();
         }
-
-        // Restore window proc
-        if (restore) {
-            ::SetWindowLongPtrW(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(g_qtWindowProc));
-        }
     }
 
     Win32WindowContext::Win32WindowContext() : AbstractWindowContext() {
@@ -801,7 +796,7 @@
 
     Win32WindowContext::~Win32WindowContext() {
         if (windowId) {
-            removeManagedWindow(reinterpret_cast<HWND>(windowId), false);
+            removeManagedWindow(reinterpret_cast<HWND>(windowId));
         }
     }
 
@@ -897,9 +892,9 @@
         return getWindowFrameBorderThickness(reinterpret_cast<HWND>(windowId));
     }
 
-    void Win32WindowContext::winIdChanged(QWindow *oldWindow, bool destroyed) {
+    void Win32WindowContext::winIdChanged(QWindow *oldWindow) {
         if (oldWindow) {
-            removeManagedWindow(reinterpret_cast<HWND>(windowId), !destroyed);
+            removeManagedWindow(reinterpret_cast<HWND>(windowId));
         }
 
         if (!m_windowHandle) {
diff --git a/src/core/contexts/win32windowcontext_p.h b/src/core/contexts/win32windowcontext_p.h
index 3d2649e..c8c7ed4 100644
--- a/src/core/contexts/win32windowcontext_p.h
+++ b/src/core/contexts/win32windowcontext_p.h
@@ -30,7 +30,7 @@
         int borderThickness() const;
 
     protected:
-        void winIdChanged(QWindow *oldWindow, bool destroyed) override;
+        void winIdChanged(QWindow *oldWindow) override;
 
     public:
         bool windowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result);

--
Gitblit v1.9.1