From 4484586a4d35f4a5e7a89a3ee4465701c3e3c35e Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Wed, 20 May 2026 12:47:14 +0000 Subject: [PATCH] v2: Fix rendering with scale factors less than 100% It looks like FrameSvg rendering breaks with scale factors less than 100%. So, clamp the device pixel ratio for svgs to make sure that FrameSvgs fill the decoration as expected. BUG: 520272 (cherry picked from commit 4e4853bef948adf2af16fa858b58b87bd9e11455) Co-authored-by: Vlad Zahorodnii --- v2/decoration.cpp | 29 +++++++++++++++-------------- v2/decorationbutton.cpp | 9 +++++---- v2/util.h | 24 ++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 18 deletions(-) create mode 100644 v2/util.h diff --git a/v2/decoration.cpp b/v2/decoration.cpp index f12bda1..5275f21 100644 --- a/v2/decoration.cpp +++ b/v2/decoration.cpp @@ -10,6 +10,7 @@ #include "decorationbuttongroup.h" #include "decorationtheme.h" #include "decorationthemeprovider.h" +#include "util.h" #include #include @@ -67,43 +68,43 @@ bool Decoration::init() m_auroraerc = KSharedConfig::openConfig(QStringLiteral("auroraerc")); updateButtonSizeFactor(); - const qreal devicePixelRatio = window()->scale(); + const qreal svgDevicePixelRatio = frameSvgScale(window()->scale()); m_decoration = std::make_unique(); m_decoration->setImagePath(m_theme->decorationPath()); m_decoration->setElementPrefix(QStringLiteral("decoration")); m_decoration->setEnabledBorders(KSvg::FrameSvg::AllBorders); - m_decoration->setDevicePixelRatio(devicePixelRatio); + m_decoration->setDevicePixelRatio(svgDevicePixelRatio); m_decorationInactive = std::make_unique(); m_decorationInactive->setImagePath(m_theme->decorationPath()); m_decorationInactive->setElementPrefix(m_decoration->hasElementPrefix(QStringLiteral("decoration-inactive")) ? QStringLiteral("decoration-inactive") : m_decoration->prefix()); m_decorationInactive->setEnabledBorders(KSvg::FrameSvg::AllBorders); - m_decorationInactive->setDevicePixelRatio(devicePixelRatio); + m_decorationInactive->setDevicePixelRatio(svgDevicePixelRatio); m_decorationMaximized = std::make_unique(); m_decorationMaximized->setImagePath(m_theme->decorationPath()); m_decorationMaximized->setElementPrefix(m_decoration->hasElementPrefix(QStringLiteral("decoration-maximized")) ? QStringLiteral("decoration-maximized") : m_decoration->prefix()); m_decorationMaximized->setEnabledBorders(KSvg::FrameSvg::NoBorder); - m_decorationMaximized->setDevicePixelRatio(devicePixelRatio); + m_decorationMaximized->setDevicePixelRatio(svgDevicePixelRatio); m_decorationMaximizedInactive = std::make_unique(); m_decorationMaximizedInactive->setImagePath(m_theme->decorationPath()); m_decorationMaximizedInactive->setElementPrefix(m_decorationInactive->hasElementPrefix(QStringLiteral("decoration-maximized-inactive")) ? QStringLiteral("decoration-maximized-inactive") : m_decorationMaximized->prefix()); m_decorationMaximizedInactive->setEnabledBorders(KSvg::FrameSvg::NoBorder); - m_decorationMaximizedInactive->setDevicePixelRatio(devicePixelRatio); + m_decorationMaximizedInactive->setDevicePixelRatio(svgDevicePixelRatio); if (m_decoration->hasElementPrefix(QStringLiteral("innerborder"))) { m_innerBorder = std::make_unique(); m_innerBorder->setImagePath(m_theme->decorationPath()); m_innerBorder->setElementPrefix(QStringLiteral("innerborder")); - m_innerBorder->setDevicePixelRatio(devicePixelRatio); + m_innerBorder->setDevicePixelRatio(svgDevicePixelRatio); } if (m_decoration->hasElementPrefix(QStringLiteral("innerborder-inactive"))) { m_innerBorderInactive = std::make_unique(); m_innerBorderInactive->setImagePath(m_theme->decorationPath()); m_innerBorderInactive->setElementPrefix(QStringLiteral("innerborder-inactive")); - m_innerBorderInactive->setDevicePixelRatio(devicePixelRatio); + m_innerBorderInactive->setDevicePixelRatio(svgDevicePixelRatio); } if (m_decoration->hasElementPrefix(QStringLiteral("mask"))) { @@ -323,18 +324,18 @@ void Decoration::onWindowCaptionChanged() void Decoration::onWindowScaleChanged() { - const qreal devicePixelRatio = window()->scale(); + const qreal svgDevicePixelRatio = frameSvgScale(window()->scale()); - m_decoration->setDevicePixelRatio(devicePixelRatio); - m_decorationInactive->setDevicePixelRatio(devicePixelRatio); - m_decorationMaximized->setDevicePixelRatio(devicePixelRatio); - m_decorationMaximizedInactive->setDevicePixelRatio(devicePixelRatio); + m_decoration->setDevicePixelRatio(svgDevicePixelRatio); + m_decorationInactive->setDevicePixelRatio(svgDevicePixelRatio); + m_decorationMaximized->setDevicePixelRatio(svgDevicePixelRatio); + m_decorationMaximizedInactive->setDevicePixelRatio(svgDevicePixelRatio); if (m_innerBorder) { - m_innerBorder->setDevicePixelRatio(devicePixelRatio); + m_innerBorder->setDevicePixelRatio(svgDevicePixelRatio); } if (m_innerBorderInactive) { - m_innerBorderInactive->setDevicePixelRatio(devicePixelRatio); + m_innerBorderInactive->setDevicePixelRatio(svgDevicePixelRatio); } } diff --git a/v2/decorationbutton.cpp b/v2/decorationbutton.cpp index 445d273..75a1040 100644 --- a/v2/decorationbutton.cpp +++ b/v2/decorationbutton.cpp @@ -5,6 +5,7 @@ */ #include "decorationbutton.h" +#include "util.h" #include @@ -242,7 +243,7 @@ SvgDecorationButton::SvgDecorationButton(KDecoration3::DecorationButtonType type : DecorationButton(type, decoration, parent) { connect(decoration->window(), &KDecoration3::DecoratedWindow::scaleChanged, this, [this, decoration]() { - m_svgs.setDevicePixelRatio(decoration->window()->scale()); + m_svgs.setDevicePixelRatio(frameSvgScale(decoration->window()->scale())); }); connect(decoration->window(), &KDecoration3::DecoratedWindow::activeChanged, this, &SvgDecorationButton::updateFrame); @@ -254,7 +255,7 @@ SvgDecorationButton::SvgDecorationButton(KDecoration3::DecorationButtonType type void SvgDecorationButton::setImagePath(const QString &path, const QSizeF &implicitSize) { - m_svgs = SvgFrameSet::from(path, implicitSize, decoration()->window()->scale()); + m_svgs = SvgFrameSet::from(path, implicitSize, frameSvgScale(decoration()->window()->scale())); updateFrame(); setGeometry(QRectF(QPointF(0, 0), implicitSize)); @@ -313,7 +314,7 @@ MaximizeDecorationButton::MaximizeDecorationButton(KDecoration3::Decoration *dec : DecorationButton(KDecoration3::DecorationButtonType::Maximize, decoration, parent) { connect(decoration->window(), &KDecoration3::DecoratedWindow::scaleChanged, this, [this, decoration]() { - const qreal devicePixelRatio = decoration->window()->scale(); + const qreal devicePixelRatio = frameSvgScale(decoration->window()->scale()); m_maximize.setDevicePixelRatio(devicePixelRatio); if (m_restore) { @@ -336,7 +337,7 @@ MaximizeDecorationButton::MaximizeDecorationButton(KDecoration3::Decoration *dec void MaximizeDecorationButton::setImagePath(const QString &maximizeImagePath, const QString &restoreImagePath, const QSizeF &implicitSize) { - const qreal devicePixelRatio = decoration()->window()->scale(); + const qreal devicePixelRatio = frameSvgScale(decoration()->window()->scale()); m_maximize = SvgFrameSet::from(maximizeImagePath, implicitSize, devicePixelRatio); if (!restoreImagePath.isEmpty()) { diff --git a/v2/util.h b/v2/util.h new file mode 100644 index 0000000..b724e48 --- /dev/null +++ b/v2/util.h @@ -0,0 +1,24 @@ +/* + SPDX-FileCopyrightText: 2026 Vlad Zahorodnii + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#pragma once + +#include + +namespace Aurorae +{ + +static inline qreal frameSvgScale(qreal scale) +{ + // FrameSvg rendering breaks with scale factors less than 100%. + if (scale < 1) { + return 1; + } else { + return scale; + } +} + +} -- 2.54.0