Multiple fixes regarding blobs #66

Merged
zach merged 2 commits from blob-fix into main 2026-04-19 21:41:43 +02:00
13 changed files with 74 additions and 98 deletions
+1
View File
@@ -4,6 +4,7 @@ import Quickshell
Singleton {
readonly property AppearanceConf.Anim anim: Config.appearance.anim
readonly property AppearanceConf.Deform deform: Config.appearance.deform
readonly property AppearanceConf.FontStuff font: Config.appearance.font
readonly property AppearanceConf.Padding padding: Config.appearance.padding
// Literally just here to shorten accessing stuff :woe:
+5
View File
@@ -3,6 +3,8 @@ import Quickshell.Io
JsonObject {
property Anim anim: Anim {
}
property Deform deform: Deform {
}
property FontStuff font: FontStuff {
}
property Padding padding: Padding {
@@ -43,6 +45,9 @@ JsonObject {
property real scale: 1
property int small: 200 * scale
}
component Deform: JsonObject {
property real scale: 1
}
component FontFamily: JsonObject {
property string clock: "Rubik"
property string material: "Material Symbols Rounded"
+3
View File
@@ -48,6 +48,9 @@ Singleton {
padding: {
scale: appearance.padding.scale
},
deform: {
scale: appearance.deform.scale
},
font: {
family: {
sans: appearance.font.family.sans,
+10 -9
View File
@@ -170,7 +170,7 @@ Variants {
PanelBg {
id: dashBg
deformAmount: 0
deformAmount: 0.15 * Config.appearance.deform.scale
panel: panels.dashboard
radius: Appearance.rounding.normal
}
@@ -178,7 +178,7 @@ Variants {
PanelBg {
id: launcherBg
deformAmount: 0
deformAmount: 0.15 * Config.appearance.deform.scale
panel: panels.launcher
radius: Appearance.rounding.smallest + 5
}
@@ -187,7 +187,7 @@ Variants {
id: sidebarBg
bottomLeftRadius: 0
deformAmount: 0
deformAmount: 0.1 * Config.appearance.deform.scale
exclude: panels.sidebar.offsetscale > 0.08 ? [] : [utilsBg]
implicitHeight: panel.height * (1 / rawDeformMatrix.m22) + 2
panel: panels.sidebar
@@ -196,7 +196,7 @@ Variants {
PanelBg {
id: osdBg
deformAmount: 0
deformAmount: 0.1 * Config.appearance.deform.scale
panel: panels.osd
radius: 20
}
@@ -210,7 +210,7 @@ Variants {
PanelBg {
id: utilsBg
deformAmount: panels.sidebar.visible ? 0 : 0
deformAmount: panels.sidebar.visible ? (0.1 * Config.appearance.deform.scale) : (0.1 * Config.appearance.deform.scale)
exclude: panels.sidebar.offsetScale > 0.08 ? [] : [sidebarBg]
panel: panels.utilities
topLeftRadius: 0
@@ -219,15 +219,16 @@ Variants {
PanelBg {
id: popoutBg
deformAmount: 0
deformAmount: 0.15 * Config.appearance.deform.scale
implicitWidth: panels.popouts.width
panel: panels.popoutsWrapper
radius: (panels.popouts.currentName.startsWith("audio") || panels.popouts.currentName.startsWith("updates")) ? Appearance.rounding.normal : Appearance.rounding.smallest
}
PanelBg {
id: resourcesBg
deformAmount: 0
deformAmount: 0.15 * Config.appearance.deform.scale
panel: panels.resources
radius: Appearance.rounding.normal
}
@@ -235,7 +236,7 @@ Variants {
PanelBg {
id: settingsBg
deformAmount: 0
deformAmount: 0.1 * Config.appearance.deform.scale
panel: panels.settings
radius: Appearance.rounding.large
topLeftRadius: Appearance.rounding.large + Appearance.padding.smaller
@@ -245,7 +246,7 @@ Variants {
PanelBg {
id: dockBg
deformAmount: 0
deformAmount: 0.15 * Config.appearance.deform.scale
panel: panels.dock
radius: Appearance.rounding.normal
}
+2 -2
View File
@@ -26,8 +26,8 @@ Item {
Behavior on offsetScale {
Anim {
duration: MaterialEasing.expressiveEffectsTime
easing.bezierCurve: MaterialEasing.expressiveEffects
duration: Appearance.anim.durations.expressiveDefaultSpatial
easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial
}
}
Behavior on x {
+4 -3
View File
@@ -101,9 +101,10 @@ Item {
readonly property bool shouldBeActive: root.popouts.currentName === name
active: false
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: 5
// anchors.horizontalCenter: parent.horizontalCenter
// anchors.top: parent.top
// anchors.topMargin: 5
anchors.centerIn: parent
opacity: 0
scale: 0.8
+13 -3
View File
@@ -57,6 +57,16 @@ SettingsPage {
setting: "scale"
step: 0.1
}
Separator {
}
SettingSpinBox {
name: "Deform animation scale"
object: Config.appearance.deform
setting: "scale"
step: 0.1
}
}
SettingsSection {
@@ -118,9 +128,9 @@ SettingsPage {
}
SettingSpinBox {
name: "Session GIF speed"
max: 5
min: 0
name: "Session GIF speed"
object: Config.appearance.anim
setting: "sessionGifSpeed"
step: 0.1
@@ -144,9 +154,9 @@ SettingsPage {
}
SettingSpinBox {
name: "Base opacity"
max: 1
min: 0
name: "Base opacity"
object: Config.appearance.transparency
setting: "base"
step: 0.05
@@ -156,9 +166,9 @@ SettingsPage {
}
SettingSpinBox {
name: "Layer opacity"
max: 1
min: 0
name: "Layer opacity"
object: Config.appearance.transparency
setting: "layers"
step: 0.05
+8 -1
View File
@@ -815,7 +815,14 @@ export const settingsIndex = [
category: "appearance",
categoryName: "Appearance",
section: "Scale",
keywords: ["animation", "speed", "duration"],
keywords: ["animation", "speed", "duration", "scale"],
},
{
name: "Deform animation scale",
category: "appearance",
categoryName: "Appearance",
section: "Scale",
keywords: ["animation", "deform", "scale"],
},
// Fonts section
{
+14 -3
View File
@@ -24,6 +24,7 @@ Item {
CustomRect {
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
color: DynamicColors.tPalette.m3surfaceContainer
implicitHeight: parent.implicitHeight
radius: Appearance.rounding.small
@@ -31,8 +32,8 @@ Item {
Behavior on implicitHeight {
Anim {
duration: MaterialEasing.emphasizedDecelTime
easing.bezierCurve: MaterialEasing.emphasized
duration: MaterialEasing.expressiveEffectsTime
easing.bezierCurve: MaterialEasing.expressiveEffects
}
}
}
@@ -40,7 +41,11 @@ Item {
ColumnLayout {
id: layout
anchors.centerIn: parent
// anchors.centerIn: parent
anchors.left: parent.left
anchors.margins: Appearance.padding.small
anchors.right: parent.right
anchors.top: parent.top
implicitWidth: stack.currentItem ? stack.currentItem.childrenRect.height : 0
spacing: 12
@@ -98,6 +103,12 @@ Item {
Layout.preferredHeight: currentIndex === 0 ? vol.childrenRect.height : dev.childrenRect.height
currentIndex: 0
// Behavior on Layout.preferredHeight {
// Anim {
// duration: MaterialEasing.expressiveEffectsTime
// easing.bezierCurve: MaterialEasing.expressiveEffects
// }
// }
Behavior on currentIndex {
SequentialAnimation {
ParallelAnimation {
+5 -5
View File
@@ -8,8 +8,8 @@ import qs.Config
Item {
id: root
property list<real> animCurve: MaterialEasing.expressiveEffects
property int animLength: MaterialEasing.expressiveEffectsTime
property list<real> animCurve: Appearance.anim.curves.expressiveDefaultSpatial
property int animLength: Appearance.anim.durations.expressiveDefaultSpatial
readonly property alias content: content
readonly property Item current: (content.item as Content)?.current ?? null
property real currentCenter
@@ -73,9 +73,9 @@ Item {
Comp {
id: content
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
// anchors.centerIn: parent
// anchors.horizontalCenter: parent.horizontalCenter
// anchors.top: parent.top
anchors.centerIn: parent
shouldBeActive: root.hasCurrent && !root.detachedMode
sourceComponent: Content {
+7 -3
View File
@@ -72,11 +72,15 @@ void BlobShape::geometryChange(const QRectF& newGeometry, const QRectF& oldGeome
// Accumulate sub-pixel drift so slow movements don't desync the shader
m_pendingDx += static_cast<float>(newGeometry.x() - oldGeometry.x());
m_pendingDy += static_cast<float>(newGeometry.y() - oldGeometry.y());
const auto dw = std::abs(newGeometry.width() - oldGeometry.width());
const auto dh = std::abs(newGeometry.height() - oldGeometry.height());
if (std::abs(m_pendingDx) > 0.5f || std::abs(m_pendingDy) > 0.5f || dw > 0.5 || dh > 0.5) {
m_pendingDw += static_cast<float>(newGeometry.width() - oldGeometry.width());
m_pendingDh += static_cast<float>(newGeometry.height() - oldGeometry.height());
if (std::abs(m_pendingDx) > 0.5f || std::abs(m_pendingDy) > 0.5f ||
std::abs(m_pendingDw) > 0.5f || std::abs(m_pendingDh) > 0.5f) {
m_pendingDx = 0;
m_pendingDy = 0;
m_pendingDw = 0;
m_pendingDh = 0;
m_group->markShapeDirty(this);
}
}
+2
View File
@@ -85,6 +85,8 @@ QVector<BlobRectData> m_cachedRects;
int m_cachedMyIndex = -2;
float m_pendingDx = 0;
float m_pendingDy = 0;
float m_pendingDw = 0;
float m_pendingDh = 0;
bool m_cachedHasInverted = false;
float m_cachedInvertedRadius = 0;
float m_cachedInvertedOuter[4] = {};
-69
View File
@@ -138,75 +138,6 @@ void main() {
d *= scale;
}
// Rect-to-rect edge sinks: track the same edge of neighboring rects
{
float rectSinkValue = 0.0;
vec2 iHalf = sh.xy;
float preOff = smoothFactor * (1.0 / 6.0);
for (int j = 0; j < rectCount; j++) {
if (j == i)
continue;
vec4 jRect = rectData[j * 5];
vec4 jProps = rectData[j * 5 + 1];
vec2 jSh = rectData[j * 5 + 3].xy;
vec2 jCtr = jRect.xy + jProps.yz;
// Per-edge containment: the other rect's full span on the
// perpendicular axis must be inside this rect for that edge.
bool hInside = (jCtr.y - jSh.y) >= (center.y - iHalf.y) &&
(jCtr.y + jSh.y) <= (center.y + iHalf.y);
bool vInside = (jCtr.x - jSh.x) >= (center.x - iHalf.x) &&
(jCtr.x + jSh.x) <= (center.x + iHalf.x);
// Top/Bottom: other rect's height must be inside this rect
float topPen =
hInside ? clamp((center.y - iHalf.y) - (jCtr.y - jSh.y) - preOff,
0.0, smoothFactor)
: 0.0;
float botPen =
hInside ? clamp((jCtr.y + jSh.y) - (center.y + iHalf.y) - preOff,
0.0, smoothFactor)
: 0.0;
// Left/Right: other rect's width must be inside this rect
float leftPen =
vInside ? clamp((center.x - iHalf.x) - (jCtr.x - jSh.x) - preOff,
0.0, smoothFactor)
: 0.0;
float rightPen =
vInside ? clamp((jCtr.x + jSh.x) - (center.x + iHalf.x) - preOff,
0.0, smoothFactor)
: 0.0;
// Lateral distance from pixel to other rect's extent along each edge
float hLat = max(abs(pixel.x - jCtr.x) - jSh.x, 0.0);
float vLat = max(abs(pixel.y - jCtr.y) - jSh.y, 0.0);
// Perpendicular proximity: full strength at edge, fade inside
float topZone =
1.0 - smoothstep(center.y - iHalf.y,
center.y - iHalf.y + smoothFactor, pixel.y);
float botZone = smoothstep(center.y + iHalf.y - smoothFactor,
center.y + iHalf.y, pixel.y);
float leftZone =
1.0 - smoothstep(center.x - iHalf.x,
center.x - iHalf.x + smoothFactor, pixel.x);
float rightZone = smoothstep(center.x + iHalf.x - smoothFactor,
center.x + iHalf.x, pixel.x);
float s = smoothFactor * 2.0;
float sink = max(max(topPen * smoothstep(s, 0.0, hLat) * topZone,
botPen * smoothstep(s, 0.0, hLat) * botZone),
max(leftPen * smoothstep(s, 0.0, vLat) * leftZone,
rightPen * smoothstep(s, 0.0, vLat) * rightZone));
rectSinkValue = max(rectSinkValue, sink);
}
d -= rectSinkValue;
}
mergedSdf = smin(mergedSdf, d, smoothFactor);
if (d < smoothFactor && d < minDist) {
minDist = d;