refactor
This commit is contained in:
parent
b946809927
commit
d86f55832f
|
@ -31,6 +31,7 @@ project(FramelessHelper
|
|||
)
|
||||
|
||||
include(CMakeDependentOption)
|
||||
include(cmake/utils.cmake)
|
||||
|
||||
# TODO: Use add_feature_info() for every option below? Is it worth doing?
|
||||
option(FRAMELESSHELPER_BUILD_STATIC "Build FramelessHelper as a static library." OFF)
|
||||
|
@ -61,16 +62,7 @@ option(FRAMELESSHELPER_NO_TRANSLATION "Don't bundle the I18N translations into t
|
|||
option(FRAMELESSHELPER_NO_MICA_MATERIAL "Disable the cross-platform homemade Mica Material." OFF)
|
||||
option(FRAMELESSHELPER_NO_BORDER_PAINTER "Disable the cross-platform window frame border painter." OFF)
|
||||
option(FRAMELESSHELPER_NO_SYSTEM_BUTTON "Disable the pre-defined StandardSystemButton control." OFF)
|
||||
|
||||
if(FRAMELESSHELPER_NO_WINDOW AND FRAMELESSHELPER_BUILD_EXAMPLES)
|
||||
message(WARNING "You can't build the examples when the FramelessWindow class is disabled at the same time!")
|
||||
set(FRAMELESSHELPER_BUILD_EXAMPLES OFF)
|
||||
endif()
|
||||
|
||||
set(FRAMELESSHELPER_64BIT_POSTFIX "")
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(FRAMELESSHELPER_64BIT_POSTFIX "64")
|
||||
endif()
|
||||
cmake_dependent_option(FRAMELESSHELPER_NATIVE_IMPL "Use platform native implementation instead of Qt to get best experience." ON WIN32 OFF)
|
||||
|
||||
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Gui)
|
||||
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Gui)
|
||||
|
@ -78,10 +70,18 @@ find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Gui)
|
|||
find_package(QT NAMES Qt6 Qt5 QUIET COMPONENTS Widgets Quick)
|
||||
find_package(Qt${QT_VERSION_MAJOR} QUIET COMPONENTS Widgets Quick)
|
||||
|
||||
include(cmake/utils.cmake)
|
||||
if(FRAMELESSHELPER_NATIVE_IMPL AND NOT WIN32)
|
||||
message(WARNING "FRAMELESSHELPER_NATIVE_IMPL currently only supports the Windows platform!")
|
||||
set(FRAMELESSHELPER_NATIVE_IMPL OFF)
|
||||
endif()
|
||||
|
||||
if(NOT APPLE AND FRAMELESSHELPER_ENABLE_UNIVERSAL_BUILD)
|
||||
message(WARNING "Current OS is not macOS, universal build will be disabled.")
|
||||
if(FRAMELESSHELPER_NO_WINDOW AND FRAMELESSHELPER_BUILD_EXAMPLES)
|
||||
message(WARNING "You can't build the examples when the FramelessWindow class is disabled at the same time!")
|
||||
set(FRAMELESSHELPER_BUILD_EXAMPLES OFF)
|
||||
endif()
|
||||
|
||||
if(FRAMELESSHELPER_ENABLE_UNIVERSAL_BUILD AND NOT APPLE)
|
||||
message(WARNING "Universal build is a macOS only feature, it will be disabled on current platform.")
|
||||
set(FRAMELESSHELPER_ENABLE_UNIVERSAL_BUILD OFF)
|
||||
elseif(APPLE AND ((QT_VERSION VERSION_LESS "6.2" AND QT_VERSION VERSION_GREATER_EQUAL "6.0") OR (QT_VERSION VERSION_LESS "5.15.9")))
|
||||
message(WARNING "Your Qt version ${QT_VERSION} doesn't support universal build, it will be disabled.")
|
||||
|
@ -94,6 +94,29 @@ endif()
|
|||
|
||||
if(FRAMELESSHELPER_ENABLE_VCLTL AND NOT MSVC)
|
||||
message(WARNING "VC-LTL is only available for the MSVC toolchain.")
|
||||
set(FRAMELESSHELPER_ENABLE_VCLTL OFF)
|
||||
endif()
|
||||
|
||||
if(FRAMELESSHELPER_ENABLE_YYTHUNKS AND NOT MSVC)
|
||||
message(WARNING "YY-Thunks is only available for the MSVC toolchain.")
|
||||
set(FRAMELESSHELPER_ENABLE_YYTHUNKS OFF)
|
||||
endif()
|
||||
|
||||
if(NOT TARGET Qt${QT_VERSION_MAJOR}::Core OR NOT TARGET Qt${QT_VERSION_MAJOR}::Gui)
|
||||
message(WARNING "Can't find the QtCore and/or QtGui module. Nothing will be built.")
|
||||
set(FRAMELESSHELPER_BUILD_WIDGETS OFF)
|
||||
set(FRAMELESSHELPER_BUILD_QUICK OFF)
|
||||
set(FRAMELESSHELPER_BUILD_EXAMPLES OFF)
|
||||
endif()
|
||||
|
||||
if(FRAMELESSHELPER_BUILD_QUICK AND NOT TARGET Qt${QT_VERSION_MAJOR}::Quick)
|
||||
message(WARNING "Can't find the QtQuick module. FramelessHelper's QtQuick implementation and the QtQuick demo won't be built.")
|
||||
set(FRAMELESSHELPER_BUILD_QUICK OFF)
|
||||
endif()
|
||||
|
||||
set(FRAMELESSHELPER_64BIT_POSTFIX "")
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(FRAMELESSHELPER_64BIT_POSTFIX "64")
|
||||
endif()
|
||||
|
||||
set(FRAMELESSHELPER_LICENSE_HEADER "/*
|
||||
|
@ -144,25 +167,23 @@ if(MINGW AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
|||
set(FRAMELESSHELPER_ENABLE_CFGUARD OFF)
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
if(FRAMELESSHELPER_ENABLE_VCLTL)
|
||||
include(cmake/VC-LTL.cmake)
|
||||
if("x${SupportLTL}" STREQUAL "xtrue")
|
||||
# Make sure we will always overwrite the previous settings.
|
||||
unset(CMAKE_MSVC_RUNTIME_LIBRARY)
|
||||
unset(CMAKE_MSVC_RUNTIME_LIBRARY CACHE)
|
||||
#unset(CMAKE_MSVC_RUNTIME_LIBRARY PARENT_SCOPE)
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>" CACHE STRING "" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
if(FRAMELESSHELPER_ENABLE_YYTHUNKS)
|
||||
unset(YYTHUNKS_TARGET_OS)
|
||||
unset(YYTHUNKS_TARGET_OS CACHE)
|
||||
#unset(YYTHUNKS_TARGET_OS PARENT_SCOPE)
|
||||
set(YYTHUNKS_TARGET_OS "WinXP" CACHE STRING "" FORCE)
|
||||
include(cmake/YY-Thunks.cmake)
|
||||
if(FRAMELESSHELPER_ENABLE_VCLTL)
|
||||
include(cmake/VC-LTL.cmake)
|
||||
if("x${SupportLTL}" STREQUAL "xtrue")
|
||||
# Make sure we will always overwrite the previous settings.
|
||||
unset(CMAKE_MSVC_RUNTIME_LIBRARY)
|
||||
unset(CMAKE_MSVC_RUNTIME_LIBRARY CACHE)
|
||||
#unset(CMAKE_MSVC_RUNTIME_LIBRARY PARENT_SCOPE)
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>" CACHE STRING "" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
if(FRAMELESSHELPER_ENABLE_YYTHUNKS)
|
||||
unset(YYTHUNKS_TARGET_OS)
|
||||
unset(YYTHUNKS_TARGET_OS CACHE)
|
||||
#unset(YYTHUNKS_TARGET_OS PARENT_SCOPE)
|
||||
set(YYTHUNKS_TARGET_OS "WinXP" CACHE STRING "" FORCE)
|
||||
include(cmake/YY-Thunks.cmake)
|
||||
endif()
|
||||
|
||||
set(__extra_flags "")
|
||||
if(FRAMELESSHELPER_NO_INSTALL)
|
||||
|
@ -175,11 +196,6 @@ prepare_package_export(
|
|||
)
|
||||
unset(__extra_flags)
|
||||
|
||||
if(FRAMELESSHELPER_BUILD_QUICK AND NOT TARGET Qt${QT_VERSION_MAJOR}::Quick)
|
||||
message(WARNING "Can't find the QtQuick module. FramelessHelper's QtQuick implementation and the QtQuick demo won't be built.")
|
||||
set(FRAMELESSHELPER_BUILD_QUICK OFF)
|
||||
endif()
|
||||
|
||||
set(FRAMELESSHELPER_VERSION_FILE "${PROJECT_BINARY_DIR}/framelesshelper.version")
|
||||
generate_project_version(
|
||||
PATH "${FRAMELESSHELPER_VERSION_FILE}"
|
||||
|
@ -202,14 +218,11 @@ add_project_config(KEY "translation" CONDITION NOT FRAMELESSHELPER_NO_TRANSLATIO
|
|||
add_project_config(KEY "mica_material" CONDITION NOT FRAMELESSHELPER_NO_MICA_MATERIAL)
|
||||
add_project_config(KEY "border_painter" CONDITION NOT FRAMELESSHELPER_NO_BORDER_PAINTER)
|
||||
add_project_config(KEY "system_button" CONDITION NOT FRAMELESSHELPER_NO_SYSTEM_BUTTON)
|
||||
add_project_config(KEY "native_impl" CONDITION FRAMELESSHELPER_NATIVE_IMPL)
|
||||
generate_project_config(PATH "${FRAMELESSHELPER_CONFIG_FILE}")
|
||||
|
||||
if(TARGET Qt${QT_VERSION_MAJOR}::Core AND TARGET Qt${QT_VERSION_MAJOR}::Gui)
|
||||
if(FRAMELESSHELPER_BUILD_WIDGETS OR FRAMELESSHELPER_BUILD_QUICK)
|
||||
add_subdirectory(src)
|
||||
else()
|
||||
message(WARNING "Can't find the QtCore and QtGui module. Nothing will be built.")
|
||||
set(FRAMELESSHELPER_BUILD_WIDGETS OFF)
|
||||
set(FRAMELESSHELPER_BUILD_EXAMPLES OFF)
|
||||
endif()
|
||||
|
||||
if(FRAMELESSHELPER_BUILD_EXAMPLES)
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
@echo off
|
||||
title Building FramelessHelper ...
|
||||
setlocal
|
||||
cls
|
||||
set __vs_bat=%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat
|
||||
if not exist "%__vs_bat%" set __vs_bat=%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat
|
||||
if not exist "%__vs_bat%" set __vs_bat=%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat
|
||||
if not exist "%__vs_bat%" set __vs_bat=%ProgramFiles(x86)%\Microsoft Visual Studio\2015\Community\VC\Auxiliary\Build\vcvars64.bat
|
||||
if not exist "%__vs_bat%" (
|
||||
echo Cannot find a valid Visual Studio toolchain!
|
||||
echo Please install at least Visual Studio 2015 to the default location
|
||||
echo and install the English language pack at the same time.
|
||||
echo If you want to use clang-cl or MinGW to build this project, please
|
||||
echo make sure you have added their directory to your PATH environment
|
||||
echo variable.
|
||||
echo Press the ENTER key to continue, or close this window directly.
|
||||
pause
|
||||
) else (
|
||||
call "%__vs_bat%"
|
||||
)
|
||||
cmake --version
|
||||
echo ninja build
|
||||
ninja --version
|
||||
cd /d "%~dp0"
|
||||
if exist build.user.bat call build.user.bat
|
||||
if not defined CC set CC=cl.exe
|
||||
if not defined CXX set CXX=cl.exe
|
||||
if not defined QTDIR set QTDIR=%SystemDrive%\Qt\6.6.0\msvc2019_64
|
||||
echo CC=%CC%
|
||||
echo CXX=%CXX%
|
||||
echo QTDIR=%QTDIR%
|
||||
if exist build rd /s /q build
|
||||
md build
|
||||
cd build
|
||||
md cmake
|
||||
cd cmake
|
||||
cmake -DCMAKE_C_COMPILER="%CC%" -DCMAKE_CXX_COMPILER="%CXX%" -DCMAKE_PREFIX_PATH="%QTDIR%" -DCMAKE_INSTALL_PREFIX="%~dp0build\install" -DCMAKE_CONFIGURATION_TYPES=Release;Debug -G"Ninja Multi-Config" -DFRAMELESSHELPER_ENABLE_VCLTL=ON -DFRAMELESSHELPER_ENABLE_YYTHUNKS=ON -DFRAMELESSHELPER_ENABLE_SPECTRE=ON -DFRAMELESSHELPER_ENABLE_EHCONTGUARD=ON -DFRAMELESSHELPER_ENABLE_INTELCET=ON -DFRAMELESSHELPER_ENABLE_INTELJCC=ON -DFRAMELESSHELPER_ENABLE_CFGUARD=ON -DFRAMELESSHELPER_FORCE_LTO=ON "%~dp0"
|
||||
cmake --build . --target all --config Release --parallel
|
||||
cmake --build . --target all --config Debug --parallel
|
||||
cmake --install . --config Release --strip
|
||||
cmake --install . --config Debug
|
||||
goto fin
|
||||
:fin
|
||||
endlocal
|
||||
cd /d "%~dp0"
|
||||
pause
|
||||
exit /b 0
|
|
@ -1,37 +0,0 @@
|
|||
@echo off
|
||||
title Building FramelessHelper ...
|
||||
setlocal
|
||||
cls
|
||||
set __vs_bat=%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat
|
||||
if not exist "%__vs_bat%" set __vs_bat=%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat
|
||||
if not exist "%__vs_bat%" set __vs_bat=%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat
|
||||
if not exist "%__vs_bat%" set __vs_bat=%ProgramFiles(x86)%\Microsoft Visual Studio\2015\Community\VC\Auxiliary\Build\vcvars64.bat
|
||||
if not exist "%__vs_bat%" (
|
||||
echo Cannot find a valid Visual Studio toolchain!
|
||||
echo Please install at least Visual Studio 2015 to the default location!
|
||||
goto fin
|
||||
)
|
||||
call "%__vs_bat%"
|
||||
cmake --version
|
||||
echo ninja build
|
||||
ninja --version
|
||||
cd /d "%~dp0"
|
||||
if exist "%~dp0build.user.bat" call "%~dp0build.user.bat"
|
||||
if not defined QTDIR set QTDIR=C:\Qt\6.6.0\msvc2019_64
|
||||
echo QTDIR=%QTDIR%
|
||||
if exist cmake rd /s /q cmake
|
||||
md cmake
|
||||
cd cmake
|
||||
md build
|
||||
cd build
|
||||
cmake -DCMAKE_PREFIX_PATH="%QTDIR%" -DCMAKE_INSTALL_PREFIX="%~dp0cmake\install" -DCMAKE_CONFIGURATION_TYPES=Release;Debug -G"Ninja Multi-Config" -DFRAMELESSHELPER_ENABLE_VCLTL=ON -DFRAMELESSHELPER_ENABLE_YYTHUNKS=ON -DFRAMELESSHELPER_ENABLE_SPECTRE=ON -DFRAMELESSHELPER_ENABLE_EHCONTGUARD=ON -DFRAMELESSHELPER_ENABLE_INTELCET=ON -DFRAMELESSHELPER_ENABLE_INTELJCC=ON -DFRAMELESSHELPER_ENABLE_CFGUARD=ON -DFRAMELESSHELPER_FORCE_LTO=ON "%~dp0.."
|
||||
cmake --build . --target all --config Release --parallel
|
||||
cmake --build . --target all --config Debug --parallel
|
||||
cmake --install . --config Release --strip
|
||||
cmake --install . --config Debug
|
||||
goto fin
|
||||
:fin
|
||||
endlocal
|
||||
cd /d "%~dp0"
|
||||
pause
|
||||
exit /b 0
|
|
@ -31,13 +31,10 @@
|
|||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
class ChromePalettePrivate;
|
||||
|
||||
class FRAMELESSHELPER_CORE_API ChromePalette : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DECLARE_PRIVATE(ChromePalette)
|
||||
Q_DISABLE_COPY_MOVE(ChromePalette)
|
||||
FRAMELESSHELPER_PUBLIC_QT_CLASS(ChromePalette)
|
||||
|
||||
Q_PROPERTY(QColor titleBarActiveBackgroundColor READ titleBarActiveBackgroundColor
|
||||
WRITE setTitleBarActiveBackgroundColor RESET resetTitleBarActiveBackgroundColor
|
||||
|
@ -120,9 +117,6 @@ Q_SIGNALS:
|
|||
void closeButtonPressColorChanged();
|
||||
void titleBarColorChanged();
|
||||
void chromeButtonColorChanged();
|
||||
|
||||
private:
|
||||
QScopedPointer<ChromePalettePrivate> d_ptr;
|
||||
};
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
|
|
@ -26,25 +26,27 @@
|
|||
|
||||
#include <FramelessHelper/Core/framelesshelpercore_global.h>
|
||||
|
||||
#if !FRAMELESSHELPER_CONFIG(native_impl)
|
||||
|
||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
struct SystemParameters;
|
||||
|
||||
class FramelessHelperQtPrivate;
|
||||
class FRAMELESSHELPER_CORE_API FramelessHelperQt : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DISABLE_COPY_MOVE(FramelessHelperQt)
|
||||
FRAMELESSHELPER_PUBLIC_QT_CLASS(FramelessHelperQt)
|
||||
|
||||
public:
|
||||
explicit FramelessHelperQt(QObject *parent = nullptr);
|
||||
~FramelessHelperQt() override;
|
||||
|
||||
static void addWindow(const SystemParameters *params);
|
||||
static void removeWindow(const WId windowId);
|
||||
static void addWindow(const QObject *window);
|
||||
static void removeWindow(const QObject *window);
|
||||
|
||||
protected:
|
||||
Q_NODISCARD bool eventFilter(QObject *object, QEvent *event) override;
|
||||
};
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
||||
#endif // !native_impl
|
||||
|
|
|
@ -29,24 +29,26 @@
|
|||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
|
||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
#if FRAMELESSHELPER_CONFIG(native_impl)
|
||||
|
||||
struct SystemParameters;
|
||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
class FRAMELESSHELPER_CORE_API FramelessHelperWin : public QAbstractNativeEventFilter
|
||||
{
|
||||
Q_DISABLE_COPY_MOVE(FramelessHelperWin)
|
||||
FRAMELESSHELPER_CLASS(FramelessHelperWin)
|
||||
|
||||
public:
|
||||
explicit FramelessHelperWin();
|
||||
~FramelessHelperWin() override;
|
||||
|
||||
static void addWindow(const SystemParameters *params);
|
||||
static void removeWindow(const WId windowId);
|
||||
static void addWindow(const QObject *window);
|
||||
static void removeWindow(const QObject *window);
|
||||
|
||||
Q_NODISCARD bool nativeEventFilter(const QByteArray &eventType, void *message, QT_NATIVE_EVENT_RESULT_TYPE *result) override;
|
||||
};
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
||||
#endif // native_impl
|
||||
|
||||
#endif // Q_OS_WINDOWS
|
||||
|
|
|
@ -86,6 +86,46 @@
|
|||
|
||||
#include <FramelessHelper/Core/framelesshelpercore_global.h>
|
||||
|
||||
#ifndef SC_SIZE
|
||||
# define SC_SIZE (0xF000)
|
||||
#endif
|
||||
|
||||
#ifndef SC_SIZELEFT
|
||||
# define SC_SIZELEFT (0xF001)
|
||||
#endif
|
||||
|
||||
#ifndef SC_SIZERIGHT
|
||||
# define SC_SIZERIGHT (0xF002)
|
||||
#endif
|
||||
|
||||
#ifndef SC_SIZETOP
|
||||
# define SC_SIZETOP (0xF003)
|
||||
#endif
|
||||
|
||||
#ifndef SC_SIZETOPLEFT
|
||||
# define SC_SIZETOPLEFT (0xF004)
|
||||
#endif
|
||||
|
||||
#ifndef SC_SIZETOPRIGHT
|
||||
# define SC_SIZETOPRIGHT (0xF005)
|
||||
#endif
|
||||
|
||||
#ifndef SC_SIZEBOTTOM
|
||||
# define SC_SIZEBOTTOM (0xF006)
|
||||
#endif
|
||||
|
||||
#ifndef SC_SIZEBOTTOMLEFT
|
||||
# define SC_SIZEBOTTOMLEFT (0xF007)
|
||||
#endif
|
||||
|
||||
#ifndef SC_SIZEBOTTOMRIGHT
|
||||
# define SC_SIZEBOTTOMRIGHT (0xF008)
|
||||
#endif
|
||||
|
||||
#ifndef SC_DRAGMOVE
|
||||
# define SC_DRAGMOVE (0xF012)
|
||||
#endif
|
||||
|
||||
#ifndef WM_SIZEWAIT
|
||||
# define WM_SIZEWAIT (0x0004)
|
||||
#endif
|
||||
|
@ -1102,7 +1142,7 @@ _AdjustWindowRectExForDpi2(
|
|||
|
||||
EXTERN_C_END
|
||||
|
||||
[[maybe_unused]] inline constexpr const int kAutoHideTaskBarThickness = 2; // The thickness of an auto-hide taskbar in pixels.
|
||||
[[maybe_unused]] inline constexpr const unsigned char kAutoHideTaskBarThickness = 2; // The thickness of an auto-hide taskbar in pixels.
|
||||
[[maybe_unused]] inline constexpr const wchar_t kDwmRegistryKey[] = LR"(Software\Microsoft\Windows\DWM)";
|
||||
[[maybe_unused]] inline constexpr const wchar_t kPersonalizeRegistryKey[] = LR"(Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)";
|
||||
[[maybe_unused]] inline constexpr const wchar_t kThemeSettingChangeEventName[] = L"ImmersiveColorSet";
|
||||
|
@ -1111,3 +1151,95 @@ EXTERN_C_END
|
|||
[[maybe_unused]] inline constexpr const wchar_t kSystemLightThemeResourceName[] = L"Explorer";
|
||||
[[maybe_unused]] inline constexpr const wchar_t kDesktopRegistryKey[] = LR"(Control Panel\Desktop)";
|
||||
[[maybe_unused]] inline constexpr const wchar_t kDarkModePropertyName[] = L"UseImmersiveDarkModeColors";
|
||||
|
||||
[[maybe_unused]] [[nodiscard]] inline constexpr bool operator==(const POINT &lhs, const POINT &rhs) noexcept
|
||||
{
|
||||
return ((lhs.x == rhs.x) && (lhs.y == rhs.y));
|
||||
}
|
||||
|
||||
[[maybe_unused]] [[nodiscard]] inline constexpr bool operator!=(const POINT &lhs, const POINT &rhs) noexcept
|
||||
{
|
||||
return !operator==(lhs, rhs);
|
||||
}
|
||||
|
||||
[[maybe_unused]] [[nodiscard]] inline constexpr bool operator==(const SIZE &lhs, const SIZE &rhs) noexcept
|
||||
{
|
||||
return ((lhs.cx == rhs.cx) && (lhs.cy == rhs.cy));
|
||||
}
|
||||
|
||||
[[maybe_unused]] [[nodiscard]] inline constexpr bool operator!=(const SIZE &lhs, const SIZE &rhs) noexcept
|
||||
{
|
||||
return !operator==(lhs, rhs);
|
||||
}
|
||||
|
||||
[[maybe_unused]] [[nodiscard]] inline constexpr bool operator>(const SIZE &lhs, const SIZE &rhs) noexcept
|
||||
{
|
||||
return ((lhs.cx * lhs.cy) > (rhs.cx * rhs.cy));
|
||||
}
|
||||
|
||||
[[maybe_unused]] [[nodiscard]] inline constexpr bool operator>=(const SIZE &lhs, const SIZE &rhs) noexcept
|
||||
{
|
||||
return (operator>(lhs, rhs) || operator==(lhs, rhs));
|
||||
}
|
||||
|
||||
[[maybe_unused]] [[nodiscard]] inline constexpr bool operator<(const SIZE &lhs, const SIZE &rhs) noexcept
|
||||
{
|
||||
return (operator!=(lhs, rhs) && !operator>(lhs, rhs));
|
||||
}
|
||||
|
||||
[[maybe_unused]] [[nodiscard]] inline constexpr bool operator<=(const SIZE &lhs, const SIZE &rhs) noexcept
|
||||
{
|
||||
return (operator<(lhs, rhs) || operator==(lhs, rhs));
|
||||
}
|
||||
|
||||
[[maybe_unused]] [[nodiscard]] inline constexpr bool operator==(const RECT &lhs, const RECT &rhs) noexcept
|
||||
{
|
||||
return ((lhs.left == rhs.left) && (lhs.top == rhs.top) && (lhs.right == rhs.right) && (lhs.bottom == rhs.bottom));
|
||||
}
|
||||
|
||||
[[maybe_unused]] [[nodiscard]] inline constexpr bool operator!=(const RECT &lhs, const RECT &rhs) noexcept
|
||||
{
|
||||
return !operator==(lhs, rhs);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline constexpr QPoint point2qpoint(const POINT &point)
|
||||
{
|
||||
return QPoint{ int(point.x), int(point.y) };
|
||||
}
|
||||
|
||||
[[nodiscard]] inline constexpr POINT qpoint2point(const QPoint &point)
|
||||
{
|
||||
return POINT{ LONG(point.x()), LONG(point.y()) };
|
||||
}
|
||||
|
||||
[[nodiscard]] inline constexpr QSize size2qsize(const SIZE &size)
|
||||
{
|
||||
return QSize{ int(size.cx), int(size.cy) };
|
||||
}
|
||||
|
||||
[[nodiscard]] inline constexpr SIZE qsize2size(const QSize &size)
|
||||
{
|
||||
return SIZE{ LONG(size.width()), LONG(size.height()) };
|
||||
}
|
||||
|
||||
[[nodiscard]] inline constexpr QRect rect2qrect(const RECT &rect)
|
||||
{
|
||||
return QRect{ QPoint{ int(rect.left), int(rect.top) }, QSize{ int(RECT_WIDTH(rect)), int(RECT_HEIGHT(rect)) } };
|
||||
}
|
||||
|
||||
[[nodiscard]] inline constexpr RECT qrect2rect(const QRect &qrect)
|
||||
{
|
||||
return RECT{ LONG(qrect.left()), LONG(qrect.top()), LONG(qrect.right()), LONG(qrect.bottom()) };
|
||||
}
|
||||
|
||||
[[nodiscard]] inline /*constexpr*/ QString hwnd2str(const WId windowId)
|
||||
{
|
||||
// NULL handle is allowed here.
|
||||
return FRAMELESSHELPER_STRING_LITERAL("0x") + QString::number(windowId, 16).toUpper().rightJustified(8, u'0');
|
||||
}
|
||||
|
||||
[[nodiscard]] inline /*constexpr*/ QString hwnd2str(const HWND hwnd)
|
||||
{
|
||||
// NULL handle is allowed here.
|
||||
return hwnd2str(reinterpret_cast<WId>(hwnd));
|
||||
}
|
||||
|
|
|
@ -67,11 +67,16 @@ QT_END_NAMESPACE
|
|||
# define Q_OS_WINDOWS // Since 5.14
|
||||
#endif
|
||||
|
||||
#ifndef Q_DISABLE_MOVE
|
||||
# define Q_DISABLE_MOVE(Class) \
|
||||
Class(Class &&) = delete; \
|
||||
Class &operator=(Class &&) = delete;
|
||||
#endif
|
||||
|
||||
#ifndef Q_DISABLE_COPY_MOVE // Since 5.13
|
||||
# define Q_DISABLE_COPY_MOVE(Class) \
|
||||
Q_DISABLE_COPY(Class) \
|
||||
Class(Class &&) = delete; \
|
||||
Class &operator=(Class &&) = delete;
|
||||
Q_DISABLE_MOVE(Class)
|
||||
#endif
|
||||
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 10, 0))
|
||||
|
@ -253,6 +258,83 @@ QT_END_NAMESPACE
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef FRAMELESSHELPER_CLASS
|
||||
# define FRAMELESSHELPER_CLASS(Class) \
|
||||
private: \
|
||||
Q_DISABLE_COPY(Class)
|
||||
#endif
|
||||
|
||||
#ifndef FRAMELESSHELPER_CLASS_DPTR
|
||||
# define FRAMELESSHELPER_CLASS_DPTR(Class) \
|
||||
private: \
|
||||
Q_DECLARE_PRIVATE(Class) \
|
||||
const QScopedPointer<Class##Private> d_ptr;
|
||||
#endif
|
||||
|
||||
#ifndef FRAMELESSHELPER_CLASS_QPTR
|
||||
# define FRAMELESSHELPER_CLASS_QPTR(Class) \
|
||||
private: \
|
||||
Q_DECLARE_PUBLIC(Class) \
|
||||
public: \
|
||||
Class *q_ptr = nullptr;
|
||||
#endif
|
||||
|
||||
#ifndef FRAMELESSHELPER_PRIVATE_CLASS_GETTER
|
||||
# define FRAMELESSHELPER_PRIVATE_CLASS_GETTER(Class) \
|
||||
public: \
|
||||
Q_NODISCARD static Class##Private *get(Class *q); \
|
||||
Q_NODISCARD static const Class##Private *get(const Class *q);
|
||||
#endif
|
||||
|
||||
#ifndef FRAMELESSHELPER_PRIVATE_CLASS_GETTER_IMPL
|
||||
# define FRAMELESSHELPER_PRIVATE_CLASS_GETTER_IMPL(Class) \
|
||||
Class##Private *Class##Private::get(Class *q) { \
|
||||
Q_ASSERT(q); \
|
||||
return (q ? q->d_func() : nullptr); \
|
||||
} \
|
||||
const Class##Private *Class##Private::get(const Class *q) { \
|
||||
Q_ASSERT(q); \
|
||||
return (q ? q->d_func() : nullptr); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef FRAMELESSHELPER_PUBLIC_CLASS
|
||||
# define FRAMELESSHELPER_PUBLIC_CLASS(Class) \
|
||||
private: \
|
||||
FRAMELESSHELPER_CLASS(Class) \
|
||||
FRAMELESSHELPER_CLASS_DPTR(Class)
|
||||
#endif
|
||||
|
||||
#ifndef FRAMELESSHELPER_PRIVATE_CLASS
|
||||
# define FRAMELESSHELPER_PRIVATE_CLASS(Class) \
|
||||
private: \
|
||||
FRAMELESSHELPER_CLASS(Class##Private) \
|
||||
FRAMELESSHELPER_CLASS_QPTR(Class) \
|
||||
FRAMELESSHELPER_PRIVATE_CLASS_GETTER(Class)
|
||||
#endif
|
||||
|
||||
#ifndef FRAMELESSHELPER_QT_CLASS
|
||||
# define FRAMELESSHELPER_QT_CLASS(Class) \
|
||||
private: \
|
||||
FRAMELESSHELPER_CLASS_INFO \
|
||||
FRAMELESSHELPER_CLASS(Class)
|
||||
#endif
|
||||
|
||||
#ifndef FRAMELESSHELPER_PUBLIC_QT_CLASS
|
||||
# define FRAMELESSHELPER_PUBLIC_QT_CLASS(Class) \
|
||||
private: \
|
||||
FRAMELESSHELPER_QT_CLASS(Class) \
|
||||
FRAMELESSHELPER_CLASS_DPTR(Class)
|
||||
#endif
|
||||
|
||||
#ifndef FRAMELESSHELPER_PRIVATE_QT_CLASS
|
||||
# define FRAMELESSHELPER_PRIVATE_QT_CLASS(Class) \
|
||||
private: \
|
||||
FRAMELESSHELPER_QT_CLASS(Class##Private) \
|
||||
FRAMELESSHELPER_CLASS_QPTR(Class) \
|
||||
FRAMELESSHELPER_PRIVATE_CLASS_GETTER(Class)
|
||||
#endif
|
||||
|
||||
#if FRAMELESSHELPER_CONFIG(bundle_resource)
|
||||
// Call this function in your main() function if you are using FramelessHelper as a static library,
|
||||
// it can make sure the resources bundled in the static library are correctly initialized.
|
||||
|
|
|
@ -28,15 +28,11 @@
|
|||
|
||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
struct SystemParameters;
|
||||
class FramelessManagerPrivate;
|
||||
|
||||
class FRAMELESSHELPER_CORE_API FramelessManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DECLARE_PRIVATE(FramelessManager)
|
||||
Q_DISABLE_COPY_MOVE(FramelessManager)
|
||||
FRAMELESSHELPER_PUBLIC_QT_CLASS(FramelessManager)
|
||||
Q_PROPERTY(Global::SystemTheme systemTheme READ systemTheme WRITE setOverrideTheme NOTIFY systemThemeChanged FINAL)
|
||||
Q_PROPERTY(QColor systemAccentColor READ systemAccentColor NOTIFY systemThemeChanged FINAL)
|
||||
Q_PROPERTY(QString wallpaper READ wallpaper NOTIFY wallpaperChanged FINAL)
|
||||
|
@ -51,8 +47,8 @@ public:
|
|||
Q_NODISCARD Global::WallpaperAspectStyle wallpaperAspectStyle() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void addWindow(const SystemParameters *params);
|
||||
void removeWindow(const WId windowId);
|
||||
Q_NODISCARD bool addWindow(const QObject *window, const WId windowId);
|
||||
Q_NODISCARD bool removeWindow(const QObject *window);
|
||||
void setOverrideTheme(const Global::SystemTheme theme);
|
||||
|
||||
Q_SIGNALS:
|
||||
|
@ -62,9 +58,6 @@ Q_SIGNALS:
|
|||
private:
|
||||
explicit FramelessManager(QObject *parent = nullptr);
|
||||
~FramelessManager() override;
|
||||
|
||||
private:
|
||||
QScopedPointer<FramelessManagerPrivate> d_ptr;
|
||||
};
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
|
|
@ -31,13 +31,10 @@
|
|||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
class MicaMaterialPrivate;
|
||||
|
||||
class FRAMELESSHELPER_CORE_API MicaMaterial : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DISABLE_COPY_MOVE(MicaMaterial)
|
||||
Q_DECLARE_PRIVATE(MicaMaterial)
|
||||
FRAMELESSHELPER_PUBLIC_QT_CLASS(MicaMaterial)
|
||||
|
||||
Q_PROPERTY(QColor tintColor READ tintColor WRITE setTintColor NOTIFY tintColorChanged FINAL)
|
||||
Q_PROPERTY(qreal tintOpacity READ tintOpacity WRITE setTintOpacity NOTIFY tintOpacityChanged FINAL)
|
||||
|
@ -80,9 +77,6 @@ Q_SIGNALS:
|
|||
void noiseOpacityChanged();
|
||||
void fallbackEnabledChanged();
|
||||
void shouldRedraw();
|
||||
|
||||
private:
|
||||
QScopedPointer<MicaMaterialPrivate> d_ptr;
|
||||
};
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
|
|
@ -32,24 +32,17 @@
|
|||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
class ChromePalette;
|
||||
|
||||
class FRAMELESSHELPER_CORE_API ChromePalettePrivate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DECLARE_PUBLIC(ChromePalette)
|
||||
Q_DISABLE_COPY_MOVE(ChromePalettePrivate)
|
||||
FRAMELESSHELPER_PRIVATE_QT_CLASS(ChromePalette)
|
||||
|
||||
public:
|
||||
explicit ChromePalettePrivate(ChromePalette *q);
|
||||
~ChromePalettePrivate() override;
|
||||
|
||||
Q_NODISCARD static ChromePalettePrivate *get(ChromePalette *q);
|
||||
Q_NODISCARD static const ChromePalettePrivate *get(const ChromePalette *q);
|
||||
|
||||
Q_SLOT void refresh();
|
||||
|
||||
ChromePalette *q_ptr = nullptr;
|
||||
// System-defined ones:
|
||||
QColor titleBarActiveBackgroundColor_sys = {};
|
||||
QColor titleBarInactiveBackgroundColor_sys = {};
|
||||
|
|
|
@ -31,8 +31,7 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
|
|||
class FRAMELESSHELPER_CORE_API FramelessConfig : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DISABLE_COPY_MOVE(FramelessConfig)
|
||||
FRAMELESSHELPER_QT_CLASS(FramelessConfig)
|
||||
|
||||
public:
|
||||
Q_NODISCARD static FramelessConfig *instance();
|
||||
|
|
|
@ -25,7 +25,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <FramelessHelper/Core/framelesshelpercore_global.h>
|
||||
#include <QtCore/qhash.h>
|
||||
#include <QtGui/qwindowdefs.h>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QScreen;
|
||||
|
@ -62,7 +65,7 @@ using GetWidgetHandleCallback = std::function<QObject *()>;
|
|||
using ForceChildrenRepaintCallback = std::function<void(const int)>;
|
||||
using ResetQtGrabbedControlCallback = std::function<bool()>;
|
||||
|
||||
struct SystemParameters
|
||||
struct FRAMELESSHELPER_CORE_API FramelessCallbacks
|
||||
{
|
||||
GetWindowFlagsCallback getWindowFlags = nullptr;
|
||||
SetWindowFlagsCallback setWindowFlags = nullptr;
|
||||
|
@ -92,29 +95,90 @@ struct SystemParameters
|
|||
GetWidgetHandleCallback getWidgetHandle = nullptr;
|
||||
ForceChildrenRepaintCallback forceChildrenRepaint = nullptr;
|
||||
ResetQtGrabbedControlCallback resetQtGrabbedControl = nullptr;
|
||||
|
||||
FramelessCallbacks();
|
||||
virtual ~FramelessCallbacks();
|
||||
|
||||
using PtrType = std::shared_ptr<FramelessCallbacks>;
|
||||
[[nodiscard]] static PtrType create();
|
||||
|
||||
private:
|
||||
FRAMELESSHELPER_CLASS(FramelessCallbacks)
|
||||
};
|
||||
using FramelessCallbacksPtr = FramelessCallbacks::PtrType;
|
||||
|
||||
enum class ExtraDataType : quint8
|
||||
{
|
||||
WindowsUtilities,
|
||||
LinuxUtilities,
|
||||
MacOSUtilities,
|
||||
FramelessWidgetsHelper,
|
||||
FramelessQuickHelper
|
||||
};
|
||||
|
||||
using FramelessParams = SystemParameters *;
|
||||
using FramelessParamsConst = const SystemParameters *;
|
||||
using FramelessParamsRef = SystemParameters &;
|
||||
using FramelessParamsConstRef = const SystemParameters &;
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
||||
inline uint qHash(const ExtraDataType key, const uint seed = 0) noexcept {
|
||||
return ::qHash(static_cast<quint8>(key), seed);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct FRAMELESSHELPER_CORE_API FramelessExtraData
|
||||
{
|
||||
FramelessExtraData();
|
||||
virtual ~FramelessExtraData();
|
||||
|
||||
using PtrType = std::shared_ptr<FramelessExtraData>;
|
||||
|
||||
private:
|
||||
FRAMELESSHELPER_CLASS(FramelessExtraData)
|
||||
};
|
||||
using FramelessExtraDataPtr = FramelessExtraData::PtrType;
|
||||
using FramelessExtraDataPtrs = QList<FramelessExtraDataPtr>;
|
||||
using FramelessExtraDataHash = QHash<ExtraDataType, FramelessExtraDataPtr>;
|
||||
|
||||
struct FRAMELESSHELPER_CORE_API FramelessData
|
||||
{
|
||||
QObject *window = nullptr;
|
||||
WId windowId = 0;
|
||||
QObject *internalEventHandler = nullptr;
|
||||
bool frameless = false;
|
||||
FramelessCallbacksPtr callbacks = nullptr;
|
||||
FramelessExtraDataHash extraData = {};
|
||||
|
||||
FramelessData();
|
||||
virtual ~FramelessData();
|
||||
|
||||
using PtrType = std::shared_ptr<FramelessData>;
|
||||
[[nodiscard]] static PtrType create();
|
||||
|
||||
private:
|
||||
FRAMELESSHELPER_CLASS(FramelessData)
|
||||
};
|
||||
using FramelessDataPtr = FramelessData::PtrType;
|
||||
using FramelessDataPtrs = QList<FramelessDataPtr>;
|
||||
using FramelessDataHash = QHash<QObject *, FramelessDataPtr>;
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
||||
#define DECLARE_SIZE_COMPARE_OPERATORS(Type1, Type2) \
|
||||
[[maybe_unused]] [[nodiscard]] static inline constexpr bool operator>(const Type1 &lhs, const Type2 &rhs) noexcept \
|
||||
[[maybe_unused]] [[nodiscard]] inline constexpr bool operator>(const Type1 &lhs, const Type2 &rhs) noexcept \
|
||||
{ \
|
||||
return ((lhs.width() * lhs.height()) > (rhs.width() * rhs.height())); \
|
||||
} \
|
||||
[[maybe_unused]] [[nodiscard]] static inline constexpr bool operator>=(const Type1 &lhs, const Type2 &rhs) noexcept \
|
||||
[[maybe_unused]] [[nodiscard]] inline constexpr bool operator>=(const Type1 &lhs, const Type2 &rhs) noexcept \
|
||||
{ \
|
||||
return (operator>(lhs, rhs) || operator==(lhs, rhs)); \
|
||||
} \
|
||||
[[maybe_unused]] [[nodiscard]] static inline constexpr bool operator<(const Type1 &lhs, const Type2 &rhs) noexcept \
|
||||
[[maybe_unused]] [[nodiscard]] inline constexpr bool operator<(const Type1 &lhs, const Type2 &rhs) noexcept \
|
||||
{ \
|
||||
return (operator!=(lhs, rhs) && !operator>(lhs, rhs)); \
|
||||
} \
|
||||
[[maybe_unused]] [[nodiscard]] static inline constexpr bool operator<=(const Type1 &lhs, const Type2 &rhs) noexcept \
|
||||
[[maybe_unused]] [[nodiscard]] inline constexpr bool operator<=(const Type1 &lhs, const Type2 &rhs) noexcept \
|
||||
{ \
|
||||
return (operator<(lhs, rhs) || operator==(lhs, rhs)); \
|
||||
}
|
||||
|
||||
DECLARE_SIZE_COMPARE_OPERATORS(QSize, QSize)
|
||||
DECLARE_SIZE_COMPARE_OPERATORS(QSizeF, QSizeF)
|
||||
DECLARE_SIZE_COMPARE_OPERATORS(QSize, QSizeF)
|
||||
DECLARE_SIZE_COMPARE_OPERATORS(QSizeF, QSize)
|
||||
|
|
|
@ -30,23 +30,19 @@
|
|||
|
||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
struct SystemParameters;
|
||||
class FramelessManager;
|
||||
struct FramelessData;
|
||||
using FramelessDataPtr = std::shared_ptr<FramelessData>;
|
||||
|
||||
class FramelessManager;
|
||||
class FRAMELESSHELPER_CORE_API FramelessManagerPrivate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DECLARE_PUBLIC(FramelessManager)
|
||||
Q_DISABLE_COPY_MOVE(FramelessManagerPrivate)
|
||||
FRAMELESSHELPER_PRIVATE_QT_CLASS(FramelessManager)
|
||||
|
||||
public:
|
||||
explicit FramelessManagerPrivate(FramelessManager *q);
|
||||
~FramelessManagerPrivate() override;
|
||||
|
||||
Q_NODISCARD static FramelessManagerPrivate *get(FramelessManager *pub);
|
||||
Q_NODISCARD static const FramelessManagerPrivate *get(const FramelessManager *pub);
|
||||
|
||||
static void initializeIconFont();
|
||||
Q_NODISCARD static QFont getIconFont();
|
||||
|
||||
|
@ -60,7 +56,12 @@ public:
|
|||
void doNotifySystemThemeHasChangedOrNot();
|
||||
void doNotifyWallpaperHasChangedOrNot();
|
||||
|
||||
FramelessManager *q_ptr = nullptr;
|
||||
Q_NODISCARD static FramelessDataPtr getData(const QObject *window);
|
||||
Q_NODISCARD static FramelessDataPtr createData(const QObject *window, const WId windowId);
|
||||
Q_NODISCARD static WId getWindowId(const QObject *window);
|
||||
Q_NODISCARD static QObject *getWindow(const WId windowId);
|
||||
static void updateWindowId(const QObject *window, const WId newWindowId);
|
||||
|
||||
Global::SystemTheme systemTheme = Global::SystemTheme::Unknown;
|
||||
std::optional<Global::SystemTheme> overrideTheme = std::nullopt;
|
||||
QColor accentColor = {};
|
||||
|
|
|
@ -32,21 +32,15 @@
|
|||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
class MicaMaterial;
|
||||
|
||||
class FRAMELESSHELPER_CORE_API MicaMaterialPrivate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DISABLE_COPY_MOVE(MicaMaterialPrivate)
|
||||
Q_DECLARE_PUBLIC(MicaMaterial)
|
||||
FRAMELESSHELPER_PRIVATE_QT_CLASS(MicaMaterial)
|
||||
|
||||
public:
|
||||
explicit MicaMaterialPrivate(MicaMaterial *q);
|
||||
~MicaMaterialPrivate() override;
|
||||
|
||||
Q_NODISCARD static MicaMaterialPrivate *get(MicaMaterial *q);
|
||||
Q_NODISCARD static const MicaMaterialPrivate *get(const MicaMaterial *q);
|
||||
|
||||
Q_NODISCARD static QColor systemFallbackColor();
|
||||
|
||||
Q_NODISCARD QPoint mapToWallpaper(const QPoint &pos) const;
|
||||
|
@ -60,7 +54,6 @@ public:
|
|||
void initialize();
|
||||
void prepareGraphicsResources();
|
||||
|
||||
MicaMaterial *q_ptr = nullptr;
|
||||
QColor tintColor = {};
|
||||
qreal tintOpacity = qreal(0);
|
||||
QColor fallbackColor = {};
|
||||
|
|
|
@ -60,8 +60,7 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
|
|||
class FRAMELESSHELPER_CORE_API RegistryKey : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DISABLE_COPY_MOVE(RegistryKey)
|
||||
FRAMELESSHELPER_QT_CLASS(RegistryKey)
|
||||
|
||||
public:
|
||||
explicit RegistryKey(const Global::RegistryRootKey root, const QString &key, QObject *parent = nullptr);
|
||||
|
|
|
@ -37,7 +37,7 @@ using ScopeGuardCallback = std::function<void()>;
|
|||
|
||||
class [[nodiscard]] ScopeGuard
|
||||
{
|
||||
Q_DISABLE_COPY(ScopeGuard)
|
||||
FRAMELESSHELPER_CLASS(ScopeGuard)
|
||||
|
||||
public:
|
||||
ScopeGuard()
|
||||
|
|
|
@ -31,8 +31,7 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
|
|||
class FRAMELESSHELPER_CORE_API SysApiLoader : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DISABLE_COPY_MOVE(SysApiLoader)
|
||||
FRAMELESSHELPER_QT_CLASS(SysApiLoader)
|
||||
|
||||
public:
|
||||
Q_NODISCARD static SysApiLoader *instance();
|
||||
|
|
|
@ -32,22 +32,15 @@
|
|||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
class WindowBorderPainter;
|
||||
|
||||
class FRAMELESSHELPER_CORE_API WindowBorderPainterPrivate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DECLARE_PUBLIC(WindowBorderPainter)
|
||||
Q_DISABLE_COPY_MOVE(WindowBorderPainterPrivate)
|
||||
FRAMELESSHELPER_PRIVATE_QT_CLASS(WindowBorderPainter)
|
||||
|
||||
public:
|
||||
explicit WindowBorderPainterPrivate(WindowBorderPainter *q);
|
||||
~WindowBorderPainterPrivate() override;
|
||||
|
||||
Q_NODISCARD static WindowBorderPainterPrivate *get(WindowBorderPainter *q);
|
||||
Q_NODISCARD static const WindowBorderPainterPrivate *get(const WindowBorderPainter *q);
|
||||
|
||||
WindowBorderPainter *q_ptr = nullptr;
|
||||
std::optional<int> thickness = std::nullopt;
|
||||
std::optional<Global::WindowEdges> edges = std::nullopt;
|
||||
std::optional<QColor> activeColor = std::nullopt;
|
||||
|
|
|
@ -37,30 +37,22 @@ QT_END_NAMESPACE
|
|||
|
||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
struct SystemParameters;
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API
|
||||
Qt::CursorShape calculateCursorShape(const QWindow *window, const QPoint &pos);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API
|
||||
Qt::Edges calculateWindowEdges(const QWindow *window, const QPoint &pos);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API Qt::CursorShape calculateCursorShape(const QWindow *window, const QPoint &pos);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API Qt::Edges calculateWindowEdges(const QWindow *window, const QPoint &pos);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool startSystemMove(QWindow *window, const QPoint &globalPos);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool startSystemResize(QWindow *window, const Qt::Edges edges, const QPoint &globalPos);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API QString getSystemButtonGlyph(const Global::SystemButtonType button);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API QWindow *findWindow(const WId windowId);
|
||||
FRAMELESSHELPER_CORE_API void moveWindowToDesktopCenter(
|
||||
const SystemParameters *params, const bool considerTaskBar);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API Qt::WindowState windowStatesToWindowState(
|
||||
const Qt::WindowStates states);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool moveWindowToDesktopCenter(const WId windowId, const bool considerTaskBar);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API Qt::WindowState windowStatesToWindowState(const Qt::WindowStates states);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isThemeChangeEvent(const QEvent * const event);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API QColor calculateSystemButtonBackgroundColor(
|
||||
const Global::SystemButtonType button, const Global::ButtonState state);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API QColor calculateSystemButtonBackgroundColor(const Global::SystemButtonType button, const Global::ButtonState state);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool shouldAppsUseDarkMode();
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isTitleBarColorized();
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool
|
||||
setBlurBehindWindowEnabled(const WId windowId, const Global::BlurMode mode, const QColor &color);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool setBlurBehindWindowEnabled(const WId windowId, const Global::BlurMode mode, const QColor &color);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API QString getWallpaperFilePath();
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API Global::WallpaperAspectStyle getWallpaperAspectStyle();
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isBlurBehindWindowSupported();
|
||||
|
@ -100,31 +92,24 @@ FRAMELESSHELPER_CORE_API void moveWindowToDesktopCenter(
|
|||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isFullScreen(const WId windowId);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isWindowNoState(const WId windowId);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool syncWmPaintWithDwm();
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool showSystemMenu(
|
||||
const WId windowId, const QPoint &pos,
|
||||
const bool selectFirstEntry, const SystemParameters *params);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool showSystemMenu(const WId windowId, const QPoint &pos, const bool selectFirstEntry);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API QColor getDwmColorizationColor(bool *opaque = nullptr, bool *ok = nullptr);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API Global::DwmColorizationArea getDwmColorizationArea();
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isHighContrastModeEnabled();
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 getPrimaryScreenDpi(const bool horizontal);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 getWindowDpi(const WId windowId, const bool horizontal);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 getResizeBorderThicknessForDpi
|
||||
(const bool horizontal, const quint32 dpi);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 getResizeBorderThickness(const WId windowId,
|
||||
const bool horizontal,
|
||||
const bool scaled);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 getResizeBorderThicknessForDpi(const bool horizontal, const quint32 dpi);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 getResizeBorderThickness(const WId windowId, const bool horizontal, const bool scaled);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 getCaptionBarHeightForDpi(const quint32 dpi);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 getCaptionBarHeight(const WId windowId, const bool scaled);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 getTitleBarHeightForDpi(const quint32 dpi);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 getTitleBarHeight(const WId windowId, const bool scaled);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 getFrameBorderThicknessForDpi(const quint32 dpi);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 getFrameBorderThickness(const WId windowId,
|
||||
const bool scaled);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API quint32 getFrameBorderThickness(const WId windowId, const bool scaled);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool maybeFixupQtInternals(const WId windowId);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isWindowFrameBorderVisible();
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isFrameBorderColorized();
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool installWindowProcHook(
|
||||
const WId windowId, const SystemParameters *params);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool installWindowProcHook(const WId windowId);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool uninstallWindowProcHook(const WId windowId);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool setAeroSnappingEnabled(const WId windowId, const bool enable);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool tryToEnableHighestDpiAwarenessLevel();
|
||||
|
@ -132,20 +117,17 @@ FRAMELESSHELPER_CORE_API void moveWindowToDesktopCenter(
|
|||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool shouldAppsUseDarkMode_windows();
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API QColor getAccentColor_windows();
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool setCornerStyleForWindow(const WId windowId, const Global::WindowCornerStyle style);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool hideOriginalTitleBarElements
|
||||
(const WId windowId, const bool disable = true);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool hideOriginalTitleBarElements(const WId windowId, const bool disable = true);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool setQtDarkModeAwareEnabled(const bool enable);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool refreshWin32ThemeResources(const WId windowId, const bool dark);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool enableNonClientAreaDpiScalingForWindow(const WId windowId);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API
|
||||
Global::DpiAwareness getDpiAwarenessForCurrentProcess(bool *highest = nullptr);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API Global::DpiAwareness getDpiAwarenessForCurrentProcess(bool *highest = nullptr);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool fixupChildWindowsDpiMessage(const WId windowId);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool fixupDialogsDpiScaling();
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool setDarkModeAllowedForApp(const bool allow = true);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool bringWindowToFront(const WId windowId);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API QPoint getWindowPlacementOffset(const WId windowId);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API QRect getWindowRestoreGeometry(const WId windowId);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool removeMicaWindow(const WId windowId);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API quint64 getKeyState();
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isValidWindow(const WId windowId, const bool checkVisible, const bool checkTopLevel);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool updateFramebufferTransparency(const WId windowId);
|
||||
|
@ -156,8 +138,7 @@ FRAMELESSHELPER_CORE_API void printWin32Message(void *msg);
|
|||
#endif // Q_OS_WINDOWS
|
||||
|
||||
#if (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API QScreen *x11_findScreenForVirtualDesktop
|
||||
(const int virtualDesktopNumber);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API QScreen *x11_findScreenForVirtualDesktop(const int virtualDesktopNumber);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API x11_return_type x11_appRootWindow(const int screen);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API int x11_appScreen();
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API x11_return_type x11_appTime();
|
||||
|
@ -166,11 +147,8 @@ FRAMELESSHELPER_CORE_API void printWin32Message(void *msg);
|
|||
[[nodiscard]] FRAMELESSHELPER_CORE_API QByteArray x11_nextStartupId();
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API Display *x11_display();
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API xcb_connection_t *x11_connection();
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API QByteArray getWindowProperty
|
||||
(const WId windowId, const xcb_atom_t prop, const xcb_atom_t type, const quint32 data_len);
|
||||
FRAMELESSHELPER_CORE_API void setWindowProperty
|
||||
(const WId windowId, const xcb_atom_t prop, const xcb_atom_t type,
|
||||
const void *data, const quint32 data_len, const uint8_t format);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API QByteArray getWindowProperty(const WId windowId, const xcb_atom_t prop, const xcb_atom_t type, const quint32 data_len);
|
||||
FRAMELESSHELPER_CORE_API void setWindowProperty(const WId windowId, const xcb_atom_t prop, const xcb_atom_t type, const void *data, const quint32 data_len, const uint8_t format);
|
||||
FRAMELESSHELPER_CORE_API void clearWindowProperty(const WId windowId, const xcb_atom_t prop);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API xcb_atom_t internAtom(const char *name);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API QString getWindowManagerName();
|
||||
|
@ -180,11 +158,9 @@ FRAMELESSHELPER_CORE_API void clearWindowProperty(const WId windowId, const xcb_
|
|||
FRAMELESSHELPER_CORE_API void openSystemMenu(const WId windowId, const QPoint &globalPos);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool shouldAppsUseDarkMode_linux();
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API QColor getAccentColor_linux();
|
||||
FRAMELESSHELPER_CORE_API void sendMoveResizeMessage
|
||||
(const WId windowId, const uint32_t action, const QPoint &globalPos, const Qt::MouseButton button = Qt::LeftButton);
|
||||
FRAMELESSHELPER_CORE_API void sendMoveResizeMessage(const WId windowId, const uint32_t action, const QPoint &globalPos, const Qt::MouseButton button = Qt::LeftButton);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool isCustomDecorationSupported();
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool
|
||||
setPlatformPropertiesForWindow(QWindow *window, const QVariantHash &props);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool setPlatformPropertiesForWindow(QWindow *window, const QVariantHash &props);
|
||||
#endif // Q_OS_LINUX
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
|
|
|
@ -31,13 +31,10 @@
|
|||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
class WindowBorderPainterPrivate;
|
||||
|
||||
class FRAMELESSHELPER_CORE_API WindowBorderPainter : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DISABLE_COPY_MOVE(WindowBorderPainter)
|
||||
Q_DECLARE_PRIVATE(WindowBorderPainter)
|
||||
FRAMELESSHELPER_PUBLIC_QT_CLASS(WindowBorderPainter)
|
||||
|
||||
Q_PROPERTY(int thickness READ thickness WRITE setThickness NOTIFY thicknessChanged FINAL)
|
||||
Q_PROPERTY(Global::WindowEdges edges READ edges WRITE setEdges NOTIFY edgesChanged FINAL)
|
||||
|
@ -77,9 +74,6 @@ Q_SIGNALS:
|
|||
void inactiveColorChanged();
|
||||
void nativeBorderChanged();
|
||||
void shouldRepaint();
|
||||
|
||||
private:
|
||||
QScopedPointer<WindowBorderPainterPrivate> d_ptr;
|
||||
};
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
|
|
@ -84,8 +84,7 @@ FRAMELESSHELPER_QUICK_API void FramelessHelperQuickRegisterTypes(QQmlEngine *);
|
|||
class FRAMELESSHELPER_QUICK_API QuickGlobal : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DISABLE_COPY_MOVE(QuickGlobal)
|
||||
FRAMELESSHELPER_QT_CLASS(QuickGlobal)
|
||||
#ifdef QML_NAMED_ELEMENT
|
||||
QML_NAMED_ELEMENT(FramelessHelperConstants)
|
||||
#endif
|
||||
|
|
|
@ -36,20 +36,18 @@ class QuickMicaMaterial;
|
|||
#if FRAMELESSHELPER_CONFIG(border_painter)
|
||||
class QuickWindowBorder;
|
||||
#endif
|
||||
class FramelessQuickHelperPrivate;
|
||||
|
||||
class FramelessQuickHelperPrivate;
|
||||
class FRAMELESSHELPER_QUICK_API FramelessQuickHelper : public QQuickItem
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
FRAMELESSHELPER_PUBLIC_QT_CLASS(FramelessQuickHelper)
|
||||
#ifdef QML_NAMED_ELEMENT
|
||||
QML_NAMED_ELEMENT(FramelessHelper)
|
||||
#endif
|
||||
#ifdef QML_ATTACHED
|
||||
QML_ATTACHED(FramelessQuickHelper)
|
||||
#endif
|
||||
Q_DECLARE_PRIVATE(FramelessQuickHelper)
|
||||
Q_DISABLE_COPY_MOVE(FramelessQuickHelper)
|
||||
Q_PROPERTY(QQuickItem* titleBarItem READ titleBarItem WRITE setTitleBarItem NOTIFY titleBarItemChanged FINAL)
|
||||
Q_PROPERTY(bool windowFixedSize READ isWindowFixedSize WRITE setWindowFixedSize NOTIFY windowFixedSizeChanged FINAL)
|
||||
Q_PROPERTY(bool blurBehindWindowEnabled READ isBlurBehindWindowEnabled WRITE setBlurBehindWindowEnabled NOTIFY blurBehindWindowEnabledChanged FINAL)
|
||||
|
@ -109,9 +107,6 @@ Q_SIGNALS:
|
|||
void blurBehindWindowEnabledChanged();
|
||||
void windowChanged2();
|
||||
void ready();
|
||||
|
||||
private:
|
||||
QScopedPointer<FramelessQuickHelperPrivate> d_ptr;
|
||||
};
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
|
|
@ -36,8 +36,7 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
|
|||
class FRAMELESSHELPER_QUICK_API FramelessQuickUtils : public QObject, public QQmlParserStatus
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DISABLE_COPY_MOVE(FramelessQuickUtils)
|
||||
FRAMELESSHELPER_QT_CLASS(FramelessQuickUtils)
|
||||
Q_INTERFACES(QQmlParserStatus)
|
||||
#ifdef QML_NAMED_ELEMENT
|
||||
QML_NAMED_ELEMENT(FramelessUtils)
|
||||
|
|
|
@ -33,16 +33,13 @@
|
|||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
class FramelessQuickApplicationWindowPrivate;
|
||||
|
||||
class FRAMELESSHELPER_QUICK_API FramelessQuickApplicationWindow : public QQuickApplicationWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
FRAMELESSHELPER_PUBLIC_QT_CLASS(FramelessQuickApplicationWindow)
|
||||
#ifdef QML_NAMED_ELEMENT
|
||||
QML_NAMED_ELEMENT(FramelessApplicationWindow)
|
||||
#endif
|
||||
Q_DECLARE_PRIVATE(FramelessQuickApplicationWindow)
|
||||
Q_DISABLE_COPY_MOVE(FramelessQuickApplicationWindow)
|
||||
Q_PROPERTY(bool hidden READ isHidden NOTIFY hiddenChanged FINAL)
|
||||
Q_PROPERTY(bool normal READ isNormal NOTIFY normalChanged FINAL)
|
||||
Q_PROPERTY(bool minimized READ isMinimized NOTIFY minimizedChanged FINAL)
|
||||
|
@ -77,9 +74,6 @@ Q_SIGNALS:
|
|||
void maximizedChanged();
|
||||
void zoomedChanged();
|
||||
void fullScreenChanged();
|
||||
|
||||
private:
|
||||
QScopedPointer<FramelessQuickApplicationWindowPrivate> d_ptr;
|
||||
};
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
|
|
@ -35,23 +35,17 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
|
|||
#if FRAMELESSHELPER_CONFIG(border_painter)
|
||||
class QuickWindowBorder;
|
||||
#endif
|
||||
class FramelessQuickApplicationWindow;
|
||||
|
||||
class FramelessQuickApplicationWindow;
|
||||
class FRAMELESSHELPER_QUICK_API FramelessQuickApplicationWindowPrivate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DECLARE_PUBLIC(FramelessQuickApplicationWindow)
|
||||
Q_DISABLE_COPY_MOVE(FramelessQuickApplicationWindowPrivate)
|
||||
FRAMELESSHELPER_PRIVATE_QT_CLASS(FramelessQuickApplicationWindow)
|
||||
|
||||
public:
|
||||
explicit FramelessQuickApplicationWindowPrivate(FramelessQuickApplicationWindow *q);
|
||||
~FramelessQuickApplicationWindowPrivate() override;
|
||||
|
||||
Q_NODISCARD static FramelessQuickApplicationWindowPrivate *get(FramelessQuickApplicationWindow *pub);
|
||||
Q_NODISCARD static const FramelessQuickApplicationWindowPrivate *get(const FramelessQuickApplicationWindow *pub);
|
||||
|
||||
FramelessQuickApplicationWindow *q_ptr = nullptr;
|
||||
QQuickWindow::Visibility savedVisibility = QQuickWindow::Windowed;
|
||||
#if FRAMELESSHELPER_CONFIG(border_painter)
|
||||
QuickWindowBorder *windowBorder = nullptr;
|
||||
|
|
|
@ -39,23 +39,17 @@ class QuickMicaMaterial;
|
|||
#if FRAMELESSHELPER_CONFIG(border_painter)
|
||||
class QuickWindowBorder;
|
||||
#endif
|
||||
class FramelessQuickHelper;
|
||||
struct FramelessQuickHelperData;
|
||||
|
||||
class FramelessQuickHelper;
|
||||
class FRAMELESSHELPER_QUICK_API FramelessQuickHelperPrivate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DECLARE_PUBLIC(FramelessQuickHelper)
|
||||
Q_DISABLE_COPY_MOVE(FramelessQuickHelperPrivate)
|
||||
FRAMELESSHELPER_PRIVATE_QT_CLASS(FramelessQuickHelper)
|
||||
|
||||
public:
|
||||
explicit FramelessQuickHelperPrivate(FramelessQuickHelper *q);
|
||||
~FramelessQuickHelperPrivate() override;
|
||||
|
||||
Q_NODISCARD static FramelessQuickHelperPrivate *get(FramelessQuickHelper *pub);
|
||||
Q_NODISCARD static const FramelessQuickHelperPrivate *get(const FramelessQuickHelper *pub);
|
||||
|
||||
void attach();
|
||||
void detach();
|
||||
|
||||
|
@ -83,11 +77,8 @@ public:
|
|||
Q_NODISCARD bool isInTitleBarDraggableArea(const QPoint &pos) const;
|
||||
Q_NODISCARD bool shouldIgnoreMouseEvents(const QPoint &pos) const;
|
||||
void setSystemButtonState(const QuickGlobal::SystemButtonType button, const QuickGlobal::ButtonState state);
|
||||
Q_NODISCARD const FramelessQuickHelperData *getWindowData() const;
|
||||
Q_NODISCARD FramelessQuickHelperData *getWindowDataMutable() const;
|
||||
void rebindWindow();
|
||||
|
||||
FramelessQuickHelper *q_ptr = nullptr;
|
||||
QColor savedWindowBackgroundColor = {};
|
||||
bool blurBehindWindowEnabled = false;
|
||||
std::optional<bool> extendIntoTitleBar = std::nullopt;
|
||||
|
|
|
@ -33,16 +33,13 @@
|
|||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
class FramelessQuickWindowPrivate;
|
||||
|
||||
class FRAMELESSHELPER_QUICK_API FramelessQuickWindow : public QQuickWindowQmlImpl
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
FRAMELESSHELPER_PUBLIC_QT_CLASS(FramelessQuickWindow)
|
||||
#ifdef QML_NAMED_ELEMENT
|
||||
QML_NAMED_ELEMENT(FramelessWindow)
|
||||
#endif
|
||||
Q_DECLARE_PRIVATE(FramelessQuickWindow)
|
||||
Q_DISABLE_COPY_MOVE(FramelessQuickWindow)
|
||||
Q_PROPERTY(bool hidden READ isHidden NOTIFY hiddenChanged FINAL)
|
||||
Q_PROPERTY(bool normal READ isNormal NOTIFY normalChanged FINAL)
|
||||
Q_PROPERTY(bool minimized READ isMinimized NOTIFY minimizedChanged FINAL)
|
||||
|
@ -77,9 +74,6 @@ Q_SIGNALS:
|
|||
void maximizedChanged();
|
||||
void zoomedChanged();
|
||||
void fullScreenChanged();
|
||||
|
||||
private:
|
||||
QScopedPointer<FramelessQuickWindowPrivate> d_ptr;
|
||||
};
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
|
|
@ -35,23 +35,17 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
|
|||
#if FRAMELESSHELPER_CONFIG(border_painter)
|
||||
class QuickWindowBorder;
|
||||
#endif
|
||||
class FramelessQuickWindow;
|
||||
|
||||
class FramelessQuickWindow;
|
||||
class FRAMELESSHELPER_QUICK_API FramelessQuickWindowPrivate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DECLARE_PUBLIC(FramelessQuickWindow)
|
||||
Q_DISABLE_COPY_MOVE(FramelessQuickWindowPrivate)
|
||||
FRAMELESSHELPER_PRIVATE_QT_CLASS(FramelessQuickWindow)
|
||||
|
||||
public:
|
||||
explicit FramelessQuickWindowPrivate(FramelessQuickWindow *q);
|
||||
~FramelessQuickWindowPrivate() override;
|
||||
|
||||
Q_NODISCARD static FramelessQuickWindowPrivate *get(FramelessQuickWindow *pub);
|
||||
Q_NODISCARD static const FramelessQuickWindowPrivate *get(const FramelessQuickWindow *pub);
|
||||
|
||||
FramelessQuickWindow *q_ptr = nullptr;
|
||||
QQuickWindow::Visibility savedVisibility = QQuickWindow::Windowed;
|
||||
#if FRAMELESSHELPER_CONFIG(border_painter)
|
||||
QuickWindowBorder *windowBorder = nullptr;
|
||||
|
|
|
@ -33,11 +33,10 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
|
|||
class FRAMELESSHELPER_QUICK_API QuickImageItem : public QQuickPaintedItem
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
FRAMELESSHELPER_QT_CLASS(QuickImageItem)
|
||||
#ifdef QML_NAMED_ELEMENT
|
||||
QML_NAMED_ELEMENT(ImageItem)
|
||||
#endif
|
||||
Q_DISABLE_COPY_MOVE(QuickImageItem)
|
||||
|
||||
Q_PROPERTY(QVariant source READ source WRITE setSource NOTIFY sourceChanged FINAL)
|
||||
|
||||
|
|
|
@ -31,27 +31,21 @@
|
|||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
class MicaMaterial;
|
||||
class QuickMicaMaterial;
|
||||
|
||||
class QuickMicaMaterial;
|
||||
class FRAMELESSHELPER_QUICK_API QuickMicaMaterialPrivate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DISABLE_COPY_MOVE(QuickMicaMaterialPrivate)
|
||||
Q_DECLARE_PUBLIC(QuickMicaMaterial)
|
||||
FRAMELESSHELPER_PRIVATE_QT_CLASS(QuickMicaMaterial)
|
||||
|
||||
public:
|
||||
explicit QuickMicaMaterialPrivate(QuickMicaMaterial *q);
|
||||
~QuickMicaMaterialPrivate() override;
|
||||
|
||||
Q_NODISCARD static QuickMicaMaterialPrivate *get(QuickMicaMaterial *q);
|
||||
Q_NODISCARD static const QuickMicaMaterialPrivate *get(const QuickMicaMaterial *q);
|
||||
|
||||
Q_SLOT void rebindWindow();
|
||||
|
||||
void initialize();
|
||||
|
||||
QuickMicaMaterial *q_ptr = nullptr;
|
||||
QMetaObject::Connection rootWindowXChangedConnection = {};
|
||||
QMetaObject::Connection rootWindowYChangedConnection = {};
|
||||
QMetaObject::Connection rootWindowActiveChangedConnection = {};
|
||||
|
|
|
@ -40,11 +40,10 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
|
|||
class FRAMELESSHELPER_QUICK_API QuickStandardSystemButton : public QQuickButton
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
FRAMELESSHELPER_QT_CLASS(QuickStandardSystemButton)
|
||||
#ifdef QML_NAMED_ELEMENT
|
||||
QML_NAMED_ELEMENT(StandardSystemButton)
|
||||
#endif
|
||||
Q_DISABLE_COPY_MOVE(QuickStandardSystemButton)
|
||||
Q_PROPERTY(QuickGlobal::SystemButtonType buttonType READ buttonType WRITE setButtonType NOTIFY buttonTypeChanged FINAL)
|
||||
Q_PROPERTY(QString glyph READ glyph WRITE setGlyph NOTIFY glyphChanged FINAL)
|
||||
Q_PROPERTY(QColor hoverColor READ hoverColor WRITE setHoverColor NOTIFY hoverColorChanged FINAL)
|
||||
|
|
|
@ -46,11 +46,10 @@ class QuickImageItem;
|
|||
class FRAMELESSHELPER_QUICK_API QuickStandardTitleBar : public QQuickRectangle
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
FRAMELESSHELPER_QT_CLASS(QuickStandardTitleBar)
|
||||
#ifdef QML_NAMED_ELEMENT
|
||||
QML_NAMED_ELEMENT(StandardTitleBar)
|
||||
#endif // QML_NAMED_ELEMENT
|
||||
Q_DISABLE_COPY_MOVE(QuickStandardTitleBar)
|
||||
Q_PROPERTY(Qt::Alignment titleLabelAlignment READ titleLabelAlignment WRITE setTitleLabelAlignment NOTIFY titleLabelAlignmentChanged FINAL)
|
||||
Q_PROPERTY(QQuickLabel* titleLabel READ titleLabel CONSTANT FINAL)
|
||||
#if (!defined(Q_OS_MACOS) && FRAMELESSHELPER_CONFIG(system_button))
|
||||
|
|
|
@ -30,29 +30,23 @@
|
|||
|
||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
class QuickWindowBorder;
|
||||
class WindowBorderPainter;
|
||||
|
||||
class QuickWindowBorder;
|
||||
class FRAMELESSHELPER_QUICK_API QuickWindowBorderPrivate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DISABLE_COPY_MOVE(QuickWindowBorderPrivate)
|
||||
Q_DECLARE_PUBLIC(QuickWindowBorder)
|
||||
FRAMELESSHELPER_PRIVATE_QT_CLASS(QuickWindowBorder)
|
||||
|
||||
public:
|
||||
explicit QuickWindowBorderPrivate(QuickWindowBorder *q);
|
||||
~QuickWindowBorderPrivate() override;
|
||||
|
||||
Q_NODISCARD static QuickWindowBorderPrivate *get(QuickWindowBorder *q);
|
||||
Q_NODISCARD static const QuickWindowBorderPrivate *get(const QuickWindowBorder *q);
|
||||
|
||||
Q_SLOT void update();
|
||||
|
||||
void initialize();
|
||||
void rebindWindow();
|
||||
|
||||
QuickWindowBorder *q_ptr = nullptr;
|
||||
WindowBorderPainter *borderPainter = nullptr;
|
||||
QMetaObject::Connection activeChangeConnection = {};
|
||||
QMetaObject::Connection visibilityChangeConnection = {};
|
||||
|
|
|
@ -35,12 +35,11 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
|
|||
class FRAMELESSHELPER_QUICK_API QuickChromePalette : public ChromePalette, public QQmlParserStatus
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
FRAMELESSHELPER_QT_CLASS(QuickChromePalette)
|
||||
Q_INTERFACES(QQmlParserStatus)
|
||||
#ifdef QML_ANONYMOUS
|
||||
QML_ANONYMOUS
|
||||
#endif
|
||||
Q_DISABLE_COPY_MOVE(QuickChromePalette)
|
||||
Q_INTERFACES(QQmlParserStatus)
|
||||
|
||||
public:
|
||||
explicit QuickChromePalette(QObject *parent = nullptr);
|
||||
|
|
|
@ -32,16 +32,13 @@
|
|||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
class QuickMicaMaterialPrivate;
|
||||
|
||||
class FRAMELESSHELPER_QUICK_API QuickMicaMaterial : public QQuickPaintedItem
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
FRAMELESSHELPER_PUBLIC_QT_CLASS(QuickMicaMaterial)
|
||||
#ifdef QML_NAMED_ELEMENT
|
||||
QML_NAMED_ELEMENT(MicaMaterial)
|
||||
#endif
|
||||
Q_DISABLE_COPY_MOVE(QuickMicaMaterial)
|
||||
Q_DECLARE_PRIVATE(QuickMicaMaterial)
|
||||
|
||||
Q_PROPERTY(QColor tintColor READ tintColor WRITE setTintColor NOTIFY tintColorChanged FINAL)
|
||||
Q_PROPERTY(qreal tintOpacity READ tintOpacity WRITE setTintOpacity NOTIFY tintOpacityChanged FINAL)
|
||||
|
@ -81,9 +78,6 @@ protected:
|
|||
void itemChange(const ItemChange change, const ItemChangeData &value) override;
|
||||
void classBegin() override;
|
||||
void componentComplete() override;
|
||||
|
||||
private:
|
||||
QScopedPointer<QuickMicaMaterialPrivate> d_ptr;
|
||||
};
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
|
|
@ -32,16 +32,13 @@
|
|||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
class QuickWindowBorderPrivate;
|
||||
|
||||
class FRAMELESSHELPER_QUICK_API QuickWindowBorder : public QQuickPaintedItem
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
FRAMELESSHELPER_PUBLIC_QT_CLASS(QuickWindowBorder)
|
||||
#ifdef QML_NAMED_ELEMENT
|
||||
QML_NAMED_ELEMENT(WindowBorder)
|
||||
#endif
|
||||
Q_DISABLE_COPY_MOVE(QuickWindowBorder)
|
||||
Q_DECLARE_PRIVATE(QuickWindowBorder)
|
||||
|
||||
Q_PROPERTY(qreal thickness READ thickness WRITE setThickness NOTIFY thicknessChanged FINAL)
|
||||
Q_PROPERTY(QuickGlobal::WindowEdges edges READ edges WRITE setEdges NOTIFY edgesChanged FINAL)
|
||||
|
@ -86,9 +83,6 @@ Q_SIGNALS:
|
|||
void activeColorChanged();
|
||||
void inactiveColorChanged();
|
||||
void nativeBorderChanged();
|
||||
|
||||
private:
|
||||
QScopedPointer<QuickWindowBorderPrivate> d_ptr;
|
||||
};
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
|
|
@ -32,20 +32,14 @@
|
|||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
class FramelessDialogPrivate;
|
||||
|
||||
class FRAMELESSHELPER_WIDGETS_API FramelessDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DECLARE_PRIVATE(FramelessDialog)
|
||||
Q_DISABLE_COPY_MOVE(FramelessDialog)
|
||||
FRAMELESSHELPER_PUBLIC_QT_CLASS(FramelessDialog)
|
||||
|
||||
public:
|
||||
explicit FramelessDialog(QWidget *parent = nullptr);
|
||||
~FramelessDialog() override;
|
||||
|
||||
private:
|
||||
QScopedPointer<FramelessDialogPrivate> d_ptr;
|
||||
};
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
|
|
@ -32,13 +32,10 @@
|
|||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
class FramelessMainWindowPrivate;
|
||||
|
||||
class FRAMELESSHELPER_WIDGETS_API FramelessMainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DECLARE_PRIVATE(FramelessMainWindow)
|
||||
Q_DISABLE_COPY_MOVE(FramelessMainWindow)
|
||||
FRAMELESSHELPER_PUBLIC_QT_CLASS(FramelessMainWindow)
|
||||
Q_PROPERTY(bool hidden READ isHidden NOTIFY hiddenChanged FINAL)
|
||||
Q_PROPERTY(bool normal READ isNormal NOTIFY normalChanged FINAL)
|
||||
Q_PROPERTY(bool zoomed READ isZoomed NOTIFY zoomedChanged FINAL)
|
||||
|
@ -58,9 +55,6 @@ Q_SIGNALS:
|
|||
void hiddenChanged();
|
||||
void normalChanged();
|
||||
void zoomedChanged();
|
||||
|
||||
private:
|
||||
QScopedPointer<FramelessMainWindowPrivate> d_ptr;
|
||||
};
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
|
|
@ -32,13 +32,10 @@
|
|||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
class FramelessWidgetPrivate;
|
||||
|
||||
class FRAMELESSHELPER_WIDGETS_API FramelessWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DECLARE_PRIVATE(FramelessWidget)
|
||||
Q_DISABLE_COPY_MOVE(FramelessWidget)
|
||||
FRAMELESSHELPER_PUBLIC_QT_CLASS(FramelessWidget)
|
||||
Q_PROPERTY(bool hidden READ isHidden NOTIFY hiddenChanged FINAL)
|
||||
Q_PROPERTY(bool normal READ isNormal NOTIFY normalChanged FINAL)
|
||||
Q_PROPERTY(bool zoomed READ isZoomed NOTIFY zoomedChanged FINAL)
|
||||
|
@ -58,9 +55,6 @@ Q_SIGNALS:
|
|||
void hiddenChanged();
|
||||
void normalChanged();
|
||||
void zoomedChanged();
|
||||
|
||||
private:
|
||||
QScopedPointer<FramelessWidgetPrivate> d_ptr;
|
||||
};
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
|
|
@ -35,14 +35,12 @@ class MicaMaterial;
|
|||
#if FRAMELESSHELPER_CONFIG(border_painter)
|
||||
class WindowBorderPainter;
|
||||
#endif
|
||||
class FramelessWidgetsHelperPrivate;
|
||||
|
||||
class FramelessWidgetsHelperPrivate;
|
||||
class FRAMELESSHELPER_WIDGETS_API FramelessWidgetsHelper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DECLARE_PRIVATE(FramelessWidgetsHelper)
|
||||
Q_DISABLE_COPY_MOVE(FramelessWidgetsHelper)
|
||||
FRAMELESSHELPER_PUBLIC_QT_CLASS(FramelessWidgetsHelper)
|
||||
Q_PROPERTY(QWidget* titleBarWidget READ titleBarWidget WRITE setTitleBarWidget NOTIFY titleBarWidgetChanged FINAL)
|
||||
Q_PROPERTY(bool windowFixedSize READ isWindowFixedSize WRITE setWindowFixedSize NOTIFY windowFixedSizeChanged FINAL)
|
||||
Q_PROPERTY(bool blurBehindWindowEnabled READ isBlurBehindWindowEnabled WRITE setBlurBehindWindowEnabled NOTIFY blurBehindWindowEnabledChanged FINAL)
|
||||
|
@ -96,9 +94,6 @@ Q_SIGNALS:
|
|||
void blurBehindWindowEnabledChanged();
|
||||
void windowChanged();
|
||||
void ready();
|
||||
|
||||
private:
|
||||
QScopedPointer<FramelessWidgetsHelperPrivate> d_ptr;
|
||||
};
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
|
|
@ -30,24 +30,18 @@
|
|||
|
||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
class FramelessDialog;
|
||||
class WidgetsSharedHelper;
|
||||
|
||||
class FramelessDialog;
|
||||
class FRAMELESSHELPER_WIDGETS_API FramelessDialogPrivate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DECLARE_PUBLIC(FramelessDialog)
|
||||
Q_DISABLE_COPY_MOVE(FramelessDialogPrivate)
|
||||
FRAMELESSHELPER_PRIVATE_QT_CLASS(FramelessDialog)
|
||||
|
||||
public:
|
||||
explicit FramelessDialogPrivate(FramelessDialog *q);
|
||||
~FramelessDialogPrivate() override;
|
||||
|
||||
Q_NODISCARD static FramelessDialogPrivate *get(FramelessDialog *pub);
|
||||
Q_NODISCARD static const FramelessDialogPrivate *get(const FramelessDialog *pub);
|
||||
|
||||
FramelessDialog *q_ptr = nullptr;
|
||||
WidgetsSharedHelper *sharedHelper = nullptr;
|
||||
};
|
||||
|
||||
|
|
|
@ -30,24 +30,18 @@
|
|||
|
||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
class FramelessMainWindow;
|
||||
class WidgetsSharedHelper;
|
||||
|
||||
class FramelessMainWindow;
|
||||
class FRAMELESSHELPER_WIDGETS_API FramelessMainWindowPrivate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DECLARE_PUBLIC(FramelessMainWindow)
|
||||
Q_DISABLE_COPY_MOVE(FramelessMainWindowPrivate)
|
||||
FRAMELESSHELPER_PRIVATE_QT_CLASS(FramelessMainWindow)
|
||||
|
||||
public:
|
||||
explicit FramelessMainWindowPrivate(FramelessMainWindow *q);
|
||||
~FramelessMainWindowPrivate() override;
|
||||
|
||||
Q_NODISCARD static FramelessMainWindowPrivate *get(FramelessMainWindow *pub);
|
||||
Q_NODISCARD static const FramelessMainWindowPrivate *get(const FramelessMainWindow *pub);
|
||||
|
||||
FramelessMainWindow *q_ptr = nullptr;
|
||||
Qt::WindowState savedWindowState = Qt::WindowNoState;
|
||||
WidgetsSharedHelper *sharedHelper = nullptr;
|
||||
};
|
||||
|
|
|
@ -30,24 +30,18 @@
|
|||
|
||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
class FramelessWidget;
|
||||
class WidgetsSharedHelper;
|
||||
|
||||
class FramelessWidget;
|
||||
class FRAMELESSHELPER_WIDGETS_API FramelessWidgetPrivate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DECLARE_PUBLIC(FramelessWidget)
|
||||
Q_DISABLE_COPY_MOVE(FramelessWidgetPrivate)
|
||||
FRAMELESSHELPER_PRIVATE_QT_CLASS(FramelessWidget)
|
||||
|
||||
public:
|
||||
explicit FramelessWidgetPrivate(FramelessWidget *q);
|
||||
~FramelessWidgetPrivate() override;
|
||||
|
||||
Q_NODISCARD static FramelessWidgetPrivate *get(FramelessWidget *pub);
|
||||
Q_NODISCARD static const FramelessWidgetPrivate *get(const FramelessWidget *pub);
|
||||
|
||||
FramelessWidget *q_ptr = nullptr;
|
||||
Qt::WindowState savedWindowState = Qt::WindowNoState;
|
||||
WidgetsSharedHelper *sharedHelper = nullptr;
|
||||
};
|
||||
|
|
|
@ -36,24 +36,18 @@ class MicaMaterial;
|
|||
#if FRAMELESSHELPER_CONFIG(border_painter)
|
||||
class WindowBorderPainter;
|
||||
#endif
|
||||
class FramelessWidgetsHelper;
|
||||
struct FramelessWidgetsHelperData;
|
||||
class WidgetsSharedHelper;
|
||||
|
||||
class FramelessWidgetsHelper;
|
||||
class FRAMELESSHELPER_WIDGETS_API FramelessWidgetsHelperPrivate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DECLARE_PUBLIC(FramelessWidgetsHelper)
|
||||
Q_DISABLE_COPY_MOVE(FramelessWidgetsHelperPrivate)
|
||||
FRAMELESSHELPER_PRIVATE_QT_CLASS(FramelessWidgetsHelper)
|
||||
|
||||
public:
|
||||
explicit FramelessWidgetsHelperPrivate(FramelessWidgetsHelper *q);
|
||||
~FramelessWidgetsHelperPrivate() override;
|
||||
|
||||
Q_NODISCARD static FramelessWidgetsHelperPrivate *get(FramelessWidgetsHelper *pub);
|
||||
Q_NODISCARD static const FramelessWidgetsHelperPrivate *get(const FramelessWidgetsHelper *pub);
|
||||
|
||||
void attach();
|
||||
void detach();
|
||||
|
||||
|
@ -83,10 +77,7 @@ public:
|
|||
Q_NODISCARD bool shouldIgnoreMouseEvents(const QPoint &pos) const;
|
||||
void setSystemButtonState(const Global::SystemButtonType button, const Global::ButtonState state);
|
||||
Q_NODISCARD QWidget *findTopLevelWindow() const;
|
||||
Q_NODISCARD const FramelessWidgetsHelperData *getWindowData() const;
|
||||
Q_NODISCARD FramelessWidgetsHelperData *getWindowDataMutable() const;
|
||||
|
||||
FramelessWidgetsHelper *q_ptr = nullptr;
|
||||
QColor savedWindowBackgroundColor = {};
|
||||
bool blurBehindWindowEnabled = false;
|
||||
QPointer<QWidget> window = nullptr;
|
||||
|
|
|
@ -32,24 +32,17 @@
|
|||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
class StandardSystemButton;
|
||||
|
||||
class FRAMELESSHELPER_WIDGETS_API StandardSystemButtonPrivate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DECLARE_PUBLIC(StandardSystemButton)
|
||||
Q_DISABLE_COPY_MOVE(StandardSystemButtonPrivate)
|
||||
FRAMELESSHELPER_PRIVATE_QT_CLASS(StandardSystemButton)
|
||||
|
||||
public:
|
||||
explicit StandardSystemButtonPrivate(StandardSystemButton *q);
|
||||
~StandardSystemButtonPrivate() override;
|
||||
|
||||
Q_NODISCARD static StandardSystemButtonPrivate *get(StandardSystemButton *pub);
|
||||
Q_NODISCARD static const StandardSystemButtonPrivate *get(const StandardSystemButton *pub);
|
||||
|
||||
Q_NODISCARD static QSize getRecommendedButtonSize();
|
||||
|
||||
StandardSystemButton *q_ptr = nullptr;
|
||||
Global::SystemButtonType buttonType = Global::SystemButtonType::Unknown;
|
||||
QString glyph = {};
|
||||
QColor hoverColor = {};
|
||||
|
|
|
@ -40,14 +40,12 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
|
|||
class StandardSystemButton;
|
||||
#endif
|
||||
class ChromePalette;
|
||||
class StandardTitleBar;
|
||||
|
||||
class StandardTitleBar;
|
||||
class FRAMELESSHELPER_WIDGETS_API StandardTitleBarPrivate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DECLARE_PUBLIC(StandardTitleBar)
|
||||
Q_DISABLE_COPY_MOVE(StandardTitleBarPrivate)
|
||||
FRAMELESSHELPER_PRIVATE_QT_CLASS(StandardTitleBar)
|
||||
|
||||
public:
|
||||
struct FontMetrics
|
||||
|
@ -60,9 +58,6 @@ public:
|
|||
explicit StandardTitleBarPrivate(StandardTitleBar *q);
|
||||
~StandardTitleBarPrivate() override;
|
||||
|
||||
Q_NODISCARD static StandardTitleBarPrivate *get(StandardTitleBar *pub);
|
||||
Q_NODISCARD static const StandardTitleBarPrivate *get(const StandardTitleBar *pub);
|
||||
|
||||
Q_NODISCARD QRect windowIconRect() const;
|
||||
Q_NODISCARD bool windowIconVisible_real() const;
|
||||
Q_NODISCARD bool isInTitleBarIconArea(const QPoint &pos) const;
|
||||
|
@ -79,7 +74,6 @@ public:
|
|||
|
||||
void initialize();
|
||||
|
||||
StandardTitleBar *q_ptr = nullptr;
|
||||
#if (!defined(Q_OS_MACOS) && FRAMELESSHELPER_CONFIG(system_button))
|
||||
StandardSystemButton *minimizeButton = nullptr;
|
||||
StandardSystemButton *maximizeButton = nullptr;
|
||||
|
|
|
@ -39,8 +39,7 @@ class WindowBorderPainter;
|
|||
class FRAMELESSHELPER_WIDGETS_API WidgetsSharedHelper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DISABLE_COPY_MOVE(WidgetsSharedHelper)
|
||||
FRAMELESSHELPER_QT_CLASS(WidgetsSharedHelper)
|
||||
#if FRAMELESSHELPER_CONFIG(mica_material)
|
||||
Q_PROPERTY(bool micaEnabled READ isMicaEnabled WRITE setMicaEnabled NOTIFY micaEnabledChanged FINAL)
|
||||
#endif
|
||||
|
|
|
@ -32,13 +32,10 @@
|
|||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
class StandardSystemButtonPrivate;
|
||||
|
||||
class FRAMELESSHELPER_WIDGETS_API StandardSystemButton : public QPushButton
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DECLARE_PRIVATE(StandardSystemButton)
|
||||
Q_DISABLE_COPY_MOVE(StandardSystemButton)
|
||||
FRAMELESSHELPER_PUBLIC_QT_CLASS(StandardSystemButton)
|
||||
Q_PROPERTY(Global::SystemButtonType buttonType READ buttonType WRITE setButtonType NOTIFY buttonTypeChanged FINAL)
|
||||
Q_PROPERTY(QString glyph READ glyph WRITE setGlyph NOTIFY glyphChanged FINAL)
|
||||
Q_PROPERTY(QColor hoverColor READ hoverColor WRITE setHoverColor NOTIFY hoverColorChanged FINAL)
|
||||
|
@ -89,9 +86,6 @@ Q_SIGNALS:
|
|||
void inactiveForegroundColorChanged();
|
||||
void activeChanged();
|
||||
void glyphSizeChanged();
|
||||
|
||||
private:
|
||||
QScopedPointer<StandardSystemButtonPrivate> d_ptr;
|
||||
};
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
|
|
@ -37,13 +37,10 @@
|
|||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
class StandardTitleBarPrivate;
|
||||
|
||||
class FRAMELESSHELPER_WIDGETS_API StandardTitleBar : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DECLARE_PRIVATE(StandardTitleBar)
|
||||
Q_DISABLE_COPY_MOVE(StandardTitleBar)
|
||||
FRAMELESSHELPER_PUBLIC_QT_CLASS(StandardTitleBar)
|
||||
Q_PROPERTY(Qt::Alignment titleLabelAlignment READ titleLabelAlignment WRITE setTitleLabelAlignment NOTIFY titleLabelAlignmentChanged FINAL)
|
||||
#if (!defined(Q_OS_MACOS) && FRAMELESSHELPER_CONFIG(system_button))
|
||||
Q_PROPERTY(StandardSystemButton* minimizeButton READ minimizeButton CONSTANT FINAL)
|
||||
|
@ -104,9 +101,6 @@ Q_SIGNALS:
|
|||
void windowIconSizeChanged();
|
||||
void windowIconVisibleChanged();
|
||||
void titleFontChanged();
|
||||
|
||||
private:
|
||||
QScopedPointer<StandardTitleBarPrivate> d_ptr;
|
||||
};
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
|
|
@ -35,18 +35,18 @@ if(UNIX AND NOT APPLE)
|
|||
endif()
|
||||
find_package(X11 QUIET COMPONENTS xcb)
|
||||
if(TARGET X11::xcb)
|
||||
message("Found system XCB. The XCB wrapper will be disabled.")
|
||||
message(STATUS "--- Found system XCB. The XCB wrapper will be disabled.")
|
||||
else()
|
||||
message("System XCB not found. The XCB wrapper will be used instead.")
|
||||
message(STATUS "--- System XCB not found. The XCB wrapper will be used instead.")
|
||||
endif()
|
||||
find_package(PkgConfig QUIET)
|
||||
if(PkgConfig_FOUND)
|
||||
pkg_check_modules(GTK3 QUIET IMPORTED_TARGET gtk+-3.0)
|
||||
endif()
|
||||
if(TARGET PkgConfig::GTK3)
|
||||
message("Found system GTK. The GTK wrapper will be disabled.")
|
||||
message(STATUS "--- Found system GTK. The GTK wrapper will be disabled.")
|
||||
else()
|
||||
message("System GTK not found. The GTK wrapper will be used instead.")
|
||||
message(STATUS "--- System GTK not found. The GTK wrapper will be used instead.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@ -61,14 +61,12 @@ set(PUBLIC_HEADERS
|
|||
${FRAMELESSHELPER_VERSION_FILE}
|
||||
${FRAMELESSHELPER_CONFIG_FILE}
|
||||
${INCLUDE_PREFIX}/framelesshelpercore_global.h
|
||||
${INCLUDE_PREFIX}/framelesshelper_qt.h
|
||||
${INCLUDE_PREFIX}/framelessmanager.h
|
||||
${INCLUDE_PREFIX}/utils.h
|
||||
)
|
||||
|
||||
set(PUBLIC_HEADERS_ALIAS
|
||||
${INCLUDE_PREFIX}/Global
|
||||
${INCLUDE_PREFIX}/FramelessHelper_Qt
|
||||
${INCLUDE_PREFIX}/FramelessManager
|
||||
${INCLUDE_PREFIX}/Utils
|
||||
)
|
||||
|
@ -84,7 +82,6 @@ set(PRIVATE_HEADERS
|
|||
|
||||
set(SOURCES
|
||||
utils.cpp
|
||||
framelesshelper_qt.cpp
|
||||
framelessmanager.cpp
|
||||
framelessconfig.cpp
|
||||
sysapiloader.cpp
|
||||
|
@ -92,14 +89,8 @@ set(SOURCES
|
|||
)
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND PUBLIC_HEADERS
|
||||
${INCLUDE_PREFIX}/framelesshelper_windows.h
|
||||
${INCLUDE_PREFIX}/framelesshelper_win.h
|
||||
)
|
||||
list(APPEND PUBLIC_HEADERS_ALIAS
|
||||
${INCLUDE_PREFIX}/FramelessHelper_Windows
|
||||
${INCLUDE_PREFIX}/FramelessHelper_Win
|
||||
)
|
||||
list(APPEND PUBLIC_HEADERS ${INCLUDE_PREFIX}/framelesshelper_windows.h)
|
||||
list(APPEND PUBLIC_HEADERS_ALIAS ${INCLUDE_PREFIX}/FramelessHelper_Windows)
|
||||
list(APPEND PRIVATE_HEADERS
|
||||
${INCLUDE_PREFIX}/private/registrykey_p.h
|
||||
${INCLUDE_PREFIX}/private/winverhelper_p.h
|
||||
|
@ -107,25 +98,35 @@ if(WIN32)
|
|||
list(APPEND SOURCES
|
||||
registrykey.cpp
|
||||
utils_win.cpp
|
||||
framelesshelper_win.cpp
|
||||
winverhelper.cpp
|
||||
platformsupport_win.cpp
|
||||
)
|
||||
elseif(APPLE)
|
||||
list(APPEND SOURCES utils_mac.mm)
|
||||
elseif(UNIX)
|
||||
list(APPEND PUBLIC_HEADERS
|
||||
${INCLUDE_PREFIX}/framelesshelper_linux.h
|
||||
)
|
||||
list(APPEND PUBLIC_HEADERS_ALIAS
|
||||
${INCLUDE_PREFIX}/FramelessHelper_Linux
|
||||
)
|
||||
list(APPEND PUBLIC_HEADERS ${INCLUDE_PREFIX}/framelesshelper_linux.h)
|
||||
list(APPEND PUBLIC_HEADERS_ALIAS ${INCLUDE_PREFIX}/FramelessHelper_Linux)
|
||||
list(APPEND SOURCES
|
||||
utils_linux.cpp
|
||||
platformsupport_linux.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if(FRAMELESSHELPER_NATIVE_IMPL)
|
||||
if(WIN32)
|
||||
list(APPEND PUBLIC_HEADERS ${INCLUDE_PREFIX}/framelesshelper_win.h)
|
||||
list(APPEND PUBLIC_HEADERS_ALIAS ${INCLUDE_PREFIX}/FramelessHelper_Win)
|
||||
list(APPEND SOURCES framelesshelper_win.cpp)
|
||||
elseif(APPLE)
|
||||
elseif(UNIX)
|
||||
else()
|
||||
endif()
|
||||
else()
|
||||
list(APPEND PUBLIC_HEADERS ${INCLUDE_PREFIX}/framelesshelper_qt.h)
|
||||
list(APPEND PUBLIC_HEADERS_ALIAS ${INCLUDE_PREFIX}/FramelessHelper_Qt)
|
||||
list(APPEND SOURCES framelesshelper_qt.cpp)
|
||||
endif()
|
||||
|
||||
if(NOT FRAMELESSHELPER_NO_TITLEBAR)
|
||||
list(APPEND PUBLIC_HEADERS ${INCLUDE_PREFIX}/chromepalette.h)
|
||||
list(APPEND PUBLIC_HEADERS_ALIAS ${INCLUDE_PREFIX}/ChromePalette)
|
||||
|
@ -158,7 +159,7 @@ if(WIN32 AND NOT FRAMELESSHELPER_BUILD_STATIC)
|
|||
COPYRIGHT "MIT License"
|
||||
ORIGINAL_FILENAME "${SUB_MODULE_FULL_NAME}.dll"
|
||||
PRODUCT "${PROJECT_NAME}"
|
||||
COMMENTS "Built from commit ${PROJECT_VERSION_COMMIT} on ${PROJECT_COMPILE_DATETIME} (UTC)."
|
||||
COMMENTS "Who don't love Raiden Shogun ?"
|
||||
LIBRARY
|
||||
)
|
||||
endif()
|
||||
|
|
|
@ -85,14 +85,14 @@ Q_GLOBAL_STATIC(FramelessConfigData, g_framelessConfigData)
|
|||
static inline void warnInappropriateOptions()
|
||||
{
|
||||
const FramelessConfig * const cfg = FramelessConfig::instance();
|
||||
if (cfg->isSet(Option::UseCrossPlatformQtImplementation)) {
|
||||
WARNING << "Option::UseCrossPlatformQtImplementation is deprecated and has no effect now. It will be removed in a future version.";
|
||||
}
|
||||
#ifdef Q_OS_WINDOWS
|
||||
if (cfg->isSet(Option::DisableWindowsSnapLayout)) {
|
||||
WARNING << "Option::DisableWindowsSnapLayout is deprecated and will removed in a future version. It has not effect now.";
|
||||
WARNING << "Option::DisableWindowsSnapLayout is deprecated and has no effect now. It will be removed in a future version.";
|
||||
}
|
||||
#else
|
||||
if (cfg->isSet(Option::UseCrossPlatformQtImplementation)) {
|
||||
WARNING << "Option::UseCrossPlatformQtImplementation is default on non-Windows platforms.";
|
||||
}
|
||||
if (cfg->isSet(Option::ForceHideWindowFrameBorder)) {
|
||||
WARNING << "Option::ForceHideWindowFrameBorder is only available on Windows.";
|
||||
}
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
*/
|
||||
|
||||
#include "framelesshelper_qt.h"
|
||||
|
||||
#if !FRAMELESSHELPER_CONFIG(native_impl)
|
||||
|
||||
#include "framelessmanager.h"
|
||||
#include "framelessmanager_p.h"
|
||||
#include "framelessconfig_p.h"
|
||||
|
@ -49,40 +52,80 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
|
|||
|
||||
using namespace Global;
|
||||
|
||||
struct FramelessQtHelperData
|
||||
struct FramelessDataQt : public FramelessData
|
||||
{
|
||||
SystemParameters params = {};
|
||||
FramelessHelperQt *eventFilter = nullptr;
|
||||
FramelessHelperQt *framelessHelperImpl = nullptr;
|
||||
bool cursorShapeChanged = false;
|
||||
bool leftButtonPressed = false;
|
||||
|
||||
FramelessDataQt();
|
||||
~FramelessDataQt() override;
|
||||
};
|
||||
using FramelessDataQtPtr = std::shared_ptr<FramelessDataQt>;
|
||||
|
||||
[[nodiscard]] static inline FramelessDataQtPtr tryGetData(const QObject *window)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
if (!window) {
|
||||
return nullptr;
|
||||
}
|
||||
const FramelessDataPtr data = FramelessManagerPrivate::getData(window);
|
||||
if (!data) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::dynamic_pointer_cast<FramelessDataQt>(data);
|
||||
}
|
||||
|
||||
class FramelessHelperQtPrivate
|
||||
{
|
||||
FRAMELESSHELPER_PRIVATE_CLASS(FramelessHelperQt)
|
||||
|
||||
public:
|
||||
explicit FramelessHelperQtPrivate(FramelessHelperQt *q);
|
||||
~FramelessHelperQtPrivate();
|
||||
|
||||
const QObject *window = nullptr;
|
||||
};
|
||||
|
||||
using FramelessQtHelperInternal = QHash<WId, FramelessQtHelperData>;
|
||||
FramelessDataQt::FramelessDataQt() = default;
|
||||
|
||||
Q_GLOBAL_STATIC(FramelessQtHelperInternal, g_framelessQtHelperData)
|
||||
FramelessDataQt::~FramelessDataQt() = default;
|
||||
|
||||
FramelessHelperQt::FramelessHelperQt(QObject *parent) : QObject(parent) {}
|
||||
[[nodiscard]] FramelessDataPtr FramelessData::create()
|
||||
{
|
||||
return std::make_shared<FramelessDataQt>();
|
||||
}
|
||||
|
||||
FramelessHelperQtPrivate::FramelessHelperQtPrivate(FramelessHelperQt *q) : q_ptr(q)
|
||||
{
|
||||
Q_ASSERT(q_ptr);
|
||||
}
|
||||
|
||||
FramelessHelperQtPrivate::~FramelessHelperQtPrivate() = default;
|
||||
|
||||
FramelessHelperQt::FramelessHelperQt(QObject *parent) : QObject(parent), d_ptr(new FramelessHelperQtPrivate(this))
|
||||
{
|
||||
}
|
||||
|
||||
FramelessHelperQt::~FramelessHelperQt() = default;
|
||||
|
||||
void FramelessHelperQt::addWindow(FramelessParamsConst params)
|
||||
void FramelessHelperQt::addWindow(const QObject *window)
|
||||
{
|
||||
Q_ASSERT(params);
|
||||
if (!params) {
|
||||
Q_ASSERT(window);
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
const WId windowId = params->getWindowId();
|
||||
const auto it = g_framelessQtHelperData()->constFind(windowId);
|
||||
if (it != g_framelessQtHelperData()->constEnd()) {
|
||||
const FramelessDataQtPtr data = tryGetData(window);
|
||||
if (!data || data->frameless || !data->callbacks) {
|
||||
return;
|
||||
}
|
||||
FramelessQtHelperData data = {};
|
||||
data.params = *params;
|
||||
QWindow *window = params->getWindowHandle();
|
||||
// Give it a parent so that it can be automatically deleted by Qt.
|
||||
data.eventFilter = new FramelessHelperQt(window);
|
||||
g_framelessQtHelperData()->insert(windowId, data);
|
||||
const auto shouldApplyFramelessFlag = []() -> bool {
|
||||
QWindow *qWindow = data->callbacks->getWindowHandle();
|
||||
Q_ASSERT(qWindow);
|
||||
if (!qWindow) {
|
||||
return;
|
||||
}
|
||||
data->frameless = true;
|
||||
static const auto shouldApplyFramelessFlag = []() -> bool {
|
||||
#ifdef Q_OS_MACOS
|
||||
return false;
|
||||
#elif (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
|
@ -92,35 +135,47 @@ void FramelessHelperQt::addWindow(FramelessParamsConst params)
|
|||
#endif // Q_OS_MACOS
|
||||
}();
|
||||
#if (defined(Q_OS_MACOS) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)))
|
||||
window->setProperty("_q_mac_wantsLayer", 1);
|
||||
qWindow->setProperty("_q_mac_wantsLayer", 1);
|
||||
#endif // (defined(Q_OS_MACOS) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)))
|
||||
if (shouldApplyFramelessFlag) {
|
||||
params->setWindowFlags(params->getWindowFlags() | Qt::FramelessWindowHint);
|
||||
data->callbacks->setWindowFlags(data->callbacks->getWindowFlags() | Qt::FramelessWindowHint);
|
||||
} else {
|
||||
#if (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
std::ignore = Utils::tryHideSystemTitleBar(windowId, true);
|
||||
std::ignore = Utils::tryHideSystemTitleBar(data->callbacks->getWindowId(), true);
|
||||
#elif defined(Q_OS_MACOS)
|
||||
Utils::setSystemTitleBarVisible(windowId, false);
|
||||
Utils::setSystemTitleBarVisible(data->callbacks->getWindowId(), false);
|
||||
#endif // Q_OS_LINUX
|
||||
}
|
||||
window->installEventFilter(data.eventFilter);
|
||||
if (!data->framelessHelperImpl) {
|
||||
data->framelessHelperImpl = new FramelessHelperQt(qWindow);
|
||||
data->framelessHelperImpl->d_func()->window = window;
|
||||
qWindow->installEventFilter(data->framelessHelperImpl);
|
||||
}
|
||||
FramelessHelperEnableThemeAware();
|
||||
}
|
||||
|
||||
void FramelessHelperQt::removeWindow(const WId windowId)
|
||||
void FramelessHelperQt::removeWindow(const QObject *window)
|
||||
{
|
||||
Q_ASSERT(windowId);
|
||||
if (!windowId) {
|
||||
Q_ASSERT(window);
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
const auto it = g_framelessQtHelperData()->constFind(windowId);
|
||||
if (it == g_framelessQtHelperData()->constEnd()) {
|
||||
const FramelessDataQtPtr data = tryGetData(window);
|
||||
if (!data || !data->frameless || !data->callbacks) {
|
||||
return;
|
||||
}
|
||||
g_framelessQtHelperData()->erase(it);
|
||||
if (data->framelessHelperImpl) {
|
||||
QWindow *qWindow = data->callbacks->getWindowHandle();
|
||||
Q_ASSERT(qWindow);
|
||||
if (qWindow) {
|
||||
qWindow->removeEventFilter(data->framelessHelperImpl);
|
||||
delete data->framelessHelperImpl;
|
||||
data->framelessHelperImpl = nullptr;
|
||||
}
|
||||
}
|
||||
#ifdef Q_OS_MACOS
|
||||
Utils::removeWindowProxy(windowId);
|
||||
#endif
|
||||
Utils::removeWindowProxy(data->callbacks->getWindowId());
|
||||
#endif // Q_OS_MACOS
|
||||
}
|
||||
|
||||
bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event)
|
||||
|
@ -131,24 +186,22 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event)
|
|||
return false;
|
||||
}
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 5, 0))
|
||||
// First detect whether we got a theme change event or not, if so,
|
||||
// inform the user the system theme has changed.
|
||||
if (Utils::isThemeChangeEvent(event)) {
|
||||
// Sometimes the FramelessManager instance may be destroyed already.
|
||||
if (FramelessManager * const manager = FramelessManager::instance()) {
|
||||
if (FramelessManagerPrivate * const managerPriv = FramelessManagerPrivate::get(manager)) {
|
||||
if (FramelessManager *manager = FramelessManager::instance()) {
|
||||
if (FramelessManagerPrivate *managerPriv = FramelessManagerPrivate::get(manager)) {
|
||||
managerPriv->notifySystemThemeHasChangedOrNot();
|
||||
}
|
||||
}
|
||||
return QObject::eventFilter(object, event);
|
||||
return false;
|
||||
}
|
||||
#endif // (QT_VERSION < QT_VERSION_CHECK(6, 5, 0))
|
||||
// We are only interested in events that are dispatched to top level windows.
|
||||
if (!object->isWindowType()) {
|
||||
return QObject::eventFilter(object, event);
|
||||
Q_D(FramelessHelperQt);
|
||||
if (!d->window || !object->isWindowType()) {
|
||||
return false;
|
||||
}
|
||||
const QEvent::Type type = event->type();
|
||||
// We are only interested in some specific mouse events (plus DPR change event).
|
||||
// We are only interested in some specific mouse events (plus the DPR change event).
|
||||
if ((type != QEvent::MouseButtonPress) && (type != QEvent::MouseButtonRelease)
|
||||
&& (type != QEvent::MouseButtonDblClick) && (type != QEvent::MouseMove)
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0))
|
||||
|
@ -157,25 +210,22 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event)
|
|||
&& (type != QEvent::ScreenChangeInternal) // Qt's internal event to notify screen change and DPR change.
|
||||
#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0))
|
||||
) {
|
||||
return QObject::eventFilter(object, event);
|
||||
return false;
|
||||
}
|
||||
const auto window = qobject_cast<QWindow *>(object);
|
||||
const WId windowId = window->winId();
|
||||
const auto it = g_framelessQtHelperData()->find(windowId);
|
||||
if (it == g_framelessQtHelperData()->end()) {
|
||||
return QObject::eventFilter(object, event);
|
||||
const FramelessDataQtPtr data = tryGetData(d->window);
|
||||
if (!data || !data->frameless || !data->callbacks) {
|
||||
return false;
|
||||
}
|
||||
const FramelessQtHelperData &data = it.value();
|
||||
FramelessQtHelperData &muData = it.value();
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0))
|
||||
if (type == QEvent::DevicePixelRatioChange)
|
||||
#else // QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
|
||||
if (type == QEvent::ScreenChangeInternal)
|
||||
#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0))
|
||||
{
|
||||
data.params.forceChildrenRepaint(500);
|
||||
return QObject::eventFilter(object, event);
|
||||
data->callbacks->forceChildrenRepaint(500);
|
||||
return false;
|
||||
}
|
||||
const auto qWindow = qobject_cast<QWindow *>(object);
|
||||
const auto mouseEvent = static_cast<QMouseEvent *>(event);
|
||||
const Qt::MouseButton button = mouseEvent->button();
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
|
@ -185,64 +235,63 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event)
|
|||
const QPoint scenePos = mouseEvent->windowPos().toPoint();
|
||||
const QPoint globalPos = mouseEvent->screenPos().toPoint();
|
||||
#endif
|
||||
const bool windowFixedSize = data.params.isWindowFixedSize();
|
||||
const bool ignoreThisEvent = data.params.shouldIgnoreMouseEvents(scenePos);
|
||||
const bool insideTitleBar = data.params.isInsideTitleBarDraggableArea(scenePos);
|
||||
const bool dontOverrideCursor = data.params.getProperty(kDontOverrideCursorVar, false).toBool();
|
||||
const bool dontToggleMaximize = data.params.getProperty(kDontToggleMaximizeVar, false).toBool();
|
||||
const bool windowFixedSize = data->callbacks->isWindowFixedSize();
|
||||
const bool ignoreThisEvent = data->callbacks->shouldIgnoreMouseEvents(scenePos);
|
||||
const bool insideTitleBar = data->callbacks->isInsideTitleBarDraggableArea(scenePos);
|
||||
const bool dontOverrideCursor = data->callbacks->getProperty(kDontOverrideCursorVar, false).toBool();
|
||||
const bool dontToggleMaximize = data->callbacks->getProperty(kDontToggleMaximizeVar, false).toBool();
|
||||
switch (type) {
|
||||
case QEvent::MouseButtonPress: {
|
||||
case QEvent::MouseButtonPress:
|
||||
if (button == Qt::LeftButton) {
|
||||
muData.leftButtonPressed = true;
|
||||
data->leftButtonPressed = true;
|
||||
if (!windowFixedSize) {
|
||||
const Qt::Edges edges = Utils::calculateWindowEdges(window, scenePos);
|
||||
const Qt::Edges edges = Utils::calculateWindowEdges(qWindow, scenePos);
|
||||
if (edges != Qt::Edges{}) {
|
||||
std::ignore = Utils::startSystemResize(window, edges, globalPos);
|
||||
std::ignore = Utils::startSystemResize(qWindow, edges, globalPos);
|
||||
event->accept();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case QEvent::MouseButtonRelease: {
|
||||
break;
|
||||
case QEvent::MouseButtonRelease:
|
||||
if (button == Qt::LeftButton) {
|
||||
muData.leftButtonPressed = false;
|
||||
}
|
||||
if (button == Qt::RightButton) {
|
||||
data->leftButtonPressed = false;
|
||||
} else if (button == Qt::RightButton) {
|
||||
if (!ignoreThisEvent && insideTitleBar) {
|
||||
data.params.showSystemMenu(globalPos);
|
||||
data->callbacks->showSystemMenu(globalPos);
|
||||
event->accept();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case QEvent::MouseButtonDblClick: {
|
||||
break;
|
||||
case QEvent::MouseButtonDblClick:
|
||||
if (!dontToggleMaximize && (button == Qt::LeftButton) && !windowFixedSize && !ignoreThisEvent && insideTitleBar) {
|
||||
Qt::WindowState newWindowState = Qt::WindowNoState;
|
||||
if (data.params.getWindowState() != Qt::WindowMaximized) {
|
||||
if (data->callbacks->getWindowState() != Qt::WindowMaximized) {
|
||||
newWindowState = Qt::WindowMaximized;
|
||||
}
|
||||
data.params.setWindowState(newWindowState);
|
||||
data->callbacks->setWindowState(newWindowState);
|
||||
event->accept();
|
||||
return true;
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
case QEvent::MouseMove: {
|
||||
if (!dontOverrideCursor && !windowFixedSize) {
|
||||
const Qt::CursorShape cs = Utils::calculateCursorShape(window, scenePos);
|
||||
const Qt::CursorShape cs = Utils::calculateCursorShape(qWindow, scenePos);
|
||||
if (cs == Qt::ArrowCursor) {
|
||||
if (data.cursorShapeChanged) {
|
||||
data.params.unsetCursor();
|
||||
muData.cursorShapeChanged = false;
|
||||
if (data->cursorShapeChanged) {
|
||||
data->callbacks->unsetCursor();
|
||||
data->cursorShapeChanged = false;
|
||||
}
|
||||
} else {
|
||||
data.params.setCursor(cs);
|
||||
muData.cursorShapeChanged = true;
|
||||
data->callbacks->setCursor(cs);
|
||||
data->cursorShapeChanged = true;
|
||||
}
|
||||
}
|
||||
if (data.leftButtonPressed) {
|
||||
if (data->leftButtonPressed) {
|
||||
if (!ignoreThisEvent && insideTitleBar) {
|
||||
std::ignore = Utils::startSystemMove(window, globalPos);
|
||||
std::ignore = Utils::startSystemMove(qWindow, globalPos);
|
||||
event->accept();
|
||||
return true;
|
||||
}
|
||||
|
@ -251,7 +300,9 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
return QObject::eventFilter(object, event);
|
||||
return false;
|
||||
}
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
||||
#endif // !native_impl
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
|
||||
#if FRAMELESSHELPER_CONFIG(native_impl)
|
||||
|
||||
#include "framelessmanager.h"
|
||||
#include "framelessmanager_p.h"
|
||||
#include "framelessconfig_p.h"
|
||||
|
@ -60,7 +62,7 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
|
|||
|
||||
using namespace Global;
|
||||
|
||||
static constexpr const auto kMessageTag = WPARAM(2546789017);
|
||||
static constexpr const auto kMessageTag = WPARAM(0x97CCEA99);
|
||||
|
||||
FRAMELESSHELPER_STRING_CONSTANT(MonitorFromWindow)
|
||||
FRAMELESSHELPER_STRING_CONSTANT(GetMonitorInfoW)
|
||||
|
@ -100,9 +102,8 @@ enum class WindowPart : quint8
|
|||
TitleBar
|
||||
};
|
||||
|
||||
struct FramelessWin32HelperData
|
||||
struct FramelessDataWin : public FramelessData
|
||||
{
|
||||
SystemParameters params = {};
|
||||
// Store the last hit test result, it's helpful to handle WM_MOUSEMOVE and WM_NCMOUSELEAVE.
|
||||
WindowPart lastHitTestResult = WindowPart::Outside;
|
||||
// True if we blocked a WM_MOUSELEAVE when mouse moves on chrome button, false when a
|
||||
|
@ -112,36 +113,39 @@ struct FramelessWin32HelperData
|
|||
#if (QT_VERSION < QT_VERSION_CHECK(6, 5, 1))
|
||||
QRect restoreGeometry = {};
|
||||
#endif // (QT_VERSION < QT_VERSION_CHECK(6, 5, 1))
|
||||
};
|
||||
|
||||
struct FramelessWin32HelperInternal
|
||||
FramelessDataWin();
|
||||
~FramelessDataWin() override;
|
||||
};
|
||||
using FramelessDataWinPtr = std::shared_ptr<FramelessDataWin>;
|
||||
|
||||
FramelessDataWin::FramelessDataWin() = default;
|
||||
|
||||
FramelessDataWin::~FramelessDataWin() = default;
|
||||
|
||||
[[nodiscard]] FramelessDataPtr FramelessData::create()
|
||||
{
|
||||
std::unique_ptr<FramelessHelperWin> nativeEventFilter = nullptr;
|
||||
QHash<WId, FramelessWin32HelperData> data = {};
|
||||
return std::make_shared<FramelessDataWin>();
|
||||
}
|
||||
|
||||
[[nodiscard]] static inline FramelessDataWinPtr tryGetData(const QObject *window)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
if (!window) {
|
||||
return nullptr;
|
||||
}
|
||||
const FramelessDataPtr data = FramelessManagerPrivate::getData(window);
|
||||
if (!data) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::dynamic_pointer_cast<FramelessDataWin>(data);
|
||||
}
|
||||
|
||||
struct FramelessHelperWinInternal
|
||||
{
|
||||
std::unique_ptr<FramelessHelperWin> eventFilter = nullptr;
|
||||
};
|
||||
|
||||
Q_GLOBAL_STATIC(FramelessWin32HelperInternal, g_framelessWin32HelperData)
|
||||
|
||||
[[nodiscard]] extern bool operator==(const POINT &lhs, const POINT &rhs) noexcept;
|
||||
[[nodiscard]] extern bool operator!=(const POINT &lhs, const POINT &rhs) noexcept;
|
||||
|
||||
[[nodiscard]] extern bool operator==(const SIZE &lhs, const SIZE &rhs) noexcept;
|
||||
[[nodiscard]] extern bool operator!=(const SIZE &lhs, const SIZE &rhs) noexcept;
|
||||
|
||||
[[nodiscard]] extern bool operator==(const RECT &lhs, const RECT &rhs) noexcept;
|
||||
[[nodiscard]] extern bool operator!=(const RECT &lhs, const RECT &rhs) noexcept;
|
||||
|
||||
[[nodiscard]] extern QPoint point2qpoint(const POINT &point);
|
||||
[[nodiscard]] extern POINT qpoint2point(const QPoint &point);
|
||||
|
||||
[[nodiscard]] extern QSize size2qsize(const SIZE &size);
|
||||
[[nodiscard]] extern SIZE qsize2size(const QSize &size);
|
||||
|
||||
[[nodiscard]] extern QRect rect2qrect(const RECT &rect);
|
||||
[[nodiscard]] extern RECT qrect2rect(const QRect &qrect);
|
||||
|
||||
[[nodiscard]] extern QString hwnd2str(const WId windowId);
|
||||
[[nodiscard]] extern QString hwnd2str(const HWND hwnd);
|
||||
Q_GLOBAL_STATIC(FramelessHelperWinInternal, g_internalData)
|
||||
|
||||
[[nodiscard]] extern std::optional<MONITORINFOEXW> getMonitorForWindow(const HWND hwnd);
|
||||
|
||||
|
@ -212,49 +216,48 @@ FramelessHelperWin::FramelessHelperWin() : QAbstractNativeEventFilter() {}
|
|||
|
||||
FramelessHelperWin::~FramelessHelperWin() = default;
|
||||
|
||||
void FramelessHelperWin::addWindow(FramelessParamsConst params)
|
||||
void FramelessHelperWin::addWindow(const QObject *window)
|
||||
{
|
||||
Q_ASSERT(params);
|
||||
if (!params) {
|
||||
Q_ASSERT(window);
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
const WId windowId = params->getWindowId();
|
||||
const auto it = g_framelessWin32HelperData()->data.constFind(windowId);
|
||||
if (it != g_framelessWin32HelperData()->data.constEnd()) {
|
||||
const FramelessDataWinPtr data = tryGetData(window);
|
||||
if (!data || data->frameless || !data->callbacks) {
|
||||
return;
|
||||
}
|
||||
FramelessWin32HelperData data = {};
|
||||
data.params = *params;
|
||||
data.dpi = {Utils::getWindowDpi(windowId, true), Utils::getWindowDpi(windowId, false)};
|
||||
g_framelessWin32HelperData()->data.insert(windowId, data);
|
||||
if (!g_framelessWin32HelperData()->nativeEventFilter) {
|
||||
g_framelessWin32HelperData()->nativeEventFilter = std::make_unique<FramelessHelperWin>();
|
||||
qApp->installNativeEventFilter(g_framelessWin32HelperData()->nativeEventFilter.get());
|
||||
QWindow *qWindow = data->callbacks->getWindowHandle();
|
||||
Q_ASSERT(qWindow);
|
||||
if (!qWindow) {
|
||||
return;
|
||||
}
|
||||
DEBUG.noquote() << "The DPI of window" << hwnd2str(windowId) << "is" << data.dpi;
|
||||
const QWindow *window = params->getWindowHandle();
|
||||
data->frameless = true;
|
||||
data->dpi = Dpi{ Utils::getWindowDpi(data->windowId, true), Utils::getWindowDpi(data->windowId, false) };
|
||||
DEBUG.noquote() << "The DPI of window" << hwnd2str(data->windowId) << "is" << data->dpi;
|
||||
// Remove the bad window styles added by Qt (it's not that "bad" though).
|
||||
std::ignore = Utils::maybeFixupQtInternals(windowId);
|
||||
std::ignore = Utils::maybeFixupQtInternals(data->windowId);
|
||||
#if 0
|
||||
params->setWindowFlags(params->getWindowFlags() | Qt::FramelessWindowHint);
|
||||
data->callbacks->setWindowFlags(data->callbacks->getWindowFlags() | Qt::FramelessWindowHint);
|
||||
#else
|
||||
// Qt maintains a frame margin internally, we need to update it accordingly
|
||||
// otherwise we'll get lots of warning messages when we change the window
|
||||
// geometry, it will also affect the final window geometry because QPA will
|
||||
// always take it into account when setting window size and position.
|
||||
std::ignore = Utils::updateInternalWindowFrameMargins(const_cast<QWindow *>(window), true);
|
||||
std::ignore = Utils::updateInternalWindowFrameMargins(qWindow, true);
|
||||
#endif
|
||||
// Tell DWM our preferred frame margin.
|
||||
std::ignore = Utils::updateWindowFrameMargins(windowId, false);
|
||||
std::ignore = Utils::updateWindowFrameMargins(data->windowId, false);
|
||||
// Tell DWM we don't use the window icon/caption/sysmenu, don't draw them.
|
||||
std::ignore = Utils::hideOriginalTitleBarElements(windowId);
|
||||
std::ignore = Utils::hideOriginalTitleBarElements(data->windowId);
|
||||
// Without this hack, the child windows can't get DPI change messages from
|
||||
// Windows, which means only the top level windows can be scaled to the correct
|
||||
// size, we of course don't want such thing from happening.
|
||||
std::ignore = Utils::fixupChildWindowsDpiMessage(windowId);
|
||||
std::ignore = Utils::fixupChildWindowsDpiMessage(data->windowId);
|
||||
#if 0 // Conflicts with our blur mode setting.
|
||||
if (Utils::isWindowAccelerated(window) && Utils::isWindowTransparent(window)) {
|
||||
std::ignore = Utils::updateFramebufferTransparency(windowId);
|
||||
// If we are using 3D APIs (D3D, Vulkan, OpenGL, etc) to draw the window content,
|
||||
// we need to setup the DWM rendering policy as well.
|
||||
if (Utils::isWindowAccelerated(qWindow) && Utils::isWindowTransparent(qWindow)) {
|
||||
std::ignore = Utils::updateFramebufferTransparency(data->windowId);
|
||||
}
|
||||
#endif
|
||||
if (WindowsVersionHelper::isWin10RS1OrGreater()) {
|
||||
|
@ -262,42 +265,33 @@ void FramelessHelperWin::addWindow(FramelessParamsConst params)
|
|||
FramelessHelperEnableThemeAware();
|
||||
if (WindowsVersionHelper::isWin10RS5OrGreater()) {
|
||||
const bool dark = (FramelessManager::instance()->systemTheme() == SystemTheme::Dark);
|
||||
const auto isWidget = [params]() -> bool {
|
||||
const QObject *widget = params->getWidgetHandle();
|
||||
const auto isWidget = [&data]() -> bool {
|
||||
const QObject *widget = data->callbacks->getWidgetHandle();
|
||||
return (widget && widget->isWidgetType());
|
||||
}();
|
||||
if (!isWidget) {
|
||||
// Tell UXTheme we may need dark theme controls.
|
||||
// Causes some QtWidgets paint incorrectly, so only apply to Qt Quick applications.
|
||||
std::ignore = Utils::updateGlobalWin32ControlsTheme(windowId, dark);
|
||||
std::ignore = Utils::updateGlobalWin32ControlsTheme(data->windowId, dark);
|
||||
}
|
||||
std::ignore = Utils::refreshWin32ThemeResources(windowId, dark);
|
||||
std::ignore = Utils::refreshWin32ThemeResources(data->windowId, dark);
|
||||
if (WindowsVersionHelper::isWin11OrGreater()) {
|
||||
// DWM provides official API to adjust the window corner style, but only since Windows 11.
|
||||
if (FramelessConfig::instance()->isSet(Option::WindowUseSquareCorners)) {
|
||||
std::ignore = Utils::setCornerStyleForWindow(windowId, WindowCornerStyle::Square);
|
||||
std::ignore = Utils::setCornerStyleForWindow(data->windowId, WindowCornerStyle::Square);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!g_internalData()->eventFilter) {
|
||||
g_internalData()->eventFilter = std::make_unique<FramelessHelperWin>();
|
||||
qApp->installNativeEventFilter(g_internalData()->eventFilter.get());
|
||||
}
|
||||
}
|
||||
|
||||
void FramelessHelperWin::removeWindow(const WId windowId)
|
||||
void FramelessHelperWin::removeWindow(const QObject *window)
|
||||
{
|
||||
Q_ASSERT(windowId);
|
||||
if (!windowId) {
|
||||
return;
|
||||
}
|
||||
const auto it = g_framelessWin32HelperData()->data.constFind(windowId);
|
||||
if (it == g_framelessWin32HelperData()->data.constEnd()) {
|
||||
return;
|
||||
}
|
||||
g_framelessWin32HelperData()->data.erase(it);
|
||||
if (g_framelessWin32HelperData()->data.isEmpty()) {
|
||||
if (g_framelessWin32HelperData()->nativeEventFilter) {
|
||||
qApp->removeNativeEventFilter(g_framelessWin32HelperData()->nativeEventFilter.get());
|
||||
g_framelessWin32HelperData()->nativeEventFilter.reset();
|
||||
}
|
||||
}
|
||||
Q_UNUSED(window);
|
||||
}
|
||||
|
||||
bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *message, QT_NATIVE_EVENT_RESULT_TYPE *result)
|
||||
|
@ -319,15 +313,10 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
// Anyway, we should skip the entire processing in this case.
|
||||
return false;
|
||||
}
|
||||
const auto windowId = reinterpret_cast<WId>(hWnd);
|
||||
// Let's be extra safe.
|
||||
if (!Utils::isValidWindow(windowId, false, true)) {
|
||||
return false;
|
||||
}
|
||||
const UINT uMsg = msg->message;
|
||||
|
||||
const UINT uMsg = msg->message;
|
||||
// We should skip these messages otherwise we will get crashes.
|
||||
// WM_QUIT won't be posted to the WindowProc function.
|
||||
// NOTE: WM_QUIT won't be posted to the WindowProc function.
|
||||
switch (uMsg) {
|
||||
case WM_CLOSE:
|
||||
case WM_DESTROY:
|
||||
|
@ -340,19 +329,30 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
break;
|
||||
}
|
||||
|
||||
const auto it = g_framelessWin32HelperData()->data.find(windowId);
|
||||
if (it == g_framelessWin32HelperData()->data.end()) {
|
||||
const auto windowId = reinterpret_cast<WId>(hWnd);
|
||||
// Let's be extra safe.
|
||||
if (!Utils::isValidWindow(windowId, false, true)) {
|
||||
return false;
|
||||
}
|
||||
const FramelessWin32HelperData &data = it.value();
|
||||
FramelessWin32HelperData &muData = it.value();
|
||||
const QWindow *window = data.params.getWindowHandle();
|
||||
|
||||
const QObject *window = FramelessManagerPrivate::getWindow(windowId);
|
||||
if (!window) {
|
||||
return false;
|
||||
}
|
||||
const FramelessDataWinPtr data = tryGetData(window);
|
||||
if (!data || !data->frameless || !data->callbacks) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QWindow *qWindow = data->callbacks->getWindowHandle();
|
||||
|
||||
const bool frameBorderVisible = Utils::isWindowFrameBorderVisible();
|
||||
|
||||
const WPARAM wParam = msg->wParam;
|
||||
const LPARAM lParam = msg->lParam;
|
||||
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 5, 1))
|
||||
const auto updateRestoreGeometry = [windowId, &data, &muData](const bool ignoreWindowState) -> void {
|
||||
const auto updateRestoreGeometry = [windowId, &data](const bool ignoreWindowState) -> void {
|
||||
if (!ignoreWindowState && !Utils::isWindowNoState(windowId)) {
|
||||
return;
|
||||
}
|
||||
|
@ -361,10 +361,10 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
WARNING << "The calculated restore geometry is invalid.";
|
||||
return;
|
||||
}
|
||||
if (Utils::isValidGeometry(data.restoreGeometry) && (data.restoreGeometry == rect)) {
|
||||
if (Utils::isValidGeometry(data->restoreGeometry) && (data->restoreGeometry == rect)) {
|
||||
return;
|
||||
}
|
||||
muData.restoreGeometry = rect;
|
||||
data->restoreGeometry = rect;
|
||||
};
|
||||
#endif // (QT_VERSION < QT_VERSION_CHECK(6, 5, 1))
|
||||
|
||||
|
@ -372,6 +372,9 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
const int myMsg = overrideMessage.value_or(uMsg);
|
||||
const auto wparam = [myMsg, wParam]() -> WPARAM {
|
||||
if (myMsg == WM_NCMOUSELEAVE) {
|
||||
// wParam is always ignored in mouse leave messages, but here we
|
||||
// give them a special tag to be able to distinguish which messages
|
||||
// are sent by ourselves.
|
||||
return kMessageTag;
|
||||
}
|
||||
const quint64 keyState = Utils::getKeyState();
|
||||
|
@ -383,6 +386,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
}();
|
||||
const auto lparam = [myMsg, lParam, hWnd]() -> LPARAM {
|
||||
if (myMsg == WM_NCMOUSELEAVE) {
|
||||
// lParam is always ignored in mouse leave messages.
|
||||
return 0;
|
||||
}
|
||||
const auto screenPos = POINT{ GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
||||
|
@ -439,7 +443,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
case WM_NCXBUTTONDBLCLK:
|
||||
SEND_MESSAGE(hWnd, WM_XBUTTONDBLCLK, wparam, lparam);
|
||||
break;
|
||||
#if 0
|
||||
#if 0 // ### TODO: How to handle touch events?
|
||||
case WM_NCPOINTERUPDATE:
|
||||
case WM_NCPOINTERDOWN:
|
||||
case WM_NCPOINTERUP:
|
||||
|
@ -465,28 +469,28 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
// the reason above, and these superfluous mouse leave events cause Qt to think the
|
||||
// mouse has left the control, and thus we actually lost the hover state.
|
||||
// So we filter out these superfluous mouse leave events here to avoid this issue.
|
||||
const QPoint qtScenePos = Utils::fromNativeLocalPosition(window, QPoint{ msg->pt.x, msg->pt.y });
|
||||
const QPoint qtScenePos = Utils::fromNativeLocalPosition(qWindow, QPoint{ msg->pt.x, msg->pt.y });
|
||||
SystemButtonType dummy = SystemButtonType::Unknown;
|
||||
if (data.params.isInsideSystemButtons(qtScenePos, &dummy)) {
|
||||
muData.mouseLeaveBlocked = true;
|
||||
if (data->callbacks->isInsideSystemButtons(qtScenePos, &dummy)) {
|
||||
data->mouseLeaveBlocked = true;
|
||||
*result = FALSE;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
muData.mouseLeaveBlocked = false;
|
||||
data->mouseLeaveBlocked = false;
|
||||
}
|
||||
|
||||
switch (uMsg) {
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 9, 0)) // Qt has done this for us since 5.9.0
|
||||
case WM_NCCREATE: {
|
||||
case WM_NCCREATE:
|
||||
// Enable automatic DPI scaling for the non-client area of the window,
|
||||
// such as the caption bar, the scrollbars, and the menu bar. We need
|
||||
// to do this explicitly and manually here (only inside WM_NCCREATE).
|
||||
// If we are using the PMv2 DPI awareness mode, the non-client area
|
||||
// of the window will be scaled by the OS automatically, so there will
|
||||
// be no need to do this in that case.
|
||||
Utils::enableNonClientAreaDpiScalingForWindow(windowId);
|
||||
} break;
|
||||
std::ignore = Utils::enableNonClientAreaDpiScalingForWindow(windowId);
|
||||
break;
|
||||
#endif
|
||||
case WM_NCCALCSIZE: {
|
||||
// Windows是根据这个消息的返回值来设置窗口的客户区(窗口中真正显示的内容)
|
||||
|
@ -811,8 +815,8 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
// color, our homemade top border can almost have exactly the same
|
||||
// appearance with the system's one.
|
||||
|
||||
const auto hitTestRecorder = qScopeGuard([&muData, &result](){
|
||||
muData.lastHitTestResult = getHittedWindowPart(*result);
|
||||
const auto hitTestRecorder = qScopeGuard([&data, &result](){
|
||||
data->lastHitTestResult = getHittedWindowPart(*result);
|
||||
});
|
||||
|
||||
const auto nativeGlobalPos = POINT{ GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
||||
|
@ -830,9 +834,9 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
const auto clientWidth = RECT_WIDTH(clientRect);
|
||||
const auto clientHeight = RECT_HEIGHT(clientRect);
|
||||
|
||||
const QPoint qtScenePos = Utils::fromNativeLocalPosition(window, QPoint(nativeLocalPos.x, nativeLocalPos.y));
|
||||
const QPoint qtScenePos = Utils::fromNativeLocalPosition(qWindow, QPoint(nativeLocalPos.x, nativeLocalPos.y));
|
||||
SystemButtonType sysButtonType = SystemButtonType::Unknown;
|
||||
if (data.params.isInsideSystemButtons(qtScenePos, &sysButtonType)) {
|
||||
if (data->callbacks->isInsideSystemButtons(qtScenePos, &sysButtonType)) {
|
||||
// Even if the mouse is inside the chrome button area now, we should still allow the user
|
||||
// to be able to resize the window with the top or right window border, this is also the
|
||||
// normal behavior of a native Win32 window.
|
||||
|
@ -881,10 +885,10 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
const bool full = Utils::isFullScreen(windowId);
|
||||
const int frameSizeY = Utils::getResizeBorderThickness(windowId, false, true);
|
||||
const bool isTop = (nativeLocalPos.y < frameSizeY);
|
||||
const bool isTitleBar = data.params.isInsideTitleBarDraggableArea(qtScenePos);
|
||||
const bool isFixedSize = data.params.isWindowFixedSize();
|
||||
const bool dontOverrideCursor = data.params.getProperty(kDontOverrideCursorVar, false).toBool();
|
||||
const bool dontToggleMaximize = data.params.getProperty(kDontToggleMaximizeVar, false).toBool();
|
||||
const bool isTitleBar = data->callbacks->isInsideTitleBarDraggableArea(qtScenePos);
|
||||
const bool isFixedSize = data->callbacks->isWindowFixedSize();
|
||||
const bool dontOverrideCursor = data->callbacks->getProperty(kDontOverrideCursorVar, false).toBool();
|
||||
const bool dontToggleMaximize = data->callbacks->getProperty(kDontToggleMaximizeVar, false).toBool();
|
||||
|
||||
if (dontToggleMaximize) {
|
||||
static bool once = false;
|
||||
|
@ -995,8 +999,8 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
return true;
|
||||
}
|
||||
case WM_MOUSEMOVE:
|
||||
if ((data.lastHitTestResult != WindowPart::ChromeButton) && data.mouseLeaveBlocked) {
|
||||
muData.mouseLeaveBlocked = false;
|
||||
if ((data->lastHitTestResult != WindowPart::ChromeButton) && data->mouseLeaveBlocked) {
|
||||
data->mouseLeaveBlocked = false;
|
||||
std::ignore = requestForMouseLeaveMessage(hWnd, false);
|
||||
}
|
||||
break;
|
||||
|
@ -1013,17 +1017,17 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
case WM_NCXBUTTONDOWN:
|
||||
case WM_NCXBUTTONUP:
|
||||
case WM_NCXBUTTONDBLCLK:
|
||||
#if 0
|
||||
#if 0 // ### TODO: How to handle touch events?
|
||||
case WM_NCPOINTERUPDATE:
|
||||
case WM_NCPOINTERDOWN:
|
||||
case WM_NCPOINTERUP:
|
||||
#endif
|
||||
case WM_NCMOUSEHOVER: {
|
||||
const WindowPart currentWindowPart = data.lastHitTestResult;
|
||||
const WindowPart currentWindowPart = data->lastHitTestResult;
|
||||
if (uMsg == WM_NCMOUSEMOVE) {
|
||||
if (currentWindowPart != WindowPart::ChromeButton) {
|
||||
std::ignore = data.params.resetQtGrabbedControl();
|
||||
if (muData.mouseLeaveBlocked) {
|
||||
std::ignore = data->callbacks->resetQtGrabbedControl();
|
||||
if (data->mouseLeaveBlocked) {
|
||||
emulateClientAreaMessage(WM_NCMOUSELEAVE);
|
||||
}
|
||||
}
|
||||
|
@ -1034,32 +1038,38 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
// If the mouse is entering the client area, there must be a WM_NCHITTEST setting
|
||||
// it to `Client` before the WM_NCMOUSELEAVE comes;
|
||||
// If the mouse is leaving the window, current window part remains as `Outside`.
|
||||
muData.lastHitTestResult = WindowPart::Outside;
|
||||
data->lastHitTestResult = WindowPart::Outside;
|
||||
}
|
||||
|
||||
if (currentWindowPart == WindowPart::ChromeButton) {
|
||||
emulateClientAreaMessage();
|
||||
if (uMsg == WM_NCMOUSEMOVE) {
|
||||
// ### FIXME FIXME FIXME
|
||||
// ### FIXME: Calling DefWindowProc() here is really dangerous, investigate how to avoid doing this.
|
||||
// ### FIXME FIXME FIXME
|
||||
*result = ::DefWindowProcW(hWnd, WM_NCMOUSEMOVE, wParam, lParam);
|
||||
} else {
|
||||
// According to MSDN, we should return non-zero for X button messages to indicate
|
||||
// we have handled these messages (due to historical reasons), for all other messages
|
||||
// we should return zero instead.
|
||||
*result = (((uMsg >= WM_NCXBUTTONDOWN) && (uMsg <= WM_NCXBUTTONDBLCLK)) ? TRUE : FALSE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} break;
|
||||
case WM_NCMOUSELEAVE: {
|
||||
const WindowPart currentWindowPart = data.lastHitTestResult;
|
||||
const WindowPart currentWindowPart = data->lastHitTestResult;
|
||||
if (currentWindowPart == WindowPart::ChromeButton) {
|
||||
// If we press on the chrome button and move mouse, Windows will take the pressing area
|
||||
// as HTCLIENT which maybe because of our former retransmission of WM_NCLBUTTONDOWN, as
|
||||
// a result, a WM_NCMOUSELEAVE will come immediately and a lot of WM_MOUSEMOVE will come
|
||||
// if we move the mouse, we should track the mouse in advance.
|
||||
if (muData.mouseLeaveBlocked) {
|
||||
muData.mouseLeaveBlocked = false;
|
||||
if (data->mouseLeaveBlocked) {
|
||||
data->mouseLeaveBlocked = false;
|
||||
std::ignore = requestForMouseLeaveMessage(hWnd, false);
|
||||
}
|
||||
} else {
|
||||
if (data.mouseLeaveBlocked) {
|
||||
if (data->mouseLeaveBlocked) {
|
||||
// The mouse is moving from the chrome button to other non-client area, we should
|
||||
// emulate a WM_MOUSELEAVE message to reset the button state.
|
||||
emulateClientAreaMessage(WM_NCMOUSELEAVE);
|
||||
|
@ -1071,7 +1081,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
// the mouse leaves window from client area and enters window from non-client area,
|
||||
// but it has no bad effect.
|
||||
|
||||
std::ignore = data.params.resetQtGrabbedControl();
|
||||
std::ignore = data->callbacks->resetQtGrabbedControl();
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
@ -1085,9 +1095,9 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
// of the application a lot.
|
||||
const auto windowPos = reinterpret_cast<LPWINDOWPOS>(lParam);
|
||||
const QRect suggestedFrameGeometry{ windowPos->x, windowPos->y, windowPos->cx, windowPos->cy };
|
||||
const QMargins frameMargins = (Utils::getWindowSystemFrameMargins(windowId) + Utils::getWindowCustomFrameMargins(window));
|
||||
const QMargins frameMargins = (Utils::getWindowSystemFrameMargins(windowId) + Utils::getWindowCustomFrameMargins(qWindow));
|
||||
const QRect suggestedGeometry = (suggestedFrameGeometry - frameMargins);
|
||||
if (Utils::toNativePixels(window, window->size()) != suggestedGeometry.size()) {
|
||||
if (Utils::toNativePixels(qWindow, qWindow->size()) != suggestedGeometry.size()) {
|
||||
windowPos->flags |= SWP_NOCOPYBITS;
|
||||
}
|
||||
} break;
|
||||
|
@ -1106,7 +1116,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
}
|
||||
const auto newDpi = UINT(wParam);
|
||||
const QSize oldSize = {RECT_WIDTH(clientRect), RECT_HEIGHT(clientRect)};
|
||||
const QSize newSize = Utils::rescaleSize(oldSize, data.dpi.x, newDpi);
|
||||
const QSize newSize = Utils::rescaleSize(oldSize, data->dpi.x, newDpi);
|
||||
const auto suggestedSize = reinterpret_cast<LPSIZE>(lParam);
|
||||
suggestedSize->cx = newSize.width();
|
||||
suggestedSize->cy = newSize.height();
|
||||
|
@ -1127,7 +1137,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
}
|
||||
#endif // (QT_VERSION <= QT_VERSION_CHECK(6, 4, 2))
|
||||
case WM_DPICHANGED: {
|
||||
const Dpi oldDpi = data.dpi;
|
||||
const Dpi oldDpi = data->dpi;
|
||||
const Dpi newDpi = {UINT(LOWORD(wParam)), UINT(HIWORD(wParam))};
|
||||
if (Q_UNLIKELY(newDpi == oldDpi)) {
|
||||
WARNING << "Wrong WM_DPICHANGED received: same DPI.";
|
||||
|
@ -1135,14 +1145,14 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
}
|
||||
DEBUG.noquote() << "New DPI for window" << hwnd2str(hWnd)
|
||||
<< "is" << newDpi << "(was" << oldDpi << ").";
|
||||
muData.dpi = newDpi;
|
||||
data->dpi = newDpi;
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 5, 1))
|
||||
if (Utils::isValidGeometry(data.restoreGeometry)) {
|
||||
if (Utils::isValidGeometry(data->restoreGeometry)) {
|
||||
// Update the window size only. The position should not be changed.
|
||||
muData.restoreGeometry.setSize(Utils::rescaleSize(data.restoreGeometry.size(), oldDpi.x, newDpi.x));
|
||||
data->restoreGeometry.setSize(Utils::rescaleSize(data->restoreGeometry.size(), oldDpi.x, newDpi.x));
|
||||
}
|
||||
#endif // (QT_VERSION < QT_VERSION_CHECK(6, 5, 1))
|
||||
data.params.forceChildrenRepaint(500);
|
||||
data->callbacks->forceChildrenRepaint(500);
|
||||
} break;
|
||||
case WM_DWMCOMPOSITIONCHANGED:
|
||||
// Re-apply the custom window frame if recovered from the basic theme.
|
||||
|
@ -1157,7 +1167,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
if (wParam != SIZE_MAXIMIZED) {
|
||||
break;
|
||||
}
|
||||
if (!Utils::isValidGeometry(data.restoreGeometry)) {
|
||||
if (!Utils::isValidGeometry(data->restoreGeometry)) {
|
||||
updateRestoreGeometry(true);
|
||||
break;
|
||||
}
|
||||
|
@ -1169,11 +1179,11 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
break;
|
||||
}
|
||||
// The restore geometry is correct, no need to bother.
|
||||
if (rect2qrect(wp.rcNormalPosition) == data.restoreGeometry) {
|
||||
if (rect2qrect(wp.rcNormalPosition) == data->restoreGeometry) {
|
||||
break;
|
||||
}
|
||||
// OK, the restore geometry is wrong, let's correct it then :)
|
||||
wp.rcNormalPosition = qrect2rect(data.restoreGeometry);
|
||||
wp.rcNormalPosition = qrect2rect(data->restoreGeometry);
|
||||
if (::SetWindowPlacement(hWnd, &wp) == FALSE) {
|
||||
WARNING << Utils::getSystemErrorMessage(kSetWindowPlacement);
|
||||
}
|
||||
|
@ -1271,7 +1281,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
|
||||
#if 0 // Conflicts with our blur mode setting.
|
||||
if ((uMsg == WM_DWMCOMPOSITIONCHANGED) || (uMsg == WM_DWMCOLORIZATIONCOLORCHANGED)) {
|
||||
if (Utils::isWindowAccelerated(window) && Utils::isWindowTransparent(window)) {
|
||||
if (Utils::isWindowAccelerated(qWindow) && Utils::isWindowTransparent(qWindow)) {
|
||||
std::ignore = Utils::updateFramebufferTransparency(windowId);
|
||||
}
|
||||
}
|
||||
|
@ -1288,7 +1298,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
if (WindowsVersionHelper::isWin10RS5OrGreater()) {
|
||||
const bool dark = (FramelessManager::instance()->systemTheme() == SystemTheme::Dark);
|
||||
const auto isWidget = [&data]() -> bool {
|
||||
const auto widget = data.params.getWidgetHandle();
|
||||
const auto widget = data->callbacks->getWidgetHandle();
|
||||
return (widget && widget->isWidgetType());
|
||||
}();
|
||||
if (!isWidget) {
|
||||
|
@ -1319,4 +1329,6 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
|||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
||||
#endif // native_impl
|
||||
|
||||
#endif // Q_OS_WINDOWS
|
||||
|
|
|
@ -114,6 +114,23 @@ using namespace Global;
|
|||
static_assert(std::size(WindowsVersions) == (static_cast<int>(WindowsVersion::Latest) + 1));
|
||||
#endif
|
||||
|
||||
FramelessCallbacks::FramelessCallbacks() = default;
|
||||
|
||||
FramelessCallbacks::~FramelessCallbacks() = default;
|
||||
|
||||
FramelessCallbacksPtr FramelessCallbacks::create()
|
||||
{
|
||||
return std::make_shared<FramelessCallbacks>();
|
||||
}
|
||||
|
||||
FramelessExtraData::FramelessExtraData() = default;
|
||||
|
||||
FramelessExtraData::~FramelessExtraData() = default;
|
||||
|
||||
FramelessData::FramelessData() = default;
|
||||
|
||||
FramelessData::~FramelessData() = default;
|
||||
|
||||
void FramelessHelperCoreInitialize()
|
||||
{
|
||||
static bool inited = false;
|
||||
|
|
|
@ -24,12 +24,20 @@
|
|||
|
||||
#include "framelessmanager.h"
|
||||
#include "framelessmanager_p.h"
|
||||
#include "framelesshelper_qt.h"
|
||||
#include "framelessconfig_p.h"
|
||||
#include "framelesshelpercore_global_p.h"
|
||||
#if FRAMELESSHELPER_CONFIG(native_impl)
|
||||
# ifdef Q_OS_WINDOWS
|
||||
# include "framelesshelper_win.h"
|
||||
# elif (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
# elif defined(Q_OS_MACOS)
|
||||
# else
|
||||
# endif
|
||||
#else
|
||||
# include "framelesshelper_qt.h"
|
||||
#endif
|
||||
#include "framelessconfig_p.h"
|
||||
#include "utils.h"
|
||||
#ifdef Q_OS_WINDOWS
|
||||
# include "framelesshelper_win.h"
|
||||
# include "winverhelper_p.h"
|
||||
#endif
|
||||
#include <QtCore/qvariant.h>
|
||||
|
@ -37,6 +45,7 @@
|
|||
#include <QtCore/qloggingcategory.h>
|
||||
#include <QtGui/qfontdatabase.h>
|
||||
#include <QtGui/qwindow.h>
|
||||
#include <QtGui/qevent.h>
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
|
||||
# include <QtGui/qguiapplication.h>
|
||||
# include <QtGui/qstylehints.h>
|
||||
|
@ -59,12 +68,26 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
|
|||
|
||||
using namespace Global;
|
||||
|
||||
using FramelessManagerData = QList<WId>;
|
||||
|
||||
Q_GLOBAL_STATIC(FramelessManagerData, g_framelessManagerData)
|
||||
|
||||
static constexpr const int kEventDelayInterval = 1000;
|
||||
|
||||
struct InternalData
|
||||
{
|
||||
FramelessDataHash dataMap = {};
|
||||
QHash<WId, QObject *> windowMap = {};
|
||||
|
||||
InternalData();
|
||||
~InternalData();
|
||||
|
||||
private:
|
||||
FRAMELESSHELPER_CLASS(InternalData)
|
||||
};
|
||||
|
||||
InternalData::InternalData() = default;
|
||||
|
||||
InternalData::~InternalData() = default;
|
||||
|
||||
Q_GLOBAL_STATIC(InternalData, g_internalData)
|
||||
|
||||
#if FRAMELESSHELPER_CONFIG(bundle_resource)
|
||||
[[nodiscard]] static inline QString iconFontFamilyName()
|
||||
{
|
||||
|
@ -83,16 +106,60 @@ static constexpr const int kEventDelayInterval = 1000;
|
|||
}
|
||||
#endif
|
||||
|
||||
[[nodiscard]] static inline bool usePureQtImplementation()
|
||||
class InternalEventFilter : public QObject
|
||||
{
|
||||
static const auto result = []() -> bool {
|
||||
#ifdef Q_OS_WINDOWS
|
||||
return FramelessConfig::instance()->isSet(Option::UseCrossPlatformQtImplementation);
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}();
|
||||
return result;
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_QT_CLASS(InternalEventFilter)
|
||||
|
||||
public:
|
||||
explicit InternalEventFilter(const QObject *window, QObject *parent = nullptr);
|
||||
~InternalEventFilter() override;
|
||||
|
||||
protected:
|
||||
Q_NODISCARD bool eventFilter(QObject *object, QEvent *event) override;
|
||||
|
||||
private:
|
||||
const QObject *m_window = nullptr;
|
||||
};
|
||||
|
||||
InternalEventFilter::InternalEventFilter(const QObject *window, QObject *parent) : QObject(parent), m_window(window)
|
||||
{
|
||||
Q_ASSERT(m_window);
|
||||
Q_ASSERT(m_window->isWidgetType() || m_window->isWindowType());
|
||||
}
|
||||
|
||||
InternalEventFilter::~InternalEventFilter() = default;
|
||||
|
||||
bool InternalEventFilter::eventFilter(QObject *object, QEvent *event)
|
||||
{
|
||||
Q_ASSERT(object);
|
||||
Q_ASSERT(event);
|
||||
Q_ASSERT(m_window);
|
||||
if (!object || !event || !m_window || (object != m_window)) {
|
||||
return false;
|
||||
}
|
||||
const FramelessDataPtr data = FramelessManagerPrivate::getData(m_window);
|
||||
if (!data || !data->frameless || !data->callbacks) {
|
||||
return false;
|
||||
}
|
||||
switch (event->type()) {
|
||||
case QEvent::WinIdChange: {
|
||||
const WId windowId = data->callbacks->getWindowId();
|
||||
Q_ASSERT(windowId);
|
||||
if (windowId) {
|
||||
FramelessManagerPrivate::updateWindowId(m_window, windowId);
|
||||
}
|
||||
} break;
|
||||
case QEvent::Close: {
|
||||
const auto ce = static_cast<const QCloseEvent *>(event);
|
||||
if (ce->isAccepted()) {
|
||||
std::ignore = FramelessManager::instance()->removeWindow(m_window);
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
FramelessManagerPrivate::FramelessManagerPrivate(FramelessManager *q) : QObject(q)
|
||||
|
@ -133,7 +200,7 @@ void FramelessManagerPrivate::initializeIconFont()
|
|||
return;
|
||||
}
|
||||
inited = true;
|
||||
framelesshelpercore_initResource();
|
||||
FramelessHelperCoreInitResource();
|
||||
// We always register this font because it's our only fallback.
|
||||
const int id = QFontDatabase::addApplicationFont(FRAMELESSHELPER_STRING_LITERAL(":/org.wangwenx190.FramelessHelper/resources/fonts/iconfont.ttf"));
|
||||
if (id < 0) {
|
||||
|
@ -229,6 +296,80 @@ void FramelessManagerPrivate::doNotifyWallpaperHasChangedOrNot()
|
|||
}
|
||||
}
|
||||
|
||||
FramelessDataPtr FramelessManagerPrivate::getData(const QObject *window)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
Q_ASSERT(window->isWidgetType() || window->isWindowType());
|
||||
if (!window || !(window->isWidgetType() || window->isWindowType())) {
|
||||
return nullptr;
|
||||
}
|
||||
return g_internalData()->dataMap.value(const_cast<QObject *>(window));
|
||||
}
|
||||
|
||||
FramelessDataPtr FramelessManagerPrivate::createData(const QObject *window, const WId windowId)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
Q_ASSERT(window->isWidgetType() || window->isWindowType());
|
||||
Q_ASSERT(windowId);
|
||||
if (!window || !(window->isWidgetType() || window->isWindowType()) || !windowId) {
|
||||
return nullptr;
|
||||
}
|
||||
const auto win = const_cast<QObject *>(window);
|
||||
auto it = g_internalData()->dataMap.find(win);
|
||||
if (it == g_internalData()->dataMap.end()) {
|
||||
FramelessDataPtr data = FramelessData::create();
|
||||
data->window = win;
|
||||
data->windowId = windowId;
|
||||
it = g_internalData()->dataMap.insert(win, data);
|
||||
g_internalData()->windowMap.insert(windowId, win);
|
||||
}
|
||||
return it.value();
|
||||
}
|
||||
|
||||
WId FramelessManagerPrivate::getWindowId(const QObject *window)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
Q_ASSERT(window->isWidgetType() || window->isWindowType());
|
||||
if (!window || !(window->isWidgetType() || window->isWindowType())) {
|
||||
return 0;
|
||||
}
|
||||
if (const FramelessDataPtr data = getData(window)) {
|
||||
return data->windowId;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
QObject *FramelessManagerPrivate::getWindow(const WId windowId)
|
||||
{
|
||||
Q_ASSERT(windowId);
|
||||
if (!windowId) {
|
||||
return nullptr;
|
||||
}
|
||||
return g_internalData()->windowMap.value(windowId);
|
||||
}
|
||||
|
||||
void FramelessManagerPrivate::updateWindowId(const QObject *window, const WId newWindowId)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
Q_ASSERT(window->isWidgetType() || window->isWindowType());
|
||||
Q_ASSERT(newWindowId);
|
||||
if (!window || !(window->isWidgetType() || window->isWindowType()) || !newWindowId) {
|
||||
return;
|
||||
}
|
||||
const auto win = const_cast<QObject *>(window);
|
||||
const FramelessDataPtr data = g_internalData()->dataMap.value(win);
|
||||
Q_ASSERT(data);
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
const WId oldWindowId = data->windowId;
|
||||
data->windowId = newWindowId;
|
||||
g_internalData()->windowMap.remove(oldWindowId);
|
||||
g_internalData()->windowMap.insert(newWindowId, win);
|
||||
data->frameless = false;
|
||||
std::ignore = FramelessManager::instance()->addWindow(window, newWindowId);
|
||||
}
|
||||
|
||||
bool FramelessManagerPrivate::isThemeOverrided() const
|
||||
{
|
||||
return (overrideTheme.value_or(SystemTheme::Unknown) != SystemTheme::Unknown);
|
||||
|
@ -264,8 +405,8 @@ void FramelessManagerPrivate::initialize()
|
|||
// We are doing some tricks in our Windows message handling code, so
|
||||
// we don't use Qt's theme notifier on Windows. But for other platforms
|
||||
// we want to use as many Qt functionalities as possible.
|
||||
#if ((QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)) && !defined(Q_OS_WINDOWS))
|
||||
QStyleHints * const styleHints = QGuiApplication::styleHints();
|
||||
#if ((QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)) && !FRAMELESSHELPER_CONFIG(native_impl))
|
||||
QStyleHints *styleHints = QGuiApplication::styleHints();
|
||||
Q_ASSERT(styleHints);
|
||||
if (styleHints) {
|
||||
connect(styleHints, &QStyleHints::colorSchemeChanged, this, [this](const Qt::ColorScheme colorScheme){
|
||||
|
@ -342,51 +483,81 @@ void FramelessManager::setOverrideTheme(const SystemTheme theme)
|
|||
Q_EMIT systemThemeChanged();
|
||||
}
|
||||
|
||||
void FramelessManager::addWindow(FramelessParamsConst params)
|
||||
bool FramelessManager::addWindow(const QObject *window, const WId windowId)
|
||||
{
|
||||
Q_ASSERT(params);
|
||||
if (!params) {
|
||||
return;
|
||||
Q_ASSERT(window);
|
||||
Q_ASSERT(window->isWidgetType() || window->isWindowType());
|
||||
Q_ASSERT(windowId);
|
||||
if (!window || !(window->isWidgetType() || window->isWindowType()) || !windowId) {
|
||||
return false;
|
||||
}
|
||||
const WId windowId = params->getWindowId();
|
||||
if (g_framelessManagerData()->contains(windowId)) {
|
||||
return;
|
||||
FramelessDataPtr data = FramelessManagerPrivate::getData(window);
|
||||
if (data && data->frameless) {
|
||||
return false;
|
||||
}
|
||||
g_framelessManagerData()->append(windowId);
|
||||
static const bool pureQt = usePureQtImplementation();
|
||||
if (pureQt) {
|
||||
FramelessHelperQt::addWindow(params);
|
||||
if (!data) {
|
||||
data = FramelessData::create();
|
||||
data->window = const_cast<QObject *>(window);
|
||||
data->windowId = windowId;
|
||||
g_internalData()->dataMap.insert(data->window, data);
|
||||
g_internalData()->windowMap.insert(windowId, data->window);
|
||||
}
|
||||
#ifdef Q_OS_WINDOWS
|
||||
if (!pureQt) {
|
||||
FramelessHelperWin::addWindow(params);
|
||||
}
|
||||
std::ignore = Utils::installWindowProcHook(windowId, params);
|
||||
#if FRAMELESSHELPER_CONFIG(native_impl)
|
||||
# ifdef Q_OS_WINDOWS
|
||||
std::ignore = Utils::installWindowProcHook(windowId);
|
||||
FramelessHelperWin::addWindow(window);
|
||||
# elif (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
# elif defined(Q_OS_MACOS)
|
||||
# else
|
||||
# endif
|
||||
#else
|
||||
FramelessHelperQt::addWindow(window);
|
||||
#endif
|
||||
connect(params->getWindowHandle(), &QWindow::destroyed, FramelessManager::instance(), [this, windowId](){ removeWindow(windowId); });
|
||||
if (!data->internalEventHandler) {
|
||||
data->internalEventHandler = new InternalEventFilter(data->window, data->window);
|
||||
data->window->installEventFilter(data->internalEventHandler);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void FramelessManager::removeWindow(const WId windowId)
|
||||
bool FramelessManager::removeWindow(const QObject *window)
|
||||
{
|
||||
Q_ASSERT(windowId);
|
||||
if (!windowId) {
|
||||
return;
|
||||
Q_ASSERT(window);
|
||||
if (!window) {
|
||||
return false;
|
||||
}
|
||||
if (!g_framelessManagerData()->contains(windowId)) {
|
||||
return;
|
||||
const auto it = g_internalData()->dataMap.constFind(const_cast<QObject *>(window));
|
||||
if (it == g_internalData()->dataMap.constEnd()) {
|
||||
return false;
|
||||
}
|
||||
g_framelessManagerData()->removeAll(windowId);
|
||||
static const bool pureQt = usePureQtImplementation();
|
||||
if (pureQt) {
|
||||
FramelessHelperQt::removeWindow(windowId);
|
||||
const FramelessDataPtr data = it.value();
|
||||
Q_ASSERT(data);
|
||||
Q_ASSERT(data->window);
|
||||
Q_ASSERT(data->windowId);
|
||||
if (!data || !data->window || !data->windowId) {
|
||||
return false;
|
||||
}
|
||||
#ifdef Q_OS_WINDOWS
|
||||
if (!pureQt) {
|
||||
FramelessHelperWin::removeWindow(windowId);
|
||||
if (data->internalEventHandler) {
|
||||
data->window->removeEventFilter(data->internalEventHandler);
|
||||
delete data->internalEventHandler;
|
||||
data->internalEventHandler = nullptr;
|
||||
}
|
||||
std::ignore = Utils::uninstallWindowProcHook(windowId);
|
||||
std::ignore = Utils::removeMicaWindow(windowId);
|
||||
#if FRAMELESSHELPER_CONFIG(native_impl)
|
||||
# ifdef Q_OS_WINDOWS
|
||||
FramelessHelperWin::removeWindow(window);
|
||||
std::ignore = Utils::uninstallWindowProcHook(data->windowId);
|
||||
# elif (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
# elif defined(Q_OS_MACOS)
|
||||
# else
|
||||
# endif
|
||||
#else
|
||||
FramelessHelperQt::removeWindow(window);
|
||||
#endif
|
||||
g_internalData()->dataMap.erase(it);
|
||||
g_internalData()->windowMap.remove(data->windowId);
|
||||
return true;
|
||||
}
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
||||
#include "framelessmanager.moc"
|
||||
|
|
|
@ -62,11 +62,6 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
|
|||
# define CRITICAL QT_NO_QDEBUG_MACRO()
|
||||
#endif
|
||||
|
||||
DECLARE_SIZE_COMPARE_OPERATORS(QSize, QSize)
|
||||
DECLARE_SIZE_COMPARE_OPERATORS(QSizeF, QSizeF)
|
||||
DECLARE_SIZE_COMPARE_OPERATORS(QSize, QSizeF)
|
||||
DECLARE_SIZE_COMPARE_OPERATORS(QSizeF, QSize)
|
||||
|
||||
using namespace Global;
|
||||
|
||||
[[maybe_unused]] static constexpr const QSize kMaximumPictureSize = { 1920, 1080 };
|
||||
|
@ -487,8 +482,7 @@ static inline void expblur(QImage &img, qreal radius, const bool improvedQuality
|
|||
class WallpaperThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DISABLE_COPY_MOVE(WallpaperThread)
|
||||
FRAMELESSHELPER_QT_CLASS(WallpaperThread)
|
||||
|
||||
public:
|
||||
explicit WallpaperThread(QObject *parent = nullptr) : QThread(parent) {}
|
||||
|
@ -657,7 +651,7 @@ void MicaMaterialPrivate::maybeGenerateBlurredWallpaper(const bool force)
|
|||
void MicaMaterialPrivate::updateMaterialBrush()
|
||||
{
|
||||
#if FRAMELESSHELPER_CONFIG(bundle_resource)
|
||||
framelesshelpercore_initResource();
|
||||
FramelessHelperCoreInitResource();
|
||||
static const QImage noiseTexture = QImage(FRAMELESSHELPER_STRING_LITERAL(":/org.wangwenx190.FramelessHelper/resources/images/noise.png"));
|
||||
#endif // FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE
|
||||
QImage micaTexture = QImage(QSize(64, 64), kDefaultImageFormat);
|
||||
|
|
|
@ -50,11 +50,11 @@ _GetWindowCompositionAttribute(const HWND hWnd, PWINDOWCOMPOSITIONATTRIBDATA pvD
|
|||
Q_ASSERT(hWnd);
|
||||
Q_ASSERT(pvData);
|
||||
if (!hWnd || !pvData) {
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
::SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
if (!API_USER_AVAILABLE(GetWindowCompositionAttribute)) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
return API_CALL_FUNCTION4(user32, GetWindowCompositionAttribute, hWnd, pvData);
|
||||
|
@ -66,11 +66,11 @@ _SetWindowCompositionAttribute(const HWND hWnd, PWINDOWCOMPOSITIONATTRIBDATA pvD
|
|||
Q_ASSERT(hWnd);
|
||||
Q_ASSERT(pvData);
|
||||
if (!hWnd || !pvData) {
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
::SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
if (!API_USER_AVAILABLE(SetWindowCompositionAttribute)) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
return API_CALL_FUNCTION4(user32, SetWindowCompositionAttribute, hWnd, pvData);
|
||||
|
@ -111,14 +111,14 @@ _ShouldAppsUseDarkMode(VOID)
|
|||
{
|
||||
FRAMELESSHELPER_USE_NAMESPACE
|
||||
if (!WindowsVersionHelper::isWin10OrGreater()) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
static const auto pShouldAppsUseDarkMode
|
||||
= reinterpret_cast<ShouldAppsUseDarkModePtr>(
|
||||
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(132)));
|
||||
if (!pShouldAppsUseDarkMode) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
return pShouldAppsUseDarkMode();
|
||||
|
@ -129,19 +129,19 @@ _AllowDarkModeForWindow(const HWND hWnd, const BOOL bAllow)
|
|||
{
|
||||
Q_ASSERT(hWnd);
|
||||
if (!hWnd) {
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
::SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
FRAMELESSHELPER_USE_NAMESPACE
|
||||
if (!WindowsVersionHelper::isWin10OrGreater()) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
static const auto pAllowDarkModeForWindow
|
||||
= reinterpret_cast<AllowDarkModeForWindowPtr>(
|
||||
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(133)));
|
||||
if (!pAllowDarkModeForWindow) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
return pAllowDarkModeForWindow(hWnd, bAllow);
|
||||
|
@ -152,14 +152,14 @@ _AllowDarkModeForApp(const BOOL bAllow)
|
|||
{
|
||||
FRAMELESSHELPER_USE_NAMESPACE
|
||||
if (!WindowsVersionHelper::isWin10OrGreater()) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
static const auto pAllowDarkModeForApp
|
||||
= reinterpret_cast<AllowDarkModeForAppPtr>(
|
||||
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(135)));
|
||||
if (!pAllowDarkModeForApp) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
return pAllowDarkModeForApp(bAllow);
|
||||
|
@ -170,14 +170,14 @@ _FlushMenuThemes(VOID)
|
|||
{
|
||||
FRAMELESSHELPER_USE_NAMESPACE
|
||||
if (!WindowsVersionHelper::isWin10OrGreater()) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return;
|
||||
}
|
||||
static const auto pFlushMenuThemes
|
||||
= reinterpret_cast<FlushMenuThemesPtr>(
|
||||
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(136)));
|
||||
if (!pFlushMenuThemes) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return;
|
||||
}
|
||||
pFlushMenuThemes();
|
||||
|
@ -188,14 +188,14 @@ _RefreshImmersiveColorPolicyState(VOID)
|
|||
{
|
||||
FRAMELESSHELPER_USE_NAMESPACE
|
||||
if (!WindowsVersionHelper::isWin10OrGreater()) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return;
|
||||
}
|
||||
static const auto pRefreshImmersiveColorPolicyState
|
||||
= reinterpret_cast<RefreshImmersiveColorPolicyStatePtr>(
|
||||
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(104)));
|
||||
if (!pRefreshImmersiveColorPolicyState) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return;
|
||||
}
|
||||
pRefreshImmersiveColorPolicyState();
|
||||
|
@ -206,19 +206,19 @@ _IsDarkModeAllowedForWindow(const HWND hWnd)
|
|||
{
|
||||
Q_ASSERT(hWnd);
|
||||
if (!hWnd) {
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
::SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
FRAMELESSHELPER_USE_NAMESPACE
|
||||
if (!WindowsVersionHelper::isWin10OrGreater()) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
static const auto pIsDarkModeAllowedForWindow
|
||||
= reinterpret_cast<IsDarkModeAllowedForWindowPtr>(
|
||||
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(137)));
|
||||
if (!pIsDarkModeAllowedForWindow) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
return pIsDarkModeAllowedForWindow(hWnd);
|
||||
|
@ -229,14 +229,14 @@ _GetIsImmersiveColorUsingHighContrast(const IMMERSIVE_HC_CACHE_MODE mode)
|
|||
{
|
||||
FRAMELESSHELPER_USE_NAMESPACE
|
||||
if (!WindowsVersionHelper::isWin10OrGreater()) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
static const auto pGetIsImmersiveColorUsingHighContrast
|
||||
= reinterpret_cast<GetIsImmersiveColorUsingHighContrastPtr>(
|
||||
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(106)));
|
||||
if (!pGetIsImmersiveColorUsingHighContrast) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
return pGetIsImmersiveColorUsingHighContrast(mode);
|
||||
|
@ -248,19 +248,19 @@ _OpenNcThemeData(const HWND hWnd, LPCWSTR pszClassList)
|
|||
Q_ASSERT(hWnd);
|
||||
Q_ASSERT(pszClassList);
|
||||
if (!hWnd || !pszClassList) {
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
::SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return nullptr;
|
||||
}
|
||||
FRAMELESSHELPER_USE_NAMESPACE
|
||||
if (!WindowsVersionHelper::isWin10OrGreater()) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return nullptr;
|
||||
}
|
||||
static const auto pOpenNcThemeData
|
||||
= reinterpret_cast<OpenNcThemeDataPtr>(
|
||||
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(49)));
|
||||
if (!pOpenNcThemeData) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return nullptr;
|
||||
}
|
||||
return pOpenNcThemeData(hWnd, pszClassList);
|
||||
|
@ -271,14 +271,14 @@ _ShouldSystemUseDarkMode(VOID)
|
|||
{
|
||||
FRAMELESSHELPER_USE_NAMESPACE
|
||||
if (!WindowsVersionHelper::isWin10OrGreater()) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
static const auto pShouldSystemUseDarkMode
|
||||
= reinterpret_cast<ShouldSystemUseDarkModePtr>(
|
||||
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(138)));
|
||||
if (!pShouldSystemUseDarkMode) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
return pShouldSystemUseDarkMode();
|
||||
|
@ -289,14 +289,14 @@ _SetPreferredAppMode(const PREFERRED_APP_MODE mode)
|
|||
{
|
||||
FRAMELESSHELPER_USE_NAMESPACE
|
||||
if (!WindowsVersionHelper::isWin10OrGreater()) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return PAM_MAX;
|
||||
}
|
||||
static const auto pSetPreferredAppMode
|
||||
= reinterpret_cast<SetPreferredAppModePtr>(
|
||||
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(135)));
|
||||
if (!pSetPreferredAppMode) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return PAM_MAX;
|
||||
}
|
||||
return pSetPreferredAppMode(mode);
|
||||
|
@ -307,14 +307,14 @@ _IsDarkModeAllowedForApp(VOID)
|
|||
{
|
||||
FRAMELESSHELPER_USE_NAMESPACE
|
||||
if (!WindowsVersionHelper::isWin10OrGreater()) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
static const auto pIsDarkModeAllowedForApp
|
||||
= reinterpret_cast<IsDarkModeAllowedForAppPtr>(
|
||||
SysApiLoader::resolve(kuxtheme, MAKEINTRESOURCEA(139)));
|
||||
if (!pIsDarkModeAllowedForApp) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
return pIsDarkModeAllowedForApp();
|
||||
|
@ -325,12 +325,12 @@ _EnableChildWindowDpiMessage2(const HWND hWnd, const BOOL fEnable)
|
|||
{
|
||||
Q_ASSERT(hWnd);
|
||||
if (!hWnd) {
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
::SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
FRAMELESSHELPER_USE_NAMESPACE
|
||||
if (!WindowsVersionHelper::isWin10OrGreater()) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
using EnableChildWindowDpiMessagePtr = decltype(&::_EnableChildWindowDpiMessage);
|
||||
|
@ -355,7 +355,7 @@ _EnableChildWindowDpiMessage2(const HWND hWnd, const BOOL fEnable)
|
|||
return nullptr;
|
||||
}();
|
||||
if (!pEnableChildWindowDpiMessage) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
return pEnableChildWindowDpiMessage(hWnd, fEnable);
|
||||
|
@ -366,7 +366,7 @@ _EnablePerMonitorDialogScaling2(VOID)
|
|||
{
|
||||
FRAMELESSHELPER_USE_NAMESPACE
|
||||
if (!WindowsVersionHelper::isWin10OrGreater()) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
using EnablePerMonitorDialogScalingPtr = decltype(&::_EnablePerMonitorDialogScaling);
|
||||
|
@ -385,7 +385,7 @@ _EnablePerMonitorDialogScaling2(VOID)
|
|||
return nullptr;
|
||||
}();
|
||||
if (!pEnablePerMonitorDialogScaling) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
return pEnablePerMonitorDialogScaling();
|
||||
|
@ -396,12 +396,12 @@ _GetDpiForWindow2(const HWND hWnd)
|
|||
{
|
||||
Q_ASSERT(hWnd);
|
||||
if (!hWnd) {
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
::SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
FRAMELESSHELPER_USE_NAMESPACE
|
||||
if (!WindowsVersionHelper::isWin10OrGreater()) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return 0;
|
||||
}
|
||||
using GetDpiForWindowPtr = decltype(&::_GetDpiForWindow);
|
||||
|
@ -424,7 +424,7 @@ _GetDpiForWindow2(const HWND hWnd)
|
|||
return nullptr;
|
||||
}();
|
||||
if (!pGetDpiForWindow) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return 0;
|
||||
}
|
||||
return pGetDpiForWindow(hWnd);
|
||||
|
@ -436,12 +436,12 @@ _GetSystemMetricsForDpi2(const int nIndex, const UINT dpi)
|
|||
Q_ASSERT(nIndex >= 0);
|
||||
Q_ASSERT(dpi != 0);
|
||||
if ((nIndex < 0) || (dpi == 0)) {
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
::SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
FRAMELESSHELPER_USE_NAMESPACE
|
||||
if (!WindowsVersionHelper::isWin10OrGreater()) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return 0;
|
||||
}
|
||||
using GetSystemMetricsForDpiPtr = decltype(&::_GetSystemMetricsForDpi);
|
||||
|
@ -460,7 +460,7 @@ _GetSystemMetricsForDpi2(const int nIndex, const UINT dpi)
|
|||
return nullptr;
|
||||
}();
|
||||
if (!pGetSystemMetricsForDpi) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return 0;
|
||||
}
|
||||
return pGetSystemMetricsForDpi(nIndex, dpi);
|
||||
|
@ -473,12 +473,12 @@ _AdjustWindowRectExForDpi2(LPRECT lpRect, const DWORD dwStyle,
|
|||
Q_ASSERT(lpRect);
|
||||
Q_ASSERT(dpi != 0);
|
||||
if (!lpRect || (dpi == 0)) {
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
::SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
FRAMELESSHELPER_USE_NAMESPACE
|
||||
if (!WindowsVersionHelper::isWin10OrGreater()) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
using AdjustWindowRectExForDpiPtr = decltype(&::_AdjustWindowRectExForDpi);
|
||||
|
@ -496,7 +496,7 @@ _AdjustWindowRectExForDpi2(LPRECT lpRect, const DWORD dwStyle,
|
|||
return nullptr;
|
||||
}();
|
||||
if (!pAdjustWindowRectExForDpi) {
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
return pAdjustWindowRectExForDpi(lpRect, dwStyle, bMenu, dwExStyle, dpi);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "utils.h"
|
||||
#include "framelesshelpercore_global_p.h"
|
||||
#include "framelessmanager_p.h"
|
||||
#ifdef Q_OS_WINDOWS
|
||||
# include "winverhelper_p.h"
|
||||
#endif // Q_OS_WINDOWS
|
||||
|
@ -210,29 +211,38 @@ QWindow *Utils::findWindow(const WId windowId)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void Utils::moveWindowToDesktopCenter(FramelessParamsConst params, const bool considerTaskBar)
|
||||
bool Utils::moveWindowToDesktopCenter(const WId windowId, const bool considerTaskBar)
|
||||
{
|
||||
Q_ASSERT(params);
|
||||
if (!params) {
|
||||
return;
|
||||
Q_ASSERT(windowId);
|
||||
if (!windowId) {
|
||||
return false;
|
||||
}
|
||||
const QSize windowSize = params->getWindowSize();
|
||||
if (windowSize.isEmpty() || (windowSize == kDefaultWindowSize)) {
|
||||
return;
|
||||
const QObject *window = FramelessManagerPrivate::getWindow(windowId);
|
||||
if (!window) {
|
||||
return false;
|
||||
}
|
||||
const QScreen *screen = params->getWindowScreen();
|
||||
const FramelessDataPtr data = FramelessManagerPrivate::getData(window);
|
||||
if (!data || !data->callbacks) {
|
||||
return false;
|
||||
}
|
||||
const QSize windowSize = data->callbacks->getWindowSize();
|
||||
if (windowSize.isEmpty() || (windowSize <= kDefaultWindowSize)) {
|
||||
return false;
|
||||
}
|
||||
const QScreen *screen = data->callbacks->getWindowScreen();
|
||||
if (!screen) {
|
||||
screen = QGuiApplication::primaryScreen();
|
||||
}
|
||||
Q_ASSERT(screen);
|
||||
if (!screen) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
const QSize screenSize = (considerTaskBar ? screen->availableSize() : screen->size());
|
||||
const QPoint offset = (considerTaskBar ? screen->availableGeometry().topLeft() : QPoint(0, 0));
|
||||
const int newX = std::round(qreal(screenSize.width() - windowSize.width()) / qreal(2));
|
||||
const int newY = std::round(qreal(screenSize.height() - windowSize.height()) / qreal(2));
|
||||
params->setWindowPosition(QPoint(newX + offset.x(), newY + offset.y()));
|
||||
data->callbacks->setWindowPosition(QPoint(newX + offset.x(), newY + offset.y()));
|
||||
return true;
|
||||
}
|
||||
|
||||
Qt::WindowState Utils::windowStatesToWindowState(const Qt::WindowStates states)
|
||||
|
@ -314,9 +324,9 @@ bool Utils::shouldAppsUseDarkMode()
|
|||
qreal Utils::roundScaleFactor(const qreal factor)
|
||||
{
|
||||
// Qt can't handle scale factors less than 1.0 (according to the comments in qhighdpiscaling.cpp).
|
||||
Q_ASSERT((factor > 1) || qFuzzyCompare(factor, qreal(1)));
|
||||
if (factor < 1) {
|
||||
return 1;
|
||||
Q_ASSERT((factor > qreal(1)) || qFuzzyCompare(factor, qreal(1)));
|
||||
if (factor < qreal(1)) {
|
||||
return qreal(1);
|
||||
}
|
||||
#if (!FRAMELESSHELPER_CONFIG(private_qt) || (QT_VERSION < QT_VERSION_CHECK(6, 2, 1)))
|
||||
# if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
|
|
|
@ -132,7 +132,7 @@ extern QString gtkSettings(const gchar *);
|
|||
// https://bugreports.qt.io/browse/QTBUG-102488
|
||||
const QPoint localPos = window->mapFromGlobal(globalPos);
|
||||
const QPoint scenePos = localPos; // windowPos in Qt5.
|
||||
const auto event = std::make_unique<QMouseEvent>(
|
||||
const auto event = new QMouseEvent(
|
||||
QEvent::MouseButtonRelease,
|
||||
localPos,
|
||||
scenePos,
|
||||
|
@ -140,7 +140,7 @@ extern QString gtkSettings(const gchar *);
|
|||
Qt::LeftButton,
|
||||
QGuiApplication::mouseButtons() ^ Qt::LeftButton,
|
||||
QGuiApplication::keyboardModifiers());
|
||||
QGuiApplication::sendEvent(window, event.get());
|
||||
QGuiApplication::postEvent(window, event);
|
||||
}
|
||||
|
||||
QScreen *Utils::x11_findScreenForVirtualDesktop(const int virtualDesktopNumber)
|
||||
|
|
|
@ -87,7 +87,7 @@ using namespace Global;
|
|||
|
||||
class MacOSNotificationObserver
|
||||
{
|
||||
Q_DISABLE_COPY_MOVE(MacOSNotificationObserver)
|
||||
FRAMELESSHELPER_CLASS(MacOSNotificationObserver)
|
||||
|
||||
public:
|
||||
explicit MacOSNotificationObserver(NSObject *object, NSNotificationName name, const Callback &callback) {
|
||||
|
@ -125,7 +125,7 @@ private:
|
|||
|
||||
class MacOSKeyValueObserver
|
||||
{
|
||||
Q_DISABLE_COPY_MOVE(MacOSKeyValueObserver)
|
||||
FRAMELESSHELPER_CLASS(MacOSKeyValueObserver)
|
||||
|
||||
public:
|
||||
// Note: MacOSKeyValueObserver must not outlive the object observed!
|
||||
|
@ -176,7 +176,7 @@ private:
|
|||
|
||||
class MacOSThemeObserver
|
||||
{
|
||||
Q_DISABLE_COPY_MOVE(MacOSThemeObserver)
|
||||
FRAMELESSHELPER_CLASS(MacOSThemeObserver)
|
||||
|
||||
public:
|
||||
explicit MacOSThemeObserver()
|
||||
|
@ -223,8 +223,7 @@ private:
|
|||
class NSWindowProxy : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
FRAMELESSHELPER_CLASS_INFO
|
||||
Q_DISABLE_COPY_MOVE(NSWindowProxy)
|
||||
FRAMELESSHELPER_QT_CLASS(NSWindowProxy)
|
||||
|
||||
public:
|
||||
explicit NSWindowProxy(QWindow *qtWindow, NSWindow *macWindow, QObject *parent = nil) : QObject(parent)
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "framelesshelper_windows.h"
|
||||
#include "framelessmanager.h"
|
||||
#include "framelessmanager_p.h"
|
||||
#include "framelessconfig_p.h"
|
||||
#include "sysapiloader_p.h"
|
||||
#include "registrykey_p.h"
|
||||
|
@ -193,19 +194,44 @@ FRAMELESSHELPER_STRING_CONSTANT(ScreenToClient)
|
|||
FRAMELESSHELPER_STRING_CONSTANT(DwmFlush)
|
||||
FRAMELESSHELPER_STRING_CONSTANT(GetCursorPos)
|
||||
|
||||
struct Win32UtilsData
|
||||
struct UtilsWinExtraData : public FramelessExtraData
|
||||
{
|
||||
SystemParameters params = {};
|
||||
};
|
||||
|
||||
struct Win32UtilsInternal
|
||||
{
|
||||
QHash<WId, Win32UtilsData> data = {};
|
||||
WNDPROC qtWindowProc = nullptr;
|
||||
QList<WId> micaWindowIds = {};
|
||||
};
|
||||
bool windowProcHooked = false;
|
||||
bool mica = false;
|
||||
|
||||
Q_GLOBAL_STATIC(Win32UtilsInternal, g_win32UtilsData)
|
||||
UtilsWinExtraData();
|
||||
~UtilsWinExtraData() override;
|
||||
|
||||
[[nodiscard]] static FramelessExtraDataPtr create();
|
||||
};
|
||||
using UtilsWinExtraDataPtr = std::shared_ptr<UtilsWinExtraData>;
|
||||
|
||||
UtilsWinExtraData::UtilsWinExtraData() = default;
|
||||
|
||||
UtilsWinExtraData::~UtilsWinExtraData() = default;
|
||||
|
||||
FramelessExtraDataPtr UtilsWinExtraData::create()
|
||||
{
|
||||
return std::make_shared<UtilsWinExtraData>();
|
||||
}
|
||||
|
||||
[[nodiscard]] static inline UtilsWinExtraDataPtr tryGetExtraData(const FramelessDataPtr &data, const bool create)
|
||||
{
|
||||
Q_ASSERT(data);
|
||||
if (!data) {
|
||||
return nullptr;
|
||||
}
|
||||
auto it = data->extraData.find(ExtraDataType::WindowsUtilities);
|
||||
if (it == data->extraData.end()) {
|
||||
if (create) {
|
||||
it = data->extraData.insert(ExtraDataType::WindowsUtilities, UtilsWinExtraData::create());
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return std::dynamic_pointer_cast<UtilsWinExtraData>(it.value());
|
||||
}
|
||||
|
||||
struct Win32Message
|
||||
{
|
||||
|
@ -583,99 +609,6 @@ static constexpr const std::array<Win32Message, 333> g_win32MessageMap =
|
|||
};
|
||||
#undef DEFINE_WIN32_MESSAGE
|
||||
|
||||
[[nodiscard]] bool operator==(const POINT &lhs, const POINT &rhs) noexcept
|
||||
{
|
||||
return ((lhs.x == rhs.x) && (lhs.y == rhs.y));
|
||||
}
|
||||
|
||||
[[nodiscard]] bool operator!=(const POINT &lhs, const POINT &rhs) noexcept
|
||||
{
|
||||
return !operator==(lhs, rhs);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool operator==(const SIZE &lhs, const SIZE &rhs) noexcept
|
||||
{
|
||||
return ((lhs.cx == rhs.cx) && (lhs.cy == rhs.cy));
|
||||
}
|
||||
|
||||
[[nodiscard]] bool operator!=(const SIZE &lhs, const SIZE &rhs) noexcept
|
||||
{
|
||||
return !operator==(lhs, rhs);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool operator>(const SIZE &lhs, const SIZE &rhs) noexcept
|
||||
{
|
||||
return ((lhs.cx * lhs.cy) > (rhs.cx * rhs.cy));
|
||||
}
|
||||
|
||||
[[nodiscard]] bool operator>=(const SIZE &lhs, const SIZE &rhs) noexcept
|
||||
{
|
||||
return (operator>(lhs, rhs) || operator==(lhs, rhs));
|
||||
}
|
||||
|
||||
[[nodiscard]] bool operator<(const SIZE &lhs, const SIZE &rhs) noexcept
|
||||
{
|
||||
return (operator!=(lhs, rhs) && !operator>(lhs, rhs));
|
||||
}
|
||||
|
||||
[[nodiscard]] bool operator<=(const SIZE &lhs, const SIZE &rhs) noexcept
|
||||
{
|
||||
return (operator<(lhs, rhs) || operator==(lhs, rhs));
|
||||
}
|
||||
|
||||
[[nodiscard]] bool operator==(const RECT &lhs, const RECT &rhs) noexcept
|
||||
{
|
||||
return ((lhs.left == rhs.left) && (lhs.top == rhs.top)
|
||||
&& (lhs.right == rhs.right) && (lhs.bottom == rhs.bottom));
|
||||
}
|
||||
|
||||
[[nodiscard]] bool operator!=(const RECT &lhs, const RECT &rhs) noexcept
|
||||
{
|
||||
return !operator==(lhs, rhs);
|
||||
}
|
||||
|
||||
[[nodiscard]] QPoint point2qpoint(const POINT &point)
|
||||
{
|
||||
return QPoint{ int(point.x), int(point.y) };
|
||||
}
|
||||
|
||||
[[nodiscard]] POINT qpoint2point(const QPoint &point)
|
||||
{
|
||||
return POINT{ LONG(point.x()), LONG(point.y()) };
|
||||
}
|
||||
|
||||
[[nodiscard]] QSize size2qsize(const SIZE &size)
|
||||
{
|
||||
return QSize{ int(size.cx), int(size.cy) };
|
||||
}
|
||||
|
||||
[[nodiscard]] SIZE qsize2size(const QSize &size)
|
||||
{
|
||||
return SIZE{ LONG(size.width()), LONG(size.height()) };
|
||||
}
|
||||
|
||||
[[nodiscard]] QRect rect2qrect(const RECT &rect)
|
||||
{
|
||||
return QRect{ QPoint{ int(rect.left), int(rect.top) }, QSize{ int(RECT_WIDTH(rect)), int(RECT_HEIGHT(rect)) } };
|
||||
}
|
||||
|
||||
[[nodiscard]] RECT qrect2rect(const QRect &qrect)
|
||||
{
|
||||
return RECT{ LONG(qrect.left()), LONG(qrect.top()), LONG(qrect.right()), LONG(qrect.bottom()) };
|
||||
}
|
||||
|
||||
[[nodiscard]] QString hwnd2str(const WId windowId)
|
||||
{
|
||||
// NULL handle is allowed here.
|
||||
return FRAMELESSHELPER_STRING_LITERAL("0x") + QString::number(windowId, 16).toUpper().rightJustified(8, u'0');
|
||||
}
|
||||
|
||||
[[nodiscard]] QString hwnd2str(const HWND hwnd)
|
||||
{
|
||||
// NULL handle is allowed here.
|
||||
return hwnd2str(reinterpret_cast<WId>(hwnd));
|
||||
}
|
||||
|
||||
[[nodiscard]] std::optional<MONITORINFOEXW> getMonitorForWindow(const HWND hwnd)
|
||||
{
|
||||
Q_ASSERT(hwnd);
|
||||
|
@ -734,8 +667,7 @@ static constexpr const std::array<Win32Message, 333> g_win32MessageMap =
|
|||
static const auto currentOsVer = []() -> std::optional<VersionNumber> {
|
||||
if (API_NT_AVAILABLE(RtlGetVersion)) {
|
||||
using RtlGetVersionPtr = _NTSTATUS(WINAPI *)(PRTL_OSVERSIONINFOW);
|
||||
const auto pRtlGetVersion =
|
||||
reinterpret_cast<RtlGetVersionPtr>(SysApiLoader::instance()->get(kntdll, kRtlGetVersion));
|
||||
const auto pRtlGetVersion = reinterpret_cast<RtlGetVersionPtr>(SysApiLoader::instance()->get(kntdll, kRtlGetVersion));
|
||||
RTL_OSVERSIONINFOEXW osvi;
|
||||
SecureZeroMemory(&osvi, sizeof(osvi));
|
||||
osvi.dwOSVersionInfoSize = sizeof(osvi);
|
||||
|
@ -785,8 +717,7 @@ static constexpr const std::array<Win32Message, 333> g_win32MessageMap =
|
|||
return kErrorMessageTemplate.arg(function, QString::number(code), errorText);
|
||||
#else // !FRAMELESSHELPER_CONFIG(private_qt)
|
||||
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<LPWSTR>(&buf), 0, nullptr) == 0) {
|
||||
if (::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast<LPWSTR>(&buf), 0, nullptr) == 0) {
|
||||
return FRAMELESSHELPER_STRING_LITERAL("FormatMessageW() returned empty string.");
|
||||
}
|
||||
const QString errorText = QString::fromWCharArray(buf).trimmed();
|
||||
|
@ -839,16 +770,14 @@ static constexpr const std::array<Win32Message, 333> g_win32MessageMap =
|
|||
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,
|
||||
currentWindowWidth, currentWindowHeight, flags) == FALSE) {
|
||||
if (::SetWindowPos(hwnd, nullptr, newWindowX, newWindowY, currentWindowWidth, currentWindowHeight, flags) == FALSE) {
|
||||
WARNING << Utils::getSystemErrorMessage(kSetWindowPos);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]] static inline int getSystemMetrics2(const int index, const bool horizontal,
|
||||
const quint32 dpi)
|
||||
[[nodiscard]] static inline int getSystemMetrics2(const int index, const bool horizontal, const quint32 dpi)
|
||||
{
|
||||
Q_ASSERT(dpi != 0);
|
||||
if (dpi == 0) {
|
||||
|
@ -863,8 +792,7 @@ static constexpr const std::array<Win32Message, 333> g_win32MessageMap =
|
|||
return std::round(qreal(::GetSystemMetrics(index)) / currentDpr * requestedDpr);
|
||||
}
|
||||
|
||||
[[nodiscard]] static inline int getSystemMetrics2(const WId windowId, const int index,
|
||||
const bool horizontal, const bool scaled)
|
||||
[[nodiscard]] static inline int getSystemMetrics2(const WId windowId, const int index, const bool horizontal, const bool scaled)
|
||||
{
|
||||
Q_ASSERT(windowId);
|
||||
if (!windowId) {
|
||||
|
@ -883,29 +811,29 @@ static constexpr const std::array<Win32Message, 333> g_win32MessageMap =
|
|||
return std::round(qreal(::GetSystemMetrics(index)) / dpr);
|
||||
}
|
||||
|
||||
[[maybe_unused]] [[nodiscard]] static inline
|
||||
[[maybe_unused]] [[nodiscard]] static inline constexpr
|
||||
DWORD qtEdgesToWin32Orientation(const Qt::Edges edges)
|
||||
{
|
||||
if (edges == Qt::Edges{}) {
|
||||
return 0;
|
||||
} else if (edges == (Qt::LeftEdge)) {
|
||||
return 0xF001; // SC_SIZELEFT
|
||||
return SC_SIZELEFT;
|
||||
} else if (edges == (Qt::RightEdge)) {
|
||||
return 0xF002; // SC_SIZERIGHT
|
||||
return SC_SIZERIGHT;
|
||||
} else if (edges == (Qt::TopEdge)) {
|
||||
return 0xF003; // SC_SIZETOP
|
||||
return SC_SIZETOP;
|
||||
} else if (edges == (Qt::TopEdge | Qt::LeftEdge)) {
|
||||
return 0xF004; // SC_SIZETOPLEFT
|
||||
return SC_SIZETOPLEFT;
|
||||
} else if (edges == (Qt::TopEdge | Qt::RightEdge)) {
|
||||
return 0xF005; // SC_SIZETOPRIGHT
|
||||
return SC_SIZETOPRIGHT;
|
||||
} else if (edges == (Qt::BottomEdge)) {
|
||||
return 0xF006; // SC_SIZEBOTTOM
|
||||
return SC_SIZEBOTTOM;
|
||||
} else if (edges == (Qt::BottomEdge | Qt::LeftEdge)) {
|
||||
return 0xF007; // SC_SIZEBOTTOMLEFT
|
||||
return SC_SIZEBOTTOMLEFT;
|
||||
} else if (edges == (Qt::BottomEdge | Qt::RightEdge)) {
|
||||
return 0xF008; // SC_SIZEBOTTOMRIGHT
|
||||
return SC_SIZEBOTTOMRIGHT;
|
||||
} else {
|
||||
return 0xF000; // SC_SIZE
|
||||
return SC_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -923,7 +851,7 @@ static constexpr const std::array<Win32Message, 333> g_win32MessageMap =
|
|||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] static inline bool isNonClientMessage(const UINT message)
|
||||
[[nodiscard]] static inline constexpr bool isNonClientMessage(const UINT message)
|
||||
{
|
||||
if (((message >= WM_NCCREATE) && (message <= WM_NCACTIVATE))
|
||||
|| ((message >= WM_NCMOUSEMOVE) && (message <= WM_NCMBUTTONDBLCLK))
|
||||
|
@ -936,7 +864,7 @@ static constexpr const std::array<Win32Message, 333> g_win32MessageMap =
|
|||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] static inline bool isMouseMessage(const UINT message, bool *isNonClient = nullptr)
|
||||
[[nodiscard]] static inline constexpr bool isMouseMessage(const UINT message, bool *isNonClient = nullptr)
|
||||
{
|
||||
if (((message >= WM_MOUSEFIRST) && (message <= WM_MOUSELAST))
|
||||
|| ((message == WM_MOUSEHOVER) || (message == WM_MOUSELEAVE))) {
|
||||
|
@ -956,18 +884,12 @@ static constexpr const std::array<Win32Message, 333> g_win32MessageMap =
|
|||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] static inline bool usePureQtImplementation()
|
||||
{
|
||||
static const bool result = FramelessConfig::instance()->isSet(Option::UseCrossPlatformQtImplementation);
|
||||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] static inline LRESULT CALLBACK FramelessHelperHookWindowProc
|
||||
(const HWND hWnd, const UINT uMsg, const WPARAM wParam, const LPARAM lParam)
|
||||
{
|
||||
Q_ASSERT(hWnd);
|
||||
if (!hWnd) {
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
#if FRAMELESSHELPER_CONFIG(debug_output)
|
||||
if (isWin32MessageDebuggingEnabled()) {
|
||||
|
@ -981,11 +903,27 @@ static constexpr const std::array<Win32Message, 333> g_win32MessageMap =
|
|||
Utils::printWin32Message(&message);
|
||||
}
|
||||
#endif
|
||||
const auto defaultWindowProcessing = [hWnd, uMsg, wParam, lParam]() -> LRESULT { return ::DefWindowProcW(hWnd, uMsg, wParam, lParam); };
|
||||
const auto windowId = reinterpret_cast<WId>(hWnd);
|
||||
const auto it = g_win32UtilsData()->data.constFind(windowId);
|
||||
if (it == g_win32UtilsData()->data.constEnd()) {
|
||||
return ::DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||
const QObject *window = FramelessManagerPrivate::getWindow(windowId);
|
||||
if (!window) {
|
||||
return defaultWindowProcessing();
|
||||
}
|
||||
const FramelessDataPtr data = FramelessManagerPrivate::getData(window);
|
||||
if (!data || !data->frameless || !data->callbacks) {
|
||||
return defaultWindowProcessing();
|
||||
}
|
||||
const UtilsWinExtraDataPtr extraData = tryGetExtraData(data, false);
|
||||
Q_ASSERT(extraData);
|
||||
if (!extraData) {
|
||||
return defaultWindowProcessing();
|
||||
}
|
||||
const QWindow *qWindow = data->callbacks->getWindowHandle();
|
||||
Q_ASSERT(qWindow);
|
||||
if (!qWindow) {
|
||||
return defaultWindowProcessing();
|
||||
}
|
||||
#if FRAMELESSHELPER_CONFIG(native_impl)
|
||||
// https://github.com/qt/qtbase/blob/e26a87f1ecc40bc8c6aa5b889fce67410a57a702/src/plugins/platforms/windows/qwindowscontext.cpp#L1025
|
||||
// We can see from the source code that Qt will filter out some messages first and then send the unfiltered
|
||||
// messages to the event dispatcher. To activate the Snap Layout feature on Windows 11, we must process
|
||||
|
@ -1004,7 +942,7 @@ static constexpr const std::array<Win32Message, 333> g_win32MessageMap =
|
|||
// (and correct client area size, especially when the window is maximized/fullscreen). So we still go through
|
||||
// the normal code path of the original qWindowsWndProc() function, but only for this specific message. It should
|
||||
// be OK because Qt won't prevent us from handling WM_NCCALCSIZE.
|
||||
if (!usePureQtImplementation() && (uMsg != WM_NCCALCSIZE)) {
|
||||
if (uMsg != WM_NCCALCSIZE) {
|
||||
MSG message;
|
||||
SecureZeroMemory(&message, sizeof(message));
|
||||
message.hwnd = hWnd;
|
||||
|
@ -1034,7 +972,7 @@ static constexpr const std::array<Win32Message, 333> g_win32MessageMap =
|
|||
return LRESULT(filterResult);
|
||||
}
|
||||
}
|
||||
const Win32UtilsData &data = it.value();
|
||||
#endif // native_impl
|
||||
const auto getNativePosFromMouse = [lParam]() -> QPoint {
|
||||
return {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
|
||||
};
|
||||
|
@ -1073,8 +1011,8 @@ static constexpr const std::array<Win32Message, 333> g_win32MessageMap =
|
|||
switch (uMsg) {
|
||||
case WM_RBUTTONUP: {
|
||||
const QPoint nativeLocalPos = getNativePosFromMouse();
|
||||
const QPoint qtScenePos = Utils::fromNativeLocalPosition(data.params.getWindowHandle(), nativeLocalPos);
|
||||
if (data.params.isInsideTitleBarDraggableArea(qtScenePos)) {
|
||||
const QPoint qtScenePos = Utils::fromNativeLocalPosition(qWindow, nativeLocalPos);
|
||||
if (data->callbacks->isInsideTitleBarDraggableArea(qtScenePos)) {
|
||||
POINT pos = {nativeLocalPos.x(), nativeLocalPos.y()};
|
||||
if (::ClientToScreen(hWnd, &pos) == FALSE) {
|
||||
WARNING << Utils::getSystemErrorMessage(kClientToScreen);
|
||||
|
@ -1084,12 +1022,12 @@ static constexpr const std::array<Win32Message, 333> g_win32MessageMap =
|
|||
nativeGlobalPos = {pos.x, pos.y};
|
||||
}
|
||||
} break;
|
||||
case WM_NCRBUTTONUP: {
|
||||
case WM_NCRBUTTONUP:
|
||||
if (wParam == HTCAPTION) {
|
||||
shouldShowSystemMenu = true;
|
||||
nativeGlobalPos = getNativePosFromMouse();
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
case WM_SYSCOMMAND: {
|
||||
const WPARAM filteredWParam = (wParam & 0xFFF0);
|
||||
if ((filteredWParam == SC_KEYMENU) && (lParam == VK_SPACE)) {
|
||||
|
@ -1112,20 +1050,20 @@ static constexpr const std::array<Win32Message, 333> g_win32MessageMap =
|
|||
break;
|
||||
}
|
||||
if (shouldShowSystemMenu) {
|
||||
std::ignore = Utils::showSystemMenu(windowId, nativeGlobalPos, broughtByKeyboard, &data.params);
|
||||
std::ignore = Utils::showSystemMenu(windowId, nativeGlobalPos, broughtByKeyboard);
|
||||
// QPA's internal code will handle system menu events separately, and its
|
||||
// behavior is not what we would want to see because it doesn't know our
|
||||
// window doesn't have any window frame now, so return early here to avoid
|
||||
// entering Qt's own handling logic.
|
||||
return 0; // Return 0 means we have handled this event.
|
||||
return FALSE; // Return 0 means we have handled this event.
|
||||
}
|
||||
Q_ASSERT(g_win32UtilsData()->qtWindowProc);
|
||||
if (g_win32UtilsData()->qtWindowProc) {
|
||||
Q_ASSERT(extraData->qtWindowProc);
|
||||
if (extraData->qtWindowProc) {
|
||||
// Hand over to Qt's original window proc function for events we are not
|
||||
// interested in.
|
||||
return ::CallWindowProcW(g_win32UtilsData()->qtWindowProc, hWnd, uMsg, wParam, lParam);
|
||||
return ::CallWindowProcW(extraData->qtWindowProc, hWnd, uMsg, wParam, lParam);
|
||||
} else {
|
||||
return ::DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||
return defaultWindowProcessing();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1167,16 +1105,12 @@ bool Utils::triggerFrameChange(const WId windowId)
|
|||
return false;
|
||||
}
|
||||
const auto hwnd = reinterpret_cast<HWND>(windowId);
|
||||
static constexpr const UINT swpFlags =
|
||||
(SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOSIZE
|
||||
| SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER);
|
||||
static constexpr const UINT swpFlags = (SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER);
|
||||
if (::SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, swpFlags) == FALSE) {
|
||||
WARNING << getSystemErrorMessage(kSetWindowPos);
|
||||
return false;
|
||||
}
|
||||
static constexpr const UINT rdwFlags =
|
||||
(RDW_ERASE | RDW_FRAME | RDW_INVALIDATE
|
||||
| RDW_UPDATENOW | RDW_ALLCHILDREN);
|
||||
static constexpr const UINT rdwFlags = (RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN);
|
||||
if (::RedrawWindow(hwnd, nullptr, nullptr, rdwFlags) == FALSE) {
|
||||
WARNING << getSystemErrorMessage(kRedrawWindow);
|
||||
return false;
|
||||
|
@ -1193,19 +1127,31 @@ bool Utils::updateWindowFrameMargins(const WId windowId, const bool reset)
|
|||
if (!API_DWM_AVAILABLE(DwmExtendFrameIntoClientArea)) {
|
||||
return false;
|
||||
}
|
||||
// We can't extend the window frame when DWM composition is disabled.
|
||||
// We can't extend the window frame when DWM composition is disabled anyway.
|
||||
// No need to try further in this case.
|
||||
if (!isDwmCompositionEnabled()) {
|
||||
return false;
|
||||
}
|
||||
const bool micaEnabled = g_win32UtilsData()->micaWindowIds.contains(windowId);
|
||||
const auto margins = [micaEnabled, reset]() -> MARGINS {
|
||||
const QObject *window = FramelessManagerPrivate::getWindow(windowId);
|
||||
if (!window) {
|
||||
return false;
|
||||
}
|
||||
const FramelessDataPtr data = FramelessManagerPrivate::getData(window);
|
||||
if (!data) {
|
||||
return false;
|
||||
}
|
||||
const UtilsWinExtraDataPtr extraData = tryGetExtraData(data, false);
|
||||
Q_ASSERT(extraData);
|
||||
if (!extraData) {
|
||||
return false;
|
||||
}
|
||||
const auto margins = [&extraData, reset]() -> MARGINS {
|
||||
// To make Mica/Mica Alt work for normal Win32 windows, we have to
|
||||
// let the window frame extend to the whole window (or disable the
|
||||
// redirection surface, but this will break GDI's rendering, so we
|
||||
// can't do this, unfortunately), so we can't change the window frame
|
||||
// margins in this case, otherwise Mica/Mica Alt will be broken.
|
||||
if (micaEnabled) {
|
||||
if (extraData->mica) {
|
||||
return {-1, -1, -1, -1};
|
||||
}
|
||||
if (reset || isWindowFrameBorderVisible()) {
|
||||
|
@ -1275,9 +1221,9 @@ QString Utils::getSystemErrorMessage(const QString &function)
|
|||
if (function.isEmpty()) {
|
||||
return {};
|
||||
}
|
||||
const DWORD code = GetLastError();
|
||||
const DWORD code = ::GetLastError();
|
||||
if (code == ERROR_SUCCESS) {
|
||||
return {};
|
||||
return kSuccessMessageText;
|
||||
}
|
||||
return getSystemErrorMessageImpl(function, code);
|
||||
}
|
||||
|
@ -1342,12 +1288,19 @@ DwmColorizationArea Utils::getDwmColorizationArea()
|
|||
return DwmColorizationArea::None;
|
||||
}
|
||||
|
||||
bool Utils::showSystemMenu(const WId windowId, const QPoint &pos, const bool selectFirstEntry,
|
||||
FramelessParamsConst params)
|
||||
bool Utils::showSystemMenu(const WId windowId, const QPoint &pos, const bool selectFirstEntry)
|
||||
{
|
||||
Q_ASSERT(windowId);
|
||||
Q_ASSERT(params);
|
||||
if (!windowId || !params) {
|
||||
if (!windowId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const QObject *window = FramelessManagerPrivate::getWindow(windowId);
|
||||
if (!window) {
|
||||
return false;
|
||||
}
|
||||
const FramelessDataPtr data = FramelessManagerPrivate::getData(window);
|
||||
if (!data || !data->frameless || !data->callbacks) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1361,11 +1314,11 @@ bool Utils::showSystemMenu(const WId windowId, const QPoint &pos, const bool sel
|
|||
}
|
||||
|
||||
// Tweak the menu items according to the current window status and user settings.
|
||||
const bool disableRestore = params->getProperty(kSysMenuDisableRestoreVar, false).toBool();
|
||||
const bool disableMinimize = params->getProperty(kSysMenuDisableMinimizeVar, false).toBool();
|
||||
const bool disableMaximize = params->getProperty(kSysMenuDisableMaximizeVar, false).toBool();
|
||||
const bool disableRestore = data->callbacks->getProperty(kSysMenuDisableRestoreVar, false).toBool();
|
||||
const bool disableMinimize = data->callbacks->getProperty(kSysMenuDisableMinimizeVar, false).toBool();
|
||||
const bool disableMaximize = data->callbacks->getProperty(kSysMenuDisableMaximizeVar, false).toBool();
|
||||
const bool maxOrFull = (IsMaximized(hWnd) || isFullScreen(windowId));
|
||||
const bool fixedSize = params->isWindowFixedSize();
|
||||
const bool fixedSize = data->callbacks->isWindowFixedSize();
|
||||
::EnableMenuItem(hMenu, SC_RESTORE, (MF_BYCOMMAND | ((maxOrFull && !fixedSize && !disableRestore) ? MFS_ENABLED : MFS_DISABLED)));
|
||||
// The first menu item should be selected by default if the menu is brought
|
||||
// up by keyboard. I don't know how to pre-select a menu item but it seems
|
||||
|
@ -1399,14 +1352,13 @@ bool Utils::showSystemMenu(const WId windowId, const QPoint &pos, const bool sel
|
|||
::SetMenuDefaultItem(hMenu, defaultItemId, FALSE);
|
||||
|
||||
// Popup the system menu at the required position.
|
||||
const int result = ::TrackPopupMenu(hMenu, (TPM_RETURNCMD | (QGuiApplication::isRightToLeft()
|
||||
? TPM_RIGHTALIGN : TPM_LEFTALIGN)), pos.x(), pos.y(), 0, hWnd, nullptr);
|
||||
const int result = ::TrackPopupMenu(hMenu, (TPM_RETURNCMD | (QGuiApplication::isRightToLeft() ? TPM_RIGHTALIGN : TPM_LEFTALIGN)), pos.x(), pos.y(), 0, hWnd, nullptr);
|
||||
|
||||
// Unhighlight the first menu item after the popup menu is closed, otherwise it will keep
|
||||
// highlighting until we unhighlight it manually.
|
||||
::HiliteMenuItem(hWnd, hMenu, SC_RESTORE, (MF_BYCOMMAND | MFS_UNHILITE));
|
||||
|
||||
if (result == 0) {
|
||||
if (result == FALSE) {
|
||||
// The user canceled the menu, no need to continue.
|
||||
return true;
|
||||
}
|
||||
|
@ -1614,13 +1566,10 @@ quint32 Utils::getPrimaryScreenDpi(const bool horizontal)
|
|||
// Using Direct2D to get the primary monitor's DPI is only available on Windows 7
|
||||
// and onwards, but it has been marked as deprecated by Microsoft.
|
||||
if (API_D2D_AVAILABLE(D2D1CreateFactory)) {
|
||||
using D2D1CreateFactoryPtr =
|
||||
HRESULT(WINAPI *)(D2D1_FACTORY_TYPE, REFIID, CONST D2D1_FACTORY_OPTIONS *, void **);
|
||||
const auto pD2D1CreateFactory =
|
||||
reinterpret_cast<D2D1CreateFactoryPtr>(SysApiLoader::instance()->get(kd2d1, kD2D1CreateFactory));
|
||||
using D2D1CreateFactoryPtr = HRESULT(WINAPI *)(D2D1_FACTORY_TYPE, REFIID, CONST D2D1_FACTORY_OPTIONS *, void **);
|
||||
const auto pD2D1CreateFactory = reinterpret_cast<D2D1CreateFactoryPtr>(SysApiLoader::instance()->get(kd2d1, kD2D1CreateFactory));
|
||||
ID2D1Factory *d2dFactory = nullptr;
|
||||
HRESULT hr = pD2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory),
|
||||
nullptr, reinterpret_cast<void **>(&d2dFactory));
|
||||
HRESULT hr = pD2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory), nullptr, reinterpret_cast<void **>(&d2dFactory));
|
||||
if (SUCCEEDED(hr)) {
|
||||
// We want to get the newest system DPI, so refresh the system metrics
|
||||
// manually to ensure that.
|
||||
|
@ -1740,11 +1689,9 @@ quint32 Utils::getResizeBorderThicknessForDpi(const bool horizontal, const quint
|
|||
return 0;
|
||||
}
|
||||
if (horizontal) {
|
||||
return (getSystemMetrics2(SM_CXSIZEFRAME, true, dpi)
|
||||
+ getSystemMetrics2(SM_CXPADDEDBORDER, true, dpi));
|
||||
return (getSystemMetrics2(SM_CXSIZEFRAME, true, dpi) + getSystemMetrics2(SM_CXPADDEDBORDER, true, dpi));
|
||||
} else {
|
||||
return (getSystemMetrics2(SM_CYSIZEFRAME, false, dpi)
|
||||
+ getSystemMetrics2(SM_CYPADDEDBORDER, false, dpi));
|
||||
return (getSystemMetrics2(SM_CYSIZEFRAME, false, dpi) + getSystemMetrics2(SM_CYPADDEDBORDER, false, dpi));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1755,11 +1702,9 @@ quint32 Utils::getResizeBorderThickness(const WId windowId, const bool horizonta
|
|||
return 0;
|
||||
}
|
||||
if (horizontal) {
|
||||
return (getSystemMetrics2(windowId, SM_CXSIZEFRAME, true, scaled)
|
||||
+ getSystemMetrics2(windowId, SM_CXPADDEDBORDER, true, scaled));
|
||||
return (getSystemMetrics2(windowId, SM_CXSIZEFRAME, true, scaled) + getSystemMetrics2(windowId, SM_CXPADDEDBORDER, true, scaled));
|
||||
} else {
|
||||
return (getSystemMetrics2(windowId, SM_CYSIZEFRAME, false, scaled)
|
||||
+ getSystemMetrics2(windowId, SM_CYPADDEDBORDER, false, scaled));
|
||||
return (getSystemMetrics2(windowId, SM_CYSIZEFRAME, false, scaled) + getSystemMetrics2(windowId, SM_CYPADDEDBORDER, false, scaled));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1830,13 +1775,12 @@ quint32 Utils::getFrameBorderThickness(const WId windowId, const bool scaled)
|
|||
const qreal scaleFactor = (qreal(dpi) / qreal(USER_DEFAULT_SCREEN_DPI));
|
||||
const auto hwnd = reinterpret_cast<HWND>(windowId);
|
||||
UINT value = 0;
|
||||
const HRESULT hr = API_CALL_FUNCTION(dwmapi, DwmGetWindowAttribute, hwnd,
|
||||
_DWMWA_VISIBLE_FRAME_BORDER_THICKNESS, &value, sizeof(value));
|
||||
const HRESULT hr = API_CALL_FUNCTION(dwmapi, DwmGetWindowAttribute, hwnd, _DWMWA_VISIBLE_FRAME_BORDER_THICKNESS, &value, sizeof(value));
|
||||
if (SUCCEEDED(hr)) {
|
||||
const qreal dpr = (scaled ? 1.0 : scaleFactor);
|
||||
const qreal dpr = (scaled ? qreal(1) : scaleFactor);
|
||||
return std::round(qreal(value) / dpr);
|
||||
} else {
|
||||
const qreal dpr = (scaled ? scaleFactor : 1.0);
|
||||
const qreal dpr = (scaled ? scaleFactor : qreal(1));
|
||||
return std::round(qreal(kDefaultWindowFrameBorderThickness) * dpr);
|
||||
}
|
||||
}
|
||||
|
@ -1949,7 +1893,7 @@ bool Utils::startSystemMove(QWindow *window, const QPoint &globalPos)
|
|||
return false;
|
||||
}
|
||||
const auto hwnd = reinterpret_cast<HWND>(window->winId());
|
||||
if (::PostMessageW(hwnd, WM_SYSCOMMAND, 0xF012 /*SC_DRAGMOVE*/, 0) == FALSE) {
|
||||
if (::PostMessageW(hwnd, WM_SYSCOMMAND, SC_DRAGMOVE, 0) == FALSE) {
|
||||
WARNING << getSystemErrorMessage(kPostMessageW);
|
||||
return false;
|
||||
}
|
||||
|
@ -1986,10 +1930,8 @@ bool Utils::startSystemResize(QWindow *window, const Qt::Edges edges, const QPoi
|
|||
bool Utils::isWindowFrameBorderVisible()
|
||||
{
|
||||
static const auto result = []() -> bool {
|
||||
#if FRAMELESSHELPER_CONFIG(native_impl)
|
||||
const FramelessConfig * const config = FramelessConfig::instance();
|
||||
if (config->isSet(Option::UseCrossPlatformQtImplementation)) {
|
||||
return false;
|
||||
}
|
||||
if (config->isSet(Option::ForceShowWindowFrameBorder)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -1997,6 +1939,9 @@ bool Utils::isWindowFrameBorderVisible()
|
|||
return false;
|
||||
}
|
||||
return WindowsVersionHelper::isWin10OrGreater();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}();
|
||||
return result;
|
||||
}
|
||||
|
@ -2016,15 +1961,29 @@ bool Utils::isFrameBorderColorized()
|
|||
return isTitleBarColorized();
|
||||
}
|
||||
|
||||
bool Utils::installWindowProcHook(const WId windowId, FramelessParamsConst params)
|
||||
bool Utils::installWindowProcHook(const WId windowId)
|
||||
{
|
||||
Q_ASSERT(windowId);
|
||||
Q_ASSERT(params);
|
||||
if (!windowId || !params) {
|
||||
if (!windowId) {
|
||||
return false;
|
||||
}
|
||||
const QObject *window = FramelessManagerPrivate::getWindow(windowId);
|
||||
Q_ASSERT(window);
|
||||
if (!window) {
|
||||
return false;
|
||||
}
|
||||
const FramelessDataPtr data = FramelessManagerPrivate::getData(window);
|
||||
Q_ASSERT(data);
|
||||
if (!data || data->frameless) {
|
||||
return false;
|
||||
}
|
||||
const UtilsWinExtraDataPtr extraData = tryGetExtraData(data, true);
|
||||
Q_ASSERT(extraData);
|
||||
if (!extraData) {
|
||||
return false;
|
||||
}
|
||||
const auto hwnd = reinterpret_cast<HWND>(windowId);
|
||||
if (!g_win32UtilsData()->qtWindowProc) {
|
||||
if (!extraData->qtWindowProc) {
|
||||
::SetLastError(ERROR_SUCCESS);
|
||||
const auto qtWindowProc = reinterpret_cast<WNDPROC>(::GetWindowLongPtrW(hwnd, GWLP_WNDPROC));
|
||||
Q_ASSERT(qtWindowProc);
|
||||
|
@ -2032,18 +1991,15 @@ bool Utils::installWindowProcHook(const WId windowId, FramelessParamsConst param
|
|||
WARNING << getSystemErrorMessage(kGetWindowLongPtrW);
|
||||
return false;
|
||||
}
|
||||
g_win32UtilsData()->qtWindowProc = qtWindowProc;
|
||||
extraData->qtWindowProc = qtWindowProc;
|
||||
}
|
||||
const auto it = g_win32UtilsData()->data.constFind(windowId);
|
||||
if (it == g_win32UtilsData()->data.constEnd()) {
|
||||
Win32UtilsData data = {};
|
||||
data.params = *params;
|
||||
g_win32UtilsData()->data.insert(windowId, data);
|
||||
if (!extraData->windowProcHooked) {
|
||||
::SetLastError(ERROR_SUCCESS);
|
||||
if (::SetWindowLongPtrW(hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(FramelessHelperHookWindowProc)) == 0) {
|
||||
WARNING << getSystemErrorMessage(kSetWindowLongPtrW);
|
||||
return false;
|
||||
}
|
||||
extraData->windowProcHooked = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -2054,19 +2010,30 @@ bool Utils::uninstallWindowProcHook(const WId windowId)
|
|||
if (!windowId) {
|
||||
return false;
|
||||
}
|
||||
const auto it = g_win32UtilsData()->data.constFind(windowId);
|
||||
if (it != g_win32UtilsData()->data.constEnd()) {
|
||||
g_win32UtilsData()->data.erase(it);
|
||||
const QObject *window = FramelessManagerPrivate::getWindow(windowId);
|
||||
if (!window) {
|
||||
return false;
|
||||
}
|
||||
if (g_win32UtilsData()->data.isEmpty() && g_win32UtilsData()->qtWindowProc) {
|
||||
const auto hwnd = reinterpret_cast<HWND>(windowId);
|
||||
::SetLastError(ERROR_SUCCESS);
|
||||
if (::SetWindowLongPtrW(hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(g_win32UtilsData()->qtWindowProc)) == 0) {
|
||||
WARNING << getSystemErrorMessage(kSetWindowLongPtrW);
|
||||
return false;
|
||||
}
|
||||
g_win32UtilsData()->qtWindowProc = nullptr;
|
||||
const FramelessDataPtr data = FramelessManagerPrivate::getData(window);
|
||||
if (!data || !data->frameless) {
|
||||
return false;
|
||||
}
|
||||
const UtilsWinExtraDataPtr extraData = tryGetExtraData(data, false);
|
||||
if (!extraData || !extraData->windowProcHooked) {
|
||||
return false;
|
||||
}
|
||||
Q_ASSERT(extraData->qtWindowProc);
|
||||
if (!extraData->qtWindowProc) {
|
||||
return false;
|
||||
}
|
||||
const auto hwnd = reinterpret_cast<HWND>(windowId);
|
||||
::SetLastError(ERROR_SUCCESS);
|
||||
if (::SetWindowLongPtrW(hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(extraData->qtWindowProc)) == 0) {
|
||||
WARNING << getSystemErrorMessage(kSetWindowLongPtrW);
|
||||
return false;
|
||||
}
|
||||
extraData->qtWindowProc = nullptr;
|
||||
extraData->windowProcHooked = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2323,6 +2290,19 @@ bool Utils::setBlurBehindWindowEnabled(const WId windowId, const BlurMode mode,
|
|||
if (!windowId) {
|
||||
return false;
|
||||
}
|
||||
const QObject *window = FramelessManagerPrivate::getWindow(windowId);
|
||||
if (!window) {
|
||||
return false;
|
||||
}
|
||||
const FramelessDataPtr data = FramelessManagerPrivate::getData(window);
|
||||
if (!data) {
|
||||
return false;
|
||||
}
|
||||
const UtilsWinExtraDataPtr extraData = tryGetExtraData(data, false);
|
||||
// Don't assert here, the user may be using pure Qt solution.
|
||||
if (!extraData) {
|
||||
return false;
|
||||
}
|
||||
const auto hwnd = reinterpret_cast<HWND>(windowId);
|
||||
if (WindowsVersionHelper::isWin8OrGreater()) {
|
||||
if (!(API_DWM_AVAILABLE(DwmSetWindowAttribute)
|
||||
|
@ -2330,8 +2310,8 @@ bool Utils::setBlurBehindWindowEnabled(const WId windowId, const BlurMode mode,
|
|||
WARNING << "Blur behind window is not available on current platform.";
|
||||
return false;
|
||||
}
|
||||
const auto restoreWindowFrameMargins = [windowId]() -> void {
|
||||
g_win32UtilsData()->micaWindowIds.removeAll(windowId);
|
||||
const auto restoreWindowFrameMargins = [windowId, &extraData]() -> void {
|
||||
extraData->mica = false;
|
||||
std::ignore = updateWindowFrameMargins(windowId, false);
|
||||
};
|
||||
static const auto userPreferredBlurMode = []() -> std::optional<BlurMode> {
|
||||
|
@ -2372,7 +2352,7 @@ bool Utils::setBlurBehindWindowEnabled(const WId windowId, const BlurMode mode,
|
|||
return mode;
|
||||
}
|
||||
if (((mode == BlurMode::Windows_Mica) || (mode == BlurMode::Windows_MicaAlt))
|
||||
&& !WindowsVersionHelper::isWin11OrGreater()) {
|
||||
&& !WindowsVersionHelper::isWin11OrGreater()) {
|
||||
WARNING << "The Mica material is not supported on your system, fallback to the Acrylic blur instead...";
|
||||
if (WindowsVersionHelper::isWin10OrGreater()) {
|
||||
return BlurMode::Windows_Acrylic;
|
||||
|
@ -2438,7 +2418,7 @@ bool Utils::setBlurBehindWindowEnabled(const WId windowId, const BlurMode mode,
|
|||
return result;
|
||||
} else {
|
||||
if ((blurMode == BlurMode::Windows_Mica) || (blurMode == BlurMode::Windows_MicaAlt)) {
|
||||
g_win32UtilsData()->micaWindowIds.append(windowId);
|
||||
extraData->mica = true;
|
||||
// By giving a negative value, DWM will extend the window frame into the whole
|
||||
// client area. We need this step because the Mica material can only be applied
|
||||
// to the non-client area of a window. Without this step, you'll get a window
|
||||
|
@ -2682,9 +2662,9 @@ bool Utils::setQtDarkModeAwareEnabled(const bool enable)
|
|||
// flag has no effect for pure Qt Quick applications.
|
||||
return {App::DarkModeWindowFrames | App::DarkModeStyle};
|
||||
# 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.
|
||||
// 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))
|
||||
}());
|
||||
|
@ -3107,16 +3087,6 @@ QRect Utils::getWindowRestoreGeometry(const WId windowId)
|
|||
return rect2qrect(wp.rcNormalPosition).translated(getWindowPlacementOffset(windowId));
|
||||
}
|
||||
|
||||
bool Utils::removeMicaWindow(const WId windowId)
|
||||
{
|
||||
Q_ASSERT(windowId);
|
||||
if (!windowId) {
|
||||
return false;
|
||||
}
|
||||
g_win32UtilsData()->micaWindowIds.removeAll(windowId);
|
||||
return true;
|
||||
}
|
||||
|
||||
quint64 Utils::getKeyState()
|
||||
{
|
||||
quint64 result = 0;
|
||||
|
@ -3163,7 +3133,7 @@ bool Utils::isValidWindow(const WId windowId, const bool checkVisible, const boo
|
|||
return false;
|
||||
}
|
||||
const LONG_PTR exStyles = ::GetWindowLongPtrW(hwnd, GWL_EXSTYLE);
|
||||
if ((exStyles != 0) && (exStyles & WS_EX_TOOLWINDOW)) {
|
||||
if ((exStyles == 0) || (exStyles & WS_EX_TOOLWINDOW)) {
|
||||
return false;
|
||||
}
|
||||
RECT rect = { 0, 0, 0, 0 };
|
||||
|
@ -3209,11 +3179,11 @@ bool Utils::updateFramebufferTransparency(const WId windowId)
|
|||
DWM_BLURBEHIND bb;
|
||||
SecureZeroMemory(&bb, sizeof(bb));
|
||||
bb.dwFlags = (DWM_BB_ENABLE | DWM_BB_BLURREGION);
|
||||
bb.hRgnBlur = CreateRectRgn(0, 0, -1, -1);
|
||||
bb.hRgnBlur = ::CreateRectRgn(0, 0, -1, -1);
|
||||
bb.fEnable = TRUE;
|
||||
const HRESULT hr = API_CALL_FUNCTION(dwmapi, DwmEnableBlurBehindWindow, hwnd, &bb);
|
||||
if (bb.hRgnBlur) {
|
||||
if (DeleteObject(bb.hRgnBlur) == FALSE) {
|
||||
if (::DeleteObject(bb.hRgnBlur) == FALSE) {
|
||||
WARNING << getSystemErrorMessage(kDeleteObject);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ using namespace Global;
|
|||
|
||||
class WinVerHelper
|
||||
{
|
||||
Q_DISABLE_COPY_MOVE(WinVerHelper)
|
||||
FRAMELESSHELPER_CLASS(WinVerHelper)
|
||||
|
||||
public:
|
||||
explicit WinVerHelper();
|
||||
|
|
|
@ -109,7 +109,7 @@ if(WIN32 AND NOT FRAMELESSHELPER_BUILD_STATIC)
|
|||
COPYRIGHT "MIT License"
|
||||
ORIGINAL_FILENAME "${SUB_MODULE_FULL_NAME}.dll"
|
||||
PRODUCT "${PROJECT_NAME}"
|
||||
COMMENTS "Built from commit ${PROJECT_VERSION_COMMIT} on ${PROJECT_COMPILE_DATETIME} (UTC)."
|
||||
COMMENTS "Who don't love Raiden Shogun ?"
|
||||
LIBRARY
|
||||
)
|
||||
endif()
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#endif
|
||||
#include <FramelessHelper/Core/framelessmanager.h>
|
||||
#include <FramelessHelper/Core/utils.h>
|
||||
#include <FramelessHelper/Core/private/framelessmanager_p.h>
|
||||
#include <FramelessHelper/Core/private/framelessconfig_p.h>
|
||||
#include <FramelessHelper/Core/private/framelesshelpercore_global_p.h>
|
||||
#ifdef Q_OS_WINDOWS
|
||||
|
@ -72,10 +73,8 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
|
|||
|
||||
using namespace Global;
|
||||
|
||||
struct FramelessQuickHelperData
|
||||
struct FramelessQuickHelperExtraData : public FramelessExtraData
|
||||
{
|
||||
bool ready = false;
|
||||
SystemParameters params = {};
|
||||
QPointer<QQuickItem> titleBarItem = nullptr;
|
||||
QList<QPointer<QQuickItem>> hitTestVisibleItems = {};
|
||||
QPointer<QQuickItem> windowIconButton = nullptr;
|
||||
|
@ -84,11 +83,52 @@ struct FramelessQuickHelperData
|
|||
QPointer<QQuickItem> maximizeButton = nullptr;
|
||||
QPointer<QQuickItem> closeButton = nullptr;
|
||||
QList<QRect> hitTestVisibleRects = {};
|
||||
|
||||
FramelessQuickHelperExtraData();
|
||||
~FramelessQuickHelperExtraData() override;
|
||||
|
||||
[[nodiscard]] static FramelessExtraDataPtr create();
|
||||
};
|
||||
using FramelessQuickHelperExtraDataPtr = std::shared_ptr<FramelessQuickHelperExtraData>;
|
||||
|
||||
using FramelessQuickHelperInternal = QHash<WId, FramelessQuickHelperData>;
|
||||
FramelessQuickHelperExtraData::FramelessQuickHelperExtraData() = default;
|
||||
|
||||
Q_GLOBAL_STATIC(FramelessQuickHelperInternal, g_framelessQuickHelperData)
|
||||
FramelessQuickHelperExtraData::~FramelessQuickHelperExtraData() = default;
|
||||
|
||||
FramelessExtraDataPtr FramelessQuickHelperExtraData::create()
|
||||
{
|
||||
return std::make_shared<FramelessQuickHelperExtraData>();
|
||||
}
|
||||
|
||||
[[nodiscard]] static inline FramelessQuickHelperExtraDataPtr tryGetExtraData(const FramelessDataPtr &data, const bool create)
|
||||
{
|
||||
Q_ASSERT(data);
|
||||
if (!data) {
|
||||
return nullptr;
|
||||
}
|
||||
auto it = data->extraData.find(ExtraDataType::FramelessQuickHelper);
|
||||
if (it == data->extraData.end()) {
|
||||
if (create) {
|
||||
it = data->extraData.insert(ExtraDataType::FramelessQuickHelper, FramelessQuickHelperExtraData::create());
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return std::dynamic_pointer_cast<FramelessQuickHelperExtraData>(it.value());
|
||||
}
|
||||
|
||||
[[nodiscard]] static inline FramelessQuickHelperExtraDataPtr tryGetExtraData(const QQuickWindow *window, const bool create)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
if (!window) {
|
||||
return nullptr;
|
||||
}
|
||||
const FramelessDataPtr data = FramelessManagerPrivate::getData(window);
|
||||
if (!data) {
|
||||
return nullptr;
|
||||
}
|
||||
return tryGetExtraData(data, create);
|
||||
}
|
||||
|
||||
FramelessQuickHelperPrivate::FramelessQuickHelperPrivate(FramelessQuickHelper *q) : QObject(q)
|
||||
{
|
||||
|
@ -124,59 +164,61 @@ const FramelessQuickHelperPrivate *FramelessQuickHelperPrivate::get(const Framel
|
|||
void FramelessQuickHelperPrivate::attach()
|
||||
{
|
||||
Q_Q(FramelessQuickHelper);
|
||||
QQuickWindow * const window = q->window();
|
||||
QQuickWindow *window = q->window();
|
||||
Q_ASSERT(window);
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
const WId windowId = window->winId();
|
||||
|
||||
FramelessQuickHelperData * const data = getWindowDataMutable();
|
||||
if (!data || data->ready) {
|
||||
const FramelessDataPtr data = FramelessManagerPrivate::createData(window, windowId);
|
||||
Q_ASSERT(data);
|
||||
if (!data || data->frameless) {
|
||||
return;
|
||||
}
|
||||
|
||||
SystemParameters params = {};
|
||||
params.getWindowId = [window]() -> WId { return window->winId(); };
|
||||
params.getWindowFlags = [window]() -> Qt::WindowFlags { return window->flags(); };
|
||||
params.setWindowFlags = [window](const Qt::WindowFlags flags) -> void { window->setFlags(flags); };
|
||||
params.getWindowSize = [window]() -> QSize { return window->size(); };
|
||||
params.setWindowSize = [window](const QSize &size) -> void { window->resize(size); };
|
||||
params.getWindowPosition = [window]() -> QPoint { return window->position(); };
|
||||
params.setWindowPosition = [window](const QPoint &pos) -> void { window->setX(pos.x()); window->setY(pos.y()); };
|
||||
params.getWindowScreen = [window]() -> QScreen * { return window->screen(); };
|
||||
params.isWindowFixedSize = [q]() -> bool { return q->isWindowFixedSize(); };
|
||||
params.setWindowFixedSize = [q](const bool value) -> void { q->setWindowFixedSize(value); };
|
||||
params.getWindowState = [window]() -> Qt::WindowState { return window->windowState(); };
|
||||
params.setWindowState = [window](const Qt::WindowState state) -> void { window->setWindowState(state); };
|
||||
params.getWindowHandle = [window]() -> QWindow * { return window; };
|
||||
params.windowToScreen = [window](const QPoint &pos) -> QPoint { return window->mapToGlobal(pos); };
|
||||
params.screenToWindow = [window](const QPoint &pos) -> QPoint { return window->mapFromGlobal(pos); };
|
||||
params.isInsideSystemButtons = [this](const QPoint &pos, SystemButtonType *button) -> bool {
|
||||
QuickGlobal::SystemButtonType button2 = QuickGlobal::SystemButtonType::Unknown;
|
||||
const bool result = isInSystemButtons(pos, &button2);
|
||||
*button = FRAMELESSHELPER_ENUM_QUICK_TO_CORE(SystemButtonType, button2);
|
||||
return result;
|
||||
};
|
||||
params.isInsideTitleBarDraggableArea = [this](const QPoint &pos) -> bool { return isInTitleBarDraggableArea(pos); };
|
||||
params.getWindowDevicePixelRatio = [window]() -> qreal { return window->effectiveDevicePixelRatio(); };
|
||||
params.setSystemButtonState = [this](const SystemButtonType button, const ButtonState state) -> void {
|
||||
setSystemButtonState(FRAMELESSHELPER_ENUM_CORE_TO_QUICK(SystemButtonType, button),
|
||||
FRAMELESSHELPER_ENUM_CORE_TO_QUICK(ButtonState, state));
|
||||
};
|
||||
params.shouldIgnoreMouseEvents = [this](const QPoint &pos) -> bool { return shouldIgnoreMouseEvents(pos); };
|
||||
params.showSystemMenu = [q](const QPoint &pos) -> void { q->showSystemMenu(pos); };
|
||||
params.setProperty = [this](const char *name, const QVariant &value) -> void { setProperty(name, value); };
|
||||
params.getProperty = [this](const char *name, const QVariant &defaultValue) -> QVariant { return getProperty(name, defaultValue); };
|
||||
params.setCursor = [window](const QCursor &cursor) -> void { window->setCursor(cursor); };
|
||||
params.unsetCursor = [window]() -> void { window->unsetCursor(); };
|
||||
params.getWidgetHandle = []() -> QObject * { return nullptr; };
|
||||
params.forceChildrenRepaint = [this](const int delay) -> void { repaintAllChildren(delay); };
|
||||
params.resetQtGrabbedControl = []() -> bool { return false; };
|
||||
if (!data->callbacks) {
|
||||
data->callbacks = FramelessCallbacks::create();
|
||||
data->callbacks->getWindowId = [window]() -> WId { return window->winId(); };
|
||||
data->callbacks->getWindowFlags = [window]() -> Qt::WindowFlags { return window->flags(); };
|
||||
data->callbacks->setWindowFlags = [window](const Qt::WindowFlags flags) -> void { window->setFlags(flags); };
|
||||
data->callbacks->getWindowSize = [window]() -> QSize { return window->size(); };
|
||||
data->callbacks->setWindowSize = [window](const QSize &size) -> void { window->resize(size); };
|
||||
data->callbacks->getWindowPosition = [window]() -> QPoint { return window->position(); };
|
||||
data->callbacks->setWindowPosition = [window](const QPoint &pos) -> void { window->setX(pos.x()); window->setY(pos.y()); };
|
||||
data->callbacks->getWindowScreen = [window]() -> QScreen * { return window->screen(); };
|
||||
data->callbacks->isWindowFixedSize = [q]() -> bool { return q->isWindowFixedSize(); };
|
||||
data->callbacks->setWindowFixedSize = [q](const bool value) -> void { q->setWindowFixedSize(value); };
|
||||
data->callbacks->getWindowState = [window]() -> Qt::WindowState { return window->windowState(); };
|
||||
data->callbacks->setWindowState = [window](const Qt::WindowState state) -> void { window->setWindowState(state); };
|
||||
data->callbacks->getWindowHandle = [q]() -> QWindow * { return q->window(); };
|
||||
data->callbacks->windowToScreen = [window](const QPoint &pos) -> QPoint { return window->mapToGlobal(pos); };
|
||||
data->callbacks->screenToWindow = [window](const QPoint &pos) -> QPoint { return window->mapFromGlobal(pos); };
|
||||
data->callbacks->isInsideSystemButtons = [this](const QPoint &pos, SystemButtonType *button) -> bool {
|
||||
QuickGlobal::SystemButtonType button2 = QuickGlobal::SystemButtonType::Unknown;
|
||||
const bool result = isInSystemButtons(pos, &button2);
|
||||
*button = FRAMELESSHELPER_ENUM_QUICK_TO_CORE(SystemButtonType, button2);
|
||||
return result;
|
||||
};
|
||||
data->callbacks->isInsideTitleBarDraggableArea = [this](const QPoint &pos) -> bool { return isInTitleBarDraggableArea(pos); };
|
||||
data->callbacks->getWindowDevicePixelRatio = [window]() -> qreal { return window->effectiveDevicePixelRatio(); };
|
||||
data->callbacks->setSystemButtonState = [this](const SystemButtonType button, const ButtonState state) -> void {
|
||||
setSystemButtonState(FRAMELESSHELPER_ENUM_CORE_TO_QUICK(SystemButtonType, button), FRAMELESSHELPER_ENUM_CORE_TO_QUICK(ButtonState, state));
|
||||
};
|
||||
data->callbacks->shouldIgnoreMouseEvents = [this](const QPoint &pos) -> bool { return shouldIgnoreMouseEvents(pos); };
|
||||
data->callbacks->showSystemMenu = [q](const QPoint &pos) -> void { q->showSystemMenu(pos); };
|
||||
data->callbacks->setProperty = [this](const char *name, const QVariant &value) -> void { setProperty(name, value); };
|
||||
data->callbacks->getProperty = [this](const char *name, const QVariant &defaultValue) -> QVariant { return getProperty(name, defaultValue); };
|
||||
data->callbacks->setCursor = [window](const QCursor &cursor) -> void { window->setCursor(cursor); };
|
||||
data->callbacks->unsetCursor = [window]() -> void { window->unsetCursor(); };
|
||||
data->callbacks->getWidgetHandle = []() -> QObject * { return nullptr; };
|
||||
data->callbacks->forceChildrenRepaint = [this](const int delay) -> void { repaintAllChildren(delay); };
|
||||
data->callbacks->resetQtGrabbedControl = []() -> bool { return false; };
|
||||
}
|
||||
|
||||
FramelessManager::instance()->addWindow(¶ms);
|
||||
std::ignore = tryGetExtraData(data, true);
|
||||
|
||||
data->params = params;
|
||||
data->ready = true;
|
||||
std::ignore = FramelessManager::instance()->addWindow(window, windowId);
|
||||
|
||||
// We have to wait for a little time before moving the top level window
|
||||
// , because the platform window may not finish initializing by the time
|
||||
|
@ -198,17 +240,11 @@ void FramelessQuickHelperPrivate::attach()
|
|||
void FramelessQuickHelperPrivate::detach()
|
||||
{
|
||||
Q_Q(FramelessQuickHelper);
|
||||
QQuickWindow * const w = q->window();
|
||||
if (!w) {
|
||||
const QQuickWindow *window = q->window();
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
const WId windowId = w->winId();
|
||||
const auto it = g_framelessQuickHelperData()->constFind(windowId);
|
||||
if (it == g_framelessQuickHelperData()->constEnd()) {
|
||||
return;
|
||||
}
|
||||
g_framelessQuickHelperData()->erase(it);
|
||||
FramelessManager::instance()->removeWindow(windowId);
|
||||
std::ignore = FramelessManager::instance()->removeWindow(window);
|
||||
}
|
||||
|
||||
void FramelessQuickHelperPrivate::emitSignalForAllInstances(const char *signal)
|
||||
|
@ -433,37 +469,43 @@ bool FramelessQuickHelperPrivate::isInSystemButtons(const QPoint &pos, QuickGlob
|
|||
if (!button) {
|
||||
return false;
|
||||
}
|
||||
const FramelessQuickHelperData *data = getWindowData();
|
||||
if (!data) {
|
||||
Q_Q(const FramelessQuickHelper);
|
||||
const QQuickWindow * const window = q->window();
|
||||
if (!window) {
|
||||
return false;
|
||||
}
|
||||
const FramelessQuickHelperExtraDataPtr extraData = tryGetExtraData(window, false);
|
||||
Q_ASSERT(extraData);
|
||||
if (!extraData) {
|
||||
return false;
|
||||
}
|
||||
*button = QuickGlobal::SystemButtonType::Unknown;
|
||||
if (data->windowIconButton && data->windowIconButton->isVisible() && data->windowIconButton->isEnabled()) {
|
||||
if (mapItemGeometryToScene(data->windowIconButton).contains(pos)) {
|
||||
if (extraData->windowIconButton && extraData->windowIconButton->isVisible() && extraData->windowIconButton->isEnabled()) {
|
||||
if (mapItemGeometryToScene(extraData->windowIconButton).contains(pos)) {
|
||||
*button = QuickGlobal::SystemButtonType::WindowIcon;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (data->contextHelpButton && data->contextHelpButton->isVisible() && data->contextHelpButton->isEnabled()) {
|
||||
if (mapItemGeometryToScene(data->contextHelpButton).contains(pos)) {
|
||||
if (extraData->contextHelpButton && extraData->contextHelpButton->isVisible() && extraData->contextHelpButton->isEnabled()) {
|
||||
if (mapItemGeometryToScene(extraData->contextHelpButton).contains(pos)) {
|
||||
*button = QuickGlobal::SystemButtonType::Help;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (data->minimizeButton && data->minimizeButton->isVisible() && data->minimizeButton->isEnabled()) {
|
||||
if (mapItemGeometryToScene(data->minimizeButton).contains(pos)) {
|
||||
if (extraData->minimizeButton && extraData->minimizeButton->isVisible() && extraData->minimizeButton->isEnabled()) {
|
||||
if (mapItemGeometryToScene(extraData->minimizeButton).contains(pos)) {
|
||||
*button = QuickGlobal::SystemButtonType::Minimize;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (data->maximizeButton && data->maximizeButton->isVisible() && data->maximizeButton->isEnabled()) {
|
||||
if (mapItemGeometryToScene(data->maximizeButton).contains(pos)) {
|
||||
if (extraData->maximizeButton && extraData->maximizeButton->isVisible() && extraData->maximizeButton->isEnabled()) {
|
||||
if (mapItemGeometryToScene(extraData->maximizeButton).contains(pos)) {
|
||||
*button = QuickGlobal::SystemButtonType::Maximize;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (data->closeButton && data->closeButton->isVisible() && data->closeButton->isEnabled()) {
|
||||
if (mapItemGeometryToScene(data->closeButton).contains(pos)) {
|
||||
if (extraData->closeButton && extraData->closeButton->isVisible() && extraData->closeButton->isEnabled()) {
|
||||
if (mapItemGeometryToScene(extraData->closeButton).contains(pos)) {
|
||||
*button = QuickGlobal::SystemButtonType::Close;
|
||||
return true;
|
||||
}
|
||||
|
@ -473,18 +515,6 @@ bool FramelessQuickHelperPrivate::isInSystemButtons(const QPoint &pos, QuickGlob
|
|||
|
||||
bool FramelessQuickHelperPrivate::isInTitleBarDraggableArea(const QPoint &pos) const
|
||||
{
|
||||
const FramelessQuickHelperData *data = getWindowData();
|
||||
if (!data) {
|
||||
return false;
|
||||
}
|
||||
if (!data->titleBarItem) {
|
||||
// There's no title bar at all, the mouse will always be in the client area.
|
||||
return false;
|
||||
}
|
||||
if (!data->titleBarItem->isVisible() || !data->titleBarItem->isEnabled()) {
|
||||
// The title bar is hidden or disabled for some reason, treat it as there's no title bar.
|
||||
return false;
|
||||
}
|
||||
Q_Q(const FramelessQuickHelper);
|
||||
const QQuickWindow * const window = q->window();
|
||||
if (!window) {
|
||||
|
@ -492,8 +522,21 @@ bool FramelessQuickHelperPrivate::isInTitleBarDraggableArea(const QPoint &pos) c
|
|||
// so we assume there's no title bar.
|
||||
return false;
|
||||
}
|
||||
const FramelessQuickHelperExtraDataPtr extraData = tryGetExtraData(window, false);
|
||||
Q_ASSERT(extraData);
|
||||
if (!extraData) {
|
||||
return false;
|
||||
}
|
||||
if (!extraData->titleBarItem) {
|
||||
// There's no title bar at all, the mouse will always be in the client area.
|
||||
return false;
|
||||
}
|
||||
if (!extraData->titleBarItem->isVisible() || !extraData->titleBarItem->isEnabled()) {
|
||||
// The title bar is hidden or disabled for some reason, treat it as there's no title bar.
|
||||
return false;
|
||||
}
|
||||
const QRect windowRect = {QPoint(0, 0), window->size()};
|
||||
const QRect titleBarRect = mapItemGeometryToScene(data->titleBarItem);
|
||||
const QRect titleBarRect = mapItemGeometryToScene(extraData->titleBarItem);
|
||||
if (!titleBarRect.intersects(windowRect)) {
|
||||
// The title bar is totally outside of the window for some reason,
|
||||
// also treat it as there's no title bar.
|
||||
|
@ -501,24 +544,24 @@ bool FramelessQuickHelperPrivate::isInTitleBarDraggableArea(const QPoint &pos) c
|
|||
}
|
||||
QRegion region = titleBarRect;
|
||||
const auto systemButtons = {
|
||||
data->windowIconButton, data->contextHelpButton,
|
||||
data->minimizeButton, data->maximizeButton,
|
||||
data->closeButton
|
||||
extraData->windowIconButton, extraData->contextHelpButton,
|
||||
extraData->minimizeButton, extraData->maximizeButton,
|
||||
extraData->closeButton
|
||||
};
|
||||
for (auto &&button : std::as_const(systemButtons)) {
|
||||
if (button && button->isVisible() && button->isEnabled()) {
|
||||
region -= mapItemGeometryToScene(button);
|
||||
}
|
||||
}
|
||||
if (!data->hitTestVisibleItems.isEmpty()) {
|
||||
for (auto &&item : std::as_const(data->hitTestVisibleItems)) {
|
||||
if (!extraData->hitTestVisibleItems.isEmpty()) {
|
||||
for (auto &&item : std::as_const(extraData->hitTestVisibleItems)) {
|
||||
if (item && item->isVisible() && item->isEnabled()) {
|
||||
region -= mapItemGeometryToScene(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!data->hitTestVisibleRects.isEmpty()) {
|
||||
for (auto &&rect : std::as_const(data->hitTestVisibleRects)) {
|
||||
if (!extraData->hitTestVisibleRects.isEmpty()) {
|
||||
for (auto &&rect : std::as_const(extraData->hitTestVisibleRects)) {
|
||||
if (rect.isValid()) {
|
||||
region -= rect;
|
||||
}
|
||||
|
@ -556,38 +599,6 @@ void FramelessQuickHelperPrivate::setSystemButtonState(const QuickGlobal::System
|
|||
Q_UNUSED(state);
|
||||
}
|
||||
|
||||
const FramelessQuickHelperData *FramelessQuickHelperPrivate::getWindowData() const
|
||||
{
|
||||
Q_Q(const FramelessQuickHelper);
|
||||
const QQuickWindow * const window = q->window();
|
||||
//Q_ASSERT(window);
|
||||
if (!window) {
|
||||
return nullptr;
|
||||
}
|
||||
const WId windowId = window->winId();
|
||||
auto it = g_framelessQuickHelperData()->find(windowId);
|
||||
if (it == g_framelessQuickHelperData()->end()) {
|
||||
it = g_framelessQuickHelperData()->insert(windowId, {});
|
||||
}
|
||||
return &it.value();
|
||||
}
|
||||
|
||||
FramelessQuickHelperData *FramelessQuickHelperPrivate::getWindowDataMutable() const
|
||||
{
|
||||
Q_Q(const FramelessQuickHelper);
|
||||
const QQuickWindow * const window = q->window();
|
||||
//Q_ASSERT(window);
|
||||
if (!window) {
|
||||
return nullptr;
|
||||
}
|
||||
const WId windowId = window->winId();
|
||||
auto it = g_framelessQuickHelperData()->find(windowId);
|
||||
if (it == g_framelessQuickHelperData()->end()) {
|
||||
it = g_framelessQuickHelperData()->insert(windowId, {});
|
||||
}
|
||||
return &it.value();
|
||||
}
|
||||
|
||||
void FramelessQuickHelperPrivate::rebindWindow()
|
||||
{
|
||||
Q_Q(FramelessQuickHelper);
|
||||
|
@ -668,33 +679,41 @@ void FramelessQuickHelper::setHitTestVisible_item(QQuickItem *item, const bool v
|
|||
if (!item) {
|
||||
return;
|
||||
}
|
||||
Q_D(FramelessQuickHelper);
|
||||
FramelessQuickHelperData *data = d->getWindowDataMutable();
|
||||
if (!data) {
|
||||
const QQuickWindow * const w = window();
|
||||
if (!w) {
|
||||
return;
|
||||
}
|
||||
const FramelessQuickHelperExtraDataPtr extraData = tryGetExtraData(w, false);
|
||||
Q_ASSERT(extraData);
|
||||
if (!extraData) {
|
||||
return;
|
||||
}
|
||||
if (visible) {
|
||||
data->hitTestVisibleItems.append(item);
|
||||
extraData->hitTestVisibleItems.append(item);
|
||||
} else {
|
||||
data->hitTestVisibleItems.removeAll(item);
|
||||
extraData->hitTestVisibleItems.removeAll(item);
|
||||
}
|
||||
}
|
||||
|
||||
void FramelessQuickHelper::setHitTestVisible_rect(const QRect &rect, const bool visible)
|
||||
{
|
||||
Q_ASSERT(rect.isValid());
|
||||
if (!rect.isValid()) {
|
||||
Q_ASSERT(Utils::isValidGeometry(rect));
|
||||
if (!Utils::isValidGeometry(rect)) {
|
||||
return;
|
||||
}
|
||||
Q_D(FramelessQuickHelper);
|
||||
FramelessQuickHelperData *data = d->getWindowDataMutable();
|
||||
if (!data) {
|
||||
const QQuickWindow * const w = window();
|
||||
if (!w) {
|
||||
return;
|
||||
}
|
||||
const FramelessQuickHelperExtraDataPtr extraData = tryGetExtraData(w, false);
|
||||
Q_ASSERT(extraData);
|
||||
if (!extraData) {
|
||||
return;
|
||||
}
|
||||
if (visible) {
|
||||
data->hitTestVisibleRects.append(rect);
|
||||
extraData->hitTestVisibleRects.append(rect);
|
||||
} else {
|
||||
data->hitTestVisibleRects.removeAll(rect);
|
||||
extraData->hitTestVisibleRects.removeAll(rect);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -714,9 +733,12 @@ void FramelessQuickHelper::setHitTestVisible_object(QObject *object, const bool
|
|||
|
||||
bool FramelessQuickHelper::isContentExtendedIntoTitleBar() const
|
||||
{
|
||||
Q_D(const FramelessQuickHelper);
|
||||
const FramelessQuickHelperData *data = d->getWindowData();
|
||||
return (data ? data->ready : false);
|
||||
const QQuickWindow * const w = window();
|
||||
if (!w) {
|
||||
return false;
|
||||
}
|
||||
const FramelessDataPtr data = FramelessManagerPrivate::getData(w);
|
||||
return (data && data->frameless);
|
||||
}
|
||||
|
||||
void FramelessQuickHelper::extendsContentIntoTitleBar(const bool value)
|
||||
|
@ -736,9 +758,16 @@ void FramelessQuickHelper::extendsContentIntoTitleBar(const bool value)
|
|||
|
||||
QQuickItem *FramelessQuickHelper::titleBarItem() const
|
||||
{
|
||||
Q_D(const FramelessQuickHelper);
|
||||
const FramelessQuickHelperData *data = d->getWindowData();
|
||||
return (data ? data->titleBarItem : nullptr);
|
||||
const QQuickWindow * const w = window();
|
||||
if (!w) {
|
||||
return nullptr;
|
||||
}
|
||||
const FramelessQuickHelperExtraDataPtr extraData = tryGetExtraData(w, false);
|
||||
Q_ASSERT(extraData);
|
||||
if (!extraData) {
|
||||
return nullptr;
|
||||
}
|
||||
return extraData->titleBarItem;
|
||||
}
|
||||
|
||||
void FramelessQuickHelper::setTitleBarItem(QQuickItem *value)
|
||||
|
@ -747,12 +776,17 @@ void FramelessQuickHelper::setTitleBarItem(QQuickItem *value)
|
|||
if (!value) {
|
||||
return;
|
||||
}
|
||||
Q_D(FramelessQuickHelper);
|
||||
FramelessQuickHelperData *data = d->getWindowDataMutable();
|
||||
if (!data || (data->titleBarItem == value)) {
|
||||
const QQuickWindow * const w = window();
|
||||
if (!w) {
|
||||
return;
|
||||
}
|
||||
data->titleBarItem = value;
|
||||
const FramelessQuickHelperExtraDataPtr extraData = tryGetExtraData(w, false);
|
||||
Q_ASSERT(extraData);
|
||||
if (!extraData || (extraData->titleBarItem == value)) {
|
||||
return;
|
||||
}
|
||||
extraData->titleBarItem = value;
|
||||
Q_D(FramelessQuickHelper);
|
||||
d->emitSignalForAllInstances("titleBarItemChanged");
|
||||
}
|
||||
|
||||
|
@ -763,27 +797,31 @@ void FramelessQuickHelper::setSystemButton(QQuickItem *item, const QuickGlobal::
|
|||
if (!item || (buttonType == QuickGlobal::SystemButtonType::Unknown)) {
|
||||
return;
|
||||
}
|
||||
Q_D(FramelessQuickHelper);
|
||||
FramelessQuickHelperData *data = d->getWindowDataMutable();
|
||||
if (!data) {
|
||||
const QQuickWindow * const w = window();
|
||||
if (!w) {
|
||||
return;
|
||||
}
|
||||
const FramelessQuickHelperExtraDataPtr extraData = tryGetExtraData(w, false);
|
||||
Q_ASSERT(extraData);
|
||||
if (!extraData) {
|
||||
return;
|
||||
}
|
||||
switch (buttonType) {
|
||||
case QuickGlobal::SystemButtonType::WindowIcon:
|
||||
data->windowIconButton = item;
|
||||
extraData->windowIconButton = item;
|
||||
break;
|
||||
case QuickGlobal::SystemButtonType::Help:
|
||||
data->contextHelpButton = item;
|
||||
extraData->contextHelpButton = item;
|
||||
break;
|
||||
case QuickGlobal::SystemButtonType::Minimize:
|
||||
data->minimizeButton = item;
|
||||
extraData->minimizeButton = item;
|
||||
break;
|
||||
case QuickGlobal::SystemButtonType::Maximize:
|
||||
case QuickGlobal::SystemButtonType::Restore:
|
||||
data->maximizeButton = item;
|
||||
extraData->maximizeButton = item;
|
||||
break;
|
||||
case QuickGlobal::SystemButtonType::Close:
|
||||
data->closeButton = item;
|
||||
extraData->closeButton = item;
|
||||
break;
|
||||
case QuickGlobal::SystemButtonType::Unknown:
|
||||
Q_UNREACHABLE();
|
||||
|
@ -799,8 +837,7 @@ void FramelessQuickHelper::showSystemMenu(const QPoint &pos)
|
|||
const WId windowId = w->winId();
|
||||
const QPoint nativePos = Utils::toNativeGlobalPosition(w, pos);
|
||||
#ifdef Q_OS_WINDOWS
|
||||
Q_D(FramelessQuickHelper);
|
||||
std::ignore = Utils::showSystemMenu(windowId, nativePos, false, &d->getWindowData()->params);
|
||||
std::ignore = Utils::showSystemMenu(windowId, nativePos, false);
|
||||
#elif (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
Utils::openSystemMenu(windowId, nativePos);
|
||||
#else
|
||||
|
@ -832,11 +869,11 @@ void FramelessQuickHelper::windowStartSystemResize2(const Qt::Edges edges, const
|
|||
|
||||
void FramelessQuickHelper::moveWindowToDesktopCenter()
|
||||
{
|
||||
if (!window()) {
|
||||
const QQuickWindow * const w = window();
|
||||
if (!w) {
|
||||
return;
|
||||
}
|
||||
Q_D(FramelessQuickHelper);
|
||||
Utils::moveWindowToDesktopCenter(&d->getWindowData()->params, true);
|
||||
std::ignore = Utils::moveWindowToDesktopCenter(w->winId(), true);
|
||||
}
|
||||
|
||||
void FramelessQuickHelper::bringWindowToFront()
|
||||
|
@ -912,6 +949,7 @@ bool FramelessQuickHelper::isBlurBehindWindowEnabled() const
|
|||
|
||||
void FramelessQuickHelper::setBlurBehindWindowEnabled(const bool value)
|
||||
{
|
||||
#if (!defined(Q_OS_WINDOWS) || FRAMELESSHELPER_CONFIG(native_impl))
|
||||
QQuickWindow * const w = window();
|
||||
if (!w) {
|
||||
return;
|
||||
|
@ -948,6 +986,9 @@ void FramelessQuickHelper::setBlurBehindWindowEnabled(const bool value)
|
|||
#endif
|
||||
d->emitSignalForAllInstances("blurBehindWindowEnabledChanged");
|
||||
}
|
||||
#else // Windows && !native_impl
|
||||
Q_UNUSED(value);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FramelessQuickHelper::isReady() const
|
||||
|
|
|
@ -102,7 +102,7 @@ if(WIN32 AND NOT FRAMELESSHELPER_BUILD_STATIC)
|
|||
COPYRIGHT "MIT License"
|
||||
ORIGINAL_FILENAME "${SUB_MODULE_FULL_NAME}.dll"
|
||||
PRODUCT "${PROJECT_NAME}"
|
||||
COMMENTS "Built from commit ${PROJECT_VERSION_COMMIT} on ${PROJECT_COMPILE_DATETIME} (UTC)."
|
||||
COMMENTS "Who don't love Raiden Shogun ?"
|
||||
LIBRARY
|
||||
)
|
||||
endif()
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "widgetssharedhelper_p.h"
|
||||
#include <FramelessHelper/Core/framelessmanager.h>
|
||||
#include <FramelessHelper/Core/utils.h>
|
||||
#include <FramelessHelper/Core/private/framelessmanager_p.h>
|
||||
#include <FramelessHelper/Core/private/framelessconfig_p.h>
|
||||
#include <FramelessHelper/Core/private/framelesshelpercore_global_p.h>
|
||||
#include <QtCore/qhash.h>
|
||||
|
@ -71,10 +72,8 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
|
|||
|
||||
using namespace Global;
|
||||
|
||||
struct FramelessWidgetsHelperData
|
||||
struct FramelessWidgetsHelperExtraData : public FramelessExtraData
|
||||
{
|
||||
bool ready = false;
|
||||
SystemParameters params = {};
|
||||
QPointer<QWidget> titleBarWidget = nullptr;
|
||||
QList<QPointer<QWidget>> hitTestVisibleWidgets = {};
|
||||
QPointer<QWidget> windowIconButton = nullptr;
|
||||
|
@ -83,13 +82,54 @@ struct FramelessWidgetsHelperData
|
|||
QPointer<QWidget> maximizeButton = nullptr;
|
||||
QPointer<QWidget> closeButton = nullptr;
|
||||
QList<QRect> hitTestVisibleRects = {};
|
||||
|
||||
FramelessWidgetsHelperExtraData();
|
||||
~FramelessWidgetsHelperExtraData() override;
|
||||
|
||||
[[nodiscard]] static FramelessExtraDataPtr create();
|
||||
};
|
||||
using FramelessWidgetsHelperExtraDataPtr = std::shared_ptr<FramelessWidgetsHelperExtraData>;
|
||||
|
||||
using FramelessWidgetsHelperInternal = QHash<WId, FramelessWidgetsHelperData>;
|
||||
FramelessWidgetsHelperExtraData::FramelessWidgetsHelperExtraData() = default;
|
||||
|
||||
Q_GLOBAL_STATIC(FramelessWidgetsHelperInternal, g_framelessWidgetsHelperData)
|
||||
FramelessWidgetsHelperExtraData::~FramelessWidgetsHelperExtraData() = default;
|
||||
|
||||
[[nodiscard]] static inline bool isWidgetFixedSize(const QWidget * const widget)
|
||||
FramelessExtraDataPtr FramelessWidgetsHelperExtraData::create()
|
||||
{
|
||||
return std::make_shared<FramelessWidgetsHelperExtraData>();
|
||||
}
|
||||
|
||||
[[nodiscard]] static inline FramelessWidgetsHelperExtraDataPtr tryGetExtraData(const FramelessDataPtr &data, const bool create)
|
||||
{
|
||||
Q_ASSERT(data);
|
||||
if (!data) {
|
||||
return nullptr;
|
||||
}
|
||||
auto it = data->extraData.find(ExtraDataType::FramelessWidgetsHelper);
|
||||
if (it == data->extraData.end()) {
|
||||
if (create) {
|
||||
it = data->extraData.insert(ExtraDataType::FramelessWidgetsHelper, FramelessWidgetsHelperExtraData::create());
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return std::dynamic_pointer_cast<FramelessWidgetsHelperExtraData>(it.value());
|
||||
}
|
||||
|
||||
[[nodiscard]] static inline FramelessWidgetsHelperExtraDataPtr tryGetExtraData(const QWidget *window, const bool create)
|
||||
{
|
||||
Q_ASSERT(window);
|
||||
if (!window) {
|
||||
return nullptr;
|
||||
}
|
||||
const FramelessDataPtr data = FramelessManagerPrivate::getData(window);
|
||||
if (!data) {
|
||||
return nullptr;
|
||||
}
|
||||
return tryGetExtraData(data, create);
|
||||
}
|
||||
|
||||
[[nodiscard]] static inline bool isWidgetFixedSize(const QWidget *widget)
|
||||
{
|
||||
Q_ASSERT(widget);
|
||||
if (!widget) {
|
||||
|
@ -114,7 +154,7 @@ Q_GLOBAL_STATIC(FramelessWidgetsHelperInternal, g_framelessWidgetsHelperData)
|
|||
return false;
|
||||
}
|
||||
|
||||
static inline void forceWidgetRepaint(QWidget * const widget)
|
||||
static inline void forceWidgetRepaint(QWidget *widget)
|
||||
{
|
||||
Q_ASSERT(widget);
|
||||
if (!widget) {
|
||||
|
@ -360,7 +400,7 @@ void FramelessWidgetsHelperPrivate::setReadyWaitTime(const quint32 time)
|
|||
|
||||
void FramelessWidgetsHelperPrivate::attach()
|
||||
{
|
||||
QWidget * const tlw = findTopLevelWindow();
|
||||
QWidget *tlw = findTopLevelWindow();
|
||||
Q_ASSERT(tlw);
|
||||
if (!tlw) {
|
||||
return;
|
||||
|
@ -377,69 +417,72 @@ void FramelessWidgetsHelperPrivate::attach()
|
|||
window->setAttribute(Qt::WA_NativeWindow);
|
||||
}
|
||||
|
||||
FramelessWidgetsHelperData * const data = getWindowDataMutable();
|
||||
if (!data || data->ready) {
|
||||
const WId windowId = window->winId();
|
||||
const FramelessDataPtr data = FramelessManagerPrivate::createData(window, windowId);
|
||||
Q_ASSERT(data);
|
||||
if (!data || data->frameless) {
|
||||
return;
|
||||
}
|
||||
|
||||
Q_Q(FramelessWidgetsHelper);
|
||||
|
||||
SystemParameters params = {};
|
||||
params.getWindowId = [this]() -> WId { return window->winId(); };
|
||||
params.getWindowFlags = [this]() -> Qt::WindowFlags { return window->windowFlags(); };
|
||||
params.setWindowFlags = [this](const Qt::WindowFlags flags) -> void { window->setWindowFlags(flags); };
|
||||
params.getWindowSize = [this]() -> QSize { return window->size(); };
|
||||
params.setWindowSize = [this](const QSize &size) -> void { window->resize(size); };
|
||||
params.getWindowPosition = [this]() -> QPoint { return window->pos(); };
|
||||
params.setWindowPosition = [this](const QPoint &pos) -> void { window->move(pos); };
|
||||
params.getWindowScreen = [this]() -> QScreen * {
|
||||
if (!data->callbacks) {
|
||||
data->callbacks = FramelessCallbacks::create();
|
||||
data->callbacks->getWindowId = [this]() -> WId { return window->winId(); };
|
||||
data->callbacks->getWindowFlags = [this]() -> Qt::WindowFlags { return window->windowFlags(); };
|
||||
data->callbacks->setWindowFlags = [this](const Qt::WindowFlags flags) -> void { window->setWindowFlags(flags); };
|
||||
data->callbacks->getWindowSize = [this]() -> QSize { return window->size(); };
|
||||
data->callbacks->setWindowSize = [this](const QSize &size) -> void { window->resize(size); };
|
||||
data->callbacks->getWindowPosition = [this]() -> QPoint { return window->pos(); };
|
||||
data->callbacks->setWindowPosition = [this](const QPoint &pos) -> void { window->move(pos); };
|
||||
data->callbacks->getWindowScreen = [this]() -> QScreen * {
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
return window->screen();
|
||||
return window->screen();
|
||||
#else
|
||||
return window->windowHandle()->screen();
|
||||
return window->windowHandle()->screen();
|
||||
#endif
|
||||
};
|
||||
params.isWindowFixedSize = [q]() -> bool { return q->isWindowFixedSize(); };
|
||||
params.setWindowFixedSize = [q](const bool value) -> void { q->setWindowFixedSize(value); };
|
||||
params.getWindowState = [this]() -> Qt::WindowState { return Utils::windowStatesToWindowState(window->windowState()); };
|
||||
params.setWindowState = [this](const Qt::WindowState state) -> void { window->setWindowState(state); };
|
||||
params.getWindowHandle = [this]() -> QWindow * { return window->windowHandle(); };
|
||||
params.windowToScreen = [this](const QPoint &pos) -> QPoint { return window->mapToGlobal(pos); };
|
||||
params.screenToWindow = [this](const QPoint &pos) -> QPoint { return window->mapFromGlobal(pos); };
|
||||
params.isInsideSystemButtons = [this](const QPoint &pos, SystemButtonType *button) -> bool { return isInSystemButtons(pos, button); };
|
||||
params.isInsideTitleBarDraggableArea = [this](const QPoint &pos) -> bool { return isInTitleBarDraggableArea(pos); };
|
||||
params.getWindowDevicePixelRatio = [this]() -> qreal { return window->devicePixelRatioF(); };
|
||||
params.setSystemButtonState = [this](const SystemButtonType button, const ButtonState state) -> void { setSystemButtonState(button, state); };
|
||||
params.shouldIgnoreMouseEvents = [this](const QPoint &pos) -> bool { return shouldIgnoreMouseEvents(pos); };
|
||||
params.showSystemMenu = [q](const QPoint &pos) -> void { q->showSystemMenu(pos); };
|
||||
params.setProperty = [this](const char *name, const QVariant &value) -> void { setProperty(name, value); };
|
||||
params.getProperty = [this](const char *name, const QVariant &defaultValue) -> QVariant { return getProperty(name, defaultValue); };
|
||||
params.setCursor = [this](const QCursor &cursor) -> void { window->setCursor(cursor); };
|
||||
params.unsetCursor = [this]() -> void { window->unsetCursor(); };
|
||||
params.getWidgetHandle = [this]() -> QObject * { return window; };
|
||||
params.forceChildrenRepaint = [this](const int delay) -> void { repaintAllChildren(delay); };
|
||||
params.resetQtGrabbedControl = []() -> bool {
|
||||
if (qt_button_down) {
|
||||
static constexpr const auto invalidPos = QPoint{ -99999, -99999 };
|
||||
const auto event = std::make_unique<QMouseEvent>(
|
||||
QEvent::MouseButtonRelease,
|
||||
invalidPos,
|
||||
invalidPos,
|
||||
invalidPos,
|
||||
Qt::LeftButton,
|
||||
QGuiApplication::mouseButtons() ^ Qt::LeftButton,
|
||||
QGuiApplication::keyboardModifiers());
|
||||
QApplication::sendEvent(qt_button_down, event.get());
|
||||
qt_button_down = nullptr;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
};
|
||||
data->callbacks->isWindowFixedSize = [q]() -> bool { return q->isWindowFixedSize(); };
|
||||
data->callbacks->setWindowFixedSize = [q](const bool value) -> void { q->setWindowFixedSize(value); };
|
||||
data->callbacks->getWindowState = [this]() -> Qt::WindowState { return Utils::windowStatesToWindowState(window->windowState()); };
|
||||
data->callbacks->setWindowState = [this](const Qt::WindowState state) -> void { window->setWindowState(state); };
|
||||
data->callbacks->getWindowHandle = [this]() -> QWindow * { return window->windowHandle(); };
|
||||
data->callbacks->windowToScreen = [this](const QPoint &pos) -> QPoint { return window->mapToGlobal(pos); };
|
||||
data->callbacks->screenToWindow = [this](const QPoint &pos) -> QPoint { return window->mapFromGlobal(pos); };
|
||||
data->callbacks->isInsideSystemButtons = [this](const QPoint &pos, SystemButtonType *button) -> bool { return isInSystemButtons(pos, button); };
|
||||
data->callbacks->isInsideTitleBarDraggableArea = [this](const QPoint &pos) -> bool { return isInTitleBarDraggableArea(pos); };
|
||||
data->callbacks->getWindowDevicePixelRatio = [this]() -> qreal { return window->devicePixelRatioF(); };
|
||||
data->callbacks->setSystemButtonState = [this](const SystemButtonType button, const ButtonState state) -> void { setSystemButtonState(button, state); };
|
||||
data->callbacks->shouldIgnoreMouseEvents = [this](const QPoint &pos) -> bool { return shouldIgnoreMouseEvents(pos); };
|
||||
data->callbacks->showSystemMenu = [q](const QPoint &pos) -> void { q->showSystemMenu(pos); };
|
||||
data->callbacks->setProperty = [this](const char *name, const QVariant &value) -> void { setProperty(name, value); };
|
||||
data->callbacks->getProperty = [this](const char *name, const QVariant &defaultValue) -> QVariant { return getProperty(name, defaultValue); };
|
||||
data->callbacks->setCursor = [this](const QCursor &cursor) -> void { window->setCursor(cursor); };
|
||||
data->callbacks->unsetCursor = [this]() -> void { window->unsetCursor(); };
|
||||
data->callbacks->getWidgetHandle = [this]() -> QObject * { return window; };
|
||||
data->callbacks->forceChildrenRepaint = [this](const int delay) -> void { repaintAllChildren(delay); };
|
||||
data->callbacks->resetQtGrabbedControl = []() -> bool {
|
||||
if (qt_button_down) {
|
||||
static constexpr const auto invalidPos = QPoint{ -99999, -99999 };
|
||||
const auto event = new QMouseEvent(
|
||||
QEvent::MouseButtonRelease,
|
||||
invalidPos,
|
||||
invalidPos,
|
||||
invalidPos,
|
||||
Qt::LeftButton,
|
||||
QGuiApplication::mouseButtons() ^ Qt::LeftButton,
|
||||
QGuiApplication::keyboardModifiers());
|
||||
QApplication::postEvent(qt_button_down, event);
|
||||
qt_button_down = nullptr;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
FramelessManager::instance()->addWindow(¶ms);
|
||||
std::ignore = tryGetExtraData(data, true);
|
||||
|
||||
data->params = params;
|
||||
data->ready = true;
|
||||
std::ignore = FramelessManager::instance()->addWindow(window, windowId);
|
||||
|
||||
// We have to wait for a little time before moving the top level window
|
||||
// , because the platform window may not finish initializing by the time
|
||||
|
@ -464,13 +507,7 @@ void FramelessWidgetsHelperPrivate::detach()
|
|||
if (!window) {
|
||||
return;
|
||||
}
|
||||
const WId windowId = window->winId();
|
||||
const auto it = g_framelessWidgetsHelperData()->constFind(windowId);
|
||||
if (it == g_framelessWidgetsHelperData()->constEnd()) {
|
||||
return;
|
||||
}
|
||||
g_framelessWidgetsHelperData()->erase(it);
|
||||
FramelessManager::instance()->removeWindow(windowId);
|
||||
std::ignore = FramelessManager::instance()->removeWindow(window);
|
||||
window = nullptr;
|
||||
emitSignalForAllInstances("windowChanged");
|
||||
}
|
||||
|
@ -488,34 +525,6 @@ QWidget *FramelessWidgetsHelperPrivate::findTopLevelWindow() const
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
const FramelessWidgetsHelperData *FramelessWidgetsHelperPrivate::getWindowData() const
|
||||
{
|
||||
//Q_ASSERT(window);
|
||||
if (!window) {
|
||||
return nullptr;
|
||||
}
|
||||
const WId windowId = window->winId();
|
||||
auto it = g_framelessWidgetsHelperData()->find(windowId);
|
||||
if (it == g_framelessWidgetsHelperData()->end()) {
|
||||
it = g_framelessWidgetsHelperData()->insert(windowId, {});
|
||||
}
|
||||
return &it.value();
|
||||
}
|
||||
|
||||
FramelessWidgetsHelperData *FramelessWidgetsHelperPrivate::getWindowDataMutable() const
|
||||
{
|
||||
//Q_ASSERT(window);
|
||||
if (!window) {
|
||||
return nullptr;
|
||||
}
|
||||
const WId windowId = window->winId();
|
||||
auto it = g_framelessWidgetsHelperData()->find(windowId);
|
||||
if (it == g_framelessWidgetsHelperData()->end()) {
|
||||
it = g_framelessWidgetsHelperData()->insert(windowId, {});
|
||||
}
|
||||
return &it.value();
|
||||
}
|
||||
|
||||
QRect FramelessWidgetsHelperPrivate::mapWidgetGeometryToScene(const QWidget * const widget) const
|
||||
{
|
||||
Q_ASSERT(widget);
|
||||
|
@ -536,37 +545,41 @@ bool FramelessWidgetsHelperPrivate::isInSystemButtons(const QPoint &pos, SystemB
|
|||
if (!button) {
|
||||
return false;
|
||||
}
|
||||
const FramelessWidgetsHelperData *data = getWindowData();
|
||||
if (!data) {
|
||||
if (!window) {
|
||||
return false;
|
||||
}
|
||||
const FramelessWidgetsHelperExtraDataPtr extraData = tryGetExtraData(window, false);
|
||||
Q_ASSERT(extraData);
|
||||
if (!extraData) {
|
||||
return false;
|
||||
}
|
||||
*button = SystemButtonType::Unknown;
|
||||
if (data->windowIconButton && data->windowIconButton->isVisible() && data->windowIconButton->isEnabled()) {
|
||||
if (mapWidgetGeometryToScene(data->windowIconButton).contains(pos)) {
|
||||
if (extraData->windowIconButton && extraData->windowIconButton->isVisible() && extraData->windowIconButton->isEnabled()) {
|
||||
if (mapWidgetGeometryToScene(extraData->windowIconButton).contains(pos)) {
|
||||
*button = SystemButtonType::WindowIcon;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (data->contextHelpButton && data->contextHelpButton->isVisible() && data->contextHelpButton->isEnabled()) {
|
||||
if (mapWidgetGeometryToScene(data->contextHelpButton).contains(pos)) {
|
||||
if (extraData->contextHelpButton && extraData->contextHelpButton->isVisible() && extraData->contextHelpButton->isEnabled()) {
|
||||
if (mapWidgetGeometryToScene(extraData->contextHelpButton).contains(pos)) {
|
||||
*button = SystemButtonType::Help;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (data->minimizeButton && data->minimizeButton->isVisible() && data->minimizeButton->isEnabled()) {
|
||||
if (mapWidgetGeometryToScene(data->minimizeButton).contains(pos)) {
|
||||
if (extraData->minimizeButton && extraData->minimizeButton->isVisible() && extraData->minimizeButton->isEnabled()) {
|
||||
if (mapWidgetGeometryToScene(extraData->minimizeButton).contains(pos)) {
|
||||
*button = SystemButtonType::Minimize;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (data->maximizeButton && data->maximizeButton->isVisible() && data->maximizeButton->isEnabled()) {
|
||||
if (mapWidgetGeometryToScene(data->maximizeButton).contains(pos)) {
|
||||
if (extraData->maximizeButton && extraData->maximizeButton->isVisible() && extraData->maximizeButton->isEnabled()) {
|
||||
if (mapWidgetGeometryToScene(extraData->maximizeButton).contains(pos)) {
|
||||
*button = SystemButtonType::Maximize;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (data->closeButton && data->closeButton->isVisible() && data->closeButton->isEnabled()) {
|
||||
if (mapWidgetGeometryToScene(data->closeButton).contains(pos)) {
|
||||
if (extraData->closeButton && extraData->closeButton->isVisible() && extraData->closeButton->isEnabled()) {
|
||||
if (mapWidgetGeometryToScene(extraData->closeButton).contains(pos)) {
|
||||
*button = SystemButtonType::Close;
|
||||
return true;
|
||||
}
|
||||
|
@ -576,25 +589,26 @@ bool FramelessWidgetsHelperPrivate::isInSystemButtons(const QPoint &pos, SystemB
|
|||
|
||||
bool FramelessWidgetsHelperPrivate::isInTitleBarDraggableArea(const QPoint &pos) const
|
||||
{
|
||||
const FramelessWidgetsHelperData *data = getWindowData();
|
||||
if (!data) {
|
||||
return false;
|
||||
}
|
||||
if (!data->titleBarWidget) {
|
||||
// There's no title bar at all, the mouse will always be in the client area.
|
||||
return false;
|
||||
}
|
||||
if (!data->titleBarWidget->isVisible() || !data->titleBarWidget->isEnabled()) {
|
||||
// The title bar is hidden or disabled for some reason, treat it as there's no title bar.
|
||||
return false;
|
||||
}
|
||||
if (!window) {
|
||||
// The FramelessWidgetsHelper object has not been attached to a specific window yet,
|
||||
// so we assume there's no title bar.
|
||||
return false;
|
||||
}
|
||||
const FramelessWidgetsHelperExtraDataPtr extraData = tryGetExtraData(window, false);
|
||||
Q_ASSERT(extraData);
|
||||
if (!extraData) {
|
||||
return false;
|
||||
}
|
||||
if (!extraData->titleBarWidget) {
|
||||
// There's no title bar at all, the mouse will always be in the client area.
|
||||
return false;
|
||||
}
|
||||
if (!extraData->titleBarWidget->isVisible() || !extraData->titleBarWidget->isEnabled()) {
|
||||
// The title bar is hidden or disabled for some reason, treat it as there's no title bar.
|
||||
return false;
|
||||
}
|
||||
const QRect windowRect = {QPoint(0, 0), window->size()};
|
||||
const QRect titleBarRect = mapWidgetGeometryToScene(data->titleBarWidget);
|
||||
const QRect titleBarRect = mapWidgetGeometryToScene(extraData->titleBarWidget);
|
||||
if (!titleBarRect.intersects(windowRect)) {
|
||||
// The title bar is totally outside of the window for some reason,
|
||||
// also treat it as there's no title bar.
|
||||
|
@ -602,24 +616,24 @@ bool FramelessWidgetsHelperPrivate::isInTitleBarDraggableArea(const QPoint &pos)
|
|||
}
|
||||
QRegion region = titleBarRect;
|
||||
const auto systemButtons = {
|
||||
data->windowIconButton, data->contextHelpButton,
|
||||
data->minimizeButton, data->maximizeButton,
|
||||
data->closeButton
|
||||
extraData->windowIconButton, extraData->contextHelpButton,
|
||||
extraData->minimizeButton, extraData->maximizeButton,
|
||||
extraData->closeButton
|
||||
};
|
||||
for (auto &&button : std::as_const(systemButtons)) {
|
||||
if (button && button->isVisible() && button->isEnabled()) {
|
||||
region -= mapWidgetGeometryToScene(button);
|
||||
}
|
||||
}
|
||||
if (!data->hitTestVisibleWidgets.isEmpty()) {
|
||||
for (auto &&widget : std::as_const(data->hitTestVisibleWidgets)) {
|
||||
if (!extraData->hitTestVisibleWidgets.isEmpty()) {
|
||||
for (auto &&widget : std::as_const(extraData->hitTestVisibleWidgets)) {
|
||||
if (widget && widget->isVisible() && widget->isEnabled()) {
|
||||
region -= mapWidgetGeometryToScene(widget);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!data->hitTestVisibleRects.isEmpty()) {
|
||||
for (auto &&rect : std::as_const(data->hitTestVisibleRects)) {
|
||||
if (!extraData->hitTestVisibleRects.isEmpty()) {
|
||||
for (auto &&rect : std::as_const(extraData->hitTestVisibleRects)) {
|
||||
if (rect.isValid()) {
|
||||
region -= rect;
|
||||
}
|
||||
|
@ -660,7 +674,7 @@ void FramelessWidgetsHelper::moveWindowToDesktopCenter()
|
|||
if (!d->window) {
|
||||
return;
|
||||
}
|
||||
Utils::moveWindowToDesktopCenter(&d->getWindowData()->params, true);
|
||||
std::ignore = Utils::moveWindowToDesktopCenter(d->window->winId(), true);
|
||||
}
|
||||
|
||||
void FramelessWidgetsHelper::bringWindowToFront()
|
||||
|
@ -692,7 +706,7 @@ void FramelessWidgetsHelper::showSystemMenu(const QPoint &pos)
|
|||
const WId windowId = d->window->winId();
|
||||
const QPoint nativePos = Utils::toNativeGlobalPosition(d->window->windowHandle(), pos);
|
||||
#ifdef Q_OS_WINDOWS
|
||||
std::ignore = Utils::showSystemMenu(windowId, nativePos, false, &d->getWindowData()->params);
|
||||
std::ignore = Utils::showSystemMenu(windowId, nativePos, false);
|
||||
#elif (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
Utils::openSystemMenu(windowId, nativePos);
|
||||
#else
|
||||
|
@ -730,26 +744,30 @@ void FramelessWidgetsHelper::setSystemButton(QWidget *widget, const SystemButton
|
|||
return;
|
||||
}
|
||||
Q_D(FramelessWidgetsHelper);
|
||||
FramelessWidgetsHelperData *data = d->getWindowDataMutable();
|
||||
if (!data) {
|
||||
if (!d->window) {
|
||||
return;
|
||||
}
|
||||
const FramelessWidgetsHelperExtraDataPtr extraData = tryGetExtraData(d->window, false);
|
||||
Q_ASSERT(extraData);
|
||||
if (!extraData) {
|
||||
return;
|
||||
}
|
||||
switch (buttonType) {
|
||||
case SystemButtonType::WindowIcon:
|
||||
data->windowIconButton = widget;
|
||||
extraData->windowIconButton = widget;
|
||||
break;
|
||||
case SystemButtonType::Help:
|
||||
data->contextHelpButton = widget;
|
||||
extraData->contextHelpButton = widget;
|
||||
break;
|
||||
case SystemButtonType::Minimize:
|
||||
data->minimizeButton = widget;
|
||||
extraData->minimizeButton = widget;
|
||||
break;
|
||||
case SystemButtonType::Maximize:
|
||||
case SystemButtonType::Restore:
|
||||
data->maximizeButton = widget;
|
||||
extraData->maximizeButton = widget;
|
||||
break;
|
||||
case SystemButtonType::Close:
|
||||
data->closeButton = widget;
|
||||
extraData->closeButton = widget;
|
||||
break;
|
||||
case SystemButtonType::Unknown:
|
||||
Q_UNREACHABLE();
|
||||
|
@ -835,6 +853,7 @@ bool FramelessWidgetsHelper::isBlurBehindWindowEnabled() const
|
|||
|
||||
void FramelessWidgetsHelper::setBlurBehindWindowEnabled(const bool enable)
|
||||
{
|
||||
#if (!defined(Q_OS_WINDOWS) || FRAMELESSHELPER_CONFIG(native_impl))
|
||||
Q_D(FramelessWidgetsHelper);
|
||||
if (!d->window) {
|
||||
return;
|
||||
|
@ -866,6 +885,9 @@ void FramelessWidgetsHelper::setBlurBehindWindowEnabled(const bool enable)
|
|||
DEBUG << "Blur behind window is not supported on current platform.";
|
||||
}
|
||||
}
|
||||
#else // Windows && !native_impl
|
||||
Q_UNUSED(enable);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FramelessWidgetsHelper::isReady() const
|
||||
|
@ -895,8 +917,11 @@ void FramelessWidgetsHelper::waitForReady()
|
|||
bool FramelessWidgetsHelper::isContentExtendedIntoTitleBar() const
|
||||
{
|
||||
Q_D(const FramelessWidgetsHelper);
|
||||
const FramelessWidgetsHelperData *data = d->getWindowData();
|
||||
return (data ? data->ready : false);
|
||||
if (!d->window) {
|
||||
return false;
|
||||
}
|
||||
const FramelessDataPtr data = FramelessManagerPrivate::getData(d->window);
|
||||
return (data && data->frameless);
|
||||
}
|
||||
|
||||
void FramelessWidgetsHelper::setTitleBarWidget(QWidget *widget)
|
||||
|
@ -906,19 +931,30 @@ void FramelessWidgetsHelper::setTitleBarWidget(QWidget *widget)
|
|||
return;
|
||||
}
|
||||
Q_D(FramelessWidgetsHelper);
|
||||
FramelessWidgetsHelperData *data = d->getWindowDataMutable();
|
||||
if (!data || (data->titleBarWidget == widget)) {
|
||||
if (!d->window) {
|
||||
return;
|
||||
}
|
||||
data->titleBarWidget = widget;
|
||||
const FramelessWidgetsHelperExtraDataPtr extraData = tryGetExtraData(d->window, false);
|
||||
Q_ASSERT(extraData);
|
||||
if (!extraData || (extraData->titleBarWidget == widget)) {
|
||||
return;
|
||||
}
|
||||
extraData->titleBarWidget = widget;
|
||||
d->emitSignalForAllInstances("titleBarWidgetChanged");
|
||||
}
|
||||
|
||||
QWidget *FramelessWidgetsHelper::titleBarWidget() const
|
||||
{
|
||||
Q_D(const FramelessWidgetsHelper);
|
||||
const FramelessWidgetsHelperData *data = d->getWindowData();
|
||||
return (data ? data->titleBarWidget : nullptr);
|
||||
if (!d->window) {
|
||||
return nullptr;
|
||||
}
|
||||
const FramelessWidgetsHelperExtraDataPtr extraData = tryGetExtraData(d->window, false);
|
||||
Q_ASSERT(extraData);
|
||||
if (!extraData) {
|
||||
return nullptr;
|
||||
}
|
||||
return extraData->titleBarWidget;
|
||||
}
|
||||
|
||||
void FramelessWidgetsHelper::setHitTestVisible(QWidget *widget, const bool visible)
|
||||
|
@ -928,32 +964,40 @@ void FramelessWidgetsHelper::setHitTestVisible(QWidget *widget, const bool visib
|
|||
return;
|
||||
}
|
||||
Q_D(FramelessWidgetsHelper);
|
||||
FramelessWidgetsHelperData *data = d->getWindowDataMutable();
|
||||
if (!data) {
|
||||
if (!d->window) {
|
||||
return;
|
||||
}
|
||||
const FramelessWidgetsHelperExtraDataPtr extraData = tryGetExtraData(d->window, false);
|
||||
Q_ASSERT(extraData);
|
||||
if (!extraData) {
|
||||
return;
|
||||
}
|
||||
if (visible) {
|
||||
data->hitTestVisibleWidgets.append(widget);
|
||||
extraData->hitTestVisibleWidgets.append(widget);
|
||||
} else {
|
||||
data->hitTestVisibleWidgets.removeAll(widget);
|
||||
extraData->hitTestVisibleWidgets.removeAll(widget);
|
||||
}
|
||||
}
|
||||
|
||||
void FramelessWidgetsHelper::setHitTestVisible(const QRect &rect, const bool visible)
|
||||
{
|
||||
Q_ASSERT(rect.isValid());
|
||||
if (!rect.isValid()) {
|
||||
Q_ASSERT(Utils::isValidGeometry(rect));
|
||||
if (!Utils::isValidGeometry(rect)) {
|
||||
return;
|
||||
}
|
||||
Q_D(FramelessWidgetsHelper);
|
||||
FramelessWidgetsHelperData *data = d->getWindowDataMutable();
|
||||
if (!data) {
|
||||
if (!d->window) {
|
||||
return;
|
||||
}
|
||||
const FramelessWidgetsHelperExtraDataPtr extraData = tryGetExtraData(d->window, false);
|
||||
Q_ASSERT(extraData);
|
||||
if (!extraData) {
|
||||
return;
|
||||
}
|
||||
if (visible) {
|
||||
data->hitTestVisibleRects.append(rect);
|
||||
extraData->hitTestVisibleRects.append(rect);
|
||||
} else {
|
||||
data->hitTestVisibleRects.removeAll(rect);
|
||||
extraData->hitTestVisibleRects.removeAll(rect);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue