From b5d2ae5888413a2434c8538bbd2ae881ee05968e Mon Sep 17 00:00:00 2001 From: Yuhang Zhao <2546789017@qq.com> Date: Sat, 2 Apr 2022 17:56:45 +0800 Subject: [PATCH] quick: improve the standard titlebar's appearance And some minor tweaks to the initialize() function. Signed-off-by: Yuhang Zhao <2546789017@qq.com> --- examples/mainwindow/main.cpp | 2 + examples/mainwindow/mainwindow.cpp | 2 +- examples/quick/main.cpp | 3 ++ examples/quick/qml/MainWindow.qml | 2 +- examples/widget/main.cpp | 2 + .../Core/framelesshelpercore_global.h | 24 ++++++--- .../Quick/framelessquickutils.h | 8 +++ .../Quick/framelessquickwindow.h | 2 +- .../Widgets/framelessmainwindow.h | 2 +- .../FramelessHelper/Widgets/framelesswidget.h | 2 +- .../Widgets/framelesswidgetshelper.h | 2 +- src/core/framelesswindowsmanager.cpp | 53 +++++++++++++------ src/quick/framelessquickutils.cpp | 20 +++++++ src/quick/framelessquickwindow.cpp | 8 +-- src/quick/framelessquickwindow_p.h | 2 +- src/quick/qml/CloseButton.qml | 17 ++++-- src/quick/qml/MaximizeButton.qml | 15 ++++-- src/quick/qml/MinimizeButton.qml | 15 ++++-- src/widgets/framelessmainwindow.cpp | 4 +- src/widgets/framelesswidget.cpp | 4 +- src/widgets/framelesswidgetshelper.cpp | 6 +-- 21 files changed, 139 insertions(+), 56 deletions(-) diff --git a/examples/mainwindow/main.cpp b/examples/mainwindow/main.cpp index 0752d90..410935c 100644 --- a/examples/mainwindow/main.cpp +++ b/examples/mainwindow/main.cpp @@ -29,6 +29,8 @@ FRAMELESSHELPER_USE_NAMESPACE int main(int argc, char *argv[]) { + // Not necessary, but better call this function, before the construction + // of any Q(Core|Gui)Application instances. FramelessHelper::Core::initialize(); QApplication application(argc, argv); diff --git a/examples/mainwindow/mainwindow.cpp b/examples/mainwindow/mainwindow.cpp index 79a353c..0924a69 100644 --- a/examples/mainwindow/mainwindow.cpp +++ b/examples/mainwindow/mainwindow.cpp @@ -87,7 +87,7 @@ void MainWindow::setupUi() setHitTestVisible(titleBar->closeButton); connect(titleBar->minimizeButton, &QPushButton::clicked, this, &MainWindow::showMinimized); - connect(titleBar->maximizeButton, &QPushButton::clicked, this, &MainWindow::toggleMaximize); + connect(titleBar->maximizeButton, &QPushButton::clicked, this, &MainWindow::toggleMaximized); connect(titleBar->closeButton, &QPushButton::clicked, this, &MainWindow::close); connect(this, &MainWindow::windowIconChanged, titleBar->iconButton, &QPushButton::setIcon); connect(this, &MainWindow::windowTitleChanged, titleBar->titleLabel, &QLabel::setText); diff --git a/examples/quick/main.cpp b/examples/quick/main.cpp index b2ac5ac..bb98578 100644 --- a/examples/quick/main.cpp +++ b/examples/quick/main.cpp @@ -32,6 +32,8 @@ FRAMELESSHELPER_USE_NAMESPACE int main(int argc, char *argv[]) { + // Not necessary, but better call this function, before the construction + // of any Q(Core|Gui)Application instances. FramelessHelper::Core::initialize(); QGuiApplication application(argc, argv); @@ -63,6 +65,7 @@ int main(int argc, char *argv[]) QQuickStyle::setStyle(FRAMELESSHELPER_STRING_LITERAL("Default")); #endif + // VERY IMPORTANT! Don't forget to register the QML types! FramelessHelper::Quick::registerTypes(&engine); const QUrl homepageUrl(FRAMELESSHELPER_STRING_LITERAL("qrc:///qml/MainWindow.qml")); diff --git a/examples/quick/qml/MainWindow.qml b/examples/quick/qml/MainWindow.qml index 2ad38d1..ab412b1 100644 --- a/examples/quick/qml/MainWindow.qml +++ b/examples/quick/qml/MainWindow.qml @@ -67,7 +67,7 @@ FramelessWindow { } maximizeButton { id: maximizeButton - onClicked: window.toggleMaximize() + onClicked: window.toggleMaximized() } closeButton { id: closeButton diff --git a/examples/widget/main.cpp b/examples/widget/main.cpp index be3e44b..49c3d96 100644 --- a/examples/widget/main.cpp +++ b/examples/widget/main.cpp @@ -29,6 +29,8 @@ FRAMELESSHELPER_USE_NAMESPACE int main(int argc, char *argv[]) { + // Not necessary, but better call this function, before the construction + // of any Q(Core|Gui)Application instances. FramelessHelper::Core::initialize(); QApplication application(argc, argv); diff --git a/include/FramelessHelper/Core/framelesshelpercore_global.h b/include/FramelessHelper/Core/framelesshelpercore_global.h index c638e31..b901c6b 100644 --- a/include/FramelessHelper/Core/framelesshelpercore_global.h +++ b/include/FramelessHelper/Core/framelesshelpercore_global.h @@ -146,11 +146,6 @@ using NATIVE_EVENT_RESULT_TYPE = long; FRAMELESSHELPER_BEGIN_NAMESPACE -namespace FramelessHelper::Core -{ -FRAMELESSHELPER_CORE_API void initialize(); -} - namespace Global { @@ -169,6 +164,10 @@ Q_NAMESPACE_EXPORT(FRAMELESSHELPER_CORE_API) [[maybe_unused]] static constexpr const QColor kDefaultFrameBorderActiveColor = {77, 77, 77}; // #4D4D4D [[maybe_unused]] static constexpr const QColor kDefaultFrameBorderInactiveColorDark = {87, 89, 89}; // #575959 [[maybe_unused]] static constexpr const QColor kDefaultFrameBorderInactiveColorLight = {166, 166, 166}; // #A6A6A6 +[[maybe_unused]] static constexpr const QColor kDefaultSystemButtonHoverColor = {204, 204, 204}; // #CCCCCC +[[maybe_unused]] static constexpr const QColor kDefaultSystemButtonPressColor = {179, 179, 179}; // #B3B3B3 +[[maybe_unused]] static constexpr const QColor kDefaultSystemCloseButtonHoverColor = {232, 17, 35}; // #E81123 +[[maybe_unused]] static constexpr const QColor kDefaultSystemCloseButtonPressColor = {241, 112, 122}; // #F1707A [[maybe_unused]] static constexpr const QSize kDefaultSystemButtonSize = {int(qRound(qreal(kDefaultTitleBarHeight) * 1.5)), kDefaultTitleBarHeight}; [[maybe_unused]] static constexpr const QSize kDefaultSystemButtonIconSize = {16, 16}; @@ -199,12 +198,16 @@ enum class Option : int DontTouchWindowFrameBorderColor = 0x00000200, // Windows only, don't change the window frame border color. DontInstallSystemMenuHook = 0x00000400, // Windows only, don't install the system menu hook. DisableSystemMenu = 0x00000800, // Windows only, don't open the system menu when right clicks the titlebar. - NoDoubleClickMaximizeToggle = 0x00001000, // Don't toggle the maximize state when double clicks the titlebar. + NoDoubleClickMaximizeToggle = 0x00001000, // Don't toggle the maximized state when user double clicks the titlebar. DisableResizing = 0x00002000, // Disable resizing of the window. DisableDragging = 0x00004000, // Disable dragging through the titlebar of the window. DontTouchCursorShape = 0x00008000, // Don't change the cursor shape while the mouse is hovering above the window. - DontMoveWindowToDesktopCenter = 0x00010000, // Don't move the window to the desktop center before shown. - DontTreatFullScreenAsZoomed = 0x00020000 // Don't treat fullscreen as zoomed (maximized). + DontMoveWindowToDesktopCenter = 0x00010000, // Don't move the window to the desktop center before it's first shown. + DontTreatFullScreenAsZoomed = 0x00020000, // Don't treat fullscreen as zoomed (maximized). + DontTouchHighDpiScalingPolicy = 0x00040000, // Don't change Qt's default high DPI scaling policy. Qt5 default: disabled, Qt6 default: enabled. + DontTouchScaleFactorRoundingPolicy = 0x00080000, // Don't change Qt's default scale factor rounding policy. Qt5 default: round, Qt6 default: pass through. + DontTouchProcessDpiAwarenessLevel = 0x00100000, // Windows only, don't change the current process's DPI awareness level. + DontEnsureNonNativeWidgetSiblings = 0x00200000 // Don't ensure that siblings of native widgets stay non-native. }; Q_ENUM_NS(Option) Q_DECLARE_FLAGS(Options, Option) @@ -344,6 +347,11 @@ struct SystemParameters } // namespace Global +namespace FramelessHelper::Core +{ +FRAMELESSHELPER_CORE_API void initialize(const Global::Options options = {}); +} // namespace FramelessHelper::Core + FRAMELESSHELPER_END_NAMESPACE Q_DECLARE_METATYPE(FRAMELESSHELPER_PREPEND_NAMESPACE(Global::UserSettings)) diff --git a/include/FramelessHelper/Quick/framelessquickutils.h b/include/FramelessHelper/Quick/framelessquickutils.h index 83dd6be..dfaf5ec 100644 --- a/include/FramelessHelper/Quick/framelessquickutils.h +++ b/include/FramelessHelper/Quick/framelessquickutils.h @@ -54,6 +54,10 @@ class FRAMELESSHELPER_QUICK_API FramelessQuickUtils : public QObject Q_PROPERTY(QColor defaultSystemDarkColor READ defaultSystemDarkColor CONSTANT FINAL) Q_PROPERTY(QSizeF defaultSystemButtonSize READ defaultSystemButtonSize CONSTANT FINAL) Q_PROPERTY(QSizeF defaultSystemButtonIconSize READ defaultSystemButtonIconSize CONSTANT FINAL) + Q_PROPERTY(QColor defaultSystemButtonHoverColor READ defaultSystemButtonHoverColor CONSTANT FINAL) + Q_PROPERTY(QColor defaultSystemButtonPressColor READ defaultSystemButtonPressColor CONSTANT FINAL) + Q_PROPERTY(QColor defaultSystemCloseButtonHoverColor READ defaultSystemCloseButtonHoverColor CONSTANT FINAL) + Q_PROPERTY(QColor defaultSystemCloseButtonPressColor READ defaultSystemCloseButtonPressColor CONSTANT FINAL) public: explicit FramelessQuickUtils(QObject *parent = nullptr); @@ -69,6 +73,10 @@ public: Q_NODISCARD static QColor defaultSystemDarkColor(); Q_NODISCARD static QSizeF defaultSystemButtonSize(); Q_NODISCARD static QSizeF defaultSystemButtonIconSize(); + Q_NODISCARD static QColor defaultSystemButtonHoverColor(); + Q_NODISCARD static QColor defaultSystemButtonPressColor(); + Q_NODISCARD static QColor defaultSystemCloseButtonHoverColor(); + Q_NODISCARD static QColor defaultSystemCloseButtonPressColor(); Q_SIGNALS: void darkModeEnabledChanged(); diff --git a/include/FramelessHelper/Quick/framelessquickwindow.h b/include/FramelessHelper/Quick/framelessquickwindow.h index 933e8a2..947ae98 100644 --- a/include/FramelessHelper/Quick/framelessquickwindow.h +++ b/include/FramelessHelper/Quick/framelessquickwindow.h @@ -65,7 +65,7 @@ public: public Q_SLOTS: void showMinimized2(); - void toggleMaximize(); + void toggleMaximized(); void toggleFullScreen(); void showSystemMenu(const QPoint &pos); void startSystemMove2(); diff --git a/include/FramelessHelper/Widgets/framelessmainwindow.h b/include/FramelessHelper/Widgets/framelessmainwindow.h index 0db8276..489604b 100644 --- a/include/FramelessHelper/Widgets/framelessmainwindow.h +++ b/include/FramelessHelper/Widgets/framelessmainwindow.h @@ -56,7 +56,7 @@ public: public Q_SLOTS: void setHitTestVisible(QWidget *widget); - void toggleMaximize(); + void toggleMaximized(); void toggleFullScreen(); void moveToDesktopCenter(); void bringToFront(); diff --git a/include/FramelessHelper/Widgets/framelesswidget.h b/include/FramelessHelper/Widgets/framelesswidget.h index 2b7e8a7..3614535 100644 --- a/include/FramelessHelper/Widgets/framelesswidget.h +++ b/include/FramelessHelper/Widgets/framelesswidget.h @@ -60,7 +60,7 @@ public: public Q_SLOTS: void setHitTestVisible(QWidget *widget); - void toggleMaximize(); + void toggleMaximized(); void toggleFullScreen(); void moveToDesktopCenter(); void bringToFront(); diff --git a/include/FramelessHelper/Widgets/framelesswidgetshelper.h b/include/FramelessHelper/Widgets/framelesswidgetshelper.h index 85be054..16d9bc0 100644 --- a/include/FramelessHelper/Widgets/framelesswidgetshelper.h +++ b/include/FramelessHelper/Widgets/framelesswidgetshelper.h @@ -68,7 +68,7 @@ public: public Q_SLOTS: void setHitTestVisible(QWidget *widget); - void toggleMaximize(); + void toggleMaximized(); void toggleFullScreen(); void moveToDesktopCenter(); void bringToFront(); diff --git a/src/core/framelesswindowsmanager.cpp b/src/core/framelesswindowsmanager.cpp index 2ba8360..d8aedfa 100644 --- a/src/core/framelesswindowsmanager.cpp +++ b/src/core/framelesswindowsmanager.cpp @@ -131,7 +131,7 @@ void FramelessWindowsManager::addWindow(const UserSettings &settings, const Syst #endif } -void FramelessHelper::Core::initialize() +void FramelessHelper::Core::initialize(const Options options) { static bool inited = false; if (inited) { @@ -139,27 +139,43 @@ void FramelessHelper::Core::initialize() } inited = true; #ifdef Q_OS_WINDOWS - // This is equivalent to set the "dpiAware" and "dpiAwareness" field in your manifest file. - // It works through out Windows Vista to Windows 11. - Utils::tryToEnableHighestDpiAwarenessLevel(); + if (!(options & Option::DontTouchProcessDpiAwarenessLevel)) { + // This is equivalent to set the "dpiAware" and "dpiAwareness" field in + // your manifest file. It works through out Windows Vista to Windows 11. + // It's highly recommended to enable the highest DPI awareness level + // (currently it's PerMonitor Version 2, or PMv2 for short) for any GUI + // applications, to allow your user interface scale to an appropriate + // size and still stay sharp, though you will have to do the calculation + // and resize by yourself. + Utils::tryToEnableHighestDpiAwarenessLevel(); + } #endif - // This attribute is known to be NOT compatible with QGLWidget. - // Please consider migrating to the recommended QOpenGLWidget instead. - QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); + if (!(options & Option::DontEnsureNonNativeWidgetSiblings)) { + // This attribute is known to be __NOT__ compatible with QGLWidget. + // Please consider migrating to the recommended QOpenGLWidget instead. + QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); + } #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) - // Enable high DPI scaling by default, but only for Qt5 applications, - // because this is the default setting of Qt6 and it can't be changed - // from outside anymore (except for internal testing). - QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); + if (!(options & Option::DontTouchHighDpiScalingPolicy)) { + // Enable high DPI scaling by default, but only for Qt5 applications, + // because this has become the default setting since Qt6 and it can't + // be changed from outside anymore (except for internal testing purposes). + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); + } #endif #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) - // Non-integer scale factors will cause Qt have some painting defects - // for both Qt Widgets and Qt Quick applications, and it's still not - // totally fixed till now (Qt 6.4), so we round the scale factors to - // get a better looking. - QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Round); + if (!(options & Option::DontTouchScaleFactorRoundingPolicy)) { + // Non-integer scale factors will cause Qt have some painting defects + // for both Qt Widgets and Qt Quick applications, and it's still not + // totally fixed till now (Qt 6.4), so we round the scale factors to + // get a better looking. Non-integer scale factors will also cause + // flicker and jitter during window resizing. + QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Round); + } #endif + // Mainly for Qt Quick applications, but won't bring any harm to Qt Widgets + // applications either. qRegisterMetaType