diff --git a/include/FramelessHelper/Widgets/private/standardtitlebar_p.h b/include/FramelessHelper/Widgets/private/standardtitlebar_p.h index a7a834e4..a41f77a2 100644 --- a/include/FramelessHelper/Widgets/private/standardtitlebar_p.h +++ b/include/FramelessHelper/Widgets/private/standardtitlebar_p.h @@ -64,6 +64,7 @@ class FRAMELESSHELPER_WIDGETS_API StandardTitleBarPrivate : public QObject Q_NODISCARD QFont defaultFont() const; Q_NODISCARD FontMetrics titleLabelSize() const; + Q_NODISCARD int titleLabelMaxWidth() const; Q_SLOT void updateMaximizeButton(); Q_SLOT void updateTitleBarColor(); diff --git a/src/core/utils_win.cpp b/src/core/utils_win.cpp index c65bc1ca..3e68f3d9 100644 --- a/src/core/utils_win.cpp +++ b/src/core/utils_win.cpp @@ -193,6 +193,7 @@ FRAMELESSHELPER_STRING_CONSTANT(RedrawWindow) FRAMELESSHELPER_STRING_CONSTANT(ScreenToClient) FRAMELESSHELPER_STRING_CONSTANT(DwmFlush) FRAMELESSHELPER_STRING_CONSTANT(GetCursorPos) +FRAMELESSHELPER_STRING_CONSTANT(DeleteObject) struct UtilsWinExtraData : public FramelessExtraData { @@ -3175,7 +3176,6 @@ bool Utils::updateFramebufferTransparency(const WId windowId) bool ok = false; std::ignore = getDwmColorizationColor(&opaque, &ok); if (WindowsVersionHelper::isWin8OrGreater() || (ok && !opaque)) { -#if 0 // Windows QPA will always do this for us. DWM_BLURBEHIND bb; SecureZeroMemory(&bb, sizeof(bb)); bb.dwFlags = (DWM_BB_ENABLE | DWM_BB_BLURREGION); @@ -3191,7 +3191,6 @@ bool Utils::updateFramebufferTransparency(const WId windowId) WARNING << getSystemErrorMessageImpl(kDwmEnableBlurBehindWindow, hr); return false; } -#endif } else { // HACK: Disable framebuffer transparency on Windows 7 when the // colorization color is opaque, because otherwise the window diff --git a/src/quick/quickstandardtitlebar.cpp b/src/quick/quickstandardtitlebar.cpp index 972d1d4a..97e848e8 100644 --- a/src/quick/quickstandardtitlebar.cpp +++ b/src/quick/quickstandardtitlebar.cpp @@ -92,25 +92,26 @@ void QuickStandardTitleBar::setTitleLabelAlignment(const Qt::Alignment value) m_windowTitleLabel->setVAlign(QQuickLabel::AlignVCenter); const QQuickItemPrivate * const titleBarPriv = QQuickItemPrivate::get(this); labelAnchors->setVerticalCenter(titleBarPriv->verticalCenter()); - if (m_labelAlignment & Qt::AlignLeft) { + if ((m_labelAlignment & Qt::AlignLeft) || (m_labelAlignment & Qt::AlignRight) || (m_labelAlignment & Qt::AlignHCenter)) { if (m_windowIcon->isVisible()) { labelAnchors->setLeft(QQuickItemPrivate::get(m_windowIcon)->right()); } else { labelAnchors->setLeft(titleBarPriv->left()); } labelAnchors->setLeftMargin(kDefaultTitleBarContentsMargin); - m_windowTitleLabel->setHAlign(QQuickLabel::AlignLeft); - } else if (m_labelAlignment & Qt::AlignRight) { #ifdef Q_OS_MACOS labelAnchors->setRight(titleBarPriv->right()); #elif FRAMELESSHELPER_CONFIG(system_button) labelAnchors->setRight(QQuickItemPrivate::get(m_systemButtonsRow)->left()); #endif labelAnchors->setRightMargin(kDefaultTitleBarContentsMargin); - m_windowTitleLabel->setHAlign(QQuickLabel::AlignRight); - } else if (m_labelAlignment & Qt::AlignHCenter) { - labelAnchors->setHorizontalCenter(titleBarPriv->horizontalCenter()); - m_windowTitleLabel->setHAlign(QQuickLabel::AlignHCenter); + if (m_labelAlignment & Qt::AlignLeft) { + m_windowTitleLabel->setHAlign(QQuickLabel::AlignLeft); + } else if (m_labelAlignment & Qt::AlignRight) { + m_windowTitleLabel->setHAlign(QQuickLabel::AlignRight); + } else { + m_windowTitleLabel->setHAlign(QQuickLabel::AlignHCenter); + } } else { WARNING << "The alignment for the title label is not set!"; labelAnchors->setLeft(titleBarPriv->left()); @@ -503,6 +504,8 @@ void QuickStandardTitleBar::initialize() setHeight(kDefaultTitleBarHeight); m_windowTitleLabel = new QQuickLabel(this); + m_windowTitleLabel->setMaximumLineCount(1); + m_windowTitleLabel->setElideMode(QQuickText::ElideRight); QFont f = m_windowTitleLabel->font(); f.setPointSize(kDefaultTitleBarFontPointSize); m_windowTitleLabel->setFont(f); diff --git a/src/widgets/standardtitlebar.cpp b/src/widgets/standardtitlebar.cpp index 29ffda0f..f7871cf9 100644 --- a/src/widgets/standardtitlebar.cpp +++ b/src/widgets/standardtitlebar.cpp @@ -144,13 +144,33 @@ StandardTitleBarPrivate::FontMetrics StandardTitleBarPrivate::titleLabelSize() c } const QFont font = titleFont.value_or(defaultFont()); const QFontMetrics fontMetrics(font); + const int textWidth = Utils::horizontalAdvance(fontMetrics, text); return { - /* .width */ Utils::horizontalAdvance(fontMetrics, text), + /* .width */ std::min(textWidth, titleLabelMaxWidth()), /* .height */ fontMetrics.height(), /* .ascent */ fontMetrics.ascent() }; } +int StandardTitleBarPrivate::titleLabelMaxWidth() const +{ +#if (FRAMELESSHELPER_CONFIG(system_button) && !defined(Q_OS_MACOS)) + const int chromeButtonAreaWidth = (closeButton->x() + closeButton->width() - minimizeButton->x()); +#else + static constexpr const int chromeButtonAreaWidth = 70; +#endif + Q_Q(const StandardTitleBar); + int textMaxWidth = q->width(); + if ((labelAlignment & Qt::AlignLeft) || (labelAlignment & Qt::AlignRight)) { + textMaxWidth -= (windowIconRect().width() + chromeButtonAreaWidth + (kDefaultTitleBarContentsMargin * 2)); + } else if (labelAlignment & Qt::AlignHCenter) { + textMaxWidth -= ((chromeButtonAreaWidth + kDefaultTitleBarContentsMargin) * 2); + } else { + textMaxWidth = std::round(qreal(textMaxWidth) * qreal(0.8)); + } + return std::max(textMaxWidth, 0); +} + bool StandardTitleBarPrivate::mouseEventHandler(QMouseEvent *event) { #ifdef Q_OS_MACOS @@ -578,7 +598,12 @@ void StandardTitleBar::paintEvent(QPaintEvent *event) const int y = std::round((qreal(height() - labelSize.height) / qreal(2)) + qreal(labelSize.ascent)); return {x, y}; }(); - painter.drawText(pos, text); + const int textMaxWidth = d->titleLabelMaxWidth(); + const QString elidedText = painter.fontMetrics().elidedText(text, Qt::ElideRight, textMaxWidth, Qt::TextShowMnemonic); + // No need to draw the text if there's only the elide mark left (or even less). + if (elidedText.size() > 3) { + painter.drawText(pos, elidedText); + } } } if (d->windowIconVisible) {