Compare commits

..

No commits in common. "8cc6a155352760cf363df432cc52957892334de2" and "d9ce1c4302ceabfd8748a7658ae9a2d918575303" have entirely different histories.

30 changed files with 399 additions and 379 deletions

View File

@ -100,13 +100,6 @@ QT_END_NAMESPACE
using QT_ENTER_EVENT_TYPE = QEvent; using QT_ENTER_EVENT_TYPE = QEvent;
#endif #endif
// QLatin1StringView can't be constexpr until Qt6?
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
# define Q_STRING_CONSTEXPR constexpr
#else
# define Q_STRING_CONSTEXPR
#endif
#ifndef QUtf8String #ifndef QUtf8String
# define QUtf8String(str) QString::fromUtf8(str) # define QUtf8String(str) QString::fromUtf8(str)
#endif #endif
@ -139,26 +132,6 @@ QT_END_NAMESPACE
# endif # endif
#endif #endif
#ifndef FRAMELESSHELPER_BYTEARRAY
# define FRAMELESSHELPER_BYTEARRAY(ba) ba
#endif
#ifndef FRAMELESSHELPER_STRING
# if (QT_VERSION >= QT_VERSION_CHECK(6, 4, 0))
# define FRAMELESSHELPER_STRING(str) str##_L1
# else
# define FRAMELESSHELPER_STRING(str) QLatin1String(str)
# endif
#endif
#ifndef FRAMELESSHELPER_STRING_TYPE
# if (QT_VERSION >= QT_VERSION_CHECK(6, 4, 0))
# define FRAMELESSHELPER_STRING_TYPE QLatin1StringView
# else
# define FRAMELESSHELPER_STRING_TYPE QLatin1String
# endif
#endif
#ifndef Q_UNREACHABLE_RETURN // Since 6.5 #ifndef Q_UNREACHABLE_RETURN // Since 6.5
# define Q_UNREACHABLE_RETURN(...) \ # define Q_UNREACHABLE_RETURN(...) \
do { \ do { \
@ -169,12 +142,12 @@ QT_END_NAMESPACE
#ifndef FRAMELESSHELPER_BYTEARRAY_CONSTANT2 #ifndef FRAMELESSHELPER_BYTEARRAY_CONSTANT2
# define FRAMELESSHELPER_BYTEARRAY_CONSTANT2(name, ba) \ # define FRAMELESSHELPER_BYTEARRAY_CONSTANT2(name, ba) \
[[maybe_unused]] static constexpr const auto k##name = FRAMELESSHELPER_BYTEARRAY(ba); [[maybe_unused]] static const auto k##name = FRAMELESSHELPER_BYTEARRAY_LITERAL(ba);
#endif #endif
#ifndef FRAMELESSHELPER_STRING_CONSTANT2 #ifndef FRAMELESSHELPER_STRING_CONSTANT2
# define FRAMELESSHELPER_STRING_CONSTANT2(name, str) \ # define FRAMELESSHELPER_STRING_CONSTANT2(name, str) \
[[maybe_unused]] static Q_STRING_CONSTEXPR const auto k##name = FRAMELESSHELPER_STRING(str); [[maybe_unused]] static const auto k##name = FRAMELESSHELPER_STRING_LITERAL(str);
#endif #endif
#ifndef FRAMELESSHELPER_BYTEARRAY_CONSTANT #ifndef FRAMELESSHELPER_BYTEARRAY_CONSTANT
@ -275,11 +248,16 @@ Q_NAMESPACE_EXPORT(FRAMELESSHELPER_CORE_API)
[[maybe_unused]] inline Q_COLOR_CONSTEXPR const QColor kDefaultSystemButtonBackgroundColor = {204, 204, 204}; // #CCCCCC [[maybe_unused]] inline Q_COLOR_CONSTEXPR const QColor kDefaultSystemButtonBackgroundColor = {204, 204, 204}; // #CCCCCC
[[maybe_unused]] inline Q_COLOR_CONSTEXPR const QColor kDefaultSystemCloseButtonBackgroundColor = {232, 17, 35}; // #E81123 [[maybe_unused]] inline Q_COLOR_CONSTEXPR const QColor kDefaultSystemCloseButtonBackgroundColor = {232, 17, 35}; // #E81123
[[maybe_unused]] inline constexpr const char kDontOverrideCursorVar[] = "FRAMELESSHELPER_DONT_OVERRIDE_CURSOR"; [[maybe_unused]] inline const QByteArray kDontOverrideCursorVar
[[maybe_unused]] inline constexpr const char kDontToggleMaximizeVar[] = "FRAMELESSHELPER_DONT_TOGGLE_MAXIMIZE"; = FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_DONT_OVERRIDE_CURSOR");
[[maybe_unused]] inline constexpr const char kSysMenuDisableMinimizeVar[] = "FRAMELESSHELPER_SYSTEM_MENU_DISABLE_MINIMIZE"; [[maybe_unused]] inline const QByteArray kDontToggleMaximizeVar
[[maybe_unused]] inline constexpr const char kSysMenuDisableMaximizeVar[] = "FRAMELESSHELPER_SYSTEM_MENU_DISABLE_MAXIMIZE"; = FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_DONT_TOGGLE_MAXIMIZE");
[[maybe_unused]] inline constexpr const char kSysMenuDisableRestoreVar[] = "FRAMELESSHELPER_SYSTEM_MENU_DISABLE_RESTORE"; [[maybe_unused]] inline const QByteArray kSysMenuDisableMinimizeVar
= FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_SYSTEM_MENU_DISABLE_MINIMIZE");
[[maybe_unused]] inline const QByteArray kSysMenuDisableMaximizeVar
= FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_SYSTEM_MENU_DISABLE_MAXIMIZE");
[[maybe_unused]] inline const QByteArray kSysMenuDisableRestoreVar
= FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_SYSTEM_MENU_DISABLE_RESTORE");
enum class Option : quint8 enum class Option : quint8
{ {

View File

@ -42,6 +42,9 @@ class FRAMELESSHELPER_CORE_API FramelessManager : public QObject
Q_PROPERTY(Global::WallpaperAspectStyle wallpaperAspectStyle READ wallpaperAspectStyle NOTIFY wallpaperChanged FINAL) Q_PROPERTY(Global::WallpaperAspectStyle wallpaperAspectStyle READ wallpaperAspectStyle NOTIFY wallpaperChanged FINAL)
public: public:
explicit FramelessManager(QObject *parent = nullptr);
~FramelessManager() override;
Q_NODISCARD static FramelessManager *instance(); Q_NODISCARD static FramelessManager *instance();
Q_NODISCARD Global::SystemTheme systemTheme() const; Q_NODISCARD Global::SystemTheme systemTheme() const;
@ -58,10 +61,6 @@ Q_SIGNALS:
void systemThemeChanged(); void systemThemeChanged();
void wallpaperChanged(); void wallpaperChanged();
private:
explicit FramelessManager(QObject *parent = nullptr);
~FramelessManager() override;
private: private:
QScopedPointer<FramelessManagerPrivate> d_ptr; QScopedPointer<FramelessManagerPrivate> d_ptr;
}; };

View File

@ -25,7 +25,6 @@
#pragma once #pragma once
#include <FramelessHelper/Core/framelesshelpercore_global.h> #include <FramelessHelper/Core/framelesshelpercore_global.h>
#include <optional>
FRAMELESSHELPER_BEGIN_NAMESPACE FRAMELESSHELPER_BEGIN_NAMESPACE

View File

@ -34,6 +34,9 @@ class FRAMELESSHELPER_CORE_API FramelessConfig : public QObject
Q_DISABLE_COPY_MOVE(FramelessConfig) Q_DISABLE_COPY_MOVE(FramelessConfig)
public: public:
explicit FramelessConfig(QObject *parent = nullptr);
~FramelessConfig() override;
Q_NODISCARD static FramelessConfig *instance(); Q_NODISCARD static FramelessConfig *instance();
void reload(const bool force = false); void reload(const bool force = false);
@ -43,10 +46,6 @@ public:
static void setLoadFromEnvironmentVariablesDisabled(const bool on = true); static void setLoadFromEnvironmentVariablesDisabled(const bool on = true);
static void setLoadFromConfigurationFileDisabled(const bool on = true); static void setLoadFromConfigurationFileDisabled(const bool on = true);
private:
explicit FramelessConfig(QObject *parent = nullptr);
~FramelessConfig() override;
}; };
FRAMELESSHELPER_END_NAMESPACE FRAMELESSHELPER_END_NAMESPACE

View File

@ -56,8 +56,8 @@ using SetSystemButtonStateCallback = std::function<void(const Global::SystemButt
using GetWindowIdCallback = std::function<WId()>; using GetWindowIdCallback = std::function<WId()>;
using ShouldIgnoreMouseEventsCallback = std::function<bool(const QPoint &)>; using ShouldIgnoreMouseEventsCallback = std::function<bool(const QPoint &)>;
using ShowSystemMenuCallback = std::function<void(const QPoint &)>; using ShowSystemMenuCallback = std::function<void(const QPoint &)>;
using SetPropertyCallback = std::function<void(const char *, const QVariant &)>; using SetPropertyCallback = std::function<void(const QByteArray &, const QVariant &)>;
using GetPropertyCallback = std::function<QVariant(const char *, const QVariant &)>; using GetPropertyCallback = std::function<QVariant(const QByteArray &, const QVariant &)>;
using SetCursorCallback = std::function<void(const QCursor &)>; using SetCursorCallback = std::function<void(const QCursor &)>;
using UnsetCursorCallback = std::function<void()>; using UnsetCursorCallback = std::function<void()>;
using GetWidgetHandleCallback = std::function<QObject *()>; using GetWidgetHandleCallback = std::function<QObject *()>;

View File

@ -25,7 +25,6 @@
#pragma once #pragma once
#include <FramelessHelper/Core/framelesshelpercore_global.h> #include <FramelessHelper/Core/framelesshelpercore_global.h>
#include <optional>
FRAMELESSHELPER_BEGIN_NAMESPACE FRAMELESSHELPER_BEGIN_NAMESPACE

View File

@ -26,7 +26,6 @@
#include <FramelessHelper/Core/framelesshelpercore_global.h> #include <FramelessHelper/Core/framelesshelpercore_global.h>
#include <QtCore/qvariant.h> #include <QtCore/qvariant.h>
#include <optional>
#ifndef REGISTRYKEY_FORCE_QSETTINGS #ifndef REGISTRYKEY_FORCE_QSETTINGS
# define REGISTRYKEY_FORCE_QSETTINGS (0) # define REGISTRYKEY_FORCE_QSETTINGS (0)

View File

@ -34,6 +34,9 @@ class FRAMELESSHELPER_CORE_API SysApiLoader : public QObject
Q_DISABLE_COPY_MOVE(SysApiLoader) Q_DISABLE_COPY_MOVE(SysApiLoader)
public: public:
explicit SysApiLoader(QObject *parent = nullptr);
~SysApiLoader() override;
Q_NODISCARD static SysApiLoader *instance(); Q_NODISCARD static SysApiLoader *instance();
Q_NODISCARD static QString platformSharedLibrarySuffixName(); Q_NODISCARD static QString platformSharedLibrarySuffixName();
@ -41,6 +44,7 @@ public:
Q_NODISCARD static QString generateUniqueKey(const QString &library, const QString &function); Q_NODISCARD static QString generateUniqueKey(const QString &library, const QString &function);
Q_NODISCARD static QFunctionPointer resolve(const QString &library, const char *function); Q_NODISCARD static QFunctionPointer resolve(const QString &library, const char *function);
Q_NODISCARD static QFunctionPointer resolve(const QString &library, const QByteArray &function);
Q_NODISCARD static QFunctionPointer resolve(const QString &library, const QString &function); Q_NODISCARD static QFunctionPointer resolve(const QString &library, const QString &function);
Q_NODISCARD bool isAvailable(const QString &library, const QString &function); Q_NODISCARD bool isAvailable(const QString &library, const QString &function);
@ -52,10 +56,6 @@ public:
{ {
return reinterpret_cast<T>(get(library, function)); return reinterpret_cast<T>(get(library, function));
} }
private:
explicit SysApiLoader(QObject *parent = nullptr);
~SysApiLoader() override;
}; };
FRAMELESSHELPER_END_NAMESPACE FRAMELESSHELPER_END_NAMESPACE

View File

@ -25,7 +25,6 @@
#pragma once #pragma once
#include <FramelessHelper/Core/framelesshelpercore_global.h> #include <FramelessHelper/Core/framelesshelpercore_global.h>
#include <array>
FRAMELESSHELPER_BEGIN_NAMESPACE FRAMELESSHELPER_BEGIN_NAMESPACE
@ -89,35 +88,35 @@ struct VersionNumber
}; };
#ifdef Q_OS_WINDOWS #ifdef Q_OS_WINDOWS
[[maybe_unused]] inline constexpr const std::array<VersionNumber, 27> WindowsVersions = [[maybe_unused]] inline constexpr const VersionNumber WindowsVersions[] =
{ {
VersionNumber{ 5, 0, 2195 }, // Windows 2000 { 5, 0, 2195}, // Windows 2000
VersionNumber{ 5, 1, 2600 }, // Windows XP { 5, 1, 2600}, // Windows XP
VersionNumber{ 5, 2, 3790 }, // Windows XP x64 Edition or Windows Server 2003 { 5, 2, 3790}, // Windows XP x64 Edition or Windows Server 2003
VersionNumber{ 6, 0, 6000 }, // Windows Vista { 6, 0, 6000}, // Windows Vista
VersionNumber{ 6, 0, 6001 }, // Windows Vista with Service Pack 1 or Windows Server 2008 { 6, 0, 6001}, // Windows Vista with Service Pack 1 or Windows Server 2008
VersionNumber{ 6, 0, 6002 }, // Windows Vista with Service Pack 2 { 6, 0, 6002}, // Windows Vista with Service Pack 2
VersionNumber{ 6, 1, 7600 }, // Windows 7 or Windows Server 2008 R2 { 6, 1, 7600}, // Windows 7 or Windows Server 2008 R2
VersionNumber{ 6, 1, 7601 }, // Windows 7 with Service Pack 1 or Windows Server 2008 R2 with Service Pack 1 { 6, 1, 7601}, // Windows 7 with Service Pack 1 or Windows Server 2008 R2 with Service Pack 1
VersionNumber{ 6, 2, 9200 }, // Windows 8 or Windows Server 2012 { 6, 2, 9200}, // Windows 8 or Windows Server 2012
VersionNumber{ 6, 3, 9200 }, // Windows 8.1 or Windows Server 2012 R2 { 6, 3, 9200}, // Windows 8.1 or Windows Server 2012 R2
VersionNumber{ 6, 3, 9600 }, // Windows 8.1 with Update 1 { 6, 3, 9600}, // Windows 8.1 with Update 1
VersionNumber{ 10, 0, 10240 }, // Windows 10 Version 1507 (TH1) {10, 0, 10240}, // Windows 10 Version 1507 (TH1)
VersionNumber{ 10, 0, 10586 }, // Windows 10 Version 1511 (November Update) (TH2) {10, 0, 10586}, // Windows 10 Version 1511 (November Update) (TH2)
VersionNumber{ 10, 0, 14393 }, // Windows 10 Version 1607 (Anniversary Update) (RS1) or Windows Server 2016 {10, 0, 14393}, // Windows 10 Version 1607 (Anniversary Update) (RS1) or Windows Server 2016
VersionNumber{ 10, 0, 15063 }, // Windows 10 Version 1703 (Creators Update) (RS2) {10, 0, 15063}, // Windows 10 Version 1703 (Creators Update) (RS2)
VersionNumber{ 10, 0, 16299 }, // Windows 10 Version 1709 (Fall Creators Update) (RS3) {10, 0, 16299}, // Windows 10 Version 1709 (Fall Creators Update) (RS3)
VersionNumber{ 10, 0, 17134 }, // Windows 10 Version 1803 (April 2018 Update) (RS4) {10, 0, 17134}, // Windows 10 Version 1803 (April 2018 Update) (RS4)
VersionNumber{ 10, 0, 17763 }, // Windows 10 Version 1809 (October 2018 Update) (RS5) or Windows Server 2019 {10, 0, 17763}, // Windows 10 Version 1809 (October 2018 Update) (RS5) or Windows Server 2019
VersionNumber{ 10, 0, 18362 }, // Windows 10 Version 1903 (May 2019 Update) (19H1) {10, 0, 18362}, // Windows 10 Version 1903 (May 2019 Update) (19H1)
VersionNumber{ 10, 0, 18363 }, // Windows 10 Version 1909 (November 2019 Update) (19H2) {10, 0, 18363}, // Windows 10 Version 1909 (November 2019 Update) (19H2)
VersionNumber{ 10, 0, 19041 }, // Windows 10 Version 2004 (May 2020 Update) (20H1) {10, 0, 19041}, // Windows 10 Version 2004 (May 2020 Update) (20H1)
VersionNumber{ 10, 0, 19042 }, // Windows 10 Version 20H2 (October 2020 Update) (20H2) {10, 0, 19042}, // Windows 10 Version 20H2 (October 2020 Update) (20H2)
VersionNumber{ 10, 0, 19043 }, // Windows 10 Version 21H1 (May 2021 Update) (21H1) {10, 0, 19043}, // Windows 10 Version 21H1 (May 2021 Update) (21H1)
VersionNumber{ 10, 0, 19044 }, // Windows 10 Version 21H2 (November 2021 Update) (21H2) {10, 0, 19044}, // Windows 10 Version 21H2 (November 2021 Update) (21H2)
VersionNumber{ 10, 0, 19045 }, // Windows 10 Version 22H2 (October 2022 Update) (22H2) {10, 0, 19045}, // Windows 10 Version 22H2 (October 2022 Update) (22H2)
VersionNumber{ 10, 0, 22000 }, // Windows 11 Version 21H2 (21H2) {10, 0, 22000}, // Windows 11 Version 21H2 (21H2)
VersionNumber{ 10, 0, 22621 } // Windows 11 Version 22H2 (October 2022 Update) (22H2) {10, 0, 22621} // Windows 11 Version 22H2 (October 2022 Update) (22H2)
}; };
#endif // Q_OS_WINDOWS #endif // Q_OS_WINDOWS

View File

@ -25,7 +25,6 @@
#pragma once #pragma once
#include <FramelessHelper/Core/framelesshelpercore_global.h> #include <FramelessHelper/Core/framelesshelpercore_global.h>
#include <optional>
FRAMELESSHELPER_BEGIN_NAMESPACE FRAMELESSHELPER_BEGIN_NAMESPACE

View File

@ -25,7 +25,6 @@
#pragma once #pragma once
#include <FramelessHelper/Quick/framelesshelperquick_global.h> #include <FramelessHelper/Quick/framelesshelperquick_global.h>
#include <optional>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QQuickItem; class QQuickItem;
@ -73,13 +72,13 @@ public:
Q_NODISCARD bool isWindowFixedSize() const; Q_NODISCARD bool isWindowFixedSize() const;
void setWindowFixedSize(const bool value); void setWindowFixedSize(const bool value);
void emitSignalForAllInstances(const char *signal); void emitSignalForAllInstances(const QByteArray &signal);
Q_NODISCARD bool isBlurBehindWindowEnabled() const; Q_NODISCARD bool isBlurBehindWindowEnabled() const;
void setBlurBehindWindowEnabled(const bool value, const QColor &color); void setBlurBehindWindowEnabled(const bool value, const QColor &color);
void setProperty(const char *name, const QVariant &value); void setProperty(const QByteArray &name, const QVariant &value);
Q_NODISCARD QVariant getProperty(const char *name, const QVariant &defaultValue = {}); Q_NODISCARD QVariant getProperty(const QByteArray &name, const QVariant &defaultValue = {});
Q_NODISCARD QuickMicaMaterial *findOrCreateMicaMaterial() const; Q_NODISCARD QuickMicaMaterial *findOrCreateMicaMaterial() const;
Q_NODISCARD QuickWindowBorder *findOrCreateWindowBorder() const; Q_NODISCARD QuickWindowBorder *findOrCreateWindowBorder() const;

View File

@ -71,13 +71,13 @@ public:
Q_NODISCARD bool isWindowFixedSize() const; Q_NODISCARD bool isWindowFixedSize() const;
void setWindowFixedSize(const bool value); void setWindowFixedSize(const bool value);
void emitSignalForAllInstances(const char *signal); void emitSignalForAllInstances(const QByteArray &signal);
Q_NODISCARD bool isBlurBehindWindowEnabled() const; Q_NODISCARD bool isBlurBehindWindowEnabled() const;
void setBlurBehindWindowEnabled(const bool enable, const QColor &color); void setBlurBehindWindowEnabled(const bool enable, const QColor &color);
void setProperty(const char *name, const QVariant &value); void setProperty(const QByteArray &name, const QVariant &value);
Q_NODISCARD QVariant getProperty(const char *name, const QVariant &defaultValue = {}); Q_NODISCARD QVariant getProperty(const QByteArray &name, const QVariant &defaultValue = {});
Q_NODISCARD QWidget *window() const; Q_NODISCARD QWidget *window() const;

View File

@ -25,7 +25,6 @@
#pragma once #pragma once
#include <FramelessHelper/Widgets/framelesshelperwidgets_global.h> #include <FramelessHelper/Widgets/framelesshelperwidgets_global.h>
#include <optional>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QEnterEvent; class QEnterEvent;

View File

@ -26,7 +26,6 @@
#include <FramelessHelper/Widgets/framelesshelperwidgets_global.h> #include <FramelessHelper/Widgets/framelesshelperwidgets_global.h>
#include <QtGui/qfont.h> #include <QtGui/qfont.h>
#include <optional>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QPaintEvent; class QPaintEvent;

View File

@ -95,11 +95,10 @@ void ChromePalettePrivate::refresh()
// Calculate the most appropriate foreground color, based on the // Calculate the most appropriate foreground color, based on the
// current background color. // current background color.
const qreal grayF = ( const qreal grayF = (
(qreal(0.299) * titleBarActiveBackgroundColor_sys.redF()) + (0.299 * titleBarActiveBackgroundColor_sys.redF()) +
(qreal(0.587) * titleBarActiveBackgroundColor_sys.greenF()) + (0.587 * titleBarActiveBackgroundColor_sys.greenF()) +
(qreal(0.114) * titleBarActiveBackgroundColor_sys.blueF())); (0.114 * titleBarActiveBackgroundColor_sys.blueF()));
static constexpr const auto kFlag = qreal(0.5); if (grayF <= 0.5) {
if ((grayF < kFlag) || qFuzzyCompare(grayF, kFlag)) {
return kDefaultWhiteColor; return kDefaultWhiteColor;
} }
} }

View File

@ -23,7 +23,6 @@
*/ */
#include "framelessconfig_p.h" #include "framelessconfig_p.h"
#include <array>
#include <QtCore/qdir.h> #include <QtCore/qdir.h>
#include <QtCore/qsettings.h> #include <QtCore/qsettings.h>
#include <QtCore/qcoreapplication.h> #include <QtCore/qcoreapplication.h>
@ -48,29 +47,38 @@ static Q_LOGGING_CATEGORY(lcFramelessConfig, "wangwenx190.framelesshelper.core.f
using namespace Global; using namespace Global;
struct FramelessConfigEntry FRAMELESSHELPER_STRING_CONSTANT2(ConfigFileName, ".framelesshelper.ini")
static const struct
{ {
const char *env = nullptr; const QByteArray env = {};
const char *cfg = nullptr; const QByteArray cfg = {};
} OptionsTable[] = {
{FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_USE_CROSS_PLATFORM_QT_IMPLEMENTATION"),
FRAMELESSHELPER_BYTEARRAY_LITERAL("Options/UseCrossPlatformQtImplementation")},
{FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_FORCE_HIDE_WINDOW_FRAME_BORDER"),
FRAMELESSHELPER_BYTEARRAY_LITERAL("Options/ForceHideWindowFrameBorder")},
{FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_FORCE_SHOW_WINDOW_FRAME_BORDER"),
FRAMELESSHELPER_BYTEARRAY_LITERAL("Options/ForceShowWindowFrameBorder")},
{FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_DISABLE_WINDOWS_SNAP_LAYOUT"),
FRAMELESSHELPER_BYTEARRAY_LITERAL("Options/DisableWindowsSnapLayout")},
{FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_WINDOW_USE_ROUND_CORNERS"),
FRAMELESSHELPER_BYTEARRAY_LITERAL("Options/WindowUseRoundCorners")},
{FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_CENTER_WINDOW_BEFORE_SHOW"),
FRAMELESSHELPER_BYTEARRAY_LITERAL("Options/CenterWindowBeforeShow")},
{FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_ENABLE_BLUR_BEHIND_WINDOW"),
FRAMELESSHELPER_BYTEARRAY_LITERAL("Options/EnableBlurBehindWindow")},
{FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_FORCE_NON_NATIVE_BACKGROUND_BLUR"),
FRAMELESSHELPER_BYTEARRAY_LITERAL("Options/ForceNonNativeBackgroundBlur")},
{FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_DISABLE_LAZY_INITIALIZATION_FOR_MICA_MATERIAL"),
FRAMELESSHELPER_BYTEARRAY_LITERAL("Options/DisableLazyInitializationForMicaMaterial")},
{FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_FORCE_NATIVE_BACKGROUND_BLUR"),
FRAMELESSHELPER_BYTEARRAY_LITERAL("Options/ForceNativeBackgroundBlur")}
}; };
static constexpr const std::array<FramelessConfigEntry, 10> FramelessOptionsTable = static constexpr const auto OptionCount = std::size(OptionsTable);
{
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" },
FramelessConfigEntry{ "FRAMELESSHELPER_WINDOW_USE_ROUND_CORNERS", "Options/WindowUseRoundCorners" },
FramelessConfigEntry{ "FRAMELESSHELPER_CENTER_WINDOW_BEFORE_SHOW", "Options/CenterWindowBeforeShow" },
FramelessConfigEntry{ "FRAMELESSHELPER_ENABLE_BLUR_BEHIND_WINDOW", "Options/EnableBlurBehindWindow" },
FramelessConfigEntry{ "FRAMELESSHELPER_FORCE_NON_NATIVE_BACKGROUND_BLUR", "Options/ForceNonNativeBackgroundBlur" },
FramelessConfigEntry{ "FRAMELESSHELPER_DISABLE_LAZY_INITIALIZATION_FOR_MICA_MATERIAL", "Options/DisableLazyInitializationForMicaMaterial" },
FramelessConfigEntry{ "FRAMELESSHELPER_FORCE_NATIVE_BACKGROUND_BLUR", "Options/ForceNativeBackgroundBlur" }
};
static constexpr const auto OptionCount = std::size(FramelessOptionsTable); struct ConfigData
struct FramelessConfigData
{ {
bool loaded = false; bool loaded = false;
bool options[OptionCount] = {}; bool options[OptionCount] = {};
@ -78,7 +86,9 @@ struct FramelessConfigData
bool disableCfgFile = false; bool disableCfgFile = false;
}; };
Q_GLOBAL_STATIC(FramelessConfigData, g_framelessConfigData) Q_GLOBAL_STATIC(ConfigData, g_data)
Q_GLOBAL_STATIC(FramelessConfig, g_config)
static inline void warnInappropriateOptions() static inline void warnInappropriateOptions()
{ {
@ -117,13 +127,12 @@ FramelessConfig::~FramelessConfig() = default;
FramelessConfig *FramelessConfig::instance() FramelessConfig *FramelessConfig::instance()
{ {
static FramelessConfig config; return g_config();
return &config;
} }
void FramelessConfig::reload(const bool force) void FramelessConfig::reload(const bool force)
{ {
if (g_framelessConfigData()->loaded && !force) { if (g_data()->loaded && !force) {
return; return;
} }
const auto configFile = []() -> std::unique_ptr<QSettings> { const auto configFile = []() -> std::unique_ptr<QSettings> {
@ -131,39 +140,39 @@ void FramelessConfig::reload(const bool force)
return nullptr; return nullptr;
} }
const QDir appDir(QCoreApplication::applicationDirPath()); const QDir appDir(QCoreApplication::applicationDirPath());
return std::make_unique<QSettings>(appDir.filePath(FRAMELESSHELPER_STRING_LITERAL(".framelesshelper.ini")), QSettings::IniFormat); return std::make_unique<QSettings>(appDir.filePath(kConfigFileName), QSettings::IniFormat);
}(); }();
for (int i = 0; i != OptionCount; ++i) { for (int i = 0; i != OptionCount; ++i) {
const bool envVar = (!g_framelessConfigData()->disableEnvVar const bool envVar = (!g_data()->disableEnvVar
&& qEnvironmentVariableIsSet(FramelessOptionsTable.at(i).env) && qEnvironmentVariableIsSet(OptionsTable[i].env.constData())
&& (qEnvironmentVariableIntValue(FramelessOptionsTable.at(i).env) > 0)); && (qEnvironmentVariableIntValue(OptionsTable[i].env.constData()) > 0));
const bool cfgFile = (!g_framelessConfigData()->disableCfgFile && configFile const bool cfgFile = (!g_data()->disableCfgFile && configFile
&& configFile->value(QUtf8String(FramelessOptionsTable.at(i).cfg), false).toBool()); && configFile->value(QUtf8String(OptionsTable[i].cfg), false).toBool());
g_framelessConfigData()->options[i] = (envVar || cfgFile); g_data()->options[i] = (envVar || cfgFile);
} }
g_framelessConfigData()->loaded = true; g_data()->loaded = true;
QTimer::singleShot(0, this, [](){ warnInappropriateOptions(); }); QTimer::singleShot(0, this, [](){ warnInappropriateOptions(); });
} }
void FramelessConfig::set(const Option option, const bool on) void FramelessConfig::set(const Option option, const bool on)
{ {
g_framelessConfigData()->options[static_cast<int>(option)] = on; g_data()->options[static_cast<int>(option)] = on;
} }
bool FramelessConfig::isSet(const Option option) const bool FramelessConfig::isSet(const Option option) const
{ {
return g_framelessConfigData()->options[static_cast<int>(option)]; return g_data()->options[static_cast<int>(option)];
} }
void FramelessConfig::setLoadFromEnvironmentVariablesDisabled(const bool on) void FramelessConfig::setLoadFromEnvironmentVariablesDisabled(const bool on)
{ {
g_framelessConfigData()->disableEnvVar = on; g_data()->disableEnvVar = on;
} }
void FramelessConfig::setLoadFromConfigurationFileDisabled(const bool on) void FramelessConfig::setLoadFromConfigurationFileDisabled(const bool on)
{ {
g_framelessConfigData()->disableCfgFile = on; g_data()->disableCfgFile = on;
} }
FRAMELESSHELPER_END_NAMESPACE FRAMELESSHELPER_END_NAMESPACE

View File

@ -50,7 +50,7 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
using namespace Global; using namespace Global;
struct FramelessQtHelperData struct QtHelperData
{ {
SystemParameters params = {}; SystemParameters params = {};
FramelessHelperQt *eventFilter = nullptr; FramelessHelperQt *eventFilter = nullptr;
@ -58,12 +58,12 @@ struct FramelessQtHelperData
bool leftButtonPressed = false; bool leftButtonPressed = false;
}; };
struct FramelessQtHelper struct QtHelper
{ {
QHash<WId, FramelessQtHelperData> data = {}; QHash<WId, QtHelperData> data = {};
}; };
Q_GLOBAL_STATIC(FramelessQtHelper, g_framelessQtHelperData) Q_GLOBAL_STATIC(QtHelper, g_qtHelper)
FramelessHelperQt::FramelessHelperQt(QObject *parent) : QObject(parent) {} FramelessHelperQt::FramelessHelperQt(QObject *parent) : QObject(parent) {}
@ -76,16 +76,15 @@ void FramelessHelperQt::addWindow(FramelessParamsConst params)
return; return;
} }
const WId windowId = params->getWindowId(); const WId windowId = params->getWindowId();
const auto it = g_framelessQtHelperData()->data.constFind(windowId); if (g_qtHelper()->data.contains(windowId)) {
if (it != g_framelessQtHelperData()->data.constEnd()) {
return; return;
} }
FramelessQtHelperData data = {}; QtHelperData data = {};
data.params = *params; data.params = *params;
QWindow *window = params->getWindowHandle(); QWindow *window = params->getWindowHandle();
// Give it a parent so that it can be automatically deleted by Qt. // Give it a parent so that it can be automatically deleted by Qt.
data.eventFilter = new FramelessHelperQt(window); data.eventFilter = new FramelessHelperQt(window);
g_framelessQtHelperData()->data.insert(windowId, data); g_qtHelper()->data.insert(windowId, data);
const auto shouldApplyFramelessFlag = []() -> bool { const auto shouldApplyFramelessFlag = []() -> bool {
#ifdef Q_OS_MACOS #ifdef Q_OS_MACOS
return false; return false;
@ -102,7 +101,7 @@ void FramelessHelperQt::addWindow(FramelessParamsConst params)
params->setWindowFlags(params->getWindowFlags() | Qt::FramelessWindowHint); params->setWindowFlags(params->getWindowFlags() | Qt::FramelessWindowHint);
} else { } else {
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX
std::ignore = Utils::tryHideSystemTitleBar(windowId, true); Q_UNUSED(Utils::tryHideSystemTitleBar(windowId, true));
#elif defined(Q_OS_MACOS) #elif defined(Q_OS_MACOS)
Utils::setSystemTitleBarVisible(windowId, false); Utils::setSystemTitleBarVisible(windowId, false);
#endif // Q_OS_LINUX #endif // Q_OS_LINUX
@ -117,11 +116,10 @@ void FramelessHelperQt::removeWindow(const WId windowId)
if (!windowId) { if (!windowId) {
return; return;
} }
const auto it = g_framelessQtHelperData()->data.constFind(windowId); if (!g_qtHelper()->data.contains(windowId)) {
if (it == g_framelessQtHelperData()->data.constEnd()) {
return; return;
} }
g_framelessQtHelperData()->data.erase(it); g_qtHelper()->data.remove(windowId);
#ifdef Q_OS_MACOS #ifdef Q_OS_MACOS
Utils::removeWindowProxy(windowId); Utils::removeWindowProxy(windowId);
#endif #endif
@ -165,12 +163,10 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event)
} }
const auto window = qobject_cast<QWindow *>(object); const auto window = qobject_cast<QWindow *>(object);
const WId windowId = window->winId(); const WId windowId = window->winId();
const auto it = g_framelessQtHelperData()->data.find(windowId); if (!g_qtHelper()->data.contains(windowId)) {
if (it == g_framelessQtHelperData()->data.end()) {
return QObject::eventFilter(object, event); return QObject::eventFilter(object, event);
} }
const FramelessQtHelperData &data = it.value(); const QtHelperData data = g_qtHelper()->data.value(windowId);
FramelessQtHelperData &muData = it.value();
#if (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0))
if (type == QEvent::DevicePixelRatioChange) if (type == QEvent::DevicePixelRatioChange)
#else // QT_VERSION < QT_VERSION_CHECK(6, 6, 0) #else // QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
@ -197,7 +193,7 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event)
switch (type) { switch (type) {
case QEvent::MouseButtonPress: { case QEvent::MouseButtonPress: {
if (button == Qt::LeftButton) { if (button == Qt::LeftButton) {
muData.leftButtonPressed = true; g_qtHelper()->data[windowId].leftButtonPressed = true;
if (!windowFixedSize) { if (!windowFixedSize) {
const Qt::Edges edges = Utils::calculateWindowEdges(window, scenePos); const Qt::Edges edges = Utils::calculateWindowEdges(window, scenePos);
if (edges != Qt::Edges{}) { if (edges != Qt::Edges{}) {
@ -210,7 +206,7 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event)
} break; } break;
case QEvent::MouseButtonRelease: { case QEvent::MouseButtonRelease: {
if (button == Qt::LeftButton) { if (button == Qt::LeftButton) {
muData.leftButtonPressed = false; g_qtHelper()->data[windowId].leftButtonPressed = false;
} }
if (button == Qt::RightButton) { if (button == Qt::RightButton) {
if (!ignoreThisEvent && insideTitleBar) { if (!ignoreThisEvent && insideTitleBar) {
@ -237,11 +233,11 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event)
if (cs == Qt::ArrowCursor) { if (cs == Qt::ArrowCursor) {
if (data.cursorShapeChanged) { if (data.cursorShapeChanged) {
data.params.unsetCursor(); data.params.unsetCursor();
muData.cursorShapeChanged = false; g_qtHelper()->data[windowId].cursorShapeChanged = false;
} }
} else { } else {
data.params.setCursor(cs); data.params.setCursor(cs);
muData.cursorShapeChanged = true; g_qtHelper()->data[windowId].cursorShapeChanged = true;
} }
} }
if (data.leftButtonPressed) { if (data.leftButtonPressed) {

View File

@ -30,7 +30,6 @@
#include "winverhelper_p.h" #include "winverhelper_p.h"
#include "framelesshelper_windows.h" #include "framelesshelper_windows.h"
#include "framelesshelpercore_global_p.h" #include "framelesshelpercore_global_p.h"
#include <optional>
#include <QtCore/qhash.h> #include <QtCore/qhash.h>
#include <QtCore/qvariant.h> #include <QtCore/qvariant.h>
#include <QtCore/qcoreapplication.h> #include <QtCore/qcoreapplication.h>
@ -56,7 +55,9 @@ static Q_LOGGING_CATEGORY(lcFramelessHelperWin, "wangwenx190.framelesshelper.cor
using namespace Global; using namespace Global;
[[maybe_unused]] static constexpr const wchar_t kFallbackTitleBarWindowClassName[] = L"org.wangwenx190.FramelessHelper.FallbackTitleBarWindow"; [[maybe_unused]] static constexpr const wchar_t kFallbackTitleBarWindowClassName[] =
L"org.wangwenx190.FramelessHelper.FallbackTitleBarWindow";
FRAMELESSHELPER_BYTEARRAY_CONSTANT2(Win32MessageTypeName, "windows_generic_MSG")
FRAMELESSHELPER_STRING_CONSTANT(MonitorFromWindow) FRAMELESSHELPER_STRING_CONSTANT(MonitorFromWindow)
FRAMELESSHELPER_STRING_CONSTANT(GetMonitorInfoW) FRAMELESSHELPER_STRING_CONSTANT(GetMonitorInfoW)
FRAMELESSHELPER_STRING_CONSTANT(ScreenToClient) FRAMELESSHELPER_STRING_CONSTANT(ScreenToClient)
@ -84,8 +85,15 @@ FRAMELESSHELPER_STRING_CONSTANT(UnregisterClassW)
FRAMELESSHELPER_STRING_CONSTANT(DestroyWindow) FRAMELESSHELPER_STRING_CONSTANT(DestroyWindow)
FRAMELESSHELPER_STRING_CONSTANT(GetWindowPlacement) FRAMELESSHELPER_STRING_CONSTANT(GetWindowPlacement)
FRAMELESSHELPER_STRING_CONSTANT(SetWindowPlacement) FRAMELESSHELPER_STRING_CONSTANT(SetWindowPlacement)
[[maybe_unused]] static constexpr const char kFallbackTitleBarErrorMessage[] =
"FramelessHelper is unable to create the fallback title bar window, and thus the snap layout feature will be disabled"
" unconditionally. You can ignore this error and continue running your application, nothing else will be affected, "
"no need to worry. But if you really need the snap layout feature, please add a manifest file to your application and "
"explicitly declare Windows 11 compatibility in it. If you just want to hide this error message, please use the "
"FramelessConfig class to officially disable the snap layout feature for Windows 11.";
[[maybe_unused]] static constexpr const char kD3DWorkaroundEnvVar[] = "FRAMELESSHELPER_USE_D3D_WORKAROUND";
struct FramelessWin32HelperData struct Win32HelperData
{ {
SystemParameters params = {}; SystemParameters params = {};
bool trackingMouse = false; bool trackingMouse = false;
@ -96,14 +104,14 @@ struct FramelessWin32HelperData
#endif // (QT_VERSION < QT_VERSION_CHECK(6, 5, 1)) #endif // (QT_VERSION < QT_VERSION_CHECK(6, 5, 1))
}; };
struct FramelessWin32Helper struct Win32Helper
{ {
std::unique_ptr<FramelessHelperWin> nativeEventFilter = nullptr; std::unique_ptr<FramelessHelperWin> nativeEventFilter = nullptr;
QHash<WId, FramelessWin32HelperData> data = {}; QHash<WId, Win32HelperData> data = {};
QHash<WId, WId> fallbackTitleBarToParentWindowMapping = {}; QHash<WId, WId> fallbackTitleBarToParentWindowMapping = {};
}; };
Q_GLOBAL_STATIC(FramelessWin32Helper, g_framelessWin32HelperData) Q_GLOBAL_STATIC(Win32Helper, g_win32Helper)
[[nodiscard]] extern bool operator==(const RECT &lhs, const RECT &rhs) noexcept; [[nodiscard]] extern bool operator==(const RECT &lhs, const RECT &rhs) noexcept;
[[nodiscard]] extern bool operator!=(const RECT &lhs, const RECT &rhs) noexcept; [[nodiscard]] extern bool operator!=(const RECT &lhs, const RECT &rhs) noexcept;
@ -134,17 +142,14 @@ Q_GLOBAL_STATIC(FramelessWin32Helper, g_framelessWin32HelperData)
return DefWindowProcW(hWnd, uMsg, wParam, lParam); return DefWindowProcW(hWnd, uMsg, wParam, lParam);
} }
const auto windowId = reinterpret_cast<WId>(hWnd); const auto windowId = reinterpret_cast<WId>(hWnd);
const auto fallbackTitleBarIt = g_framelessWin32HelperData()->fallbackTitleBarToParentWindowMapping.constFind(windowId); if (!g_win32Helper()->fallbackTitleBarToParentWindowMapping.contains(windowId)) {
if (fallbackTitleBarIt == g_framelessWin32HelperData()->fallbackTitleBarToParentWindowMapping.constEnd()) {
return DefWindowProcW(hWnd, uMsg, wParam, lParam); return DefWindowProcW(hWnd, uMsg, wParam, lParam);
} }
const WId parentWindowId = fallbackTitleBarIt.value(); const WId parentWindowId = g_win32Helper()->fallbackTitleBarToParentWindowMapping.value(windowId);
const auto it = g_framelessWin32HelperData()->data.find(parentWindowId); if (!g_win32Helper()->data.contains(parentWindowId)) {
if (it == g_framelessWin32HelperData()->data.end()) {
return DefWindowProcW(hWnd, uMsg, wParam, lParam); return DefWindowProcW(hWnd, uMsg, wParam, lParam);
} }
const FramelessWin32HelperData &data = it.value(); const Win32HelperData data = g_win32Helper()->data.value(parentWindowId);
FramelessWin32HelperData &muData = it.value();
const auto parentWindowHandle = reinterpret_cast<HWND>(parentWindowId); const auto parentWindowHandle = reinterpret_cast<HWND>(parentWindowId);
// All mouse events: client area mouse events + non-client area mouse events. // All mouse events: client area mouse events + non-client area mouse events.
// Hit-testing event should not be considered as a mouse event. // Hit-testing event should not be considered as a mouse event.
@ -276,14 +281,14 @@ Q_GLOBAL_STATIC(FramelessWin32Helper, g_framelessWin32HelperData)
WARNING << Utils::getSystemErrorMessage(kTrackMouseEvent); WARNING << Utils::getSystemErrorMessage(kTrackMouseEvent);
break; break;
} }
muData.trackingMouse = true; g_win32Helper()->data[parentWindowId].trackingMouse = true;
} }
} break; } break;
case WM_NCMOUSELEAVE: case WM_NCMOUSELEAVE:
case WM_MOUSELEAVE: { case WM_MOUSELEAVE: {
// When the mouse leaves the drag rect, make sure to dismiss any hover. // When the mouse leaves the drag rect, make sure to dismiss any hover.
releaseButtons(std::nullopt); releaseButtons(std::nullopt);
muData.trackingMouse = false; g_win32Helper()->data[parentWindowId].trackingMouse = false;
} break; } break;
// NB: *Shouldn't be forwarding these* when they're not over the caption // NB: *Shouldn't be forwarding these* when they're not over the caption
// because they can inadvertently take action using the system's default // because they can inadvertently take action using the system's default
@ -470,10 +475,8 @@ static inline void cleanupFallbackWindow()
WARNING << "Failed to register the window class for the fallback title bar window."; WARNING << "Failed to register the window class for the fallback title bar window.";
return false; return false;
} }
static constexpr const auto style = DWORD(WS_CHILD); const HWND fallbackTitleBarWindowHandle = CreateWindowExW((WS_EX_LAYERED | WS_EX_NOREDIRECTIONBITMAP),
static constexpr const auto exStyle = DWORD(WS_EX_LAYERED | WS_EX_NOREDIRECTIONBITMAP); kFallbackTitleBarWindowClassName, nullptr, WS_CHILD, 0, 0, 0, 0,
const HWND fallbackTitleBarWindowHandle = CreateWindowExW(exStyle,
kFallbackTitleBarWindowClassName, nullptr, style, 0, 0, 0, 0,
parentWindowHandle, nullptr, instance, nullptr); parentWindowHandle, nullptr, instance, nullptr);
// Some users reported that when using MinGW, the following assert won't trigger any // Some users reported that when using MinGW, the following assert won't trigger any
// message box and will just crash, that's absolutely not what we would want to see. // message box and will just crash, that's absolutely not what we would want to see.
@ -481,13 +484,10 @@ static inline void cleanupFallbackWindow()
// error, so let's just remove this assert anyway. It is meant to give the user some // error, so let's just remove this assert anyway. It is meant to give the user some
// hint about how to use the snap layout feature, but now it seems things are going // hint about how to use the snap layout feature, but now it seems things are going
// to a wrong direction instead. // to a wrong direction instead.
//Q_ASSERT_X(fallbackTitleBarWindowHandle, __FUNCTION__, kFallbackTitleBarErrorMessage);
if (!fallbackTitleBarWindowHandle) { if (!fallbackTitleBarWindowHandle) {
WARNING << Utils::getSystemErrorMessage(kCreateWindowExW); WARNING << Utils::getSystemErrorMessage(kCreateWindowExW);
WARNING << "FramelessHelper is unable to create the fallback title bar window, and thus the snap layout feature will be disabled" WARNING << kFallbackTitleBarErrorMessage;
" unconditionally. You can ignore this error and continue running your application, nothing else will be affected, "
"no need to worry. But if you really need the snap layout feature, please add a manifest file to your application and "
"explicitly declare Windows 11 compatibility in it. If you just want to hide this error message, please use the "
"FramelessConfig class to officially disable the snap layout feature for Windows 11.";
return false; return false;
} }
// Layered windows won't become visible unless we call the SetLayeredWindowAttributes() // Layered windows won't become visible unless we call the SetLayeredWindowAttributes()
@ -501,10 +501,10 @@ static inline void cleanupFallbackWindow()
WARNING << "Failed to re-position the fallback title bar window."; WARNING << "Failed to re-position the fallback title bar window.";
return false; return false;
} }
g_framelessWin32HelperData()->data[parentWindowId].fallbackTitleBarWindowId = fallbackTitleBarWindowId; g_win32Helper()->data[parentWindowId].fallbackTitleBarWindowId = fallbackTitleBarWindowId;
g_framelessWin32HelperData()->fallbackTitleBarToParentWindowMapping.insert(fallbackTitleBarWindowId, parentWindowId); g_win32Helper()->fallbackTitleBarToParentWindowMapping.insert(fallbackTitleBarWindowId, parentWindowId);
// ### Why do we need an extra resize here? // ### Why do we need an extra resize here?
QTimer::singleShot(200, qApp, [parentWindowId, fallbackTitleBarWindowId, hide](){ QTimer::singleShot(0, qApp, [parentWindowId, fallbackTitleBarWindowId, hide](){
std::ignore = resizeFallbackTitleBarWindow(parentWindowId, fallbackTitleBarWindowId, hide); std::ignore = resizeFallbackTitleBarWindow(parentWindowId, fallbackTitleBarWindowId, hide);
}); });
return true; return true;
@ -521,17 +521,16 @@ void FramelessHelperWin::addWindow(FramelessParamsConst params)
return; return;
} }
const WId windowId = params->getWindowId(); const WId windowId = params->getWindowId();
const auto it = g_framelessWin32HelperData()->data.constFind(windowId); if (g_win32Helper()->data.contains(windowId)) {
if (it != g_framelessWin32HelperData()->data.constEnd()) {
return; return;
} }
FramelessWin32HelperData data = {}; Win32HelperData data = {};
data.params = *params; data.params = *params;
data.dpi = {Utils::getWindowDpi(windowId, true), Utils::getWindowDpi(windowId, false)}; data.dpi = {Utils::getWindowDpi(windowId, true), Utils::getWindowDpi(windowId, false)};
g_framelessWin32HelperData()->data.insert(windowId, data); g_win32Helper()->data.insert(windowId, data);
if (!g_framelessWin32HelperData()->nativeEventFilter) { if (!g_win32Helper()->nativeEventFilter) {
g_framelessWin32HelperData()->nativeEventFilter = std::make_unique<FramelessHelperWin>(); g_win32Helper()->nativeEventFilter = std::make_unique<FramelessHelperWin>();
qApp->installNativeEventFilter(g_framelessWin32HelperData()->nativeEventFilter.get()); qApp->installNativeEventFilter(g_win32Helper()->nativeEventFilter.get());
} }
DEBUG.noquote() << "The DPI of window" << hwnd2str(windowId) << "is" << data.dpi; DEBUG.noquote() << "The DPI of window" << hwnd2str(windowId) << "is" << data.dpi;
// Remove the bad window styles added by Qt (it's not that "bad" though). // Remove the bad window styles added by Qt (it's not that "bad" though).
@ -587,30 +586,29 @@ void FramelessHelperWin::removeWindow(const WId windowId)
if (!windowId) { if (!windowId) {
return; return;
} }
const auto it = g_framelessWin32HelperData()->data.constFind(windowId); if (!g_win32Helper()->data.contains(windowId)) {
if (it == g_framelessWin32HelperData()->data.constEnd()) {
return; return;
} }
g_framelessWin32HelperData()->data.erase(it); g_win32Helper()->data.remove(windowId);
if (g_framelessWin32HelperData()->data.isEmpty()) { if (g_win32Helper()->data.isEmpty()) {
if (g_framelessWin32HelperData()->nativeEventFilter) { if (g_win32Helper()->nativeEventFilter) {
qApp->removeNativeEventFilter(g_framelessWin32HelperData()->nativeEventFilter.get()); qApp->removeNativeEventFilter(g_win32Helper()->nativeEventFilter.get());
g_framelessWin32HelperData()->nativeEventFilter.reset(); g_win32Helper()->nativeEventFilter.reset();
} }
} }
auto fallbackTitleBarIt = g_framelessWin32HelperData()->fallbackTitleBarToParentWindowMapping.constBegin(); auto it = g_win32Helper()->fallbackTitleBarToParentWindowMapping.constBegin();
while (fallbackTitleBarIt != g_framelessWin32HelperData()->fallbackTitleBarToParentWindowMapping.constEnd()) { while (it != g_win32Helper()->fallbackTitleBarToParentWindowMapping.constEnd()) {
if (fallbackTitleBarIt.value() == windowId) { if (it.value() == windowId) {
g_framelessWin32HelperData()->fallbackTitleBarToParentWindowMapping.erase(fallbackTitleBarIt); g_win32Helper()->fallbackTitleBarToParentWindowMapping.remove(it.key());
break; break;
} }
++fallbackTitleBarIt; ++it;
} }
} }
bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *message, QT_NATIVE_EVENT_RESULT_TYPE *result) bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *message, QT_NATIVE_EVENT_RESULT_TYPE *result)
{ {
if ((eventType != "windows_generic_MSG") || !message || !result) { if ((eventType != kWin32MessageTypeName) || !message || !result) {
return false; return false;
} }
// QPA by default stores the global mouse position in the pt field, // QPA by default stores the global mouse position in the pt field,
@ -637,18 +635,16 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
if ((uMsg == WM_CLOSE) || (uMsg == WM_DESTROY)) { if ((uMsg == WM_CLOSE) || (uMsg == WM_DESTROY)) {
return false; return false;
} }
const auto it = g_framelessWin32HelperData()->data.find(windowId); if (!g_win32Helper()->data.contains(windowId)) {
if (it == g_framelessWin32HelperData()->data.end()) {
return false; return false;
} }
const FramelessWin32HelperData &data = it.value(); const Win32HelperData data = g_win32Helper()->data.value(windowId);
FramelessWin32HelperData &muData = it.value();
const bool frameBorderVisible = Utils::isWindowFrameBorderVisible(); const bool frameBorderVisible = Utils::isWindowFrameBorderVisible();
const WPARAM wParam = msg->wParam; const WPARAM wParam = msg->wParam;
const LPARAM lParam = msg->lParam; const LPARAM lParam = msg->lParam;
#if (QT_VERSION < QT_VERSION_CHECK(6, 5, 1)) #if (QT_VERSION < QT_VERSION_CHECK(6, 5, 1))
const auto updateRestoreGeometry = [windowId, &data, &muData](const bool ignoreWindowState) -> void { const auto updateRestoreGeometry = [windowId, &data](const bool ignoreWindowState) -> void {
if (!ignoreWindowState && !Utils::isWindowNoState(windowId)) { if (!ignoreWindowState && !Utils::isWindowNoState(windowId)) {
return; return;
} }
@ -660,7 +656,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
if (Utils::isValidGeometry(data.restoreGeometry) && (data.restoreGeometry == rect)) { if (Utils::isValidGeometry(data.restoreGeometry) && (data.restoreGeometry == rect)) {
return; return;
} }
muData.restoreGeometry = rect; g_win32Helper()->data[windowId].restoreGeometry = rect;
}; };
#endif // (QT_VERSION < QT_VERSION_CHECK(6, 5, 1)) #endif // (QT_VERSION < QT_VERSION_CHECK(6, 5, 1))
@ -912,7 +908,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
// of the upper-left non-client area. It's confirmed that this issue exists // of the upper-left non-client area. It's confirmed that this issue exists
// from Windows 7 to Windows 10. Not tested on Windows 11 yet. Don't know // from Windows 7 to Windows 10. Not tested on Windows 11 yet. Don't know
// whether it exists on Windows XP to Windows Vista or not. // whether it exists on Windows XP to Windows Vista or not.
const bool needD3DWorkaround = (qEnvironmentVariableIntValue("FRAMELESSHELPER_USE_D3D_WORKAROUND") != 0); const bool needD3DWorkaround = (qEnvironmentVariableIntValue(kD3DWorkaroundEnvVar) != 0);
*result = (((static_cast<BOOL>(wParam) == FALSE) || needD3DWorkaround) ? 0 : WVR_REDRAW); *result = (((static_cast<BOOL>(wParam) == FALSE) || needD3DWorkaround) ? 0 : WVR_REDRAW);
return true; return true;
} }
@ -1183,11 +1179,12 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
} }
DEBUG.noquote() << "New DPI for window" << hwnd2str(hWnd) DEBUG.noquote() << "New DPI for window" << hwnd2str(hWnd)
<< "is" << newDpi << "(was" << oldDpi << ")."; << "is" << newDpi << "(was" << oldDpi << ").";
muData.dpi = newDpi; g_win32Helper()->data[windowId].dpi = newDpi;
#if (QT_VERSION < QT_VERSION_CHECK(6, 5, 1)) #if (QT_VERSION < QT_VERSION_CHECK(6, 5, 1))
if (Utils::isValidGeometry(data.restoreGeometry)) { if (Utils::isValidGeometry(data.restoreGeometry)) {
// Update the window size only. The position should not be changed. // Update the window size only. The position should not be changed.
muData.restoreGeometry.setSize(Utils::rescaleSize(data.restoreGeometry.size(), oldDpi.x, newDpi.x)); g_win32Helper()->data[windowId].restoreGeometry.setSize(
Utils::rescaleSize(data.restoreGeometry.size(), oldDpi.x, newDpi.x));
} }
#endif // (QT_VERSION < QT_VERSION_CHECK(6, 5, 1)) #endif // (QT_VERSION < QT_VERSION_CHECK(6, 5, 1))
data.params.forceChildrenRepaint(500); data.params.forceChildrenRepaint(500);

View File

@ -129,6 +129,17 @@ using namespace Global;
static_assert(std::size(WindowsVersions) == (static_cast<int>(WindowsVersion::Latest) + 1)); static_assert(std::size(WindowsVersions) == (static_cast<int>(WindowsVersion::Latest) + 1));
#endif #endif
#ifdef Q_OS_LINUX
[[maybe_unused]] static constexpr const char QT_QPA_ENV_VAR[] = "QT_QPA_PLATFORM";
FRAMELESSHELPER_BYTEARRAY_CONSTANT(xcb)
#endif
#ifdef Q_OS_MACOS
[[maybe_unused]] static constexpr const char MAC_LAYER_ENV_VAR[] = "QT_MAC_WANTS_LAYER";
#endif
[[maybe_unused]] static constexpr const char kNoLogoEnvVar[] = "FRAMELESSHELPER_NO_LOGO";
void registerInitializeHook(const InitializeHookCallback &cb) void registerInitializeHook(const InitializeHookCallback &cb)
{ {
Q_UNUSED(cb); Q_UNUSED(cb);
@ -160,14 +171,14 @@ void initialize()
// We are setting the preferred QPA backend, so we have to set it early // We are setting the preferred QPA backend, so we have to set it early
// enough, that is, before the construction of any Q(Gui)Application // enough, that is, before the construction of any Q(Gui)Application
// instances. QCoreApplication won't instantiate the platform plugin. // instances. QCoreApplication won't instantiate the platform plugin.
qputenv("QT_QPA_PLATFORM", "xcb"); qputenv(QT_QPA_ENV_VAR, kxcb);
// Fedora and Arch users report segfault when calling XInitThreads() and gtk_init(). // Fedora and Arch users report segfault when calling XInitThreads() and gtk_init().
//XInitThreads(); // Users report that GTK is crashing without this. //XInitThreads(); // Users report that GTK is crashing without this.
//gtk_init(nullptr, nullptr); // Users report that GTK functionalities won't work without this. //gtk_init(nullptr, nullptr); // Users report that GTK functionalities won't work without this.
#endif #endif
#if (defined(Q_OS_MACOS) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))) #if (defined(Q_OS_MACOS) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)))
qputenv("QT_MAC_WANTS_LAYER", "1"); qputenv(MAC_LAYER_ENV_VAR, FRAMELESSHELPER_BYTEARRAY_LITERAL("1"));
#endif #endif
#ifdef Q_OS_WINDOWS #ifdef Q_OS_WINDOWS
@ -267,7 +278,7 @@ void setApplicationOSThemeAware()
void outputLogo() void outputLogo()
{ {
if (qEnvironmentVariableIntValue("FRAMELESSHELPER_NO_LOGO")) { if (qEnvironmentVariableIntValue(kNoLogoEnvVar)) {
return; return;
} }
const VersionInfo &ver = version(); const VersionInfo &ver = version();

View File

@ -60,12 +60,28 @@ static Q_LOGGING_CATEGORY(lcFramelessManager, "wangwenx190.framelesshelper.core.
using namespace Global; using namespace Global;
struct FramelessManagerData struct FramelessManagerHelper
{ {
QList<WId> windowIds = {}; QList<WId> windowIds = {};
}; };
Q_GLOBAL_STATIC(FramelessManagerData, g_framelessManagerData) Q_GLOBAL_STATIC(FramelessManagerHelper, g_helper)
Q_GLOBAL_STATIC(FramelessManager, g_manager)
[[maybe_unused]] static constexpr const char kGlobalFlagVarName[] = "__FRAMELESSHELPER__";
#ifndef FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE
FRAMELESSHELPER_STRING_CONSTANT2(IconFontFilePath, ":/org.wangwenx190.FramelessHelper/resources/fonts/iconfont.ttf")
FRAMELESSHELPER_STRING_CONSTANT2(IconFontFamilyName_win11, "Segoe Fluent Icons")
FRAMELESSHELPER_STRING_CONSTANT2(IconFontFamilyName_win10, "Segoe MDL2 Assets")
FRAMELESSHELPER_STRING_CONSTANT2(IconFontFamilyName_fallback, "iconfont")
# ifdef Q_OS_MACOS
[[maybe_unused]] static constexpr const int kIconFontPointSize = 10;
# else // !Q_OS_MACOS
[[maybe_unused]] static constexpr const int kIconFontPointSize = 8;
# endif // Q_OS_MACOS
#endif // FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE
#ifndef FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE #ifndef FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE
[[nodiscard]] static inline QString iconFontFamilyName() [[nodiscard]] static inline QString iconFontFamilyName()
@ -73,13 +89,13 @@ Q_GLOBAL_STATIC(FramelessManagerData, g_framelessManagerData)
static const auto result = []() -> QString { static const auto result = []() -> QString {
#ifdef Q_OS_WINDOWS #ifdef Q_OS_WINDOWS
if (WindowsVersionHelper::isWin11OrGreater()) { if (WindowsVersionHelper::isWin11OrGreater()) {
return FRAMELESSHELPER_STRING_LITERAL("Segoe Fluent Icons"); return kIconFontFamilyName_win11;
} }
if (WindowsVersionHelper::isWin10OrGreater()) { if (WindowsVersionHelper::isWin10OrGreater()) {
return FRAMELESSHELPER_STRING_LITERAL("Segoe MDL2 Assets"); return kIconFontFamilyName_win10;
} }
#endif // Q_OS_WINDOWS #endif // Q_OS_WINDOWS
return FRAMELESSHELPER_STRING_LITERAL("iconfont"); return kIconFontFamilyName_fallback;
}(); }();
return result; return result;
} }
@ -125,11 +141,11 @@ void FramelessManagerPrivate::initializeIconFont()
inited = true; inited = true;
framelesshelpercore_initResource(); framelesshelpercore_initResource();
// We always register this font because it's our only fallback. // We always register this font because it's our only fallback.
const int id = QFontDatabase::addApplicationFont(FRAMELESSHELPER_STRING_LITERAL(":/org.wangwenx190.FramelessHelper/resources/fonts/iconfont.ttf")); const int id = QFontDatabase::addApplicationFont(kIconFontFilePath);
if (id < 0) { if (id < 0) {
WARNING << "Failed to load icon font."; WARNING << "Failed to load icon font:" << kIconFontFilePath;
} else { } else {
DEBUG << "Successfully registered icon font."; DEBUG << "Successfully registered icon font:" << QFontDatabase::applicationFontFamilies(id);
} }
#endif // FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE #endif // FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE
} }
@ -142,11 +158,7 @@ QFont FramelessManagerPrivate::getIconFont()
static const auto font = []() -> QFont { static const auto font = []() -> QFont {
QFont f = {}; QFont f = {};
f.setFamily(iconFontFamilyName()); f.setFamily(iconFontFamilyName());
# ifdef Q_OS_MACOS f.setPointSize(kIconFontPointSize);
f.setPointSize(10);
# else // !Q_OS_MACOS
f.setPointSize(8);
# endif // Q_OS_MACOS
return f; return f;
}(); }();
return font; return font;
@ -184,10 +196,10 @@ void FramelessManagerPrivate::addWindow(FramelessParamsConst params)
return; return;
} }
const WId windowId = params->getWindowId(); const WId windowId = params->getWindowId();
if (g_framelessManagerData()->windowIds.contains(windowId)) { if (g_helper()->windowIds.contains(windowId)) {
return; return;
} }
g_framelessManagerData()->windowIds.append(windowId); g_helper()->windowIds.append(windowId);
static const bool pureQt = usePureQtImplementation(); static const bool pureQt = usePureQtImplementation();
if (pureQt) { if (pureQt) {
FramelessHelperQt::addWindow(params); FramelessHelperQt::addWindow(params);
@ -207,10 +219,10 @@ void FramelessManagerPrivate::removeWindow(const WId windowId)
if (!windowId) { if (!windowId) {
return; return;
} }
if (!g_framelessManagerData()->windowIds.contains(windowId)) { if (!g_helper()->windowIds.contains(windowId)) {
return; return;
} }
g_framelessManagerData()->windowIds.removeAll(windowId); g_helper()->windowIds.removeAll(windowId);
static const bool pureQt = usePureQtImplementation(); static const bool pureQt = usePureQtImplementation();
if (pureQt) { if (pureQt) {
FramelessHelperQt::removeWindow(windowId); FramelessHelperQt::removeWindow(windowId);
@ -344,10 +356,9 @@ void FramelessManagerPrivate::initialize()
flagSet = true; flagSet = true;
// Set a global flag so that people can check whether FramelessHelper is being // Set a global flag so that people can check whether FramelessHelper is being
// used without actually accessing the FramelessHelper interface. // used without actually accessing the FramelessHelper interface.
static constexpr const char flag[] = "__FRAMELESSHELPER__";
const int ver = FramelessHelper::Core::version().version; const int ver = FramelessHelper::Core::version().version;
qputenv(flag, QByteArray::number(ver)); qputenv(kGlobalFlagVarName, QByteArray::number(ver));
qApp->setProperty(flag, ver); qApp->setProperty(kGlobalFlagVarName, ver);
} }
} }
@ -360,8 +371,7 @@ FramelessManager::~FramelessManager() = default;
FramelessManager *FramelessManager::instance() FramelessManager *FramelessManager::instance()
{ {
static FramelessManager manager; return g_manager();
return &manager;
} }
SystemTheme FramelessManager::systemTheme() const SystemTheme FramelessManager::systemTheme() const

View File

@ -28,7 +28,6 @@
#include "utils.h" #include "utils.h"
#include "framelessconfig_p.h" #include "framelessconfig_p.h"
#include "framelesshelpercore_global_p.h" #include "framelesshelpercore_global_p.h"
#include <optional>
#include <QtCore/qsysinfo.h> #include <QtCore/qsysinfo.h>
#include <QtCore/qloggingcategory.h> #include <QtCore/qloggingcategory.h>
#include <QtCore/qmutex.h> #include <QtCore/qmutex.h>
@ -78,6 +77,10 @@ using namespace Global;
[[maybe_unused]] static Q_COLOR_CONSTEXPR const QColor kDefaultFallbackColorDark = {44, 44, 44}; // #2C2C2C [[maybe_unused]] static Q_COLOR_CONSTEXPR const QColor kDefaultFallbackColorDark = {44, 44, 44}; // #2C2C2C
[[maybe_unused]] static Q_COLOR_CONSTEXPR const QColor kDefaultFallbackColorLight = {249, 249, 249}; // #F9F9F9 [[maybe_unused]] static Q_COLOR_CONSTEXPR const QColor kDefaultFallbackColorLight = {249, 249, 249}; // #F9F9F9
#ifndef FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE
FRAMELESSHELPER_STRING_CONSTANT2(NoiseImageFilePath, ":/org.wangwenx190.FramelessHelper/resources/images/noise.png")
#endif // FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE
struct ImageData struct ImageData
{ {
QPixmap blurredWallpaper = {}; QPixmap blurredWallpaper = {};
@ -666,7 +669,7 @@ void MicaMaterialPrivate::updateMaterialBrush()
{ {
#ifndef FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE #ifndef FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE
framelesshelpercore_initResource(); framelesshelpercore_initResource();
static const QImage noiseTexture = QImage(FRAMELESSHELPER_STRING_LITERAL(":/org.wangwenx190.FramelessHelper/resources/images/noise.png")); static const QImage noiseTexture = QImage(kNoiseImageFilePath);
#endif // FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE #endif // FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE
QImage micaTexture = QImage(QSize(64, 64), kDefaultImageFormat); QImage micaTexture = QImage(QSize(64, 64), kDefaultImageFormat);
QColor fillColor = ((FramelessManager::instance()->systemTheme() == SystemTheme::Dark) ? kDefaultSystemDarkColor : kDefaultSystemLightColor2); QColor fillColor = ((FramelessManager::instance()->systemTheme() == SystemTheme::Dark) ? kDefaultSystemDarkColor : kDefaultSystemLightColor2);

View File

@ -24,7 +24,6 @@
#include "registrykey_p.h" #include "registrykey_p.h"
#include "framelesshelper_windows.h" #include "framelesshelper_windows.h"
#include <array>
#include <QtCore/qloggingcategory.h> #include <QtCore/qloggingcategory.h>
#if REGISTRYKEY_QWINREGISTRYKEY #if REGISTRYKEY_QWINREGISTRYKEY
# include <QtCore/private/qwinregistry_p.h> # include <QtCore/private/qwinregistry_p.h>
@ -50,35 +49,33 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
using namespace Global; using namespace Global;
static constexpr const std::array<ULONG_PTR, 10> g_registryKeyMap = static const HKEY g_keyMap[] = {
{ HKEY_CLASSES_ROOT,
0x80000000, // HKEY_CLASSES_ROOT HKEY_CURRENT_USER,
0x80000001, // HKEY_CURRENT_USER HKEY_LOCAL_MACHINE,
0x80000002, // HKEY_LOCAL_MACHINE HKEY_USERS,
0x80000003, // HKEY_USERS HKEY_PERFORMANCE_DATA,
0x80000004, // HKEY_PERFORMANCE_DATA HKEY_CURRENT_CONFIG,
0x80000005, // HKEY_CURRENT_CONFIG HKEY_DYN_DATA,
0x80000006, // HKEY_DYN_DATA HKEY_CURRENT_USER_LOCAL_SETTINGS,
0x80000007, // HKEY_CURRENT_USER_LOCAL_SETTINGS HKEY_PERFORMANCE_TEXT,
0x80000050, // HKEY_PERFORMANCE_TEXT HKEY_PERFORMANCE_NLSTEXT
0x80000060 // HKEY_PERFORMANCE_NLSTEXT
}; };
static constexpr const auto registryKeyCount = std::size(g_registryKeyMap); static_assert(std::size(g_keyMap) == (static_cast<int>(RegistryRootKey::PerformanceNlsText) + 1));
static_assert(registryKeyCount == (static_cast<int>(RegistryRootKey::PerformanceNlsText) + 1));
[[maybe_unused]] static Q_STRING_CONSTEXPR const std::array<FRAMELESSHELPER_STRING_TYPE, registryKeyCount> g_registryStrMap = static const QString g_strMap[] = {
{ FRAMELESSHELPER_STRING_LITERAL("HKEY_CLASSES_ROOT"),
FRAMELESSHELPER_STRING("HKEY_CLASSES_ROOT"), FRAMELESSHELPER_STRING_LITERAL("HKEY_CURRENT_USER"),
FRAMELESSHELPER_STRING("HKEY_CURRENT_USER"), FRAMELESSHELPER_STRING_LITERAL("HKEY_LOCAL_MACHINE"),
FRAMELESSHELPER_STRING("HKEY_LOCAL_MACHINE"), FRAMELESSHELPER_STRING_LITERAL("HKEY_USERS"),
FRAMELESSHELPER_STRING("HKEY_USERS"), FRAMELESSHELPER_STRING_LITERAL("HKEY_PERFORMANCE_DATA"),
FRAMELESSHELPER_STRING("HKEY_PERFORMANCE_DATA"), FRAMELESSHELPER_STRING_LITERAL("HKEY_CURRENT_CONFIG"),
FRAMELESSHELPER_STRING("HKEY_CURRENT_CONFIG"), FRAMELESSHELPER_STRING_LITERAL("HKEY_DYN_DATA"),
FRAMELESSHELPER_STRING("HKEY_DYN_DATA"), FRAMELESSHELPER_STRING_LITERAL("HKEY_CURRENT_USER_LOCAL_SETTINGS"),
FRAMELESSHELPER_STRING("HKEY_CURRENT_USER_LOCAL_SETTINGS"), FRAMELESSHELPER_STRING_LITERAL("HKEY_PERFORMANCE_TEXT"),
FRAMELESSHELPER_STRING("HKEY_PERFORMANCE_TEXT"), FRAMELESSHELPER_STRING_LITERAL("HKEY_PERFORMANCE_NLSTEXT")
FRAMELESSHELPER_STRING("HKEY_PERFORMANCE_NLSTEXT")
}; };
static_assert(std::size(g_strMap) == std::size(g_keyMap));
RegistryKey::RegistryKey(const RegistryRootKey root, const QString &key, QObject *parent) : QObject(parent) RegistryKey::RegistryKey(const RegistryRootKey root, const QString &key, QObject *parent) : QObject(parent)
{ {
@ -89,12 +86,12 @@ RegistryKey::RegistryKey(const RegistryRootKey root, const QString &key, QObject
m_rootKey = root; m_rootKey = root;
m_subKey = key; m_subKey = key;
#if REGISTRYKEY_QWINREGISTRYKEY #if REGISTRYKEY_QWINREGISTRYKEY
m_registryKey.reset(new QWinRegistryKey(reinterpret_cast<HKEY>(g_registryKeyMap.at(static_cast<int>(m_rootKey))), m_subKey)); m_registryKey.reset(new QWinRegistryKey(g_keyMap[static_cast<int>(m_rootKey)], m_subKey));
if (!m_registryKey->isValid()) { if (!m_registryKey->isValid()) {
m_registryKey.reset(); m_registryKey.reset();
} }
#else #else
const QString rootKey = g_registryStrMap.at(static_cast<int>(m_rootKey)); const QString rootKey = g_strMap[static_cast<int>(m_rootKey)];
const auto lastSlashPos = m_subKey.lastIndexOf(u'\\'); const auto lastSlashPos = m_subKey.lastIndexOf(u'\\');
m_settings.reset(new QSettings(rootKey + u'\\' + m_subKey.left(lastSlashPos), QSettings::NativeFormat)); m_settings.reset(new QSettings(rootKey + u'\\' + m_subKey.left(lastSlashPos), QSettings::NativeFormat));
if (m_settings->childGroups().contains(m_subKey.mid(lastSlashPos + 1))) { if (m_settings->childGroups().contains(m_subKey.mid(lastSlashPos + 1))) {

View File

@ -76,7 +76,9 @@ struct SysApiLoaderData
QHash<QString, QFunctionPointer> functionCache = {}; QHash<QString, QFunctionPointer> functionCache = {};
}; };
Q_GLOBAL_STATIC(SysApiLoaderData, g_sysApiLoaderData) Q_GLOBAL_STATIC(SysApiLoaderData, g_loaderData)
Q_GLOBAL_STATIC(SysApiLoader, g_sysApiLoader)
static const bool LoaderDebugFlag = qEnvironmentVariableIntValue("FRAMELESSHELPER_SYSAPILOADER_DEBUG"); static const bool LoaderDebugFlag = qEnvironmentVariableIntValue("FRAMELESSHELPER_SYSAPILOADER_DEBUG");
@ -88,8 +90,7 @@ SysApiLoader::~SysApiLoader() = default;
SysApiLoader *SysApiLoader::instance() SysApiLoader *SysApiLoader::instance()
{ {
static SysApiLoader loader; return g_sysApiLoader();
return &loader;
} }
QString SysApiLoader::platformSharedLibrarySuffixName() QString SysApiLoader::platformSharedLibrarySuffixName()
@ -102,7 +103,7 @@ QString SysApiLoader::platformSharedLibrarySuffixName()
#elif defined(Q_OS_MACOS) #elif defined(Q_OS_MACOS)
return FRAMELESSHELPER_STRING_LITERAL(".dylib"); return FRAMELESSHELPER_STRING_LITERAL(".dylib");
#else #else
# error "Unsupported platform!" #error "Unsupported platform!"
#endif #endif
}(); }();
return result; return result;
@ -166,6 +167,16 @@ QFunctionPointer SysApiLoader::resolve(const QString &library, const char *funct
#endif // SYSAPILOADER_QLIBRARY #endif // SYSAPILOADER_QLIBRARY
} }
QFunctionPointer SysApiLoader::resolve(const QString &library, const QByteArray &function)
{
Q_ASSERT(!library.isEmpty());
Q_ASSERT(!function.isEmpty());
if (library.isEmpty() || function.isEmpty()) {
return nullptr;
}
return SysApiLoader::resolve(library, function.constData());
}
QFunctionPointer SysApiLoader::resolve(const QString &library, const QString &function) QFunctionPointer SysApiLoader::resolve(const QString &library, const QString &function)
{ {
Q_ASSERT(!library.isEmpty()); Q_ASSERT(!library.isEmpty());
@ -173,7 +184,7 @@ QFunctionPointer SysApiLoader::resolve(const QString &library, const QString &fu
if (library.isEmpty() || function.isEmpty()) { if (library.isEmpty() || function.isEmpty()) {
return nullptr; return nullptr;
} }
return SysApiLoader::resolve(library, function.toUtf8().constData()); return SysApiLoader::resolve(library, function.toUtf8());
} }
bool SysApiLoader::isAvailable(const QString &library, const QString &function) bool SysApiLoader::isAvailable(const QString &library, const QString &function)
@ -184,15 +195,14 @@ bool SysApiLoader::isAvailable(const QString &library, const QString &function)
return false; return false;
} }
const QString key = generateUniqueKey(library, function); const QString key = generateUniqueKey(library, function);
const auto it = g_sysApiLoaderData()->functionCache.constFind(key); if (g_loaderData()->functionCache.contains(key)) {
if (it != g_sysApiLoaderData()->functionCache.constEnd()) {
if (LoaderDebugFlag) { if (LoaderDebugFlag) {
DEBUG << Q_FUNC_INFO << "Function cache found:" << key; DEBUG << Q_FUNC_INFO << "Function cache found:" << key;
} }
return (it.value() != nullptr); return (g_loaderData()->functionCache.value(key) != nullptr);
} else { } else {
const QFunctionPointer symbol = SysApiLoader::resolve(library, function); const QFunctionPointer symbol = SysApiLoader::resolve(library, function);
g_sysApiLoaderData()->functionCache.insert(key, symbol); g_loaderData()->functionCache.insert(key, symbol);
if (LoaderDebugFlag) { if (LoaderDebugFlag) {
DEBUG << Q_FUNC_INFO << "New function cache:" << key << (symbol ? "[VALID]" : "[NULL]"); DEBUG << Q_FUNC_INFO << "New function cache:" << key << (symbol ? "[VALID]" : "[NULL]");
} }
@ -214,12 +224,11 @@ QFunctionPointer SysApiLoader::get(const QString &library, const QString &functi
return nullptr; return nullptr;
} }
const QString key = generateUniqueKey(library, function); const QString key = generateUniqueKey(library, function);
const auto it = g_sysApiLoaderData()->functionCache.constFind(key); if (g_loaderData()->functionCache.contains(key)) {
if (it != g_sysApiLoaderData()->functionCache.constEnd()) {
if (LoaderDebugFlag) { if (LoaderDebugFlag) {
DEBUG << Q_FUNC_INFO << "Function cache found:" << key; DEBUG << Q_FUNC_INFO << "Function cache found:" << key;
} }
return it.value(); return g_loaderData()->functionCache.value(key);
} else { } else {
if (LoaderDebugFlag) { if (LoaderDebugFlag) {
DEBUG << Q_FUNC_INFO << "Function cache not found:" << key; DEBUG << Q_FUNC_INFO << "Function cache not found:" << key;

View File

@ -27,7 +27,6 @@
#ifdef Q_OS_WINDOWS #ifdef Q_OS_WINDOWS
# include "winverhelper_p.h" # include "winverhelper_p.h"
#endif // Q_OS_WINDOWS #endif // Q_OS_WINDOWS
#include <array>
#include <QtCore/qloggingcategory.h> #include <QtCore/qloggingcategory.h>
#include <QtGui/qwindow.h> #include <QtGui/qwindow.h>
#include <QtGui/qscreen.h> #include <QtGui/qscreen.h>
@ -69,15 +68,14 @@ struct FONT_ICON
quint32 Fallback = 0; quint32 Fallback = 0;
}; };
static constexpr const std::array<FONT_ICON, 7> g_fontIconsTable = static const QHash<int, FONT_ICON> g_fontIconsTable = {
{ {static_cast<int>(SystemButtonType::Unknown), {0x0000, 0x0000}},
FONT_ICON{ 0x0000, 0x0000 }, {static_cast<int>(SystemButtonType::WindowIcon), {0xE756, 0x0000}},
FONT_ICON{ 0xE756, 0x0000 }, {static_cast<int>(SystemButtonType::Help), {0xE897, 0x0000}},
FONT_ICON{ 0xE897, 0x0000 }, {static_cast<int>(SystemButtonType::Minimize), {0xE921, 0xE93E}},
FONT_ICON{ 0xE921, 0xE93E }, {static_cast<int>(SystemButtonType::Maximize), {0xE922, 0xE93C}},
FONT_ICON{ 0xE922, 0xE93C }, {static_cast<int>(SystemButtonType::Restore), {0xE923, 0xE93D}},
FONT_ICON{ 0xE923, 0xE93D }, {static_cast<int>(SystemButtonType::Close), {0xE8BB, 0xE93B}}
FONT_ICON{ 0xE8BB, 0xE93B }
}; };
#endif // FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE #endif // FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE
@ -173,7 +171,12 @@ QString Utils::getSystemButtonGlyph(const SystemButtonType button)
#ifdef FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE #ifdef FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE
return {}; return {};
#else // !FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE #else // !FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE
const FONT_ICON &icon = g_fontIconsTable.at(static_cast<int>(button)); const auto index = static_cast<int>(button);
if (!g_fontIconsTable.contains(index)) {
WARNING << "FIXME: Add FONT_ICON value for button" << button;
return {};
}
const FONT_ICON icon = g_fontIconsTable.value(index);
# ifdef Q_OS_WINDOWS # ifdef Q_OS_WINDOWS
// Windows 11: Segoe Fluent Icons (https://docs.microsoft.com/en-us/windows/apps/design/style/segoe-fluent-icons-font) // Windows 11: Segoe Fluent Icons (https://docs.microsoft.com/en-us/windows/apps/design/style/segoe-fluent-icons-font)
// Windows 10: Segoe MDL2 Assets (https://docs.microsoft.com/en-us/windows/apps/design/style/segoe-ui-symbol-font) // Windows 10: Segoe MDL2 Assets (https://docs.microsoft.com/en-us/windows/apps/design/style/segoe-ui-symbol-font)
@ -228,8 +231,8 @@ void Utils::moveWindowToDesktopCenter(FramelessParamsConst params, const bool co
} }
const QSize screenSize = (considerTaskBar ? screen->availableSize() : screen->size()); const QSize screenSize = (considerTaskBar ? screen->availableSize() : screen->size());
const QPoint offset = (considerTaskBar ? screen->availableGeometry().topLeft() : QPoint(0, 0)); const QPoint offset = (considerTaskBar ? screen->availableGeometry().topLeft() : QPoint(0, 0));
const int newX = std::round(qreal(screenSize.width() - windowSize.width()) / qreal(2)); const int newX = std::round(qreal(screenSize.width() - windowSize.width()) / 2.0);
const int newY = std::round(qreal(screenSize.height() - windowSize.height()) / qreal(2)); const int newY = std::round(qreal(screenSize.height() - windowSize.height()) / 2.0);
params->setWindowPosition(QPoint(newX + offset.x(), newY + offset.y())); params->setWindowPosition(QPoint(newX + offset.x(), newY + offset.y()));
} }

View File

@ -32,7 +32,6 @@
#include "framelesshelpercore_global_p.h" #include "framelesshelpercore_global_p.h"
#include "versionnumber_p.h" #include "versionnumber_p.h"
#include "scopeguard_p.h" #include "scopeguard_p.h"
#include <optional>
#include <QtCore/qhash.h> #include <QtCore/qhash.h>
#include <QtCore/qloggingcategory.h> #include <QtCore/qloggingcategory.h>
#include <QtGui/qwindow.h> #include <QtGui/qwindow.h>
@ -73,10 +72,13 @@ static Q_LOGGING_CATEGORY(lcUtilsWin, "wangwenx190.framelesshelper.core.utils.wi
using namespace Global; using namespace Global;
static constexpr const char kNoFixQtInternalEnvVar[] = "FRAMELESSHELPER_WINDOWS_DONT_FIX_QT";
static const QString qDwmColorKeyName = QString::fromWCharArray(kDwmColorKeyName);
static constexpr const char kDpiNoAccessErrorMessage[] = static constexpr const char kDpiNoAccessErrorMessage[] =
"FramelessHelper doesn't have access to change the current process's DPI awareness mode," "FramelessHelper doesn't have access to change the current process's DPI awareness mode,"
" most likely due to it has been set externally already. Eg: application manifest file."; " most likely due to it has been set externally already. Eg: application manifest file.";
FRAMELESSHELPER_STRING_CONSTANT2(SuccessMessageText, "The operation completed successfully.") FRAMELESSHELPER_STRING_CONSTANT2(SuccessMessageText, "The operation completed successfully.")
FRAMELESSHELPER_STRING_CONSTANT2(EmptyMessageText, "FormatMessageW() returned empty string.")
FRAMELESSHELPER_STRING_CONSTANT2(ErrorMessageTemplate, "Function %1() failed with error code %2: %3.") FRAMELESSHELPER_STRING_CONSTANT2(ErrorMessageTemplate, "Function %1() failed with error code %2: %3.")
FRAMELESSHELPER_STRING_CONSTANT(Composition) FRAMELESSHELPER_STRING_CONSTANT(Composition)
FRAMELESSHELPER_STRING_CONSTANT(ColorizationColor) FRAMELESSHELPER_STRING_CONSTANT(ColorizationColor)
@ -185,7 +187,7 @@ FRAMELESSHELPER_STRING_CONSTANT(BringWindowToTop)
FRAMELESSHELPER_STRING_CONSTANT(SetActiveWindow) FRAMELESSHELPER_STRING_CONSTANT(SetActiveWindow)
FRAMELESSHELPER_STRING_CONSTANT(RedrawWindow) FRAMELESSHELPER_STRING_CONSTANT(RedrawWindow)
struct Win32UtilsData struct Win32UtilsHelperData
{ {
WNDPROC originalWindowProc = nullptr; WNDPROC originalWindowProc = nullptr;
SystemParameters params = {}; SystemParameters params = {};
@ -193,11 +195,38 @@ struct Win32UtilsData
struct Win32UtilsHelper struct Win32UtilsHelper
{ {
QHash<WId, Win32UtilsData> data = {}; QHash<WId, Win32UtilsHelperData> data = {};
QList<WId> micaWindowIds = {}; QList<WId> micaWindowIds = {};
}; };
Q_GLOBAL_STATIC(Win32UtilsHelper, g_win32UtilsData) Q_GLOBAL_STATIC(Win32UtilsHelper, g_utilsHelper)
struct SYSTEM_METRIC
{
int DPI_96 = 0; // 100%. The scale factor for the device is 1x.
int DPI_115 = 0; // 120%. The scale factor for the device is 1.2x.
int DPI_120 = 0; // 125%. The scale factor for the device is 1.25x.
int DPI_134 = 0; // 140%. The scale factor for the device is 1.4x.
int DPI_144 = 0; // 150%. The scale factor for the device is 1.5x.
int DPI_154 = 0; // 160%. The scale factor for the device is 1.6x.
int DPI_168 = 0; // 175%. The scale factor for the device is 1.75x.
int DPI_173 = 0; // 180%. The scale factor for the device is 1.8x.
int DPI_192 = 0; // 200%. The scale factor for the device is 2x.
int DPI_216 = 0; // 225%. The scale factor for the device is 2.25x.
int DPI_240 = 0; // 250%. The scale factor for the device is 2.5x.
int DPI_288 = 0; // 300%. The scale factor for the device is 3x.
int DPI_336 = 0; // 350%. The scale factor for the device is 3.5x.
int DPI_384 = 0; // 400%. The scale factor for the device is 4x.
int DPI_432 = 0; // 450%. The scale factor for the device is 4.5x.
int DPI_480 = 0; // 500%. The scale factor for the device is 5x.
};
[[maybe_unused]] static const QHash<int, SYSTEM_METRIC> g_systemMetricsTable = {
{SM_CYCAPTION, {23, 27, 29, 32, 34, 36, 40, 41, 45, 51, 56, 67, 78, 89, 100, 111}},
{SM_CXSIZEFRAME, { 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 7, 7, 8, 8}},
{SM_CYSIZEFRAME, { 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 7, 7, 8, 8}},
{SM_CXPADDEDBORDER, { 4, 5, 5, 6, 6, 6, 7, 7, 8, 9, 10, 12, 14, 16, 18, 20}}
};
[[nodiscard]] bool operator==(const RECT &lhs, const RECT &rhs) noexcept [[nodiscard]] bool operator==(const RECT &lhs, const RECT &rhs) noexcept
{ {
@ -273,12 +302,6 @@ Q_GLOBAL_STATIC(Win32UtilsHelper, g_win32UtilsData)
return key; return key;
} }
[[nodiscard]] static inline QString dwmColorKeyName()
{
static const QString name = QString::fromWCharArray(kDwmColorKeyName);
return name;
}
[[nodiscard]] static inline bool doCompareWindowsVersion(const VersionNumber &targetOsVer) [[nodiscard]] static inline bool doCompareWindowsVersion(const VersionNumber &targetOsVer)
{ {
static const auto currentOsVer = []() -> std::optional<VersionNumber> { static const auto currentOsVer = []() -> std::optional<VersionNumber> {
@ -314,7 +337,7 @@ Q_GLOBAL_STATIC(Win32UtilsHelper, g_win32UtilsData)
osvi.dwMinorVersion = targetOsVer.Minor; osvi.dwMinorVersion = targetOsVer.Minor;
osvi.dwBuildNumber = targetOsVer.Patch; osvi.dwBuildNumber = targetOsVer.Patch;
DWORDLONG dwlConditionMask = 0; DWORDLONG dwlConditionMask = 0;
static constexpr const auto op = VER_GREATER_EQUAL; const auto op = VER_GREATER_EQUAL;
VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, op); VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, op);
VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, op); VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, op);
VER_SET_CONDITION(dwlConditionMask, VER_BUILDNUMBER, op); VER_SET_CONDITION(dwlConditionMask, VER_BUILDNUMBER, op);
@ -334,7 +357,7 @@ Q_GLOBAL_STATIC(Win32UtilsHelper, g_win32UtilsData)
LPWSTR buf = nullptr; LPWSTR buf = nullptr;
if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast<LPWSTR>(&buf), 0, nullptr) == 0) { nullptr, code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast<LPWSTR>(&buf), 0, nullptr) == 0) {
return FRAMELESSHELPER_STRING_LITERAL("FormatMessageW() returned empty string."); return kEmptyMessageText;
} }
const QString errorText = QString::fromWCharArray(buf).trimmed(); const QString errorText = QString::fromWCharArray(buf).trimmed();
LocalFree(buf); LocalFree(buf);
@ -466,11 +489,10 @@ static inline void moveWindowToMonitor(const HWND hwnd, const MONITORINFOEXW &ac
return 0; return 0;
} }
const auto windowId = reinterpret_cast<WId>(hWnd); const auto windowId = reinterpret_cast<WId>(hWnd);
const auto it = g_win32UtilsData()->data.constFind(windowId); if (!g_utilsHelper()->data.contains(windowId)) {
if (it == g_win32UtilsData()->data.constEnd()) {
return DefWindowProcW(hWnd, uMsg, wParam, lParam); return DefWindowProcW(hWnd, uMsg, wParam, lParam);
} }
const Win32UtilsData &data = it.value(); const Win32UtilsHelperData data = g_utilsHelper()->data.value(windowId);
const auto getNativePosFromMouse = [lParam]() -> QPoint { const auto getNativePosFromMouse = [lParam]() -> QPoint {
return {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)}; return {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
}; };
@ -567,7 +589,7 @@ static inline void moveWindowToMonitor(const HWND hwnd, const MONITORINFOEXW &ac
bool Utils::isWindowsVersionOrGreater(const WindowsVersion version) bool Utils::isWindowsVersionOrGreater(const WindowsVersion version)
{ {
return doCompareWindowsVersion(WindowsVersions.at(static_cast<int>(version))); return doCompareWindowsVersion(WindowsVersions[static_cast<int>(version)]);
} }
bool Utils::isDwmCompositionEnabled() bool Utils::isDwmCompositionEnabled()
@ -632,7 +654,7 @@ void Utils::updateWindowFrameMargins(const WId windowId, const bool reset)
if (!API_DWM_AVAILABLE(DwmExtendFrameIntoClientArea)) { if (!API_DWM_AVAILABLE(DwmExtendFrameIntoClientArea)) {
return; return;
} }
const bool micaEnabled = g_win32UtilsData()->micaWindowIds.contains(windowId); const bool micaEnabled = g_utilsHelper()->micaWindowIds.contains(windowId);
const auto margins = [micaEnabled, reset]() -> MARGINS { const auto margins = [micaEnabled, reset]() -> MARGINS {
// To make Mica/Mica Alt work for normal Win32 windows, we have to // To make Mica/Mica Alt work for normal Win32 windows, we have to
// let the window frame extend to the whole window (or disable the // let the window frame extend to the whole window (or disable the
@ -749,9 +771,9 @@ DwmColorizationArea Utils::getDwmColorizationArea()
return DwmColorizationArea::None; return DwmColorizationArea::None;
} }
const RegistryKey themeRegistry(RegistryRootKey::CurrentUser, personalizeRegistryKey()); const RegistryKey themeRegistry(RegistryRootKey::CurrentUser, personalizeRegistryKey());
const DWORD themeValue = themeRegistry.isValid() ? themeRegistry.value<DWORD>(dwmColorKeyName()).value_or(0) : 0; const DWORD themeValue = themeRegistry.isValid() ? themeRegistry.value<DWORD>(qDwmColorKeyName).value_or(0) : 0;
const RegistryKey dwmRegistry(RegistryRootKey::CurrentUser, dwmRegistryKey()); const RegistryKey dwmRegistry(RegistryRootKey::CurrentUser, dwmRegistryKey());
const DWORD dwmValue = dwmRegistry.isValid() ? dwmRegistry.value<DWORD>(dwmColorKeyName()).value_or(0) : 0; const DWORD dwmValue = dwmRegistry.isValid() ? dwmRegistry.value<DWORD>(qDwmColorKeyName).value_or(0) : 0;
const bool theme = (themeValue != 0); const bool theme = (themeValue != 0);
const bool dwm = (dwmValue != 0); const bool dwm = (dwmValue != 0);
if (theme && dwm) { if (theme && dwm) {
@ -930,7 +952,7 @@ void Utils::syncWmPaintWithDwm()
m = dt - (period * w); m = dt - (period * w);
Q_ASSERT(m >= 0); Q_ASSERT(m >= 0);
Q_ASSERT(m < period); Q_ASSERT(m < period);
const qreal m_ms = (qreal(1000) * qreal(m) / qreal(freq.QuadPart)); const qreal m_ms = (1000.0 * qreal(m) / qreal(freq.QuadPart));
Sleep(static_cast<DWORD>(std::round(m_ms))); Sleep(static_cast<DWORD>(std::round(m_ms)));
if (API_CALL_FUNCTION4(winmm, timeEndPeriod, ms_granularity) != TIMERR_NOERROR) { if (API_CALL_FUNCTION4(winmm, timeEndPeriod, ms_granularity) != TIMERR_NOERROR) {
WARNING << "timeEndPeriod() failed."; WARNING << "timeEndPeriod() failed.";
@ -1018,12 +1040,12 @@ quint32 Utils::getPrimaryScreenDpi(const bool horizontal)
// manually to ensure that. // manually to ensure that.
hr = d2dFactory->ReloadSystemMetrics(); hr = d2dFactory->ReloadSystemMetrics();
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
FLOAT dpiX = FLOAT(0), dpiY = FLOAT(0); FLOAT dpiX = 0.0f, dpiY = 0.0f;
QT_WARNING_PUSH QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED QT_WARNING_DISABLE_DEPRECATED
d2dFactory->GetDesktopDpi(&dpiX, &dpiY); d2dFactory->GetDesktopDpi(&dpiX, &dpiY);
QT_WARNING_POP QT_WARNING_POP
if ((dpiX > FLOAT(0)) && (dpiY > FLOAT(0))) { if ((dpiX > 0.0f) && (dpiY > 0.0f)) {
return (horizontal ? quint32(std::round(dpiX)) : quint32(std::round(dpiY))); return (horizontal ? quint32(std::round(dpiX)) : quint32(std::round(dpiY)));
} else { } else {
WARNING << "GetDesktopDpi() failed."; WARNING << "GetDesktopDpi() failed.";
@ -1257,7 +1279,7 @@ void Utils::maybeFixupQtInternals(const WId windowId)
if (!windowId) { if (!windowId) {
return; return;
} }
if (qEnvironmentVariableIntValue("FRAMELESSHELPER_WINDOWS_DONT_FIX_QT")) { if (qEnvironmentVariableIntValue(kNoFixQtInternalEnvVar)) {
return; return;
} }
bool shouldUpdateFrame = false; bool shouldUpdateFrame = false;
@ -1397,8 +1419,7 @@ void Utils::installSystemMenuHook(const WId windowId, FramelessParamsConst param
if (!windowId || !params) { if (!windowId || !params) {
return; return;
} }
const auto it = g_win32UtilsData()->data.constFind(windowId); if (g_utilsHelper()->data.contains(windowId)) {
if (it != g_win32UtilsData()->data.constEnd()) {
return; return;
} }
const auto hwnd = reinterpret_cast<HWND>(windowId); const auto hwnd = reinterpret_cast<HWND>(windowId);
@ -1415,10 +1436,10 @@ void Utils::installSystemMenuHook(const WId windowId, FramelessParamsConst param
return; return;
} }
//triggerFrameChange(windowId); // Crash //triggerFrameChange(windowId); // Crash
Win32UtilsData data = {}; Win32UtilsHelperData data = {};
data.originalWindowProc = originalWindowProc; data.originalWindowProc = originalWindowProc;
data.params = *params; data.params = *params;
g_win32UtilsData()->data.insert(windowId, data); g_utilsHelper()->data.insert(windowId, data);
} }
void Utils::uninstallSystemMenuHook(const WId windowId) void Utils::uninstallSystemMenuHook(const WId windowId)
@ -1427,11 +1448,10 @@ void Utils::uninstallSystemMenuHook(const WId windowId)
if (!windowId) { if (!windowId) {
return; return;
} }
const auto it = g_win32UtilsData()->data.constFind(windowId); if (!g_utilsHelper()->data.contains(windowId)) {
if (it == g_win32UtilsData()->data.constEnd()) {
return; return;
} }
const Win32UtilsData &data = it.value(); const Win32UtilsHelperData data = g_utilsHelper()->data.value(windowId);
Q_ASSERT(data.originalWindowProc); Q_ASSERT(data.originalWindowProc);
if (!data.originalWindowProc) { if (!data.originalWindowProc) {
return; return;
@ -1443,7 +1463,7 @@ void Utils::uninstallSystemMenuHook(const WId windowId)
return; return;
} }
//triggerFrameChange(windowId); // Crash //triggerFrameChange(windowId); // Crash
g_win32UtilsData()->data.erase(it); g_utilsHelper()->data.remove(windowId);
} }
void Utils::setAeroSnappingEnabled(const WId windowId, const bool enable) void Utils::setAeroSnappingEnabled(const WId windowId, const bool enable)
@ -1698,7 +1718,9 @@ bool Utils::setBlurBehindWindowEnabled(const WId windowId, const BlurMode mode,
return false; return false;
} }
const auto restoreWindowFrameMargins = [windowId]() -> void { const auto restoreWindowFrameMargins = [windowId]() -> void {
g_win32UtilsData()->micaWindowIds.removeAll(windowId); if (g_utilsHelper()->micaWindowIds.contains(windowId)) {
g_utilsHelper()->micaWindowIds.removeAll(windowId);
}
updateWindowFrameMargins(windowId, false); updateWindowFrameMargins(windowId, false);
}; };
const bool preferMicaAlt = (qEnvironmentVariableIntValue("FRAMELESSHELPER_PREFER_MICA_ALT") != 0); const bool preferMicaAlt = (qEnvironmentVariableIntValue("FRAMELESSHELPER_PREFER_MICA_ALT") != 0);
@ -1769,7 +1791,9 @@ bool Utils::setBlurBehindWindowEnabled(const WId windowId, const BlurMode mode,
return result; return result;
} else { } else {
if ((blurMode == BlurMode::Windows_Mica) || (blurMode == BlurMode::Windows_MicaAlt)) { if ((blurMode == BlurMode::Windows_Mica) || (blurMode == BlurMode::Windows_MicaAlt)) {
g_win32UtilsData()->micaWindowIds.append(windowId); if (!g_utilsHelper()->micaWindowIds.contains(windowId)) {
g_utilsHelper()->micaWindowIds.append(windowId);
}
// By giving a negative value, DWM will extend the window frame into the whole // By giving a negative value, DWM will extend the window frame into the whole
// client area. We need this step because the Mica material can only be applied // client area. We need this step because the Mica material can only be applied
// to the non-client area of a window. Without this step, you'll get a window // to the non-client area of a window. Without this step, you'll get a window
@ -2424,7 +2448,10 @@ void Utils::removeMicaWindow(const WId windowId)
if (!windowId) { if (!windowId) {
return; return;
} }
g_win32UtilsData()->micaWindowIds.removeAll(windowId); if (!g_utilsHelper()->micaWindowIds.contains(windowId)) {
return;
}
g_utilsHelper()->micaWindowIds.removeAll(windowId);
} }
void Utils::removeSysMenuHook(const WId windowId) void Utils::removeSysMenuHook(const WId windowId)
@ -2433,11 +2460,10 @@ void Utils::removeSysMenuHook(const WId windowId)
if (!windowId) { if (!windowId) {
return; return;
} }
const auto it = g_win32UtilsData()->data.constFind(windowId); if (!g_utilsHelper()->data.contains(windowId)) {
if (it == g_win32UtilsData()->data.constEnd()) {
return; return;
} }
g_win32UtilsData()->data.erase(it); g_utilsHelper()->data.remove(windowId);
} }
quint64 Utils::queryMouseButtonState() quint64 Utils::queryMouseButtonState()

View File

@ -24,7 +24,6 @@
#include "winverhelper_p.h" #include "winverhelper_p.h"
#include "utils.h" #include "utils.h"
#include <array>
FRAMELESSHELPER_BEGIN_NAMESPACE FRAMELESSHELPER_BEGIN_NAMESPACE
@ -44,7 +43,7 @@ private:
void initialize(); void initialize();
private: private:
std::array<bool, static_cast<int>(WindowsVersion::Latest) + 1> m_flags = {}; bool m_flags[static_cast<int>(WindowsVersion::Latest) + 1] = {};
}; };
WinVerHelper::WinVerHelper() WinVerHelper::WinVerHelper()
@ -56,7 +55,7 @@ WinVerHelper::~WinVerHelper() = default;
bool WinVerHelper::check(const WindowsVersion version) const bool WinVerHelper::check(const WindowsVersion version) const
{ {
return m_flags.at(static_cast<int>(version)); return m_flags[static_cast<int>(version)];
} }
void WinVerHelper::initialize() void WinVerHelper::initialize()

View File

@ -141,7 +141,6 @@ if(QT_VERSION VERSION_GREATER_EQUAL "6.3")
VERSION "1.0" VERSION "1.0"
OUTPUT_DIRECTORY "${__import_base_dir}/org/wangwenx190/${PROJECT_NAME}" OUTPUT_DIRECTORY "${__import_base_dir}/org/wangwenx190/${PROJECT_NAME}"
RESOURCE_PREFIX "/" RESOURCE_PREFIX "/"
TYPEINFO "plugins.qmltypes" # This is the type info file name since at least Qt5, some tools won't recognize other names.
#NO_RESOURCE_TARGET_PATH # Can't be used for non-executables. #NO_RESOURCE_TARGET_PATH # Can't be used for non-executables.
OUTPUT_TARGETS __qml_targets OUTPUT_TARGETS __qml_targets
IMPORTS IMPORTS

View File

@ -143,7 +143,7 @@ void FramelessQuickHelperPrivate::extendsContentIntoTitleBar(const bool value)
} }
m_extendIntoTitleBar = value; m_extendIntoTitleBar = value;
if (!m_destroying) { if (!m_destroying) {
emitSignalForAllInstances("extendsContentIntoTitleBarChanged"); emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("extendsContentIntoTitleBarChanged"));
} }
} }
@ -166,7 +166,7 @@ void FramelessQuickHelperPrivate::setTitleBarItem(QQuickItem *value)
return; return;
} }
data->titleBarItem = value; data->titleBarItem = value;
emitSignalForAllInstances("titleBarItemChanged"); emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("titleBarItemChanged"));
} }
void FramelessQuickHelperPrivate::attach() void FramelessQuickHelperPrivate::attach()
@ -213,8 +213,8 @@ void FramelessQuickHelperPrivate::attach()
}; };
params.shouldIgnoreMouseEvents = [this](const QPoint &pos) -> bool { return shouldIgnoreMouseEvents(pos); }; params.shouldIgnoreMouseEvents = [this](const QPoint &pos) -> bool { return shouldIgnoreMouseEvents(pos); };
params.showSystemMenu = [this](const QPoint &pos) -> void { showSystemMenu(pos); }; params.showSystemMenu = [this](const QPoint &pos) -> void { showSystemMenu(pos); };
params.setProperty = [this](const char *name, const QVariant &value) -> void { setProperty(name, value); }; params.setProperty = [this](const QByteArray &name, const QVariant &value) -> void { setProperty(name, value); };
params.getProperty = [this](const char *name, const QVariant &defaultValue) -> QVariant { return getProperty(name, defaultValue); }; params.getProperty = [this](const QByteArray &name, const QVariant &defaultValue) -> QVariant { return getProperty(name, defaultValue); };
params.setCursor = [window](const QCursor &cursor) -> void { window->setCursor(cursor); }; params.setCursor = [window](const QCursor &cursor) -> void { window->setCursor(cursor); };
params.unsetCursor = [window]() -> void { window->unsetCursor(); }; params.unsetCursor = [window]() -> void { window->unsetCursor(); };
params.getWidgetHandle = []() -> QObject * { return nullptr; }; params.getWidgetHandle = []() -> QObject * { return nullptr; };
@ -238,7 +238,7 @@ void FramelessQuickHelperPrivate::attach()
if (FramelessConfig::instance()->isSet(Option::EnableBlurBehindWindow)) { if (FramelessConfig::instance()->isSet(Option::EnableBlurBehindWindow)) {
setBlurBehindWindowEnabled(true, {}); setBlurBehindWindowEnabled(true, {});
} }
emitSignalForAllInstances("ready"); emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("ready"));
}); });
} }
@ -460,14 +460,13 @@ void FramelessQuickHelperPrivate::setWindowFixedSize(const bool value)
#ifdef Q_OS_WINDOWS #ifdef Q_OS_WINDOWS
Utils::setAeroSnappingEnabled(window->winId(), !value); Utils::setAeroSnappingEnabled(window->winId(), !value);
#endif #endif
emitSignalForAllInstances("windowFixedSizeChanged"); emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("windowFixedSizeChanged"));
} }
void FramelessQuickHelperPrivate::emitSignalForAllInstances(const char *signal) void FramelessQuickHelperPrivate::emitSignalForAllInstances(const QByteArray &signal)
{ {
Q_ASSERT(signal); Q_ASSERT(!signal.isEmpty());
Q_ASSERT(*signal != '\0'); if (signal.isEmpty()) {
if (!signal || (*signal == '\0')) {
return; return;
} }
Q_Q(FramelessQuickHelper); Q_Q(FramelessQuickHelper);
@ -483,7 +482,7 @@ void FramelessQuickHelperPrivate::emitSignalForAllInstances(const char *signal)
return; return;
} }
for (auto &&instance : std::as_const(instances)) { for (auto &&instance : std::as_const(instances)) {
QMetaObject::invokeMethod(instance, signal); QMetaObject::invokeMethod(instance, signal.constData());
} }
} }
@ -520,23 +519,22 @@ void FramelessQuickHelperPrivate::setBlurBehindWindowEnabled(const bool value, c
if (Utils::setBlurBehindWindowEnabled(window->winId(), if (Utils::setBlurBehindWindowEnabled(window->winId(),
FRAMELESSHELPER_ENUM_QUICK_TO_CORE(BlurMode, mode), color)) { FRAMELESSHELPER_ENUM_QUICK_TO_CORE(BlurMode, mode), color)) {
m_blurBehindWindowEnabled = value; m_blurBehindWindowEnabled = value;
emitSignalForAllInstances("blurBehindWindowEnabledChanged"); emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("blurBehindWindowEnabledChanged"));
} else { } else {
WARNING << "Failed to enable/disable blur behind window."; WARNING << "Failed to enable/disable blur behind window.";
} }
} else { } else {
m_blurBehindWindowEnabled = value; m_blurBehindWindowEnabled = value;
findOrCreateMicaMaterial()->setVisible(m_blurBehindWindowEnabled); findOrCreateMicaMaterial()->setVisible(m_blurBehindWindowEnabled);
emitSignalForAllInstances("blurBehindWindowEnabledChanged"); emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("blurBehindWindowEnabledChanged"));
} }
} }
void FramelessQuickHelperPrivate::setProperty(const char *name, const QVariant &value) void FramelessQuickHelperPrivate::setProperty(const QByteArray &name, const QVariant &value)
{ {
Q_ASSERT(name); Q_ASSERT(!name.isEmpty());
Q_ASSERT(*name != '\0');
Q_ASSERT(value.isValid()); Q_ASSERT(value.isValid());
if (!name || (*name == '\0') || !value.isValid()) { if (name.isEmpty() || !value.isValid()) {
return; return;
} }
Q_Q(FramelessQuickHelper); Q_Q(FramelessQuickHelper);
@ -544,14 +542,13 @@ void FramelessQuickHelperPrivate::setProperty(const char *name, const QVariant &
if (!window) { if (!window) {
return; return;
} }
window->setProperty(name, value); window->setProperty(name.constData(), value);
} }
QVariant FramelessQuickHelperPrivate::getProperty(const char *name, const QVariant &defaultValue) QVariant FramelessQuickHelperPrivate::getProperty(const QByteArray &name, const QVariant &defaultValue)
{ {
Q_ASSERT(name); Q_ASSERT(!name.isEmpty());
Q_ASSERT(*name != '\0'); if (name.isEmpty()) {
if (!name || (*name == '\0')) {
return {}; return {};
} }
Q_Q(FramelessQuickHelper); Q_Q(FramelessQuickHelper);
@ -559,7 +556,7 @@ QVariant FramelessQuickHelperPrivate::getProperty(const char *name, const QVaria
if (!window) { if (!window) {
return {}; return {};
} }
const QVariant value = window->property(name); const QVariant value = window->property(name.constData());
return (value.isValid() ? value : defaultValue); return (value.isValid() ? value : defaultValue);
} }

View File

@ -217,14 +217,13 @@ void FramelessWidgetsHelperPrivate::setWindowFixedSize(const bool value)
#ifdef Q_OS_WINDOWS #ifdef Q_OS_WINDOWS
Utils::setAeroSnappingEnabled(m_window->winId(), !value); Utils::setAeroSnappingEnabled(m_window->winId(), !value);
#endif #endif
emitSignalForAllInstances("windowFixedSizeChanged"); emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("windowFixedSizeChanged"));
} }
void FramelessWidgetsHelperPrivate::emitSignalForAllInstances(const char *signal) void FramelessWidgetsHelperPrivate::emitSignalForAllInstances(const QByteArray &signal)
{ {
Q_ASSERT(signal); Q_ASSERT(!signal.isEmpty());
Q_ASSERT(*signal != '\0'); if (signal.isEmpty()) {
if (!signal || (*signal == '\0')) {
return; return;
} }
if (!m_window) { if (!m_window) {
@ -235,7 +234,7 @@ void FramelessWidgetsHelperPrivate::emitSignalForAllInstances(const char *signal
return; return;
} }
for (auto &&instance : std::as_const(instances)) { for (auto &&instance : std::as_const(instances)) {
QMetaObject::invokeMethod(instance, signal); QMetaObject::invokeMethod(instance, signal.constData());
} }
} }
@ -262,7 +261,7 @@ void FramelessWidgetsHelperPrivate::setBlurBehindWindowEnabled(const bool enable
if (Utils::setBlurBehindWindowEnabled(m_window->winId(), if (Utils::setBlurBehindWindowEnabled(m_window->winId(),
(enable ? BlurMode::Default : BlurMode::Disable), color)) { (enable ? BlurMode::Default : BlurMode::Disable), color)) {
m_blurBehindWindowEnabled = enable; m_blurBehindWindowEnabled = enable;
emitSignalForAllInstances("blurBehindWindowEnabledChanged"); emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("blurBehindWindowEnabledChanged"));
} else { } else {
WARNING << "Failed to enable/disable blur behind window."; WARNING << "Failed to enable/disable blur behind window.";
} }
@ -270,40 +269,38 @@ void FramelessWidgetsHelperPrivate::setBlurBehindWindowEnabled(const bool enable
if (WidgetsSharedHelper * const helper = findOrCreateSharedHelper(m_window)) { if (WidgetsSharedHelper * const helper = findOrCreateSharedHelper(m_window)) {
m_blurBehindWindowEnabled = enable; m_blurBehindWindowEnabled = enable;
helper->setMicaEnabled(m_blurBehindWindowEnabled); helper->setMicaEnabled(m_blurBehindWindowEnabled);
emitSignalForAllInstances("blurBehindWindowEnabledChanged"); emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("blurBehindWindowEnabledChanged"));
} else { } else {
DEBUG << "Blur behind window is not supported on current platform."; DEBUG << "Blur behind window is not supported on current platform.";
} }
} }
} }
void FramelessWidgetsHelperPrivate::setProperty(const char *name, const QVariant &value) void FramelessWidgetsHelperPrivate::setProperty(const QByteArray &name, const QVariant &value)
{ {
Q_ASSERT(name); Q_ASSERT(!name.isEmpty());
Q_ASSERT(*name != '\0');
Q_ASSERT(value.isValid()); Q_ASSERT(value.isValid());
if (!name || (*name == '\0') || !value.isValid()) { if (name.isEmpty() || !value.isValid()) {
return; return;
} }
Q_ASSERT(m_window); Q_ASSERT(m_window);
if (!m_window) { if (!m_window) {
return; return;
} }
m_window->setProperty(name, value); m_window->setProperty(name.constData(), value);
} }
QVariant FramelessWidgetsHelperPrivate::getProperty(const char *name, const QVariant &defaultValue) QVariant FramelessWidgetsHelperPrivate::getProperty(const QByteArray &name, const QVariant &defaultValue)
{ {
Q_ASSERT(name); Q_ASSERT(!name.isEmpty());
Q_ASSERT(*name != '\0'); if (name.isEmpty()) {
if (!name || (*name == '\0')) {
return {}; return {};
} }
Q_ASSERT(m_window); Q_ASSERT(m_window);
if (!m_window) { if (!m_window) {
return {}; return {};
} }
const QVariant value = m_window->property(name); const QVariant value = m_window->property(name.constData());
return (value.isValid() ? value : defaultValue); return (value.isValid() ? value : defaultValue);
} }
@ -449,7 +446,7 @@ void FramelessWidgetsHelperPrivate::setTitleBarWidget(QWidget *widget)
return; return;
} }
data->titleBarWidget = widget; data->titleBarWidget = widget;
emitSignalForAllInstances("titleBarWidgetChanged"); emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("titleBarWidgetChanged"));
} }
QWidget *FramelessWidgetsHelperPrivate::getTitleBarWidget() const QWidget *FramelessWidgetsHelperPrivate::getTitleBarWidget() const
@ -561,8 +558,8 @@ void FramelessWidgetsHelperPrivate::attach()
params.setSystemButtonState = [this](const SystemButtonType button, const ButtonState state) -> void { setSystemButtonState(button, state); }; params.setSystemButtonState = [this](const SystemButtonType button, const ButtonState state) -> void { setSystemButtonState(button, state); };
params.shouldIgnoreMouseEvents = [this](const QPoint &pos) -> bool { return shouldIgnoreMouseEvents(pos); }; params.shouldIgnoreMouseEvents = [this](const QPoint &pos) -> bool { return shouldIgnoreMouseEvents(pos); };
params.showSystemMenu = [this](const QPoint &pos) -> void { showSystemMenu(pos); }; params.showSystemMenu = [this](const QPoint &pos) -> void { showSystemMenu(pos); };
params.setProperty = [this](const char *name, const QVariant &value) -> void { setProperty(name, value); }; params.setProperty = [this](const QByteArray &name, const QVariant &value) -> void { setProperty(name, value); };
params.getProperty = [this](const char *name, const QVariant &defaultValue) -> QVariant { return getProperty(name, defaultValue); }; params.getProperty = [this](const QByteArray &name, const QVariant &defaultValue) -> QVariant { return getProperty(name, defaultValue); };
params.setCursor = [window](const QCursor &cursor) -> void { window->setCursor(cursor); }; params.setCursor = [window](const QCursor &cursor) -> void { window->setCursor(cursor); };
params.unsetCursor = [window]() -> void { window->unsetCursor(); }; params.unsetCursor = [window]() -> void { window->unsetCursor(); };
params.getWidgetHandle = [window]() -> QObject * { return window; }; params.getWidgetHandle = [window]() -> QObject * { return window; };
@ -586,8 +583,8 @@ void FramelessWidgetsHelperPrivate::attach()
if (FramelessConfig::instance()->isSet(Option::EnableBlurBehindWindow)) { if (FramelessConfig::instance()->isSet(Option::EnableBlurBehindWindow)) {
setBlurBehindWindowEnabled(true, {}); setBlurBehindWindowEnabled(true, {});
} }
emitSignalForAllInstances("windowChanged"); emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("windowChanged"));
emitSignalForAllInstances("ready"); emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("ready"));
}); });
} }
@ -603,7 +600,7 @@ void FramelessWidgetsHelperPrivate::detach()
g_widgetsHelper()->data.remove(windowId); g_widgetsHelper()->data.remove(windowId);
FramelessManager::instance()->removeWindow(windowId); FramelessManager::instance()->removeWindow(windowId);
m_window = nullptr; m_window = nullptr;
emitSignalForAllInstances("windowChanged"); emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("windowChanged"));
} }
void FramelessWidgetsHelperPrivate::extendsContentIntoTitleBar(const bool value) void FramelessWidgetsHelperPrivate::extendsContentIntoTitleBar(const bool value)
@ -617,7 +614,7 @@ void FramelessWidgetsHelperPrivate::extendsContentIntoTitleBar(const bool value)
detach(); detach();
} }
if (!m_destroying) { if (!m_destroying) {
emitSignalForAllInstances("extendsContentIntoTitleBarChanged"); emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("extendsContentIntoTitleBarChanged"));
} }
} }

View File

@ -700,14 +700,14 @@ void StandardTitleBar::mouseReleaseEvent(QMouseEvent *event)
{ {
QWidget::mouseReleaseEvent(event); QWidget::mouseReleaseEvent(event);
Q_D(StandardTitleBar); Q_D(StandardTitleBar);
std::ignore = d->mouseEventHandler(event); Q_UNUSED(d->mouseEventHandler(event));
} }
void StandardTitleBar::mouseDoubleClickEvent(QMouseEvent *event) void StandardTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
{ {
QWidget::mouseDoubleClickEvent(event); QWidget::mouseDoubleClickEvent(event);
Q_D(StandardTitleBar); Q_D(StandardTitleBar);
std::ignore = d->mouseEventHandler(event); Q_UNUSED(d->mouseEventHandler(event));
} }
FRAMELESSHELPER_END_NAMESPACE FRAMELESSHELPER_END_NAMESPACE