diff --git a/quickshell/Modules/DDash/Media/LyricsOverlay.qml b/quickshell/Modules/DDash/Media/LyricsOverlay.qml index 76bde3cb2..d6da28977 100644 --- a/quickshell/Modules/DDash/Media/LyricsOverlay.qml +++ b/quickshell/Modules/DDash/Media/LyricsOverlay.qml @@ -340,6 +340,18 @@ FocusScope { } } } + + StateLayer { + anchors.fill: parent + enabled: root.controller.canSeekLines + stateColor: Theme.onSurfaceVariant + cornerRadius: Theme.cornerRadius + onClicked: { + root.following = true; + root.forceActiveFocus(Qt.MouseFocusReason); + root.controller.seekToLine(lyric.index); + } + } } } diff --git a/quickshell/Modules/DDash/Media/LyricsVocal.qml b/quickshell/Modules/DDash/Media/LyricsVocal.qml index 73166e982..b0ee0d445 100644 --- a/quickshell/Modules/DDash/Media/LyricsVocal.qml +++ b/quickshell/Modules/DDash/Media/LyricsVocal.qml @@ -90,6 +90,7 @@ Item { } Item { + y: (root.implicitHeight - height) / 2 width: parent.width height: Math.ceil(line.implicitHeight * root.textScale) diff --git a/quickshell/Services/LyricsController.qml b/quickshell/Services/LyricsController.qml index f0d41562f..b43b7952a 100644 --- a/quickshell/Services/LyricsController.qml +++ b/quickshell/Services/LyricsController.qml @@ -20,6 +20,7 @@ QtObject { property bool enabled: false readonly property bool available: DMSService.capabilities.includes("lyrics") + readonly property bool canSeekLines: synced && (player?.canSeek ?? false) && duration > 0 readonly property string fileUrl: url.startsWith("file://") ? url : "" readonly property string trackKey: track ? JSON.stringify([track.key, track.title, track.artist, track.album, fileUrl, MediaOptions.enabledLyricsProviders]) : "" readonly property int duration: Math.round(track?.length ?? 0) @@ -371,6 +372,16 @@ QtObject { state = "ready"; } + function seekToLine(index) { + if (!synced || duration <= 0 || !player?.canSeek) + return false; + const line = lines[index]; + if (!line || !Number.isFinite(line.t)) + return false; + player.position = Math.max(0.1, Math.min(line.t, duration * 0.99)); + return true; + } + function currentTime() { if (!anchorPlaying) return anchorPosition;