wip
This commit is contained in:
parent
5ffb2ef733
commit
ae674a2507
|
@ -104,26 +104,32 @@ private:
|
||||||
};
|
};
|
||||||
using FramelessCallbacksPtr = FramelessCallbacks::PtrType;
|
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
|
struct FramelessData
|
||||||
{
|
{
|
||||||
bool frameless = false;
|
bool frameless = false;
|
||||||
FramelessCallbacksPtr callbacks = nullptr;
|
FramelessCallbacksPtr callbacks = nullptr;
|
||||||
struct {
|
FramelessExtraDataHash extraData = {};
|
||||||
void *ptr = nullptr;
|
|
||||||
using DeleterFunctionPrototype = void(*)(void*);
|
|
||||||
DeleterFunctionPrototype deleter = nullptr;
|
|
||||||
} extraData = {};
|
|
||||||
|
|
||||||
using PtrType = std::shared_ptr<FramelessData>;
|
using PtrType = std::shared_ptr<FramelessData>;
|
||||||
[[nodiscard]] static PtrType create();
|
[[nodiscard]] static PtrType create();
|
||||||
|
|
||||||
~FramelessData();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Q_DISABLE_COPY_MOVE(FramelessData)
|
Q_DISABLE_COPY_MOVE(FramelessData)
|
||||||
};
|
};
|
||||||
using FramelessDataPtr = FramelessData::PtrType;
|
using FramelessDataPtr = FramelessData::PtrType;
|
||||||
|
using FramelessDataPtrs = QList<FramelessDataPtr>;
|
||||||
using FramelessDataHash = QHash<const QWindow *, FramelessDataPtr>;
|
using FramelessDataHash = QHash<const QWindow *, FramelessDataPtr>;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
|
@ -25,9 +25,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <FramelessHelper/Core/framelesshelpercore_global.h>
|
#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))
|
#if (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
@ -37,8 +34,6 @@ QT_END_NAMESPACE
|
||||||
|
|
||||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||||
|
|
||||||
struct SystemParameters;
|
|
||||||
|
|
||||||
namespace Utils
|
namespace Utils
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,6 @@ class QuickMicaMaterial;
|
||||||
class QuickWindowBorder;
|
class QuickWindowBorder;
|
||||||
#endif
|
#endif
|
||||||
class FramelessQuickHelper;
|
class FramelessQuickHelper;
|
||||||
struct FramelessQuickHelperData;
|
|
||||||
|
|
||||||
class FRAMELESSHELPER_QUICK_API FramelessQuickHelperPrivate : public QObject
|
class FRAMELESSHELPER_QUICK_API FramelessQuickHelperPrivate : public QObject
|
||||||
{
|
{
|
||||||
|
@ -83,8 +82,6 @@ public:
|
||||||
Q_NODISCARD bool isInTitleBarDraggableArea(const QPoint &pos) const;
|
Q_NODISCARD bool isInTitleBarDraggableArea(const QPoint &pos) const;
|
||||||
Q_NODISCARD bool shouldIgnoreMouseEvents(const QPoint &pos) const;
|
Q_NODISCARD bool shouldIgnoreMouseEvents(const QPoint &pos) const;
|
||||||
void setSystemButtonState(const QuickGlobal::SystemButtonType button, const QuickGlobal::ButtonState state);
|
void setSystemButtonState(const QuickGlobal::SystemButtonType button, const QuickGlobal::ButtonState state);
|
||||||
Q_NODISCARD const FramelessQuickHelperData *getWindowData() const;
|
|
||||||
Q_NODISCARD FramelessQuickHelperData *getWindowDataMutable() const;
|
|
||||||
void rebindWindow();
|
void rebindWindow();
|
||||||
|
|
||||||
FramelessQuickHelper *q_ptr = nullptr;
|
FramelessQuickHelper *q_ptr = nullptr;
|
||||||
|
|
|
@ -56,7 +56,7 @@ struct FramelessConfigEntry
|
||||||
|
|
||||||
static constexpr const std::array<FramelessConfigEntry, static_cast<int>(Option::Last) + 1> FramelessOptionsTable =
|
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_HIDE_WINDOW_FRAME_BORDER", "Options/ForceHideWindowFrameBorder" },
|
||||||
FramelessConfigEntry{ "FRAMELESSHELPER_FORCE_SHOW_WINDOW_FRAME_BORDER", "Options/ForceShowWindowFrameBorder" },
|
FramelessConfigEntry{ "FRAMELESSHELPER_FORCE_SHOW_WINDOW_FRAME_BORDER", "Options/ForceShowWindowFrameBorder" },
|
||||||
FramelessConfigEntry{ "FRAMELESSHELPER_DISABLE_WINDOWS_SNAP_LAYOUT", "Options/DisableWindowsSnapLayout" },
|
FramelessConfigEntry{ "FRAMELESSHELPER_DISABLE_WINDOWS_SNAP_LAYOUT", "Options/DisableWindowsSnapLayout" },
|
||||||
|
@ -85,14 +85,14 @@ Q_GLOBAL_STATIC(FramelessConfigData, g_framelessConfigData)
|
||||||
static inline void warnInappropriateOptions()
|
static inline void warnInappropriateOptions()
|
||||||
{
|
{
|
||||||
const FramelessConfig * const cfg = FramelessConfig::instance();
|
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
|
#ifdef Q_OS_WINDOWS
|
||||||
if (cfg->isSet(Option::DisableWindowsSnapLayout)) {
|
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
|
#else
|
||||||
if (cfg->isSet(Option::UseCrossPlatformQtImplementation)) {
|
|
||||||
WARNING << "Option::UseCrossPlatformQtImplementation is default on non-Windows platforms.";
|
|
||||||
}
|
|
||||||
if (cfg->isSet(Option::ForceHideWindowFrameBorder)) {
|
if (cfg->isSet(Option::ForceHideWindowFrameBorder)) {
|
||||||
WARNING << "Option::ForceHideWindowFrameBorder is only available on Windows.";
|
WARNING << "Option::ForceHideWindowFrameBorder is only available on Windows.";
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,8 +114,21 @@ struct FramelessDataWin : public FramelessData
|
||||||
QRect restoreGeometry = {};
|
QRect restoreGeometry = {};
|
||||||
#endif // (QT_VERSION < QT_VERSION_CHECK(6, 5, 1))
|
#endif // (QT_VERSION < QT_VERSION_CHECK(6, 5, 1))
|
||||||
};
|
};
|
||||||
|
using FramelessDataWinPtr = std::shared_ptr<FramelessDataWin>;
|
||||||
|
|
||||||
#define GetFramelessDataWin(Window) std::dynamic_pointer_cast<FramelessDataWin>(FramelessManagerPrivate::getData(Window))
|
[[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);
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] FramelessDataPtr FramelessData::create()
|
[[nodiscard]] FramelessDataPtr FramelessData::create()
|
||||||
{
|
{
|
||||||
|
@ -199,7 +212,7 @@ void FramelessHelperWin::addWindow(const QWindow *window)
|
||||||
if (!window) {
|
if (!window) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto data = GetFramelessDataWin(window);
|
const FramelessDataWinPtr data = tryGetData(window);
|
||||||
Q_ASSERT(data);
|
Q_ASSERT(data);
|
||||||
if (!data || data->frameless) {
|
if (!data || data->frameless) {
|
||||||
return;
|
return;
|
||||||
|
@ -292,7 +305,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto data = GetFramelessDataWin(window);
|
const FramelessDataWinPtr data = tryGetData(window);
|
||||||
Q_ASSERT(data);
|
Q_ASSERT(data);
|
||||||
if (!data || !data->frameless) {
|
if (!data || !data->frameless) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -119,15 +119,20 @@ FramelessCallbacksPtr FramelessCallbacks::create()
|
||||||
return std::make_shared<FramelessCallbacks>();
|
return std::make_shared<FramelessCallbacks>();
|
||||||
}
|
}
|
||||||
|
|
||||||
FramelessData::~FramelessData()
|
FramelessExtraDataPtr FramelessExtraData::create()
|
||||||
{
|
{
|
||||||
if (extraData.ptr) {
|
return std::make_shared<FramelessExtraData>();
|
||||||
Q_ASSERT(extraData.deleter);
|
|
||||||
if (extraData.deleter) {
|
|
||||||
extraData.deleter(extraData.ptr);
|
|
||||||
extraData.deleter = nullptr;
|
|
||||||
}
|
}
|
||||||
extraData.ptr = nullptr;
|
|
||||||
|
FramelessExtraData::~FramelessExtraData()
|
||||||
|
{
|
||||||
|
if (ptr) {
|
||||||
|
Q_ASSERT(deleter);
|
||||||
|
if (deleter) {
|
||||||
|
deleter(ptr);
|
||||||
|
deleter = nullptr;
|
||||||
|
}
|
||||||
|
ptr = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -194,19 +194,48 @@ FRAMELESSHELPER_STRING_CONSTANT(ScreenToClient)
|
||||||
FRAMELESSHELPER_STRING_CONSTANT(DwmFlush)
|
FRAMELESSHELPER_STRING_CONSTANT(DwmFlush)
|
||||||
FRAMELESSHELPER_STRING_CONSTANT(GetCursorPos)
|
FRAMELESSHELPER_STRING_CONSTANT(GetCursorPos)
|
||||||
|
|
||||||
struct FramelessDataExtra
|
static constexpr const auto UTILS_WIN_EXTRA_DATA_ID = quint8(1);
|
||||||
|
|
||||||
|
struct UtilsWinExtraData : public FramelessExtraData
|
||||||
{
|
{
|
||||||
WNDPROC qtWindowProc = nullptr;
|
WNDPROC qtWindowProc = nullptr;
|
||||||
bool windowProcHooked = false;
|
bool windowProcHooked = false;
|
||||||
bool mica = false;
|
bool mica = false;
|
||||||
};
|
|
||||||
|
|
||||||
static inline void FramelessDataExtraDeleter(void *data)
|
[[nodiscard]] static FramelessExtraDataPtr create();
|
||||||
|
};
|
||||||
|
using UtilsWinExtraDataPtr = std::shared_ptr<UtilsWinExtraData>;
|
||||||
|
|
||||||
|
FramelessExtraDataPtr UtilsWinExtraData::create()
|
||||||
{
|
{
|
||||||
Q_ASSERT(data);
|
return std::make_shared<UtilsWinExtraData>();
|
||||||
if (data) {
|
|
||||||
delete static_cast<FramelessDataExtra *>(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
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
|
struct Win32Message
|
||||||
|
@ -889,7 +918,7 @@ static constexpr const std::array<Win32Message, 333> g_win32MessageMap =
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return ::DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
return ::DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
const auto extraData = static_cast<FramelessDataExtra *>(data->extraData.ptr);
|
const UtilsWinExtraDataPtr extraData = tryGetExtraData(data, false);
|
||||||
Q_ASSERT(extraData);
|
Q_ASSERT(extraData);
|
||||||
if (!extraData) {
|
if (!extraData) {
|
||||||
return ::DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
return ::DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||||
|
@ -1101,12 +1130,7 @@ bool Utils::updateWindowFrameMargins(const QWindow *window, const bool reset)
|
||||||
if (!isDwmCompositionEnabled()) {
|
if (!isDwmCompositionEnabled()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const FramelessDataPtr data = FramelessManagerPrivate::getData(window);
|
const UtilsWinExtraDataPtr extraData = tryGetExtraData(window, false);
|
||||||
Q_ASSERT(data);
|
|
||||||
if (!data) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const auto extraData = static_cast<FramelessDataExtra *>(data->extraData.ptr);
|
|
||||||
Q_ASSERT(extraData);
|
Q_ASSERT(extraData);
|
||||||
if (!extraData) {
|
if (!extraData) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1932,18 +1956,7 @@ bool Utils::installWindowProcHook(const QWindow *window)
|
||||||
if (!window) {
|
if (!window) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const FramelessDataPtr data = FramelessManagerPrivate::getData(window);
|
const UtilsWinExtraDataPtr extraData = tryGetExtraData(window, true);
|
||||||
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);
|
const auto hwnd = qWindowId<HWND>(window);
|
||||||
if (!extraData->qtWindowProc) {
|
if (!extraData->qtWindowProc) {
|
||||||
::SetLastError(ERROR_SUCCESS);
|
::SetLastError(ERROR_SUCCESS);
|
||||||
|
@ -1972,12 +1985,7 @@ bool Utils::uninstallWindowProcHook(const QWindow *window)
|
||||||
if (!window) {
|
if (!window) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const FramelessDataPtr data = FramelessManagerPrivate::getData(window);
|
const UtilsWinExtraDataPtr extraData = tryGetExtraData(window, false);
|
||||||
Q_ASSERT(data);
|
|
||||||
if (!data) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const auto extraData = static_cast<FramelessDataExtra *>(data->extraData.ptr);
|
|
||||||
if (!extraData || !extraData->windowProcHooked) {
|
if (!extraData || !extraData->windowProcHooked) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2249,12 +2257,7 @@ bool Utils::setBlurBehindWindowEnabled(const QWindow *window, const BlurMode mod
|
||||||
if (!window) {
|
if (!window) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const FramelessDataPtr data = FramelessManagerPrivate::getData(window);
|
const UtilsWinExtraDataPtr extraData = tryGetExtraData(window, false);
|
||||||
Q_ASSERT(data);
|
|
||||||
if (!data) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const auto extraData = static_cast<FramelessDataExtra *>(data->extraData.ptr);
|
|
||||||
Q_ASSERT(extraData);
|
Q_ASSERT(extraData);
|
||||||
if (!extraData) {
|
if (!extraData) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -3013,12 +3016,8 @@ bool Utils::removeMicaWindow(const QWindow *window)
|
||||||
if (!window) {
|
if (!window) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const FramelessDataPtr data = FramelessManagerPrivate::getData(window);
|
const UtilsWinExtraDataPtr extraData = tryGetExtraData(window, false);
|
||||||
Q_ASSERT(data);
|
Q_ASSERT(extraData);
|
||||||
if (!data) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const auto extraData = static_cast<FramelessDataExtra *>(data->extraData.ptr);
|
|
||||||
if (!extraData || !extraData->mica) {
|
if (!extraData || !extraData->mica) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#endif
|
#endif
|
||||||
#include <FramelessHelper/Core/framelessmanager.h>
|
#include <FramelessHelper/Core/framelessmanager.h>
|
||||||
#include <FramelessHelper/Core/utils.h>
|
#include <FramelessHelper/Core/utils.h>
|
||||||
|
#include <FramelessHelper/Core/private/framelessmanager_p.h>
|
||||||
#include <FramelessHelper/Core/private/framelessconfig_p.h>
|
#include <FramelessHelper/Core/private/framelessconfig_p.h>
|
||||||
#include <FramelessHelper/Core/private/framelesshelpercore_global_p.h>
|
#include <FramelessHelper/Core/private/framelesshelpercore_global_p.h>
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
|
@ -72,10 +73,10 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||||
|
|
||||||
using namespace Global;
|
using namespace Global;
|
||||||
|
|
||||||
struct FramelessQuickHelperData
|
static constexpr const auto FRAMELESS_QUICK_HELPER_EXTRA_DATA_ID = quint8(3);
|
||||||
|
|
||||||
|
struct FramelessQuickHelperExtraData : public FramelessExtraData
|
||||||
{
|
{
|
||||||
bool ready = false;
|
|
||||||
SystemParameters params = {};
|
|
||||||
QPointer<QQuickItem> titleBarItem = nullptr;
|
QPointer<QQuickItem> titleBarItem = nullptr;
|
||||||
QList<QPointer<QQuickItem>> hitTestVisibleItems = {};
|
QList<QPointer<QQuickItem>> hitTestVisibleItems = {};
|
||||||
QPointer<QQuickItem> windowIconButton = nullptr;
|
QPointer<QQuickItem> windowIconButton = nullptr;
|
||||||
|
@ -84,11 +85,42 @@ struct FramelessQuickHelperData
|
||||||
QPointer<QQuickItem> maximizeButton = nullptr;
|
QPointer<QQuickItem> maximizeButton = nullptr;
|
||||||
QPointer<QQuickItem> closeButton = nullptr;
|
QPointer<QQuickItem> closeButton = nullptr;
|
||||||
QList<QRect> hitTestVisibleRects = {};
|
QList<QRect> hitTestVisibleRects = {};
|
||||||
|
|
||||||
|
[[nodiscard]] static FramelessExtraDataPtr create();
|
||||||
};
|
};
|
||||||
|
using FramelessQuickHelperExtraDataPtr = std::shared_ptr<FramelessQuickHelperExtraData>;
|
||||||
|
|
||||||
using FramelessQuickHelperInternal = QHash<WId, FramelessQuickHelperData>;
|
FramelessExtraDataPtr FramelessQuickHelperExtraData::create()
|
||||||
|
{
|
||||||
|
return std::make_shared<FramelessQuickHelperExtraData>();
|
||||||
|
}
|
||||||
|
|
||||||
Q_GLOBAL_STATIC(FramelessQuickHelperInternal, g_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());
|
||||||
|
}
|
||||||
|
|
||||||
FramelessQuickHelperPrivate::FramelessQuickHelperPrivate(FramelessQuickHelper *q) : QObject(q)
|
FramelessQuickHelperPrivate::FramelessQuickHelperPrivate(FramelessQuickHelper *q) : QObject(q)
|
||||||
{
|
{
|
||||||
|
@ -130,53 +162,54 @@ void FramelessQuickHelperPrivate::attach()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FramelessQuickHelperData * const data = getWindowDataMutable();
|
const FramelessDataPtr data = FramelessManagerPrivate::getData(window);
|
||||||
if (!data || data->ready) {
|
Q_ASSERT(data);
|
||||||
|
if (!data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemParameters params = {};
|
if (!data->callbacks) {
|
||||||
params.getWindowId = [window]() -> WId { return window->winId(); };
|
data->callbacks = FramelessCallbacks::create();
|
||||||
params.getWindowFlags = [window]() -> Qt::WindowFlags { return window->flags(); };
|
data->callbacks->getWindowId = [window]() -> WId { return window->winId(); };
|
||||||
params.setWindowFlags = [window](const Qt::WindowFlags flags) -> void { window->setFlags(flags); };
|
data->callbacks->getWindowFlags = [window]() -> Qt::WindowFlags { return window->flags(); };
|
||||||
params.getWindowSize = [window]() -> QSize { return window->size(); };
|
data->callbacks->setWindowFlags = [window](const Qt::WindowFlags flags) -> void { window->setFlags(flags); };
|
||||||
params.setWindowSize = [window](const QSize &size) -> void { window->resize(size); };
|
data->callbacks->getWindowSize = [window]() -> QSize { return window->size(); };
|
||||||
params.getWindowPosition = [window]() -> QPoint { return window->position(); };
|
data->callbacks->setWindowSize = [window](const QSize &size) -> void { window->resize(size); };
|
||||||
params.setWindowPosition = [window](const QPoint &pos) -> void { window->setX(pos.x()); window->setY(pos.y()); };
|
data->callbacks->getWindowPosition = [window]() -> QPoint { return window->position(); };
|
||||||
params.getWindowScreen = [window]() -> QScreen * { return window->screen(); };
|
data->callbacks->setWindowPosition = [window](const QPoint &pos) -> void { window->setX(pos.x()); window->setY(pos.y()); };
|
||||||
params.isWindowFixedSize = [q]() -> bool { return q->isWindowFixedSize(); };
|
data->callbacks->getWindowScreen = [window]() -> QScreen * { return window->screen(); };
|
||||||
params.setWindowFixedSize = [q](const bool value) -> void { q->setWindowFixedSize(value); };
|
data->callbacks->isWindowFixedSize = [q]() -> bool { return q->isWindowFixedSize(); };
|
||||||
params.getWindowState = [window]() -> Qt::WindowState { return window->windowState(); };
|
data->callbacks->setWindowFixedSize = [q](const bool value) -> void { q->setWindowFixedSize(value); };
|
||||||
params.setWindowState = [window](const Qt::WindowState state) -> void { window->setWindowState(state); };
|
data->callbacks->getWindowState = [window]() -> Qt::WindowState { return window->windowState(); };
|
||||||
params.getWindowHandle = [window]() -> QWindow * { return window; };
|
data->callbacks->setWindowState = [window](const Qt::WindowState state) -> void { window->setWindowState(state); };
|
||||||
params.windowToScreen = [window](const QPoint &pos) -> QPoint { return window->mapToGlobal(pos); };
|
data->callbacks->getWindowHandle = [window]() -> QWindow * { return window; };
|
||||||
params.screenToWindow = [window](const QPoint &pos) -> QPoint { return window->mapFromGlobal(pos); };
|
data->callbacks->windowToScreen = [window](const QPoint &pos) -> QPoint { return window->mapToGlobal(pos); };
|
||||||
params.isInsideSystemButtons = [this](const QPoint &pos, SystemButtonType *button) -> bool {
|
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;
|
QuickGlobal::SystemButtonType button2 = QuickGlobal::SystemButtonType::Unknown;
|
||||||
const bool result = isInSystemButtons(pos, &button2);
|
const bool result = isInSystemButtons(pos, &button2);
|
||||||
*button = FRAMELESSHELPER_ENUM_QUICK_TO_CORE(SystemButtonType, button2);
|
*button = FRAMELESSHELPER_ENUM_QUICK_TO_CORE(SystemButtonType, button2);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
params.isInsideTitleBarDraggableArea = [this](const QPoint &pos) -> bool { return isInTitleBarDraggableArea(pos); };
|
data->callbacks->isInsideTitleBarDraggableArea = [this](const QPoint &pos) -> bool { return isInTitleBarDraggableArea(pos); };
|
||||||
params.getWindowDevicePixelRatio = [window]() -> qreal { return window->effectiveDevicePixelRatio(); };
|
data->callbacks->getWindowDevicePixelRatio = [window]() -> qreal { return window->effectiveDevicePixelRatio(); };
|
||||||
params.setSystemButtonState = [this](const SystemButtonType button, const ButtonState state) -> void {
|
data->callbacks->setSystemButtonState = [this](const SystemButtonType button, const ButtonState state) -> void {
|
||||||
setSystemButtonState(FRAMELESSHELPER_ENUM_CORE_TO_QUICK(SystemButtonType, button),
|
setSystemButtonState(FRAMELESSHELPER_ENUM_CORE_TO_QUICK(SystemButtonType, button), FRAMELESSHELPER_ENUM_CORE_TO_QUICK(ButtonState, state));
|
||||||
FRAMELESSHELPER_ENUM_CORE_TO_QUICK(ButtonState, state));
|
|
||||||
};
|
};
|
||||||
params.shouldIgnoreMouseEvents = [this](const QPoint &pos) -> bool { return shouldIgnoreMouseEvents(pos); };
|
data->callbacks->shouldIgnoreMouseEvents = [this](const QPoint &pos) -> bool { return shouldIgnoreMouseEvents(pos); };
|
||||||
params.showSystemMenu = [q](const QPoint &pos) -> void { q->showSystemMenu(pos); };
|
data->callbacks->showSystemMenu = [q](const QPoint &pos) -> void { q->showSystemMenu(pos); };
|
||||||
params.setProperty = [this](const char *name, const QVariant &value) -> void { setProperty(name, value); };
|
data->callbacks->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); };
|
data->callbacks->getProperty = [this](const char *name, const QVariant &defaultValue) -> QVariant { return getProperty(name, defaultValue); };
|
||||||
params.setCursor = [window](const QCursor &cursor) -> void { window->setCursor(cursor); };
|
data->callbacks->setCursor = [window](const QCursor &cursor) -> void { window->setCursor(cursor); };
|
||||||
params.unsetCursor = [window]() -> void { window->unsetCursor(); };
|
data->callbacks->unsetCursor = [window]() -> void { window->unsetCursor(); };
|
||||||
params.getWidgetHandle = []() -> QObject * { return nullptr; };
|
data->callbacks->getWidgetHandle = []() -> QObject * { return nullptr; };
|
||||||
params.forceChildrenRepaint = [this](const int delay) -> void { repaintAllChildren(delay); };
|
data->callbacks->forceChildrenRepaint = [this](const int delay) -> void { repaintAllChildren(delay); };
|
||||||
params.resetQtGrabbedControl = []() -> bool { return false; };
|
data->callbacks->resetQtGrabbedControl = []() -> bool { return false; };
|
||||||
|
}
|
||||||
|
|
||||||
FramelessManager::instance()->addWindow(¶ms);
|
std::ignore = tryGetExtraData(data, true);
|
||||||
|
|
||||||
data->params = params;
|
std::ignore = FramelessManager::instance()->addWindow(window);
|
||||||
data->ready = true;
|
|
||||||
|
|
||||||
// We have to wait for a little time before moving the top level window
|
// 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
|
// , because the platform window may not finish initializing by the time
|
||||||
|
@ -198,17 +231,11 @@ void FramelessQuickHelperPrivate::attach()
|
||||||
void FramelessQuickHelperPrivate::detach()
|
void FramelessQuickHelperPrivate::detach()
|
||||||
{
|
{
|
||||||
Q_Q(FramelessQuickHelper);
|
Q_Q(FramelessQuickHelper);
|
||||||
QQuickWindow * const w = q->window();
|
const QQuickWindow * const window = q->window();
|
||||||
if (!w) {
|
if (!window) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const WId windowId = w->winId();
|
std::ignore = FramelessManager::instance()->removeWindow(window);
|
||||||
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)
|
void FramelessQuickHelperPrivate::emitSignalForAllInstances(const char *signal)
|
||||||
|
@ -433,37 +460,43 @@ bool FramelessQuickHelperPrivate::isInSystemButtons(const QPoint &pos, QuickGlob
|
||||||
if (!button) {
|
if (!button) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const FramelessQuickHelperData *data = getWindowData();
|
Q_Q(const FramelessQuickHelper);
|
||||||
if (!data) {
|
const QQuickWindow * const window = q->window();
|
||||||
|
if (!window) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const FramelessQuickHelperExtraDataPtr extraData = tryGetExtraData(window, false);
|
||||||
|
Q_ASSERT(extraData);
|
||||||
|
if (!extraData) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
*button = QuickGlobal::SystemButtonType::Unknown;
|
*button = QuickGlobal::SystemButtonType::Unknown;
|
||||||
if (data->windowIconButton && data->windowIconButton->isVisible() && data->windowIconButton->isEnabled()) {
|
if (extraData->windowIconButton && extraData->windowIconButton->isVisible() && extraData->windowIconButton->isEnabled()) {
|
||||||
if (mapItemGeometryToScene(data->windowIconButton).contains(pos)) {
|
if (mapItemGeometryToScene(extraData->windowIconButton).contains(pos)) {
|
||||||
*button = QuickGlobal::SystemButtonType::WindowIcon;
|
*button = QuickGlobal::SystemButtonType::WindowIcon;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (data->contextHelpButton && data->contextHelpButton->isVisible() && data->contextHelpButton->isEnabled()) {
|
if (extraData->contextHelpButton && extraData->contextHelpButton->isVisible() && extraData->contextHelpButton->isEnabled()) {
|
||||||
if (mapItemGeometryToScene(data->contextHelpButton).contains(pos)) {
|
if (mapItemGeometryToScene(extraData->contextHelpButton).contains(pos)) {
|
||||||
*button = QuickGlobal::SystemButtonType::Help;
|
*button = QuickGlobal::SystemButtonType::Help;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (data->minimizeButton && data->minimizeButton->isVisible() && data->minimizeButton->isEnabled()) {
|
if (extraData->minimizeButton && extraData->minimizeButton->isVisible() && extraData->minimizeButton->isEnabled()) {
|
||||||
if (mapItemGeometryToScene(data->minimizeButton).contains(pos)) {
|
if (mapItemGeometryToScene(extraData->minimizeButton).contains(pos)) {
|
||||||
*button = QuickGlobal::SystemButtonType::Minimize;
|
*button = QuickGlobal::SystemButtonType::Minimize;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (data->maximizeButton && data->maximizeButton->isVisible() && data->maximizeButton->isEnabled()) {
|
if (extraData->maximizeButton && extraData->maximizeButton->isVisible() && extraData->maximizeButton->isEnabled()) {
|
||||||
if (mapItemGeometryToScene(data->maximizeButton).contains(pos)) {
|
if (mapItemGeometryToScene(extraData->maximizeButton).contains(pos)) {
|
||||||
*button = QuickGlobal::SystemButtonType::Maximize;
|
*button = QuickGlobal::SystemButtonType::Maximize;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (data->closeButton && data->closeButton->isVisible() && data->closeButton->isEnabled()) {
|
if (extraData->closeButton && extraData->closeButton->isVisible() && extraData->closeButton->isEnabled()) {
|
||||||
if (mapItemGeometryToScene(data->closeButton).contains(pos)) {
|
if (mapItemGeometryToScene(extraData->closeButton).contains(pos)) {
|
||||||
*button = QuickGlobal::SystemButtonType::Close;
|
*button = QuickGlobal::SystemButtonType::Close;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -473,18 +506,6 @@ bool FramelessQuickHelperPrivate::isInSystemButtons(const QPoint &pos, QuickGlob
|
||||||
|
|
||||||
bool FramelessQuickHelperPrivate::isInTitleBarDraggableArea(const QPoint &pos) const
|
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);
|
Q_Q(const FramelessQuickHelper);
|
||||||
const QQuickWindow * const window = q->window();
|
const QQuickWindow * const window = q->window();
|
||||||
if (!window) {
|
if (!window) {
|
||||||
|
@ -492,8 +513,21 @@ bool FramelessQuickHelperPrivate::isInTitleBarDraggableArea(const QPoint &pos) c
|
||||||
// so we assume there's no title bar.
|
// so we assume there's no title bar.
|
||||||
return false;
|
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 windowRect = {QPoint(0, 0), window->size()};
|
||||||
const QRect titleBarRect = mapItemGeometryToScene(data->titleBarItem);
|
const QRect titleBarRect = mapItemGeometryToScene(extraData->titleBarItem);
|
||||||
if (!titleBarRect.intersects(windowRect)) {
|
if (!titleBarRect.intersects(windowRect)) {
|
||||||
// The title bar is totally outside of the window for some reason,
|
// The title bar is totally outside of the window for some reason,
|
||||||
// also treat it as there's no title bar.
|
// also treat it as there's no title bar.
|
||||||
|
@ -501,24 +535,24 @@ bool FramelessQuickHelperPrivate::isInTitleBarDraggableArea(const QPoint &pos) c
|
||||||
}
|
}
|
||||||
QRegion region = titleBarRect;
|
QRegion region = titleBarRect;
|
||||||
const auto systemButtons = {
|
const auto systemButtons = {
|
||||||
data->windowIconButton, data->contextHelpButton,
|
extraData->windowIconButton, extraData->contextHelpButton,
|
||||||
data->minimizeButton, data->maximizeButton,
|
extraData->minimizeButton, extraData->maximizeButton,
|
||||||
data->closeButton
|
extraData->closeButton
|
||||||
};
|
};
|
||||||
for (auto &&button : std::as_const(systemButtons)) {
|
for (auto &&button : std::as_const(systemButtons)) {
|
||||||
if (button && button->isVisible() && button->isEnabled()) {
|
if (button && button->isVisible() && button->isEnabled()) {
|
||||||
region -= mapItemGeometryToScene(button);
|
region -= mapItemGeometryToScene(button);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!data->hitTestVisibleItems.isEmpty()) {
|
if (!extraData->hitTestVisibleItems.isEmpty()) {
|
||||||
for (auto &&item : std::as_const(data->hitTestVisibleItems)) {
|
for (auto &&item : std::as_const(extraData->hitTestVisibleItems)) {
|
||||||
if (item && item->isVisible() && item->isEnabled()) {
|
if (item && item->isVisible() && item->isEnabled()) {
|
||||||
region -= mapItemGeometryToScene(item);
|
region -= mapItemGeometryToScene(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!data->hitTestVisibleRects.isEmpty()) {
|
if (!extraData->hitTestVisibleRects.isEmpty()) {
|
||||||
for (auto &&rect : std::as_const(data->hitTestVisibleRects)) {
|
for (auto &&rect : std::as_const(extraData->hitTestVisibleRects)) {
|
||||||
if (rect.isValid()) {
|
if (rect.isValid()) {
|
||||||
region -= rect;
|
region -= rect;
|
||||||
}
|
}
|
||||||
|
@ -556,38 +590,6 @@ void FramelessQuickHelperPrivate::setSystemButtonState(const QuickGlobal::System
|
||||||
Q_UNUSED(state);
|
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()
|
void FramelessQuickHelperPrivate::rebindWindow()
|
||||||
{
|
{
|
||||||
Q_Q(FramelessQuickHelper);
|
Q_Q(FramelessQuickHelper);
|
||||||
|
@ -668,33 +670,41 @@ void FramelessQuickHelper::setHitTestVisible_item(QQuickItem *item, const bool v
|
||||||
if (!item) {
|
if (!item) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Q_D(FramelessQuickHelper);
|
const QQuickWindow * const w = window();
|
||||||
FramelessQuickHelperData *data = d->getWindowDataMutable();
|
if (!w) {
|
||||||
if (!data) {
|
return;
|
||||||
|
}
|
||||||
|
const FramelessQuickHelperExtraDataPtr extraData = tryGetExtraData(w, false);
|
||||||
|
Q_ASSERT(extraData);
|
||||||
|
if (!extraData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (visible) {
|
if (visible) {
|
||||||
data->hitTestVisibleItems.append(item);
|
extraData->hitTestVisibleItems.append(item);
|
||||||
} else {
|
} else {
|
||||||
data->hitTestVisibleItems.removeAll(item);
|
extraData->hitTestVisibleItems.removeAll(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessQuickHelper::setHitTestVisible_rect(const QRect &rect, const bool visible)
|
void FramelessQuickHelper::setHitTestVisible_rect(const QRect &rect, const bool visible)
|
||||||
{
|
{
|
||||||
Q_ASSERT(rect.isValid());
|
Q_ASSERT(Utils::isValidGeometry(rect));
|
||||||
if (!rect.isValid()) {
|
if (!Utils::isValidGeometry(rect)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Q_D(FramelessQuickHelper);
|
const QQuickWindow * const w = window();
|
||||||
FramelessQuickHelperData *data = d->getWindowDataMutable();
|
if (!w) {
|
||||||
if (!data) {
|
return;
|
||||||
|
}
|
||||||
|
const FramelessQuickHelperExtraDataPtr extraData = tryGetExtraData(w, false);
|
||||||
|
Q_ASSERT(extraData);
|
||||||
|
if (!extraData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (visible) {
|
if (visible) {
|
||||||
data->hitTestVisibleRects.append(rect);
|
extraData->hitTestVisibleRects.append(rect);
|
||||||
} else {
|
} else {
|
||||||
data->hitTestVisibleRects.removeAll(rect);
|
extraData->hitTestVisibleRects.removeAll(rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -714,9 +724,13 @@ void FramelessQuickHelper::setHitTestVisible_object(QObject *object, const bool
|
||||||
|
|
||||||
bool FramelessQuickHelper::isContentExtendedIntoTitleBar() const
|
bool FramelessQuickHelper::isContentExtendedIntoTitleBar() const
|
||||||
{
|
{
|
||||||
Q_D(const FramelessQuickHelper);
|
const QQuickWindow * const w = window();
|
||||||
const FramelessQuickHelperData *data = d->getWindowData();
|
if (!w) {
|
||||||
return (data ? data->ready : false);
|
return false;
|
||||||
|
}
|
||||||
|
const FramelessDataPtr data = FramelessManagerPrivate::getData(w);
|
||||||
|
Q_ASSERT(data);
|
||||||
|
return (data && data->frameless);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessQuickHelper::extendsContentIntoTitleBar(const bool value)
|
void FramelessQuickHelper::extendsContentIntoTitleBar(const bool value)
|
||||||
|
@ -736,9 +750,16 @@ void FramelessQuickHelper::extendsContentIntoTitleBar(const bool value)
|
||||||
|
|
||||||
QQuickItem *FramelessQuickHelper::titleBarItem() const
|
QQuickItem *FramelessQuickHelper::titleBarItem() const
|
||||||
{
|
{
|
||||||
Q_D(const FramelessQuickHelper);
|
const QQuickWindow * const w = window();
|
||||||
const FramelessQuickHelperData *data = d->getWindowData();
|
if (!w) {
|
||||||
return (data ? data->titleBarItem : nullptr);
|
return nullptr;
|
||||||
|
}
|
||||||
|
const FramelessQuickHelperExtraDataPtr extraData = tryGetExtraData(w, false);
|
||||||
|
Q_ASSERT(extraData);
|
||||||
|
if (!extraData) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return extraData->titleBarItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessQuickHelper::setTitleBarItem(QQuickItem *value)
|
void FramelessQuickHelper::setTitleBarItem(QQuickItem *value)
|
||||||
|
@ -747,12 +768,17 @@ void FramelessQuickHelper::setTitleBarItem(QQuickItem *value)
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Q_D(FramelessQuickHelper);
|
const QQuickWindow * const w = window();
|
||||||
FramelessQuickHelperData *data = d->getWindowDataMutable();
|
if (!w) {
|
||||||
if (!data || (data->titleBarItem == value)) {
|
|
||||||
return;
|
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");
|
d->emitSignalForAllInstances("titleBarItemChanged");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -763,27 +789,31 @@ void FramelessQuickHelper::setSystemButton(QQuickItem *item, const QuickGlobal::
|
||||||
if (!item || (buttonType == QuickGlobal::SystemButtonType::Unknown)) {
|
if (!item || (buttonType == QuickGlobal::SystemButtonType::Unknown)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Q_D(FramelessQuickHelper);
|
const QQuickWindow * const w = window();
|
||||||
FramelessQuickHelperData *data = d->getWindowDataMutable();
|
if (!w) {
|
||||||
if (!data) {
|
return;
|
||||||
|
}
|
||||||
|
const FramelessQuickHelperExtraDataPtr extraData = tryGetExtraData(w, false);
|
||||||
|
Q_ASSERT(extraData);
|
||||||
|
if (!extraData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (buttonType) {
|
switch (buttonType) {
|
||||||
case QuickGlobal::SystemButtonType::WindowIcon:
|
case QuickGlobal::SystemButtonType::WindowIcon:
|
||||||
data->windowIconButton = item;
|
extraData->windowIconButton = item;
|
||||||
break;
|
break;
|
||||||
case QuickGlobal::SystemButtonType::Help:
|
case QuickGlobal::SystemButtonType::Help:
|
||||||
data->contextHelpButton = item;
|
extraData->contextHelpButton = item;
|
||||||
break;
|
break;
|
||||||
case QuickGlobal::SystemButtonType::Minimize:
|
case QuickGlobal::SystemButtonType::Minimize:
|
||||||
data->minimizeButton = item;
|
extraData->minimizeButton = item;
|
||||||
break;
|
break;
|
||||||
case QuickGlobal::SystemButtonType::Maximize:
|
case QuickGlobal::SystemButtonType::Maximize:
|
||||||
case QuickGlobal::SystemButtonType::Restore:
|
case QuickGlobal::SystemButtonType::Restore:
|
||||||
data->maximizeButton = item;
|
extraData->maximizeButton = item;
|
||||||
break;
|
break;
|
||||||
case QuickGlobal::SystemButtonType::Close:
|
case QuickGlobal::SystemButtonType::Close:
|
||||||
data->closeButton = item;
|
extraData->closeButton = item;
|
||||||
break;
|
break;
|
||||||
case QuickGlobal::SystemButtonType::Unknown:
|
case QuickGlobal::SystemButtonType::Unknown:
|
||||||
Q_UNREACHABLE();
|
Q_UNREACHABLE();
|
||||||
|
@ -796,15 +826,12 @@ void FramelessQuickHelper::showSystemMenu(const QPoint &pos)
|
||||||
if (!w) {
|
if (!w) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const WId windowId = w->winId();
|
|
||||||
const QPoint nativePos = Utils::toNativeGlobalPosition(w, pos);
|
const QPoint nativePos = Utils::toNativeGlobalPosition(w, pos);
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
Q_D(FramelessQuickHelper);
|
std::ignore = Utils::showSystemMenu(w, nativePos, false);
|
||||||
std::ignore = Utils::showSystemMenu(windowId, nativePos, false, &d->getWindowData()->params);
|
|
||||||
#elif (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
#elif (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||||
Utils::openSystemMenu(windowId, nativePos);
|
Utils::openSystemMenu(w, nativePos);
|
||||||
#else
|
#else
|
||||||
Q_UNUSED(windowId);
|
|
||||||
Q_UNUSED(nativePos);
|
Q_UNUSED(nativePos);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -832,11 +859,11 @@ void FramelessQuickHelper::windowStartSystemResize2(const Qt::Edges edges, const
|
||||||
|
|
||||||
void FramelessQuickHelper::moveWindowToDesktopCenter()
|
void FramelessQuickHelper::moveWindowToDesktopCenter()
|
||||||
{
|
{
|
||||||
if (!window()) {
|
const QQuickWindow * const w = window();
|
||||||
|
if (!w) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Q_D(FramelessQuickHelper);
|
std::ignore = Utils::moveWindowToDesktopCenter(w, true);
|
||||||
Utils::moveWindowToDesktopCenter(&d->getWindowData()->params, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessQuickHelper::bringWindowToFront()
|
void FramelessQuickHelper::bringWindowToFront()
|
||||||
|
@ -846,7 +873,7 @@ void FramelessQuickHelper::bringWindowToFront()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
std::ignore = Utils::bringWindowToFront(w->winId());
|
std::ignore = Utils::bringWindowToFront(w);
|
||||||
#else
|
#else
|
||||||
if (w->visibility() == QQuickWindow::Hidden) {
|
if (w->visibility() == QQuickWindow::Hidden) {
|
||||||
w->show();
|
w->show();
|
||||||
|
@ -898,7 +925,7 @@ void FramelessQuickHelper::setWindowFixedSize(const bool value)
|
||||||
w->setMaximumSize(QSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX));
|
w->setMaximumSize(QSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX));
|
||||||
}
|
}
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
std::ignore = Utils::setAeroSnappingEnabled(w->winId(), !value);
|
std::ignore = Utils::setAeroSnappingEnabled(w, !value);
|
||||||
#endif
|
#endif
|
||||||
Q_D(FramelessQuickHelper);
|
Q_D(FramelessQuickHelper);
|
||||||
d->emitSignalForAllInstances("windowFixedSizeChanged");
|
d->emitSignalForAllInstances("windowFixedSizeChanged");
|
||||||
|
@ -935,7 +962,7 @@ void FramelessQuickHelper::setBlurBehindWindowEnabled(const bool value)
|
||||||
}
|
}
|
||||||
mode = QuickGlobal::BlurMode::Disable;
|
mode = QuickGlobal::BlurMode::Disable;
|
||||||
}
|
}
|
||||||
if (Utils::setBlurBehindWindowEnabled(w->winId(), FRAMELESSHELPER_ENUM_QUICK_TO_CORE(BlurMode, mode), {})) {
|
if (Utils::setBlurBehindWindowEnabled(w, FRAMELESSHELPER_ENUM_QUICK_TO_CORE(BlurMode, mode), {})) {
|
||||||
d->blurBehindWindowEnabled = value;
|
d->blurBehindWindowEnabled = value;
|
||||||
d->emitSignalForAllInstances("blurBehindWindowEnabledChanged");
|
d->emitSignalForAllInstances("blurBehindWindowEnabledChanged");
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "widgetssharedhelper_p.h"
|
#include "widgetssharedhelper_p.h"
|
||||||
#include <FramelessHelper/Core/framelessmanager.h>
|
#include <FramelessHelper/Core/framelessmanager.h>
|
||||||
#include <FramelessHelper/Core/utils.h>
|
#include <FramelessHelper/Core/utils.h>
|
||||||
|
#include <FramelessHelper/Core/private/framelessmanager_p.h>
|
||||||
#include <FramelessHelper/Core/private/framelessconfig_p.h>
|
#include <FramelessHelper/Core/private/framelessconfig_p.h>
|
||||||
#include <FramelessHelper/Core/private/framelesshelpercore_global_p.h>
|
#include <FramelessHelper/Core/private/framelesshelpercore_global_p.h>
|
||||||
#include <QtCore/qhash.h>
|
#include <QtCore/qhash.h>
|
||||||
|
@ -71,10 +72,10 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||||
|
|
||||||
using namespace Global;
|
using namespace Global;
|
||||||
|
|
||||||
struct FramelessWidgetsHelperData
|
static constexpr const auto FRAMELESS_WIDGETS_HELPER_EXTRA_DATA_ID = quint8(2);
|
||||||
|
|
||||||
|
struct FramelessWidgetsHelperExtraData : public FramelessExtraData
|
||||||
{
|
{
|
||||||
bool ready = false;
|
|
||||||
SystemParameters params = {};
|
|
||||||
QPointer<QWidget> titleBarWidget = nullptr;
|
QPointer<QWidget> titleBarWidget = nullptr;
|
||||||
QList<QPointer<QWidget>> hitTestVisibleWidgets = {};
|
QList<QPointer<QWidget>> hitTestVisibleWidgets = {};
|
||||||
QPointer<QWidget> windowIconButton = nullptr;
|
QPointer<QWidget> windowIconButton = nullptr;
|
||||||
|
@ -83,11 +84,42 @@ struct FramelessWidgetsHelperData
|
||||||
QPointer<QWidget> maximizeButton = nullptr;
|
QPointer<QWidget> maximizeButton = nullptr;
|
||||||
QPointer<QWidget> closeButton = nullptr;
|
QPointer<QWidget> closeButton = nullptr;
|
||||||
QList<QRect> hitTestVisibleRects = {};
|
QList<QRect> hitTestVisibleRects = {};
|
||||||
|
|
||||||
|
[[nodiscard]] static FramelessExtraDataPtr create();
|
||||||
};
|
};
|
||||||
|
using FramelessWidgetsHelperExtraDataPtr = std::shared_ptr<FramelessWidgetsHelperExtraData>;
|
||||||
|
|
||||||
using FramelessWidgetsHelperInternal = QHash<WId, FramelessWidgetsHelperData>;
|
FramelessExtraDataPtr FramelessWidgetsHelperExtraData::create()
|
||||||
|
{
|
||||||
|
return std::make_shared<FramelessWidgetsHelperExtraData>();
|
||||||
|
}
|
||||||
|
|
||||||
Q_GLOBAL_STATIC(FramelessWidgetsHelperInternal, g_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());
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] static inline bool isWidgetFixedSize(const QWidget * const widget)
|
[[nodiscard]] static inline bool isWidgetFixedSize(const QWidget * const widget)
|
||||||
{
|
{
|
||||||
|
@ -421,7 +453,7 @@ void FramelessWidgetsHelperPrivate::attach()
|
||||||
params.resetQtGrabbedControl = []() -> bool {
|
params.resetQtGrabbedControl = []() -> bool {
|
||||||
if (qt_button_down) {
|
if (qt_button_down) {
|
||||||
static constexpr const auto invalidPos = QPoint{ -99999, -99999 };
|
static constexpr const auto invalidPos = QPoint{ -99999, -99999 };
|
||||||
const auto event = std::make_unique<QMouseEvent>(
|
const auto event = new QMouseEvent(
|
||||||
QEvent::MouseButtonRelease,
|
QEvent::MouseButtonRelease,
|
||||||
invalidPos,
|
invalidPos,
|
||||||
invalidPos,
|
invalidPos,
|
||||||
|
@ -429,7 +461,7 @@ void FramelessWidgetsHelperPrivate::attach()
|
||||||
Qt::LeftButton,
|
Qt::LeftButton,
|
||||||
QGuiApplication::mouseButtons() ^ Qt::LeftButton,
|
QGuiApplication::mouseButtons() ^ Qt::LeftButton,
|
||||||
QGuiApplication::keyboardModifiers());
|
QGuiApplication::keyboardModifiers());
|
||||||
QApplication::sendEvent(qt_button_down, event.get());
|
QApplication::postEvent(qt_button_down, event);
|
||||||
qt_button_down = nullptr;
|
qt_button_down = nullptr;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue