diff --git a/Config/Appearance.qml b/Config/Appearance.qml index d2bf19e..f78ffc1 100644 --- a/Config/Appearance.qml +++ b/Config/Appearance.qml @@ -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: diff --git a/Config/AppearanceConf.qml b/Config/AppearanceConf.qml index 0debb62..60bab0f 100644 --- a/Config/AppearanceConf.qml +++ b/Config/AppearanceConf.qml @@ -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" diff --git a/Config/Config.qml b/Config/Config.qml index 9d67806..295b8e5 100644 --- a/Config/Config.qml +++ b/Config/Config.qml @@ -48,6 +48,9 @@ Singleton { padding: { scale: appearance.padding.scale }, + deform: { + scale: appearance.deform.scale + }, font: { family: { sans: appearance.font.family.sans, diff --git a/Drawers/Windows.qml b/Drawers/Windows.qml index 4efedf9..460484f 100644 --- a/Drawers/Windows.qml +++ b/Drawers/Windows.qml @@ -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 } diff --git a/Modules/ClipWrapper.qml b/Modules/ClipWrapper.qml index 6802d9a..d9265d0 100644 --- a/Modules/ClipWrapper.qml +++ b/Modules/ClipWrapper.qml @@ -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 { diff --git a/Modules/Content.qml b/Modules/Content.qml index e308a10..f3035d3 100644 --- a/Modules/Content.qml +++ b/Modules/Content.qml @@ -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 diff --git a/Modules/Settings/Categories/Appearance.qml b/Modules/Settings/Categories/Appearance.qml index ddeaf3b..3114b2e 100644 --- a/Modules/Settings/Categories/Appearance.qml +++ b/Modules/Settings/Categories/Appearance.qml @@ -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 diff --git a/Modules/Settings/SettingsIndex.mjs b/Modules/Settings/SettingsIndex.mjs index a56c645..f3afffb 100644 --- a/Modules/Settings/SettingsIndex.mjs +++ b/Modules/Settings/SettingsIndex.mjs @@ -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 { diff --git a/Modules/SysTray/Popouts/AudioPopup.qml b/Modules/SysTray/Popouts/AudioPopup.qml index 5a2f078..5b14d11 100644 --- a/Modules/SysTray/Popouts/AudioPopup.qml +++ b/Modules/SysTray/Popouts/AudioPopup.qml @@ -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 { diff --git a/Modules/Wrapper.qml b/Modules/Wrapper.qml index 00e6f76..8b7f4e9 100644 --- a/Modules/Wrapper.qml +++ b/Modules/Wrapper.qml @@ -8,8 +8,8 @@ import qs.Config Item { id: root - property list animCurve: MaterialEasing.expressiveEffects - property int animLength: MaterialEasing.expressiveEffectsTime + property list 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 { diff --git a/Plugins/ZShell/Blobs/blobshape.cpp b/Plugins/ZShell/Blobs/blobshape.cpp index b6103fd..d284a5e 100644 --- a/Plugins/ZShell/Blobs/blobshape.cpp +++ b/Plugins/ZShell/Blobs/blobshape.cpp @@ -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(newGeometry.x() - oldGeometry.x()); m_pendingDy += static_cast(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(newGeometry.width() - oldGeometry.width()); + m_pendingDh += static_cast(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); } } diff --git a/Plugins/ZShell/Blobs/blobshape.hpp b/Plugins/ZShell/Blobs/blobshape.hpp index aa1d018..f130c23 100644 --- a/Plugins/ZShell/Blobs/blobshape.hpp +++ b/Plugins/ZShell/Blobs/blobshape.hpp @@ -85,6 +85,8 @@ QVector 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] = {}; diff --git a/Plugins/ZShell/Blobs/shaders/blob.frag b/Plugins/ZShell/Blobs/shaders/blob.frag index f9d8503..4f3bd45 100644 --- a/Plugins/ZShell/Blobs/shaders/blob.frag +++ b/Plugins/ZShell/Blobs/shaders/blob.frag @@ -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;