bar/workspaces: refactor
This commit is contained in:
parent
2be46ff65a
commit
d8f7bac960
9 changed files with 98 additions and 111 deletions
|
|
@ -254,13 +254,12 @@ All configuration options are in `~/.config/caelestia/shell.json`.
|
|||
},
|
||||
"workspaces": {
|
||||
"activeIndicator": true,
|
||||
"activeLabel": " ",
|
||||
"activeLabel": "",
|
||||
"activeTrail": false,
|
||||
"label": " ",
|
||||
"occupiedBg": false,
|
||||
"occupiedLabel": " ",
|
||||
"occupiedLabel": "",
|
||||
"perMonitorWorkspaces": true,
|
||||
"rounded": true,
|
||||
"showWindows": true,
|
||||
"shown": 5
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,15 +50,14 @@ JsonObject {
|
|||
|
||||
component Workspaces: JsonObject {
|
||||
property int shown: 5
|
||||
property bool rounded: true
|
||||
property bool activeIndicator: true
|
||||
property bool occupiedBg: false
|
||||
property bool showWindows: true
|
||||
property bool activeTrail: false
|
||||
property bool perMonitorWorkspaces: true
|
||||
property string label: " "
|
||||
property string occupiedLabel: " "
|
||||
property string activeLabel: " "
|
||||
property string occupiedLabel: ""
|
||||
property string activeLabel: ""
|
||||
}
|
||||
|
||||
component Tray: JsonObject {
|
||||
|
|
|
|||
|
|
@ -177,6 +177,5 @@ ColumnLayout {
|
|||
|
||||
visible: enabled
|
||||
active: enabled
|
||||
asynchronous: true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,6 @@ Item {
|
|||
anchors.right: parent.right
|
||||
|
||||
active: root.shouldBeVisible || root.visible
|
||||
asynchronous: true
|
||||
|
||||
sourceComponent: Bar {
|
||||
width: root.contentWidth
|
||||
|
|
|
|||
|
|
@ -8,45 +8,38 @@ StyledRect {
|
|||
id: root
|
||||
|
||||
required property int activeWsId
|
||||
required property list<Workspace> workspaces
|
||||
required property Repeater workspaces
|
||||
required property Item mask
|
||||
required property real maskWidth
|
||||
required property real maskHeight
|
||||
required property int groupOffset
|
||||
|
||||
readonly property int currentWsIdx: activeWsId - 1 - groupOffset
|
||||
property real leading: getWsY(currentWsIdx)
|
||||
property real trailing: getWsY(currentWsIdx)
|
||||
property real currentSize: workspaces[currentWsIdx]?.size ?? 0
|
||||
readonly property int currentWsIdx: (activeWsId - 1) % Config.bar.workspaces.shown
|
||||
|
||||
property real leading: workspaces.itemAt(currentWsIdx)?.y ?? 0
|
||||
property real trailing: workspaces.itemAt(currentWsIdx)?.y ?? 0
|
||||
property real currentSize: workspaces.itemAt(currentWsIdx)?.size ?? 0
|
||||
property real offset: Math.min(leading, trailing)
|
||||
property real size: {
|
||||
const s = Math.abs(leading - trailing) + currentSize;
|
||||
if (Config.bar.workspaces.activeTrail && lastWs > currentWsIdx)
|
||||
return Math.min(getWsY(lastWs) + (workspaces[lastWs]?.size ?? 0) - offset, s);
|
||||
if (Config.bar.workspaces.activeTrail && lastWs > currentWsIdx) {
|
||||
const ws = workspaces.itemAt(lastWs);
|
||||
// console.log(ws, lastWs);
|
||||
return ws ? Math.min(ws.y + ws.size - offset, s) : 0;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
property int cWs
|
||||
property int lastWs
|
||||
|
||||
function getWsY(idx: int): real {
|
||||
let y = 0;
|
||||
for (let i = 0; i < idx; i++)
|
||||
y += workspaces[i]?.size ?? 0;
|
||||
return y;
|
||||
}
|
||||
|
||||
onCurrentWsIdxChanged: {
|
||||
lastWs = cWs;
|
||||
cWs = currentWsIdx;
|
||||
}
|
||||
|
||||
clip: true
|
||||
x: 1
|
||||
y: offset + 1
|
||||
implicitWidth: Config.bar.sizes.innerHeight - 2
|
||||
implicitHeight: size - 2
|
||||
radius: Config.bar.workspaces.rounded ? Appearance.rounding.full : 0
|
||||
y: offset + mask.y
|
||||
implicitWidth: Config.bar.sizes.innerWidth - Appearance.padding.small * 2
|
||||
implicitHeight: size
|
||||
radius: Appearance.rounding.full
|
||||
color: Colours.palette.m3primary
|
||||
|
||||
Colouriser {
|
||||
|
|
@ -56,8 +49,8 @@ StyledRect {
|
|||
|
||||
x: 0
|
||||
y: -parent.offset
|
||||
implicitWidth: root.maskWidth
|
||||
implicitHeight: root.maskHeight
|
||||
implicitWidth: root.mask.implicitWidth
|
||||
implicitHeight: root.mask.implicitHeight
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import QtQuick
|
|||
Item {
|
||||
id: root
|
||||
|
||||
required property list<Workspace> workspaces
|
||||
required property Repeater workspaces
|
||||
required property var occupied
|
||||
required property int groupOffset
|
||||
|
||||
|
|
@ -48,18 +48,17 @@ Item {
|
|||
|
||||
required property var modelData
|
||||
|
||||
readonly property Workspace start: root.workspaces[modelData.start - 1 - root.groupOffset] ?? null
|
||||
readonly property Workspace end: root.workspaces[modelData.end - 1 - root.groupOffset] ?? null
|
||||
readonly property Workspace start: root.workspaces.itemAt((modelData.start - 1) % Config.bar.workspaces.shown) ?? null
|
||||
readonly property Workspace end: root.workspaces.itemAt((modelData.end - 1) % Config.bar.workspaces.shown) ?? null
|
||||
|
||||
color: Colours.tPalette.m3surfaceContainerHigh
|
||||
radius: Config.bar.workspaces.rounded ? Appearance.rounding.full : 0
|
||||
anchors.horizontalCenter: root.horizontalCenter
|
||||
|
||||
x: start?.x ?? 0
|
||||
y: start?.y ?? 0
|
||||
implicitWidth: Config.bar.sizes.innerHeight
|
||||
implicitHeight: end?.y + end?.height - start?.y
|
||||
y: (start?.y ?? 0) - 1
|
||||
implicitWidth: Config.bar.sizes.innerWidth - Appearance.padding.small * 2 + 2
|
||||
implicitHeight: start && end ? end.y + end.size - start.y + 2 : 0
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
color: Colours.layer(Colours.palette.m3surfaceContainerHigh, 2)
|
||||
radius: Appearance.rounding.full
|
||||
|
||||
scale: 0
|
||||
Component.onCompleted: scale = 1
|
||||
|
|
@ -70,11 +69,11 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
Behavior on x {
|
||||
Behavior on y {
|
||||
Anim {}
|
||||
}
|
||||
|
||||
Behavior on y {
|
||||
Behavior on implicitHeight {
|
||||
Anim {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import Quickshell
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
Item {
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
required property int index
|
||||
|
|
@ -16,41 +16,44 @@ Item {
|
|||
|
||||
readonly property bool isWorkspace: true // Flag for finding workspace children
|
||||
// Unanimated prop for others to use as reference
|
||||
readonly property real size: childrenRect.height + (hasWindows ? Appearance.padding.smaller : 0)
|
||||
readonly property int size: implicitHeight + (hasWindows ? Appearance.padding.small : 0)
|
||||
|
||||
readonly property int ws: groupOffset + index + 1
|
||||
readonly property bool isOccupied: occupied[ws] ?? false
|
||||
readonly property bool hasWindows: isOccupied && Config.bar.workspaces.showWindows
|
||||
|
||||
Layout.preferredWidth: childrenRect.width
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.preferredHeight: size
|
||||
|
||||
spacing: 0
|
||||
|
||||
StyledText {
|
||||
id: indicator
|
||||
|
||||
readonly property string label: Config.bar.workspaces.label || root.ws
|
||||
readonly property string occupiedLabel: Config.bar.workspaces.occupiedLabel || label
|
||||
readonly property string activeLabel: Config.bar.workspaces.activeLabel || (root.isOccupied ? occupiedLabel : label)
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
|
||||
Layout.preferredHeight: Config.bar.sizes.innerWidth - Appearance.padding.small * 2
|
||||
|
||||
animate: true
|
||||
text: root.activeWsId === root.ws ? activeLabel : root.isOccupied ? occupiedLabel : label
|
||||
text: {
|
||||
const label = Config.bar.workspaces.label || root.ws;
|
||||
const occupiedLabel = Config.bar.workspaces.occupiedLabel || label;
|
||||
const activeLabel = Config.bar.workspaces.activeLabel || (root.isOccupied ? occupiedLabel : label);
|
||||
return root.activeWsId === root.ws ? activeLabel : root.isOccupied ? occupiedLabel : label;
|
||||
}
|
||||
color: Config.bar.workspaces.occupiedBg || root.isOccupied || root.activeWsId === root.ws ? Colours.palette.m3onSurface : Colours.layer(Colours.palette.m3outlineVariant, 2)
|
||||
horizontalAlignment: StyledText.AlignHCenter
|
||||
verticalAlignment: StyledText.AlignVCenter
|
||||
|
||||
width: Config.bar.sizes.innerHeight
|
||||
height: Config.bar.sizes.innerHeight
|
||||
verticalAlignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: windows
|
||||
|
||||
active: Config.bar.workspaces.showWindows
|
||||
asynchronous: true
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.fillHeight: true
|
||||
Layout.topMargin: -Config.bar.sizes.innerWidth / 10
|
||||
|
||||
anchors.horizontalCenter: indicator.horizontalCenter
|
||||
anchors.top: indicator.bottom
|
||||
anchors.topMargin: -Config.bar.sizes.innerHeight / 10
|
||||
visible: active
|
||||
active: root.hasWindows
|
||||
asynchronous: true
|
||||
|
||||
sourceComponent: Column {
|
||||
spacing: 0
|
||||
|
|
@ -91,10 +94,6 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
Behavior on Layout.preferredWidth {
|
||||
Anim {}
|
||||
}
|
||||
|
||||
Behavior on Layout.preferredHeight {
|
||||
Anim {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,76 +13,61 @@ StyledRect {
|
|||
required property ShellScreen screen
|
||||
|
||||
readonly property int activeWsId: Config.bar.workspaces.perMonitorWorkspaces ? (Hyprland.monitorFor(screen).activeWorkspace?.id ?? 1) : Hyprland.activeWsId
|
||||
readonly property list<Workspace> workspaces: layout.children.filter(c => c.isWorkspace).sort((w1, w2) => w1.ws - w2.ws)
|
||||
|
||||
readonly property var occupied: Hyprland.workspaces.values.reduce((acc, curr) => {
|
||||
acc[curr.id] = curr.lastIpcObject.windows > 0;
|
||||
return acc;
|
||||
}, {})
|
||||
readonly property int groupOffset: Math.floor((activeWsId - 1) / Config.bar.workspaces.shown) * Config.bar.workspaces.shown
|
||||
|
||||
implicitWidth: layout.implicitWidth + Appearance.padding.small * 2
|
||||
implicitHeight: layout.implicitHeight + Appearance.padding.small * 2
|
||||
implicitWidth: Config.bar.sizes.innerWidth
|
||||
|
||||
color: Colours.tPalette.m3surfaceContainer
|
||||
radius: Appearance.rounding.full
|
||||
|
||||
Item {
|
||||
id: inner
|
||||
Loader {
|
||||
active: Config.bar.workspaces.occupiedBg
|
||||
asynchronous: true
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.margins: Appearance.padding.small
|
||||
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
|
||||
spacing: 0
|
||||
|
||||
Repeater {
|
||||
model: Config.bar.workspaces.shown
|
||||
|
||||
Workspace {
|
||||
activeWsId: root.activeWsId
|
||||
occupied: root.occupied
|
||||
groupOffset: root.groupOffset
|
||||
}
|
||||
}
|
||||
sourceComponent: OccupiedBg {
|
||||
workspaces: workspaces
|
||||
occupied: root.occupied
|
||||
groupOffset: root.groupOffset
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
active: Config.bar.workspaces.occupiedBg
|
||||
asynchronous: true
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
|
||||
z: -1
|
||||
anchors.fill: parent
|
||||
anchors.centerIn: parent
|
||||
spacing: Math.floor(Appearance.spacing.small / 2)
|
||||
|
||||
sourceComponent: OccupiedBg {
|
||||
workspaces: root.workspaces
|
||||
Repeater {
|
||||
id: workspaces
|
||||
|
||||
model: Config.bar.workspaces.shown
|
||||
|
||||
Workspace {
|
||||
activeWsId: root.activeWsId
|
||||
occupied: root.occupied
|
||||
groupOffset: root.groupOffset
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
active: Config.bar.workspaces.activeIndicator
|
||||
asynchronous: true
|
||||
Loader {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
active: Config.bar.workspaces.activeIndicator
|
||||
asynchronous: true
|
||||
|
||||
sourceComponent: ActiveIndicator {
|
||||
activeWsId: root.activeWsId
|
||||
workspaces: root.workspaces
|
||||
mask: layout
|
||||
maskWidth: inner.width
|
||||
maskHeight: inner.height
|
||||
groupOffset: root.groupOffset
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
|
||||
onPressed: event => {
|
||||
const ws = layout.childAt(event.x, event.y).index + root.groupOffset + 1;
|
||||
if (Hyprland.activeWsId !== ws)
|
||||
Hyprland.dispatch(`workspace ${ws}`);
|
||||
}
|
||||
sourceComponent: ActiveIndicator {
|
||||
activeWsId: root.activeWsId
|
||||
workspaces: workspaces
|
||||
mask: layout
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -183,4 +183,19 @@ Singleton {
|
|||
return "volume_down";
|
||||
return "volume_mute";
|
||||
}
|
||||
|
||||
function getSpecialWsIcon(name: string): string {
|
||||
name = name.toLowerCase().slice("special:".length);
|
||||
if (name === "special")
|
||||
return "star";
|
||||
if (name === "communication")
|
||||
return "forum";
|
||||
if (name === "music")
|
||||
return "music_note";
|
||||
if (name === "todo")
|
||||
return "checklist";
|
||||
if (name === "sysmon")
|
||||
return "monitor_heart";
|
||||
return name[0].toUpperCase();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue