diff --git a/CMakeLists.txt b/CMakeLists.txt index bd0805f..e66e8c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,8 @@ project(FramelessHelper LANGUAGES CXX) option(BUILD_EXAMPLES "Build examples." ON) option(TEST_UNIX "Test UNIX version (from Win32)." OFF) +set(BUILD_SHARED_LIBS ON) + set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) @@ -15,34 +17,6 @@ set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) -if(NOT DEFINED CMAKE_DEBUG_POSTFIX) - if(WIN32) - set(CMAKE_DEBUG_POSTFIX d) - else() - set(CMAKE_DEBUG_POSTFIX _debug) - endif() -endif() - -if(NOT DEFINED CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE Release) -endif() - -if(NOT (CMAKE_BUILD_TYPE STREQUAL "Debug") AND BUILD_SHARED_LIBS) - set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON) -endif() - -if(NOT DEFINED CMAKE_RUNTIME_OUTPUT_DIRECTORY) - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) -endif() - -if(NOT DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY) - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) -endif() - -if(NOT DEFINED CMAKE_ARCHIVE_OUTPUT_DIRECTORY) - set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) -endif() - find_package(QT NAMES Qt6 Qt5 COMPONENTS Gui REQUIRED) find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Gui REQUIRED) find_package(QT NAMES Qt6 Qt5 COMPONENTS Quick) @@ -94,16 +68,6 @@ if(NOT BUILD_SHARED_LIBS) ) endif() -if(MSVC) - target_compile_options(${PROJECT_NAME} PRIVATE /utf-8 /permissive-) - if(CMAKE_BUILD_TYPE STREQUAL "Debug") - target_compile_options(${PROJECT_NAME} PRIVATE /JMC) - else() - target_compile_options(${PROJECT_NAME} PRIVATE /guard:cf) - target_link_options(${PROJECT_NAME} PRIVATE /GUARD:CF) - endif() -endif() - target_compile_definitions(${PROJECT_NAME} PRIVATE QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII diff --git a/examples/mainwindow/CMakeLists.txt b/examples/mainwindow/CMakeLists.txt index a5ffebc..f7870c6 100644 --- a/examples/mainwindow/CMakeLists.txt +++ b/examples/mainwindow/CMakeLists.txt @@ -36,16 +36,6 @@ target_compile_definitions(MainWindow PRIVATE QT_DISABLE_DEPRECATED_BEFORE=0x060100 ) -if(MSVC) - target_compile_options(MainWindow PRIVATE /utf-8 /permissive-) - if(CMAKE_BUILD_TYPE STREQUAL "Debug") - target_compile_options(MainWindow PRIVATE /JMC) - else() - target_compile_options(MainWindow PRIVATE /guard:cf) - target_link_options(MainWindow PRIVATE /GUARD:CF) - endif() -endif() - if(WIN32) target_link_libraries(MainWindow PRIVATE dwmapi) endif() diff --git a/examples/quick/CMakeLists.txt b/examples/quick/CMakeLists.txt index 2e33ab2..4e85d0a 100644 --- a/examples/quick/CMakeLists.txt +++ b/examples/quick/CMakeLists.txt @@ -34,16 +34,6 @@ target_compile_definitions(Quick PRIVATE QT_DISABLE_DEPRECATED_BEFORE=0x060100 ) -if(MSVC) - target_compile_options(Quick PRIVATE /utf-8 /permissive-) - if(CMAKE_BUILD_TYPE STREQUAL "Debug") - target_compile_options(Quick PRIVATE /JMC) - else() - target_compile_options(Quick PRIVATE /guard:cf) - target_link_options(Quick PRIVATE /GUARD:CF) - endif() -endif() - if(WIN32) target_link_libraries(Quick PRIVATE dwmapi) endif() diff --git a/examples/widget/CMakeLists.txt b/examples/widget/CMakeLists.txt index 5b83d9e..83e847b 100644 --- a/examples/widget/CMakeLists.txt +++ b/examples/widget/CMakeLists.txt @@ -34,16 +34,6 @@ target_compile_definitions(Widget PRIVATE QT_DISABLE_DEPRECATED_BEFORE=0x060100 ) -if(MSVC) - target_compile_options(Widget PRIVATE /utf-8 /permissive-) - if(CMAKE_BUILD_TYPE STREQUAL "Debug") - target_compile_options(Widget PRIVATE /JMC) - else() - target_compile_options(Widget PRIVATE /guard:cf) - target_link_options(Widget PRIVATE /GUARD:CF) - endif() -endif() - if(WIN32) target_link_libraries(Widget PRIVATE dwmapi) endif() diff --git a/examples/widget/widget.cpp b/examples/widget/widget.cpp index 2aed980..4bca9da 100644 --- a/examples/widget/widget.cpp +++ b/examples/widget/widget.cpp @@ -23,11 +23,12 @@ */ #include "widget.h" +#include +#include +#include #include #include -#include #include -#include #include "../../utilities.h" #include "../../framelesswindowsmanager.h" @@ -315,10 +316,13 @@ bool Widget::nativeEvent(const QByteArray &eventType, void *message, long *resul if (Utilities::isThemeChanged(message)) { updateStyleSheet(); updateSystemButtonIcons(); + return true; } QPointF pos = {}; if (Utilities::isSystemMenuRequested(message, &pos)) { - if (!Utilities::showSystemMenu(winId(), pos)) { + if (Utilities::showSystemMenu(winId(), pos)) { + return true; + } else { qWarning() << "Failed to display the system menu."; } } diff --git a/framelesshelper_win32.cpp b/framelesshelper_win32.cpp index 1b5d329..3920718 100644 --- a/framelesshelper_win32.cpp +++ b/framelesshelper_win32.cpp @@ -313,13 +313,11 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me monitorInfo.cbSize = sizeof(monitorInfo); const HMONITOR monitor = MonitorFromWindow(msg->hwnd, MONITOR_DEFAULTTONEAREST); if (!monitor) { - const HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); - qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("MonitorFromWindow"), hr); + qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("MonitorFromWindow")); break; } if (GetMonitorInfoW(monitor, &monitorInfo) == FALSE) { - const HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); - qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("GetMonitorInfoW"), hr); + qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("GetMonitorInfoW")); break; } // This helper can be used to determine if there's a @@ -349,14 +347,12 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me if (_abd.hWnd) { const HMONITOR windowMonitor = MonitorFromWindow(msg->hwnd, MONITOR_DEFAULTTONEAREST); if (!windowMonitor) { - const HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); - qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("MonitorFromWindow"), hr); + qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("MonitorFromWindow")); break; } const HMONITOR taskbarMonitor = MonitorFromWindow(_abd.hWnd, MONITOR_DEFAULTTOPRIMARY); if (!taskbarMonitor) { - const HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); - qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("MonitorFromWindow"), hr); + qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("MonitorFromWindow")); break; } if (taskbarMonitor == windowMonitor) { @@ -545,15 +541,13 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me POINT winLocalMouse = {GET_X_LPARAM(msg->lParam), GET_Y_LPARAM(msg->lParam)}; if (ScreenToClient(msg->hwnd, &winLocalMouse) == FALSE) { - const HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); - qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("ScreenToClient"), hr); + qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("ScreenToClient")); break; } const QPointF localMouse = {static_cast(winLocalMouse.x), static_cast(winLocalMouse.y)}; RECT clientRect = {0, 0, 0, 0}; if (GetClientRect(msg->hwnd, &clientRect) == FALSE) { - const HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); - qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("GetClientRect"), hr); + qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("GetClientRect")); break; } const LONG windowWidth = clientRect.right; @@ -653,27 +647,24 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me // Disable painting while these messages are handled to prevent them // from drawing a window caption over the client area. - const auto oldStyle = GetWindowLongPtrW(msg->hwnd, GWL_STYLE); + const LONG_PTR oldStyle = GetWindowLongPtrW(msg->hwnd, GWL_STYLE); // Prevent Windows from drawing the default title bar by temporarily // toggling the WS_VISIBLE style. - if (SetWindowLongPtrW(msg->hwnd, GWL_STYLE, oldStyle & ~WS_VISIBLE) == 0) { - const HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); - qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("SetWindowLongPtrW"), hr); + if (SetWindowLongPtrW(msg->hwnd, GWL_STYLE, static_cast(oldStyle & ~WS_VISIBLE)) == 0) { + qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("SetWindowLongPtrW")); break; } const auto winId = reinterpret_cast(msg->hwnd); Utilities::triggerFrameChange(winId); const LRESULT ret = DefWindowProcW(msg->hwnd, msg->message, msg->wParam, msg->lParam); if (SetWindowLongPtrW(msg->hwnd, GWL_STYLE, oldStyle) == 0) { - const HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); - qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("SetWindowLongPtrW"), hr); + qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("SetWindowLongPtrW")); break; } Utilities::triggerFrameChange(winId); *result = ret; return true; } -#if 0 case WM_SIZE: { const bool normal = (msg->wParam == SIZE_RESTORED); const bool max = (msg->wParam == SIZE_MAXIMIZED); @@ -683,7 +674,6 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me Utilities::updateQtFrameMargins(const_cast(window), true); } } break; -#endif default: break; } diff --git a/framelesshelper_windows.h b/framelesshelper_windows.h index 60ea894..d9eb80b 100644 --- a/framelesshelper_windows.h +++ b/framelesshelper_windows.h @@ -105,18 +105,13 @@ #define IsMaximized(window) (IsZoomed(window) != FALSE) #endif -constexpr int kAutoHideTaskbarThickness = 2; // The thickness of an auto-hide taskbar in pixels +[[maybe_unused]] constexpr int kAutoHideTaskbarThickness = 2; // The thickness of an auto-hide taskbar in pixels -constexpr char kDwmRegistryKey[] = R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM)"; -constexpr char kPersonalizeRegistryKey[] = R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)"; +[[maybe_unused]] constexpr char kDwmRegistryKey[] = R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM)"; +[[maybe_unused]] constexpr char kPersonalizeRegistryKey[] = R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)"; -constexpr int kDefaultResizeBorderThicknessClassic = 4; -constexpr int kDefaultResizeBorderThicknessAero = 8; -constexpr int kDefaultCaptionHeight = 23; +[[maybe_unused]] constexpr int kDefaultResizeBorderThicknessClassic = 4; +[[maybe_unused]] constexpr int kDefaultResizeBorderThicknessAero = 8; +[[maybe_unused]] constexpr int kDefaultCaptionHeight = 23; -enum : WORD -{ - _DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 = 19, - _DWMWA_USE_IMMERSIVE_DARK_MODE = 20, - _DWMWA_VISIBLE_FRAME_BORDER_THICKNESS = 37 -}; +[[maybe_unused]] constexpr WORD _DWMWA_VISIBLE_FRAME_BORDER_THICKNESS = 37; diff --git a/framelesswindowsmanager.cpp b/framelesswindowsmanager.cpp index 6eaa095..093e8f7 100644 --- a/framelesswindowsmanager.cpp +++ b/framelesswindowsmanager.cpp @@ -54,15 +54,6 @@ void FramelessWindowsManager::addWindow(QWindow *window) framelessHelperUnix()->removeWindowFrame(window); #else FramelessHelperWin::addFramelessWindow(window); - QObject::connect(window, &QWindow::windowStateChanged, [window](Qt::WindowState state){ - const bool normal = (state == Qt::WindowNoState); - const bool max = (state == Qt::WindowMaximized); - const bool full = (state == Qt::WindowFullScreen); - if (normal || max || full) { - Utilities::updateFrameMargins(window->winId(), (max || full)); - Utilities::updateQtFrameMargins(window, true); - } - }); // Work-around a Win32 multi-monitor bug. QObject::connect(window, &QWindow::screenChanged, [window](QScreen *screen){ Q_UNUSED(screen); diff --git a/utilities.h b/utilities.h index 4b4e26d..f7be5c2 100644 --- a/utilities.h +++ b/utilities.h @@ -41,9 +41,7 @@ namespace Utilities [[nodiscard]] FRAMELESSHELPER_API QColor getColorizationColor(); [[nodiscard]] FRAMELESSHELPER_API int getWindowVisibleFrameBorderThickness(const WId winId); [[nodiscard]] FRAMELESSHELPER_API bool shouldAppsUseDarkMode(); -[[nodiscard]] FRAMELESSHELPER_API bool isHighContrastModeEnabled(); [[nodiscard]] FRAMELESSHELPER_API ColorizationArea getColorizationArea(); -[[nodiscard]] FRAMELESSHELPER_API bool isWindowDarkFrameBorderEnabled(const WId winId); [[nodiscard]] FRAMELESSHELPER_API bool isThemeChanged(const void *data); [[nodiscard]] FRAMELESSHELPER_API bool isSystemMenuRequested(const void *data, QPointF *pos); [[nodiscard]] FRAMELESSHELPER_API bool showSystemMenu(const WId winId, const QPointF &pos); @@ -57,6 +55,7 @@ FRAMELESSHELPER_API void triggerFrameChange(const WId winId); FRAMELESSHELPER_API void updateFrameMargins(const WId winId, const bool reset); FRAMELESSHELPER_API void updateQtFrameMargins(QWindow *window, const bool enable); [[nodiscard]] FRAMELESSHELPER_API QString getSystemErrorMessage(const QString &function, const HRESULT hr); +[[nodiscard]] FRAMELESSHELPER_API QString getSystemErrorMessage(const QString &function); #endif } diff --git a/utilities_linux.cpp b/utilities_linux.cpp index e8e1023..b1eeb6e 100644 --- a/utilities_linux.cpp +++ b/utilities_linux.cpp @@ -41,7 +41,7 @@ int Utilities::getSystemMetric(const QWindow *window, const SystemMetric metric, if ((resizeBorderThickness > 0) && !forceSystemValue) { return qRound(static_cast(resizeBorderThickness) * scaleFactor); } else { - // ### TODO: Retrieve system value through official API + // ### TO BE IMPLEMENTED: Retrieve system value through official API if (dpiScale) { return qRound(static_cast(kDefaultResizeBorderThickness) * devicePixelRatio); } else { @@ -54,7 +54,7 @@ int Utilities::getSystemMetric(const QWindow *window, const SystemMetric metric, if ((captionHeight > 0) && !forceSystemValue) { return qRound(static_cast(captionHeight) * scaleFactor); } else { - // ### TODO: Retrieve system value through official API + // ### TO BE IMPLEMENTED: Retrieve system value through official API if (dpiScale) { return qRound(static_cast(kDefaultCaptionHeight) * devicePixelRatio); } else { @@ -79,3 +79,51 @@ int Utilities::getSystemMetric(const QWindow *window, const SystemMetric metric, } return 0; } + +QColor Utilities::getColorizationColor() +{ + // ### TO BE IMPLEMENTED + return Qt::darkGray; +} + +int Utilities::getWindowVisibleFrameBorderThickness(const WId winId) +{ + // ### TO BE IMPLEMENTED + Q_UNUSED(winId); + return 1; +} + +bool Utilities::shouldAppsUseDarkMode() +{ + // ### TO BE IMPLEMENTED + return false; +} + +ColorizationArea Utilities::getColorizationArea() +{ + // ### TO BE IMPLEMENTED + return ColorizationArea::None; +} + +bool Utilities::isThemeChanged(const void *data) +{ + // ### TO BE IMPLEMENTED + Q_UNUSED(data); + return false; +} + +bool Utilities::isSystemMenuRequested(const void *data, QPointF *pos) +{ + // ### TO BE IMPLEMENTED + Q_UNUSED(data); + Q_UNUSED(pos); + return false; +} + +bool Utilities::showSystemMenu(const WId winId, const QPointF &pos) +{ + // ### TO BE IMPLEMENTED + Q_UNUSED(winId); + Q_UNUSED(pos); + return false; +} diff --git a/utilities_win32.cpp b/utilities_win32.cpp index 9d2d9d7..e79a0cf 100644 --- a/utilities_win32.cpp +++ b/utilities_win32.cpp @@ -43,6 +43,12 @@ Q_DECLARE_METATYPE(QMargins) FRAMELESSHELPER_BEGIN_NAMESPACE +[[nodiscard]] static inline QPointF extractMousePositionFromLParam(const LPARAM lParam) +{ + const POINT nativePos = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)}; + return QPointF(static_cast(nativePos.x), static_cast(nativePos.y)); +} + [[nodiscard]] static inline bool isWin10RS1OrGreater() { #if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)) @@ -134,8 +140,7 @@ int Utilities::getSystemMetric(const QWindow *window, const SystemMetric metric, return qRound(static_cast(result) / devicePixelRatio); } } else { - const HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); - qWarning() << getSystemErrorMessage(QStringLiteral("GetSystemMetrics"), hr); + qWarning() << getSystemErrorMessage(QStringLiteral("GetSystemMetrics")); // The padded border will disappear if DWM composition is disabled. const int defaultResizeBorderThickness = (isDwmCompositionAvailable() ? kDefaultResizeBorderThicknessAero : kDefaultResizeBorderThicknessClassic); if (dpiScale) { @@ -159,8 +164,7 @@ int Utilities::getSystemMetric(const QWindow *window, const SystemMetric metric, return qRound(static_cast(result) / devicePixelRatio); } } else { - const HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); - qWarning() << getSystemErrorMessage(QStringLiteral("GetSystemMetrics"), hr); + qWarning() << getSystemErrorMessage(QStringLiteral("GetSystemMetrics")); if (dpiScale) { return qRound(static_cast(kDefaultCaptionHeight) * devicePixelRatio); } else { @@ -196,8 +200,7 @@ void Utilities::triggerFrameChange(const WId winId) const auto hwnd = reinterpret_cast(winId); constexpr UINT flags = (SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER); if (SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, flags) == FALSE) { - const HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); - qWarning() << getSystemErrorMessage(QStringLiteral("SetWindowPos"), hr); + qWarning() << getSystemErrorMessage(QStringLiteral("SetWindowPos")); } } @@ -226,11 +229,11 @@ void Utilities::updateQtFrameMargins(QWindow *window, const bool enable) if (!window) { return; } - const bool shouldApplyCustomFrameMargins = (enable - && (window->windowState() != Qt::WindowMaximized) - && (window->windowState() != Qt::WindowFullScreen)); - const int resizeBorderThickness = shouldApplyCustomFrameMargins ? Utilities::getSystemMetric(window, SystemMetric::ResizeBorderThickness, true, true) : 0; - const int titleBarHeight = shouldApplyCustomFrameMargins ? Utilities::getSystemMetric(window, SystemMetric::TitleBarHeight, true, true) : 0; + const bool useCustomFrameMargin = (enable && (window->windowState() != Qt::WindowMaximized) + && (window->windowState() != Qt::WindowFullScreen)); + const int resizeBorderThickness = useCustomFrameMargin ? + Utilities::getSystemMetric(window, SystemMetric::ResizeBorderThickness, true, true) : 0; + const int titleBarHeight = enable ? Utilities::getSystemMetric(window, SystemMetric::TitleBarHeight, true, true) : 0; const QMargins margins = {-resizeBorderThickness, -titleBarHeight, -resizeBorderThickness, -resizeBorderThickness}; // left, top, right, bottom const QVariant marginsVar = QVariant::fromValue(margins); window->setProperty("_q_windowsCustomMargins", marginsVar); @@ -273,6 +276,19 @@ QString Utilities::getSystemErrorMessage(const QString &function, const HRESULT return message; } +QString Utilities::getSystemErrorMessage(const QString &function) +{ + Q_ASSERT(!function.isEmpty()); + if (function.isEmpty()) { + return {}; + } + const HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); + if (SUCCEEDED(hr)) { + return QStringLiteral("Operation succeeded."); + } + return getSystemErrorMessage(function, hr); +} + QColor Utilities::getColorizationColor() { COLORREF color = RGB(0, 0, 0); @@ -340,14 +356,12 @@ bool Utilities::shouldAppsUseDarkMode() tried = true; const HMODULE dll = LoadLibraryExW(L"UxTheme.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32); if (!dll) { - const HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); - qWarning() << getSystemErrorMessage(QStringLiteral("LoadLibraryExW"), hr); + qWarning() << getSystemErrorMessage(QStringLiteral("LoadLibraryExW")); return resultFromRegistry(); } func = reinterpret_cast(GetProcAddress(dll, MAKEINTRESOURCEA(132))); if (!func) { - const HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); - qWarning() << getSystemErrorMessage(QStringLiteral("GetProcAddress"), hr); + qWarning() << getSystemErrorMessage(QStringLiteral("GetProcAddress")); return resultFromRegistry(); } } @@ -356,19 +370,6 @@ bool Utilities::shouldAppsUseDarkMode() } } -bool Utilities::isHighContrastModeEnabled() -{ - HIGHCONTRASTW hc; - SecureZeroMemory(&hc, sizeof(hc)); - hc.cbSize = sizeof(hc); - if (SystemParametersInfoW(SPI_GETHIGHCONTRAST, sizeof(hc), &hc, 0) == FALSE) { - const HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); - qWarning() << getSystemErrorMessage(QStringLiteral("SystemParametersInfoW"), hr); - return false; - } - return (hc.dwFlags & HCF_HIGHCONTRASTON); -} - ColorizationArea Utilities::getColorizationArea() { if (!isWin10OrGreater()) { @@ -391,36 +392,6 @@ ColorizationArea Utilities::getColorizationArea() return ColorizationArea::None; } -bool Utilities::isWindowDarkFrameBorderEnabled(const WId winId) -{ - Q_ASSERT(winId); - if (!winId) { - return false; - } - if (!isWin10RS1OrGreater()) { - return false; - } - const auto hWnd = reinterpret_cast(winId); - BOOL enabled = FALSE; - HRESULT hr = DwmGetWindowAttribute(hWnd, _DWMWA_USE_IMMERSIVE_DARK_MODE, &enabled, sizeof(enabled)); - if (SUCCEEDED(hr)) { - return (enabled != FALSE); - } else { - // We just eat this error because this enum value was introduced in a very - // late Windows 10 version, so querying it's value will always result in - // a "parameter error" (code: 87) on systems before that value was introduced. - } - hr = DwmGetWindowAttribute(hWnd, _DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1, &enabled, sizeof(enabled)); - if (SUCCEEDED(hr)) { - return (enabled != FALSE); - } else { - // We just eat this error because this enum value was introduced in a very - // late Windows 10 version, so querying it's value will always result in - // a "parameter error" (code: 87) on systems before that value was introduced. - } - return false; -} - bool Utilities::isThemeChanged(const void *data) { Q_ASSERT(data); @@ -446,17 +417,26 @@ bool Utilities::isSystemMenuRequested(const void *data, QPointF *pos) if (!data) { return false; } + bool result = false; const auto msg = static_cast(data); if (msg->message == WM_NCRBUTTONUP) { if (msg->wParam == HTCAPTION) { - if (pos) { - const POINT nativePos = {GET_X_LPARAM(msg->lParam), GET_Y_LPARAM(msg->lParam)}; - *pos = QPointF(static_cast(nativePos.x), static_cast(nativePos.y)); - } - return true; + result = true; + } + } else if (msg->message == WM_SYSCOMMAND) { + const WPARAM filteredWParam = (msg->wParam & 0xFFF0); + if ((filteredWParam == SC_KEYMENU) && (msg->lParam == VK_SPACE)) { + result = true; + } + } else if (msg->message == WM_CONTEXTMENU) { + // + } + if (result) { + if (pos) { + *pos = extractMousePositionFromLParam(msg->lParam); } } - return false; + return result; } bool Utilities::showSystemMenu(const WId winId, const QPointF &pos) @@ -468,8 +448,7 @@ bool Utilities::showSystemMenu(const WId winId, const QPointF &pos) const auto hWnd = reinterpret_cast(winId); const HMENU menu = GetSystemMenu(hWnd, FALSE); if (!menu) { - const HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); - qWarning() << getSystemErrorMessage(QStringLiteral("GetSystemMenu"), hr); + qWarning() << getSystemErrorMessage(QStringLiteral("GetSystemMenu")); return false; } // Update the options based on window state. @@ -480,54 +459,40 @@ bool Utilities::showSystemMenu(const WId winId, const QPointF &pos) mii.fType = MFT_STRING; const auto setState = [&mii, menu](const UINT item, const bool enabled) -> bool { mii.fState = (enabled ? MF_ENABLED : MF_DISABLED); - return (SetMenuItemInfoW(menu, item, FALSE, &mii) != FALSE); + if (SetMenuItemInfoW(menu, item, FALSE, &mii) == FALSE) { + qWarning() << getSystemErrorMessage(QStringLiteral("SetMenuItemInfoW")); + return false; + } + return true; }; const bool max = IsMaximized(hWnd); if (!setState(SC_RESTORE, max)) { - const HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); - qWarning() << getSystemErrorMessage(QStringLiteral("SetMenuItemInfoW"), hr); return false; } if (!setState(SC_MOVE, !max)) { - const HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); - qWarning() << getSystemErrorMessage(QStringLiteral("SetMenuItemInfoW"), hr); return false; } if (!setState(SC_SIZE, !max)) { - const HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); - qWarning() << getSystemErrorMessage(QStringLiteral("SetMenuItemInfoW"), hr); return false; } if (!setState(SC_MINIMIZE, true)) { - const HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); - qWarning() << getSystemErrorMessage(QStringLiteral("SetMenuItemInfoW"), hr); return false; } if (!setState(SC_MAXIMIZE, !max)) { - const HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); - qWarning() << getSystemErrorMessage(QStringLiteral("SetMenuItemInfoW"), hr); return false; } if (!setState(SC_CLOSE, true)) { - const HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); - qWarning() << getSystemErrorMessage(QStringLiteral("SetMenuItemInfoW"), hr); return false; } if (SetMenuDefaultItem(menu, UINT_MAX, FALSE) == FALSE) { - const HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); - qWarning() << getSystemErrorMessage(QStringLiteral("SetMenuDefaultItem"), hr); + qWarning() << getSystemErrorMessage(QStringLiteral("SetMenuDefaultItem")); return false; } const QPoint roundedPos = pos.toPoint(); - UINT flags = TPM_RETURNCMD; - if (QGuiApplication::isRightToLeft()) { - flags |= TPM_LAYOUTRTL; - } - const auto ret = TrackPopupMenu(menu, flags, roundedPos.x(), roundedPos.y(), 0, hWnd, nullptr); + const auto ret = TrackPopupMenu(menu, TPM_RETURNCMD, roundedPos.x(), roundedPos.y(), 0, hWnd, nullptr); if (ret != 0) { if (PostMessageW(hWnd, WM_SYSCOMMAND, ret, 0) == FALSE) { - const HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); - qWarning() << getSystemErrorMessage(QStringLiteral("PostMessageW"), hr); + qWarning() << getSystemErrorMessage(QStringLiteral("PostMessageW")); return false; } }