From 053d6b104ea87e8c301c6aafa278d72443092bb4 Mon Sep 17 00:00:00 2001 From: Yuhang Zhao <2546789017@qq.com> Date: Sun, 8 May 2022 16:09:00 +0800 Subject: [PATCH] centralize how we handle global options Signed-off-by: Yuhang Zhao <2546789017@qq.com> --- README.md | 4 + examples/widget/widget.cpp | 4 +- include/FramelessHelper/Core/FramelessManager | 1 + .../Core/FramelessWindowsManager | 1 - .../Core/framelesshelpercore_global.h | 19 ++-- ...esswindowsmanager.h => framelessmanager.h} | 18 ++-- .../Core/private/framelessconfig_p.h | 49 +++++++++ ...indowsmanager_p.h => framelessmanager_p.h} | 19 ++-- .../Quick/private/quickstandardtitlebar_p.h | 6 ++ .../Widgets/private/standardtitlebar_p.h | 4 + .../Widgets/standardtitlebar.h | 7 ++ src/core/CMakeLists.txt | 8 +- src/core/framelessconfig.cpp | 102 ++++++++++++++++++ src/core/framelessconfig_p.h | 1 + src/core/framelesshelper_qt.cpp | 8 +- src/core/framelesshelper_win.cpp | 69 ++++++++---- ...indowsmanager.cpp => framelessmanager.cpp} | 83 ++++++-------- src/core/framelessmanager.h | 1 + src/core/framelessmanager_p.h | 1 + src/core/framelesswindowsmanager.h | 1 - src/core/framelesswindowsmanager_p.h | 1 - src/core/utils_win.cpp | 93 ++++++++++------ src/quick/framelessquickhelper.cpp | 4 +- src/quick/framelessquickutils.cpp | 9 +- src/quick/framelessquickwindow.cpp | 9 +- src/quick/quickstandardclosebutton.cpp | 4 +- src/quick/quickstandardmaximizebutton.cpp | 4 +- src/quick/quickstandardminimizebutton.cpp | 4 +- src/quick/quickstandardtitlebar.cpp | 19 +++- src/widgets/framelesswidgetshelper.cpp | 5 +- src/widgets/standardsystembutton.cpp | 4 +- src/widgets/standardtitlebar.cpp | 37 ++++++- src/widgets/widgetssharedhelper.cpp | 5 +- 33 files changed, 438 insertions(+), 166 deletions(-) create mode 100644 include/FramelessHelper/Core/FramelessManager delete mode 100644 include/FramelessHelper/Core/FramelessWindowsManager rename include/FramelessHelper/Core/{framelesswindowsmanager.h => framelessmanager.h} (75%) create mode 100644 include/FramelessHelper/Core/private/framelessconfig_p.h rename include/FramelessHelper/Core/private/{framelesswindowsmanager_p.h => framelessmanager_p.h} (74%) create mode 100644 src/core/framelessconfig.cpp create mode 100644 src/core/framelessconfig_p.h rename src/core/{framelesswindowsmanager.cpp => framelessmanager.cpp} (77%) create mode 100644 src/core/framelessmanager.h create mode 100644 src/core/framelessmanager_p.h delete mode 100644 src/core/framelesswindowsmanager.h delete mode 100644 src/core/framelesswindowsmanager_p.h diff --git a/README.md b/README.md index 781d5b3..69e7484 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ # FramelessHelper 2.x +## Join with us :triangular_flag_on_post: + +You can join our Discord Channel to communicate with us. You can share your findings, thoughts and ideas on improving / implementing FramelessHelper functionalities on more platforms and apps! + ## Highlights compared to 2.1 (TODO list) - Common: Added cross-platform customizable system menu for both Qt Widgets and Qt Quick. Also supports both light and dark theme. diff --git a/examples/widget/widget.cpp b/examples/widget/widget.cpp index 5109186..489a086 100644 --- a/examples/widget/widget.cpp +++ b/examples/widget/widget.cpp @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include @@ -40,7 +40,7 @@ Widget::Widget(QWidget *parent) : FramelessWidget(parent) { initialize(); startTimer(500); - connect(FramelessWindowsManager::instance(), &FramelessWindowsManager::systemThemeChanged, this, &Widget::updateStyleSheet); + connect(FramelessManager::instance(), &FramelessManager::systemThemeChanged, this, &Widget::updateStyleSheet); } Widget::~Widget() = default; diff --git a/include/FramelessHelper/Core/FramelessManager b/include/FramelessHelper/Core/FramelessManager new file mode 100644 index 0000000..7785b35 --- /dev/null +++ b/include/FramelessHelper/Core/FramelessManager @@ -0,0 +1 @@ +#include diff --git a/include/FramelessHelper/Core/FramelessWindowsManager b/include/FramelessHelper/Core/FramelessWindowsManager deleted file mode 100644 index a9d62b5..0000000 --- a/include/FramelessHelper/Core/FramelessWindowsManager +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/FramelessHelper/Core/framelesshelpercore_global.h b/include/FramelessHelper/Core/framelesshelpercore_global.h index baa4940..ef2034d 100644 --- a/include/FramelessHelper/Core/framelesshelpercore_global.h +++ b/include/FramelessHelper/Core/framelesshelpercore_global.h @@ -183,14 +183,15 @@ Q_NAMESPACE_EXPORT(FRAMELESSHELPER_CORE_API) [[maybe_unused]] static Q_CONSTEXPR2 const QColor kDefaultSystemButtonBackgroundColor = {204, 204, 204}; // #CCCCCC [[maybe_unused]] static Q_CONSTEXPR2 const QColor kDefaultSystemCloseButtonBackgroundColor = {232, 17, 35}; // #E81123 -[[maybe_unused]] static constexpr const char kUsePureQtImplFlag[] = "FRAMELESSHELPER_PURE_QT_IMPLEMENTATION"; -[[maybe_unused]] static constexpr const char kForceHideFrameBorderFlag[] = "FRAMELESSHELPER_FORCE_HIDE_FRAME_BORDER"; -[[maybe_unused]] static constexpr const char kForceShowFrameBorderFlag[] = "FRAMELESSHELPER_FORCE_SHOW_FRAME_BORDER"; - -FRAMELESSHELPER_STRING_CONSTANT2(ConfigFileName, ".framelesshelper.ini") -FRAMELESSHELPER_STRING_CONSTANT2(UsePureQtImplKeyPath, "Options/UsePureQtImplementation") -FRAMELESSHELPER_STRING_CONSTANT2(ForceHideFrameBorderKeyPath, "Options/ForceHideFrameBorder") -FRAMELESSHELPER_STRING_CONSTANT2(ForceShowFrameBorderKeyPath, "Options/ForceShowFrameBorder") +enum class Option +{ + UseCrossPlatformQtImplementation = 0, + ForceHideWindowFrameBorder = 1, + ForceShowWindowFrameBorder = 2, + DisableWindowsSnapLayouts = 3, + WindowUseRoundCorners = 4 +}; +Q_ENUM_NS(Option) enum class SystemTheme { @@ -477,7 +478,7 @@ struct SystemParameters {10, 0, 19044}, // Windows 10 Version 21H2 (November 2021 Update) (21H2) {10, 0, 22000}, // Windows 11 Version 21H2 (21H2) }; -static_assert((sizeof(WindowsVersions) / sizeof(WindowsVersions[0])) == (static_cast(WindowsVersion::_11_21H2) + 1)); +static_assert(std::size(WindowsVersions) == (static_cast(WindowsVersion::_11_21H2) + 1)); } // namespace Global diff --git a/include/FramelessHelper/Core/framelesswindowsmanager.h b/include/FramelessHelper/Core/framelessmanager.h similarity index 75% rename from include/FramelessHelper/Core/framelesswindowsmanager.h rename to include/FramelessHelper/Core/framelessmanager.h index bca11e8..e63ced4 100644 --- a/include/FramelessHelper/Core/framelesswindowsmanager.h +++ b/include/FramelessHelper/Core/framelessmanager.h @@ -29,24 +29,22 @@ FRAMELESSHELPER_BEGIN_NAMESPACE -class FramelessWindowsManagerPrivate; +class FramelessManagerPrivate; -class FRAMELESSHELPER_CORE_API FramelessWindowsManager : public QObject +class FRAMELESSHELPER_CORE_API FramelessManager : public QObject { Q_OBJECT - Q_DECLARE_PRIVATE(FramelessWindowsManager) - Q_DISABLE_COPY_MOVE(FramelessWindowsManager) - Q_PROPERTY(bool usePureQtImplementation READ usePureQtImplementation CONSTANT FINAL) + Q_DECLARE_PRIVATE(FramelessManager) + Q_DISABLE_COPY_MOVE(FramelessManager) Q_PROPERTY(Global::SystemTheme systemTheme READ systemTheme NOTIFY systemThemeChanged FINAL) Q_PROPERTY(QColor systemAccentColor READ systemAccentColor NOTIFY systemThemeChanged FINAL) public: - explicit FramelessWindowsManager(QObject *parent = nullptr); - ~FramelessWindowsManager() override; + explicit FramelessManager(QObject *parent = nullptr); + ~FramelessManager() override; - Q_NODISCARD static FramelessWindowsManager *instance(); + Q_NODISCARD static FramelessManager *instance(); - Q_NODISCARD bool usePureQtImplementation() const; Q_NODISCARD Global::SystemTheme systemTheme() const; Q_NODISCARD QColor systemAccentColor() const; @@ -57,7 +55,7 @@ Q_SIGNALS: void systemThemeChanged(); private: - QScopedPointer d_ptr; + QScopedPointer d_ptr; }; FRAMELESSHELPER_END_NAMESPACE diff --git a/include/FramelessHelper/Core/private/framelessconfig_p.h b/include/FramelessHelper/Core/private/framelessconfig_p.h new file mode 100644 index 0000000..de71fbc --- /dev/null +++ b/include/FramelessHelper/Core/private/framelessconfig_p.h @@ -0,0 +1,49 @@ +/* + * MIT License + * + * Copyright (C) 2022 by wangwenx190 (Yuhang Zhao) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#pragma once + +#include "framelesshelpercore_global.h" +#include + +FRAMELESSHELPER_BEGIN_NAMESPACE + +class FRAMELESSHELPER_CORE_API FramelessConfig : public QObject +{ + Q_OBJECT + Q_DISABLE_COPY_MOVE(FramelessConfig) + +public: + explicit FramelessConfig(QObject *parent = nullptr); + ~FramelessConfig() override; + + Q_NODISCARD static FramelessConfig *instance(); + + void reload(const bool force = false); + + void set(const Global::Option option, const bool on = true); + Q_NODISCARD bool isSet(const Global::Option option) const; +}; + +FRAMELESSHELPER_END_NAMESPACE diff --git a/include/FramelessHelper/Core/private/framelesswindowsmanager_p.h b/include/FramelessHelper/Core/private/framelessmanager_p.h similarity index 74% rename from include/FramelessHelper/Core/private/framelesswindowsmanager_p.h rename to include/FramelessHelper/Core/private/framelessmanager_p.h index 93a4e7b..f086958 100644 --- a/include/FramelessHelper/Core/private/framelesswindowsmanager_p.h +++ b/include/FramelessHelper/Core/private/framelessmanager_p.h @@ -29,22 +29,21 @@ FRAMELESSHELPER_BEGIN_NAMESPACE -class FramelessWindowsManager; +class FramelessManager; -class FRAMELESSHELPER_CORE_API FramelessWindowsManagerPrivate : public QObject +class FRAMELESSHELPER_CORE_API FramelessManagerPrivate : public QObject { Q_OBJECT - Q_DECLARE_PUBLIC(FramelessWindowsManager) - Q_DISABLE_COPY_MOVE(FramelessWindowsManagerPrivate) + Q_DECLARE_PUBLIC(FramelessManager) + Q_DISABLE_COPY_MOVE(FramelessManagerPrivate) public: - explicit FramelessWindowsManagerPrivate(FramelessWindowsManager *q); - ~FramelessWindowsManagerPrivate() override; + explicit FramelessManagerPrivate(FramelessManager *q); + ~FramelessManagerPrivate() override; - Q_NODISCARD static FramelessWindowsManagerPrivate *get(FramelessWindowsManager *pub); - Q_NODISCARD static const FramelessWindowsManagerPrivate *get(const FramelessWindowsManager *pub); + Q_NODISCARD static FramelessManagerPrivate *get(FramelessManager *pub); + Q_NODISCARD static const FramelessManagerPrivate *get(const FramelessManager *pub); - Q_NODISCARD static bool usePureQtImplementation(); Q_NODISCARD Global::SystemTheme systemTheme() const; Q_NODISCARD QColor systemAccentColor() const; @@ -55,7 +54,7 @@ private: void initialize(); private: - FramelessWindowsManager *q_ptr = nullptr; + FramelessManager *q_ptr = nullptr; Global::SystemTheme m_systemTheme = Global::SystemTheme::Unknown; QColor m_accentColor = {}; #ifdef Q_OS_WINDOWS diff --git a/include/FramelessHelper/Quick/private/quickstandardtitlebar_p.h b/include/FramelessHelper/Quick/private/quickstandardtitlebar_p.h index a038785..bd4c651 100644 --- a/include/FramelessHelper/Quick/private/quickstandardtitlebar_p.h +++ b/include/FramelessHelper/Quick/private/quickstandardtitlebar_p.h @@ -50,6 +50,7 @@ class FRAMELESSHELPER_QUICK_API QuickStandardTitleBar : public QQuickRectangle Q_PROPERTY(QuickStandardMinimizeButton* minimizeButton READ minimizeButton CONSTANT FINAL) Q_PROPERTY(QuickStandardMaximizeButton* maximizeButton READ maximizeButton CONSTANT FINAL) Q_PROPERTY(QuickStandardCloseButton* closeButton READ closeButton CONSTANT FINAL) + Q_PROPERTY(bool extended READ isExtended WRITE setExtended NOTIFY extendedChanged FINAL) public: explicit QuickStandardTitleBar(QQuickItem *parent = nullptr); @@ -62,6 +63,9 @@ public: Q_NODISCARD QuickStandardMaximizeButton *maximizeButton() const; Q_NODISCARD QuickStandardCloseButton *closeButton() const; + Q_NODISCARD bool isExtended() const; + void setExtended(const bool value); + protected: void itemChange(const ItemChange change, const ItemChangeData &value) override; @@ -75,6 +79,7 @@ private Q_SLOTS: Q_SIGNALS: void titleLabelAlignmentChanged(); + void extendedChanged(); private: void initialize(); @@ -90,6 +95,7 @@ private: QMetaObject::Connection m_windowStateChangeConnection = {}; QMetaObject::Connection m_windowActiveChangeConnection = {}; QMetaObject::Connection m_windowTitleChangeConnection = {}; + bool m_extended = false; }; FRAMELESSHELPER_END_NAMESPACE diff --git a/include/FramelessHelper/Widgets/private/standardtitlebar_p.h b/include/FramelessHelper/Widgets/private/standardtitlebar_p.h index 7088947..06aff03 100644 --- a/include/FramelessHelper/Widgets/private/standardtitlebar_p.h +++ b/include/FramelessHelper/Widgets/private/standardtitlebar_p.h @@ -50,6 +50,9 @@ public: Q_NODISCARD static StandardTitleBarPrivate *get(StandardTitleBar *pub); Q_NODISCARD static const StandardTitleBarPrivate *get(const StandardTitleBar *pub); + Q_NODISCARD bool isExtended() const; + void setExtended(const bool value); + public Q_SLOTS: void updateMaximizeButton(); void updateTitleBarStyleSheet(); @@ -67,6 +70,7 @@ private: QScopedPointer m_maximizeButton; QScopedPointer m_closeButton; QPointer m_window = nullptr; + bool m_extended = false; }; FRAMELESSHELPER_END_NAMESPACE diff --git a/include/FramelessHelper/Widgets/standardtitlebar.h b/include/FramelessHelper/Widgets/standardtitlebar.h index 9d923a4..4b65464 100644 --- a/include/FramelessHelper/Widgets/standardtitlebar.h +++ b/include/FramelessHelper/Widgets/standardtitlebar.h @@ -40,6 +40,7 @@ class FRAMELESSHELPER_WIDGETS_API StandardTitleBar : public QWidget Q_PROPERTY(StandardSystemButton* minimizeButton READ minimizeButton CONSTANT FINAL) Q_PROPERTY(StandardSystemButton* maximizeButton READ maximizeButton CONSTANT FINAL) Q_PROPERTY(StandardSystemButton* closeButton READ closeButton CONSTANT FINAL) + Q_PROPERTY(bool extended READ isExtended WRITE setExtended NOTIFY extendedChanged FINAL) public: explicit StandardTitleBar(QWidget *parent = nullptr); @@ -49,9 +50,15 @@ public: Q_NODISCARD StandardSystemButton *maximizeButton() const; Q_NODISCARD StandardSystemButton *closeButton() const; + Q_NODISCARD bool isExtended() const; + void setExtended(const bool value); + protected: void paintEvent(QPaintEvent *event) override; +Q_SIGNALS: + void extendedChanged(); + private: QScopedPointer d_ptr; }; diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 9348ad7..ef5b3bd 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -35,13 +35,15 @@ set(INCLUDE_PREFIX ../../include/FramelessHelper/Core) set(SOURCES ${INCLUDE_PREFIX}/framelesshelpercore_global.h ${INCLUDE_PREFIX}/framelesshelper_qt.h - ${INCLUDE_PREFIX}/framelesswindowsmanager.h + ${INCLUDE_PREFIX}/framelessmanager.h ${INCLUDE_PREFIX}/utils.h - ${INCLUDE_PREFIX}/private/framelesswindowsmanager_p.h + ${INCLUDE_PREFIX}/private/framelessmanager_p.h + ${INCLUDE_PREFIX}/private/framelessconfig_p.h framelesshelpercore.qrc utils.cpp framelesshelper_qt.cpp - framelesswindowsmanager.cpp + framelessmanager.cpp + framelessconfig.cpp ) if(WIN32) diff --git a/src/core/framelessconfig.cpp b/src/core/framelessconfig.cpp new file mode 100644 index 0000000..e9b12fa --- /dev/null +++ b/src/core/framelessconfig.cpp @@ -0,0 +1,102 @@ +/* + * MIT License + * + * Copyright (C) 2022 by wangwenx190 (Yuhang Zhao) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "framelessconfig_p.h" +#include +#include +#include +#include + +FRAMELESSHELPER_BEGIN_NAMESPACE + +using namespace Global; + +FRAMELESSHELPER_STRING_CONSTANT2(ConfigFileName, ".framelesshelper.ini") + +static constexpr const struct +{ + const char *env = nullptr; + const char *ini = nullptr; +} OptionsTable[] = { + {"FRAMELESSHELPER_USE_CROSS_PLATFORM_QT_IMPLEMENTATION", "Options/UseCrossPlatformQtImplementation"}, + {"FRAMELESSHELPER_FORCE_HIDE_WINDOW_FRAME_BORDER", "Options/ForceHideWindowFrameBorder"}, + {"FRAMELESSHELPER_FORCE_SHOW_WINDOW_FRAME_BORDER", "Options/ForceShowWindowFrameBorder"}, + {"FRAMELESSHELPER_DISABLE_WINDOWS_SNAP_LAYOUTS", "Options/DisableWindowsSnapLayouts"}, + {"FRAMELESSHELPER_WINDOW_USE_ROUND_CORNERS", "Options/WindowUseRoundCorners"} +}; + +static constexpr const auto OptionCount = std::size(OptionsTable); + +struct ConfigData +{ + QMutex mutex; + bool loaded = false; + bool options[OptionCount] = {}; +}; + +Q_GLOBAL_STATIC(ConfigData, g_data) + +Q_GLOBAL_STATIC(FramelessConfig, g_config) + +FramelessConfig::FramelessConfig(QObject *parent) : QObject(parent) +{ + reload(); +} + +FramelessConfig::~FramelessConfig() = default; + +FramelessConfig *FramelessConfig::instance() +{ + return g_config(); +} + +void FramelessConfig::reload(const bool force) +{ + QMutexLocker locker(&g_data()->mutex); + if (g_data()->loaded && !force) { + return; + } + const QDir appDir(QCoreApplication::applicationDirPath()); + const QSettings configFile(appDir.filePath(kConfigFileName), QSettings::IniFormat); + for (int i = 0; i != OptionCount; ++i) { + const bool on = (qEnvironmentVariableIsSet(OptionsTable[i].env) && (qEnvironmentVariableIntValue(OptionsTable[i].env) > 0)) + || (configFile.value(QUtf8String(OptionsTable[i].ini), false).toBool()); + g_data()->options[i] = on; + } + g_data()->loaded = true; +} + +void FramelessConfig::set(const Option option, const bool on) +{ + QMutexLocker locker(&g_data()->mutex); + g_data()->options[static_cast(option)] = on; +} + +bool FramelessConfig::isSet(const Option option) const +{ + QMutexLocker locker(&g_data()->mutex); + return g_data()->options[static_cast(option)]; +} + +FRAMELESSHELPER_END_NAMESPACE diff --git a/src/core/framelessconfig_p.h b/src/core/framelessconfig_p.h new file mode 100644 index 0000000..cb7acd6 --- /dev/null +++ b/src/core/framelessconfig_p.h @@ -0,0 +1 @@ +#include "../../include/FramelessHelper/Core/private/framelessconfig_p.h" diff --git a/src/core/framelesshelper_qt.cpp b/src/core/framelesshelper_qt.cpp index 878f689..0da8922 100644 --- a/src/core/framelesshelper_qt.cpp +++ b/src/core/framelesshelper_qt.cpp @@ -26,8 +26,8 @@ #include #include #include -#include "framelesswindowsmanager.h" -#include "framelesswindowsmanager_p.h" +#include "framelessmanager.h" +#include "framelessmanager_p.h" #include "utils.h" FRAMELESSHELPER_BEGIN_NAMESPACE @@ -90,8 +90,8 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event) // First detect whether we got a theme change event or not, if so, // inform the user the system theme has changed. if (Utils::isThemeChangeEvent(event)) { - FramelessWindowsManager *manager = FramelessWindowsManager::instance(); - FramelessWindowsManagerPrivate *managerPriv = FramelessWindowsManagerPrivate::get(manager); + FramelessManager *manager = FramelessManager::instance(); + FramelessManagerPrivate *managerPriv = FramelessManagerPrivate::get(manager); managerPriv->notifySystemThemeHasChangedOrNot(); return false; } diff --git a/src/core/framelesshelper_win.cpp b/src/core/framelesshelper_win.cpp index d359b40..6ca8dd9 100644 --- a/src/core/framelesshelper_win.cpp +++ b/src/core/framelesshelper_win.cpp @@ -30,8 +30,9 @@ #include #include #include -#include "framelesswindowsmanager.h" -#include "framelesswindowsmanager_p.h" +#include "framelessmanager.h" +#include "framelessmanager_p.h" +#include "framelessconfig_p.h" #include "utils.h" #include "framelesshelper_windows.h" @@ -353,7 +354,10 @@ FRAMELESSHELPER_STRING_CONSTANT(FindWindowW) if (!parentWindowId) { return false; } - if (!Utils::isWindowsVersionOrGreater(WindowsVersion::_10_1507)) { + static const bool isWin10OrGreater = []() -> bool { + return Utils::isWindowsVersionOrGreater(WindowsVersion::_10_1507); + }(); + if (!isWin10OrGreater) { qWarning() << "The drag bar window is only supported on Windows 10 and onwards."; return false; } @@ -437,17 +441,32 @@ void FramelessHelperWin::addWindow(const SystemParameters ¶ms) Utils::fixupQtInternals(windowId); Utils::updateInternalWindowFrameMargins(params.getWindowHandle(), true); Utils::updateWindowFrameMargins(windowId, false); - if (Utils::isWindowsVersionOrGreater(WindowsVersion::_10_1507)) { - if (!createDragBarWindow(windowId)) { - qWarning() << "Failed to create the drag bar window."; + static const bool isWin10OrGreater = []() -> bool { + return Utils::isWindowsVersionOrGreater(WindowsVersion::_10_1507); + }(); + if (isWin10OrGreater) { + const FramelessConfig * const config = FramelessConfig::instance(); + if (!config->isSet(Option::DisableWindowsSnapLayouts)) { + if (!createDragBarWindow(windowId)) { + qWarning() << "Failed to create the drag bar window."; + } } - if (Utils::isWindowsVersionOrGreater(WindowsVersion::_10_1607)) { + static const bool isWin10RS1OrGreater = []() -> bool { + return Utils::isWindowsVersionOrGreater(WindowsVersion::_10_1607); + }(); + if (isWin10RS1OrGreater) { const bool dark = Utils::shouldAppsUseDarkMode(); Utils::updateWindowFrameBorderColor(windowId, dark); - if (Utils::isWindowsVersionOrGreater(WindowsVersion::_10_1809)) { + static const bool isWin10RS5OrGreater = []() -> bool { + return Utils::isWindowsVersionOrGreater(WindowsVersion::_10_1809); + }(); + if (isWin10RS5OrGreater) { //Utils::updateGlobalWin32ControlsTheme(windowId, dark); // Causes some QtWidgets paint incorrectly. - if (Utils::isWindowsVersionOrGreater(WindowsVersion::_11_21H2)) { - Utils::forceSquareCornersForWindow(windowId, true); + static const bool isWin11OrGreater = []() -> bool { + return Utils::isWindowsVersionOrGreater(WindowsVersion::_11_21H2); + }(); + if (isWin11OrGreater) { + Utils::forceSquareCornersForWindow(windowId, !config->isSet(Option::WindowUseRoundCorners)); } } } @@ -623,10 +642,13 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me // First, check if we have an auto-hide taskbar at all: if (taskbarState & ABS_AUTOHIDE) { bool top = false, bottom = false, left = false, right = false; - // Due to ABM_GETAUTOHIDEBAREX only exists from Win8.1, - // we have to use another way to judge this if we are - // running on Windows 7 or Windows 8. - if (Utils::isWindowsVersionOrGreater(WindowsVersion::_8_1)) { + // Due to ABM_GETAUTOHIDEBAREX was introduced in Windows 8.1, + // we have to use another way to judge this if we are running + // on Windows 7 or Windows 8. + static const bool isWin8Point1OrGreater = []() -> bool { + return Utils::isWindowsVersionOrGreater(WindowsVersion::_8_1); + }(); + if (isWin8Point1OrGreater) { MONITORINFO monitorInfo; SecureZeroMemory(&monitorInfo, sizeof(monitorInfo)); monitorInfo.cbSize = sizeof(monitorInfo); @@ -1008,7 +1030,10 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me break; } } - if (Utils::isWindowsVersionOrGreater(WindowsVersion::_8) && data.dragBarWindowId) { + static const bool isWin10OrGreater = []() -> bool { + return Utils::isWindowsVersionOrGreater(WindowsVersion::_10_1507); + }(); + if (isWin10OrGreater && data.dragBarWindowId) { switch (uMsg) { case WM_SIZE: case WM_DISPLAYCHANGE: { @@ -1022,22 +1047,28 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me } bool systemThemeChanged = ((uMsg == WM_THEMECHANGED) || (uMsg == WM_SYSCOLORCHANGE) || (uMsg == WM_DWMCOLORIZATIONCOLORCHANGED)); - if (Utils::isWindowsVersionOrGreater(WindowsVersion::_10_1607)) { + static const bool isWin10RS1OrGreater = []() -> bool { + return Utils::isWindowsVersionOrGreater(WindowsVersion::_10_1607); + }(); + if (isWin10RS1OrGreater) { if (uMsg == WM_SETTINGCHANGE) { if ((wParam == 0) && (QString::fromWCharArray(reinterpret_cast(lParam)) .compare(qThemeSettingChangeEventName, Qt::CaseInsensitive) == 0)) { systemThemeChanged = true; const bool dark = Utils::shouldAppsUseDarkMode(); Utils::updateWindowFrameBorderColor(windowId, dark); - if (Utils::isWindowsVersionOrGreater(WindowsVersion::_10_1809)) { + static const bool isWin10RS5OrGreater = []() -> bool { + return Utils::isWindowsVersionOrGreater(WindowsVersion::_10_1809); + }(); + if (isWin10RS5OrGreater) { //Utils::updateGlobalWin32ControlsTheme(windowId, dark); // Causes some QtWidgets paint incorrectly. } } } } if (systemThemeChanged) { - FramelessWindowsManager *manager = FramelessWindowsManager::instance(); - FramelessWindowsManagerPrivate *managerPriv = FramelessWindowsManagerPrivate::get(manager); + FramelessManager *manager = FramelessManager::instance(); + FramelessManagerPrivate *managerPriv = FramelessManagerPrivate::get(manager); managerPriv->notifySystemThemeHasChangedOrNot(); } return false; diff --git a/src/core/framelesswindowsmanager.cpp b/src/core/framelessmanager.cpp similarity index 77% rename from src/core/framelesswindowsmanager.cpp rename to src/core/framelessmanager.cpp index bbb2a3a..4e5db96 100644 --- a/src/core/framelesswindowsmanager.cpp +++ b/src/core/framelessmanager.cpp @@ -22,15 +22,14 @@ * SOFTWARE. */ -#include "framelesswindowsmanager.h" -#include "framelesswindowsmanager_p.h" -#include +#include "framelessmanager.h" +#include "framelessmanager_p.h" #include -#include #include #include #include #include "framelesshelper_qt.h" +#include "framelessconfig_p.h" #include "utils.h" #ifdef Q_OS_WINDOWS # include "framelesshelper_win.h" @@ -40,15 +39,15 @@ FRAMELESSHELPER_BEGIN_NAMESPACE using namespace Global; -struct FramelessWindowsManagerHelper +struct FramelessManagerHelper { QMutex mutex; QList windowIds = {}; }; -Q_GLOBAL_STATIC(FramelessWindowsManagerHelper, g_helper) +Q_GLOBAL_STATIC(FramelessManagerHelper, g_helper) -Q_GLOBAL_STATIC(FramelessWindowsManager, g_manager) +Q_GLOBAL_STATIC(FramelessManager, g_manager) #ifdef Q_OS_LINUX static constexpr const char QT_QPA_ENV_VAR[] = "QT_QPA_PLATFORM"; @@ -60,7 +59,7 @@ static constexpr const char MAC_LAYER_ENV_VAR[] = "QT_MAC_WANTS_LAYER"; FRAMELESSHELPER_BYTEARRAY_CONSTANT2(ValueOne, "1") #endif -FramelessWindowsManagerPrivate::FramelessWindowsManagerPrivate(FramelessWindowsManager *q) : QObject(q) +FramelessManagerPrivate::FramelessManagerPrivate(FramelessManager *q) : QObject(q) { Q_ASSERT(q); if (!q) { @@ -70,9 +69,9 @@ FramelessWindowsManagerPrivate::FramelessWindowsManagerPrivate(FramelessWindowsM initialize(); } -FramelessWindowsManagerPrivate::~FramelessWindowsManagerPrivate() = default; +FramelessManagerPrivate::~FramelessManagerPrivate() = default; -FramelessWindowsManagerPrivate *FramelessWindowsManagerPrivate::get(FramelessWindowsManager *pub) +FramelessManagerPrivate *FramelessManagerPrivate::get(FramelessManager *pub) { Q_ASSERT(pub); if (!pub) { @@ -81,7 +80,7 @@ FramelessWindowsManagerPrivate *FramelessWindowsManagerPrivate::get(FramelessWin return pub->d_func(); } -const FramelessWindowsManagerPrivate *FramelessWindowsManagerPrivate::get(const FramelessWindowsManager *pub) +const FramelessManagerPrivate *FramelessManagerPrivate::get(const FramelessManager *pub) { Q_ASSERT(pub); if (!pub) { @@ -90,34 +89,17 @@ const FramelessWindowsManagerPrivate *FramelessWindowsManagerPrivate::get(const return pub->d_func(); } -bool FramelessWindowsManagerPrivate::usePureQtImplementation() -{ -#ifdef Q_OS_WINDOWS - static const bool result = []() -> bool { - if (qEnvironmentVariableIntValue(kUsePureQtImplFlag) != 0) { - return true; - } - const QString iniFilePath = QCoreApplication::applicationDirPath() + QChar(u'/') + kConfigFileName; - QSettings settings(iniFilePath, QSettings::IniFormat); - return settings.value(kUsePureQtImplKeyPath, false).toBool(); - }(); -#else - static constexpr const bool result = true; -#endif - return result; -} - -SystemTheme FramelessWindowsManagerPrivate::systemTheme() const +SystemTheme FramelessManagerPrivate::systemTheme() const { return m_systemTheme; } -QColor FramelessWindowsManagerPrivate::systemAccentColor() const +QColor FramelessManagerPrivate::systemAccentColor() const { return m_accentColor; } -void FramelessWindowsManagerPrivate::addWindow(const SystemParameters ¶ms) +void FramelessManagerPrivate::addWindow(const SystemParameters ¶ms) { Q_ASSERT(params.isValid()); if (!params.isValid()) { @@ -131,7 +113,13 @@ void FramelessWindowsManagerPrivate::addWindow(const SystemParameters ¶ms) } g_helper()->windowIds.append(windowId); g_helper()->mutex.unlock(); - static const bool pureQt = usePureQtImplementation(); + static const bool pureQt = []() -> bool { +#ifdef Q_OS_WINDOWS + return FramelessConfig::instance()->isSet(Option::UseCrossPlatformQtImplementation); +#else + return true; +#endif + }(); #ifdef Q_OS_WINDOWS if (!pureQt) { // Work-around Win32 multi-monitor artifacts. @@ -162,9 +150,9 @@ void FramelessWindowsManagerPrivate::addWindow(const SystemParameters ¶ms) #endif } -void FramelessWindowsManagerPrivate::notifySystemThemeHasChangedOrNot() +void FramelessManagerPrivate::notifySystemThemeHasChangedOrNot() { - Q_Q(FramelessWindowsManager); + Q_Q(FramelessManager); const SystemTheme currentSystemTheme = Utils::getSystemTheme(); #ifdef Q_OS_WINDOWS const DwmColorizationArea currentColorizationArea = Utils::getDwmColorizationArea(); @@ -196,7 +184,7 @@ void FramelessWindowsManagerPrivate::notifySystemThemeHasChangedOrNot() } } -void FramelessWindowsManagerPrivate::initialize() +void FramelessManagerPrivate::initialize() { m_systemTheme = Utils::getSystemTheme(); #ifdef Q_OS_WINDOWS @@ -211,38 +199,32 @@ void FramelessWindowsManagerPrivate::initialize() #endif } -FramelessWindowsManager::FramelessWindowsManager(QObject *parent) : QObject(parent), d_ptr(new FramelessWindowsManagerPrivate(this)) +FramelessManager::FramelessManager(QObject *parent) : QObject(parent), d_ptr(new FramelessManagerPrivate(this)) { } -FramelessWindowsManager::~FramelessWindowsManager() = default; +FramelessManager::~FramelessManager() = default; -FramelessWindowsManager *FramelessWindowsManager::instance() +FramelessManager *FramelessManager::instance() { return g_manager(); } -bool FramelessWindowsManager::usePureQtImplementation() const +SystemTheme FramelessManager::systemTheme() const { - Q_D(const FramelessWindowsManager); - return d->usePureQtImplementation(); -} - -SystemTheme FramelessWindowsManager::systemTheme() const -{ - Q_D(const FramelessWindowsManager); + Q_D(const FramelessManager); return d->systemTheme(); } -QColor FramelessWindowsManager::systemAccentColor() const +QColor FramelessManager::systemAccentColor() const { - Q_D(const FramelessWindowsManager); + Q_D(const FramelessManager); return d->systemAccentColor(); } -void FramelessWindowsManager::addWindow(const SystemParameters ¶ms) +void FramelessManager::addWindow(const SystemParameters ¶ms) { - Q_D(FramelessWindowsManager); + Q_D(FramelessManager); d->addWindow(params); } @@ -294,6 +276,7 @@ void FramelessHelper::Core::initialize() // flicker and jitter during window resizing. QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Round); #endif + qRegisterMetaType