quick: improve the standard titlebar's appearance

And some minor tweaks to the initialize() function.

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
Yuhang Zhao 2022-04-02 17:56:45 +08:00
parent f0846596ff
commit b5d2ae5888
21 changed files with 139 additions and 56 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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"));

View File

@ -67,7 +67,7 @@ FramelessWindow {
}
maximizeButton {
id: maximizeButton
onClicked: window.toggleMaximize()
onClicked: window.toggleMaximized()
}
closeButton {
id: closeButton

View File

@ -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);

View File

@ -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))

View File

@ -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();

View File

@ -65,7 +65,7 @@ public:
public Q_SLOTS:
void showMinimized2();
void toggleMaximize();
void toggleMaximized();
void toggleFullScreen();
void showSystemMenu(const QPoint &pos);
void startSystemMove2();

View File

@ -56,7 +56,7 @@ public:
public Q_SLOTS:
void setHitTestVisible(QWidget *widget);
void toggleMaximize();
void toggleMaximized();
void toggleFullScreen();
void moveToDesktopCenter();
void bringToFront();

View File

@ -60,7 +60,7 @@ public:
public Q_SLOTS:
void setHitTestVisible(QWidget *widget);
void toggleMaximize();
void toggleMaximized();
void toggleFullScreen();
void moveToDesktopCenter();
void bringToFront();

View File

@ -68,7 +68,7 @@ public:
public Q_SLOTS:
void setHitTestVisible(QWidget *widget);
void toggleMaximize();
void toggleMaximized();
void toggleFullScreen();
void moveToDesktopCenter();
void bringToFront();

View File

@ -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.
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.
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))
if (!(options & Option::DontTouchHighDpiScalingPolicy)) {
// 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).
// 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))
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.
// 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<Option>();
qRegisterMetaType<SystemTheme>();
qRegisterMetaType<SystemButtonType>();
@ -167,6 +183,9 @@ void FramelessHelper::Core::initialize()
qRegisterMetaType<DwmColorizationArea>();
qRegisterMetaType<Anchor>();
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
// Only needed by Qt5 Quick applications, it's hard to say whether it's a
// bug or a lack of features. The QML engine is having a hard time to find
// the correct type if the type has a long namespace with a deep hierarchy.
qRegisterMetaType<Anchor>("Global::Anchor");
#endif
qRegisterMetaType<UserSettings>();

View File

@ -118,4 +118,24 @@ QSizeF FramelessQuickUtils::defaultSystemButtonIconSize()
return kDefaultSystemButtonIconSize;
}
QColor FramelessQuickUtils::defaultSystemButtonHoverColor()
{
return kDefaultSystemButtonHoverColor;
}
QColor FramelessQuickUtils::defaultSystemButtonPressColor()
{
return kDefaultSystemButtonPressColor;
}
QColor FramelessQuickUtils::defaultSystemCloseButtonHoverColor()
{
return kDefaultSystemCloseButtonHoverColor;
}
QColor FramelessQuickUtils::defaultSystemCloseButtonPressColor()
{
return kDefaultSystemCloseButtonPressColor;
}
FRAMELESSHELPER_END_NAMESPACE

View File

@ -312,7 +312,7 @@ void FramelessQuickWindowPrivate::showMinimized2()
#endif
}
void FramelessQuickWindowPrivate::toggleMaximize()
void FramelessQuickWindowPrivate::toggleMaximized()
{
if (isFixedSize()) {
return;
@ -622,7 +622,7 @@ void FramelessQuickWindowPrivate::mouseDoubleClickEventHandler(QMouseEvent *even
if (!isInTitleBarDraggableArea(scenePos)) {
return;
}
toggleMaximize();
toggleMaximized();
}
void FramelessQuickWindowPrivate::updateTopBorderColor()
@ -743,10 +743,10 @@ void FramelessQuickWindow::showMinimized2()
d->showMinimized2();
}
void FramelessQuickWindow::toggleMaximize()
void FramelessQuickWindow::toggleMaximized()
{
Q_D(FramelessQuickWindow);
d->toggleMaximize();
d->toggleMaximized();
}
void FramelessQuickWindow::toggleFullScreen()

View File

@ -69,7 +69,7 @@ public:
public Q_SLOTS:
void showMinimized2();
void toggleMaximize();
void toggleMaximized();
void toggleFullScreen();
void showSystemMenu(const QPoint &pos);
void startSystemMove2();

View File

@ -36,18 +36,25 @@ Button {
Image {
anchors.centerIn: parent
source: (FramelessUtils.darkModeEnabled || FramelessUtils.titleBarColorized)
source: (button.hovered || FramelessUtils.darkModeEnabled || FramelessUtils.titleBarColorized)
? "image://framelesshelper/dark/close" : "image://framelesshelper/light/close"
}
}
background: Rectangle {
visible: button.hovered
color: "red"
opacity: 0.5
visible: button.hovered || button.pressed
color: {
if (button.pressed) {
return FramelessUtils.defaultSystemCloseButtonPressColor;
}
if (button.hovered) {
return FramelessUtils.defaultSystemCloseButtonHoverColor;
}
return "transparent";
}
}
ToolTip {
visible: button.hovered && !button.down
visible: button.hovered && !button.pressed
delay: Qt.styleHints.mousePressAndHoldInterval
text: qsTr("Close")
}

View File

@ -46,13 +46,20 @@ Button {
}
}
background: Rectangle {
visible: button.hovered
color: "gray"
opacity: 0.5
visible: button.hovered || button.pressed
color: {
if (button.pressed) {
return FramelessUtils.defaultSystemButtonPressColor;
}
if (button.hovered) {
return FramelessUtils.defaultSystemButtonHoverColor;
}
return "transparent";
}
}
ToolTip {
visible: button.hovered && !button.down
visible: button.hovered && !button.pressed
delay: Qt.styleHints.mousePressAndHoldInterval
text: button.maximized ? qsTr("Restore") : qsTr("Maximize")
}

View File

@ -41,13 +41,20 @@ Button {
}
}
background: Rectangle {
visible: button.hovered
color: "gray"
opacity: 0.5
visible: button.hovered || button.pressed
color: {
if (button.pressed) {
return FramelessUtils.defaultSystemButtonPressColor;
}
if (button.hovered) {
return FramelessUtils.defaultSystemButtonHoverColor;
}
return "transparent";
}
}
ToolTip {
visible: button.hovered && !button.down
visible: button.hovered && !button.pressed
delay: Qt.styleHints.mousePressAndHoldInterval
text: qsTr("Minimize")
}

View File

@ -71,9 +71,9 @@ void FramelessMainWindow::setHitTestVisible(QWidget *widget)
m_helper->setHitTestVisible(widget);
}
void FramelessMainWindow::toggleMaximize()
void FramelessMainWindow::toggleMaximized()
{
m_helper->toggleMaximize();
m_helper->toggleMaximized();
}
void FramelessMainWindow::toggleFullScreen()

View File

@ -81,9 +81,9 @@ void FramelessWidget::setHitTestVisible(QWidget *widget)
m_helper->setHitTestVisible(widget);
}
void FramelessWidget::toggleMaximize()
void FramelessWidget::toggleMaximized()
{
m_helper->toggleMaximize();
m_helper->toggleMaximized();
}
void FramelessWidget::toggleFullScreen()

View File

@ -335,7 +335,7 @@ void FramelessWidgetsHelper::mouseDoubleClickEventHandler(QMouseEvent *event)
if (!isInTitleBarDraggableArea(scenePos)) {
return;
}
toggleMaximize();
toggleMaximized();
}
void FramelessWidgetsHelper::initialize()
@ -448,7 +448,7 @@ void FramelessWidgetsHelper::createSystemTitleBar()
m_systemMaximizeButton->setFixedSize(kDefaultSystemButtonSize);
m_systemMaximizeButton->setIconSize(kDefaultSystemButtonIconSize);
m_systemMaximizeButton->setToolTip(tr("Maximize"));
connect(m_systemMaximizeButton, &QPushButton::clicked, this, &FramelessWidgetsHelper::toggleMaximize);
connect(m_systemMaximizeButton, &QPushButton::clicked, this, &FramelessWidgetsHelper::toggleMaximized);
m_systemCloseButton = new QPushButton(m_systemTitleBarWidget);
m_systemCloseButton->setFixedSize(kDefaultSystemButtonSize);
m_systemCloseButton->setIconSize(kDefaultSystemButtonIconSize);
@ -644,7 +644,7 @@ void FramelessWidgetsHelper::updateSystemButtonsIcon()
m_systemCloseButton->setIcon(qvariant_cast<QIcon>(Utils::getSystemButtonIconResource(SystemButtonType::Close, theme, resource)));
}
void FramelessWidgetsHelper::toggleMaximize()
void FramelessWidgetsHelper::toggleMaximized()
{
if (isFixedSize()) {
return;