Wallpaper: cool fade in transition via shader

This commit is contained in:
LemmyCook 2025-08-29 16:26:48 -04:00
parent 61d13a6cab
commit 63e90a5c17
4 changed files with 107 additions and 4 deletions

View file

@ -5,6 +5,7 @@ import qs.Commons
import qs.Services
Variants {
id: backgroundVariants
model: Quickshell.screens
delegate: Loader {
@ -14,6 +15,25 @@ Variants {
active: Settings.isLoaded && WallpaperService.getWallpaper(modelData.name)
sourceComponent: PanelWindow {
id: root
readonly property real transitionDuration: Settings.data.wallpaper.transitionDuration
readonly property real transitionType: Settings.data.wallpaper.transitionType
property string servicedWallpaper: WallpaperService.getWallpaper(modelData.name)
onServicedWallpaperChanged: {
if (servicedWallpaper && servicedWallpaper !== currentWallpaper.source) {
if (Settings.data.wallpaper.transitionType == 'fade') {
setWallpaperWithTransition(servicedWallpaper)
} else {
setWallpaperImmediate(servicedWallpaper)
}
}
}
// Internal state management
property bool transitioning: false
property real fadeValue: 0.0
color: Color.transparent
screen: modelData
@ -29,12 +49,74 @@ Variants {
}
Image {
id: currentWallpaper
anchors.fill: parent
fillMode: Image.PreserveAspectCrop
source: WallpaperService.getWallpaper(modelData.name)
source: ""
cache: true
smooth: true
mipmap: false
visible: false
}
Image {
id: nextWallpaper
anchors.fill: parent
fillMode: Image.PreserveAspectCrop
source: ""
cache: true
smooth: true
mipmap: false
visible: false
}
ShaderEffect {
id: shaderEffect
anchors.fill: parent
property variant source1: currentWallpaper
property variant source2: nextWallpaper
property real fade: fadeValue
fragmentShader: Qt.resolvedUrl("../../Shaders/qsb/mix_images.frag.qsb")
}
// Animation for the fade value
NumberAnimation {
id: fadeAnimation
target: root
property: "fadeValue"
from: 0.0
to: 1.0
duration: Settings.data.wallpaper.transitionDuration
easing.type: Easing.InOutQuad
onFinished: {
// Swap images after transition completes
currentWallpaper.source = nextWallpaper.source
fadeValue = 0.0
transitioning = false
}
}
function startTransition() {
if (!transitioning && nextWallpaper.source != currentWallpaper.source) {
transitioning = true
fadeAnimation.start()
}
}
function setWallpaperImmediate(source) {
currentWallpaper.source = source
nextWallpaper.source = source
fadeValue = 0.0
transitioning = false
}
function setWallpaperWithTransition(source) {
if (source != currentWallpaper.source) {
nextWallpaper.source = source
startTransition()
}
}
}
}

View file

@ -163,9 +163,8 @@ Singleton {
changeWallpaper(screenName, randomPath)
}
}
}
else {
// Pick a random wallpaper for all screens
} else {
// Pick a random wallpaper common to all screens
// We can use any screenName here, so we just pick the primary one.
var wallpaperList = getWallpapersList(Screen.name)
if (wallpaperList.length > 0) {

View file

@ -0,0 +1,22 @@
#version 450
layout(location = 0) in vec2 qt_TexCoord0;
layout(location = 0) out vec4 fragColor;
layout(binding = 1) uniform sampler2D source1;
layout(binding = 2) uniform sampler2D source2;
layout(std140, binding = 0) uniform buf {
mat4 qt_Matrix;
float qt_Opacity;
float fade;
};
void main() {
vec4 color1 = texture(source1, qt_TexCoord0);
vec4 color2 = texture(source2, qt_TexCoord0);
// Smooth cross-fade using smoothstep for better visual quality
float smoothFade = smoothstep(0.0, 1.0, fade);
// Mix the two textures based on fade value
fragColor = mix(color1, color2, smoothFade) * qt_Opacity;
}

Binary file not shown.