From 77bce901860548cd84c1680672ec75fbd6184cf8 Mon Sep 17 00:00:00 2001 From: Sine Striker <trueful@163.com> Date: 周四, 22 2月 2024 15:40:09 +0800 Subject: [PATCH] Add new winIdChange event filter --- src/core/contexts/win32windowcontext.cpp | 112 ++++++++++++++++++++++++-------------------------------- 1 files changed, 48 insertions(+), 64 deletions(-) diff --git a/src/core/contexts/win32windowcontext.cpp b/src/core/contexts/win32windowcontext.cpp index 64050b5..e0db522 100644 --- a/src/core/contexts/win32windowcontext.cpp +++ b/src/core/contexts/win32windowcontext.cpp @@ -1,3 +1,7 @@ +// Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) +// Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) +// SPDX-License-Identifier: Apache-2.0 + #include "win32windowcontext_p.h" #include <optional> @@ -92,18 +96,6 @@ monitorInfo.cbSize = sizeof(monitorInfo); ::GetMonitorInfoW(monitor, &monitorInfo); return monitorInfo; - } - - static inline void moveWindowToDesktopCenter(HWND hwnd) { - MONITORINFOEXW monitorInfo = getMonitorForWindow(hwnd); - RECT windowRect{}; - ::GetWindowRect(hwnd, &windowRect); - 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); } static inline void moveWindowToMonitor(HWND hwnd, const MONITORINFOEXW &activeMonitor) { @@ -329,7 +321,7 @@ case HTBORDER: return Win32WindowContext::FixedBorder; default: - // unreachable + Q_UNREACHABLE(); break; } return Win32WindowContext::Outside; @@ -548,8 +540,8 @@ } Win32WindowContext::~Win32WindowContext() { - if (windowId) { - removeManagedWindow(reinterpret_cast<HWND>(windowId)); + if (m_windowId) { + removeManagedWindow(reinterpret_cast<HWND>(m_windowId)); } } @@ -559,28 +551,20 @@ void Win32WindowContext::virtual_hook(int id, void *data) { switch (id) { - case CentralizeHook: { - if (!windowId) - return; - const auto hwnd = reinterpret_cast<HWND>(windowId); - moveWindowToDesktopCenter(hwnd); - return; - } - case RaiseWindowHook: { - if (!windowId) + if (!m_windowId) return; m_delegate->setWindowVisible(m_host, true); - const auto hwnd = reinterpret_cast<HWND>(windowId); + const auto hwnd = reinterpret_cast<HWND>(m_windowId); bringWindowToFront(hwnd); return; } case ShowSystemMenuHook: { - if (!windowId) + if (!m_windowId) return; const auto &pos = *static_cast<const QPoint *>(data); - auto hWnd = reinterpret_cast<HWND>(windowId); + auto hWnd = reinterpret_cast<HWND>(m_windowId); #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) const QPoint nativeGlobalPos = QHighDpi::toNativeGlobalPosition(pos, m_windowHandle); @@ -602,16 +586,16 @@ return; } - case DrawWindows10BorderHook: { #if QWINDOWKIT_CONFIG(ENABLE_WINDOWS_SYSTEM_BORDERS) - if (!windowId) + case DrawWindows10BorderHook: { + if (!m_windowId) return; auto args = static_cast<void **>(data); auto &painter = *static_cast<QPainter *>(args[0]); const auto &rect = *static_cast<const QRect *>(args[1]); const auto ®ion = *static_cast<const QRegion *>(args[2]); - const auto hwnd = reinterpret_cast<HWND>(windowId); + const auto hwnd = reinterpret_cast<HWND>(m_windowId); QPen pen; pen.setWidth(int(getWindowFrameBorderThickness(hwnd)) * 2); @@ -643,12 +627,10 @@ QPoint{m_windowHandle->width(), 0} }); painter.restore(); -#endif return; } case DrawWindows10BorderHook2: { -#if QWINDOWKIT_CONFIG(ENABLE_WINDOWS_SYSTEM_BORDERS) if (!m_windowHandle) return; @@ -656,7 +638,7 @@ // https://docs.microsoft.com/en-us/windows/win32/dwm/customframe#extending-the-client-frame // Draw a black rectangle to make Windows native top border show - auto hWnd = reinterpret_cast<HWND>(windowId); + auto hWnd = reinterpret_cast<HWND>(m_windowId); HDC hdc = ::GetDC(hWnd); RECT windowRect{}; ::GetClientRect(hWnd, &windowRect); @@ -669,9 +651,9 @@ ::FillRect(hdc, &rcTopBorder, reinterpret_cast<HBRUSH>(::GetStockObject(BLACK_BRUSH))); ::ReleaseDC(hWnd, hdc); -#endif return; } +#endif default: break; @@ -680,12 +662,12 @@ } QVariant Win32WindowContext::windowAttribute(const QString &key) const { - if (key == QStringLiteral("title-bar-rect")) { + if (key == QStringLiteral("window-rect")) { if (!m_windowHandle) return {}; RECT frame{}; - auto hwnd = reinterpret_cast<HWND>(windowId); + auto hwnd = reinterpret_cast<HWND>(m_windowId); // According to MSDN, WS_OVERLAPPED is not allowed for AdjustWindowRect. auto style = static_cast<DWORD>(::GetWindowLongPtrW(hwnd, GWL_STYLE) & ~WS_OVERLAPPED); auto exStyle = static_cast<DWORD>(::GetWindowLongPtrW(hwnd, GWL_EXSTYLE)); @@ -705,39 +687,36 @@ if (key == QStringLiteral("border-thickness")) { return m_windowHandle - ? int(getWindowFrameBorderThickness(reinterpret_cast<HWND>(windowId))) + ? int(getWindowFrameBorderThickness(reinterpret_cast<HWND>(m_windowId))) : 0; } return AbstractWindowContext::windowAttribute(key); } - void Win32WindowContext::winIdChanged() { + void Win32WindowContext::winIdChanged(WId winId, WId oldWinId) { // If the original window id is valid, remove all resources related - if (windowId) { - removeManagedWindow(reinterpret_cast<HWND>(windowId)); - windowId = 0; + if (oldWinId) { + removeManagedWindow(reinterpret_cast<HWND>(oldWinId)); } - if (!m_windowHandle) { + if (!m_windowHandle || ! winId) { return; } // Install window hook - auto winId = m_windowHandle->winId(); auto hWnd = reinterpret_cast<HWND>(winId); - if (!isSystemBorderEnabled()) { static auto margins = QVariant::fromValue(QMargins(1, 1, 1, 1)); // If we remove the system border, the window will lose its shadow. If dwm is enabled, - // then you need to set at least 1px margins, otherwise the following operation will + // then we need to set at least 1px margins, otherwise the following operation will // fail with no effect. setWindowAttribute(QStringLiteral("extra-margins"), margins); } // We should disable WS_SYSMENU, otherwise the system button icons will be visible if mica - // is enabled and the title bar is transparent + // is enabled and the title bar is transparent. { auto style = ::GetWindowLongPtrW(hWnd, GWL_STYLE); if (isSystemBorderEnabled()) { @@ -750,14 +729,15 @@ // Add managed window addManagedWindow(m_windowHandle, hWnd, this); - - // Cache win id - windowId = winId; } bool Win32WindowContext::windowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result) { *result = FALSE; + + if (message == WM_DESTROY) { + qDebug() << "WM_DESTROY"; + } // We should skip these messages otherwise we will get crashes. // NOTE: WM_QUIT won't be posted to the WindowProc function. @@ -775,6 +755,20 @@ if (!isValidWindow(hWnd, false, true)) { return false; + } + + switch (message) { + case WM_NCMOUSELEAVE: + qDebug() << "WM_NCMOUSELEAVE" << mouseLeaveBlocked; + break; + case WM_MOUSEHOVER: + qDebug() << "WM_MOUSEHOVER" << mouseLeaveBlocked; + break; + case WM_NCMOUSEHOVER: + qDebug() << "WM_NCMOUSEHOVER" << mouseLeaveBlocked; + break; + default: + break; } // Test snap layout @@ -812,7 +806,7 @@ const QVariant &oldAttribute) { Q_UNUSED(oldAttribute) - const auto hwnd = reinterpret_cast<HWND>(m_windowHandle->winId()); + const auto hwnd = reinterpret_cast<HWND>(m_windowId); const DynamicApis &apis = DynamicApis::instance(); static constexpr const MARGINS extendedMargins = {-1, -1, -1, -1}; const auto &restoreMargins = [this, &apis, hwnd]() { @@ -1162,6 +1156,8 @@ } } mouseLeaveBlocked = false; + + qDebug() << "WM_MOUSELEAVE"; break; } @@ -1170,6 +1166,7 @@ // we unset `mouseLeaveBlocked` mark and pretend as if Qt has received // WM_MOUSELEAVE. if (lastHitTestResult != WindowPart::ChromeButton && mouseLeaveBlocked) { + qDebug() << lastHitTestResult << "Track"; mouseLeaveBlocked = false; requestForMouseLeaveMessage(hWnd, false); } @@ -1258,7 +1255,7 @@ // If the mouse is entering the client area, there must be a WM_NCHITTEST // setting it to `Client` before the WM_NCMOUSELEAVE comes; if the mouse is // leaving the window, current window part remains as `Outside`. - lastHitTestResult = WindowPart::Outside; + // lastHitTestResult = WindowPart::Outside; } if (currentWindowPart == WindowPart::ChromeButton) { @@ -1324,19 +1321,6 @@ bool Win32WindowContext::customWindowHandler(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result) { switch (message) { - case WM_SHOWWINDOW: { - if (!initialCentered) { - // 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) { - initialCentered = true; - moveWindowToDesktopCenter(hWnd); - } - } - break; - } - case WM_NCHITTEST: { // 鍘熺敓Win32绐楀彛鍙湁椤惰竟鏄湪绐楀彛鍐呴儴resize鐨勶紝鍏朵綑涓夎竟閮芥槸鍦ㄧ獥鍙� // 澶栭儴杩涜resize鐨勶紝鍏跺師鐞嗘槸锛學S_THICKFRAME杩欎釜绐楀彛鏍峰紡浼氬湪绐� -- Gitblit v1.9.1