From eda513356b8eb58b3069ddceb8c3dbc63c7fcdcd Mon Sep 17 00:00:00 2001 From: Sine Striker <trueful@163.com> Date: 周日, 17 12月 2023 15:58:49 +0800 Subject: [PATCH] Update resources --- src/core/contexts/win32windowcontext.cpp | 109 +++++++++++++++++++++++++++++++----------------------- 1 files changed, 63 insertions(+), 46 deletions(-) diff --git a/src/core/contexts/win32windowcontext.cpp b/src/core/contexts/win32windowcontext.cpp index d6e361a..11b5327 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); } @@ -114,6 +114,7 @@ DYNAMIC_API_DECLARE(DwmIsCompositionEnabled); DYNAMIC_API_DECLARE(DwmGetCompositionTimingInfo); DYNAMIC_API_DECLARE(DwmGetWindowAttribute); + DYNAMIC_API_DECLARE(DwmSetWindowAttribute); DYNAMIC_API_DECLARE(GetDpiForWindow); DYNAMIC_API_DECLARE(GetSystemMetricsForDpi); DYNAMIC_API_DECLARE(GetDpiForMonitor); @@ -140,6 +141,7 @@ DYNAMIC_API_RESOLVE(dwmapi, DwmIsCompositionEnabled); DYNAMIC_API_RESOLVE(dwmapi, DwmGetCompositionTimingInfo); DYNAMIC_API_RESOLVE(dwmapi, DwmGetWindowAttribute); + DYNAMIC_API_RESOLVE(dwmapi, DwmSetWindowAttribute); QSystemLibrary winmm(QStringLiteral("winmm")); DYNAMIC_API_RESOLVE(winmm, timeGetDevCaps); @@ -428,8 +430,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); } @@ -448,6 +450,9 @@ ::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 @@ -634,7 +639,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 { @@ -797,40 +802,27 @@ case ShowSystemMenuHook: { const auto &pos = *static_cast<const QPoint *>(data); auto hWnd = reinterpret_cast<HWND>(m_windowHandle->winId()); - showSystemMenu2(hWnd, qpoint2point(pos), false, +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + const QPoint nativeGlobalPos = QHighDpi::toNativeGlobalPosition(pos, m_windowHandle); +#else + const QPoint nativeGlobalPos = QHighDpi::toNativePixels(pos, m_windowHandle); +#endif + showSystemMenu2(hWnd, qpoint2point(nativeGlobalPos), 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]); @@ -838,13 +830,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 { @@ -861,13 +850,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; @@ -881,10 +870,25 @@ 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() { // Install window hook auto winId = m_windowHandle->winId(); auto hWnd = reinterpret_cast<HWND>(winId); + +#if QT_VERSION < QT_VERSION_CHECK(6, 5, 0) + for (const auto attr : { _DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1, _DWMWA_USE_IMMERSIVE_DARK_MODE }) { + const BOOL enable = TRUE; + DynamicApis::instance().pDwmSetWindowAttribute(hWnd, attr, &enable, sizeof(enable)); + } +#endif // Inform Qt we want and have set custom margins updateInternalWindowFrameMargins(hWnd, m_windowHandle); @@ -946,12 +950,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() { @@ -1154,7 +1171,7 @@ const WindowPart currentWindowPart = lastHitTestResult; if (message == WM_NCMOUSEMOVE) { if (currentWindowPart != WindowPart::ChromeButton) { - m_delegate->resetQtGrabbedControl(); + m_delegate->resetQtGrabbedControl(m_host); if (mouseLeaveBlocked) { emulateClientAreaMessage(hWnd, message, wParam, lParam, WM_NCMOUSELEAVE); @@ -1216,7 +1233,7 @@ // window from client area, which means we will get previous window part as // HTCLIENT if the mouse leaves window from client area and enters window // from non-client area, but it has no bad effect. - m_delegate->resetQtGrabbedControl(); + m_delegate->resetQtGrabbedControl(m_host); } } break; @@ -1236,7 +1253,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