diff --git a/CMakeLists.txt b/CMakeLists.txt index 56e1a1a..63fbb6a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,6 +38,7 @@ option(FRAMELESSHELPER_BUILD_EXAMPLES "Build FramelessHelper demo applications." option(FRAMELESSHELPER_EXAMPLES_DEPLOYQT "Deploy the Qt framework after building the demo projects." ON) option(FRAMELESSHELPER_NO_DEBUG_OUTPUT "Suppress the debug messages from FramelessHelper." OFF) option(FRAMELESSHELPER_NO_BUNDLE_RESOURCE "Do not bundle any resources within FramelessHelper." OFF) +option(FRAMELESSHELPER_NO_PRIVATE "Do not use any private functionalities from Qt." OFF) include(GNUInstallDirs) include(CMakePackageConfigHelpers) @@ -109,6 +110,18 @@ endif() set(PROJECT_COMPILE_DATETIME "UNKNOWN") string(TIMESTAMP PROJECT_COMPILE_DATETIME UTC) +if(MSVC) + string(REGEX REPLACE "[-|/]GR-? " " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) + string(REGEX REPLACE "[-|/]EHs-?c-? " " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) + string(APPEND CMAKE_CXX_FLAGS " /GR ") + string(APPEND CMAKE_CXX_FLAGS " /EHsc ") + set(CMAKE_RC_FLAGS "/c65001 /DWIN32 /nologo") + if(MSVC_VERSION GREATER_EQUAL 1920) # Visual Studio 2019 version 16.0 + string(REGEX REPLACE "[-|/]Ob[0|1|2|3] " " " CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE}) + string(APPEND CMAKE_CXX_FLAGS_RELEASE " /Ob3 ") + endif() +endif() + find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Gui) find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Gui) @@ -177,4 +190,5 @@ message("Build the FramelessHelper demo applications: ${FRAMELESSHELPER_BUILD_EX message("Deploy Qt libraries after compilation: ${FRAMELESSHELPER_EXAMPLES_DEPLOYQT}") message("Suppress debug messages from FramelessHelper: ${FRAMELESSHELPER_NO_DEBUG_OUTPUT}") message("Do not bundle any resources within FramelessHelper: ${FRAMELESSHELPER_NO_BUNDLE_RESOURCE}") +message("Do not use any private functionalities from Qt: ${FRAMELESSHELPER_NO_PRIVATE}") message("#######################################") diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index e2bc683..3777976 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -29,6 +29,6 @@ if(FRAMELESSHELPER_BUILD_WIDGETS AND TARGET Qt${QT_VERSION_MAJOR}::Widgets) add_subdirectory(dialog) endif() -if(FRAMELESSHELPER_BUILD_QUICK AND TARGET Qt${QT_VERSION_MAJOR}::Quick AND ${QT_VERSION_MAJOR} GREATER_EQUAL 6) +if(FRAMELESSHELPER_BUILD_QUICK AND TARGET Qt${QT_VERSION_MAJOR}::Quick AND (${QT_VERSION_MAJOR} GREATER_EQUAL 6) AND (NOT FRAMELESSHELPER_NO_PRIVATE)) add_subdirectory(quick) endif() diff --git a/include/FramelessHelper/Core/framelesshelpercore_global.h b/include/FramelessHelper/Core/framelesshelpercore_global.h index 7acdef2..4160457 100644 --- a/include/FramelessHelper/Core/framelesshelpercore_global.h +++ b/include/FramelessHelper/Core/framelesshelpercore_global.h @@ -374,10 +374,10 @@ Q_ENUM_NS(RegistryRootKey) enum class WindowEdge : quint32 { - Left = 0x00000000, - Top = 0x00000001, - Right = 0x00000002, - Bottom = 0x00000004 + Left = 0x00000001, + Top = 0x00000002, + Right = 0x00000004, + Bottom = 0x00000010 }; Q_ENUM_NS(WindowEdge) Q_DECLARE_FLAGS(WindowEdges, WindowEdge) diff --git a/include/FramelessHelper/Core/private/registrykey_p.h b/include/FramelessHelper/Core/private/registrykey_p.h index 9ced2c2..38f9d1e 100644 --- a/include/FramelessHelper/Core/private/registrykey_p.h +++ b/include/FramelessHelper/Core/private/registrykey_p.h @@ -32,11 +32,11 @@ #endif // REGISTRYKEY_FORCE_QSETTINGS #ifndef REGISTRYKEY_IMPL -# if ((QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) && !(REGISTRYKEY_FORCE_QSETTINGS)) +# if ((QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) && !(REGISTRYKEY_FORCE_QSETTINGS) && !defined(FRAMELESSHELPER_CORE_NO_PRIVATE)) # define REGISTRYKEY_IMPL (1) -# else // ((QT_VERSION < QT_VERSION_CHECK(5, 14, 0)) || REGISTRYKEY_FORCE_QSETTINGS) +# else // ((QT_VERSION < QT_VERSION_CHECK(5, 14, 0)) || REGISTRYKEY_FORCE_QSETTINGS || defined(FRAMELESSHELPER_CORE_NO_PRIVATE)) # define REGISTRYKEY_IMPL (2) -# endif // ((QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) && !REGISTRYKEY_FORCE_QSETTINGS) +# endif // ((QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) && !REGISTRYKEY_FORCE_QSETTINGS && !defined(FRAMELESSHELPER_CORE_NO_PRIVATE)) #endif // REGISTRYKEY_IMPL #ifndef REGISTRYKEY_QWINREGISTRYKEY diff --git a/include/FramelessHelper/Core/utils.h b/include/FramelessHelper/Core/utils.h index eff6ba2..d14663e 100644 --- a/include/FramelessHelper/Core/utils.h +++ b/include/FramelessHelper/Core/utils.h @@ -69,6 +69,14 @@ FRAMELESSHELPER_CORE_API void moveWindowToDesktopCenter( FRAMELESSHELPER_CORE_API void registerThemeChangeNotification(); [[nodiscard]] FRAMELESSHELPER_CORE_API QColor getFrameBorderColor(const bool active); [[nodiscard]] FRAMELESSHELPER_CORE_API qreal roundScaleFactor(const qreal factor); +[[nodiscard]] FRAMELESSHELPER_CORE_API int toNativePixels(const QWindow *window, const int value); +[[nodiscard]] FRAMELESSHELPER_CORE_API QPoint toNativePixels(const QWindow *window, const QPoint &point); +[[nodiscard]] FRAMELESSHELPER_CORE_API QSize toNativePixels(const QWindow *window, const QSize &size); +[[nodiscard]] FRAMELESSHELPER_CORE_API QRect toNativePixels(const QWindow *window, const QRect &rect); +[[nodiscard]] FRAMELESSHELPER_CORE_API int fromNativePixels(const QWindow *window, const int value); +[[nodiscard]] FRAMELESSHELPER_CORE_API QPoint fromNativePixels(const QWindow *window, const QPoint &point); +[[nodiscard]] FRAMELESSHELPER_CORE_API QSize fromNativePixels(const QWindow *window, const QSize &size); +[[nodiscard]] FRAMELESSHELPER_CORE_API QRect fromNativePixels(const QWindow *window, const QRect &rect); #ifdef Q_OS_WINDOWS [[nodiscard]] FRAMELESSHELPER_CORE_API bool isWindowsVersionOrGreater(const Global::WindowsVersion version); @@ -109,7 +117,7 @@ FRAMELESSHELPER_CORE_API void installSystemMenuHook( const WId windowId, const Global::IsWindowFixedSizeCallback &isWindowFixedSize, const Global::IsInsideTitleBarDraggableAreaCallback &isInTitleBarArea, - const Global::GetWindowDevicePixelRatioCallback &getDevicePixelRatio); + const Global::GetWindowHandleCallback &getWindowHandle); FRAMELESSHELPER_CORE_API void uninstallSystemMenuHook(const WId windowId); FRAMELESSHELPER_CORE_API void setAeroSnappingEnabled(const WId windowId, const bool enable); FRAMELESSHELPER_CORE_API void tryToEnableHighestDpiAwarenessLevel(); diff --git a/include/FramelessHelper/Quick/private/framelessquickapplicationwindow_p.h b/include/FramelessHelper/Quick/private/framelessquickapplicationwindow_p.h index dcd750c..7826fb2 100644 --- a/include/FramelessHelper/Quick/private/framelessquickapplicationwindow_p.h +++ b/include/FramelessHelper/Quick/private/framelessquickapplicationwindow_p.h @@ -24,6 +24,8 @@ #pragma once +#ifndef FRAMELESSHELPER_QUICK_NO_PRIVATE + #include "framelesshelperquick_global.h" #include @@ -82,3 +84,5 @@ FRAMELESSHELPER_END_NAMESPACE Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickApplicationWindow)) QML_DECLARE_TYPE(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickApplicationWindow)) + +#endif // FRAMELESSHELPER_QUICK_NO_PRIVATE diff --git a/include/FramelessHelper/Quick/private/framelessquickapplicationwindow_p_p.h b/include/FramelessHelper/Quick/private/framelessquickapplicationwindow_p_p.h index c787eb7..5d57a27 100644 --- a/include/FramelessHelper/Quick/private/framelessquickapplicationwindow_p_p.h +++ b/include/FramelessHelper/Quick/private/framelessquickapplicationwindow_p_p.h @@ -24,6 +24,8 @@ #pragma once +#ifndef FRAMELESSHELPER_QUICK_NO_PRIVATE + #include "framelesshelperquick_global.h" #include "framelessquickapplicationwindow_p.h" @@ -68,3 +70,5 @@ private: FRAMELESSHELPER_END_NAMESPACE Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickApplicationWindowPrivate)) + +#endif // FRAMELESSHELPER_QUICK_NO_PRIVATE diff --git a/include/FramelessHelper/Quick/private/framelessquickwindow_p.h b/include/FramelessHelper/Quick/private/framelessquickwindow_p.h index 2db03fd..13a469d 100644 --- a/include/FramelessHelper/Quick/private/framelessquickwindow_p.h +++ b/include/FramelessHelper/Quick/private/framelessquickwindow_p.h @@ -24,6 +24,8 @@ #pragma once +#ifndef FRAMELESSHELPER_QUICK_NO_PRIVATE + #include "framelesshelperquick_global.h" #include @@ -82,3 +84,5 @@ FRAMELESSHELPER_END_NAMESPACE Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickWindow)) QML_DECLARE_TYPE(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickWindow)) + +#endif // FRAMELESSHELPER_QUICK_NO_PRIVATE diff --git a/include/FramelessHelper/Quick/private/framelessquickwindow_p_p.h b/include/FramelessHelper/Quick/private/framelessquickwindow_p_p.h index 9ea621c..83847a4 100644 --- a/include/FramelessHelper/Quick/private/framelessquickwindow_p_p.h +++ b/include/FramelessHelper/Quick/private/framelessquickwindow_p_p.h @@ -24,6 +24,8 @@ #pragma once +#ifndef FRAMELESSHELPER_QUICK_NO_PRIVATE + #include "framelesshelperquick_global.h" #include "framelessquickwindow_p.h" @@ -68,3 +70,5 @@ private: FRAMELESSHELPER_END_NAMESPACE Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickWindowPrivate)) + +#endif // FRAMELESSHELPER_QUICK_NO_PRIVATE diff --git a/include/FramelessHelper/Quick/private/quickstandardsystembutton_p.h b/include/FramelessHelper/Quick/private/quickstandardsystembutton_p.h index c5bbe59..a8764d6 100644 --- a/include/FramelessHelper/Quick/private/quickstandardsystembutton_p.h +++ b/include/FramelessHelper/Quick/private/quickstandardsystembutton_p.h @@ -24,6 +24,8 @@ #pragma once +#ifndef FRAMELESSHELPER_QUICK_NO_PRIVATE + #include "framelesshelperquick_global.h" #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) #include @@ -110,3 +112,5 @@ FRAMELESSHELPER_END_NAMESPACE Q_DECLARE_METATYPE(FRAMELESSHELPER_PREPEND_NAMESPACE(QuickStandardSystemButton)) QML_DECLARE_TYPE(FRAMELESSHELPER_PREPEND_NAMESPACE(QuickStandardSystemButton)) #endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + +#endif // FRAMELESSHELPER_QUICK_NO_PRIVATE diff --git a/include/FramelessHelper/Quick/private/quickstandardtitlebar_p.h b/include/FramelessHelper/Quick/private/quickstandardtitlebar_p.h index 33cf7b7..f66ce34 100644 --- a/include/FramelessHelper/Quick/private/quickstandardtitlebar_p.h +++ b/include/FramelessHelper/Quick/private/quickstandardtitlebar_p.h @@ -24,6 +24,8 @@ #pragma once +#ifndef FRAMELESSHELPER_QUICK_NO_PRIVATE + #include "framelesshelperquick_global.h" #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) #include "quickchromepalette.h" @@ -142,3 +144,5 @@ FRAMELESSHELPER_END_NAMESPACE Q_DECLARE_METATYPE(FRAMELESSHELPER_PREPEND_NAMESPACE(QuickStandardTitleBar)) QML_DECLARE_TYPE(FRAMELESSHELPER_PREPEND_NAMESPACE(QuickStandardTitleBar)) #endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + +#endif // FRAMELESSHELPER_QUICK_NO_PRIVATE diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 96d95ed..ce606f7 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -158,6 +158,12 @@ if(FRAMELESSHELPER_NO_BUNDLE_RESOURCE) ) endif() +if(FRAMELESSHELPER_NO_PRIVATE) + target_compile_definitions(${SUB_PROJ_NAME} PRIVATE + FRAMELESSHELPER_CORE_NO_PRIVATE + ) +endif() + target_compile_definitions(${SUB_PROJ_NAME} PRIVATE QT_NO_KEYWORDS FRAMELESSHELPER_CORE_LIBRARY @@ -182,10 +188,17 @@ elseif(UNIX) ) endif() -target_link_libraries(${SUB_PROJ_NAME} PRIVATE - Qt${QT_VERSION_MAJOR}::CorePrivate - Qt${QT_VERSION_MAJOR}::GuiPrivate -) +if(FRAMELESSHELPER_NO_PRIVATE) + target_link_libraries(${SUB_PROJ_NAME} PRIVATE + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + ) +else() + target_link_libraries(${SUB_PROJ_NAME} PRIVATE + Qt${QT_VERSION_MAJOR}::CorePrivate + Qt${QT_VERSION_MAJOR}::GuiPrivate + ) +endif() target_include_directories(${SUB_PROJ_NAME} PUBLIC "$" diff --git a/src/core/cmakehelper.cmake b/src/core/cmakehelper.cmake index 9635390..fb4f540 100644 --- a/src/core/cmakehelper.cmake +++ b/src/core/cmakehelper.cmake @@ -59,19 +59,88 @@ function(setup_compile_params arg_target) WIN32_LEAN_AND_MEAN WINRT_LEAN_AND_MEAN ) target_compile_options(${arg_target} PRIVATE - /options:strict # Don't allow unknown parameters. - /permissive- # Make sure we always write standard code. - /utf-8 - /Zc:__cplusplus # Make sure we use the correct C++ standard. - /W3 # Can't use /W4 here, Qt's own headers are not warning-clean, especially QtQuick headers. /W4 will trigger too many warnings. - /WX # Make sure we don't ignore any warnings. - $<$:/JMC> - $<$>:/guard:cf /Gw /Gy /QIntel-jcc-erratum /Zc:inline> # /guard:ehcont? /Qspectre-load? + /bigobj /utf-8 $<$>:/fp:fast /GT /Gw /Gy /guard:cf /Zc:inline> # /GA for executables. + /sdl /Zc:auto /Zc:forScope /Zc:implicitNoexcept /Zc:noexceptTypes /Zc:referenceBinding + /Zc:rvalueCast /Zc:sizedDealloc /Zc:strictStrings /Zc:throwingNew /Zc:trigraphs + /Zc:wchar_t ) target_link_options(${arg_target} PRIVATE - /WX # Don't allow unknown parameters. - $<$>:/CETCOMPAT /GUARD:CF /OPT:REF /OPT:ICF> # /GUARD:EHCONT? + $<$>:/OPT:REF /OPT:ICF /OPT:LBR /GUARD:CF> + /DYNAMICBASE /NXCOMPAT /LARGEADDRESSAWARE /WX # /TSAWARE for executables. ) + if(CMAKE_SIZEOF_VOID_P EQUAL 4) + target_link_options(${arg_target} PRIVATE /SAFESEH) + endif() + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + target_link_options(${arg_target} PRIVATE $<$>:/HIGHENTROPYVA>) + endif() + if(MSVC_VERSION GREATER_EQUAL 1900) # Visual Studio 2015 + target_compile_options(${arg_target} PRIVATE /Zc:threadSafeInit) + endif() + if(MSVC_VERSION GREATER_EQUAL 1910) # Visual Studio 2017 version 15.0 + target_compile_options(${arg_target} PRIVATE /permissive- /Zc:ternary) + endif() + if(MSVC_VERSION GREATER_EQUAL 1912) # Visual Studio 2017 version 15.5 + target_compile_options(${arg_target} PRIVATE /Zc:alignedNew) + endif() + if(MSVC_VERSION GREATER_EQUAL 1913) # Visual Studio 2017 version 15.6 + target_compile_options(${arg_target} PRIVATE /Zc:externConstexpr) + endif() + if(MSVC_VERSION GREATER_EQUAL 1914) # Visual Studio 2017 version 15.7 + target_compile_options(${arg_target} PRIVATE /Zc:__cplusplus) + endif() + if(MSVC_VERSION GREATER_EQUAL 1915) # Visual Studio 2017 version 15.8 + target_compile_options(${arg_target} PRIVATE $<$,$>:/JMC>) + endif() + if(MSVC_VERSION GREATER_EQUAL 1920) # Visual Studio 2019 version 16.0 + target_link_options(${arg_target} PRIVATE $<$>:/CETCOMPAT>) + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + target_compile_options(${arg_target} PRIVATE /d2FH4) + endif() + endif() + if(MSVC_VERSION GREATER_EQUAL 1921) # Visual Studio 2019 version 16.1 + target_compile_options(${arg_target} PRIVATE /Zc:char8_t) + endif() + if(MSVC_VERSION GREATER_EQUAL 1923) # Visual Studio 2019 version 16.3 + target_compile_options(${arg_target} PRIVATE /Zc:externC) + endif() + if(MSVC_VERSION GREATER_EQUAL 1924) # Visual Studio 2019 version 16.4 + target_compile_options(${arg_target} PRIVATE /Zc:hiddenFriend) + endif() + if(MSVC_VERSION GREATER_EQUAL 1925) # Visual Studio 2019 version 16.5 + target_compile_options(${arg_target} PRIVATE + /Zc:preprocessor /Zc:tlsGuards $<$>:/QIntel-jcc-erratum> # /Qspectre-load ? + ) + #elseif(MSVC_VERSION GREATER_EQUAL 1912) # Visual Studio 2017 version 15.5 + # target_compile_options(${arg_target} PRIVATE /Qspectre) + endif() + #[[if((MSVC_VERSION GREATER_EQUAL 1927) AND (CMAKE_SIZEOF_VOID_P EQUAL 8)) # Visual Studio 2019 version 16.7 + target_compile_options(${arg_target} PRIVATE $<$>:/guard:ehcont>) + target_link_options(${arg_target} PRIVATE $<$>:/guard:ehcont>) + endif()]] + if(MSVC_VERSION GREATER_EQUAL 1928) # Visual Studio 2019 version 16.8 & 16.9 + target_compile_options(${arg_target} PRIVATE /Zc:lambda /Zc:zeroSizeArrayNew) + endif() + if(MSVC_VERSION GREATER_EQUAL 1929) # Visual Studio 2019 version 16.10 + target_compile_options(${arg_target} PRIVATE /await:strict) + elseif(MSVC_VERSION GREATER_EQUAL 1900) # Visual Studio 2015 + target_compile_options(${arg_target} PRIVATE /await) + endif() + if(MSVC_VERSION GREATER_EQUAL 1930) # Visual Studio 2022 version 17.0 + target_compile_options(${arg_target} PRIVATE /options:strict) + endif() + if(MSVC_VERSION GREATER_EQUAL 1931) # Visual Studio 2022 version 17.1 + target_compile_options(${arg_target} PRIVATE /Zc:static_assert) + endif() + if(MSVC_VERSION GREATER_EQUAL 1932) # Visual Studio 2022 version 17.2 + target_compile_options(${arg_target} PRIVATE /Zc:__STDC__) + endif() + if(MSVC_VERSION GREATER_EQUAL 1934) # Visual Studio 2022 version 17.4 + target_compile_options(${arg_target} PRIVATE /Zc:enumTypes /Zc:gotoScope /Zc:nrvo) + endif() + if(MSVC_VERSION GREATER_EQUAL 1935) # Visual Studio 2022 version 17.5 + target_compile_options(${arg_target} PRIVATE /Zc:templateScope) + endif() else() target_compile_options(${arg_target} PRIVATE -Wall -Wextra -Werror @@ -86,18 +155,6 @@ function(setup_compile_params arg_target) $<$>:-Wl,--gc-sections> ) endif() - #[[if(CLANG) - target_compile_options(${arg_target} PRIVATE - $<$>:-Xclang -cfguard -mretpoline> - ) - target_link_options(${arg_target} PRIVATE - $<$>:-Wl,-Xlink,-guard:cf -z retpolineplt -z now> - ) - else() # GCC - target_compile_options(${arg_target} PRIVATE - $<$>:-mindirect-branch=thunk -mfunction-return=thunk -mindirect-branch-register -mindirect-branch-cs-prefix> - ) - endif()]] endif() endfunction() diff --git a/src/core/framelesshelper_win.cpp b/src/core/framelesshelper_win.cpp index 38c6ffe..9e9c1af 100644 --- a/src/core/framelesshelper_win.cpp +++ b/src/core/framelesshelper_win.cpp @@ -200,8 +200,8 @@ Q_GLOBAL_STATIC(Win32Helper, g_win32Helper) WARNING << Utils::getSystemErrorMessage(kScreenToClient); break; } - const qreal devicePixelRatio = data.params.getWindowDevicePixelRatio(); - const QPoint qtScenePos = QPointF(QPointF(qreal(nativeLocalPos.x), qreal(nativeLocalPos.y)) / devicePixelRatio).toPoint(); + const QPoint qtScenePos = Utils::fromNativePixels(data.params.getWindowHandle(), + QPoint(nativeLocalPos.x, nativeLocalPos.y)); SystemButtonType buttonType = SystemButtonType::Unknown; if (data.params.isInsideSystemButtons(qtScenePos, &buttonType)) { switch (buttonType) { @@ -989,8 +989,8 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me WARNING << Utils::getSystemErrorMessage(kScreenToClient); break; } - const qreal dpr = data.params.getWindowDevicePixelRatio(); - const QPoint qtScenePos = QPointF(QPointF(qreal(nativeLocalPos.x), qreal(nativeLocalPos.y)) / dpr).toPoint(); + const QPoint qtScenePos = Utils::fromNativePixels(data.params.getWindowHandle(), + QPoint(nativeLocalPos.x, nativeLocalPos.y)); const bool max = IsMaximized(hWnd); const bool full = Utils::isFullScreen(windowId); const int frameSizeY = Utils::getResizeBorderThickness(windowId, false, true); @@ -1125,11 +1125,11 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me windowPos->flags |= SWP_NOCOPYBITS; } break; #endif -#if ((QT_VERSION <= QT_VERSION_CHECK(6, 2, 6)) || ((QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)) && (QT_VERSION <= QT_VERSION_CHECK(6, 4, 1)))) +#if ((QT_VERSION <= QT_VERSION_CHECK(6, 2, 7)) || ((QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)) && (QT_VERSION <= QT_VERSION_CHECK(6, 4, 2)))) case WM_GETDPISCALEDSIZE: { // QtBase commit 2cfca7fd1911cc82a22763152c04c65bc05bc19a introduced a bug // which caused the custom margins is ignored during the handling of the - // WM_GETDPISCALEDSIZE message, it was shipped with Qt 6.2.1 ~ 6.2.6 & 6.3 ~ 6.4.1. + // WM_GETDPISCALEDSIZE message, it was shipped with Qt 6.2.1 ~ 6.2.7 & 6.3 ~ 6.4.2. // We workaround it by overriding the wrong handling directly. RECT clientRect = {}; if (GetClientRect(hWnd, &clientRect) == FALSE) { @@ -1162,14 +1162,14 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me *result = TRUE; // We have set our preferred window size, don't use the default linear DPI scaling. return true; // Jump over Qt's wrong handling logic. } -#endif +#endif // ((QT_VERSION <= QT_VERSION_CHECK(6, 2, 7)) || ((QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)) && (QT_VERSION <= QT_VERSION_CHECK(6, 4, 2)))) case WM_DPICHANGED: { const Dpi dpi = {UINT(LOWORD(wParam)), UINT(HIWORD(wParam))}; DEBUG.noquote() << "New DPI for window" << hwnd2str(hWnd) << "is" << dpi; g_win32Helper()->mutex.lock(); g_win32Helper()->data[windowId].dpi = dpi; g_win32Helper()->mutex.unlock(); -#if (QT_VERSION <= QT_VERSION_CHECK(6, 4, 1)) +#if (QT_VERSION <= QT_VERSION_CHECK(6, 4, 2)) // We need to wait until Qt has handled this message, otherwise everything // we have done here will always be overwritten. QTimer::singleShot(0, qApp, [data](){ // Copy the variables intentionally, otherwise they'll go out of scope when Qt finally use them. @@ -1177,7 +1177,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me // we will get wrong window sizes after the DPI change. Utils::updateInternalWindowFrameMargins(data.params.getWindowHandle(), true); }); -#endif // (QT_VERSION <= QT_VERSION_CHECK(6, 4, 1)) +#endif // (QT_VERSION <= QT_VERSION_CHECK(6, 4, 2)) } break; case WM_DWMCOMPOSITIONCHANGED: { // Re-apply the custom window frame if recovered from the basic theme. diff --git a/src/core/framelessmanager.cpp b/src/core/framelessmanager.cpp index d2ddfe9..64a55ef 100644 --- a/src/core/framelessmanager.cpp +++ b/src/core/framelessmanager.cpp @@ -220,7 +220,7 @@ void FramelessManagerPrivate::addWindow(const SystemParameters ¶ms) FramelessHelperWin::addWindow(params); } Utils::installSystemMenuHook(windowId, params.isWindowFixedSize, - params.isInsideTitleBarDraggableArea, params.getWindowDevicePixelRatio); + params.isInsideTitleBarDraggableArea, params.getWindowHandle); #endif } diff --git a/src/core/micamaterial.cpp b/src/core/micamaterial.cpp index aa5475b..9a0a174 100644 --- a/src/core/micamaterial.cpp +++ b/src/core/micamaterial.cpp @@ -34,8 +34,10 @@ #include #include #include -#include -#include +#ifndef FRAMELESSHELPER_CORE_NO_PRIVATE +# include +# include +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE #ifndef FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE // The "Q_INIT_RESOURCE()" macro can't be used within a namespace, @@ -66,11 +68,11 @@ Q_LOGGING_CATEGORY(lcMicaMaterial, "wangwenx190.framelesshelper.core.micamateria using namespace Global; -static constexpr const qreal kDefaultTintOpacity = 0.7; -static constexpr const qreal kDefaultNoiseOpacity = 0.04; -static constexpr const qreal kDefaultBlurRadius = 128.0; +[[maybe_unused]] static constexpr const qreal kDefaultTintOpacity = 0.7; +[[maybe_unused]] static constexpr const qreal kDefaultNoiseOpacity = 0.04; +[[maybe_unused]] static constexpr const qreal kDefaultBlurRadius = 128.0; -static Q_CONSTEXPR2 const QColor kDefaultSystemLightColor2 = {243, 243, 243}; // #F3F3F3 +[[maybe_unused]] static Q_CONSTEXPR2 const QColor kDefaultSystemLightColor2 = {243, 243, 243}; // #F3F3F3 #ifndef FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE FRAMELESSHELPER_STRING_CONSTANT2(NoiseImageFilePath, ":/org.wangwenx190.FramelessHelper/resources/images/noise.png") @@ -85,6 +87,14 @@ struct MicaMaterialData Q_GLOBAL_STATIC(MicaMaterialData, g_micaMaterialData) +#ifdef FRAMELESSHELPER_CORE_NO_PRIVATE +[[nodiscard]] static inline Qt::Alignment visualAlignment + (const Qt::LayoutDirection direction, const Qt::Alignment alignment) +{ + Q_UNUSED(direction); + return alignment; +} +#else // !FRAMELESSHELPER_CORE_NO_PRIVATE template [[nodiscard]] static inline int qt_static_shift(const int value) { @@ -437,6 +447,7 @@ static inline void expblur(QImage &img, qreal radius, const bool improvedQuality { return QGuiApplicationPrivate::visualAlignment(direction, alignment); } +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE /*! Returns a new rectangle of the specified \a size that is aligned to the given @@ -554,11 +565,11 @@ void MicaMaterialPrivate::maybeGenerateBlurredWallpaper(const bool force) QPainter painter(&g_micaMaterialData()->blurredWallpaper); painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform); -#if 1 - qt_blurImage(&painter, buffer, kDefaultBlurRadius, true, false); -#else +#ifdef FRAMELESSHELPER_CORE_NO_PRIVATE painter.drawImage(desktopOriginPoint, buffer); -#endif +#else // !FRAMELESSHELPER_CORE_NO_PRIVATE + qt_blurImage(&painter, buffer, kDefaultBlurRadius, true, false); +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE g_micaMaterialData()->mutex.unlock(); Q_Q(MicaMaterial); Q_EMIT q->shouldRedraw(); @@ -569,6 +580,7 @@ void MicaMaterialPrivate::updateMaterialBrush() #ifndef FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE initResource(); static const QImage noiseTexture = QImage(kNoiseImageFilePath); +#endif // FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE QImage micaTexture = QImage(QSize(64, 64), QImage::Format_ARGB32_Premultiplied); QColor fillColor = (Utils::shouldAppsUseDarkMode() ? kDefaultSystemDarkColor : kDefaultSystemLightColor2); fillColor.setAlphaF(0.9f); @@ -580,13 +592,14 @@ void MicaMaterialPrivate::updateMaterialBrush() const QRect rect = {QPoint(0, 0), micaTexture.size()}; painter.fillRect(rect, tintColor); painter.setOpacity(noiseOpacity); +#ifndef FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE painter.fillRect(rect, QBrush(noiseTexture)); +#endif // FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE micaBrush = QBrush(micaTexture); if (initialized) { Q_Q(MicaMaterial); Q_EMIT q->shouldRedraw(); } -#endif // FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE } void MicaMaterialPrivate::paint(QPainter *painter, const QSize &size, const QPoint &pos) diff --git a/src/core/sysapiloader.cpp b/src/core/sysapiloader.cpp index 11f7a55..5991785 100644 --- a/src/core/sysapiloader.cpp +++ b/src/core/sysapiloader.cpp @@ -23,13 +23,35 @@ */ #include "sysapiloader_p.h" + +#ifndef SYSAPILOADER_FORCE_QLIBRARY +# define SYSAPILOADER_FORCE_QLIBRARY (0) +#endif // SYSAPILOADER_FORCE_QLIBRARY + +#ifndef SYSAPILOADER_IMPL +# if (defined(Q_OS_WINDOWS) && !defined(FRAMELESSHELPER_CORE_NO_PRIVATE)) +# define SYSAPILOADER_IMPL (1) +# else // (!Q_OS_WINDOWS || FRAMELESSHELPER_CORE_NO_PRIVATE) +# define SYSAPILOADER_IMPL (2) +# endif // (defined(Q_OS_WINDOWS) && !defined(FRAMELESSHELPER_CORE_NO_PRIVATE)) +#endif // SYSAPILOADER_IMPL + +#ifndef SYSAPILOADER_QSYSTEMLIBRARY +# define SYSAPILOADER_QSYSTEMLIBRARY ((SYSAPILOADER_IMPL) == 1) +#endif // SYSAPILOADER_QSYSTEMLIBRARY + +#ifndef SYSAPILOADER_QLIBRARY +# define SYSAPILOADER_QLIBRARY ((SYSAPILOADER_IMPL) == 2) +#endif // SYSAPILOADER_QLIBRARY + #include #include -#ifdef Q_OS_WINDOWS +#if SYSAPILOADER_QSYSTEMLIBRARY # include -#else +#endif // SYSAPILOADER_QSYSTEMLIBRARY +#if SYSAPILOADER_QLIBRARY # include -#endif +#endif // SYSAPILOADER_QLIBRARY FRAMELESSHELPER_BEGIN_NAMESPACE @@ -75,11 +97,12 @@ QFunctionPointer SysApiLoader::resolve(const QString &library, const char *funct if (library.isEmpty() || !function) { return nullptr; } -#ifdef Q_OS_WINDOWS +#if SYSAPILOADER_QSYSTEMLIBRARY return QSystemLibrary::resolve(library, function); -#else +#endif // SYSAPILOADER_QSYSTEMLIBRARY +#if SYSAPILOADER_QLIBRARY return QLibrary::resolve(library, function); -#endif +#endif // SYSAPILOADER_QLIBRARY } QFunctionPointer SysApiLoader::resolve(const QString &library, const QByteArray &function) diff --git a/src/core/utils.cpp b/src/core/utils.cpp index 84dcd31..ffecfef 100644 --- a/src/core/utils.cpp +++ b/src/core/utils.cpp @@ -25,16 +25,19 @@ #include "utils.h" #ifdef Q_OS_WINDOWS # include "winverhelper_p.h" -#endif +#endif // Q_OS_WINDOWS #include #include #include +#ifndef FRAMELESSHELPER_CORE_NO_PRIVATE +# include +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE #if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)) # include -#elif (QT_VERSION >= QT_VERSION_CHECK(6, 2, 1)) +#elif ((QT_VERSION >= QT_VERSION_CHECK(6, 2, 1)) && !defined(FRAMELESSHELPER_CORE_NO_PRIVATE)) # include # include -#endif +#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)) FRAMELESSHELPER_BEGIN_NAMESPACE @@ -209,8 +212,8 @@ void Utils::moveWindowToDesktopCenter(const GetWindowScreenCallback &getWindowSc if (!screen) { return; } - const QSize screenSize = (considerTaskBar ? screen->availableSize() : screen->size()); - const QPoint offset = (considerTaskBar ? screen->availableGeometry().topLeft() : QPoint(0, 0)); + const QSize screenSize = (considerTaskBar ? screen->availableVirtualSize() : screen->virtualSize()); + const QPoint offset = (considerTaskBar ? screen->availableVirtualGeometry().topLeft() : QPoint(0, 0)); const int newX = qRound(qreal(screenSize.width() - windowSize.width()) / 2.0); const int newY = qRound(qreal(screenSize.height() - windowSize.height()) / 2.0); setWindowPosition(QPoint(newX + offset.x(), newY + offset.y())); @@ -282,12 +285,12 @@ bool Utils::shouldAppsUseDarkMode() { #if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)) return (QGuiApplication::styleHints()->appearance() == Qt::Appearance::Dark); -#elif (QT_VERSION >= QT_VERSION_CHECK(6, 2, 1)) +#elif ((QT_VERSION >= QT_VERSION_CHECK(6, 2, 1)) && !defined(FRAMELESSHELPER_CORE_NO_PRIVATE)) if (const QPlatformTheme * const theme = QGuiApplicationPrivate::platformTheme()) { return (theme->appearance() == QPlatformTheme::Appearance::Dark); } return false; -#else +#else // ((QT_VERSION < QT_VERSION_CHECK(6, 2, 1)) || FRAMELESSHELPER_CORE_NO_PRIVATE) # ifdef Q_OS_WINDOWS return shouldAppsUseDarkMode_windows(); # elif defined(Q_OS_LINUX) @@ -306,15 +309,16 @@ qreal Utils::roundScaleFactor(const qreal factor) if (factor <= 0) { return 1; } -#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) +#ifdef FRAMELESSHELPER_CORE_NO_PRIVATE +# if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) static const auto policy = QGuiApplication::highDpiScaleFactorRoundingPolicy(); switch (policy) { case Qt::HighDpiScaleFactorRoundingPolicy::Unset: -# if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +# if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) return factor; -# else // (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) +# else // (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) return qRound(factor); -# endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +# endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) case Qt::HighDpiScaleFactorRoundingPolicy::Round: return qRound(factor); case Qt::HighDpiScaleFactorRoundingPolicy::Ceil: @@ -327,9 +331,116 @@ qreal Utils::roundScaleFactor(const qreal factor) return factor; } return 1; -#else // (QT_VERSION < QT_VERSION_CHECK(5, 14, 0)) +# else // (QT_VERSION < QT_VERSION_CHECK(5, 14, 0)) return qRound(factor); -#endif // (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) +# endif // (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) +#else // !FRAMELESSHELPER_CORE_NO_PRIVATE + return QHighDpiScaling::roundScaleFactor(factor); +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE +} + +int Utils::toNativePixels(const QWindow *window, const int value) +{ + Q_ASSERT(window); + if (!window) { + return 0; + } +#ifdef FRAMELESSHELPER_CORE_NO_PRIVATE + return qRound(qreal(value) * window->devicePixelRatio()); +#else // !FRAMELESSHELPER_CORE_NO_PRIVATE + return QHighDpi::toNativePixels(value, window); +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE +} + +QPoint Utils::toNativePixels(const QWindow *window, const QPoint &point) +{ + Q_ASSERT(window); + if (!window) { + return {}; + } +#ifdef FRAMELESSHELPER_CORE_NO_PRIVATE + return QPointF(QPointF(point) * window->devicePixelRatio()).toPoint(); +#else // !FRAMELESSHELPER_CORE_NO_PRIVATE + return QHighDpi::toNativePixels(point, window); +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE +} + +QSize Utils::toNativePixels(const QWindow *window, const QSize &size) +{ + Q_ASSERT(window); + if (!window) { + return {}; + } +#ifdef FRAMELESSHELPER_CORE_NO_PRIVATE + return QSizeF(QSizeF(size) * window->devicePixelRatio()).toSize(); +#else // !FRAMELESSHELPER_CORE_NO_PRIVATE + return QHighDpi::toNativePixels(size, window); +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE +} + +QRect Utils::toNativePixels(const QWindow *window, const QRect &rect) +{ + Q_ASSERT(window); + if (!window) { + return {}; + } +#ifdef FRAMELESSHELPER_CORE_NO_PRIVATE + return QRect(toNativePixels(window, rect.topLeft()), toNativePixels(window, rect.size())); +#else // !FRAMELESSHELPER_CORE_NO_PRIVATE + return QHighDpi::toNativePixels(rect, window); +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE +} + +int Utils::fromNativePixels(const QWindow *window, const int value) +{ + Q_ASSERT(window); + if (!window) { + return 0; + } +#ifdef FRAMELESSHELPER_CORE_NO_PRIVATE + return qRound(qreal(value) / window->devicePixelRatio()); +#else // !FRAMELESSHELPER_CORE_NO_PRIVATE + return QHighDpi::fromNativePixels(value, window); +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE +} + +QPoint Utils::fromNativePixels(const QWindow *window, const QPoint &point) +{ + Q_ASSERT(window); + if (!window) { + return {}; + } +#ifdef FRAMELESSHELPER_CORE_NO_PRIVATE + return QPointF(QPointF(point) / window->devicePixelRatio()).toPoint(); +#else // !FRAMELESSHELPER_CORE_NO_PRIVATE + return QHighDpi::fromNativePixels(point, window); +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE +} + +QSize Utils::fromNativePixels(const QWindow *window, const QSize &size) +{ + Q_ASSERT(window); + if (!window) { + return {}; + } +#ifdef FRAMELESSHELPER_CORE_NO_PRIVATE + return QSizeF(QSizeF(size) / window->devicePixelRatio()).toSize(); +#else // !FRAMELESSHELPER_CORE_NO_PRIVATE + return QHighDpi::fromNativePixels(size, window); +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE +} + +QRect Utils::fromNativePixels(const QWindow *window, const QRect &rect) +{ + Q_ASSERT(window); + if (!window) { + return {}; + } +#ifdef FRAMELESSHELPER_CORE_NO_PRIVATE + return QRect(fromNativePixels(window, rect.topLeft()), fromNativePixels(window, rect.size())); +#else // !FRAMELESSHELPER_CORE_NO_PRIVATE + return QHighDpi::fromNativePixels(rect, window); +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE } FRAMELESSHELPER_END_NAMESPACE diff --git a/src/core/utils_linux.cpp b/src/core/utils_linux.cpp index e1529d4..dd51387 100644 --- a/src/core/utils_linux.cpp +++ b/src/core/utils_linux.cpp @@ -29,14 +29,16 @@ #include #include #include -#include -#include -#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) -# include -# include -#else -# include -#endif +#ifndef FRAMELESSHELPER_CORE_NO_PRIVATE +# include +# include +# if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +# include +# include +# else // (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) +# include +# endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE #include #include @@ -155,6 +157,10 @@ template [[maybe_unused]] [[nodiscard]] static inline QScreen *x11_findScreenForVirtualDesktop(const int virtualDesktopNumber) { +#ifdef FRAMELESSHELPER_CORE_NO_PRIVATE + Q_UNUSED(virtualDesktopNumber); + return QGuiApplication::primaryScreen(); +#else // !FRAMELESSHELPER_CORE_NO_PRIVATE if (virtualDesktopNumber == -1) { return QGuiApplication::primaryScreen(); } @@ -163,28 +169,33 @@ template return nullptr; } for (auto &&screen : qAsConst(screens)) { -#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +# if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) const auto qxcbScreen = dynamic_cast(screen->handle()); if (qxcbScreen && (qxcbScreen->virtualDesktopNumber() == virtualDesktopNumber)) { return screen; } -#else +# else // (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) if (QXcbScreenFunctions::virtualDesktopNumber(screen) == virtualDesktopNumber) { return screen; } -#endif +# endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) } return nullptr; +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE } #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) [[maybe_unused]] [[nodiscard]] static inline unsigned long x11_appRootWindow(const int screen) -#else +#else // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) [[maybe_unused]] [[nodiscard]] static inline quint32 x11_appRootWindow(const int screen) -#endif +#endif // (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) { +#ifdef FRAMELESSHELPER_CORE_NO_PRIVATE + Q_UNUSED(screen); + return 0; +#else // !FRAMELESSHELPER_CORE_NO_PRIVATE if (!qApp) { return 0; } @@ -197,10 +208,14 @@ template return 0; } return static_cast(reinterpret_cast(native->nativeResourceForScreen(krootwindow, scr))); +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE } [[maybe_unused]] [[nodiscard]] static inline int x11_appScreen() { +#ifdef FRAMELESSHELPER_CORE_NO_PRIVATE + return 0; +#else // !FRAMELESSHELPER_CORE_NO_PRIVATE if (!qApp) { return 0; } @@ -209,10 +224,14 @@ template return 0; } return reinterpret_cast(native->nativeResourceForIntegration(kx11screen)); +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE } [[maybe_unused]] [[nodiscard]] static inline quint32 x11_appTime() { +#ifdef FRAMELESSHELPER_CORE_NO_PRIVATE + return 0; +#else // !FRAMELESSHELPER_CORE_NO_PRIVATE if (!qApp) { return 0; } @@ -225,10 +244,14 @@ template return 0; } return static_cast(reinterpret_cast(native->nativeResourceForScreen(kapptime, screen))); +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE } [[maybe_unused]] [[nodiscard]] static inline quint32 x11_appUserTime() { +#ifdef FRAMELESSHELPER_CORE_NO_PRIVATE + return 0; +#else // !FRAMELESSHELPER_CORE_NO_PRIVATE if (!qApp) { return 0; } @@ -241,10 +264,14 @@ template return 0; } return static_cast(reinterpret_cast(native->nativeResourceForScreen(kappusertime, screen))); +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE } [[maybe_unused]] [[nodiscard]] static inline quint32 x11_getTimestamp() { +#ifdef FRAMELESSHELPER_CORE_NO_PRIVATE + return 0; +#else // !FRAMELESSHELPER_CORE_NO_PRIVATE if (!qApp) { return 0; } @@ -257,10 +284,14 @@ template return 0; } return static_cast(reinterpret_cast(native->nativeResourceForScreen(kgettimestamp, screen))); +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE } [[maybe_unused]] [[nodiscard]] static inline QByteArray x11_nextStartupId() { +#ifdef FRAMELESSHELPER_CORE_NO_PRIVATE + return {}; +#else // !FRAMELESSHELPER_CORE_NO_PRIVATE if (!qApp) { return {}; } @@ -269,48 +300,57 @@ template return {}; } return static_cast(native->nativeResourceForIntegration(kstartupid)); +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE } [[maybe_unused]] [[nodiscard]] static inline Display *x11_display() { +#ifdef FRAMELESSHELPER_CORE_NO_PRIVATE + return nullptr; +#else // !FRAMELESSHELPER_CORE_NO_PRIVATE if (!qApp) { return nullptr; } -#if (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)) - using namespace QNativeInterface; - const auto native = qApp->nativeInterface(); -#else +# if (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)) + using App = QNativeInterface::QX11Application; + const auto native = qApp->nativeInterface(); +# else // (QT_VERSION < QT_VERSION_CHECK(6, 2, 0)) const auto native = qApp->platformNativeInterface(); -#endif +# endif // (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)) if (!native) { return nullptr; } -#if (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)) +# if (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)) return native->display(); -#else +# else // (QT_VERSION < QT_VERSION_CHECK(6, 2, 0)) return reinterpret_cast(native->nativeResourceForIntegration(kdisplay)); -#endif +# endif // (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)) +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE } [[maybe_unused]] [[nodiscard]] static inline xcb_connection_t *x11_connection() { +#ifdef FRAMELESSHELPER_CORE_NO_PRIVATE + return nullptr; +#else // !FRAMELESSHELPER_CORE_NO_PRIVATE if (!qApp) { return nullptr; } -#if (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)) - using namespace QNativeInterface; - const auto native = qApp->nativeInterface(); -#else +# if (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)) + using App = QNativeInterface::QX11Application; + const auto native = qApp->nativeInterface(); +# else // (QT_VERSION < QT_VERSION_CHECK(6, 2, 0)) const auto native = qApp->platformNativeInterface(); -#endif +# endif // (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)) if (!native) { return nullptr; } -#if (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)) +# if (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)) return native->connection(); -#else +# else // (QT_VERSION < QT_VERSION_CHECK(6, 2, 0)) return reinterpret_cast(native->nativeResourceForIntegration(kconnection)); -#endif +# endif // (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)) +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE } static inline void @@ -387,11 +427,10 @@ static inline void if (!window) { return; } - const qreal dpr = window->devicePixelRatio(); - const QPoint deviceGlobalPos = QPointF(QPointF(globalPos) * dpr).toPoint(); + const QPoint nativeGlobalPos = Utils::toNativePixels(window, globalPos); const QPoint logicalLocalPos = window->mapFromGlobal(globalPos); - const QPoint deviceLocalPos = QPointF(QPointF(logicalLocalPos) * dpr).toPoint(); - emulateMouseButtonRelease(window->winId(), deviceGlobalPos, deviceLocalPos); + const QPoint nativeLocalPos = Utils::toNativePixels(window, logicalLocalPos); + emulateMouseButtonRelease(window->winId(), nativeGlobalPos, nativeLocalPos); } SystemTheme Utils::getSystemTheme() @@ -415,8 +454,8 @@ void Utils::startSystemMove(QWindow *window, const QPoint &globalPos) #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) window->startSystemMove(); #else - const QPoint deviceGlobalPos = QPointF(QPointF(globalPos) * window->devicePixelRatio()).toPoint(); - doStartSystemMoveResize(window->winId(), deviceGlobalPos, _NET_WM_MOVERESIZE_MOVE); + const QPoint nativeGlobalPos = Utils::toNativePixels(window, globalPos); + doStartSystemMoveResize(window->winId(), nativeGlobalPos, _NET_WM_MOVERESIZE_MOVE); #endif } @@ -442,8 +481,8 @@ void Utils::startSystemResize(QWindow *window, const Qt::Edges edges, const QPoi if (section < 0) { return; } - const QPoint deviceGlobalPos = QPointF(QPointF(globalPos) * window->devicePixelRatio()).toPoint(); - doStartSystemMoveResize(window->winId(), deviceGlobalPos, section); + const QPoint nativeGlobalPos = Utils::toNativePixels(window, globalPos); + doStartSystemMoveResize(window->winId(), nativeGlobalPos, section); #endif } diff --git a/src/core/utils_win.cpp b/src/core/utils_win.cpp index 7ee93ed..66efac1 100644 --- a/src/core/utils_win.cpp +++ b/src/core/utils_win.cpp @@ -25,17 +25,20 @@ #include "utils.h" #include #include -#include +#include #include -#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) -# include -#endif -#include -#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) -# include -#else -# include -#endif +#ifndef FRAMELESSHELPER_CORE_NO_PRIVATE +# include +# if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +# include +# endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +# include +# if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) +# include +# else // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +# include +# endif // (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE #include "framelessmanager.h" #include "framelesshelper_windows.h" #include "framelessconfig_p.h" @@ -810,7 +813,7 @@ struct Win32UtilsHelperData WNDPROC originalWindowProc = nullptr; IsWindowFixedSizeCallback isWindowFixedSize = nullptr; IsInsideTitleBarDraggableAreaCallback isInTitleBarArea = nullptr; - GetWindowDevicePixelRatioCallback getDevicePixelRatio = nullptr; + GetWindowHandleCallback getWindowHandle = nullptr; }; struct Win32UtilsHelper @@ -925,21 +928,20 @@ struct SYSTEM_METRIC if (code == ERROR_SUCCESS) { return kSuccessMessageText; } - static constexpr const bool flag = false; - if (flag) { - // The following code works well, we commented it out just because we want to use as many Qt functionalities as possible. - LPWSTR buf = nullptr; - if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - nullptr, code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast(&buf), 0, nullptr) == 0) { - return kEmptyMessageText; - } - const QString errorText = QString::fromWCharArray(buf).trimmed(); - LocalFree(buf); - buf = nullptr; - return kErrorMessageTemplate.arg(function, QString::number(code), errorText); +#ifdef FRAMELESSHELPER_CORE_NO_PRIVATE + LPWSTR buf = nullptr; + if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast(&buf), 0, nullptr) == 0) { + return kEmptyMessageText; } + const QString errorText = QString::fromWCharArray(buf).trimmed(); + LocalFree(buf); + buf = nullptr; + return kErrorMessageTemplate.arg(function, QString::number(code), errorText); +#else // !FRAMELESSHELPER_CORE_NO_PRIVATE const QString errorText = QSystemError::windowsString(code); return kErrorMessageTemplate.arg(function, QString::number(code), errorText); +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE } [[nodiscard]] static inline QString __getSystemErrorMessage(const QString &function, const HRESULT hr) @@ -1004,12 +1006,12 @@ static inline void moveWindowToMonitor(const HWND hwnd, const MONITORINFOEXW &ac WARNING << Utils::getSystemErrorMessage(kGetWindowRect); return; } - const int currentWindowWidth = currentWindowRect.right - currentWindowRect.left; - const int currentWindowHeight = currentWindowRect.bottom - currentWindowRect.top; + const int currentWindowWidth = (currentWindowRect.right - currentWindowRect.left); + const int currentWindowHeight = (currentWindowRect.bottom - currentWindowRect.top); const int currentWindowOffsetX = (currentWindowRect.left - currentMonitorRect.left); const int currentWindowOffsetY = (currentWindowRect.top - currentMonitorRect.top); - const int newWindowX = activeMonitorRect.left + currentWindowOffsetX; - const int newWindowY = activeMonitorRect.top + currentWindowOffsetY; + const int newWindowX = (activeMonitorRect.left + currentWindowOffsetX); + const int newWindowY = (activeMonitorRect.top + currentWindowOffsetY); static constexpr const UINT flags = (SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOOWNERZORDER); if (SetWindowPos(hwnd, nullptr, newWindowX, newWindowY, @@ -1134,8 +1136,7 @@ static inline void moveWindowToMonitor(const HWND hwnd, const MONITORINFOEXW &ac switch (uMsg) { case WM_RBUTTONUP: { const QPoint nativeLocalPos = getNativePosFromMouse(); - const qreal dpr = data.getDevicePixelRatio(); - const QPoint qtScenePos = QPointF(QPointF(nativeLocalPos) / dpr).toPoint(); + const QPoint qtScenePos = Utils::fromNativePixels(data.getWindowHandle(), nativeLocalPos); if (data.isInTitleBarArea(qtScenePos)) { POINT pos = {nativeLocalPos.x(), nativeLocalPos.y()}; if (ClientToScreen(hWnd, &pos) == FALSE) { @@ -1299,7 +1300,8 @@ void Utils::updateInternalWindowFrameMargins(QWindow *window, const bool enable) }(); const QVariant marginsVar = QVariant::fromValue(margins); window->setProperty("_q_windowsCustomMargins", marginsVar); -#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) +#ifndef FRAMELESSHELPER_CORE_NO_PRIVATE +# if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) if (QPlatformWindow *platformWindow = window->handle()) { if (const auto ni = QGuiApplication::platformNativeInterface()) { ni->setWindowProperty(platformWindow, kWindowsCustomMargins, marginsVar); @@ -1311,14 +1313,15 @@ void Utils::updateInternalWindowFrameMargins(QWindow *window, const bool enable) WARNING << "Failed to retrieve the platform window."; return; } -#else +# else // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) if (const auto platformWindow = dynamic_cast(window->handle())) { platformWindow->setCustomMargins(margins); } else { WARNING << "Failed to retrieve the platform window."; return; } -#endif +# endif // (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE triggerFrameChange(windowId); } @@ -2004,7 +2007,7 @@ bool Utils::isFrameBorderColorized() void Utils::installSystemMenuHook(const WId windowId, const IsWindowFixedSizeCallback &isWindowFixedSize, const IsInsideTitleBarDraggableAreaCallback &isInTitleBarArea, - const GetWindowDevicePixelRatioCallback &getDevicePixelRatio) + const GetWindowHandleCallback &getWindowHandle) { Q_ASSERT(windowId); Q_ASSERT(isWindowFixedSize); @@ -2033,7 +2036,7 @@ void Utils::installSystemMenuHook(const WId windowId, data.originalWindowProc = originalWindowProc; data.isWindowFixedSize = isWindowFixedSize; data.isInTitleBarArea = isInTitleBarArea; - data.getDevicePixelRatio = getDevicePixelRatio; + data.getWindowHandle = getWindowHandle; g_utilsHelper()->data.insert(windowId, data); } @@ -2237,22 +2240,24 @@ bool Utils::shouldAppsUseDarkMode_windows() if (!WindowsVersionHelper::isWin10RS1OrGreater()) { return false; } -#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +#ifndef FRAMELESSHELPER_CORE_NO_PRIVATE +# if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) if (const auto app = qApp->nativeInterface()) { return app->isDarkMode(); } else { WARNING << "QWindowsApplication is not available."; } -#elif (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) +# elif (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) if (const auto ni = QGuiApplication::platformNativeInterface()) { return ni->property("darkMode").toBool(); } else { WARNING << "Failed to retrieve the platform native interface."; } -#else +# else // (QT_VERSION < QT_VERSION_CHECK(5, 15, 0)) // Qt gained the ability to detect the system dark mode setting only since 5.15. // We should detect it ourself on versions below that. -#endif +# endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE // Starting from Windows 10 1903, "ShouldAppsUseDarkMode()" (exported by UXTHEME.DLL, // ordinal number 132) always return "TRUE" (actually, a random non-zero number at // runtime), so we can't use it due to this unreliability. In this case, we just simply @@ -2604,7 +2609,10 @@ void Utils::hideOriginalTitleBarElements(const WId windowId, const bool disable) void Utils::setQtDarkModeAwareEnabled(const bool enable) { -#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +#ifdef FRAMELESSHELPER_CORE_NO_PRIVATE + Q_UNUSED(enable); +#else // !FRAMELESSHELPER_CORE_NO_PRIVATE +# if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) // We'll call QPA functions, so we have to ensure that the QGuiApplication // instance has already been created and initialized, because the platform // integration infrastructure is created and maintained by QGuiApplication. @@ -2617,7 +2625,7 @@ void Utils::setQtDarkModeAwareEnabled(const bool enable) if (!enable) { return {}; // Clear the flags. } -#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)) +# if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)) // Enabling the DarkModeWindowFrames flag will save us the call of the // DwmSetWindowAttribute function. Qt will adjust the non-client area // (title bar & frame border) automatically. @@ -2627,19 +2635,20 @@ void Utils::setQtDarkModeAwareEnabled(const bool enable) // There's no global dark theme for Qt Quick applications, so setting this // flag has no effect for pure Qt Quick applications. return {App::DarkModeWindowFrames | App::DarkModeStyle}; -#else // (QT_VERSION < QT_VERSION_CHECK(6, 5, 0)) +# else // (QT_VERSION < QT_VERSION_CHECK(6, 5, 0)) // Don't try to use the broken dark theme for Qt Widgets applications. // For Qt Quick applications this is also enough. There's no global dark // theme for them anyway. return {App::DarkModeWindowFrames}; -#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)) +# endif // (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)) }()); } else { WARNING << "QWindowsApplication is not available."; } -#else // (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) +# else // (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) Q_UNUSED(enable); -#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +# endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +#endif // FRAMELESSHELPER_CORE_NO_PRIVATE } void Utils::registerThemeChangeNotification() diff --git a/src/quick/CMakeLists.txt b/src/quick/CMakeLists.txt index 4096eee..9fba4c6 100644 --- a/src/quick/CMakeLists.txt +++ b/src/quick/CMakeLists.txt @@ -168,15 +168,27 @@ if(FRAMELESSHELPER_NO_BUNDLE_RESOURCE) ) endif() +if(FRAMELESSHELPER_NO_PRIVATE) + target_compile_definitions(${SUB_PROJ_NAME} PRIVATE + FRAMELESSHELPER_QUICK_NO_PRIVATE + ) +endif() + target_compile_definitions(${SUB_PROJ_NAME} PRIVATE FRAMELESSHELPER_QUICK_LIBRARY ) -target_link_libraries(${SUB_PROJ_NAME} PRIVATE - Qt${QT_VERSION_MAJOR}::QuickPrivate - Qt${QT_VERSION_MAJOR}::QuickTemplates2Private - Qt${QT_VERSION_MAJOR}::QuickControls2Private -) +if(FRAMELESSHELPER_NO_PRIVATE) + target_link_libraries(${SUB_PROJ_NAME} PRIVATE + Qt${QT_VERSION_MAJOR}::Quick + ) +else() + target_link_libraries(${SUB_PROJ_NAME} PRIVATE + Qt${QT_VERSION_MAJOR}::QuickPrivate + Qt${QT_VERSION_MAJOR}::QuickTemplates2Private + Qt${QT_VERSION_MAJOR}::QuickControls2Private + ) +endif() target_link_libraries(${SUB_PROJ_NAME} PUBLIC ${PROJECT_NAME}::Core diff --git a/src/quick/framelesshelperquick_global.cpp b/src/quick/framelesshelperquick_global.cpp index d70fa17..4bac0db 100644 --- a/src/quick/framelesshelperquick_global.cpp +++ b/src/quick/framelesshelperquick_global.cpp @@ -28,18 +28,20 @@ # include "framelessquickhelper_p.h" # include "framelessquickutils.h" # include "quickchromepalette.h" -# include "quickstandardsystembutton_p.h" -# include "quickstandardtitlebar_p.h" -# include "framelessquickwindow_p.h" -# include "framelessquickwindow_p_p.h" -# include "framelessquickapplicationwindow_p.h" -# include "framelessquickapplicationwindow_p_p.h" # include "quickmicamaterial.h" # include "quickmicamaterial_p.h" # include "quickimageitem.h" # include "quickimageitem_p.h" # include "quickwindowborder.h" # include "quickwindowborder_p.h" +# ifndef FRAMELESSHELPER_QUICK_NO_PRIVATE +# include "quickstandardsystembutton_p.h" +# include "quickstandardtitlebar_p.h" +# include "framelessquickwindow_p.h" +# include "framelessquickwindow_p_p.h" +# include "framelessquickapplicationwindow_p.h" +# include "framelessquickapplicationwindow_p_p.h" +# endif // FRAMELESSHELPER_QUICK_NO_PRIVATE #endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) FRAMELESSHELPER_BEGIN_NAMESPACE @@ -100,6 +102,16 @@ void initialize() qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); +# ifndef FRAMELESSHELPER_QUICK_NO_PRIVATE qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); @@ -110,15 +122,7 @@ void initialize() qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); - qRegisterMetaType(); - qRegisterMetaType(); - qRegisterMetaType(); - qRegisterMetaType(); - qRegisterMetaType(); - qRegisterMetaType(); - qRegisterMetaType(); - qRegisterMetaType(); - qRegisterMetaType(); +# endif // FRAMELESSHELPER_QUICK_NO_PRIVATE #endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) } diff --git a/src/quick/framelessquickapplicationwindow.cpp b/src/quick/framelessquickapplicationwindow.cpp index 92d088c..1bf32d2 100644 --- a/src/quick/framelessquickapplicationwindow.cpp +++ b/src/quick/framelessquickapplicationwindow.cpp @@ -22,6 +22,8 @@ * SOFTWARE. */ +#ifndef FRAMELESSHELPER_QUICK_NO_PRIVATE + #include "framelessquickapplicationwindow_p.h" #include "framelessquickapplicationwindow_p_p.h" #include "framelessquickhelper.h" @@ -239,3 +241,5 @@ void FramelessQuickApplicationWindow::componentComplete() } FRAMELESSHELPER_END_NAMESPACE + +#endif // FRAMELESSHELPER_QUICK_NO_PRIVATE diff --git a/src/quick/framelessquickhelper.cpp b/src/quick/framelessquickhelper.cpp index 17d939e..7edda01 100644 --- a/src/quick/framelessquickhelper.cpp +++ b/src/quick/framelessquickhelper.cpp @@ -28,14 +28,16 @@ #include "quickwindowborder.h" #include #include -#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) -# include // For QWINDOWSIZE_MAX -#else -# include // For QWINDOWSIZE_MAX -#endif -#include -#include -#include +#ifndef FRAMELESSHELPER_QUICK_NO_PRIVATE +# if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +# include // For QWINDOWSIZE_MAX +# else // (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) +# include // For QWINDOWSIZE_MAX +# endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +# include +# include +# include +#endif // FRAMELESSHELPER_QUICK_NO_PRIVATE #include #include #include @@ -43,6 +45,10 @@ # include #endif // Q_OS_WINDOWS +#ifndef QWINDOWSIZE_MAX +# define QWINDOWSIZE_MAX ((1 << 24) - 1) +#endif // QWINDOWSIZE_MAX + FRAMELESSHELPER_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcFramelessQuickHelper, "wangwenx190.framelesshelper.quick.framelessquickhelper") @@ -356,7 +362,7 @@ void FramelessQuickHelperPrivate::showSystemMenu(const QPoint &pos) return; } const QPoint globalPos = window->mapToGlobal(pos); - const QPoint nativePos = QPointF(QPointF(globalPos) * window->effectiveDevicePixelRatio()).toPoint(); + const QPoint nativePos = Utils::toNativePixels(window, globalPos); Utils::showSystemMenu(window->winId(), nativePos, false, [this]() -> bool { return isWindowFixedSize(); }); #else Q_UNUSED(pos); @@ -578,7 +584,9 @@ QuickMicaMaterial *FramelessQuickHelperPrivate::findOrCreateMicaMaterial() const item->setParent(rootItem); item->setParentItem(rootItem); item->setZ(-999); // Make sure it always stays on the bottom. +#ifndef FRAMELESSHELPER_QUICK_NO_PRIVATE QQuickItemPrivate::get(item)->anchors()->setFill(rootItem); +#endif // FRAMELESSHELPER_QUICK_NO_PRIVATE return item; } @@ -600,7 +608,9 @@ QuickWindowBorder *FramelessQuickHelperPrivate::findOrCreateWindowBorder() const item->setParent(rootItem); item->setParentItem(rootItem); item->setZ(999); // Make sure it always stays on the top. +#ifndef FRAMELESSHELPER_QUICK_NO_PRIVATE QQuickItemPrivate::get(item)->anchors()->setFill(rootItem); +#endif // FRAMELESSHELPER_QUICK_NO_PRIVATE return item; } @@ -804,6 +814,10 @@ bool FramelessQuickHelperPrivate::shouldIgnoreMouseEvents(const QPoint &pos) con void FramelessQuickHelperPrivate::setSystemButtonState(const QuickGlobal::SystemButtonType button, const QuickGlobal::ButtonState state) { +#ifdef FRAMELESSHELPER_QUICK_NO_PRIVATE + Q_UNUSED(button); + Q_UNUSED(state); +#else // !FRAMELESSHELPER_QUICK_NO_PRIVATE Q_ASSERT(button != QuickGlobal::SystemButtonType::Unknown); if (button == QuickGlobal::SystemButtonType::Unknown) { return; @@ -880,6 +894,7 @@ void FramelessQuickHelperPrivate::setSystemButtonState(const QuickGlobal::System }; updateButtonState(quickButton); } +#endif // FRAMELESSHELPER_QUICK_NO_PRIVATE } QuickHelperData FramelessQuickHelperPrivate::getWindowData() const diff --git a/src/quick/framelessquickmodule.cpp b/src/quick/framelessquickmodule.cpp index 72ea704..1c597cd 100644 --- a/src/quick/framelessquickmodule.cpp +++ b/src/quick/framelessquickmodule.cpp @@ -29,12 +29,14 @@ #include "quickmicamaterial.h" #include "quickimageitem.h" #include "quickwindowborder.h" -#include "framelessquickwindow_p.h" -#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) -# include "framelessquickapplicationwindow_p.h" -# include "quickstandardsystembutton_p.h" -# include "quickstandardtitlebar_p.h" -#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +#ifndef FRAMELESSHELPER_QUICK_NO_PRIVATE +# include "framelessquickwindow_p.h" +# if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +# include "framelessquickapplicationwindow_p.h" +# include "quickstandardsystembutton_p.h" +# include "quickstandardtitlebar_p.h" +# endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +#endif // FRAMELESSHELPER_QUICK_NO_PRIVATE #ifndef QUICK_URI_SHORT # define QUICK_URI_SHORT FRAMELESSHELPER_QUICK_URI, 1 @@ -90,22 +92,28 @@ void FramelessHelper::Quick::registerTypes(QQmlEngine *engine) qmlRegisterAnonymousType(QUICK_URI_SHORT); qmlRegisterType(QUICK_URI_EXPAND("FramelessHelper")); - qmlRegisterType(QUICK_URI_EXPAND("FramelessWindow")); qmlRegisterType(QUICK_URI_EXPAND("MicaMaterial")); qmlRegisterType(QUICK_URI_EXPAND("ImageItem")); qmlRegisterType(QUICK_URI_EXPAND("WindowBorder")); -#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +#ifdef FRAMELESSHELPER_QUICK_NO_PRIVATE + qmlRegisterTypeNotAvailable(QUICK_URI_EXPAND("FramelessWindow"), + FRAMELESSHELPER_STRING_LITERAL("FramelessWindow is not available.")); +#else // !FRAMELESSHELPER_QUICK_NO_PRIVATE + qmlRegisterType(QUICK_URI_EXPAND("FramelessWindow")); +#endif // FRAMELESSHELPER_QUICK_NO_PRIVATE + +#if ((QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) && !defined(FRAMELESSHELPER_QUICK_NO_PRIVATE)) qmlRegisterType(QUICK_URI_EXPAND("FramelessApplicationWindow")); qmlRegisterType(QUICK_URI_EXPAND("StandardSystemButton")); qmlRegisterType(QUICK_URI_EXPAND("StandardTitleBar")); -#else // (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) +#else // ((QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) || FRAMELESSHELPER_QUICK_NO_PRIVATE) qmlRegisterTypeNotAvailable(QUICK_URI_EXPAND("FramelessApplicationWindow"), - FRAMELESSHELPER_STRING_LITERAL("FramelessApplicationWindow is not available until Qt6.")); + FRAMELESSHELPER_STRING_LITERAL("FramelessApplicationWindow is not available.")); qmlRegisterTypeNotAvailable(QUICK_URI_EXPAND("StandardSystemButton"), - FRAMELESSHELPER_STRING_LITERAL("StandardSystemButton is not available until Qt6.")); + FRAMELESSHELPER_STRING_LITERAL("StandardSystemButton is not available.")); qmlRegisterTypeNotAvailable(QUICK_URI_EXPAND("StandardTitleBar"), - FRAMELESSHELPER_STRING_LITERAL("StandardTitleBar is not available until Qt6.")); + FRAMELESSHELPER_STRING_LITERAL("StandardTitleBar is not available.")); #endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) qmlRegisterModule(QUICK_URI_FULL); diff --git a/src/quick/framelessquickwindow.cpp b/src/quick/framelessquickwindow.cpp index 7a12e44..f32ea33 100644 --- a/src/quick/framelessquickwindow.cpp +++ b/src/quick/framelessquickwindow.cpp @@ -22,6 +22,8 @@ * SOFTWARE. */ +#ifndef FRAMELESSHELPER_QUICK_NO_PRIVATE + #include "framelessquickwindow_p.h" #include "framelessquickwindow_p_p.h" #include "framelessquickhelper.h" @@ -239,3 +241,5 @@ void FramelessQuickWindow::componentComplete() } FRAMELESSHELPER_END_NAMESPACE + +#endif // FRAMELESSHELPER_QUICK_NO_PRIVATE diff --git a/src/quick/quickmicamaterial.cpp b/src/quick/quickmicamaterial.cpp index c88b6fe..509da24 100644 --- a/src/quick/quickmicamaterial.cpp +++ b/src/quick/quickmicamaterial.cpp @@ -29,9 +29,11 @@ #include #include #include -#include #include #include +#ifndef FRAMELESSHELPER_QUICK_NO_PRIVATE +# include +#endif // FRAMELESSHELPER_QUICK_NO_PRIVATE FRAMELESSHELPER_BEGIN_NAMESPACE @@ -197,7 +199,9 @@ void QuickMicaMaterialPrivate::rebindWindow() QQuickItem * const rootItem = window->contentItem(); q->setParent(rootItem); q->setParentItem(rootItem); +#ifndef FRAMELESSHELPER_QUICK_NO_PRIVATE QQuickItemPrivate::get(q)->anchors()->setFill(rootItem); +#endif // FRAMELESSHELPER_QUICK_NO_PRIVATE q->setZ(-999); // Make sure we always stays on the bottom most place. if (m_rootWindowXChangedConnection) { disconnect(m_rootWindowXChangedConnection); diff --git a/src/quick/quickstandardsystembutton.cpp b/src/quick/quickstandardsystembutton.cpp index a9d1fe1..20f39a4 100644 --- a/src/quick/quickstandardsystembutton.cpp +++ b/src/quick/quickstandardsystembutton.cpp @@ -22,6 +22,8 @@ * SOFTWARE. */ +#ifndef FRAMELESSHELPER_QUICK_NO_PRIVATE + #include "quickstandardsystembutton_p.h" #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) #include @@ -300,3 +302,5 @@ void QuickStandardSystemButton::componentComplete() FRAMELESSHELPER_END_NAMESPACE #endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + +#endif // FRAMELESSHELPER_QUICK_NO_PRIVATE diff --git a/src/quick/quickstandardtitlebar.cpp b/src/quick/quickstandardtitlebar.cpp index e3c4f9a..13ae909 100644 --- a/src/quick/quickstandardtitlebar.cpp +++ b/src/quick/quickstandardtitlebar.cpp @@ -22,6 +22,8 @@ * SOFTWARE. */ +#ifndef FRAMELESSHELPER_QUICK_NO_PRIVATE + #include "quickstandardtitlebar_p.h" #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) #include "quickimageitem.h" @@ -589,4 +591,6 @@ void QuickStandardTitleBar::componentComplete() } FRAMELESSHELPER_END_NAMESPACE -#endif +#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + +#endif // FRAMELESSHELPER_QUICK_NO_PRIVATE diff --git a/src/quick/quickwindowborder.cpp b/src/quick/quickwindowborder.cpp index c6ccf11..45d8441 100644 --- a/src/quick/quickwindowborder.cpp +++ b/src/quick/quickwindowborder.cpp @@ -25,8 +25,10 @@ #include "quickwindowborder.h" #include "quickwindowborder_p.h" #include -#include #include +#ifndef FRAMELESSHELPER_QUICK_NO_PRIVATE +# include +#endif // FRAMELESSHELPER_QUICK_NO_PRIVATE FRAMELESSHELPER_BEGIN_NAMESPACE @@ -171,7 +173,9 @@ void QuickWindowBorderPrivate::rebindWindow() QQuickItem * const rootItem = window->contentItem(); q->setParent(rootItem); q->setParentItem(rootItem); +#ifndef FRAMELESSHELPER_QUICK_NO_PRIVATE QQuickItemPrivate::get(q)->anchors()->setFill(rootItem); +#endif // FRAMELESSHELPER_QUICK_NO_PRIVATE q->setZ(999); // Make sure we always stays on the top most place. if (m_activeChangeConnection) { disconnect(m_activeChangeConnection); diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt index 9274949..2e29f89 100644 --- a/src/widgets/CMakeLists.txt +++ b/src/widgets/CMakeLists.txt @@ -107,13 +107,19 @@ if(FRAMELESSHELPER_NO_BUNDLE_RESOURCE) ) endif() +if(FRAMELESSHELPER_NO_PRIVATE) + target_compile_definitions(${SUB_PROJ_NAME} PRIVATE + FRAMELESSHELPER_WIDGETS_NO_PRIVATE + ) +endif() + target_compile_definitions(${SUB_PROJ_NAME} PRIVATE QT_NO_KEYWORDS FRAMELESSHELPER_WIDGETS_LIBRARY ) target_link_libraries(${SUB_PROJ_NAME} PRIVATE - Qt${QT_VERSION_MAJOR}::WidgetsPrivate + Qt${QT_VERSION_MAJOR}::Widgets ) target_link_libraries(${SUB_PROJ_NAME} PUBLIC diff --git a/src/widgets/framelesswidgetshelper.cpp b/src/widgets/framelesswidgetshelper.cpp index 80b98bd..e0066ec 100644 --- a/src/widgets/framelesswidgetshelper.cpp +++ b/src/widgets/framelesswidgetshelper.cpp @@ -41,6 +41,10 @@ #include #include +#ifndef QWIDGETSIZE_MAX +# define QWIDGETSIZE_MAX ((1 << 24) - 1) +#endif // QWIDGETSIZE_MAX + FRAMELESSHELPER_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcFramelessWidgetsHelper, "wangwenx190.framelesshelper.widgets.framelesswidgetshelper") @@ -815,7 +819,7 @@ void FramelessWidgetsHelperPrivate::showSystemMenu(const QPoint &pos) return; } const QPoint globalPos = m_window->mapToGlobal(pos); - const QPoint nativePos = QPointF(QPointF(globalPos) * m_window->devicePixelRatioF()).toPoint(); + const QPoint nativePos = Utils::toNativePixels(m_window->windowHandle(), globalPos); Utils::showSystemMenu(m_window->winId(), nativePos, false, [this]() -> bool { return isWindowFixedSize(); }); #else // ### TODO