Compare commits

...

2 Commits

Author SHA1 Message Date
tux
f2268f65e7 feat(cava): update bar opacity using level 2026-09-04 22:56:32 +05:30
tux
6357b949b3 feat(bar): add smooth sliding highlight to workspaces 2026-09-04 22:55:22 +05:30
2 changed files with 122 additions and 38 deletions

View File

@@ -39,7 +39,7 @@ Rectangle {
radius: bar.width / 2
color: Theme.colors.accent
antialiasing: true
opacity: 0.55 + 0.45 * bar.height / Math.max(1, barRow.height)
opacity: 0.45 + (bar.level * 0.55)
Behavior on height {
NumberAnimation {

View File

@@ -4,57 +4,141 @@ import QtQuick
import Quickshell.Hyprland
import qs.config
Row {
Item {
id: root
property int count: 7
spacing: Theme.spacing
implicitWidth: pillsRow.implicitWidth
implicitHeight: Theme.workspaces.height
Behavior on implicitWidth {
NumberAnimation {
duration: Theme.duration
easing.type: Easing.OutQuint
}
}
Repeater {
model: root.count
Row {
id: pillsRow
Rectangle {
id: pill
anchors.fill: parent
spacing: Theme.spacing
required property int index
property var ws: Hyprland.workspaces.values.find(w => w.id === pill.index + 1)
property bool isActive: Hyprland.focusedWorkspace?.id === (pill.index + 1)
Repeater {
model: root.count
radius: Theme.workspaces.radius
implicitHeight: Theme.workspaces.height
implicitWidth: pill.isActive ? pill.implicitHeight * Theme.workspaces.activeWidthRatio : pill.implicitHeight
color: {
if (handler.hovered)
return Theme.colors.accent;
if (pill.isActive || pill.ws)
return Theme.colors.accent;
return Theme.colors.inActive;
}
Rectangle {
id: pill
MouseArea {
hoverEnabled: true
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: Hyprland.dispatch("workspace " + (pill.index + 1))
}
required property int index
property var ws: Hyprland.workspaces.values.find(w => w.id === pill.index + 1)
property bool isActive: Hyprland.focusedWorkspace?.id === (pill.index + 1)
HoverHandler {
id: handler
}
Behavior on color {
ColorAnimation {
duration: Theme.duration
z: 1
radius: Theme.workspaces.radius
implicitHeight: Theme.workspaces.height
implicitWidth: pill.isActive ? pill.implicitHeight * Theme.workspaces.activeWidthRatio : pill.implicitHeight
color: {
if (pill.isActive)
return "transparent";
if (handler.hovered)
return Theme.colors.accent;
if (pill.ws)
return Theme.colors.secondaryForeground;
return Theme.colors.inActive;
}
}
Behavior on implicitWidth {
NumberAnimation {
duration: Theme.duration
easing.type: Easing.OutQuad
MouseArea {
hoverEnabled: true
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: Hyprland.dispatch("hl.dsp.focus({ workspace = " + (pill.index + 1) + " })")
}
HoverHandler {
id: handler
}
Behavior on color {
ColorAnimation {
duration: Theme.duration + 50
}
}
Behavior on implicitWidth {
NumberAnimation {
duration: Theme.duration
easing.type: Easing.OutQuad
}
}
}
}
}
Rectangle {
id: highlight
z: 2
radius: Theme.workspaces.radius
color: Theme.colors.accent
readonly property real activeW: Theme.workspaces.height * Theme.workspaces.activeWidthRatio
readonly property real inactiveW: Theme.workspaces.height
property int curIdx: Hyprland.focusedWorkspace ? Hyprland.focusedWorkspace.id - 1 : -1
property int prevIdx: 0
function getX(index, activeIndex) {
if (index < 0)
return 0;
let x = 0;
for (let i = 0; i < index; i++)
x += (i === activeIndex ? activeW : inactiveW) + pillsRow.spacing;
return x;
}
property real targetLeft: curIdx >= 0 ? getX(curIdx, curIdx) : 0
property real targetRight: curIdx >= 0 ? targetLeft + activeW : 0
property real actualLeft: targetLeft
property real actualRight: targetRight
Behavior on actualLeft {
NumberAnimation {
id: leftAnim
duration: Theme.duration
easing.type: Easing.OutQuint
}
}
Behavior on actualRight {
NumberAnimation {
id: rightAnim
duration: Theme.duration
easing.type: Easing.OutQuint
}
}
onCurIdxChanged: {
if (curIdx >= 0 && prevIdx >= 0) {
if (curIdx > prevIdx) {
leftAnim.duration = 400;
rightAnim.duration = 300;
} else if (curIdx < prevIdx) {
leftAnim.duration = 300;
rightAnim.duration = 400;
}
}
if (curIdx >= 0)
prevIdx = curIdx;
}
x: actualLeft
width: actualRight - actualLeft
height: parent.height
opacity: curIdx >= 0 ? 1 : 0
Behavior on opacity {
NumberAnimation {
duration: 180
}
}
}
}