From 0b993cc31b353b18db134d26a20724bd2d10a1d8 Mon Sep 17 00:00:00 2001 From: Sean Tietz Date: Fri, 16 Oct 2026 23:06:27 +0200 Subject: [PATCH 1/2] Let the equalizer bars step with the window's clock The bars took a new height eight times a second and eased into it over 180 ms, so they never stood still and the window drew every frame the screen offered while music played. They now jump with the window's clock, as the comment and the terminal player have it. The player view, playing, on a 1920x1080 60 Hz display (Intel Iris Xe, Hyprland), measured with BRUMM_GUI_FRAMES against dev/fakedaemon: before 60 fps and 7.5 % of a core, after 49 fps and 5.1 %. Co-Authored-By: Claude Opus 5.5 --- gui/qml/Equalizer.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gui/qml/Equalizer.qml b/gui/qml/Equalizer.qml index 7022dbf..ccf778c 100644 --- a/gui/qml/Equalizer.qml +++ b/gui/qml/Equalizer.qml @@ -12,7 +12,8 @@ Row { height: ui.px(12) // It bobs with the window's clock (ui.clock), eight times a second, - // in the frames the rest moves in. + // in the frames the rest moves in. The bars jump rather than glide: an + // easing would keep the whole window drawing at the screen's rate. property int step: -1 Connections { target: ui @@ -34,7 +35,6 @@ Row { anchors.bottom: parent.bottom radius: width / 2 color: Qt.alpha(eq.color, 0.85) - Behavior on height { enabled: !ui.calm; NumberAnimation { duration: 180; easing.type: Easing.InOutSine } } } } } From 962b40d4961fb5abd14f68aab17bdc7a9dc5c9c6 Mon Sep 17 00:00:00 2001 From: Chriopter Date: Sat, 17 Oct 2026 00:33:34 +0200 Subject: [PATCH 2/2] Draw the player view in one clock's frames The backdrop (Waves) drew into a half-size layer, which drew a second frame after every tick; it is drawn at full size now. On large screens the stage still draws it smaller (FullStage's shrink), so nothing is lost there. The window's clock (ui.clock) and the visualizer's (vizClock) both ticked 20 times a second, but not together. While the visualizer's runs, the window's clock now ticks with it, so the equalizers and the progress bar move in the frames the backdrop draws. Co-Authored-By: Claude Opus 5.5 (1M context) --- gui/qml/Main.qml | 22 ++++++++++++++-------- gui/qml/viz/Waves.qml | 8 ++++---- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/gui/qml/Main.qml b/gui/qml/Main.qml index e293d4c..7445618 100644 --- a/gui/qml/Main.qml +++ b/gui/qml/Main.qml @@ -75,13 +75,14 @@ Window { readonly property int lift: theme.dark && effects ? Text.Raised : Text.Normal readonly property color liftColor: Qt.alpha("black", 0.35) // One clock for all that moves while music plays in the window - // in front — the backdrop's drift, the equalizers, the progress - // bar — so they move in the same frames, not each in its own: 20 - // ticks a second (8 without effects: only the equalizers). It - // stands while paused, in the background, minimized, with motion - // reduced, and under the visualizer. + // in front — the equalizers, the progress bar — so they move in + // the same frames, not each in its own. While the player view's + // backdrop moves it ticks with that (vizClock, 20 a second), else + // by itself: 20 ticks a second, 8 without effects (only the + // equalizers). It stands while paused, in the background, + // minimized, with motion reduced, and under the visualizer. property int clock: 0 // milliseconds it has run - readonly property bool pulsing: pulse.running + readonly property bool pulsing: win.pulsing readonly property int radius: px(16) readonly property int coverRadius: px(6) // every cover's corners, big or small readonly property int gap: px(24) @@ -90,13 +91,18 @@ Window { Store { id: store } + readonly property bool pulsing: !!store.st.playing && ui.awake && !ui.calm && win.visibility !== Window.Minimized && !(store.full && full.opacity === 1) Timer { - id: pulse interval: ui.effects ? 50 : 125 repeat: true - running: !!store.st.playing && ui.awake && !ui.calm && win.visibility !== Window.Minimized && !(store.full && full.opacity === 1) + running: win.pulsing && !vizClock.running onTriggered: ui.clock += interval } + Connections { + target: vizClock + enabled: win.pulsing && vizClock.running + function onTriggered() { ui.clock += Math.round(vizClock.frameTime * 1000) } + } // The cover's accent, picked once per cover. property string accentFor: "" diff --git a/gui/qml/viz/Waves.qml b/gui/qml/viz/Waves.qml index 462211a..3a9eb2e 100644 --- a/gui/qml/viz/Waves.qml +++ b/gui/qml/viz/Waves.qml @@ -1,16 +1,16 @@ import QtQuick import ".." +// Waves is the window's backdrop, drawn at full size: a layer at half +// the pixels drew a second frame after every tick and cost more than it +// saved. On large screens the stage draws it smaller anyway (FullStage's +// shrink). VizEffect { id: fx backgroundColor: ui.deep adaptiveScene: true - RenderSurface { id: surface; anchors.fill: parent; density: 0.5 } Backdrop { anchors.fill: parent running: fx.running - layer.enabled: ui.effects - layer.smooth: true - layer.textureSize: surface.textureSize } }