From 4ed21585b477ab8e76903f91a1c4a06aa6bbdcee Mon Sep 17 00:00:00 2001 From: Yuhang Zhao Date: Sat, 29 Jul 2023 15:29:38 +0800 Subject: [PATCH] cleanup core module Core mostly done. TODO: Widgets & Quick module --- .../Core/framelesshelpercore_global.h | 39 +++++-- .../FramelessHelper/Core/framelessmanager.h | 7 +- .../Core/private/framelessconfig_p.h | 7 +- .../private/framelesshelpercore_global_p.h | 4 +- .../Core/private/sysapiloader_p.h | 8 +- .../Core/private/versionnumber_p.h | 56 ++++----- .../Quick/private/framelessquickhelper_p.h | 6 +- .../private/framelesswidgetshelper_p.h | 6 +- src/core/chromepalette.cpp | 9 +- src/core/framelessconfig.cpp | 76 ++++++------- src/core/framelesshelper_qt.cpp | 36 +++--- src/core/framelesshelper_win.cpp | 106 +++++++++--------- src/core/framelesshelpercore_global.cpp | 17 +-- src/core/framelessmanager.cpp | 54 ++++----- src/core/micamaterial.cpp | 6 +- src/core/registrykey.cpp | 54 ++++----- src/core/sysapiloader.cpp | 33 ++---- src/core/utils.cpp | 28 ++--- src/core/utils_win.cpp | 99 ++++++---------- src/core/winverhelper.cpp | 4 +- src/quick/CMakeLists.txt | 1 + src/quick/framelessquickhelper.cpp | 43 +++---- src/widgets/framelesswidgetshelper.cpp | 47 ++++---- src/widgets/standardtitlebar.cpp | 4 +- 24 files changed, 355 insertions(+), 395 deletions(-) diff --git a/include/FramelessHelper/Core/framelesshelpercore_global.h b/include/FramelessHelper/Core/framelesshelpercore_global.h index 2a43d4d0..31a3ca04 100644 --- a/include/FramelessHelper/Core/framelesshelpercore_global.h +++ b/include/FramelessHelper/Core/framelesshelpercore_global.h @@ -132,6 +132,26 @@ QT_END_NAMESPACE # endif #endif +#ifndef FRAMELESSHELPER_BYTEARRAY_VIEW +# define FRAMELESSHELPER_BYTEARRAY_VIEW(ba) ba +#endif + +#ifndef FRAMELESSHELPER_STRING_VIEW +# if (QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)) +# define FRAMELESSHELPER_STRING_VIEW(str) str##_L1 +# else +# define FRAMELESSHELPER_STRING_VIEW(str) QLatin1String(str) +# endif +#endif + +#ifndef FRAMELESSHELPER_STRING_VIEW_TYPE +# if (QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)) +# define FRAMELESSHELPER_STRING_VIEW_TYPE QLatin1StringView +# else +# define FRAMELESSHELPER_STRING_VIEW_TYPE QLatin1String +# endif +#endif + #ifndef Q_UNREACHABLE_RETURN // Since 6.5 # define Q_UNREACHABLE_RETURN(...) \ do { \ @@ -142,12 +162,12 @@ QT_END_NAMESPACE #ifndef FRAMELESSHELPER_BYTEARRAY_CONSTANT2 # define FRAMELESSHELPER_BYTEARRAY_CONSTANT2(name, ba) \ - [[maybe_unused]] static const auto k##name = FRAMELESSHELPER_BYTEARRAY_LITERAL(ba); + [[maybe_unused]] static constexpr const auto k##name = FRAMELESSHELPER_BYTEARRAY_VIEW(ba); #endif #ifndef FRAMELESSHELPER_STRING_CONSTANT2 # define FRAMELESSHELPER_STRING_CONSTANT2(name, str) \ - [[maybe_unused]] static const auto k##name = FRAMELESSHELPER_STRING_LITERAL(str); + [[maybe_unused]] static constexpr const auto k##name = FRAMELESSHELPER_STRING_VIEW(str); #endif #ifndef FRAMELESSHELPER_BYTEARRAY_CONSTANT @@ -248,16 +268,11 @@ 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 kDefaultSystemCloseButtonBackgroundColor = {232, 17, 35}; // #E81123 -[[maybe_unused]] inline const QByteArray kDontOverrideCursorVar - = FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_DONT_OVERRIDE_CURSOR"); -[[maybe_unused]] inline const QByteArray kDontToggleMaximizeVar - = FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_DONT_TOGGLE_MAXIMIZE"); -[[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"); +[[maybe_unused]] inline constexpr const char kDontOverrideCursorVar[] = "FRAMELESSHELPER_DONT_OVERRIDE_CURSOR"; +[[maybe_unused]] inline constexpr const char kDontToggleMaximizeVar[] = "FRAMELESSHELPER_DONT_TOGGLE_MAXIMIZE"; +[[maybe_unused]] inline constexpr const char kSysMenuDisableMinimizeVar[] = "FRAMELESSHELPER_SYSTEM_MENU_DISABLE_MINIMIZE"; +[[maybe_unused]] inline constexpr const char kSysMenuDisableMaximizeVar[] = "FRAMELESSHELPER_SYSTEM_MENU_DISABLE_MAXIMIZE"; +[[maybe_unused]] inline constexpr const char kSysMenuDisableRestoreVar[] = "FRAMELESSHELPER_SYSTEM_MENU_DISABLE_RESTORE"; enum class Option : quint8 { diff --git a/include/FramelessHelper/Core/framelessmanager.h b/include/FramelessHelper/Core/framelessmanager.h index b7a015fe..5112ae2c 100644 --- a/include/FramelessHelper/Core/framelessmanager.h +++ b/include/FramelessHelper/Core/framelessmanager.h @@ -42,9 +42,6 @@ class FRAMELESSHELPER_CORE_API FramelessManager : public QObject Q_PROPERTY(Global::WallpaperAspectStyle wallpaperAspectStyle READ wallpaperAspectStyle NOTIFY wallpaperChanged FINAL) public: - explicit FramelessManager(QObject *parent = nullptr); - ~FramelessManager() override; - Q_NODISCARD static FramelessManager *instance(); Q_NODISCARD Global::SystemTheme systemTheme() const; @@ -61,6 +58,10 @@ public Q_SLOTS: void systemThemeChanged(); void wallpaperChanged(); +private: + explicit FramelessManager(QObject *parent = nullptr); + ~FramelessManager() override; + private: QScopedPointer d_ptr; }; diff --git a/include/FramelessHelper/Core/private/framelessconfig_p.h b/include/FramelessHelper/Core/private/framelessconfig_p.h index e097568d..e97609ac 100644 --- a/include/FramelessHelper/Core/private/framelessconfig_p.h +++ b/include/FramelessHelper/Core/private/framelessconfig_p.h @@ -34,9 +34,6 @@ class FRAMELESSHELPER_CORE_API FramelessConfig : public QObject Q_DISABLE_COPY_MOVE(FramelessConfig) public: - explicit FramelessConfig(QObject *parent = nullptr); - ~FramelessConfig() override; - Q_NODISCARD static FramelessConfig *instance(); void reload(const bool force = false); @@ -46,6 +43,10 @@ class FRAMELESSHELPER_CORE_API FramelessConfig : public QObject static void setLoadFromEnvironmentVariablesDisabled(const bool on = true); static void setLoadFromConfigurationFileDisabled(const bool on = true); + +private: + explicit FramelessConfig(QObject *parent = nullptr); + ~FramelessConfig() override; }; FRAMELESSHELPER_END_NAMESPACE diff --git a/include/FramelessHelper/Core/private/framelesshelpercore_global_p.h b/include/FramelessHelper/Core/private/framelesshelpercore_global_p.h index 18b4c9b0..605867ea 100644 --- a/include/FramelessHelper/Core/private/framelesshelpercore_global_p.h +++ b/include/FramelessHelper/Core/private/framelesshelpercore_global_p.h @@ -56,8 +56,8 @@ using SetSystemButtonStateCallback = std::function; using ShouldIgnoreMouseEventsCallback = std::function; using ShowSystemMenuCallback = std::function; -using SetPropertyCallback = std::function; -using GetPropertyCallback = std::function; +using SetPropertyCallback = std::function; +using GetPropertyCallback = std::function; using SetCursorCallback = std::function; using UnsetCursorCallback = std::function; using GetWidgetHandleCallback = std::function; diff --git a/include/FramelessHelper/Core/private/sysapiloader_p.h b/include/FramelessHelper/Core/private/sysapiloader_p.h index 95506769..fa69a4a8 100644 --- a/include/FramelessHelper/Core/private/sysapiloader_p.h +++ b/include/FramelessHelper/Core/private/sysapiloader_p.h @@ -34,9 +34,6 @@ class FRAMELESSHELPER_CORE_API SysApiLoader : public QObject Q_DISABLE_COPY_MOVE(SysApiLoader) public: - explicit SysApiLoader(QObject *parent = nullptr); - ~SysApiLoader() override; - Q_NODISCARD static SysApiLoader *instance(); Q_NODISCARD static QString platformSharedLibrarySuffixName(); @@ -44,7 +41,6 @@ class FRAMELESSHELPER_CORE_API SysApiLoader : public QObject 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 QByteArray &function); Q_NODISCARD static QFunctionPointer resolve(const QString &library, const QString &function); Q_NODISCARD bool isAvailable(const QString &library, const QString &function); @@ -56,6 +52,10 @@ class FRAMELESSHELPER_CORE_API SysApiLoader : public QObject { return reinterpret_cast(get(library, function)); } + +private: + explicit SysApiLoader(QObject *parent = nullptr); + ~SysApiLoader() override; }; FRAMELESSHELPER_END_NAMESPACE diff --git a/include/FramelessHelper/Core/private/versionnumber_p.h b/include/FramelessHelper/Core/private/versionnumber_p.h index a6509b06..bcef97c3 100644 --- a/include/FramelessHelper/Core/private/versionnumber_p.h +++ b/include/FramelessHelper/Core/private/versionnumber_p.h @@ -88,35 +88,35 @@ struct VersionNumber }; #ifdef Q_OS_WINDOWS -[[maybe_unused]] inline constexpr const VersionNumber WindowsVersions[] = +[[maybe_unused]] inline constexpr const std::array WindowsVersions = { - { 5, 0, 2195}, // Windows 2000 - { 5, 1, 2600}, // Windows XP - { 5, 2, 3790}, // Windows XP x64 Edition or Windows Server 2003 - { 6, 0, 6000}, // Windows Vista - { 6, 0, 6001}, // Windows Vista with Service Pack 1 or Windows Server 2008 - { 6, 0, 6002}, // Windows Vista with Service Pack 2 - { 6, 1, 7600}, // Windows 7 or Windows Server 2008 R2 - { 6, 1, 7601}, // Windows 7 with Service Pack 1 or Windows Server 2008 R2 with Service Pack 1 - { 6, 2, 9200}, // Windows 8 or Windows Server 2012 - { 6, 3, 9200}, // Windows 8.1 or Windows Server 2012 R2 - { 6, 3, 9600}, // Windows 8.1 with Update 1 - {10, 0, 10240}, // Windows 10 Version 1507 (TH1) - {10, 0, 10586}, // Windows 10 Version 1511 (November Update) (TH2) - {10, 0, 14393}, // Windows 10 Version 1607 (Anniversary Update) (RS1) or Windows Server 2016 - {10, 0, 15063}, // Windows 10 Version 1703 (Creators Update) (RS2) - {10, 0, 16299}, // Windows 10 Version 1709 (Fall Creators Update) (RS3) - {10, 0, 17134}, // Windows 10 Version 1803 (April 2018 Update) (RS4) - {10, 0, 17763}, // Windows 10 Version 1809 (October 2018 Update) (RS5) or Windows Server 2019 - {10, 0, 18362}, // Windows 10 Version 1903 (May 2019 Update) (19H1) - {10, 0, 18363}, // Windows 10 Version 1909 (November 2019 Update) (19H2) - {10, 0, 19041}, // Windows 10 Version 2004 (May 2020 Update) (20H1) - {10, 0, 19042}, // Windows 10 Version 20H2 (October 2020 Update) (20H2) - {10, 0, 19043}, // Windows 10 Version 21H1 (May 2021 Update) (21H1) - {10, 0, 19044}, // Windows 10 Version 21H2 (November 2021 Update) (21H2) - {10, 0, 19045}, // Windows 10 Version 22H2 (October 2022 Update) (22H2) - {10, 0, 22000}, // Windows 11 Version 21H2 (21H2) - {10, 0, 22621} // Windows 11 Version 22H2 (October 2022 Update) (22H2) + VersionNumber{ 5, 0, 2195 }, // Windows 2000 + VersionNumber{ 5, 1, 2600 }, // Windows XP + VersionNumber{ 5, 2, 3790 }, // Windows XP x64 Edition or Windows Server 2003 + VersionNumber{ 6, 0, 6000 }, // Windows Vista + VersionNumber{ 6, 0, 6001 }, // Windows Vista with Service Pack 1 or Windows Server 2008 + VersionNumber{ 6, 0, 6002 }, // Windows Vista with Service Pack 2 + VersionNumber{ 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 + VersionNumber{ 6, 2, 9200 }, // Windows 8 or Windows Server 2012 + VersionNumber{ 6, 3, 9200 }, // Windows 8.1 or Windows Server 2012 R2 + VersionNumber{ 6, 3, 9600 }, // Windows 8.1 with Update 1 + VersionNumber{ 10, 0, 10240 }, // Windows 10 Version 1507 (TH1) + VersionNumber{ 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 + VersionNumber{ 10, 0, 15063 }, // Windows 10 Version 1703 (Creators Update) (RS2) + VersionNumber{ 10, 0, 16299 }, // Windows 10 Version 1709 (Fall Creators Update) (RS3) + VersionNumber{ 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 + VersionNumber{ 10, 0, 18362 }, // Windows 10 Version 1903 (May 2019 Update) (19H1) + VersionNumber{ 10, 0, 18363 }, // Windows 10 Version 1909 (November 2019 Update) (19H2) + VersionNumber{ 10, 0, 19041 }, // Windows 10 Version 2004 (May 2020 Update) (20H1) + VersionNumber{ 10, 0, 19042 }, // Windows 10 Version 20H2 (October 2020 Update) (20H2) + VersionNumber{ 10, 0, 19043 }, // Windows 10 Version 21H1 (May 2021 Update) (21H1) + VersionNumber{ 10, 0, 19044 }, // Windows 10 Version 21H2 (November 2021 Update) (21H2) + VersionNumber{ 10, 0, 19045 }, // Windows 10 Version 22H2 (October 2022 Update) (22H2) + VersionNumber{ 10, 0, 22000 }, // Windows 11 Version 21H2 (21H2) + VersionNumber{ 10, 0, 22621 } // Windows 11 Version 22H2 (October 2022 Update) (22H2) }; #endif // Q_OS_WINDOWS diff --git a/include/FramelessHelper/Quick/private/framelessquickhelper_p.h b/include/FramelessHelper/Quick/private/framelessquickhelper_p.h index 35c68da8..d0c8202b 100644 --- a/include/FramelessHelper/Quick/private/framelessquickhelper_p.h +++ b/include/FramelessHelper/Quick/private/framelessquickhelper_p.h @@ -72,13 +72,13 @@ class FRAMELESSHELPER_QUICK_API FramelessQuickHelperPrivate : public QObject Q_NODISCARD bool isWindowFixedSize() const; void setWindowFixedSize(const bool value); - void emitSignalForAllInstances(const QByteArray &signal); + void emitSignalForAllInstances(const char *signal); Q_NODISCARD bool isBlurBehindWindowEnabled() const; void setBlurBehindWindowEnabled(const bool value, const QColor &color); - void setProperty(const QByteArray &name, const QVariant &value); - Q_NODISCARD QVariant getProperty(const QByteArray &name, const QVariant &defaultValue = {}); + void setProperty(const char *name, const QVariant &value); + Q_NODISCARD QVariant getProperty(const char *name, const QVariant &defaultValue = {}); Q_NODISCARD QuickMicaMaterial *findOrCreateMicaMaterial() const; Q_NODISCARD QuickWindowBorder *findOrCreateWindowBorder() const; diff --git a/include/FramelessHelper/Widgets/private/framelesswidgetshelper_p.h b/include/FramelessHelper/Widgets/private/framelesswidgetshelper_p.h index 5b6db18a..da8dcbd4 100644 --- a/include/FramelessHelper/Widgets/private/framelesswidgetshelper_p.h +++ b/include/FramelessHelper/Widgets/private/framelesswidgetshelper_p.h @@ -71,13 +71,13 @@ class FRAMELESSHELPER_WIDGETS_API FramelessWidgetsHelperPrivate : public QObject Q_NODISCARD bool isWindowFixedSize() const; void setWindowFixedSize(const bool value); - void emitSignalForAllInstances(const QByteArray &signal); + void emitSignalForAllInstances(const char *signal); Q_NODISCARD bool isBlurBehindWindowEnabled() const; void setBlurBehindWindowEnabled(const bool enable, const QColor &color); - void setProperty(const QByteArray &name, const QVariant &value); - Q_NODISCARD QVariant getProperty(const QByteArray &name, const QVariant &defaultValue = {}); + void setProperty(const char *name, const QVariant &value); + Q_NODISCARD QVariant getProperty(const char *name, const QVariant &defaultValue = {}); Q_NODISCARD QWidget *window() const; diff --git a/src/core/chromepalette.cpp b/src/core/chromepalette.cpp index 20ee2cbc..0ca29714 100644 --- a/src/core/chromepalette.cpp +++ b/src/core/chromepalette.cpp @@ -95,10 +95,11 @@ void ChromePalettePrivate::refresh() // Calculate the most appropriate foreground color, based on the // current background color. const qreal grayF = ( - (0.299 * titleBarActiveBackgroundColor_sys.redF()) + - (0.587 * titleBarActiveBackgroundColor_sys.greenF()) + - (0.114 * titleBarActiveBackgroundColor_sys.blueF())); - if (grayF <= 0.5) { + (qreal(0.299) * titleBarActiveBackgroundColor_sys.redF()) + + (qreal(0.587) * titleBarActiveBackgroundColor_sys.greenF()) + + (qreal(0.114) * titleBarActiveBackgroundColor_sys.blueF())); + static constexpr const auto kFlag = qreal(0.5); + if ((grayF < kFlag) || qFuzzyCompare(grayF, kFlag)) { return kDefaultWhiteColor; } } diff --git a/src/core/framelessconfig.cpp b/src/core/framelessconfig.cpp index adccfd31..ecb169e6 100644 --- a/src/core/framelessconfig.cpp +++ b/src/core/framelessconfig.cpp @@ -49,36 +49,29 @@ using namespace Global; FRAMELESSHELPER_STRING_CONSTANT2(ConfigFileName, ".framelesshelper.ini") -static const struct +struct FramelessConfigEntry { - const QByteArray env = {}; - 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")} + const char *env = nullptr; + const char *cfg = nullptr; }; -static constexpr const auto OptionCount = std::size(OptionsTable); +static constexpr const std::array FramelessOptionsTable = +{ + 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" } +}; -struct ConfigData +static constexpr const auto OptionCount = std::size(FramelessOptionsTable); + +struct FramelessConfigData { bool loaded = false; bool options[OptionCount] = {}; @@ -86,9 +79,7 @@ struct ConfigData bool disableCfgFile = false; }; -Q_GLOBAL_STATIC(ConfigData, g_data) - -Q_GLOBAL_STATIC(FramelessConfig, g_config) +Q_GLOBAL_STATIC(FramelessConfigData, g_framelessConfigData) static inline void warnInappropriateOptions() { @@ -127,12 +118,13 @@ FramelessConfig::~FramelessConfig() = default; FramelessConfig *FramelessConfig::instance() { - return g_config(); + static FramelessConfig config; + return &config; } void FramelessConfig::reload(const bool force) { - if (g_data()->loaded && !force) { + if (g_framelessConfigData()->loaded && !force) { return; } const auto configFile = []() -> std::unique_ptr { @@ -143,36 +135,36 @@ void FramelessConfig::reload(const bool force) return std::make_unique(appDir.filePath(kConfigFileName), QSettings::IniFormat); }(); for (int i = 0; i != OptionCount; ++i) { - const bool envVar = (!g_data()->disableEnvVar - && qEnvironmentVariableIsSet(OptionsTable[i].env.constData()) - && (qEnvironmentVariableIntValue(OptionsTable[i].env.constData()) > 0)); - const bool cfgFile = (!g_data()->disableCfgFile && configFile - && configFile->value(QUtf8String(OptionsTable[i].cfg), false).toBool()); - g_data()->options[i] = (envVar || cfgFile); + const bool envVar = (!g_framelessConfigData()->disableEnvVar + && qEnvironmentVariableIsSet(FramelessOptionsTable.at(i).env) + && (qEnvironmentVariableIntValue(FramelessOptionsTable.at(i).env) > 0)); + const bool cfgFile = (!g_framelessConfigData()->disableCfgFile && configFile + && configFile->value(QUtf8String(FramelessOptionsTable.at(i).cfg), false).toBool()); + g_framelessConfigData()->options[i] = (envVar || cfgFile); } - g_data()->loaded = true; + g_framelessConfigData()->loaded = true; QTimer::singleShot(0, this, [](){ warnInappropriateOptions(); }); } void FramelessConfig::set(const Option option, const bool on) { - g_data()->options[static_cast(option)] = on; + g_framelessConfigData()->options[static_cast(option)] = on; } bool FramelessConfig::isSet(const Option option) const { - return g_data()->options[static_cast(option)]; + return g_framelessConfigData()->options[static_cast(option)]; } void FramelessConfig::setLoadFromEnvironmentVariablesDisabled(const bool on) { - g_data()->disableEnvVar = on; + g_framelessConfigData()->disableEnvVar = on; } void FramelessConfig::setLoadFromConfigurationFileDisabled(const bool on) { - g_data()->disableCfgFile = on; + g_framelessConfigData()->disableCfgFile = on; } FRAMELESSHELPER_END_NAMESPACE diff --git a/src/core/framelesshelper_qt.cpp b/src/core/framelesshelper_qt.cpp index b979d9a3..15f7e2c2 100644 --- a/src/core/framelesshelper_qt.cpp +++ b/src/core/framelesshelper_qt.cpp @@ -50,7 +50,7 @@ FRAMELESSHELPER_BEGIN_NAMESPACE using namespace Global; -struct QtHelperData +struct FramelessQtHelperData { SystemParameters params = {}; FramelessHelperQt *eventFilter = nullptr; @@ -58,12 +58,12 @@ struct QtHelperData bool leftButtonPressed = false; }; -struct QtHelper +struct FramelessQtHelper { - QHash data = {}; + QHash data = {}; }; -Q_GLOBAL_STATIC(QtHelper, g_qtHelper) +Q_GLOBAL_STATIC(FramelessQtHelper, g_framelessQtHelperData) FramelessHelperQt::FramelessHelperQt(QObject *parent) : QObject(parent) {} @@ -76,15 +76,16 @@ void FramelessHelperQt::addWindow(FramelessParamsConst params) return; } const WId windowId = params->getWindowId(); - if (g_qtHelper()->data.contains(windowId)) { + const auto it = g_framelessQtHelperData()->data.constFind(windowId); + if (it != g_framelessQtHelperData()->data.constEnd()) { return; } - QtHelperData data = {}; + FramelessQtHelperData data = {}; data.params = *params; QWindow *window = params->getWindowHandle(); // Give it a parent so that it can be automatically deleted by Qt. data.eventFilter = new FramelessHelperQt(window); - g_qtHelper()->data.insert(windowId, data); + g_framelessQtHelperData()->data.insert(windowId, data); const auto shouldApplyFramelessFlag = []() -> bool { #ifdef Q_OS_MACOS return false; @@ -101,7 +102,7 @@ void FramelessHelperQt::addWindow(FramelessParamsConst params) params->setWindowFlags(params->getWindowFlags() | Qt::FramelessWindowHint); } else { #ifdef Q_OS_LINUX - Q_UNUSED(Utils::tryHideSystemTitleBar(windowId, true)); + std::ignore = Utils::tryHideSystemTitleBar(windowId, true); #elif defined(Q_OS_MACOS) Utils::setSystemTitleBarVisible(windowId, false); #endif // Q_OS_LINUX @@ -116,10 +117,11 @@ void FramelessHelperQt::removeWindow(const WId windowId) if (!windowId) { return; } - if (!g_qtHelper()->data.contains(windowId)) { + const auto it = g_framelessQtHelperData()->data.constFind(windowId); + if (it == g_framelessQtHelperData()->data.constEnd()) { return; } - g_qtHelper()->data.remove(windowId); + g_framelessQtHelperData()->data.erase(it); #ifdef Q_OS_MACOS Utils::removeWindowProxy(windowId); #endif @@ -163,10 +165,12 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event) } const auto window = qobject_cast(object); const WId windowId = window->winId(); - if (!g_qtHelper()->data.contains(windowId)) { + const auto it = g_framelessQtHelperData()->data.find(windowId); + if (it == g_framelessQtHelperData()->data.end()) { return QObject::eventFilter(object, event); } - const QtHelperData data = g_qtHelper()->data.value(windowId); + const FramelessQtHelperData &data = it.value(); + FramelessQtHelperData &muData = it.value(); #if (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)) if (type == QEvent::DevicePixelRatioChange) #else // QT_VERSION < QT_VERSION_CHECK(6, 6, 0) @@ -193,7 +197,7 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event) switch (type) { case QEvent::MouseButtonPress: { if (button == Qt::LeftButton) { - g_qtHelper()->data[windowId].leftButtonPressed = true; + muData.leftButtonPressed = true; if (!windowFixedSize) { const Qt::Edges edges = Utils::calculateWindowEdges(window, scenePos); if (edges != Qt::Edges{}) { @@ -206,7 +210,7 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event) } break; case QEvent::MouseButtonRelease: { if (button == Qt::LeftButton) { - g_qtHelper()->data[windowId].leftButtonPressed = false; + muData.leftButtonPressed = false; } if (button == Qt::RightButton) { if (!ignoreThisEvent && insideTitleBar) { @@ -233,11 +237,11 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event) if (cs == Qt::ArrowCursor) { if (data.cursorShapeChanged) { data.params.unsetCursor(); - g_qtHelper()->data[windowId].cursorShapeChanged = false; + muData.cursorShapeChanged = false; } } else { data.params.setCursor(cs); - g_qtHelper()->data[windowId].cursorShapeChanged = true; + muData.cursorShapeChanged = true; } } if (data.leftButtonPressed) { diff --git a/src/core/framelesshelper_win.cpp b/src/core/framelesshelper_win.cpp index 241da8d8..d1aca95e 100644 --- a/src/core/framelesshelper_win.cpp +++ b/src/core/framelesshelper_win.cpp @@ -55,9 +55,7 @@ static Q_LOGGING_CATEGORY(lcFramelessHelperWin, "wangwenx190.framelesshelper.cor using namespace Global; -[[maybe_unused]] static constexpr const wchar_t kFallbackTitleBarWindowClassName[] = - L"org.wangwenx190.FramelessHelper.FallbackTitleBarWindow"; -FRAMELESSHELPER_BYTEARRAY_CONSTANT2(Win32MessageTypeName, "windows_generic_MSG") +[[maybe_unused]] static constexpr const wchar_t kFallbackTitleBarWindowClassName[] = L"org.wangwenx190.FramelessHelper.FallbackTitleBarWindow"; FRAMELESSHELPER_STRING_CONSTANT(MonitorFromWindow) FRAMELESSHELPER_STRING_CONSTANT(GetMonitorInfoW) FRAMELESSHELPER_STRING_CONSTANT(ScreenToClient) @@ -85,15 +83,8 @@ FRAMELESSHELPER_STRING_CONSTANT(UnregisterClassW) FRAMELESSHELPER_STRING_CONSTANT(DestroyWindow) FRAMELESSHELPER_STRING_CONSTANT(GetWindowPlacement) 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 Win32HelperData +struct FramelessWin32HelperData { SystemParameters params = {}; bool trackingMouse = false; @@ -104,14 +95,14 @@ struct Win32HelperData #endif // (QT_VERSION < QT_VERSION_CHECK(6, 5, 1)) }; -struct Win32Helper +struct FramelessWin32Helper { std::unique_ptr nativeEventFilter = nullptr; - QHash data = {}; + QHash data = {}; QHash fallbackTitleBarToParentWindowMapping = {}; }; -Q_GLOBAL_STATIC(Win32Helper, g_win32Helper) +Q_GLOBAL_STATIC(FramelessWin32Helper, g_framelessWin32HelperData) [[nodiscard]] extern bool operator==(const RECT &lhs, const RECT &rhs) noexcept; [[nodiscard]] extern bool operator!=(const RECT &lhs, const RECT &rhs) noexcept; @@ -142,14 +133,17 @@ Q_GLOBAL_STATIC(Win32Helper, g_win32Helper) return DefWindowProcW(hWnd, uMsg, wParam, lParam); } const auto windowId = reinterpret_cast(hWnd); - if (!g_win32Helper()->fallbackTitleBarToParentWindowMapping.contains(windowId)) { + const auto fallbackTitleBarIt = g_framelessWin32HelperData()->fallbackTitleBarToParentWindowMapping.constFind(windowId); + if (fallbackTitleBarIt == g_framelessWin32HelperData()->fallbackTitleBarToParentWindowMapping.constEnd()) { return DefWindowProcW(hWnd, uMsg, wParam, lParam); } - const WId parentWindowId = g_win32Helper()->fallbackTitleBarToParentWindowMapping.value(windowId); - if (!g_win32Helper()->data.contains(parentWindowId)) { + const WId parentWindowId = fallbackTitleBarIt.value(); + const auto it = g_framelessWin32HelperData()->data.find(parentWindowId); + if (it == g_framelessWin32HelperData()->data.end()) { return DefWindowProcW(hWnd, uMsg, wParam, lParam); } - const Win32HelperData data = g_win32Helper()->data.value(parentWindowId); + const FramelessWin32HelperData &data = it.value(); + FramelessWin32HelperData &muData = it.value(); const auto parentWindowHandle = reinterpret_cast(parentWindowId); // All mouse events: client area mouse events + non-client area mouse events. // Hit-testing event should not be considered as a mouse event. @@ -281,14 +275,14 @@ Q_GLOBAL_STATIC(Win32Helper, g_win32Helper) WARNING << Utils::getSystemErrorMessage(kTrackMouseEvent); break; } - g_win32Helper()->data[parentWindowId].trackingMouse = true; + muData.trackingMouse = true; } } break; case WM_NCMOUSELEAVE: case WM_MOUSELEAVE: { // When the mouse leaves the drag rect, make sure to dismiss any hover. releaseButtons(std::nullopt); - g_win32Helper()->data[parentWindowId].trackingMouse = false; + muData.trackingMouse = false; } break; // NB: *Shouldn't be forwarding these* when they're not over the caption // because they can inadvertently take action using the system's default @@ -475,8 +469,10 @@ static inline void cleanupFallbackWindow() WARNING << "Failed to register the window class for the fallback title bar window."; return false; } - const HWND fallbackTitleBarWindowHandle = CreateWindowExW((WS_EX_LAYERED | WS_EX_NOREDIRECTIONBITMAP), - kFallbackTitleBarWindowClassName, nullptr, WS_CHILD, 0, 0, 0, 0, + static constexpr const auto style = DWORD(WS_CHILD); + static constexpr const auto exStyle = DWORD(WS_EX_LAYERED | WS_EX_NOREDIRECTIONBITMAP); + const HWND fallbackTitleBarWindowHandle = CreateWindowExW(exStyle, + kFallbackTitleBarWindowClassName, nullptr, style, 0, 0, 0, 0, parentWindowHandle, nullptr, instance, nullptr); // 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. @@ -484,10 +480,13 @@ static inline void cleanupFallbackWindow() // 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 // to a wrong direction instead. - //Q_ASSERT_X(fallbackTitleBarWindowHandle, __FUNCTION__, kFallbackTitleBarErrorMessage); if (!fallbackTitleBarWindowHandle) { WARNING << Utils::getSystemErrorMessage(kCreateWindowExW); - WARNING << kFallbackTitleBarErrorMessage; + WARNING << "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."; return false; } // Layered windows won't become visible unless we call the SetLayeredWindowAttributes() @@ -501,10 +500,10 @@ static inline void cleanupFallbackWindow() WARNING << "Failed to re-position the fallback title bar window."; return false; } - g_win32Helper()->data[parentWindowId].fallbackTitleBarWindowId = fallbackTitleBarWindowId; - g_win32Helper()->fallbackTitleBarToParentWindowMapping.insert(fallbackTitleBarWindowId, parentWindowId); + g_framelessWin32HelperData()->data[parentWindowId].fallbackTitleBarWindowId = fallbackTitleBarWindowId; + g_framelessWin32HelperData()->fallbackTitleBarToParentWindowMapping.insert(fallbackTitleBarWindowId, parentWindowId); // ### Why do we need an extra resize here? - QTimer::singleShot(0, qApp, [parentWindowId, fallbackTitleBarWindowId, hide](){ + QTimer::singleShot(200, qApp, [parentWindowId, fallbackTitleBarWindowId, hide](){ std::ignore = resizeFallbackTitleBarWindow(parentWindowId, fallbackTitleBarWindowId, hide); }); return true; @@ -521,16 +520,17 @@ void FramelessHelperWin::addWindow(FramelessParamsConst params) return; } const WId windowId = params->getWindowId(); - if (g_win32Helper()->data.contains(windowId)) { + const auto it = g_framelessWin32HelperData()->data.constFind(windowId); + if (it != g_framelessWin32HelperData()->data.constEnd()) { return; } - Win32HelperData data = {}; + FramelessWin32HelperData data = {}; data.params = *params; data.dpi = {Utils::getWindowDpi(windowId, true), Utils::getWindowDpi(windowId, false)}; - g_win32Helper()->data.insert(windowId, data); - if (!g_win32Helper()->nativeEventFilter) { - g_win32Helper()->nativeEventFilter = std::make_unique(); - qApp->installNativeEventFilter(g_win32Helper()->nativeEventFilter.get()); + g_framelessWin32HelperData()->data.insert(windowId, data); + if (!g_framelessWin32HelperData()->nativeEventFilter) { + g_framelessWin32HelperData()->nativeEventFilter = std::make_unique(); + qApp->installNativeEventFilter(g_framelessWin32HelperData()->nativeEventFilter.get()); } 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). @@ -586,29 +586,30 @@ void FramelessHelperWin::removeWindow(const WId windowId) if (!windowId) { return; } - if (!g_win32Helper()->data.contains(windowId)) { + const auto it = g_framelessWin32HelperData()->data.constFind(windowId); + if (it == g_framelessWin32HelperData()->data.constEnd()) { return; } - g_win32Helper()->data.remove(windowId); - if (g_win32Helper()->data.isEmpty()) { - if (g_win32Helper()->nativeEventFilter) { - qApp->removeNativeEventFilter(g_win32Helper()->nativeEventFilter.get()); - g_win32Helper()->nativeEventFilter.reset(); + g_framelessWin32HelperData()->data.erase(it); + if (g_framelessWin32HelperData()->data.isEmpty()) { + if (g_framelessWin32HelperData()->nativeEventFilter) { + qApp->removeNativeEventFilter(g_framelessWin32HelperData()->nativeEventFilter.get()); + g_framelessWin32HelperData()->nativeEventFilter.reset(); } } - auto it = g_win32Helper()->fallbackTitleBarToParentWindowMapping.constBegin(); - while (it != g_win32Helper()->fallbackTitleBarToParentWindowMapping.constEnd()) { - if (it.value() == windowId) { - g_win32Helper()->fallbackTitleBarToParentWindowMapping.remove(it.key()); + auto fallbackTitleBarIt = g_framelessWin32HelperData()->fallbackTitleBarToParentWindowMapping.constBegin(); + while (fallbackTitleBarIt != g_framelessWin32HelperData()->fallbackTitleBarToParentWindowMapping.constEnd()) { + if (fallbackTitleBarIt.value() == windowId) { + g_framelessWin32HelperData()->fallbackTitleBarToParentWindowMapping.erase(fallbackTitleBarIt); break; } - ++it; + ++fallbackTitleBarIt; } } bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *message, QT_NATIVE_EVENT_RESULT_TYPE *result) { - if ((eventType != kWin32MessageTypeName) || !message || !result) { + if ((eventType != "windows_generic_MSG") || !message || !result) { return false; } // QPA by default stores the global mouse position in the pt field, @@ -635,10 +636,12 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me if ((uMsg == WM_CLOSE) || (uMsg == WM_DESTROY)) { return false; } - if (!g_win32Helper()->data.contains(windowId)) { + const auto it = g_framelessWin32HelperData()->data.find(windowId); + if (it == g_framelessWin32HelperData()->data.end()) { return false; } - const Win32HelperData data = g_win32Helper()->data.value(windowId); + const FramelessWin32HelperData &data = it.value(); + FramelessWin32HelperData &muData = it.value(); const bool frameBorderVisible = Utils::isWindowFrameBorderVisible(); const WPARAM wParam = msg->wParam; const LPARAM lParam = msg->lParam; @@ -656,7 +659,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me if (Utils::isValidGeometry(data.restoreGeometry) && (data.restoreGeometry == rect)) { return; } - g_win32Helper()->data[windowId].restoreGeometry = rect; + muData.restoreGeometry = rect; }; #endif // (QT_VERSION < QT_VERSION_CHECK(6, 5, 1)) @@ -908,7 +911,7 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me // 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 // whether it exists on Windows XP to Windows Vista or not. - const bool needD3DWorkaround = (qEnvironmentVariableIntValue(kD3DWorkaroundEnvVar) != 0); + const bool needD3DWorkaround = (qEnvironmentVariableIntValue("FRAMELESSHELPER_USE_D3D_WORKAROUND") != 0); *result = (((static_cast(wParam) == FALSE) || needD3DWorkaround) ? 0 : WVR_REDRAW); return true; } @@ -1179,12 +1182,11 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me } DEBUG.noquote() << "New DPI for window" << hwnd2str(hWnd) << "is" << newDpi << "(was" << oldDpi << ")."; - g_win32Helper()->data[windowId].dpi = newDpi; + muData.dpi = newDpi; #if (QT_VERSION < QT_VERSION_CHECK(6, 5, 1)) if (Utils::isValidGeometry(data.restoreGeometry)) { // Update the window size only. The position should not be changed. - g_win32Helper()->data[windowId].restoreGeometry.setSize( - Utils::rescaleSize(data.restoreGeometry.size(), oldDpi.x, newDpi.x)); + muData.restoreGeometry.setSize(Utils::rescaleSize(data.restoreGeometry.size(), oldDpi.x, newDpi.x)); } #endif // (QT_VERSION < QT_VERSION_CHECK(6, 5, 1)) data.params.forceChildrenRepaint(500); diff --git a/src/core/framelesshelpercore_global.cpp b/src/core/framelesshelpercore_global.cpp index 1f09a707..292b7c4f 100644 --- a/src/core/framelesshelpercore_global.cpp +++ b/src/core/framelesshelpercore_global.cpp @@ -129,17 +129,6 @@ using namespace Global; static_assert(std::size(WindowsVersions) == (static_cast(WindowsVersion::Latest) + 1)); #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) { Q_UNUSED(cb); @@ -171,14 +160,14 @@ void initialize() // 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 // instances. QCoreApplication won't instantiate the platform plugin. - qputenv(QT_QPA_ENV_VAR, kxcb); + qputenv("QT_QPA_PLATFORM", "xcb"); // Fedora and Arch users report segfault when calling XInitThreads() and gtk_init(). //XInitThreads(); // Users report that GTK is crashing without this. //gtk_init(nullptr, nullptr); // Users report that GTK functionalities won't work without this. #endif #if (defined(Q_OS_MACOS) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))) - qputenv(MAC_LAYER_ENV_VAR, FRAMELESSHELPER_BYTEARRAY_LITERAL("1")); + qputenv("QT_MAC_WANTS_LAYER", "1"); #endif #ifdef Q_OS_WINDOWS @@ -278,7 +267,7 @@ void setApplicationOSThemeAware() void outputLogo() { - if (qEnvironmentVariableIntValue(kNoLogoEnvVar)) { + if (qEnvironmentVariableIntValue("FRAMELESSHELPER_NO_LOGO")) { return; } const VersionInfo &ver = version(); diff --git a/src/core/framelessmanager.cpp b/src/core/framelessmanager.cpp index c409bf91..92483608 100644 --- a/src/core/framelessmanager.cpp +++ b/src/core/framelessmanager.cpp @@ -60,28 +60,12 @@ static Q_LOGGING_CATEGORY(lcFramelessManager, "wangwenx190.framelesshelper.core. using namespace Global; -struct FramelessManagerHelper +struct FramelessManagerData { QList windowIds = {}; }; -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 +Q_GLOBAL_STATIC(FramelessManagerData, g_framelessManagerData) #ifndef FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE [[nodiscard]] static inline QString iconFontFamilyName() @@ -89,13 +73,13 @@ FRAMELESSHELPER_STRING_CONSTANT2(IconFontFamilyName_fallback, "iconfont") static const auto result = []() -> QString { #ifdef Q_OS_WINDOWS if (WindowsVersionHelper::isWin11OrGreater()) { - return kIconFontFamilyName_win11; + return FRAMELESSHELPER_STRING_LITERAL("Segoe Fluent Icons"); } if (WindowsVersionHelper::isWin10OrGreater()) { - return kIconFontFamilyName_win10; + return FRAMELESSHELPER_STRING_LITERAL("Segoe MDL2 Assets"); } #endif // Q_OS_WINDOWS - return kIconFontFamilyName_fallback; + return FRAMELESSHELPER_STRING_LITERAL("iconfont"); }(); return result; } @@ -141,11 +125,11 @@ void FramelessManagerPrivate::initializeIconFont() inited = true; framelesshelpercore_initResource(); // We always register this font because it's our only fallback. - const int id = QFontDatabase::addApplicationFont(kIconFontFilePath); + const int id = QFontDatabase::addApplicationFont(FRAMELESSHELPER_STRING_LITERAL(":/org.wangwenx190.FramelessHelper/resources/fonts/iconfont.ttf")); if (id < 0) { - WARNING << "Failed to load icon font:" << kIconFontFilePath; + WARNING << "Failed to load icon font."; } else { - DEBUG << "Successfully registered icon font:" << QFontDatabase::applicationFontFamilies(id); + DEBUG << "Successfully registered icon font."; } #endif // FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE } @@ -158,7 +142,11 @@ QFont FramelessManagerPrivate::getIconFont() static const auto font = []() -> QFont { QFont f = {}; f.setFamily(iconFontFamilyName()); - f.setPointSize(kIconFontPointSize); +# ifdef Q_OS_MACOS + f.setPointSize(10); +# else // !Q_OS_MACOS + f.setPointSize(8); +# endif // Q_OS_MACOS return f; }(); return font; @@ -196,10 +184,10 @@ void FramelessManagerPrivate::addWindow(FramelessParamsConst params) return; } const WId windowId = params->getWindowId(); - if (g_helper()->windowIds.contains(windowId)) { + if (g_framelessManagerData()->windowIds.contains(windowId)) { return; } - g_helper()->windowIds.append(windowId); + g_framelessManagerData()->windowIds.append(windowId); static const bool pureQt = usePureQtImplementation(); if (pureQt) { FramelessHelperQt::addWindow(params); @@ -219,10 +207,10 @@ void FramelessManagerPrivate::removeWindow(const WId windowId) if (!windowId) { return; } - if (!g_helper()->windowIds.contains(windowId)) { + if (!g_framelessManagerData()->windowIds.contains(windowId)) { return; } - g_helper()->windowIds.removeAll(windowId); + g_framelessManagerData()->windowIds.removeAll(windowId); static const bool pureQt = usePureQtImplementation(); if (pureQt) { FramelessHelperQt::removeWindow(windowId); @@ -356,9 +344,10 @@ void FramelessManagerPrivate::initialize() flagSet = true; // Set a global flag so that people can check whether FramelessHelper is being // used without actually accessing the FramelessHelper interface. + static constexpr const char flag[] = "__FRAMELESSHELPER__"; const int ver = FramelessHelper::Core::version().version; - qputenv(kGlobalFlagVarName, QByteArray::number(ver)); - qApp->setProperty(kGlobalFlagVarName, ver); + qputenv(flag, QByteArray::number(ver)); + qApp->setProperty(flag, ver); } } @@ -371,7 +360,8 @@ FramelessManager::~FramelessManager() = default; FramelessManager *FramelessManager::instance() { - return g_manager(); + static FramelessManager manager; + return &manager; } SystemTheme FramelessManager::systemTheme() const diff --git a/src/core/micamaterial.cpp b/src/core/micamaterial.cpp index 47f366d0..9b96a5ee 100644 --- a/src/core/micamaterial.cpp +++ b/src/core/micamaterial.cpp @@ -77,10 +77,6 @@ using namespace Global; [[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 -#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 { QPixmap blurredWallpaper = {}; @@ -669,7 +665,7 @@ void MicaMaterialPrivate::updateMaterialBrush() { #ifndef FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE framelesshelpercore_initResource(); - static const QImage noiseTexture = QImage(kNoiseImageFilePath); + static const QImage noiseTexture = QImage(FRAMELESSHELPER_STRING_LITERAL(":/org.wangwenx190.FramelessHelper/resources/images/noise.png")); #endif // FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE QImage micaTexture = QImage(QSize(64, 64), kDefaultImageFormat); QColor fillColor = ((FramelessManager::instance()->systemTheme() == SystemTheme::Dark) ? kDefaultSystemDarkColor : kDefaultSystemLightColor2); diff --git a/src/core/registrykey.cpp b/src/core/registrykey.cpp index 50453541..6c0317d6 100644 --- a/src/core/registrykey.cpp +++ b/src/core/registrykey.cpp @@ -49,33 +49,35 @@ FRAMELESSHELPER_BEGIN_NAMESPACE using namespace Global; -static const HKEY g_keyMap[] = { - HKEY_CLASSES_ROOT, - HKEY_CURRENT_USER, - HKEY_LOCAL_MACHINE, - HKEY_USERS, - HKEY_PERFORMANCE_DATA, - HKEY_CURRENT_CONFIG, - HKEY_DYN_DATA, - HKEY_CURRENT_USER_LOCAL_SETTINGS, - HKEY_PERFORMANCE_TEXT, - HKEY_PERFORMANCE_NLSTEXT +static constexpr const std::array g_registryKeyMap = +{ + 0x80000000, // HKEY_CLASSES_ROOT + 0x80000001, // HKEY_CURRENT_USER + 0x80000002, // HKEY_LOCAL_MACHINE + 0x80000003, // HKEY_USERS + 0x80000004, // HKEY_PERFORMANCE_DATA + 0x80000005, // HKEY_CURRENT_CONFIG + 0x80000006, // HKEY_DYN_DATA + 0x80000007, // HKEY_CURRENT_USER_LOCAL_SETTINGS + 0x80000050, // HKEY_PERFORMANCE_TEXT + 0x80000060 // HKEY_PERFORMANCE_NLSTEXT }; -static_assert(std::size(g_keyMap) == (static_cast(RegistryRootKey::PerformanceNlsText) + 1)); +static constexpr const auto registryKeyCount = std::size(g_registryKeyMap); +static_assert(registryKeyCount == (static_cast(RegistryRootKey::PerformanceNlsText) + 1)); -static const QString g_strMap[] = { - FRAMELESSHELPER_STRING_LITERAL("HKEY_CLASSES_ROOT"), - FRAMELESSHELPER_STRING_LITERAL("HKEY_CURRENT_USER"), - FRAMELESSHELPER_STRING_LITERAL("HKEY_LOCAL_MACHINE"), - FRAMELESSHELPER_STRING_LITERAL("HKEY_USERS"), - FRAMELESSHELPER_STRING_LITERAL("HKEY_PERFORMANCE_DATA"), - FRAMELESSHELPER_STRING_LITERAL("HKEY_CURRENT_CONFIG"), - FRAMELESSHELPER_STRING_LITERAL("HKEY_DYN_DATA"), - FRAMELESSHELPER_STRING_LITERAL("HKEY_CURRENT_USER_LOCAL_SETTINGS"), - FRAMELESSHELPER_STRING_LITERAL("HKEY_PERFORMANCE_TEXT"), - FRAMELESSHELPER_STRING_LITERAL("HKEY_PERFORMANCE_NLSTEXT") +[[maybe_unused]] static constexpr const std::array g_registryStrMap = +{ + FRAMELESSHELPER_STRING_VIEW("HKEY_CLASSES_ROOT"), + FRAMELESSHELPER_STRING_VIEW("HKEY_CURRENT_USER"), + FRAMELESSHELPER_STRING_VIEW("HKEY_LOCAL_MACHINE"), + FRAMELESSHELPER_STRING_VIEW("HKEY_USERS"), + FRAMELESSHELPER_STRING_VIEW("HKEY_PERFORMANCE_DATA"), + FRAMELESSHELPER_STRING_VIEW("HKEY_CURRENT_CONFIG"), + FRAMELESSHELPER_STRING_VIEW("HKEY_DYN_DATA"), + FRAMELESSHELPER_STRING_VIEW("HKEY_CURRENT_USER_LOCAL_SETTINGS"), + FRAMELESSHELPER_STRING_VIEW("HKEY_PERFORMANCE_TEXT"), + FRAMELESSHELPER_STRING_VIEW("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) { @@ -86,12 +88,12 @@ RegistryKey::RegistryKey(const RegistryRootKey root, const QString &key, QObject m_rootKey = root; m_subKey = key; #if REGISTRYKEY_QWINREGISTRYKEY - m_registryKey.reset(new QWinRegistryKey(g_keyMap[static_cast(m_rootKey)], m_subKey)); + m_registryKey.reset(new QWinRegistryKey(reinterpret_cast(g_registryKeyMap.at(static_cast(m_rootKey))), m_subKey)); if (!m_registryKey->isValid()) { m_registryKey.reset(); } #else - const QString rootKey = g_strMap[static_cast(m_rootKey)]; + const QString rootKey = g_registryStrMap.at(static_cast(m_rootKey)); const auto lastSlashPos = m_subKey.lastIndexOf(u'\\'); m_settings.reset(new QSettings(rootKey + u'\\' + m_subKey.left(lastSlashPos), QSettings::NativeFormat)); if (m_settings->childGroups().contains(m_subKey.mid(lastSlashPos + 1))) { diff --git a/src/core/sysapiloader.cpp b/src/core/sysapiloader.cpp index 13024ede..13abd73e 100644 --- a/src/core/sysapiloader.cpp +++ b/src/core/sysapiloader.cpp @@ -76,9 +76,7 @@ struct SysApiLoaderData QHash functionCache = {}; }; -Q_GLOBAL_STATIC(SysApiLoaderData, g_loaderData) - -Q_GLOBAL_STATIC(SysApiLoader, g_sysApiLoader) +Q_GLOBAL_STATIC(SysApiLoaderData, g_sysApiLoaderData) static const bool LoaderDebugFlag = qEnvironmentVariableIntValue("FRAMELESSHELPER_SYSAPILOADER_DEBUG"); @@ -90,7 +88,8 @@ SysApiLoader::~SysApiLoader() = default; SysApiLoader *SysApiLoader::instance() { - return g_sysApiLoader(); + static SysApiLoader loader; + return &loader; } QString SysApiLoader::platformSharedLibrarySuffixName() @@ -103,7 +102,7 @@ QString SysApiLoader::platformSharedLibrarySuffixName() #elif defined(Q_OS_MACOS) return FRAMELESSHELPER_STRING_LITERAL(".dylib"); #else -#error "Unsupported platform!" +# error "Unsupported platform!" #endif }(); return result; @@ -167,16 +166,6 @@ QFunctionPointer SysApiLoader::resolve(const QString &library, const char *funct #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) { Q_ASSERT(!library.isEmpty()); @@ -184,7 +173,7 @@ QFunctionPointer SysApiLoader::resolve(const QString &library, const QString &fu if (library.isEmpty() || function.isEmpty()) { return nullptr; } - return SysApiLoader::resolve(library, function.toUtf8()); + return SysApiLoader::resolve(library, function.toUtf8().constData()); } bool SysApiLoader::isAvailable(const QString &library, const QString &function) @@ -195,14 +184,15 @@ bool SysApiLoader::isAvailable(const QString &library, const QString &function) return false; } const QString key = generateUniqueKey(library, function); - if (g_loaderData()->functionCache.contains(key)) { + const auto it = g_sysApiLoaderData()->functionCache.constFind(key); + if (it != g_sysApiLoaderData()->functionCache.constEnd()) { if (LoaderDebugFlag) { DEBUG << Q_FUNC_INFO << "Function cache found:" << key; } - return (g_loaderData()->functionCache.value(key) != nullptr); + return (it.value() != nullptr); } else { const QFunctionPointer symbol = SysApiLoader::resolve(library, function); - g_loaderData()->functionCache.insert(key, symbol); + g_sysApiLoaderData()->functionCache.insert(key, symbol); if (LoaderDebugFlag) { DEBUG << Q_FUNC_INFO << "New function cache:" << key << (symbol ? "[VALID]" : "[NULL]"); } @@ -224,11 +214,12 @@ QFunctionPointer SysApiLoader::get(const QString &library, const QString &functi return nullptr; } const QString key = generateUniqueKey(library, function); - if (g_loaderData()->functionCache.contains(key)) { + const auto it = g_sysApiLoaderData()->functionCache.constFind(key); + if (it != g_sysApiLoaderData()->functionCache.constEnd()) { if (LoaderDebugFlag) { DEBUG << Q_FUNC_INFO << "Function cache found:" << key; } - return g_loaderData()->functionCache.value(key); + return it.value(); } else { if (LoaderDebugFlag) { DEBUG << Q_FUNC_INFO << "Function cache not found:" << key; diff --git a/src/core/utils.cpp b/src/core/utils.cpp index f3b77223..d2325378 100644 --- a/src/core/utils.cpp +++ b/src/core/utils.cpp @@ -68,14 +68,15 @@ struct FONT_ICON quint32 Fallback = 0; }; -static const QHash g_fontIconsTable = { - {static_cast(SystemButtonType::Unknown), {0x0000, 0x0000}}, - {static_cast(SystemButtonType::WindowIcon), {0xE756, 0x0000}}, - {static_cast(SystemButtonType::Help), {0xE897, 0x0000}}, - {static_cast(SystemButtonType::Minimize), {0xE921, 0xE93E}}, - {static_cast(SystemButtonType::Maximize), {0xE922, 0xE93C}}, - {static_cast(SystemButtonType::Restore), {0xE923, 0xE93D}}, - {static_cast(SystemButtonType::Close), {0xE8BB, 0xE93B}} +static constexpr const std::array g_fontIconsTable = +{ + FONT_ICON{ 0x0000, 0x0000 }, + FONT_ICON{ 0xE756, 0x0000 }, + FONT_ICON{ 0xE897, 0x0000 }, + FONT_ICON{ 0xE921, 0xE93E }, + FONT_ICON{ 0xE922, 0xE93C }, + FONT_ICON{ 0xE923, 0xE93D }, + FONT_ICON{ 0xE8BB, 0xE93B } }; #endif // FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE @@ -171,12 +172,7 @@ QString Utils::getSystemButtonGlyph(const SystemButtonType button) #ifdef FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE return {}; #else // !FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE - const auto index = static_cast(button); - if (!g_fontIconsTable.contains(index)) { - WARNING << "FIXME: Add FONT_ICON value for button" << button; - return {}; - } - const FONT_ICON icon = g_fontIconsTable.value(index); + const FONT_ICON &icon = g_fontIconsTable.at(static_cast(button)); # ifdef Q_OS_WINDOWS // 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) @@ -231,8 +227,8 @@ void Utils::moveWindowToDesktopCenter(FramelessParamsConst params, const bool co } const QSize screenSize = (considerTaskBar ? screen->availableSize() : screen->size()); const QPoint offset = (considerTaskBar ? screen->availableGeometry().topLeft() : QPoint(0, 0)); - const int newX = std::round(qreal(screenSize.width() - windowSize.width()) / 2.0); - const int newY = std::round(qreal(screenSize.height() - windowSize.height()) / 2.0); + const int newX = std::round(qreal(screenSize.width() - windowSize.width()) / qreal(2)); + const int newY = std::round(qreal(screenSize.height() - windowSize.height()) / qreal(2)); params->setWindowPosition(QPoint(newX + offset.x(), newY + offset.y())); } diff --git a/src/core/utils_win.cpp b/src/core/utils_win.cpp index 5b7be2e8..ad35ce40 100644 --- a/src/core/utils_win.cpp +++ b/src/core/utils_win.cpp @@ -72,13 +72,10 @@ static Q_LOGGING_CATEGORY(lcUtilsWin, "wangwenx190.framelesshelper.core.utils.wi 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[] = "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."; 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_CONSTANT(Composition) FRAMELESSHELPER_STRING_CONSTANT(ColorizationColor) @@ -187,7 +184,7 @@ FRAMELESSHELPER_STRING_CONSTANT(BringWindowToTop) FRAMELESSHELPER_STRING_CONSTANT(SetActiveWindow) FRAMELESSHELPER_STRING_CONSTANT(RedrawWindow) -struct Win32UtilsHelperData +struct Win32UtilsData { WNDPROC originalWindowProc = nullptr; SystemParameters params = {}; @@ -195,38 +192,11 @@ struct Win32UtilsHelperData struct Win32UtilsHelper { - QHash data = {}; + QHash data = {}; QList micaWindowIds = {}; }; -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 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}} -}; +Q_GLOBAL_STATIC(Win32UtilsHelper, g_win32UtilsData) [[nodiscard]] bool operator==(const RECT &lhs, const RECT &rhs) noexcept { @@ -302,6 +272,12 @@ struct SYSTEM_METRIC return key; } +[[nodiscard]] static inline QString dwmColorKeyName() +{ + static const QString name = QString::fromWCharArray(kDwmColorKeyName); + return name; +} + [[nodiscard]] static inline bool doCompareWindowsVersion(const VersionNumber &targetOsVer) { static const auto currentOsVer = []() -> std::optional { @@ -337,7 +313,7 @@ struct SYSTEM_METRIC osvi.dwMinorVersion = targetOsVer.Minor; osvi.dwBuildNumber = targetOsVer.Patch; DWORDLONG dwlConditionMask = 0; - const auto op = VER_GREATER_EQUAL; + static constexpr const auto op = VER_GREATER_EQUAL; VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, op); VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, op); VER_SET_CONDITION(dwlConditionMask, VER_BUILDNUMBER, op); @@ -357,7 +333,7 @@ struct SYSTEM_METRIC LPWSTR buf = nullptr; if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast(&buf), 0, nullptr) == 0) { - return kEmptyMessageText; + return FRAMELESSHELPER_STRING_LITERAL("FormatMessageW() returned empty string."); } const QString errorText = QString::fromWCharArray(buf).trimmed(); LocalFree(buf); @@ -489,10 +465,11 @@ static inline void moveWindowToMonitor(const HWND hwnd, const MONITORINFOEXW &ac return 0; } const auto windowId = reinterpret_cast(hWnd); - if (!g_utilsHelper()->data.contains(windowId)) { + const auto it = g_win32UtilsData()->data.constFind(windowId); + if (it == g_win32UtilsData()->data.constEnd()) { return DefWindowProcW(hWnd, uMsg, wParam, lParam); } - const Win32UtilsHelperData data = g_utilsHelper()->data.value(windowId); + const Win32UtilsData &data = it.value(); const auto getNativePosFromMouse = [lParam]() -> QPoint { return {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)}; }; @@ -589,7 +566,7 @@ static inline void moveWindowToMonitor(const HWND hwnd, const MONITORINFOEXW &ac bool Utils::isWindowsVersionOrGreater(const WindowsVersion version) { - return doCompareWindowsVersion(WindowsVersions[static_cast(version)]); + return doCompareWindowsVersion(WindowsVersions.at(static_cast(version))); } bool Utils::isDwmCompositionEnabled() @@ -654,7 +631,7 @@ void Utils::updateWindowFrameMargins(const WId windowId, const bool reset) if (!API_DWM_AVAILABLE(DwmExtendFrameIntoClientArea)) { return; } - const bool micaEnabled = g_utilsHelper()->micaWindowIds.contains(windowId); + const bool micaEnabled = g_win32UtilsData()->micaWindowIds.contains(windowId); const auto margins = [micaEnabled, reset]() -> MARGINS { // To make Mica/Mica Alt work for normal Win32 windows, we have to // let the window frame extend to the whole window (or disable the @@ -771,9 +748,9 @@ DwmColorizationArea Utils::getDwmColorizationArea() return DwmColorizationArea::None; } const RegistryKey themeRegistry(RegistryRootKey::CurrentUser, personalizeRegistryKey()); - const DWORD themeValue = themeRegistry.isValid() ? themeRegistry.value(qDwmColorKeyName).value_or(0) : 0; + const DWORD themeValue = themeRegistry.isValid() ? themeRegistry.value(dwmColorKeyName()).value_or(0) : 0; const RegistryKey dwmRegistry(RegistryRootKey::CurrentUser, dwmRegistryKey()); - const DWORD dwmValue = dwmRegistry.isValid() ? dwmRegistry.value(qDwmColorKeyName).value_or(0) : 0; + const DWORD dwmValue = dwmRegistry.isValid() ? dwmRegistry.value(dwmColorKeyName()).value_or(0) : 0; const bool theme = (themeValue != 0); const bool dwm = (dwmValue != 0); if (theme && dwm) { @@ -952,7 +929,7 @@ void Utils::syncWmPaintWithDwm() m = dt - (period * w); Q_ASSERT(m >= 0); Q_ASSERT(m < period); - const qreal m_ms = (1000.0 * qreal(m) / qreal(freq.QuadPart)); + const qreal m_ms = (qreal(1000) * qreal(m) / qreal(freq.QuadPart)); Sleep(static_cast(std::round(m_ms))); if (API_CALL_FUNCTION4(winmm, timeEndPeriod, ms_granularity) != TIMERR_NOERROR) { WARNING << "timeEndPeriod() failed."; @@ -1040,12 +1017,12 @@ quint32 Utils::getPrimaryScreenDpi(const bool horizontal) // manually to ensure that. hr = d2dFactory->ReloadSystemMetrics(); if (SUCCEEDED(hr)) { - FLOAT dpiX = 0.0f, dpiY = 0.0f; + FLOAT dpiX = FLOAT(0), dpiY = FLOAT(0); QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED d2dFactory->GetDesktopDpi(&dpiX, &dpiY); QT_WARNING_POP - if ((dpiX > 0.0f) && (dpiY > 0.0f)) { + if ((dpiX > FLOAT(0)) && (dpiY > FLOAT(0))) { return (horizontal ? quint32(std::round(dpiX)) : quint32(std::round(dpiY))); } else { WARNING << "GetDesktopDpi() failed."; @@ -1279,7 +1256,7 @@ void Utils::maybeFixupQtInternals(const WId windowId) if (!windowId) { return; } - if (qEnvironmentVariableIntValue(kNoFixQtInternalEnvVar)) { + if (qEnvironmentVariableIntValue("FRAMELESSHELPER_WINDOWS_DONT_FIX_QT")) { return; } bool shouldUpdateFrame = false; @@ -1419,7 +1396,8 @@ void Utils::installSystemMenuHook(const WId windowId, FramelessParamsConst param if (!windowId || !params) { return; } - if (g_utilsHelper()->data.contains(windowId)) { + const auto it = g_win32UtilsData()->data.constFind(windowId); + if (it != g_win32UtilsData()->data.constEnd()) { return; } const auto hwnd = reinterpret_cast(windowId); @@ -1436,10 +1414,10 @@ void Utils::installSystemMenuHook(const WId windowId, FramelessParamsConst param return; } //triggerFrameChange(windowId); // Crash - Win32UtilsHelperData data = {}; + Win32UtilsData data = {}; data.originalWindowProc = originalWindowProc; data.params = *params; - g_utilsHelper()->data.insert(windowId, data); + g_win32UtilsData()->data.insert(windowId, data); } void Utils::uninstallSystemMenuHook(const WId windowId) @@ -1448,10 +1426,11 @@ void Utils::uninstallSystemMenuHook(const WId windowId) if (!windowId) { return; } - if (!g_utilsHelper()->data.contains(windowId)) { + const auto it = g_win32UtilsData()->data.constFind(windowId); + if (it == g_win32UtilsData()->data.constEnd()) { return; } - const Win32UtilsHelperData data = g_utilsHelper()->data.value(windowId); + const Win32UtilsData &data = it.value(); Q_ASSERT(data.originalWindowProc); if (!data.originalWindowProc) { return; @@ -1463,7 +1442,7 @@ void Utils::uninstallSystemMenuHook(const WId windowId) return; } //triggerFrameChange(windowId); // Crash - g_utilsHelper()->data.remove(windowId); + g_win32UtilsData()->data.erase(it); } void Utils::setAeroSnappingEnabled(const WId windowId, const bool enable) @@ -1718,9 +1697,7 @@ bool Utils::setBlurBehindWindowEnabled(const WId windowId, const BlurMode mode, return false; } const auto restoreWindowFrameMargins = [windowId]() -> void { - if (g_utilsHelper()->micaWindowIds.contains(windowId)) { - g_utilsHelper()->micaWindowIds.removeAll(windowId); - } + g_win32UtilsData()->micaWindowIds.removeAll(windowId); updateWindowFrameMargins(windowId, false); }; const bool preferMicaAlt = (qEnvironmentVariableIntValue("FRAMELESSHELPER_PREFER_MICA_ALT") != 0); @@ -1791,9 +1768,7 @@ bool Utils::setBlurBehindWindowEnabled(const WId windowId, const BlurMode mode, return result; } else { if ((blurMode == BlurMode::Windows_Mica) || (blurMode == BlurMode::Windows_MicaAlt)) { - if (!g_utilsHelper()->micaWindowIds.contains(windowId)) { - g_utilsHelper()->micaWindowIds.append(windowId); - } + g_win32UtilsData()->micaWindowIds.append(windowId); // By giving a negative value, DWM will extend the window frame into the whole // client area. We need this step because the Mica material can only be applied // to the non-client area of a window. Without this step, you'll get a window @@ -2448,10 +2423,7 @@ void Utils::removeMicaWindow(const WId windowId) if (!windowId) { return; } - if (!g_utilsHelper()->micaWindowIds.contains(windowId)) { - return; - } - g_utilsHelper()->micaWindowIds.removeAll(windowId); + g_win32UtilsData()->micaWindowIds.removeAll(windowId); } void Utils::removeSysMenuHook(const WId windowId) @@ -2460,10 +2432,11 @@ void Utils::removeSysMenuHook(const WId windowId) if (!windowId) { return; } - if (!g_utilsHelper()->data.contains(windowId)) { + const auto it = g_win32UtilsData()->data.constFind(windowId); + if (it == g_win32UtilsData()->data.constEnd()) { return; } - g_utilsHelper()->data.remove(windowId); + g_win32UtilsData()->data.erase(it); } quint64 Utils::queryMouseButtonState() diff --git a/src/core/winverhelper.cpp b/src/core/winverhelper.cpp index a2fe31ee..95e76365 100644 --- a/src/core/winverhelper.cpp +++ b/src/core/winverhelper.cpp @@ -43,7 +43,7 @@ class WinVerHelper void initialize(); private: - bool m_flags[static_cast(WindowsVersion::Latest) + 1] = {}; + std::array(WindowsVersion::Latest) + 1> m_flags = {}; }; WinVerHelper::WinVerHelper() @@ -55,7 +55,7 @@ WinVerHelper::~WinVerHelper() = default; bool WinVerHelper::check(const WindowsVersion version) const { - return m_flags[static_cast(version)]; + return m_flags.at(static_cast(version)); } void WinVerHelper::initialize() diff --git a/src/quick/CMakeLists.txt b/src/quick/CMakeLists.txt index e3984260..b4022847 100644 --- a/src/quick/CMakeLists.txt +++ b/src/quick/CMakeLists.txt @@ -141,6 +141,7 @@ if(QT_VERSION VERSION_GREATER_EQUAL "6.3") VERSION "1.0" OUTPUT_DIRECTORY "${__import_base_dir}/org/wangwenx190/${PROJECT_NAME}" 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. OUTPUT_TARGETS __qml_targets IMPORTS diff --git a/src/quick/framelessquickhelper.cpp b/src/quick/framelessquickhelper.cpp index 96a2616b..d2bcc7a3 100644 --- a/src/quick/framelessquickhelper.cpp +++ b/src/quick/framelessquickhelper.cpp @@ -143,7 +143,7 @@ void FramelessQuickHelperPrivate::extendsContentIntoTitleBar(const bool value) } m_extendIntoTitleBar = value; if (!m_destroying) { - emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("extendsContentIntoTitleBarChanged")); + emitSignalForAllInstances("extendsContentIntoTitleBarChanged"); } } @@ -166,7 +166,7 @@ void FramelessQuickHelperPrivate::setTitleBarItem(QQuickItem *value) return; } data->titleBarItem = value; - emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("titleBarItemChanged")); + emitSignalForAllInstances("titleBarItemChanged"); } void FramelessQuickHelperPrivate::attach() @@ -213,8 +213,8 @@ void FramelessQuickHelperPrivate::attach() }; params.shouldIgnoreMouseEvents = [this](const QPoint &pos) -> bool { return shouldIgnoreMouseEvents(pos); }; params.showSystemMenu = [this](const QPoint &pos) -> void { showSystemMenu(pos); }; - params.setProperty = [this](const QByteArray &name, const QVariant &value) -> void { setProperty(name, value); }; - params.getProperty = [this](const QByteArray &name, const QVariant &defaultValue) -> QVariant { return getProperty(name, defaultValue); }; + params.setProperty = [this](const char *name, const QVariant &value) -> void { setProperty(name, value); }; + params.getProperty = [this](const char *name, const QVariant &defaultValue) -> QVariant { return getProperty(name, defaultValue); }; params.setCursor = [window](const QCursor &cursor) -> void { window->setCursor(cursor); }; params.unsetCursor = [window]() -> void { window->unsetCursor(); }; params.getWidgetHandle = []() -> QObject * { return nullptr; }; @@ -238,7 +238,7 @@ void FramelessQuickHelperPrivate::attach() if (FramelessConfig::instance()->isSet(Option::EnableBlurBehindWindow)) { setBlurBehindWindowEnabled(true, {}); } - emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("ready")); + emitSignalForAllInstances("ready"); }); } @@ -460,13 +460,14 @@ void FramelessQuickHelperPrivate::setWindowFixedSize(const bool value) #ifdef Q_OS_WINDOWS Utils::setAeroSnappingEnabled(window->winId(), !value); #endif - emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("windowFixedSizeChanged")); + emitSignalForAllInstances("windowFixedSizeChanged"); } -void FramelessQuickHelperPrivate::emitSignalForAllInstances(const QByteArray &signal) +void FramelessQuickHelperPrivate::emitSignalForAllInstances(const char *signal) { - Q_ASSERT(!signal.isEmpty()); - if (signal.isEmpty()) { + Q_ASSERT(signal); + Q_ASSERT(*signal != '\0'); + if (!signal || (*signal == '\0')) { return; } Q_Q(FramelessQuickHelper); @@ -482,7 +483,7 @@ void FramelessQuickHelperPrivate::emitSignalForAllInstances(const QByteArray &si return; } for (auto &&instance : std::as_const(instances)) { - QMetaObject::invokeMethod(instance, signal.constData()); + QMetaObject::invokeMethod(instance, signal); } } @@ -519,22 +520,23 @@ void FramelessQuickHelperPrivate::setBlurBehindWindowEnabled(const bool value, c if (Utils::setBlurBehindWindowEnabled(window->winId(), FRAMELESSHELPER_ENUM_QUICK_TO_CORE(BlurMode, mode), color)) { m_blurBehindWindowEnabled = value; - emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("blurBehindWindowEnabledChanged")); + emitSignalForAllInstances("blurBehindWindowEnabledChanged"); } else { WARNING << "Failed to enable/disable blur behind window."; } } else { m_blurBehindWindowEnabled = value; findOrCreateMicaMaterial()->setVisible(m_blurBehindWindowEnabled); - emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("blurBehindWindowEnabledChanged")); + emitSignalForAllInstances("blurBehindWindowEnabledChanged"); } } -void FramelessQuickHelperPrivate::setProperty(const QByteArray &name, const QVariant &value) +void FramelessQuickHelperPrivate::setProperty(const char *name, const QVariant &value) { - Q_ASSERT(!name.isEmpty()); + Q_ASSERT(name); + Q_ASSERT(*name != '\0'); Q_ASSERT(value.isValid()); - if (name.isEmpty() || !value.isValid()) { + if (!name || (*name == '\0') || !value.isValid()) { return; } Q_Q(FramelessQuickHelper); @@ -542,13 +544,14 @@ void FramelessQuickHelperPrivate::setProperty(const QByteArray &name, const QVar if (!window) { return; } - window->setProperty(name.constData(), value); + window->setProperty(name, value); } -QVariant FramelessQuickHelperPrivate::getProperty(const QByteArray &name, const QVariant &defaultValue) +QVariant FramelessQuickHelperPrivate::getProperty(const char *name, const QVariant &defaultValue) { - Q_ASSERT(!name.isEmpty()); - if (name.isEmpty()) { + Q_ASSERT(name); + Q_ASSERT(*name != '\0'); + if (!name || (*name == '\0')) { return {}; } Q_Q(FramelessQuickHelper); @@ -556,7 +559,7 @@ QVariant FramelessQuickHelperPrivate::getProperty(const QByteArray &name, const if (!window) { return {}; } - const QVariant value = window->property(name.constData()); + const QVariant value = window->property(name); return (value.isValid() ? value : defaultValue); } diff --git a/src/widgets/framelesswidgetshelper.cpp b/src/widgets/framelesswidgetshelper.cpp index aeb63236..cb99fcb4 100644 --- a/src/widgets/framelesswidgetshelper.cpp +++ b/src/widgets/framelesswidgetshelper.cpp @@ -217,13 +217,14 @@ void FramelessWidgetsHelperPrivate::setWindowFixedSize(const bool value) #ifdef Q_OS_WINDOWS Utils::setAeroSnappingEnabled(m_window->winId(), !value); #endif - emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("windowFixedSizeChanged")); + emitSignalForAllInstances("windowFixedSizeChanged"); } -void FramelessWidgetsHelperPrivate::emitSignalForAllInstances(const QByteArray &signal) +void FramelessWidgetsHelperPrivate::emitSignalForAllInstances(const char *signal) { - Q_ASSERT(!signal.isEmpty()); - if (signal.isEmpty()) { + Q_ASSERT(signal); + Q_ASSERT(*signal != '\0'); + if (!signal || (*signal == '\0')) { return; } if (!m_window) { @@ -234,7 +235,7 @@ void FramelessWidgetsHelperPrivate::emitSignalForAllInstances(const QByteArray & return; } for (auto &&instance : std::as_const(instances)) { - QMetaObject::invokeMethod(instance, signal.constData()); + QMetaObject::invokeMethod(instance, signal); } } @@ -261,7 +262,7 @@ void FramelessWidgetsHelperPrivate::setBlurBehindWindowEnabled(const bool enable if (Utils::setBlurBehindWindowEnabled(m_window->winId(), (enable ? BlurMode::Default : BlurMode::Disable), color)) { m_blurBehindWindowEnabled = enable; - emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("blurBehindWindowEnabledChanged")); + emitSignalForAllInstances("blurBehindWindowEnabledChanged"); } else { WARNING << "Failed to enable/disable blur behind window."; } @@ -269,38 +270,40 @@ void FramelessWidgetsHelperPrivate::setBlurBehindWindowEnabled(const bool enable if (WidgetsSharedHelper * const helper = findOrCreateSharedHelper(m_window)) { m_blurBehindWindowEnabled = enable; helper->setMicaEnabled(m_blurBehindWindowEnabled); - emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("blurBehindWindowEnabledChanged")); + emitSignalForAllInstances("blurBehindWindowEnabledChanged"); } else { DEBUG << "Blur behind window is not supported on current platform."; } } } -void FramelessWidgetsHelperPrivate::setProperty(const QByteArray &name, const QVariant &value) +void FramelessWidgetsHelperPrivate::setProperty(const char *name, const QVariant &value) { - Q_ASSERT(!name.isEmpty()); + Q_ASSERT(name); + Q_ASSERT(*name != '\0'); Q_ASSERT(value.isValid()); - if (name.isEmpty() || !value.isValid()) { + if (!name || (*name == '\0') || !value.isValid()) { return; } Q_ASSERT(m_window); if (!m_window) { return; } - m_window->setProperty(name.constData(), value); + m_window->setProperty(name, value); } -QVariant FramelessWidgetsHelperPrivate::getProperty(const QByteArray &name, const QVariant &defaultValue) +QVariant FramelessWidgetsHelperPrivate::getProperty(const char *name, const QVariant &defaultValue) { - Q_ASSERT(!name.isEmpty()); - if (name.isEmpty()) { + Q_ASSERT(name); + Q_ASSERT(*name != '\0'); + if (!name || (*name == '\0')) { return {}; } Q_ASSERT(m_window); if (!m_window) { return {}; } - const QVariant value = m_window->property(name.constData()); + const QVariant value = m_window->property(name); return (value.isValid() ? value : defaultValue); } @@ -446,7 +449,7 @@ void FramelessWidgetsHelperPrivate::setTitleBarWidget(QWidget *widget) return; } data->titleBarWidget = widget; - emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("titleBarWidgetChanged")); + emitSignalForAllInstances("titleBarWidgetChanged"); } QWidget *FramelessWidgetsHelperPrivate::getTitleBarWidget() const @@ -558,8 +561,8 @@ void FramelessWidgetsHelperPrivate::attach() params.setSystemButtonState = [this](const SystemButtonType button, const ButtonState state) -> void { setSystemButtonState(button, state); }; params.shouldIgnoreMouseEvents = [this](const QPoint &pos) -> bool { return shouldIgnoreMouseEvents(pos); }; params.showSystemMenu = [this](const QPoint &pos) -> void { showSystemMenu(pos); }; - params.setProperty = [this](const QByteArray &name, const QVariant &value) -> void { setProperty(name, value); }; - params.getProperty = [this](const QByteArray &name, const QVariant &defaultValue) -> QVariant { return getProperty(name, defaultValue); }; + params.setProperty = [this](const char *name, const QVariant &value) -> void { setProperty(name, value); }; + params.getProperty = [this](const char *name, const QVariant &defaultValue) -> QVariant { return getProperty(name, defaultValue); }; params.setCursor = [window](const QCursor &cursor) -> void { window->setCursor(cursor); }; params.unsetCursor = [window]() -> void { window->unsetCursor(); }; params.getWidgetHandle = [window]() -> QObject * { return window; }; @@ -583,8 +586,8 @@ void FramelessWidgetsHelperPrivate::attach() if (FramelessConfig::instance()->isSet(Option::EnableBlurBehindWindow)) { setBlurBehindWindowEnabled(true, {}); } - emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("windowChanged")); - emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("ready")); + emitSignalForAllInstances("windowChanged"); + emitSignalForAllInstances("ready"); }); } @@ -600,7 +603,7 @@ void FramelessWidgetsHelperPrivate::detach() g_widgetsHelper()->data.remove(windowId); FramelessManager::instance()->removeWindow(windowId); m_window = nullptr; - emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("windowChanged")); + emitSignalForAllInstances("windowChanged"); } void FramelessWidgetsHelperPrivate::extendsContentIntoTitleBar(const bool value) @@ -614,7 +617,7 @@ void FramelessWidgetsHelperPrivate::extendsContentIntoTitleBar(const bool value) detach(); } if (!m_destroying) { - emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("extendsContentIntoTitleBarChanged")); + emitSignalForAllInstances("extendsContentIntoTitleBarChanged"); } } diff --git a/src/widgets/standardtitlebar.cpp b/src/widgets/standardtitlebar.cpp index 52580587..51f45785 100644 --- a/src/widgets/standardtitlebar.cpp +++ b/src/widgets/standardtitlebar.cpp @@ -700,14 +700,14 @@ void StandardTitleBar::mouseReleaseEvent(QMouseEvent *event) { QWidget::mouseReleaseEvent(event); Q_D(StandardTitleBar); - Q_UNUSED(d->mouseEventHandler(event)); + std::ignore = d->mouseEventHandler(event); } void StandardTitleBar::mouseDoubleClickEvent(QMouseEvent *event) { QWidget::mouseDoubleClickEvent(event); Q_D(StandardTitleBar); - Q_UNUSED(d->mouseEventHandler(event)); + std::ignore = d->mouseEventHandler(event); } FRAMELESSHELPER_END_NAMESPACE