feat: bar workspace groups

This commit is contained in:
2 * r + 2 * t 2025-04-29 12:52:01 +10:00
parent 2c7e9dd221
commit 4013fe8434
5 changed files with 31 additions and 22 deletions

View file

@ -19,6 +19,6 @@ Singleton {
component Workspaces: QtObject { component Workspaces: QtObject {
readonly property int shown: 10 readonly property int shown: 10
readonly property string style: "" readonly property string style: ""
readonly property bool occupiedBg: false readonly property bool occupiedBg: true
} }
} }

View file

@ -12,8 +12,9 @@ Rectangle {
required property Item mask required property Item mask
required property real maskWidth required property real maskWidth
required property real maskHeight required property real maskHeight
required property int groupOffset
property int currentIdx: (Hyprland.activeWorkspace?.id ?? 1) - 1 property int currentIdx: (Hyprland.activeWorkspace?.id ?? 1) - 1 - groupOffset
property int lastIdx: currentIdx property int lastIdx: currentIdx
property real leading: workspaces[currentIdx][vertical ? "y" : "x"] property real leading: workspaces[currentIdx][vertical ? "y" : "x"]
property real trailing: workspaces[lastIdx][vertical ? "y" : "x"] property real trailing: workspaces[lastIdx][vertical ? "y" : "x"]

View file

@ -1,3 +1,5 @@
pragma ComponentBehavior: Bound
import "root:/widgets" import "root:/widgets"
import "root:/config" import "root:/config"
import QtQuick import QtQuick
@ -9,8 +11,10 @@ BoxLayout {
required property bool vertical required property bool vertical
required property list<Workspace> workspaces required property list<Workspace> workspaces
required property var occupied required property var occupied
required property int groupOffset
anchors.centerIn: parent anchors.centerIn: parent
opacity: BarConfig.workspaces.occupiedBg ? 1 : 0
spacing: 0 spacing: 0
z: -1 z: -1
@ -19,11 +23,13 @@ BoxLayout {
Rectangle { Rectangle {
required property int index required property int index
readonly property int roundLeft: index === 0 || !root.occupied[index] ? Appearance.rounding.full : 0 readonly property int roundLeft: index === 0 || !root.occupied[ws - 1] ? Appearance.rounding.full : 0
readonly property int roundRight: index === BarConfig.workspaces.shown - 1 || !root.occupied[index + 2] ? Appearance.rounding.full : 0 readonly property int roundRight: index === BarConfig.workspaces.shown - 1 || !root.occupied[ws + 1] ? Appearance.rounding.full : 0
property int ws: root.groupOffset + index + 1
color: Appearance.alpha(Appearance.colours.surface2, true) color: Appearance.alpha(Appearance.colours.surface2, true)
opacity: root.occupied[index + 1] ? 1 : 0 opacity: root.occupied[ws] ? 1 : 0
topLeftRadius: roundLeft topLeftRadius: roundLeft
bottomLeftRadius: roundLeft bottomLeftRadius: roundLeft
topRightRadius: roundRight topRightRadius: roundRight
@ -42,4 +48,12 @@ BoxLayout {
} }
} }
} }
Behavior on opacity {
NumberAnimation {
duration: Appearance.anim.durations.normal
easing.type: Easing.BezierSpline
easing.bezierCurve: Appearance.anim.curves.standard
}
}
} }

View file

@ -8,11 +8,14 @@ StyledText {
required property bool vertical required property bool vertical
required property bool homogenous required property bool homogenous
required property var occupied required property var occupied
required property int groupOffset
readonly property bool isWorkspace: true // Flag for finding workspace children readonly property bool isWorkspace: true // Flag for finding workspace children
text: index + 1 property int ws: groupOffset + index + 1
color: BarConfig.workspaces.occupiedBg || occupied[index + 1] ? Appearance.colours.text : Appearance.colours.subtext0
text: ws
color: BarConfig.workspaces.occupiedBg || occupied[ws] ? Appearance.colours.text : Appearance.colours.subtext0
horizontalAlignment: StyledText.AlignHCenter horizontalAlignment: StyledText.AlignHCenter
Layout.preferredWidth: homogenous && !vertical ? BarConfig.sizes.innerHeight : -1 Layout.preferredWidth: homogenous && !vertical ? BarConfig.sizes.innerHeight : -1

View file

@ -8,15 +8,13 @@ Item {
property alias vertical: layout.vertical property alias vertical: layout.vertical
readonly property color colour: Appearance.colours.mauve readonly property color colour: Appearance.colours.mauve
property int shown: 10
property bool occupiedBg: false
property bool showWindows: false
readonly property list<Workspace> workspaces: layout.children.filter(c => c.isWorkspace) readonly property list<Workspace> workspaces: layout.children.filter(c => c.isWorkspace)
readonly property var occupied: Hyprland.workspaces.values.reduce((acc, curr) => { readonly property var occupied: Hyprland.workspaces.values.reduce((acc, curr) => {
acc[curr.id] = curr.lastIpcObject.windows > 0; acc[curr.id] = curr.lastIpcObject.windows > 0;
return acc; return acc;
}, {}) }, {})
readonly property int groupOffset: Math.floor(((Hyprland.activeWorkspace?.id ?? 1) - 1) / BarConfig.workspaces.shown) * BarConfig.workspaces.shown
implicitWidth: layout.implicitWidth implicitWidth: layout.implicitWidth
implicitHeight: layout.implicitHeight implicitHeight: layout.implicitHeight
@ -24,7 +22,6 @@ Item {
BoxLayout { BoxLayout {
id: layout id: layout
anchors.fill: parent
homogenous: true homogenous: true
spacing: 0 spacing: 0
@ -33,25 +30,18 @@ Item {
Workspace { Workspace {
vertical: root.vertical vertical: root.vertical
homogenous: true homogenous: layout.homogenous
occupied: root.occupied occupied: root.occupied
groupOffset: root.groupOffset
} }
} }
} }
OccupiedBg { OccupiedBg {
opacity: BarConfig.workspaces.occupiedBg ? 1 : 0
vertical: root.vertical vertical: root.vertical
workspaces: root.workspaces workspaces: root.workspaces
occupied: root.occupied occupied: root.occupied
groupOffset: root.groupOffset
Behavior on opacity {
NumberAnimation {
duration: Appearance.anim.durations.normal
easing.type: Easing.BezierSpline
easing.bezierCurve: Appearance.anim.curves.standard
}
}
} }
ActiveIndicator { ActiveIndicator {
@ -60,12 +50,13 @@ Item {
mask: layout mask: layout
maskWidth: root.width maskWidth: root.width
maskHeight: root.height maskHeight: root.height
groupOffset: root.groupOffset
} }
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
onPressed: event => Hyprland.dispatch(`workspace ${layout.childAt(event.x, event.y).index + 1}`) onPressed: event => Hyprland.dispatch(`workspace ${layout.childAt(event.x, event.y).index + root.groupOffset + 1}`)
onWheel: event => { onWheel: event => {
if (event.angleDelta.y < 0) if (event.angleDelta.y < 0)
Hyprland.dispatch(`workspace r+1`); Hyprland.dispatch(`workspace r+1`);