summaryrefslogtreecommitdiff
path: root/modules/bar/components
diff options
context:
space:
mode:
authorLaurens Duin <85798751+Laurens256@users.noreply.github.com>2025-08-13 06:31:48 +0200
committerGitHub <noreply@github.com>2025-08-13 14:31:48 +1000
commit3710df29f588c2aa430d9797a36afa1cbd85b128 (patch)
tree5f804118369ab2db0dbffbbd604b4ddc33af93ed /modules/bar/components
parentnix: add home manager module (#402) (diff)
downloadcaelestia-shell-3710df29f588c2aa430d9797a36afa1cbd85b128.tar.gz
caelestia-shell-3710df29f588c2aa430d9797a36afa1cbd85b128.tar.bz2
caelestia-shell-3710df29f588c2aa430d9797a36afa1cbd85b128.zip
bar: allow hiding items and reordering (#379)
* feat: reorder bar, no popout yet * chore: cleanup * refactor: use DelegateChooser * feat: popouts * chore: cleanup * better popout check + fix async stuff + bar interaction + a bunch of other fixes * fix activewindow and bar vertical padding * readme: add config opt * bar: fix top/bottom padding * bar: better wheel behaviour --------- Co-authored-by: 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>
Diffstat (limited to 'modules/bar/components')
-rw-r--r--modules/bar/components/ActiveWindow.qml97
-rw-r--r--modules/bar/components/Power.qml28
-rw-r--r--modules/bar/components/StatusIcons.qml73
-rw-r--r--modules/bar/components/workspaces/Workspaces.qml90
4 files changed, 136 insertions, 152 deletions
diff --git a/modules/bar/components/ActiveWindow.qml b/modules/bar/components/ActiveWindow.qml
index de0f0ad..3bea956 100644
--- a/modules/bar/components/ActiveWindow.qml
+++ b/modules/bar/components/ActiveWindow.qml
@@ -9,73 +9,62 @@ import QtQuick
Item {
id: root
+ required property var bar
required property Brightness.Monitor monitor
property color colour: Colours.palette.m3primary
- readonly property Item child: child
- implicitWidth: child.implicitWidth
- implicitHeight: child.implicitHeight
-
- Item {
- id: child
-
- property Item current: text1
-
- anchors.centerIn: parent
+ readonly property int maxHeight: {
+ const otherModules = bar.children.filter(c => c.id && c.item !== this && c.id !== "spacer");
+ const otherHeight = otherModules.reduce((acc, curr) => acc + curr.height, 0);
+ // Length - 2 cause repeater counts as a child
+ return bar.height - otherHeight - bar.spacing * (bar.children.length - 1) - bar.vPadding * 2;
+ }
+ property Title current: text1
- clip: true
- implicitWidth: Math.max(icon.implicitWidth, current.implicitHeight)
- implicitHeight: icon.implicitHeight + current.implicitWidth + current.anchors.topMargin
+ clip: true
+ implicitWidth: Math.max(icon.implicitWidth, current.implicitHeight)
+ implicitHeight: icon.implicitHeight + current.implicitWidth + current.anchors.topMargin
- MaterialIcon {
- id: icon
+ MaterialIcon {
+ id: icon
- animate: true
- text: Icons.getAppCategoryIcon(Hyprland.activeToplevel?.lastIpcObject.class, "desktop_windows")
- color: root.colour
+ anchors.horizontalCenter: parent.horizontalCenter
- anchors.horizontalCenter: parent.horizontalCenter
- }
+ animate: true
+ text: Icons.getAppCategoryIcon(Hyprland.activeToplevel?.lastIpcObject.class, "desktop_windows")
+ color: root.colour
+ }
- Title {
- id: text1
- }
+ Title {
+ id: text1
+ }
- Title {
- id: text2
- }
+ Title {
+ id: text2
+ }
- TextMetrics {
- id: metrics
+ TextMetrics {
+ id: metrics
- text: Hyprland.activeToplevel?.title ?? qsTr("Desktop")
- font.pointSize: Appearance.font.size.smaller
- font.family: Appearance.font.family.mono
- elide: Qt.ElideRight
- elideWidth: root.height - icon.height
+ text: Hyprland.activeToplevel?.title ?? qsTr("Desktop")
+ font.pointSize: Appearance.font.size.smaller
+ font.family: Appearance.font.family.mono
+ elide: Qt.ElideRight
+ elideWidth: root.maxHeight - icon.height
- onTextChanged: {
- const next = child.current === text1 ? text2 : text1;
- next.text = elidedText;
- child.current = next;
- }
- onElideWidthChanged: child.current.text = elidedText
- }
-
- Behavior on implicitWidth {
- NumberAnimation {
- duration: Appearance.anim.durations.normal
- easing.type: Easing.BezierSpline
- easing.bezierCurve: Appearance.anim.curves.emphasized
- }
+ onTextChanged: {
+ const next = root.current === text1 ? text2 : text1;
+ next.text = elidedText;
+ root.current = next;
}
+ onElideWidthChanged: root.current.text = elidedText
+ }
- Behavior on implicitHeight {
- NumberAnimation {
- duration: Appearance.anim.durations.normal
- easing.type: Easing.BezierSpline
- easing.bezierCurve: Appearance.anim.curves.emphasized
- }
+ Behavior on implicitHeight {
+ NumberAnimation {
+ duration: Appearance.anim.durations.normal
+ easing.type: Easing.BezierSpline
+ easing.bezierCurve: Appearance.anim.curves.emphasized
}
}
@@ -89,7 +78,7 @@ Item {
font.pointSize: metrics.font.pointSize
font.family: metrics.font.family
color: root.colour
- opacity: child.current === this ? 1 : 0
+ opacity: root.current === this ? 1 : 0
transform: Rotation {
angle: 90
diff --git a/modules/bar/components/Power.qml b/modules/bar/components/Power.qml
index 71dc296..917bdf7 100644
--- a/modules/bar/components/Power.qml
+++ b/modules/bar/components/Power.qml
@@ -2,24 +2,22 @@ import qs.components
import qs.services
import qs.config
import Quickshell
+import QtQuick
-MaterialIcon {
+Item {
id: root
required property PersistentProperties visibilities
- text: "power_settings_new"
- color: Colours.palette.m3error
- font.bold: true
- font.pointSize: Appearance.font.size.normal
+ implicitWidth: icon.implicitHeight + Appearance.padding.small * 2
+ implicitHeight: icon.implicitHeight
StateLayer {
+ // Cursed workaround to make the height larger than the parent
anchors.fill: undefined
anchors.centerIn: parent
- anchors.horizontalCenterOffset: 1
-
- implicitWidth: parent.implicitHeight + Appearance.padding.small * 2
- implicitHeight: implicitWidth
+ implicitWidth: implicitHeight
+ implicitHeight: icon.implicitHeight + Appearance.padding.small * 2
radius: Appearance.rounding.full
@@ -27,4 +25,16 @@ MaterialIcon {
root.visibilities.session = !root.visibilities.session;
}
}
+
+ MaterialIcon {
+ id: icon
+
+ anchors.centerIn: parent
+ anchors.horizontalCenterOffset: -1
+
+ text: "power_settings_new"
+ color: Colours.palette.m3error
+ font.bold: true
+ font.pointSize: Appearance.font.size.normal
+ }
}
diff --git a/modules/bar/components/StatusIcons.qml b/modules/bar/components/StatusIcons.qml
index c364d6b..f7d9828 100644
--- a/modules/bar/components/StatusIcons.qml
+++ b/modules/bar/components/StatusIcons.qml
@@ -10,51 +10,29 @@ import Quickshell.Services.UPower
import QtQuick
import QtQuick.Layouts
-Item {
+StyledRect {
id: root
property color colour: Colours.palette.m3secondary
+ readonly property alias items: iconColumn
- readonly property list<var> hoverAreas: [
- {
- name: "audio",
- item: audioIcon,
- enabled: Config.bar.status.showAudio
- },
- {
- name: "network",
- item: networkIcon,
- enabled: Config.bar.status.showNetwork
- },
- {
- name: "bluetooth",
- item: bluetoothGroup,
- enabled: Config.bar.status.showBluetooth
- },
- {
- name: "battery",
- item: batteryIcon,
- enabled: Config.bar.status.showBattery
- }
- ]
+ color: Colours.tPalette.m3surfaceContainer
+ radius: Appearance.rounding.full
clip: true
- implicitWidth: iconColumn.implicitWidth
- implicitHeight: iconColumn.implicitHeight
+ implicitWidth: iconColumn.implicitWidth + Appearance.padding.normal * 2
+ implicitHeight: iconColumn.implicitHeight + Appearance.padding.normal * 2
ColumnLayout {
id: iconColumn
- anchors.horizontalCenter: parent.horizontalCenter
+ anchors.centerIn: parent
spacing: Appearance.spacing.smaller / 2
// Audio icon
- Loader {
- id: audioIcon
-
- asynchronous: true
+ WrappedLoader {
+ name: "audio"
active: Config.bar.status.showAudio
- visible: active
sourceComponent: MaterialIcon {
animate: true
@@ -65,8 +43,6 @@ Item {
// Keyboard layout icon
Loader {
- id: kbLayout
-
Layout.alignment: Qt.AlignHCenter
asynchronous: true
active: Config.bar.status.showKbLayout
@@ -81,12 +57,9 @@ Item {
}
// Network icon
- Loader {
- id: networkIcon
-
- asynchronous: true
+ WrappedLoader {
+ name: "network"
active: Config.bar.status.showNetwork
- visible: active
sourceComponent: MaterialIcon {
animate: true
@@ -95,13 +68,10 @@ Item {
}
}
- // Bluetooth section (grouped for hover area)
- Loader {
- id: bluetoothGroup
-
- asynchronous: true
+ // Bluetooth section
+ WrappedLoader {
+ name: "bluetooth"
active: Config.bar.status.showBluetooth
- visible: active
sourceComponent: ColumnLayout {
spacing: Appearance.spacing.smaller / 2
@@ -157,12 +127,9 @@ Item {
}
// Battery icon
- Loader {
- id: batteryIcon
-
- asynchronous: true
+ WrappedLoader {
+ name: "battery"
active: Config.bar.status.showBattery
- visible: active
sourceComponent: MaterialIcon {
animate: true
@@ -194,6 +161,14 @@ Item {
Anim {}
}
+ component WrappedLoader: Loader {
+ required property string name
+
+ Layout.alignment: Qt.AlignHCenter
+ asynchronous: true
+ visible: active
+ }
+
component Anim: NumberAnimation {
duration: Appearance.anim.durations.large
easing.type: Easing.BezierSpline
diff --git a/modules/bar/components/workspaces/Workspaces.qml b/modules/bar/components/workspaces/Workspaces.qml
index 0a806f7..fb6201d 100644
--- a/modules/bar/components/workspaces/Workspaces.qml
+++ b/modules/bar/components/workspaces/Workspaces.qml
@@ -2,10 +2,11 @@ pragma ComponentBehavior: Bound
import qs.services
import qs.config
+import qs.components
import QtQuick
import QtQuick.Layouts
-Item {
+StyledRect {
id: root
readonly property list<Workspace> workspaces: layout.children.filter(c => c.isWorkspace).sort((w1, w2) => w1.ws - w2.ws)
@@ -15,60 +16,69 @@ Item {
}, {})
readonly property int groupOffset: Math.floor((Hyprland.activeWsId - 1) / Config.bar.workspaces.shown) * Config.bar.workspaces.shown
- implicitWidth: layout.implicitWidth
- implicitHeight: layout.implicitHeight
+ implicitWidth: layout.implicitWidth + Appearance.padding.small * 2
+ implicitHeight: layout.implicitHeight + Appearance.padding.small * 2
+ color: Colours.tPalette.m3surfaceContainer
+ radius: Appearance.rounding.full
- ColumnLayout {
- id: layout
+ Item {
+ id: inner
- spacing: 0
- layer.enabled: true
- layer.smooth: true
+ anchors.fill: parent
+ anchors.margins: Appearance.padding.small
- Repeater {
- model: Config.bar.workspaces.shown
+ ColumnLayout {
+ id: layout
- Workspace {
- occupied: root.occupied
- groupOffset: root.groupOffset
+ spacing: 0
+ layer.enabled: true
+ layer.smooth: true
+
+ Repeater {
+ model: Config.bar.workspaces.shown
+
+ Workspace {
+ occupied: root.occupied
+ groupOffset: root.groupOffset
+ }
}
}
- }
- Loader {
- active: Config.bar.workspaces.occupiedBg
- asynchronous: true
+ Loader {
+ active: Config.bar.workspaces.occupiedBg
+ asynchronous: true
- z: -1
- anchors.fill: parent
+ z: -1
+ anchors.fill: parent
- sourceComponent: OccupiedBg {
- workspaces: root.workspaces
- occupied: root.occupied
- groupOffset: root.groupOffset
+ sourceComponent: OccupiedBg {
+ workspaces: root.workspaces
+ occupied: root.occupied
+ groupOffset: root.groupOffset
+ }
}
- }
- Loader {
- active: Config.bar.workspaces.activeIndicator
- asynchronous: true
+ Loader {
+ active: Config.bar.workspaces.activeIndicator
+ asynchronous: true
- sourceComponent: ActiveIndicator {
- workspaces: root.workspaces
- mask: layout
- maskWidth: root.width
- maskHeight: root.height
- groupOffset: root.groupOffset
+ sourceComponent: ActiveIndicator {
+ workspaces: root.workspaces
+ mask: layout
+ maskWidth: inner.width
+ maskHeight: inner.height
+ groupOffset: root.groupOffset
+ }
}
- }
- MouseArea {
- anchors.fill: parent
+ 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}`);
+ onPressed: event => {
+ const ws = layout.childAt(event.x, event.y).index + root.groupOffset + 1;
+ if (Hyprland.activeWsId !== ws)
+ Hyprland.dispatch(`workspace ${ws}`);
+ }
}
}
}