1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-06-15 07:35:20 -04:00

fix(wallpaper): simplify wallpaper rendering logic & reliability

- Keep wallpaper surfaces persistent and remove `updatesEnabled` throttling that could leave wallpapers grey or frozen after DPMS, suspend, fullscreen, or output changes

Fixes #2612
Fixes #2299
Fixes #2272
Fixes #2028
This commit is contained in:
purian23
2026-06-12 17:30:54 -04:00
parent b34a04f723
commit bae98daa5c
3 changed files with 48 additions and 164 deletions
@@ -7,6 +7,7 @@ import qs.Widgets
import qs.Services
Variants {
readonly property var log: Log.scoped("BlurredWallpaperBackground")
model: {
if (SessionData.isGreeterMode) {
return Quickshell.screens;
@@ -85,7 +86,6 @@ Variants {
}
Component.onCompleted: {
blurWallpaperWindow.updatesEnabled = Qt.binding(() => !root.source || root.effectActive || root._renderSettling || currentWallpaper.status === Image.Loading || nextWallpaper.status === Image.Loading);
isInitialized = true;
}
@@ -93,51 +93,16 @@ Variants {
property real transitionProgress: 0
readonly property bool transitioning: transitionAnimation.running
property bool effectActive: false
property bool _renderSettling: true
property bool useNextForEffect: false
Connections {
target: currentWallpaper
function onStatusChanged() {
if (currentWallpaper.status !== Image.Ready && currentWallpaper.status !== Image.Error)
return;
root._renderSettling = true;
renderSettleTimer.restart();
}
}
Connections {
target: blurWallpaperWindow
function onWidthChanged() {
root._renderSettling = true;
renderSettleTimer.restart();
}
function onHeightChanged() {
root._renderSettling = true;
renderSettleTimer.restart();
}
}
Connections {
target: Quickshell
function onScreensChanged() {
root._renderSettling = true;
renderSettleTimer.restart();
}
}
Connections {
target: SettingsData
function onWallpaperFillModeChanged() {
root._renderSettling = true;
renderSettleTimer.restart();
}
}
Timer {
id: renderSettleTimer
interval: 1000
onTriggered: root._renderSettling = false
function handleTransitionLoadError(failedSource) {
log.warn("failed to load candidate wallpaper for", modelData.name + ":", failedSource);
transitionDelayTimer.stop();
transitionAnimation.stop();
root.useNextForEffect = false;
root.effectActive = false;
root.transitionProgress = 0.0;
nextWallpaper.source = "";
}
onSourceChanged: {
@@ -164,8 +129,6 @@ Variants {
transitionAnimation.stop();
root.transitionProgress = 0.0;
root.effectActive = false;
root._renderSettling = true;
renderSettleTimer.restart();
currentWallpaper.source = newSource;
nextWallpaper.source = "";
}
@@ -194,8 +157,6 @@ Variants {
transitionAnimation.stop();
root.transitionProgress = 0;
root.effectActive = false;
root._renderSettling = true;
renderSettleTimer.restart();
currentWallpaper.source = nextWallpaper.source;
nextWallpaper.source = "";
}
@@ -204,9 +165,6 @@ Variants {
return;
}
root._renderSettling = true;
renderSettleTimer.restart();
nextWallpaper.source = newPath;
if (nextWallpaper.status === Image.Ready)
@@ -215,7 +173,7 @@ Variants {
Loader {
anchors.fill: parent
active: !root.source || root.isColorSource
active: !root.source || root.isColorSource || currentWallpaper.status === Image.Error
asynchronous: true
sourceComponent: DankBackdrop {
@@ -238,6 +196,12 @@ Variants {
cache: true
sourceSize: Qt.size(root.textureWidth, root.textureHeight)
fillMode: root.getFillMode(SessionData.isGreeterMode ? GreetdSettings.wallpaperFillMode : SessionData.getMonitorWallpaperFillMode(modelData.name))
onStatusChanged: {
if (status === Image.Error) {
log.warn("failed to load active wallpaper for", modelData.name + ":", source);
}
}
}
Image {
@@ -253,6 +217,10 @@ Variants {
fillMode: root.getFillMode(SessionData.isGreeterMode ? GreetdSettings.wallpaperFillMode : SessionData.getMonitorWallpaperFillMode(modelData.name))
onStatusChanged: {
if (status === Image.Error) {
root.handleTransitionLoadError(source);
return;
}
if (status !== Image.Ready)
return;
if (!root.transitioning) {
@@ -329,8 +297,6 @@ Variants {
root.useNextForEffect = false;
nextWallpaper.source = "";
root.transitionProgress = 0.0;
root._renderSettling = true;
renderSettleTimer.restart();
root.effectActive = false;
}
}
+26 -91
View File
@@ -84,23 +84,11 @@ Variants {
readonly property bool transitioning: transitionAnimation.running
property bool effectActive: false
property bool _renderSettling: true
property bool _overviewBlurSettling: false
property bool useNextForEffect: false
property string pendingWallpaper: ""
property string _deferredSource: ""
readonly property bool overviewBlurActive: CompositorService.isNiri && SettingsData.blurWallpaperOnOverview && NiriService.inOverview && currentWallpaper.source !== ""
Connections {
target: currentWallpaper
function onStatusChanged() {
if (currentWallpaper.status !== Image.Ready && currentWallpaper.status !== Image.Error)
return;
root._renderSettling = true;
renderSettleTimer.restart();
}
}
function _recheckScreenScale() {
const newScale = CompositorService.getScreenScale(modelData);
if (newScale !== root.screenScale) {
@@ -109,32 +97,10 @@ Variants {
}
}
Connections {
target: wallpaperWindow
function onWidthChanged() {
root._renderSettling = true;
renderSettleTimer.restart();
}
function onHeightChanged() {
root._renderSettling = true;
renderSettleTimer.restart();
}
}
Connections {
target: Quickshell
function onScreensChanged() {
root._renderSettling = true;
renderSettleTimer.restart();
}
}
Connections {
target: NiriService
function onDisplayScalesChanged() {
root._recheckScreenScale();
root._renderSettling = true;
renderSettleTimer.restart();
}
}
@@ -142,29 +108,6 @@ Variants {
target: WlrOutputService
function onWlrOutputAvailableChanged() {
root._recheckScreenScale();
root._renderSettling = true;
renderSettleTimer.restart();
}
}
Connections {
target: NiriService
function onInOverviewChanged() {
root._overviewBlurSettling = true;
overviewBlurSettleTimer.restart();
}
}
Connections {
target: SettingsData
function onBlurWallpaperOnOverviewChanged() {
root._overviewBlurSettling = true;
overviewBlurSettleTimer.restart();
}
function onWallpaperFillModeChanged() {
root._renderSettling = true;
renderSettleTimer.restart();
}
}
@@ -181,26 +124,22 @@ Variants {
}
}
Connections {
target: IdleService
function onIsShellLockedChanged() {
if (!IdleService.isShellLocked) {
root._renderSettling = true;
renderSettleTimer.restart();
}
}
}
function handleTransitionLoadError(failedSource) {
log.warn("failed to load candidate wallpaper for", modelData.name + ":", failedSource);
transitionDelayTimer.stop();
transitionAnimation.stop();
root.useNextForEffect = false;
root.effectActive = false;
root.transitionProgress = 0.0;
currentWallpaper.layer.enabled = false;
nextWallpaper.layer.enabled = false;
nextWallpaper.source = "";
Timer {
id: renderSettleTimer
interval: 1000
onTriggered: root._renderSettling = false
}
Timer {
id: overviewBlurSettleTimer
interval: 150
onTriggered: root._overviewBlurSettling = false
if (!root.pendingWallpaper)
return;
const pending = root.pendingWallpaper;
root.pendingWallpaper = "";
Qt.callLater(() => root.changeWallpaper(pending, true));
}
function getFillMode(modeName) {
@@ -227,11 +166,6 @@ Variants {
}
Component.onCompleted: {
wallpaperWindow.updatesEnabled = Qt.binding(() => !root.source || root.effectActive || root._renderSettling || root.overviewBlurActive || root._overviewBlurSettling || root.pendingWallpaper !== "" || root._deferredSource !== "" || currentWallpaper.status === Image.Loading || nextWallpaper.status === Image.Loading);
if (!source) {
root._renderSettling = false;
}
isInitialized = true;
}
@@ -262,8 +196,6 @@ Variants {
transitionAnimation.stop();
root.transitionProgress = 0.0;
root.effectActive = false;
root._renderSettling = true;
renderSettleTimer.restart();
root.screenScale = CompositorService.getScreenScale(modelData);
currentWallpaper.source = newSource;
nextWallpaper.source = "";
@@ -328,9 +260,6 @@ Variants {
break;
}
root._renderSettling = true;
renderSettleTimer.restart();
nextWallpaper.source = newPath;
if (nextWallpaper.status === Image.Ready)
@@ -339,7 +268,7 @@ Variants {
Loader {
anchors.fill: parent
active: !root.source || root.isColorSource
active: !root.source || root.isColorSource || currentWallpaper.status === Image.Error
asynchronous: true
sourceComponent: DankBackdrop {
@@ -364,6 +293,12 @@ Variants {
cache: true
sourceSize: Qt.size(root.textureWidth, root.textureHeight)
fillMode: root.getFillMode(SessionData.getMonitorWallpaperFillMode(modelData.name))
onStatusChanged: {
if (status === Image.Error) {
log.warn("failed to load active wallpaper for", modelData.name + ":", source);
}
}
}
Image {
@@ -380,11 +315,13 @@ Variants {
fillMode: root.getFillMode(SessionData.getMonitorWallpaperFillMode(modelData.name))
onStatusChanged: {
if (status === Image.Error) {
root.handleTransitionLoadError(source);
return;
}
if (status !== Image.Ready)
return;
if (root.actualTransitionType === "none") {
root._renderSettling = true;
renderSettleTimer.restart();
currentWallpaper.source = source;
nextWallpaper.source = "";
root.transitionProgress = 0.0;
@@ -632,8 +569,6 @@ Variants {
root.transitionProgress = 0.0;
currentWallpaper.layer.enabled = false;
nextWallpaper.layer.enabled = false;
root._renderSettling = true;
renderSettleTimer.restart();
root.effectActive = false;
if (!root.pendingWallpaper)