lyrics: distrust the player position after a track change until the probe settles

ref #4025
port 2.0

(cherry picked from commit 87312075dd)
This commit is contained in:
bbedward authored and dux-ci[bot] committed 2026-10-30 14:51:24 +00:00
1 parent d4dd5c2550
commit d575699bc1
2 files changed
+29 -4

No files matched your search

+2
View File
@@ -224,6 +224,8 @@ Singleton {
readonly property int mediaLyricsPositionProbeInterval: 5000
readonly property real mediaLyricsPositionProbeDrift: 1.5
readonly property real mediaLyricsPositionProbeThreshold: 1
readonly property int mediaLyricsPositionSettleInterval: 1000
readonly property real mediaLyricsTrackStartSlack: 5
readonly property real lyricsNearOpacity: 0.55
readonly property real lyricsFarOpacity: 0.3
readonly property real lyricsLineHeight: 1.25
+27 -4
View File
@@ -57,13 +57,15 @@ QtObject {
property real anchorRate: 1
property real positionWall: 0
property var probe: null
property bool positionTrusted: true
property string clockBus: ""
property var memo: null
onTrackKeyChanged: {
cancel();
refreshPending = holdsSong();
if (!refreshPending)
clear();
restart();
requestedKey = "";
if (enabled)
resume();
@@ -172,6 +174,19 @@ QtObject {
state = "idle";
}
function restart() {
const switched = clockBus !== "" && clockBus === busName;
clockBus = busName;
clear();
positionTrusted = !switched;
if (!switched)
return;
anchorPosition = 0;
anchorWall = Date.now();
anchorPlaying = playing;
anchorRate = rate;
}
function clearContent() {
stopClock();
lines = [];
@@ -383,6 +398,7 @@ QtObject {
if (!line || !Number.isFinite(line.t))
return false;
player.position = Math.max(0.1, Math.min(line.t, duration * 0.99));
positionTrusted = true;
reanchor();
return true;
}
@@ -396,7 +412,7 @@ QtObject {
function updatePlaybackClock() {
const predicted = currentTime();
const sampled = position + (anchorPlaying ? (Date.now() - positionWall) * anchorRate / 1000 : 0);
const pendingSeek = !stopped && anchorUpdate.running && Math.abs(sampled - predicted) >= DashMetrics.mediaLyricsPositionTolerance;
const pendingSeek = !stopped && anchorUpdate.running && Math.abs(sampled - predicted) >= DashMetrics.mediaLyricsPositionTolerance && reachable(sampled);
anchorUpdate.stop();
anchorPosition = pendingSeek ? sampled : predicted;
anchorWall = Date.now();
@@ -430,6 +446,7 @@ QtObject {
const advanced = previous.position + (wall - previous.wall) * rate / 1000;
if (Math.abs(observed - advanced) > DashMetrics.mediaLyricsPositionProbeDrift)
return;
positionTrusted = true;
if (Math.abs(observed - currentTime()) < DashMetrics.mediaLyricsPositionProbeThreshold)
return;
anchorPosition = observed;
@@ -452,9 +469,15 @@ QtObject {
anchorUpdate.start();
}
// the Position Get quickshell issues on a track change can still answer with the old track (#4025)
function reachable(observed) {
return positionTrusted || observed <= currentTime() + DashMetrics.mediaLyricsTrackStartSlack;
}
function reanchor(force = true) {
anchorUpdate.stop();
const observed = player?.position ?? 0;
const sampled = player?.position ?? 0;
const observed = reachable(sampled) ? sampled : currentTime();
if (!force && anchorPlaying && Math.abs(observed - currentTime()) < DashMetrics.mediaLyricsPositionTolerance)
return false;
anchorPosition = observed;
@@ -538,7 +561,7 @@ QtObject {
}
property Timer positionProbe: Timer {
interval: DashMetrics.mediaLyricsPositionProbeInterval
interval: root.positionTrusted ? DashMetrics.mediaLyricsPositionProbeInterval : DashMetrics.mediaLyricsPositionSettleInterval
repeat: true
triggeredOnStart: true
running: root.enabled && root.synced && root.playing && !root.stopped && root.busName !== "" && DMSService.isConnected