From 4ad71b575db4b67cf5b856f9eda2252f4d0a7e5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Fri, 28 Nov 2014 16:26:27 +0100 Subject: [PATCH] Decoration::client returns a QWeakPointer --- windec/kdecoration2/breezebuttons.cpp | 64 +++++++++++++++++++-------- windec/kdecoration2/breezebuttons.h | 6 +-- windec/kdecoration2/breezedeco.cpp | 46 ++++++++++--------- 3 files changed, 73 insertions(+), 43 deletions(-) diff --git a/windec/kdecoration2/breezebuttons.cpp b/windec/kdecoration2/breezebuttons.cpp index 7bee2805..3944f482 100644 --- a/windec/kdecoration2/breezebuttons.cpp +++ b/windec/kdecoration2/breezebuttons.cpp @@ -84,17 +84,21 @@ static ButtonState stateForButton(Button *decorationButton) return ButtonState::Normal; } -const QImage &ImageProvider::button(Breeze::Button *decorationButton) +QImage ImageProvider::button(Breeze::Button *decorationButton) { auto paletteIt = m_images.begin(); - if (paletteIt == m_images.end() || paletteIt.key() != decorationButton->decoration()->client()->palette()) { - paletteIt = m_images.find(decorationButton->decoration()->client()->palette()); + if (!decorationButton->decoration()) { + return QImage(); + } + auto client = decorationButton->decoration()->client().data(); + if (paletteIt == m_images.end() || paletteIt.key() != client->palette()) { + paletteIt = m_images.find(client->palette()); } if (paletteIt == m_images.end()) { - const QPalette pal = decorationButton->decoration()->client()->palette(); + const QPalette pal = client->palette(); m_images.insert(pal, ImagesForButton()); m_colorSettings.append(ColorSettings(pal)); - paletteIt = m_images.find(decorationButton->decoration()->client()->palette()); + paletteIt = m_images.find(client->palette()); } Q_ASSERT(paletteIt != m_images.end()); @@ -108,7 +112,7 @@ const QImage &ImageProvider::button(Breeze::Button *decorationButton) } Q_ASSERT(it != paletteIt.value().end()); - auto it2 = it.value().find(decorationButton->decoration()->client()->isActive()); + auto it2 = it.value().find(client->isActive()); Q_ASSERT(it2 != it.value().end()); const ButtonState state = stateForButton(decorationButton); @@ -125,8 +129,12 @@ const QImage &ImageProvider::button(Breeze::Button *decorationButton) void ImageProvider::clearCache(Breeze::Button *decorationButton) { auto paletteIt = m_images.begin(); - if (paletteIt == m_images.end() || paletteIt.key() != decorationButton->decoration()->client()->palette()) { - paletteIt = m_images.find(decorationButton->decoration()->client()->palette()); + if (!decorationButton->decoration()) { + return; + } + const QPalette &palette = decorationButton->decoration()->client().data()->palette(); + if (paletteIt == m_images.end() || paletteIt.key() != palette) { + paletteIt = m_images.find(palette); } if (paletteIt == m_images.end()) { return; @@ -139,7 +147,7 @@ void ImageProvider::clearCache(Breeze::Button *decorationButton) paletteIt.value().erase(it); } -const ColorSettings &ImageProvider::colorSettings(const QPalette &pal) const +ColorSettings ImageProvider::colorSettings(const QPalette &pal) const { for (const ColorSettings &colorSettings : m_colorSettings) { if (colorSettings.palette() == pal) { @@ -150,9 +158,12 @@ const ColorSettings &ImageProvider::colorSettings(const QPalette &pal) const return ColorSettings(pal); } -const ColorSettings &ImageProvider::colorSettings(Breeze::Button *decorationButton) const +ColorSettings ImageProvider::colorSettings(Breeze::Button *decorationButton) const { - return colorSettings(decorationButton->decoration()->client()->palette()); + if (!decorationButton->decoration()) { + return colorSettings(QPalette()); + } + return colorSettings(decorationButton->decoration()->client().data()->palette()); } @@ -201,8 +212,12 @@ QImage ImageProvider::renderButton(Breeze::Button *decorationButton) const void ImageProvider::renderCloseButton(QPainter *painter, Breeze::Button *decorationButton) const { - const bool active = decorationButton->decoration()->client()->isActive(); - const QPalette &pal = decorationButton->decoration()->client()->palette(); + if (!decorationButton->decoration()) { + return; + } + auto client = decorationButton->decoration()->client().data(); + const bool active = client->isActive(); + const QPalette &pal = client->palette(); const bool pressed = decorationButton->isPressed(); const bool hovered = decorationButton->isHovered(); const QSize &size = decorationButton->size().toSize(); @@ -246,7 +261,10 @@ void ImageProvider::renderMaximizeButton(QPainter *painter, Breeze::Button *deco void ImageProvider::renderOnAllDesktopsButton(QPainter *painter, Breeze::Button *decorationButton) const { - const bool active = decorationButton->decoration()->client()->isActive(); + if (!decorationButton->decoration()) { + return; + } + const bool active = decorationButton->decoration()->client().data()->isActive(); painter->save(); drawGenericButtonBackground(painter, decorationButton); @@ -287,11 +305,14 @@ void ImageProvider::renderShadeButton(QPainter *painter, Breeze::Button *decorat void ImageProvider::drawGenericButtonBackground(QPainter *painter, Breeze::Button *decorationButton) const { + if (!decorationButton->decoration()) { + return; + } const bool standAlone = decorationButton->isStandAlone(); if (!decorationButton->isPressed() && !decorationButton->isHovered() && !standAlone) { return; } - const QColor baseBackgroundColor = colorSettings(decorationButton).font(decorationButton->decoration()->client()->isActive()); + const QColor baseBackgroundColor = colorSettings(decorationButton).font(decorationButton->decoration()->client().data()->isActive()); drawBackground(painter, decorationButton, QColor(baseBackgroundColor.red(), baseBackgroundColor.green(), baseBackgroundColor.blue(), @@ -341,8 +362,12 @@ void ImageProvider::drawUpArrow(QPainter *painter, Breeze::Button *decorationBut QColor ImageProvider::foregroundColor(Breeze::Button *decorationButton) const { - const ColorSettings &colors = colorSettings(decorationButton->decoration()->client()->palette()); - const bool active = decorationButton->decoration()->client()->isActive(); + if (!decorationButton->decoration()) { + return QColor(); + } + const auto client = decorationButton->decoration()->client().data(); + const ColorSettings &colors = colorSettings(client->palette()); + const bool active = client->isActive(); if (decorationButton->isStandAlone()) { return colors.titleBarColor(active); } @@ -394,9 +419,12 @@ Button::~Button() = default; void Button::paint(QPainter *painter, const QRect &repaintRegion) { Q_UNUSED(repaintRegion) + if (!decoration()) { + return; + } // TODO: optimize based on repaintRegion if (type() == KDecoration2::DecorationButtonType::Menu) { - const QPixmap pixmap = decoration()->client()->icon().pixmap(size().toSize()); + const QPixmap pixmap = decoration()->client().data()->icon().pixmap(size().toSize()); painter->drawPixmap(geometry().center() - QPoint(pixmap.width()/2, pixmap.height()/2), pixmap); } else { painter->drawImage(geometry().topLeft(), ImageProvider::self()->button(this)); diff --git a/windec/kdecoration2/breezebuttons.h b/windec/kdecoration2/breezebuttons.h index e8c51277..11ccd490 100644 --- a/windec/kdecoration2/breezebuttons.h +++ b/windec/kdecoration2/breezebuttons.h @@ -51,7 +51,7 @@ class ImageProvider final public: ~ImageProvider(); static ImageProvider *self(); - const QImage &button(Button *decorationButton); + QImage button(Button *decorationButton); void clearCache(Button *decorationButton); void invalidate(); @@ -68,8 +68,8 @@ private: void drawDownArrow(QPainter *painter, Button *decorationButton, const QPointF &offset = QPointF(0.0, 0.0)) const; void drawUpArrow(QPainter *painter, Button *decorationButton, const QPointF &offset = QPointF(0.0, 0.0)) const; QColor foregroundColor(Button *decorationButton) const; - const ColorSettings &colorSettings(Button *decorationButton) const; - const ColorSettings &colorSettings(const QPalette &pal) const; + ColorSettings colorSettings(Button *decorationButton) const; + ColorSettings colorSettings(const QPalette &pal) const; static ImageProvider *s_self; typedef QHash ImagesForButtonState; typedef QHash ImagesForDecoState; diff --git a/windec/kdecoration2/breezedeco.cpp b/windec/kdecoration2/breezedeco.cpp index 6da0e51c..bbcccca7 100644 --- a/windec/kdecoration2/breezedeco.cpp +++ b/windec/kdecoration2/breezedeco.cpp @@ -63,7 +63,7 @@ void ColorSettings::init(const QPalette &pal) Decoration::Decoration(QObject *parent, const QVariantList &args) : KDecoration2::Decoration(parent, args) - , m_colorSettings(client()->palette()) + , m_colorSettings(client().data()->palette()) , m_leftButtons(nullptr) , m_rightButtons(nullptr) { @@ -92,7 +92,7 @@ void Decoration::init() connect(client().data(), &KDecoration2::DecoratedClient::activeChanged, this, [this]() { update(); }); connect(client().data(), &KDecoration2::DecoratedClient::paletteChanged, this, [this]() { - m_colorSettings.update(client()->palette()); + m_colorSettings.update(client().data()->palette()); update(); } ); @@ -111,8 +111,8 @@ void Decoration::init() void Decoration::updateTitleBar() { auto s = settings(); - const bool maximized = client()->isMaximized(); - const int width = client()->width(); + const bool maximized = client().data()->isMaximized(); + const int width = client().data()->width(); const int height = maximized ? borderTop() : borderTop() - s->smallSpacing(); const int x = maximized ? 0 : s->largeSpacing() / 2; const int y = maximized ? 0 : s->smallSpacing(); @@ -152,20 +152,21 @@ static int borderSize(const QSharedPointer &se void Decoration::recalculateBorders() { auto s = settings(); - const Qt::Edges edges = client()->adjacentScreenEdges(); - int left = client()->isMaximizedHorizontally() || edges.testFlag(Qt::LeftEdge) ? 0 : borderSize(s); - int right = client()->isMaximizedHorizontally() || edges.testFlag(Qt::RightEdge) ? 0 : borderSize(s); + const auto c = client().data(); + const Qt::Edges edges = c->adjacentScreenEdges(); + int left = c->isMaximizedHorizontally() || edges.testFlag(Qt::LeftEdge) ? 0 : borderSize(s); + int right = c->isMaximizedHorizontally() || edges.testFlag(Qt::RightEdge) ? 0 : borderSize(s); QFontMetrics fm(s->font()); - int top = qMax(fm.boundingRect(client()->caption()).height(), s->gridUnit() * 2); + int top = qMax(fm.boundingRect(c->caption()).height(), s->gridUnit() * 2); // padding below top += s->smallSpacing() * 2 + 1; - if (!client()->isMaximized()) { + if (!c->isMaximized()) { // padding above only on maximized top += s->smallSpacing(); } - int bottom = client()->isMaximizedVertically() || edges.testFlag(Qt::BottomEdge) ? 0 : borderSize(s, true); + int bottom = c->isMaximizedVertically() || edges.testFlag(Qt::BottomEdge) ? 0 : borderSize(s, true); setBorders(QMargins(left, top, right, bottom)); const int extSize = s->largeSpacing() / 2; @@ -190,7 +191,7 @@ void Decoration::createButtons() void Decoration::updateButtonPositions() { auto s = settings(); - const int padding = client()->isMaximized() ? 0 : s->smallSpacing(); + const int padding = client().data()->isMaximized() ? 0 : s->smallSpacing(); m_rightButtons->setSpacing(s->smallSpacing()); m_leftButtons->setSpacing(s->smallSpacing()); m_leftButtons->setPos(QPointF(padding, padding)); @@ -205,7 +206,7 @@ void Decoration::paint(QPainter *painter, const QRect &repaintRegion) painter->save(); painter->setRenderHint(QPainter::Antialiasing); painter->setPen(Qt::NoPen); - painter->setBrush(m_colorSettings.frame(client()->isActive())); + painter->setBrush(m_colorSettings.frame(client().data()->isActive())); // clip away the top part painter->save(); painter->setClipRect(0, borderTop(), size().width(), size().height() - borderTop(), Qt::IntersectClip); @@ -219,21 +220,22 @@ void Decoration::paint(QPainter *painter, const QRect &repaintRegion) void Decoration::paintTitleBar(QPainter *painter, const QRect &repaintRegion) { - const bool active = client()->isActive(); + const auto c = client().data(); + const bool active = c->isActive(); const QRect titleRect(QPoint(0, 0), QSize(size().width(), borderTop())); - const QColor titleBarColor(m_colorSettings.titleBarColor(client()->isActive())); + const QColor titleBarColor(m_colorSettings.titleBarColor(c->isActive())); // render a linear gradient on title area QLinearGradient gradient; gradient.setStart(0.0, 0.0); gradient.setFinalStop(0.0, titleRect.height()); - gradient.setColorAt(0.0, titleBarColor.lighter(client()->isActive() ? 120.0 : 100.0)); + gradient.setColorAt(0.0, titleBarColor.lighter(c->isActive() ? 120.0 : 100.0)); gradient.setColorAt(0.8, titleBarColor); gradient.setColorAt(1.0, titleBarColor); gradient.setFinalStop(0.0, titleRect.height()); painter->save(); painter->setBrush(gradient); painter->setPen(Qt::NoPen); - if (client()->isMaximized()) { + if (c->isMaximized()) { painter->drawRect(titleRect); } else { painter->setClipRect(titleRect, Qt::IntersectClip); @@ -247,16 +249,16 @@ void Decoration::paintTitleBar(QPainter *painter, const QRect &repaintRegion) // TODO: should be config option painter->fillRect(0, borderTop() - titleBarSpacer - 1, size().width(), 1, - client()->palette().color(active ? QPalette::Highlight: QPalette::Background)); + c->palette().color(active ? QPalette::Highlight: QPalette::Background)); } // draw title bar spacer - painter->fillRect(0, borderTop() - titleBarSpacer, size().width(), titleBarSpacer, client()->palette().color(QPalette::Background)); + painter->fillRect(0, borderTop() - titleBarSpacer, size().width(), titleBarSpacer, c->palette().color(QPalette::Background)); // draw caption painter->setFont(s->font()); const QRect cR = captionRect(); - const QString caption = painter->fontMetrics().elidedText(client()->caption(), Qt::ElideMiddle, cR.width()); - painter->setPen(m_colorSettings.font(client()->isActive())); + const QString caption = painter->fontMetrics().elidedText(c->caption(), Qt::ElideMiddle, cR.width()); + painter->setPen(m_colorSettings.font(c->isActive())); painter->drawText(cR, Qt::AlignCenter | Qt::TextSingleLine, caption); // draw all buttons @@ -266,7 +268,7 @@ void Decoration::paintTitleBar(QPainter *painter, const QRect &repaintRegion) int Decoration::captionHeight() const { - return borderTop() - settings()->smallSpacing() * (client()->isMaximized() ? 2 : 3) - 1; + return borderTop() - settings()->smallSpacing() * (client().data()->isMaximized() ? 2 : 3) - 1; } QRect Decoration::captionRect() const @@ -274,7 +276,7 @@ QRect Decoration::captionRect() const const int leftOffset = m_leftButtons->geometry().x() + m_leftButtons->geometry().width(); const int rightOffset = size().width() - m_rightButtons->geometry().x(); const int offset = qMax(leftOffset, rightOffset); - const int yOffset = client()->isMaximized() ? 0 : settings()->smallSpacing(); + const int yOffset = client().data()->isMaximized() ? 0 : settings()->smallSpacing(); // below is the spacer return QRect(offset, yOffset, size().width() - offset * 2, captionHeight()); }