diff --git a/kdecoration/config/darklyconfigwidget.cpp b/kdecoration/config/darklyconfigwidget.cpp index 00ccbc51..dcafd4de 100644 --- a/kdecoration/config/darklyconfigwidget.cpp +++ b/kdecoration/config/darklyconfigwidget.cpp @@ -54,6 +54,8 @@ ConfigWidget::ConfigWidget(QObject *parent, const KPluginMetaData &data, const Q connect(m_ui.roundedCorners, &QAbstractButton::clicked, this, &ConfigWidget::updateChanged); connect(m_ui.otherCornerRadius, SIGNAL(valueChanged(int)), SLOT(updateChanged())); connect(m_ui.floatingTitlebar, &QAbstractButton::clicked, this, &ConfigWidget::updateChanged); + connect(m_ui.blurTransparentTitleBar, &QAbstractButton::clicked, this, &ConfigWidget::updateChanged); + connect(m_ui.matchInactiveTitleBar, &QAbstractButton::clicked, this, &ConfigWidget::updateChanged); // track animations changes connect(m_ui.animationsEnabled, &QAbstractButton::clicked, this, &ConfigWidget::updateChanged); @@ -92,6 +94,8 @@ void ConfigWidget::load() #endif m_ui.otherCornerRadius->setValue(m_internalSettings->otherCornerRadius()); m_ui.floatingTitlebar->setChecked(m_internalSettings->floatingTitlebar()); + m_ui.blurTransparentTitleBar->setChecked(m_internalSettings->blurTransparentTitleBar()); + m_ui.matchInactiveTitleBar->setChecked(m_internalSettings->matchInactiveTitleBar()); // load shadows if (m_internalSettings->shadowSize() <= InternalSettings::ShadowVeryLarge) @@ -128,6 +132,8 @@ void ConfigWidget::save() m_internalSettings->setRoundedCorners(m_ui.roundedCorners->isChecked()); m_internalSettings->setOtherCornerRadius(m_ui.otherCornerRadius->value()); m_internalSettings->setFloatingTitlebar(m_ui.floatingTitlebar->isChecked()); + m_internalSettings->setBlurTransparentTitleBar(m_ui.blurTransparentTitleBar->isChecked()); + m_internalSettings->setMatchInactiveTitleBar(m_ui.matchInactiveTitleBar->isChecked()); m_internalSettings->setShadowSize(m_ui.shadowSize->currentIndex()); m_internalSettings->setShadowStrength(qRound(qreal(m_ui.shadowStrength->value() * 255) / 100)); @@ -176,6 +182,8 @@ void ConfigWidget::defaults() m_ui.roundedCorners->setChecked(m_internalSettings->roundedCorners()); m_ui.otherCornerRadius->setValue(m_internalSettings->otherCornerRadius()); m_ui.floatingTitlebar->setChecked(m_internalSettings->floatingTitlebar()); + m_ui.blurTransparentTitleBar->setChecked(m_internalSettings->blurTransparentTitleBar()); + m_ui.matchInactiveTitleBar->setChecked(m_internalSettings->matchInactiveTitleBar()); m_ui.shadowSize->setCurrentIndex(m_internalSettings->shadowSize()); m_ui.shadowStrength->setValue(qRound(qreal(m_internalSettings->shadowStrength() * 100) / 255)); @@ -210,6 +218,10 @@ void ConfigWidget::updateChanged() modified = true; else if (m_ui.floatingTitlebar->isChecked() != m_internalSettings->floatingTitlebar()) modified = true; + else if (m_ui.blurTransparentTitleBar->isChecked() != m_internalSettings->blurTransparentTitleBar()) + modified = true; + else if (m_ui.matchInactiveTitleBar->isChecked() != m_internalSettings->matchInactiveTitleBar()) + modified = true; // animations else if (m_ui.animationsEnabled->isChecked() != m_internalSettings->animationsEnabled()) diff --git a/kdecoration/config/ui/darklyconfigurationui.ui b/kdecoration/config/ui/darklyconfigurationui.ui index ae1acde2..4aa77415 100644 --- a/kdecoration/config/ui/darklyconfigurationui.ui +++ b/kdecoration/config/ui/darklyconfigurationui.ui @@ -191,6 +191,26 @@ + + + + Make the title bar translucent and blurred, matched to the toolbar opacity so the top of the window is seamless. + + + Transparent, blurred title bar + + + + + + + Keep the titlebar background and text colors identical whether the window is focused or not, so unfocused windows don't appear lighter or more transparent. + + + Use active titlebar colors for inactive windows + + + diff --git a/kdecoration/darklydecoration.cpp b/kdecoration/darklydecoration.cpp index 262b44bb..23718a15 100644 --- a/kdecoration/darklydecoration.cpp +++ b/kdecoration/darklydecoration.cpp @@ -174,10 +174,27 @@ QColor Decoration::titleBarColor() const auto c = window(); if (hideTitleBar()) return c->color(ColorGroup::Inactive, ColorRole::TitleBar); - else if (m_animation->state() == QAbstractAnimation::Running) { - return KColorUtils::mix(c->color(ColorGroup::Inactive, ColorRole::TitleBar), c->color(ColorGroup::Active, ColorRole::TitleBar), m_opacity); - } else - return c->color(c->isActive() ? ColorGroup::Active : ColorGroup::Inactive, ColorRole::TitleBar); + + QColor color; + if (!m_internalSettings->matchInactiveTitleBar() && + m_animation->state() == QAbstractAnimation::Running) { + color = KColorUtils::mix(c->color(ColorGroup::Inactive, ColorRole::TitleBar), + c->color(ColorGroup::Active, ColorRole::TitleBar), + m_opacity); + } else { + const ColorGroup group = (c->isActive() || m_internalSettings->matchInactiveTitleBar()) + ? ColorGroup::Active : ColorGroup::Inactive; + color = c->color(group, ColorRole::TitleBar); + } + + if (m_internalSettings->blurTransparentTitleBar()) { + const int opacity = KSharedConfig::openConfig(QStringLiteral("darklyrc")) + ->group(QStringLiteral("Style")) + .readEntry("ToolBarOpacity", 100); + color.setAlpha(qRound(qBound(0, opacity, 100) * 255.0 / 100)); + } + + return color; } //________________________________________________________________ QColor Decoration::outlineColor() const @@ -199,7 +216,8 @@ QColor Decoration::outlineColor() const QColor Decoration::fontColor() const { auto c = window(); - return c->color(c->isActive() ? ColorGroup::Active : ColorGroup::Inactive, ColorRole::Foreground); + const bool useActive = c->isActive() || m_internalSettings->matchInactiveTitleBar(); + return c->color(useActive ? ColorGroup::Active : ColorGroup::Inactive, ColorRole::Foreground); } //________________________________________________________________ @@ -272,50 +290,38 @@ bool Decoration::init() //________________________________________________________________ void Decoration::updateBlur() { -if (m_internalSettings->floatingTitlebar()){ auto c = window(); - const QColor titleBarColor = c->color(c->isActive() ? ColorGroup::Active : ColorGroup::Inactive, ColorRole::TitleBar); - - // set opaque to false when non-maximized, regardless of color (prevents kornerbug) - if (titleBarColor.alpha() == 255) { + const QColor tbColor = this->titleBarColor(); + if (tbColor.alpha() == 255) { this->setOpaque(c->isMaximized()); } else { this->setOpaque(false); } - // Recalculate window shapes - calculateWindowAndTitleBarShapes(true); + if (m_internalSettings->floatingTitlebar()) { + // Recalculate window shapes + calculateWindowAndTitleBarShapes(true); - // Get window rectangle as integers - QRect windowRect(QPoint(0, 0), c->size().toSize()); + // Get window rectangle as integers + QRect windowRect(QPoint(0, 0), c->size().toSize()); - // Height of the blur region - const int blurHeight = (buttonSize() + (Metrics::TitleBar_TopMargin * 2) + 8); + // Height of the blur region + const int blurHeight = (buttonSize() + (Metrics::TitleBar_TopMargin * 2) + 8); - // Corner radius - const qreal blurRadius = c->isMaximized() ? 0.0 : m_scaledCornerRadius; + // Corner radius + const qreal blurRadius = c->isMaximized() ? 0.0 : m_scaledCornerRadius; - // Create a rounded rectangle path for the top strip - QPainterPath path; - path.addRoundedRect(QRectF(0, 0, windowRect.width(), blurHeight), blurRadius, blurRadius); + // Create a rounded rectangle path for the top strip + QPainterPath path; + path.addRoundedRect(QRectF(0, 0, windowRect.width(), blurHeight), blurRadius, blurRadius); - // Convert path to QRegion and set as blur region - QRegion blurRegion(path.toFillPolygon().toPolygon()); - this->setBlurRegion(blurRegion); -} else { - auto c = window(); - const QColor titleBarColor = c->color(c->isActive() ? ColorGroup::Active : ColorGroup::Inactive, ColorRole::TitleBar); - - // set opaque to false when non-maximized, regardless of color (prevents kornerbug) - if (titleBarColor.alpha() == 255) { - this->setOpaque(c->isMaximized()); + // Convert path to QRegion and set as blur region + QRegion blurRegion(path.toFillPolygon().toPolygon()); + this->setBlurRegion(blurRegion); } else { - this->setOpaque(false); + calculateWindowAndTitleBarShapes(true); + this->setBlurRegion(QRegion(m_windowPath->toFillPolygon().toPolygon())); } - - calculateWindowAndTitleBarShapes(true); - this->setBlurRegion(QRegion(m_windowPath->toFillPolygon().toPolygon())); -} } //________________________________________________________________ @@ -877,9 +883,10 @@ void Decoration::paint(QPainter *painter, const QRectF &repaintRegion) void Decoration::paintTitleBar(QPainter *painter, const QRectF &repaintRegion) { const auto c = window(); + const QColor titleBarColor = this->titleBarColor(); QRectF rect(QPointF(0, 0), QSizeF(size().width(), borderTop())); QBrush frontBrush; - QBrush backBrush(this->titleBarColor()); + QBrush backBrush(titleBarColor); if (!rect.intersects(repaintRegion)) { return; @@ -890,21 +897,20 @@ void Decoration::paintTitleBar(QPainter *painter, const QRectF &repaintRegion) // render a linear gradient on title area if (c->isActive() && m_internalSettings->drawBackgroundGradient()) { - const QColor titleBarColor(this->titleBarColor()); QLinearGradient gradient(0, 0, 0, m_titleRect.height()); gradient.setColorAt(0.0, titleBarColor.lighter(120)); gradient.setColorAt(0.8, titleBarColor); painter->setBrush(gradient); } else { - painter->setBrush(titleBarColor()); + painter->setBrush(titleBarColor); } auto s = settings(); painter->drawPath(*m_titleBarPath); // top highlight - if (qGray(this->titleBarColor().rgb()) < 130 && m_internalSettings->drawHighlight()) { + if (qGray(titleBarColor.rgb()) < 130 && m_internalSettings->drawHighlight()) { if (isMaximized() || !s->isAlphaChannelSupported()) { painter->setPen(QColor(255, 255, 255, 30)); painter->drawLine(m_titleRect.topLeft(), m_titleRect.topRight()); diff --git a/kdecoration/darklydecoration.h b/kdecoration/darklydecoration.h index 114b9753..5eba40ad 100644 --- a/kdecoration/darklydecoration.h +++ b/kdecoration/darklydecoration.h @@ -162,6 +162,7 @@ private Q_SLOTS: //*frame corner radius, scaled according to DPI qreal m_scaledCornerRadius = 3; + }; bool Decoration::hasBorders() const diff --git a/kdecoration/darklysettingsdata.kcfg b/kdecoration/darklysettingsdata.kcfg index 4b206a64..fd7dc7d3 100644 --- a/kdecoration/darklysettingsdata.kcfg +++ b/kdecoration/darklysettingsdata.kcfg @@ -132,6 +132,16 @@ false + + + false + + + + + false + + diff --git a/kstyle/darklystyle.cpp b/kstyle/darklystyle.cpp index 883d61dd..24fbccd4 100644 --- a/kstyle/darklystyle.cpp +++ b/kstyle/darklystyle.cpp @@ -4391,6 +4391,18 @@ bool Style::drawFrameTabWidgetPrimitive(const QStyleOption *option, QPainter *pa if (tabOption->tabBarSize.isEmpty() && !isQtQuickControl) return true; + // When Dolphin's view is transparent, the tab bar above and KItemListContainer below + // both punch transparent holes and fill at dolphinViewOpacity. The frame background + // here would otherwise be a fully opaque strip between them — the visible line. + // Match the surrounding areas: punch transparent and fill at the same opacity. + if (_isDolphin && StyleConfigData::dolphinViewOpacity() < 100 && widget && _translucentWidgets.contains(widget->window())) { + _helper->renderTransparentArea(painter, option->rect); + QColor backgroundColor = option->palette.color(QPalette::Window); + backgroundColor.setAlphaF(StyleConfigData::dolphinViewOpacity() / 100.0); + painter->fillRect(option->rect, backgroundColor); + return true; + } + // define colors const auto &palette(option->palette); const auto background(_helper->frameBackgroundColor(palette));