Compare commits

..

2 Commits

Author SHA1 Message Date
Zhao Yuhang 099da347e8 wip 2023-09-14 22:29:40 +08:00
Yuhang Zhao ae9c4ae5c8 wip 2023-09-14 17:58:50 +08:00
18 changed files with 320 additions and 412 deletions

View File

@ -120,28 +120,28 @@ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
endif()
set(FRAMELESSHELPER_LICENSE_HEADER "/*
* MIT License
*
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the \"Software\"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/")
* MIT License
*
* Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the \"Software\"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/")
set(__extra_flags "")
if(NOT FRAMELESSHELPER_BUILD_STATIC)

View File

@ -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

20
build/msvc2022.bat Normal file
View File

@ -0,0 +1,20 @@
@echo off
title Building FramelessHelper ...
setlocal
cls
call "%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat"
cd /d "%~dp0"
if exist cmake rd /s /q cmake
md cmake
cd cmake
md build
cd build
cmake -DCMAKE_PREFIX_PATH="C:\Qt\6.6.0\msvc2019_64" -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
endlocal
cd /d "%~dp0"
pause
exit /b 0

View File

@ -265,10 +265,6 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
#include "framelesshelper.version"
#ifndef __FRAMELESSHELPER__
# define __FRAMELESSHELPER__ __FRAMELESSHELPER_VERSION__
#endif // __FRAMELESSHELPER__
namespace Global
{

View File

@ -104,32 +104,26 @@ private:
};
using FramelessCallbacksPtr = FramelessCallbacks::PtrType;
struct FramelessExtraData
{
using PtrType = std::shared_ptr<FramelessExtraData>;
//[[nodiscard]] static PtrType create();
private:
Q_DISABLE_COPY_MOVE(FramelessExtraData)
};
using FramelessExtraDataPtr = FramelessExtraData::PtrType;
using FramelessExtraDataPtrs = QList<FramelessExtraDataPtr>;
using FramelessExtraDataHash = QHash<quint8, FramelessExtraDataPtr>;
struct FramelessData
{
bool frameless = false;
FramelessCallbacksPtr callbacks = nullptr;
FramelessExtraDataHash extraData = {};
struct {
void *ptr = nullptr;
using DeleterFunctionPrototype = void(*)(void*);
DeleterFunctionPrototype deleter = nullptr;
} extraData = {};
using PtrType = std::shared_ptr<FramelessData>;
[[nodiscard]] static PtrType create();
~FramelessData();
private:
Q_DISABLE_COPY_MOVE(FramelessData)
};
using FramelessDataPtr = FramelessData::PtrType;
using FramelessDataPtrs = QList<FramelessDataPtr>;
using FramelessDataHash = QHash<const QWindow *, FramelessDataPtr>;
template<typename T>

View File

@ -25,6 +25,9 @@
#pragma once
#include <FramelessHelper/Core/framelesshelpercore_global.h>
#if (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
# include <FramelessHelper/Core/framelesshelper_linux.h>
#endif // Q_OS_LINUX
#if (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
QT_BEGIN_NAMESPACE
@ -34,6 +37,8 @@ QT_END_NAMESPACE
FRAMELESSHELPER_BEGIN_NAMESPACE
struct SystemParameters;
namespace Utils
{

View File

@ -40,6 +40,7 @@ class QuickMicaMaterial;
class QuickWindowBorder;
#endif
class FramelessQuickHelper;
struct FramelessQuickHelperData;
class FRAMELESSHELPER_QUICK_API FramelessQuickHelperPrivate : public QObject
{
@ -82,6 +83,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;

View File

@ -7,6 +7,9 @@ CORE_PRIV_INC_DIR = $$CORE_PUB_INC_DIR/private
CORE_EXTRA_INC_DIR = $$PWD/inc/core
CORE_SRC_DIR = $$PWD/../src/core
DEFINES += \
FRAMELESSHELPER_CORE_STATIC
INCLUDEPATH += \
$$BASE_INC_DIR \
$$COMMON_INC_DIR \

View File

@ -22,14 +22,16 @@
* SOFTWARE.
*/
// Caution: This file is generated by CMake automatically during configure.
// WARNING!!! DO NOT EDIT THIS FILE MANUALLY!!!
// ALL YOUR MODIFICATIONS HERE WILL GET LOST AFTER RE-CONFIGURING!!!
// Generated automatically by CMake.
// WARNING! DO NOT EDIT THIS FILE MANUALLY!
// ALL CHANGES WILL BE LOST AFTER RE-CONFIGURING!
// Also please do not include this file directly,
// it's designed to be included by FramelessHelper's own headers.
#pragma once
#ifndef _FRAMELESSHELPER_CONFIG_INCLUDE_GUARD_
#define _FRAMELESSHELPER_CONFIG_INCLUDE_GUARD_
#ifndef _FRAMELESSHELPER_CONFIG_DEFINED_
#define _FRAMELESSHELPER_CONFIG_DEFINED_
#define FRAMELESSHELPER_FEATURE_static_build 1
#define FRAMELESSHELPER_FEATURE_widgets 1
@ -44,4 +46,4 @@
#define FRAMELESSHELPER_FEATURE_border_painter 1
#define FRAMELESSHELPER_FEATURE_system_button 1
#endif // _FRAMELESSHELPER_CONFIG_INCLUDE_GUARD_
#endif // _FRAMELESSHELPER_CONFIG_DEFINED_

View File

@ -22,38 +22,30 @@
* SOFTWARE.
*/
// Caution: This file is generated by CMake automatically during configure.
// WARNING!!! DO NOT EDIT THIS FILE MANUALLY!!!
// ALL YOUR MODIFICATIONS HERE WILL GET LOST AFTER RE-CONFIGURING!!!
// Generated automatically by QMake.
// WARNING! DO NOT EDIT THIS FILE MANUALLY!
// ALL CHANGES WILL BE LOST AFTER RE-CONFIGURING!
// Also please do not include this file directly,
// it's designed to be included by FramelessHelper's own headers.
#pragma once
#ifndef _FRAMELESSHELPER_VERSION_INCLUDE_GUARD_
#define _FRAMELESSHELPER_VERSION_INCLUDE_GUARD_
#ifndef _FRAMELESSHELPER_VERSION_DEFINED_
#define _FRAMELESSHELPER_VERSION_DEFINED_
[[maybe_unused]] inline constexpr const int FRAMELESSHELPER_VERSION_MAJOR = 2;
[[maybe_unused]] inline constexpr const int FRAMELESSHELPER_VERSION_MINOR = 5;
[[maybe_unused]] inline constexpr const int FRAMELESSHELPER_VERSION_PATCH = 0;
//[[maybe_unused]] inline constexpr const int FRAMELESSHELPER_VERSION_TWEAK = 0;
[[maybe_unused]] inline constexpr const char FRAMELESSHELPER_VERSION_STR[] = "2.5.0";
[[maybe_unused]] inline constexpr const char FRAMELESSHELPER_COMMIT_STR[] = "UNKNOWN";
[[maybe_unused]] inline constexpr const char FRAMELESSHELPER_COMPILE_DATETIME_STR[] = "UNKNOWN";
#define __FRAMELESSHELPER_VERSION_MAJOR__ 2
#define __FRAMELESSHELPER_VERSION_MINOR__ 5
#define __FRAMELESSHELPER_VERSION_PATCH__ 0
#define __FRAMELESSHELPER_VERSION_TWEAK__ 0
//#define __FRAMELESSHELPER_VERSION_TWEAK__ 0
#define __FRAMELESSHELPER_VERSION__ 0x02050000
#define __FRAMELESSHELPER__ 0x02050000
[[maybe_unused]] inline constexpr const unsigned long FRAMELESSHELPER_VERSION_MAJOR = 2;
[[maybe_unused]] inline constexpr const unsigned long FRAMELESSHELPER_VERSION_MINOR = 5;
[[maybe_unused]] inline constexpr const unsigned long FRAMELESSHELPER_VERSION_PATCH = 0;
[[maybe_unused]] inline constexpr const unsigned long FRAMELESSHELPER_VERSION_TWEAK = 0;
[[maybe_unused]] inline constexpr const unsigned long FRAMELESSHELPER_VERSION = 0x02050000;
[[maybe_unused]] inline constexpr const char FRAMELESSHELPER_VERSION_STR[] = "2.5.0";
[[maybe_unused]] inline constexpr const char FRAMELESSHELPER_COMMIT_HASH_STR[] = "UNKNOWN";
[[maybe_unused]] inline constexpr const char FRAMELESSHELPER_COMMIT_SUBJECT_STR[] = "UNKNOWN";
[[maybe_unused]] inline constexpr const char FRAMELESSHELPER_COMMIT_AUTHOR_STR[] = "UNKNOWN";
[[maybe_unused]] inline constexpr const char FRAMELESSHELPER_COMMIT_DATETIME_STR[] = "UNKNOWN";
[[maybe_unused]] inline constexpr const char FRAMELESSHELPER_COMMIT_BRANCH_STR[] = "UNKNOWN";
[[maybe_unused]] inline constexpr const char FRAMELESSHELPER_COMPILER_NAME_STR[] = "UNKNOWN";
[[maybe_unused]] inline constexpr const char FRAMELESSHELPER_COMPILER_VERSION_STR[] = "UNKNOWN";
[[maybe_unused]] inline constexpr const char FRAMELESSHELPER_COMPILER_VENDOR_STR[] = "UNKNOWN";
[[maybe_unused]] inline constexpr const char FRAMELESSHELPER_BUILD_DATETIME_STR[] = "UNKNOWN";
[[maybe_unused]] inline constexpr const char FRAMELESSHELPER_ARCHITECTURE_STR[] = "UNKNOWN";
[[maybe_unused]] inline constexpr const char FRAMELESSHELPER_CMAKE_VERSION_STR[] = "UNKNOWN";
[[maybe_unused]] inline constexpr const char FRAMELESSHELPER_CMAKE_GENERATOR_STR[] = "UNKNOWN";
#endif // _FRAMELESSHELPER_VERSION_INCLUDE_GUARD_
#endif // _FRAMELESSHELPER_VERSION_DEFINED_

View File

@ -9,6 +9,9 @@ QUICK_PUB_INC_DIR = $$COMMON_INC_DIR/Quick
QUICK_PRIV_INC_DIR = $$QUICK_PUB_INC_DIR/private
QUICK_SRC_DIR = $$PWD/../src/quick
DEFINES += \
FRAMELESSHELPER_QUICK_STATIC
INCLUDEPATH += \
$$BASE_INC_DIR \
$$COMMON_INC_DIR \

View File

@ -6,6 +6,9 @@ WIDGETS_PUB_INC_DIR = $$COMMON_INC_DIR/Widgets
WIDGETS_PRIV_INC_DIR = $$WIDGETS_PUB_INC_DIR/private
WIDGETS_SRC_DIR = $$PWD/../src/widgets
DEFINES += \
FRAMELESSHELPER_WIDGETS_STATIC
INCLUDEPATH += \
$$BASE_INC_DIR \
$$COMMON_INC_DIR \

View File

@ -56,7 +56,7 @@ struct FramelessConfigEntry
static constexpr const std::array<FramelessConfigEntry, static_cast<int>(Option::Last) + 1> FramelessOptionsTable =
{
//FramelessConfigEntry{ "FRAMELESSHELPER_USE_CROSS_PLATFORM_QT_IMPLEMENTATION", "Options/UseCrossPlatformQtImplementation" },
FramelessConfigEntry{ "FRAMELESSHELPER_USE_CROSS_PLATFORM_QT_IMPLEMENTATION", "Options/UseCrossPlatformQtImplementation" },
FramelessConfigEntry{ "FRAMELESSHELPER_FORCE_HIDE_WINDOW_FRAME_BORDER", "Options/ForceHideWindowFrameBorder" },
FramelessConfigEntry{ "FRAMELESSHELPER_FORCE_SHOW_WINDOW_FRAME_BORDER", "Options/ForceShowWindowFrameBorder" },
FramelessConfigEntry{ "FRAMELESSHELPER_DISABLE_WINDOWS_SNAP_LAYOUT", "Options/DisableWindowsSnapLayout" },
@ -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 has no effect now. It will be removed in a future version.";
WARNING << "Option::DisableWindowsSnapLayout is deprecated and will removed in a future version. It has not effect now.";
}
#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.";
}

View File

@ -114,21 +114,8 @@ struct FramelessDataWin : public FramelessData
QRect restoreGeometry = {};
#endif // (QT_VERSION < QT_VERSION_CHECK(6, 5, 1))
};
using FramelessDataWinPtr = std::shared_ptr<FramelessDataWin>;
[[nodiscard]] static inline FramelessDataWinPtr tryGetData(const QWindow *window)
{
Q_ASSERT(window);
if (!window) {
return nullptr;
}
const FramelessDataPtr data = FramelessManagerPrivate::getData(window);
Q_ASSERT(data);
if (!data) {
return nullptr;
}
return std::dynamic_pointer_cast<FramelessDataWin>(data);
}
#define GetFramelessDataWin(Window) std::dynamic_pointer_cast<FramelessDataWin>(FramelessManagerPrivate::getData(Window))
[[nodiscard]] FramelessDataPtr FramelessData::create()
{
@ -212,7 +199,7 @@ void FramelessHelperWin::addWindow(const QWindow *window)
if (!window) {
return;
}
const FramelessDataWinPtr data = tryGetData(window);
const auto data = GetFramelessDataWin(window);
Q_ASSERT(data);
if (!data || data->frameless) {
return;
@ -305,7 +292,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
return false;
}
const FramelessDataWinPtr data = tryGetData(window);
const auto data = GetFramelessDataWin(window);
Q_ASSERT(data);
if (!data || !data->frameless) {
return false;

View File

@ -119,20 +119,15 @@ FramelessCallbacksPtr FramelessCallbacks::create()
return std::make_shared<FramelessCallbacks>();
}
FramelessExtraDataPtr FramelessExtraData::create()
FramelessData::~FramelessData()
{
return std::make_shared<FramelessExtraData>();
}
FramelessExtraData::~FramelessExtraData()
{
if (ptr) {
Q_ASSERT(deleter);
if (deleter) {
deleter(ptr);
deleter = nullptr;
if (extraData.ptr) {
Q_ASSERT(extraData.deleter);
if (extraData.deleter) {
extraData.deleter(extraData.ptr);
extraData.deleter = nullptr;
}
ptr = nullptr;
extraData.ptr = nullptr;
}
}

View File

@ -194,48 +194,19 @@ FRAMELESSHELPER_STRING_CONSTANT(ScreenToClient)
FRAMELESSHELPER_STRING_CONSTANT(DwmFlush)
FRAMELESSHELPER_STRING_CONSTANT(GetCursorPos)
static constexpr const auto UTILS_WIN_EXTRA_DATA_ID = quint8(1);
struct UtilsWinExtraData : public FramelessExtraData
struct FramelessDataExtra
{
WNDPROC qtWindowProc = nullptr;
bool windowProcHooked = false;
bool mica = false;
[[nodiscard]] static FramelessExtraDataPtr create();
};
using UtilsWinExtraDataPtr = std::shared_ptr<UtilsWinExtraData>;
FramelessExtraDataPtr UtilsWinExtraData::create()
static inline void FramelessDataExtraDeleter(void *data)
{
return std::make_shared<UtilsWinExtraData>();
}
template<typename T>
[[nodiscard]] static inline UtilsWinExtraDataPtr tryGetExtraData(const T t, const bool create)
{
FramelessDataPtr data = nullptr;
using T2 = std::remove_cvref_t<T>;
if constexpr (std::is_same_v<T2, QWindow *>) {
data = FramelessManagerPrivate::getData(t);
} else if constexpr (std::is_same_v<T2, FramelessDataPtr>) {
data = t;
} else {
Q_UNREACHABLE_RETURN(nullptr);
}
Q_ASSERT(data);
if (!data) {
return nullptr;
if (data) {
delete static_cast<FramelessDataExtra *>(data);
}
auto it = data->extraData.find(UTILS_WIN_EXTRA_DATA_ID);
if (it == data->extraData.end()) {
if (create) {
it = data->extraData.insert(UTILS_WIN_EXTRA_DATA_ID, UtilsWinExtraData::create());
} else {
return nullptr;
}
}
return std::dynamic_pointer_cast<UtilsWinExtraData>(it.value());
}
struct Win32Message
@ -918,7 +889,7 @@ static constexpr const std::array<Win32Message, 333> g_win32MessageMap =
if (!data) {
return ::DefWindowProcW(hWnd, uMsg, wParam, lParam);
}
const UtilsWinExtraDataPtr extraData = tryGetExtraData(data, false);
const auto extraData = static_cast<FramelessDataExtra *>(data->extraData.ptr);
Q_ASSERT(extraData);
if (!extraData) {
return ::DefWindowProcW(hWnd, uMsg, wParam, lParam);
@ -1130,7 +1101,12 @@ bool Utils::updateWindowFrameMargins(const QWindow *window, const bool reset)
if (!isDwmCompositionEnabled()) {
return false;
}
const UtilsWinExtraDataPtr extraData = tryGetExtraData(window, false);
const FramelessDataPtr data = FramelessManagerPrivate::getData(window);
Q_ASSERT(data);
if (!data) {
return false;
}
const auto extraData = static_cast<FramelessDataExtra *>(data->extraData.ptr);
Q_ASSERT(extraData);
if (!extraData) {
return false;
@ -1956,7 +1932,18 @@ bool Utils::installWindowProcHook(const QWindow *window)
if (!window) {
return false;
}
const UtilsWinExtraDataPtr extraData = tryGetExtraData(window, true);
const FramelessDataPtr data = FramelessManagerPrivate::getData(window);
Q_ASSERT(data);
if (!data) {
return false;
}
if (!data->extraData.ptr) {
data->extraData.ptr = new FramelessDataExtra();
}
if (!data->extraData.deleter) {
data->extraData.deleter = FramelessDataExtraDeleter;
}
const auto extraData = static_cast<FramelessDataExtra *>(data->extraData.ptr);
const auto hwnd = qWindowId<HWND>(window);
if (!extraData->qtWindowProc) {
::SetLastError(ERROR_SUCCESS);
@ -1985,7 +1972,12 @@ bool Utils::uninstallWindowProcHook(const QWindow *window)
if (!window) {
return false;
}
const UtilsWinExtraDataPtr extraData = tryGetExtraData(window, false);
const FramelessDataPtr data = FramelessManagerPrivate::getData(window);
Q_ASSERT(data);
if (!data) {
return false;
}
const auto extraData = static_cast<FramelessDataExtra *>(data->extraData.ptr);
if (!extraData || !extraData->windowProcHooked) {
return false;
}
@ -2257,7 +2249,12 @@ bool Utils::setBlurBehindWindowEnabled(const QWindow *window, const BlurMode mod
if (!window) {
return false;
}
const UtilsWinExtraDataPtr extraData = tryGetExtraData(window, false);
const FramelessDataPtr data = FramelessManagerPrivate::getData(window);
Q_ASSERT(data);
if (!data) {
return false;
}
const auto extraData = static_cast<FramelessDataExtra *>(data->extraData.ptr);
Q_ASSERT(extraData);
if (!extraData) {
return false;
@ -3016,8 +3013,12 @@ bool Utils::removeMicaWindow(const QWindow *window)
if (!window) {
return false;
}
const UtilsWinExtraDataPtr extraData = tryGetExtraData(window, false);
Q_ASSERT(extraData);
const FramelessDataPtr data = FramelessManagerPrivate::getData(window);
Q_ASSERT(data);
if (!data) {
return false;
}
const auto extraData = static_cast<FramelessDataExtra *>(data->extraData.ptr);
if (!extraData || !extraData->mica) {
return false;
}

View File

@ -32,7 +32,6 @@
#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
@ -73,10 +72,10 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
using namespace Global;
static constexpr const auto FRAMELESS_QUICK_HELPER_EXTRA_DATA_ID = quint8(3);
struct FramelessQuickHelperExtraData : public FramelessExtraData
struct FramelessQuickHelperData
{
bool ready = false;
SystemParameters params = {};
QPointer<QQuickItem> titleBarItem = nullptr;
QList<QPointer<QQuickItem>> hitTestVisibleItems = {};
QPointer<QQuickItem> windowIconButton = nullptr;
@ -85,42 +84,11 @@ struct FramelessQuickHelperExtraData : public FramelessExtraData
QPointer<QQuickItem> maximizeButton = nullptr;
QPointer<QQuickItem> closeButton = nullptr;
QList<QRect> hitTestVisibleRects = {};
[[nodiscard]] static FramelessExtraDataPtr create();
};
using FramelessQuickHelperExtraDataPtr = std::shared_ptr<FramelessQuickHelperExtraData>;
FramelessExtraDataPtr FramelessQuickHelperExtraData::create()
{
return std::make_shared<FramelessQuickHelperExtraData>();
}
using FramelessQuickHelperInternal = QHash<WId, FramelessQuickHelperData>;
template<typename T>
[[nodiscard]] static inline FramelessQuickHelperExtraDataPtr tryGetExtraData(const T t, const bool create)
{
FramelessDataPtr data = nullptr;
using T2 = std::remove_cvref_t<T>;
if constexpr (std::is_same_v<T2, QQuickWindow *>) {
data = FramelessManagerPrivate::getData(t);
} else if constexpr (std::is_same_v<T2, FramelessDataPtr>) {
data = t;
} else {
Q_UNREACHABLE_RETURN(nullptr);
}
Q_ASSERT(data);
if (!data) {
return nullptr;
}
auto it = data->extraData.find(FRAMELESS_QUICK_HELPER_EXTRA_DATA_ID);
if (it == data->extraData.end()) {
if (create) {
it = data->extraData.insert(FRAMELESS_QUICK_HELPER_EXTRA_DATA_ID, FramelessQuickHelperExtraData::create());
} else {
return nullptr;
}
}
return std::dynamic_pointer_cast<FramelessQuickHelperExtraData>(it.value());
}
Q_GLOBAL_STATIC(FramelessQuickHelperInternal, g_framelessQuickHelperData)
FramelessQuickHelperPrivate::FramelessQuickHelperPrivate(FramelessQuickHelper *q) : QObject(q)
{
@ -162,54 +130,53 @@ void FramelessQuickHelperPrivate::attach()
return;
}
const FramelessDataPtr data = FramelessManagerPrivate::getData(window);
Q_ASSERT(data);
if (!data) {
FramelessQuickHelperData * const data = getWindowDataMutable();
if (!data || data->ready) {
return;
}
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 = [window]() -> QWindow * { return 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; };
}
std::ignore = tryGetExtraData(data, true);
std::ignore = FramelessManager::instance()->addWindow(window);
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; };
FramelessManager::instance()->addWindow(&params);
data->params = params;
data->ready = true;
// 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
@ -231,11 +198,17 @@ void FramelessQuickHelperPrivate::attach()
void FramelessQuickHelperPrivate::detach()
{
Q_Q(FramelessQuickHelper);
const QQuickWindow * const window = q->window();
if (!window) {
QQuickWindow * const w = q->window();
if (!w) {
return;
}
std::ignore = FramelessManager::instance()->removeWindow(window);
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);
}
void FramelessQuickHelperPrivate::emitSignalForAllInstances(const char *signal)
@ -460,43 +433,37 @@ bool FramelessQuickHelperPrivate::isInSystemButtons(const QPoint &pos, QuickGlob
if (!button) {
return false;
}
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) {
const FramelessQuickHelperData *data = getWindowData();
if (!data) {
return false;
}
*button = QuickGlobal::SystemButtonType::Unknown;
if (extraData->windowIconButton && extraData->windowIconButton->isVisible() && extraData->windowIconButton->isEnabled()) {
if (mapItemGeometryToScene(extraData->windowIconButton).contains(pos)) {
if (data->windowIconButton && data->windowIconButton->isVisible() && data->windowIconButton->isEnabled()) {
if (mapItemGeometryToScene(data->windowIconButton).contains(pos)) {
*button = QuickGlobal::SystemButtonType::WindowIcon;
return true;
}
}
if (extraData->contextHelpButton && extraData->contextHelpButton->isVisible() && extraData->contextHelpButton->isEnabled()) {
if (mapItemGeometryToScene(extraData->contextHelpButton).contains(pos)) {
if (data->contextHelpButton && data->contextHelpButton->isVisible() && data->contextHelpButton->isEnabled()) {
if (mapItemGeometryToScene(data->contextHelpButton).contains(pos)) {
*button = QuickGlobal::SystemButtonType::Help;
return true;
}
}
if (extraData->minimizeButton && extraData->minimizeButton->isVisible() && extraData->minimizeButton->isEnabled()) {
if (mapItemGeometryToScene(extraData->minimizeButton).contains(pos)) {
if (data->minimizeButton && data->minimizeButton->isVisible() && data->minimizeButton->isEnabled()) {
if (mapItemGeometryToScene(data->minimizeButton).contains(pos)) {
*button = QuickGlobal::SystemButtonType::Minimize;
return true;
}
}
if (extraData->maximizeButton && extraData->maximizeButton->isVisible() && extraData->maximizeButton->isEnabled()) {
if (mapItemGeometryToScene(extraData->maximizeButton).contains(pos)) {
if (data->maximizeButton && data->maximizeButton->isVisible() && data->maximizeButton->isEnabled()) {
if (mapItemGeometryToScene(data->maximizeButton).contains(pos)) {
*button = QuickGlobal::SystemButtonType::Maximize;
return true;
}
}
if (extraData->closeButton && extraData->closeButton->isVisible() && extraData->closeButton->isEnabled()) {
if (mapItemGeometryToScene(extraData->closeButton).contains(pos)) {
if (data->closeButton && data->closeButton->isVisible() && data->closeButton->isEnabled()) {
if (mapItemGeometryToScene(data->closeButton).contains(pos)) {
*button = QuickGlobal::SystemButtonType::Close;
return true;
}
@ -506,6 +473,18 @@ 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) {
@ -513,21 +492,8 @@ 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(extraData->titleBarItem);
const QRect titleBarRect = mapItemGeometryToScene(data->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.
@ -535,24 +501,24 @@ bool FramelessQuickHelperPrivate::isInTitleBarDraggableArea(const QPoint &pos) c
}
QRegion region = titleBarRect;
const auto systemButtons = {
extraData->windowIconButton, extraData->contextHelpButton,
extraData->minimizeButton, extraData->maximizeButton,
extraData->closeButton
data->windowIconButton, data->contextHelpButton,
data->minimizeButton, data->maximizeButton,
data->closeButton
};
for (auto &&button : std::as_const(systemButtons)) {
if (button && button->isVisible() && button->isEnabled()) {
region -= mapItemGeometryToScene(button);
}
}
if (!extraData->hitTestVisibleItems.isEmpty()) {
for (auto &&item : std::as_const(extraData->hitTestVisibleItems)) {
if (!data->hitTestVisibleItems.isEmpty()) {
for (auto &&item : std::as_const(data->hitTestVisibleItems)) {
if (item && item->isVisible() && item->isEnabled()) {
region -= mapItemGeometryToScene(item);
}
}
}
if (!extraData->hitTestVisibleRects.isEmpty()) {
for (auto &&rect : std::as_const(extraData->hitTestVisibleRects)) {
if (!data->hitTestVisibleRects.isEmpty()) {
for (auto &&rect : std::as_const(data->hitTestVisibleRects)) {
if (rect.isValid()) {
region -= rect;
}
@ -590,6 +556,38 @@ 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);
@ -670,41 +668,33 @@ void FramelessQuickHelper::setHitTestVisible_item(QQuickItem *item, const bool v
if (!item) {
return;
}
const QQuickWindow * const w = window();
if (!w) {
return;
}
const FramelessQuickHelperExtraDataPtr extraData = tryGetExtraData(w, false);
Q_ASSERT(extraData);
if (!extraData) {
Q_D(FramelessQuickHelper);
FramelessQuickHelperData *data = d->getWindowDataMutable();
if (!data) {
return;
}
if (visible) {
extraData->hitTestVisibleItems.append(item);
data->hitTestVisibleItems.append(item);
} else {
extraData->hitTestVisibleItems.removeAll(item);
data->hitTestVisibleItems.removeAll(item);
}
}
void FramelessQuickHelper::setHitTestVisible_rect(const QRect &rect, const bool visible)
{
Q_ASSERT(Utils::isValidGeometry(rect));
if (!Utils::isValidGeometry(rect)) {
Q_ASSERT(rect.isValid());
if (!rect.isValid()) {
return;
}
const QQuickWindow * const w = window();
if (!w) {
return;
}
const FramelessQuickHelperExtraDataPtr extraData = tryGetExtraData(w, false);
Q_ASSERT(extraData);
if (!extraData) {
Q_D(FramelessQuickHelper);
FramelessQuickHelperData *data = d->getWindowDataMutable();
if (!data) {
return;
}
if (visible) {
extraData->hitTestVisibleRects.append(rect);
data->hitTestVisibleRects.append(rect);
} else {
extraData->hitTestVisibleRects.removeAll(rect);
data->hitTestVisibleRects.removeAll(rect);
}
}
@ -724,13 +714,9 @@ void FramelessQuickHelper::setHitTestVisible_object(QObject *object, const bool
bool FramelessQuickHelper::isContentExtendedIntoTitleBar() const
{
const QQuickWindow * const w = window();
if (!w) {
return false;
}
const FramelessDataPtr data = FramelessManagerPrivate::getData(w);
Q_ASSERT(data);
return (data && data->frameless);
Q_D(const FramelessQuickHelper);
const FramelessQuickHelperData *data = d->getWindowData();
return (data ? data->ready : false);
}
void FramelessQuickHelper::extendsContentIntoTitleBar(const bool value)
@ -750,16 +736,9 @@ void FramelessQuickHelper::extendsContentIntoTitleBar(const bool value)
QQuickItem *FramelessQuickHelper::titleBarItem() const
{
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;
Q_D(const FramelessQuickHelper);
const FramelessQuickHelperData *data = d->getWindowData();
return (data ? data->titleBarItem : nullptr);
}
void FramelessQuickHelper::setTitleBarItem(QQuickItem *value)
@ -768,17 +747,12 @@ void FramelessQuickHelper::setTitleBarItem(QQuickItem *value)
if (!value) {
return;
}
const QQuickWindow * const w = window();
if (!w) {
return;
}
const FramelessQuickHelperExtraDataPtr extraData = tryGetExtraData(w, false);
Q_ASSERT(extraData);
if (!extraData || (extraData->titleBarItem == value)) {
return;
}
extraData->titleBarItem = value;
Q_D(FramelessQuickHelper);
FramelessQuickHelperData *data = d->getWindowDataMutable();
if (!data || (data->titleBarItem == value)) {
return;
}
data->titleBarItem = value;
d->emitSignalForAllInstances("titleBarItemChanged");
}
@ -789,31 +763,27 @@ void FramelessQuickHelper::setSystemButton(QQuickItem *item, const QuickGlobal::
if (!item || (buttonType == QuickGlobal::SystemButtonType::Unknown)) {
return;
}
const QQuickWindow * const w = window();
if (!w) {
return;
}
const FramelessQuickHelperExtraDataPtr extraData = tryGetExtraData(w, false);
Q_ASSERT(extraData);
if (!extraData) {
Q_D(FramelessQuickHelper);
FramelessQuickHelperData *data = d->getWindowDataMutable();
if (!data) {
return;
}
switch (buttonType) {
case QuickGlobal::SystemButtonType::WindowIcon:
extraData->windowIconButton = item;
data->windowIconButton = item;
break;
case QuickGlobal::SystemButtonType::Help:
extraData->contextHelpButton = item;
data->contextHelpButton = item;
break;
case QuickGlobal::SystemButtonType::Minimize:
extraData->minimizeButton = item;
data->minimizeButton = item;
break;
case QuickGlobal::SystemButtonType::Maximize:
case QuickGlobal::SystemButtonType::Restore:
extraData->maximizeButton = item;
data->maximizeButton = item;
break;
case QuickGlobal::SystemButtonType::Close:
extraData->closeButton = item;
data->closeButton = item;
break;
case QuickGlobal::SystemButtonType::Unknown:
Q_UNREACHABLE();
@ -826,12 +796,15 @@ void FramelessQuickHelper::showSystemMenu(const QPoint &pos)
if (!w) {
return;
}
const WId windowId = w->winId();
const QPoint nativePos = Utils::toNativeGlobalPosition(w, pos);
#ifdef Q_OS_WINDOWS
std::ignore = Utils::showSystemMenu(w, nativePos, false);
Q_D(FramelessQuickHelper);
std::ignore = Utils::showSystemMenu(windowId, nativePos, false, &d->getWindowData()->params);
#elif (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
Utils::openSystemMenu(w, nativePos);
Utils::openSystemMenu(windowId, nativePos);
#else
Q_UNUSED(windowId);
Q_UNUSED(nativePos);
#endif
}
@ -859,11 +832,11 @@ void FramelessQuickHelper::windowStartSystemResize2(const Qt::Edges edges, const
void FramelessQuickHelper::moveWindowToDesktopCenter()
{
const QQuickWindow * const w = window();
if (!w) {
if (!window()) {
return;
}
std::ignore = Utils::moveWindowToDesktopCenter(w, true);
Q_D(FramelessQuickHelper);
Utils::moveWindowToDesktopCenter(&d->getWindowData()->params, true);
}
void FramelessQuickHelper::bringWindowToFront()
@ -873,7 +846,7 @@ void FramelessQuickHelper::bringWindowToFront()
return;
}
#ifdef Q_OS_WINDOWS
std::ignore = Utils::bringWindowToFront(w);
std::ignore = Utils::bringWindowToFront(w->winId());
#else
if (w->visibility() == QQuickWindow::Hidden) {
w->show();
@ -925,7 +898,7 @@ void FramelessQuickHelper::setWindowFixedSize(const bool value)
w->setMaximumSize(QSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX));
}
#ifdef Q_OS_WINDOWS
std::ignore = Utils::setAeroSnappingEnabled(w, !value);
std::ignore = Utils::setAeroSnappingEnabled(w->winId(), !value);
#endif
Q_D(FramelessQuickHelper);
d->emitSignalForAllInstances("windowFixedSizeChanged");
@ -962,7 +935,7 @@ void FramelessQuickHelper::setBlurBehindWindowEnabled(const bool value)
}
mode = QuickGlobal::BlurMode::Disable;
}
if (Utils::setBlurBehindWindowEnabled(w, FRAMELESSHELPER_ENUM_QUICK_TO_CORE(BlurMode, mode), {})) {
if (Utils::setBlurBehindWindowEnabled(w->winId(), FRAMELESSHELPER_ENUM_QUICK_TO_CORE(BlurMode, mode), {})) {
d->blurBehindWindowEnabled = value;
d->emitSignalForAllInstances("blurBehindWindowEnabledChanged");
} else {

View File

@ -35,7 +35,6 @@
#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>
@ -72,10 +71,10 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
using namespace Global;
static constexpr const auto FRAMELESS_WIDGETS_HELPER_EXTRA_DATA_ID = quint8(2);
struct FramelessWidgetsHelperExtraData : public FramelessExtraData
struct FramelessWidgetsHelperData
{
bool ready = false;
SystemParameters params = {};
QPointer<QWidget> titleBarWidget = nullptr;
QList<QPointer<QWidget>> hitTestVisibleWidgets = {};
QPointer<QWidget> windowIconButton = nullptr;
@ -84,42 +83,11 @@ struct FramelessWidgetsHelperExtraData : public FramelessExtraData
QPointer<QWidget> maximizeButton = nullptr;
QPointer<QWidget> closeButton = nullptr;
QList<QRect> hitTestVisibleRects = {};
[[nodiscard]] static FramelessExtraDataPtr create();
};
using FramelessWidgetsHelperExtraDataPtr = std::shared_ptr<FramelessWidgetsHelperExtraData>;
FramelessExtraDataPtr FramelessWidgetsHelperExtraData::create()
{
return std::make_shared<FramelessWidgetsHelperExtraData>();
}
using FramelessWidgetsHelperInternal = QHash<WId, FramelessWidgetsHelperData>;
template<typename T>
[[nodiscard]] static inline FramelessWidgetsHelperExtraDataPtr tryGetExtraData(const T t, const bool create)
{
FramelessDataPtr data = nullptr;
using T2 = std::remove_cvref_t<T>;
if constexpr (std::is_same_v<T2, QWindow *>) {
data = FramelessManagerPrivate::getData(t);
} else if constexpr (std::is_same_v<T2, FramelessDataPtr>) {
data = t;
} else {
Q_UNREACHABLE_RETURN(nullptr);
}
Q_ASSERT(data);
if (!data) {
return nullptr;
}
auto it = data->extraData.find(FRAMELESS_WIDGETS_HELPER_EXTRA_DATA_ID);
if (it == data->extraData.end()) {
if (create) {
it = data->extraData.insert(FRAMELESS_WIDGETS_HELPER_EXTRA_DATA_ID, FramelessWidgetsHelperExtraData::create());
} else {
return nullptr;
}
}
return std::dynamic_pointer_cast<FramelessWidgetsHelperExtraData>(it.value());
}
Q_GLOBAL_STATIC(FramelessWidgetsHelperInternal, g_framelessWidgetsHelperData)
[[nodiscard]] static inline bool isWidgetFixedSize(const QWidget * const widget)
{
@ -453,7 +421,7 @@ void FramelessWidgetsHelperPrivate::attach()
params.resetQtGrabbedControl = []() -> bool {
if (qt_button_down) {
static constexpr const auto invalidPos = QPoint{ -99999, -99999 };
const auto event = new QMouseEvent(
const auto event = std::make_unique<QMouseEvent>(
QEvent::MouseButtonRelease,
invalidPos,
invalidPos,
@ -461,7 +429,7 @@ void FramelessWidgetsHelperPrivate::attach()
Qt::LeftButton,
QGuiApplication::mouseButtons() ^ Qt::LeftButton,
QGuiApplication::keyboardModifiers());
QApplication::postEvent(qt_button_down, event);
QApplication::sendEvent(qt_button_down, event.get());
qt_button_down = nullptr;
return true;
}