Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to setBlurRegion API to re-enable titlebar blur for plasma 5.25 #190

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion kdecoration/lightly.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
]
},
"org.kde.kdecoration2": {
"blur": true,
"kcmodule": true,
"recommendedBorderSize": "None"
}
Expand Down
119 changes: 88 additions & 31 deletions kdecoration/lightlydecoration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ namespace Lightly

reconfigure();
updateTitleBar();
updateBlur();
auto s = settings();
connect(s.data(), &KDecoration2::DecorationSettings::borderSizeChanged, this, &Decoration::recalculateBorders);

Expand Down Expand Up @@ -280,9 +281,12 @@ namespace Lightly
);

connect(c, &KDecoration2::DecoratedClient::activeChanged, this, &Decoration::updateAnimationState);
connect(c, &KDecoration2::DecoratedClient::activeChanged, this, &Decoration::updateBlur);
connect(c, &KDecoration2::DecoratedClient::widthChanged, this, &Decoration::updateTitleBar);
connect(c, &KDecoration2::DecoratedClient::maximizedChanged, this, &Decoration::updateTitleBar);

connect(c, &KDecoration2::DecoratedClient::sizeChanged, this, &Decoration::updateBlur); //recalculate blur region on resize

connect(c, &KDecoration2::DecoratedClient::widthChanged, this, &Decoration::updateButtonsGeometry);
connect(c, &KDecoration2::DecoratedClient::maximizedChanged, this, &Decoration::updateButtonsGeometry);
connect(c, &KDecoration2::DecoratedClient::adjacentScreenEdgesChanged, this, &Decoration::updateButtonsGeometry);
Expand All @@ -292,6 +296,69 @@ namespace Lightly
createShadow();
}

//________________________________________________________________
void Decoration::updateBlur()
{
auto c = client().data();
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() );
} else {
this->setOpaque(false);
}

calculateWindowAndTitleBarShapes(true);
this->setBlurRegion(QRegion(m_windowPath->toFillPolygon().toPolygon()));
}

//________________________________________________________________
void Decoration::calculateWindowAndTitleBarShapes(const bool windowShapeOnly)
{
auto c = client().data();
auto s = settings();

if (!windowShapeOnly || c->isShaded()) {
// set titleBar geometry and path
m_titleRect = QRect(QPoint(0, 0), QSize(size().width(), borderTop()));
m_titleBarPath->clear(); // clear the path for subsequent calls to this function
if (isMaximized() || !s->isAlphaChannelSupported()) {
m_titleBarPath->addRect(m_titleRect);

} else if (c->isShaded()) {
m_titleBarPath->addRoundedRect(m_titleRect, m_internalSettings->cornerRadius(), m_internalSettings->cornerRadius());

} else {
QPainterPath clipRect;
clipRect.addRect(m_titleRect);

// the rect is made a little bit larger to be able to clip away the rounded corners at the bottom and sides
m_titleBarPath->addRoundedRect(m_titleRect.adjusted(
isLeftEdge() ? -m_internalSettings->cornerRadius():0,
isTopEdge() ? -m_internalSettings->cornerRadius():0,
isRightEdge() ? m_internalSettings->cornerRadius():0,
m_internalSettings->cornerRadius()),
m_internalSettings->cornerRadius(),
m_internalSettings->cornerRadius());

*m_titleBarPath = m_titleBarPath->intersected(clipRect);
}
}

// set windowPath
m_windowPath->clear(); // clear the path for subsequent calls to this function
if (!c->isShaded()) {
if (s->isAlphaChannelSupported() && !isMaximized())
m_windowPath->addRoundedRect(rect(), m_internalSettings->cornerRadius(), m_internalSettings->cornerRadius());
else
m_windowPath->addRect(rect());

} else {
*m_windowPath = *m_titleBarPath;
}
}

//________________________________________________________________
void Decoration::updateTitleBar()
{
Expand Down Expand Up @@ -387,6 +454,8 @@ namespace Lightly
if( hasNoBorders() && m_internalSettings->drawSizeGrip() ) createSizeGrip();
else deleteSizeGrip();

updateBlur();

}

//________________________________________________________________
Expand Down Expand Up @@ -523,6 +592,8 @@ namespace Lightly
auto c = client().data();
auto s = settings();

calculateWindowAndTitleBarShapes();

// paint background
if( !c->isShaded() )
{
Expand Down Expand Up @@ -562,9 +633,8 @@ namespace Lightly
void Decoration::paintTitleBar(QPainter *painter, const QRect &repaintRegion)
{
const auto c = client().data();
const QRect titleRect(QPoint(0, 0), QSize(size().width(), borderTop()));

if ( !titleRect.intersects(repaintRegion) ) return;
if ( !m_titleRect.intersects(repaintRegion) ) return;

painter->save();
painter->setPen(Qt::NoPen);
Expand All @@ -574,7 +644,7 @@ namespace Lightly
{

const QColor titleBarColor( this->titleBarColor() );
QLinearGradient gradient( 0, 0, 0, titleRect.height() );
QLinearGradient gradient( 0, 0, 0, m_titleRect.height() );
gradient.setColorAt(0.0, titleBarColor.lighter( 120 ) );
gradient.setColorAt(0.8, titleBarColor);
painter->setBrush(gradient);
Expand All @@ -586,37 +656,24 @@ namespace Lightly
}

auto s = settings();
if( isMaximized() || !s->isAlphaChannelSupported() )
{

painter->drawRect(titleRect);

// top highlight
if( qGray(this->titleBarColor().rgb()) < 130 && m_internalSettings->drawHighlight() ) {
painter->setPen(QColor(255, 255, 255, 30));
painter->drawLine(titleRect.topLeft(), titleRect.topRight());
}
painter->drawPath(*m_titleBarPath);

} else if( c->isShaded() ) {
// top highlight
if( qGray(this->titleBarColor().rgb()) < 130 && m_internalSettings->drawHighlight() ) {
if( isMaximized() || !s->isAlphaChannelSupported() ) {

painter->drawRoundedRect(titleRect, m_internalSettings->cornerRadius(), m_internalSettings->cornerRadius());
painter->setPen(QColor(255, 255, 255, 30));
painter->drawLine(m_titleRect.topLeft(), m_titleRect.topRight());

} else {
} else if (!c->isShaded()) {

QRect copy ( m_titleRect.adjusted(
isLeftEdge() ? -m_internalSettings->cornerRadius():0,
isTopEdge() ? -m_internalSettings->cornerRadius():0,
isRightEdge() ? m_internalSettings->cornerRadius():0,
m_internalSettings->cornerRadius()) );

painter->setClipRect(titleRect, Qt::IntersectClip);

// the rect is made a little bit larger to be able to clip away the rounded corners at the bottom and sides
QRect copy ( titleRect.adjusted(
isLeftEdge() ? -m_internalSettings->cornerRadius():0,
isTopEdge() ? -m_internalSettings->cornerRadius():0,
isRightEdge() ? m_internalSettings->cornerRadius():0,
m_internalSettings->cornerRadius()) );


painter->drawRoundedRect(copy, m_internalSettings->cornerRadius(), m_internalSettings->cornerRadius());

// top highlight
if( qGray(this->titleBarColor().rgb()) < 130 && m_internalSettings->drawHighlight() ) {
QPixmap pix = QPixmap( copy.width(), copy.height() );
pix.fill( Qt::transparent );

Expand All @@ -631,8 +688,8 @@ namespace Lightly
p.drawRoundedRect(copy.adjusted(0, 1, 0, 0), m_internalSettings->cornerRadius(), m_internalSettings->cornerRadius());

painter->drawPixmap(copy, pix);
}

}
}

const QColor outlineColor( this->outlineColor() );
Expand All @@ -642,7 +699,7 @@ namespace Lightly
painter->setRenderHint( QPainter::Antialiasing, false );
painter->setBrush( Qt::NoBrush );
painter->setPen( outlineColor );
painter->drawLine( titleRect.bottomLeft(), titleRect.bottomRight() );
painter->drawLine( m_titleRect.bottomLeft(), m_titleRect.bottomRight() );
}

painter->restore();
Expand Down
20 changes: 20 additions & 0 deletions kdecoration/lightlydecoration.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <KDecoration2/DecoratedClient>
#include <KDecoration2/DecorationSettings>

#include <QPainterPath>
#include <QPalette>
#include <QVariant>

Expand Down Expand Up @@ -98,12 +99,22 @@ namespace Lightly
inline bool hideTitleBar() const;
//@}

std::shared_ptr<QPainterPath> titleBarPath()
{
return m_titleBarPath;
}
std::shared_ptr<QPainterPath> windowPath()
{
return m_windowPath;
}

public Q_SLOTS:
void init() override;

private Q_SLOTS:
void reconfigure();
void recalculateBorders();
void updateBlur();
void updateButtonsGeometry();
void updateButtonsGeometryDelayed();
void updateTitleBar();
Expand All @@ -116,6 +127,7 @@ namespace Lightly
QPair<QRect,Qt::Alignment> captionRect() const;

void createButtons();
void calculateWindowAndTitleBarShapes(const bool windowShapeOnly = false);
void paintTitleBar(QPainter *painter, const QRect &repaintRegion);
void createShadow();

Expand Down Expand Up @@ -148,6 +160,14 @@ namespace Lightly
//* active state change opacity
qreal m_opacity = 0;

//* Rectangular area of titlebar without clipped corners
QRect m_titleRect;

//* Exact titlebar path, with clipped rounded corners
std::shared_ptr<QPainterPath> m_titleBarPath = std::make_shared<QPainterPath>();
//* Exact window path, with clipped rounded corners
std::shared_ptr<QPainterPath> m_windowPath = std::make_shared<QPainterPath>();

};

bool Decoration::hasBorders() const
Expand Down