From 59690b8ab4f3e4c2cea0467f40e858080943dd62 Mon Sep 17 00:00:00 2001
From: Zhao Yuhang <2546789017@qq.com>
Date: 摹曛, 14 12月 2023 20:45:33 +0800
Subject: [PATCH] tweak

---
 src/core/contexts/win32windowcontext.cpp |  146 +++++++++++++++++++++++-------------------------
 1 files changed, 71 insertions(+), 75 deletions(-)

diff --git a/src/core/contexts/win32windowcontext.cpp b/src/core/contexts/win32windowcontext.cpp
index 297c39c..0f7b6f7 100644
--- a/src/core/contexts/win32windowcontext.cpp
+++ b/src/core/contexts/win32windowcontext.cpp
@@ -4,6 +4,7 @@
 
 #include <QtCore/QHash>
 #include <QtCore/QScopeGuard>
+#include <QtCore/QTimer>
 #include <QtGui/QGuiApplication>
 #include <QtGui/QPainter>
 #include <QtGui/QPalette>
@@ -26,7 +27,6 @@
 #include <dwmapi.h>
 #include <timeapi.h>
 
-#include "nativeeventfilter.h"
 #include "qwkglobal_p.h"
 
 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
@@ -83,7 +83,7 @@
     // ### FIXME: Tell the user to call in the documentation, instead of automatically
     // calling it directly.
     // ### FIXME FIXME FIXME
-    static struct QWK_Hook {
+    static const struct QWK_Hook {
         QWK_Hook() {
             qApp->setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
         }
@@ -357,44 +357,37 @@
         }
     }
 
-    static inline quint32 getWindowFrameBorderThickness(HWND hwnd) {
-        UINT result = 0;
+    static inline quint32 getSystemMetricsForDpi(int index, quint32 dpi) {
         const DynamicApis &apis = DynamicApis::instance();
-        if (SUCCEEDED(apis.pDwmGetWindowAttribute(hwnd, _DWMWA_VISIBLE_FRAME_BORDER_THICKNESS,
-                                                  &result, sizeof(result)))) {
-            return result;
-        } else {
-            const quint32 dpi = getDpiForWindow(hwnd);
-            result = quint32(std::round(qreal(1) * qreal(dpi) / qreal(USER_DEFAULT_SCREEN_DPI)));
+        if (apis.pGetSystemMetricsForDpi) {
+            return ::GetSystemMetricsForDpi(index, dpi);
+        }
+        return ::GetSystemMetrics(index);
+    }
+
+    static inline quint32 getWindowFrameBorderThickness(HWND hwnd) {
+        const DynamicApis &apis = DynamicApis::instance();
+        if (UINT result = 0; SUCCEEDED(apis.pDwmGetWindowAttribute(
+                hwnd, _DWMWA_VISIBLE_FRAME_BORDER_THICKNESS, &result, sizeof(result)))) {
             return result;
         }
+        return getSystemMetricsForDpi(SM_CXBORDER, getDpiForWindow(hwnd));
     }
 
     static inline quint32 getResizeBorderThickness(HWND hwnd) {
-        const DynamicApis &apis = DynamicApis::instance();
-        if (apis.pGetSystemMetricsForDpi) {
-            const quint32 dpi = getDpiForWindow(hwnd);
-            return apis.pGetSystemMetricsForDpi(SM_CXSIZEFRAME, dpi) +
-                   apis.pGetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi);
-        } else {
-            return ::GetSystemMetrics(SM_CXSIZEFRAME) + ::GetSystemMetrics(SM_CXPADDEDBORDER);
-        }
+        const quint32 dpi = getDpiForWindow(hwnd);
+        return getSystemMetricsForDpi(SM_CXSIZEFRAME, dpi) +
+               getSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi);
     }
 
     static inline quint32 getTitleBarHeight(HWND hwnd) {
-        const auto captionHeight = [hwnd]() -> int {
-            const DynamicApis &apis = DynamicApis::instance();
-            if (apis.pGetSystemMetricsForDpi) {
-                const quint32 dpi = getDpiForWindow(hwnd);
-                return apis.pGetSystemMetricsForDpi(SM_CYCAPTION, dpi);
-            } else {
-                return ::GetSystemMetrics(SM_CYCAPTION);
-            }
-        }();
-        return captionHeight + getResizeBorderThickness(hwnd);
+        const quint32 dpi = getDpiForWindow(hwnd);
+        return getSystemMetricsForDpi(SM_CYCAPTION, dpi) +
+               getSystemMetricsForDpi(SM_CXSIZEFRAME, dpi) +
+               getSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi);
     }
 
-    static inline void updateInternalWindowFrameMargins(HWND hwnd, QWindow *window) {
+    static void updateInternalWindowFrameMargins(HWND hwnd, QWindow *window) {
         const auto margins = [hwnd]() -> QMargins {
             const auto titleBarHeight = int(getTitleBarHeight(hwnd));
             if (isWin10OrGreater()) {
@@ -435,8 +428,8 @@
         const auto monitorInfo = getMonitorForWindow(hwnd);
         RECT windowRect{};
         ::GetWindowRect(hwnd, &windowRect);
-        const auto newX = (RECT_WIDTH(monitorInfo.rcMonitor) - RECT_WIDTH(windowRect)) / 2;
-        const auto newY = (RECT_HEIGHT(monitorInfo.rcMonitor) - RECT_HEIGHT(windowRect)) / 2;
+        const auto newX = monitorInfo.rcMonitor.left + (RECT_WIDTH(monitorInfo.rcMonitor) - RECT_WIDTH(windowRect)) / 2;
+        const auto newY = monitorInfo.rcMonitor.top + (RECT_HEIGHT(monitorInfo.rcMonitor) - RECT_HEIGHT(windowRect)) / 2;
         ::SetWindowPos(hwnd, nullptr, newX, newY, 0, 0,
                        SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
     }
@@ -455,12 +448,15 @@
         ::GetWindowPlacement(hwnd, &wp);
         return ((wp.showCmd == SW_NORMAL) || (wp.showCmd == SW_RESTORE));
 #else
+        if (isFullScreen(hwnd)) {
+            return false;
+        }
         const auto style = static_cast<DWORD>(::GetWindowLongPtrW(hwnd, GWL_STYLE));
         return (!(style & (WS_MINIMIZE | WS_MAXIMIZE)));
 #endif
     }
 
-    static inline void syncPaintEventWithDwm() {
+    static void syncPaintEventWithDwm() {
         // No need to sync with DWM if DWM composition is disabled.
         if (!isDwmCompositionEnabled()) {
             return;
@@ -505,9 +501,9 @@
         apis.ptimeEndPeriod(ms_granularity);
     }
 
-    static inline void showSystemMenu2(HWND hWnd, const POINT &pos, const bool selectFirstEntry,
-                                       const bool fixedSize) {
-        const HMENU hMenu = ::GetSystemMenu(hWnd, FALSE);
+    static void showSystemMenu2(HWND hWnd, const POINT &pos, const bool selectFirstEntry,
+                                const bool fixedSize) {
+        HMENU hMenu = ::GetSystemMenu(hWnd, FALSE);
         if (!hMenu) {
             // The corresponding window doesn't have a system menu, most likely due to the
             // lack of the "WS_SYSMENU" window style. This situation should not be treated
@@ -641,7 +637,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 {
@@ -804,40 +800,22 @@
             case ShowSystemMenuHook: {
                 const auto &pos = *static_cast<const QPoint *>(data);
                 auto hWnd = reinterpret_cast<HWND>(m_windowHandle->winId());
-                showSystemMenu2(hWnd, qpoint2point(pos), false,
+                showSystemMenu2(hWnd, qpoint2point(QHighDpi::toNativeGlobalPosition(pos, m_windowHandle)), false,
                                 m_delegate->isHostSizeFixed(m_host));
                 return;
             }
 
-            case NeedsDrawBordersHook: {
-                auto &result = *static_cast<bool *>(data);
-                result = isWin10OrGreater() && !isWin11OrGreater();
+            case DefaultColorsHook: {
+                auto &map = *static_cast<QMap<QString, QColor> *>(data);
+                map.clear();
+                map.insert(QStringLiteral("activeLight"), kWindowsColorSet.activeLight);
+                map.insert(QStringLiteral("activeDark"), kWindowsColorSet.activeDark);
+                map.insert(QStringLiteral("inactiveLight"), kWindowsColorSet.inactiveLight);
+                map.insert(QStringLiteral("inactiveDark"), kWindowsColorSet.inactiveDark);
                 return;
             }
 
-            case BorderThicknessHook: {
-                auto args = static_cast<void **>(data);
-                const bool requireNative = *static_cast<const bool *>(args[0]);
-                quint32 &thickness = *static_cast<quint32 *>(args[1]);
-                const auto hwnd = reinterpret_cast<HWND>(m_windowHandle->winId());
-                const auto nativeThickness = getWindowFrameBorderThickness(hwnd);
-                thickness = requireNative
-                                ? nativeThickness
-                                : QHighDpi::fromNativePixels(nativeThickness, m_windowHandle);
-                return;
-            }
-
-            case BorderColorsHook: {
-                auto arr = *reinterpret_cast<QList<QColor> *>(data);
-                arr.clear();
-                arr.push_back(kWindowsColorSet.activeLight);
-                arr.push_back(kWindowsColorSet.activeDark);
-                arr.push_back(kWindowsColorSet.inactiveLight);
-                arr.push_back(kWindowsColorSet.inactiveDark);
-                return;
-            }
-
-            case DrawBordersHook: {
+            case DrawWindows10BorderHook: {
                 auto args = static_cast<void **>(data);
                 auto &painter = *static_cast<QPainter *>(args[0]);
                 const auto &rect = *static_cast<const QRect *>(args[1]);
@@ -845,13 +823,10 @@
                 const auto hwnd = reinterpret_cast<HWND>(m_windowHandle->winId());
 
                 QPen pen;
-                const auto borderThickness = int(QHighDpi::fromNativePixels(
-                    getWindowFrameBorderThickness(hwnd), m_windowHandle));
-                pen.setWidth(borderThickness * 2);
-                const bool active = m_delegate->isWindowActive(m_host);
-                const bool dark = isDarkThemeActive() && isDarkWindowFrameEnabled(hwnd);
+                pen.setWidth(getWindowFrameBorderThickness(hwnd) * 2);
 
-                if (active) {
+                const bool dark = isDarkThemeActive() && isDarkWindowFrameEnabled(hwnd);
+                if (m_delegate->isWindowActive(m_host)) {
                     if (isWindowFrameBorderColorized()) {
                         pen.setColor(getAccentColor());
                     } else {
@@ -868,13 +843,13 @@
                 }
                 painter.save();
 
-                // ### TODO: do we need to enable or disable it?
+                // We needs anti-aliasing to give us better result.
                 painter.setRenderHint(QPainter::Antialiasing);
 
                 painter.setPen(pen);
                 painter.drawLine(QLine{
-                    QPoint{0,            0},
-                    QPoint{rect.width(), 0}
+                    QPoint{0,                       0},
+                    QPoint{m_windowHandle->width(), 0}
                 });
                 painter.restore();
                 return;
@@ -886,6 +861,14 @@
             }
         }
         AbstractWindowContext::virtual_hook(id, data);
+    }
+
+    bool Win32WindowContext::needBorderPainter() const {
+        return isWin10OrGreater() && !isWin11OrGreater();
+    }
+
+    int Win32WindowContext::borderThickness() const {
+        return getWindowFrameBorderThickness(reinterpret_cast<HWND>(windowId));
     }
 
     bool Win32WindowContext::setupHost() {
@@ -953,12 +936,25 @@
             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
     }
 
     QWK_USED static constexpr const struct {
-        const WPARAM wParam = 0xF1C9ADD4;
-        const LPARAM lParam = 0xAFB6F4C6;
+        const WPARAM wParam = MAKEWPARAM(44500, 61897);
+        const LPARAM lParam = MAKELPARAM(62662, 44982); // Not used. Reserve for future use.
     } kMessageTag;
 
     static inline quint64 getKeyState() {
@@ -1243,7 +1239,7 @@
                     // If wParam is TRUE, the window is being shown.
                     // If lParam is zero, the message was sent because of a call to the ShowWindow
                     // function.
-                    if (wParam && lParam == 0) {
+                    if (wParam && !lParam) {
                         centered = true;
                         moveToDesktopCenter(hWnd);
                     }

--
Gitblit v1.9.1