mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-06-24 12:05:21 -04:00
1a39b7f66c
* feat: parallax-scroll wallpaper Add a `Scrolling` wallpaper fill mode that translates the wallpaper crop with the active workspace — like Android home-screen parallax, but along niri's vertical workspace axis. The image is scaled to cover the screen on its non-scroll axis, and the active workspace index drives a fractional offset into the cropped overflow along the scroll axis. Scroll position is spring-animated CPU-side and handed to a minimal single-texture shader as a UV offset. Per-monitor scroll position is published into SessionData so the lock screen renders the same crop as the active workspace, keeping visual continuity across lock/unlock. Two implementation details worth calling out for review: - QSG_USE_SIMPLE_ANIMATION_DRIVER=1 is exported to the spawned quickshell process. The default animation driver advances in fixed ~16ms steps, capping the scroll at 60Hz and desyncing it from compositor motion on high-refresh displays; the simple driver advances by real elapsed time, restoring native-refresh pacing. Removing it visibly regresses to 60Hz. - The wallpaper survives wl_output rebind cycles (e.g. OLED image-cleaning on DPMS soft-off), which otherwise leave a stuck or void background. Recovery re-anchors the scroll target on output-lifecycle signals, rebuilds the ShaderEffect against the current render context, and re-attaches the wallpaper-layer surface on unlock for parallax-active monitors — guarded against lock state so the shader gets reliable frame hints. * simplify bindings and gate lock screen shader in a loader --------- Co-authored-by: bbedward <bbedward@gmail.com>
37 lines
1.2 KiB
GLSL
37 lines
1.2 KiB
GLSL
// ===== wp_parallax_scroll.frag =====
|
|
// Parallax scrolling wallpaper shader: samples a single pre-scaled texture
|
|
// and applies a CPU-computed UV offset (scrollX/scrollY) along the overflow
|
|
// axis. Independent of the transition-effect shaders.
|
|
#version 450
|
|
|
|
layout(location = 0) in vec2 qt_TexCoord0;
|
|
layout(location = 0) out vec4 fragColor;
|
|
|
|
layout(binding = 1) uniform sampler2D source;
|
|
|
|
layout(std140, binding = 0) uniform buf {
|
|
mat4 qt_Matrix;
|
|
float qt_Opacity;
|
|
|
|
float scrollX; // 0-100 scroll position
|
|
float scrollY; // 0-100 scroll position
|
|
float uvScaleX; // Pre-computed: screenWidth / scaledImageWidth
|
|
float uvScaleY; // Pre-computed: screenHeight / scaledImageHeight
|
|
float scrollRangeX; // Pre-computed: 1.0 - uvScaleX (or 0 if not scrollable)
|
|
float scrollRangeY; // Pre-computed: 1.0 - uvScaleY (or 0 if not scrollable)
|
|
} ubuf;
|
|
|
|
void main() {
|
|
vec2 uv = qt_TexCoord0;
|
|
|
|
// Apply UV scale and scroll offset
|
|
vec2 scrollOffset = vec2(
|
|
ubuf.scrollRangeX * (ubuf.scrollX / 100.0),
|
|
ubuf.scrollRangeY * (ubuf.scrollY / 100.0)
|
|
);
|
|
|
|
vec2 finalUV = uv * vec2(ubuf.uvScaleX, ubuf.uvScaleY) + scrollOffset;
|
|
|
|
fragColor = texture(source, finalUV) * ubuf.qt_Opacity;
|
|
}
|