summaryrefslogtreecommitdiff
path: root/bar
diff options
context:
space:
mode:
Diffstat (limited to 'bar')
-rw-r--r--bar/ActiveWindow.qml218
-rw-r--r--bar/Bar.qml278
-rw-r--r--bar/Mpris.qml366
-rw-r--r--bar/Network.qml204
-rw-r--r--bar/Power.qml226
-rw-r--r--bar/Resources.qml92
-rw-r--r--bar/TimeDate.qml232
-rw-r--r--bar/Workspace.qml474
-rw-r--r--bar/components/SimpleResource.qml160
9 files changed, 1125 insertions, 1125 deletions
diff --git a/bar/ActiveWindow.qml b/bar/ActiveWindow.qml
index 17d2322..0a6a547 100644
--- a/bar/ActiveWindow.qml
+++ b/bar/ActiveWindow.qml
@@ -10,113 +10,113 @@ import qs.config
// TODO use a item wrapping loader for opacity Behavior
IRect {
- id: root
- // hyprland toplevel isn't shown immediately...
- property var toplevel: ToplevelManager.activeToplevel
- property var icon: Quickshell.iconPath(AppSearch.guessIcon(toplevel?.appId), "image-missing")
-
- property var activated: toplevel?.activated || false
-
- implicitWidth: activated ? rowLayout.implicitWidth + General.rectMargin * 4 : 0
- implicitHeight: rowLayout.implicitHeight + General.rectMargin * 2 + Bar.topMargin * 2
- anchors.centerIn: parent
-
- color: Qt.rgba(Colors.background3.r, Colors.background3.g, Colors.background3.b, Bar.bgTransparency)
- // according to docs, null could happen but doesn't seem to happen in practice so..
- // hypr toplevel.activated is always true and doesn't change either so..
- opacity: activated ? 1 : 0
-
- bottomLeftRadius: Bar.moduleRadius
- bottomRightRadius: Bar.moduleRadius
-
- function strip(s) {
- var out = s;
- Bar.windowStrip.forEach(function (w) {
- out = out?.replace(new RegExp(w, "g"), "");
- });
- return out?.trim() || s;
- }
-
- RowLayout {
- id: rowLayout
- anchors.centerIn: parent
- spacing: Bar.resourceIconTextSpacing
- width: Math.min(implicitWidth, root.width)
-
- IconImage {
- id: icon
- source: root.icon
- implicitSize: General.appIconSize
-
- // sync animation
- opacity: root.activated ? 1 : 0
- Behavior on opacity {
- NumberAnimation {
- duration: General.animationDuration / 4
- }
- }
- }
-
- Item {
- Layout.fillWidth: true
- Layout.fillHeight: true
- implicitWidth: childrenRect.width
- IText {
- anchors.verticalCenter: parent.verticalCenter
- width: Math.min(implicitWidth, rowLayout.width - icon.implicitWidth)
- animate: true
- clip: true
- elide: Text.ElideRight
- font.pixelSize: General.fontSize
- text: strip(root?.toplevel?.title) || ""
-
- // sync animation
- opacity: root.activated ? 1 : 0
- Behavior on opacity {
- NumberAnimation {
- duration: General.animationDuration / 4
- }
- }
- }
- }
- }
-
- onIconChanged: fadeIcon.start()
-
- Behavior on opacity {
- NumberAnimation {
- duration: General.animationDuration / 4
- }
- }
-
- Behavior on width {
- ISpringAnimation {
- spring: General.springAnimationSpring * 2
- damping: General.springAnimationDamping * 1.3
- }
- }
-
- SequentialAnimation {
- id: fadeIcon
- running: false
-
- PropertyAnimation {
- target: icon
- property: "opacity"
- to: 0
- duration: General.animationDuration / 4
- }
- ScriptAction {
- script: icon.source = root.icon
- }
- PropertyAnimation {
- target: icon
- property: "opacity"
- to: 1
- duration: General.animationDuration / 4
- }
- ScriptAction {
- script: icon.source = root.icon
- }
- }
+ id: root
+ // hyprland toplevel isn't shown immediately...
+ property var toplevel: ToplevelManager.activeToplevel
+ property var icon: Quickshell.iconPath(AppSearch.guessIcon(toplevel?.appId), "image-missing")
+
+ property var activated: toplevel?.activated || false
+
+ implicitWidth: activated ? rowLayout.implicitWidth + General.rectMargin * 4 : 0
+ implicitHeight: rowLayout.implicitHeight + General.rectMargin * 2 + Bar.topMargin * 2
+ anchors.centerIn: parent
+
+ color: Qt.rgba(Colors.background3.r, Colors.background3.g, Colors.background3.b, Bar.bgTransparency)
+ // according to docs, null could happen but doesn't seem to happen in practice so..
+ // hypr toplevel.activated is always true and doesn't change either so..
+ opacity: activated ? 1 : 0
+
+ bottomLeftRadius: Bar.moduleRadius
+ bottomRightRadius: Bar.moduleRadius
+
+ function strip(s) {
+ var out = s;
+ Bar.windowStrip.forEach(function (w) {
+ out = out?.replace(new RegExp(w, "g"), "");
+ });
+ return out?.trim() || s;
+ }
+
+ RowLayout {
+ id: rowLayout
+ anchors.centerIn: parent
+ spacing: Bar.resourceIconTextSpacing
+ width: Math.min(implicitWidth, root.width)
+
+ IconImage {
+ id: icon
+ source: root.icon
+ implicitSize: General.appIconSize
+
+ // sync animation
+ opacity: root.activated ? 1 : 0
+ Behavior on opacity {
+ NumberAnimation {
+ duration: General.animationDuration / 4
+ }
+ }
+ }
+
+ Item {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ implicitWidth: childrenRect.width
+ IText {
+ anchors.verticalCenter: parent.verticalCenter
+ width: Math.min(implicitWidth, rowLayout.width - icon.implicitWidth)
+ animate: true
+ clip: true
+ elide: Text.ElideRight
+ font.pixelSize: General.fontSize
+ text: strip(root?.toplevel?.title) || ""
+
+ // sync animation
+ opacity: root.activated ? 1 : 0
+ Behavior on opacity {
+ NumberAnimation {
+ duration: General.animationDuration / 4
+ }
+ }
+ }
+ }
+ }
+
+ onIconChanged: fadeIcon.start()
+
+ Behavior on opacity {
+ NumberAnimation {
+ duration: General.animationDuration / 4
+ }
+ }
+
+ Behavior on width {
+ ISpringAnimation {
+ spring: General.springAnimationSpring * 2
+ damping: General.springAnimationDamping * 1.3
+ }
+ }
+
+ SequentialAnimation {
+ id: fadeIcon
+ running: false
+
+ PropertyAnimation {
+ target: icon
+ property: "opacity"
+ to: 0
+ duration: General.animationDuration / 4
+ }
+ ScriptAction {
+ script: icon.source = root.icon
+ }
+ PropertyAnimation {
+ target: icon
+ property: "opacity"
+ to: 1
+ duration: General.animationDuration / 4
+ }
+ ScriptAction {
+ script: icon.source = root.icon
+ }
+ }
}
diff --git a/bar/Bar.qml b/bar/Bar.qml
index 6b762b1..2ad13d1 100644
--- a/bar/Bar.qml
+++ b/bar/Bar.qml
@@ -5,143 +5,143 @@ import qs.components
import qs.config
Scope {
- id: root
-
- Variants {
- model: Quickshell.screens
-
- IWindow {
- id: barWindow
- name: "quickshell::bar"
-
- anchors {
- top: true
- left: true
- right: true
- }
- implicitHeight: child.implicitHeight + Bar.topMargin * 2
-
- IRect {
- id: child
- radius: Bar.borderRadius
- implicitHeight: Bar.height
- implicitWidth: parent.width
-
- anchors {
- left: parent.left
- right: parent.mid
- fill: parent
- top: parent.top
- }
-
- color: "transparent"
-
- IRect {
- id: leftRow
- anchors {
- left: parent.left
- }
- width: leftInnerRow.width + leftInnerRow.anchors.leftMargin - leftSpacer.width + Bar.leftMargin
- height: leftInnerRow.height
- color: Qt.rgba(Colors.background3.r, Colors.background3.g, Colors.background3.b, Bar.bgTransparency)
- bottomRightRadius: Bar.moduleRadius
-
- Behavior on color {
- ColorAnimation {
- duration: General.animationDuration
- easing.type: Easing.InOutQuad
- }
- }
- RowLayout {
- id: leftInnerRow
- height: child.height
- spacing: Bar.leftModuleSpacing
- anchors {
- left: parent.left
- leftMargin: Bar.moduleLeftMargin + Bar.leftMargin
- }
-
- Workspace {
- id: workspace
- // screen: barWindow.screen // multi monitor
- // Layout.minimumWidth: 400 // FIXME
- }
- Mpris {
- id: mpris
- }
- Item {
- id: leftSpacer
- Layout.fillWidth: true
- Layout.fillHeight: true
- }
- }
- }
-
- Item {
- id: centerRow
- anchors.centerIn: parent
-
- ActiveWindow {
- id: activeWindow
- width: Math.min(implicitWidth, child.width - Math.max(leftRow.width, rightRow.width) * 2 - Bar.leftMargin - Bar.rightMargin) // we don't do child.width - leftRow.width - rightRow.width because left and right width isn't symetric, and we're centered meaning we will colide into the larger width side
- }
- }
-
- IRect {
- id: rightRow
- anchors.right: parent.right
- width: rightInnerRow.width + rightInnerRow.anchors.rightMargin - rightSpacer.width
- height: rightInnerRow.height
- color: Qt.rgba(Colors.background3.r, Colors.background3.g, Colors.background3.b, Bar.bgTransparency)
- bottomLeftRadius: Bar.moduleRadius
-
- RowLayout {
- id: rightInnerRow
- anchors {
- right: parent.right
- rightMargin: Bar.moduleRightMargin
- }
- layoutDirection: Qt.RightToLeft
- height: child.height
- spacing: Bar.rightModuleSpacing
-
- Power {
- id: power
- }
- // Tray {
- // id: tray
- // }
- TimeDate {}
- Network {}
- // Temp {
- // id: temp
- // }
- // Gpu {
- // id: gpu
- // }
- // Memory {
- // id: memory
- // }
- // Cpu {
- // id: cpu
- // }
- Resources {}
-
- Item {
- id: rightSpacer
- Layout.fillWidth: true
- Layout.fillHeight: true
- }
- }
-
- Behavior on color {
- ColorAnimation {
- duration: General.animationDuration
- easing.type: Easing.InOutQuad
- }
- }
- }
- }
- }
- }
+ id: root
+
+ Variants {
+ model: Quickshell.screens
+
+ IWindow {
+ id: barWindow
+ name: "quickshell::bar"
+
+ anchors {
+ top: true
+ left: true
+ right: true
+ }
+ implicitHeight: child.implicitHeight + Bar.topMargin * 2
+
+ IRect {
+ id: child
+ radius: Bar.borderRadius
+ implicitHeight: Bar.height
+ implicitWidth: parent.width
+
+ anchors {
+ left: parent.left
+ right: parent.mid
+ fill: parent
+ top: parent.top
+ }
+
+ color: "transparent"
+
+ IRect {
+ id: leftRow
+ anchors {
+ left: parent.left
+ }
+ width: leftInnerRow.width + leftInnerRow.anchors.leftMargin - leftSpacer.width + Bar.leftMargin
+ height: leftInnerRow.height
+ color: Qt.rgba(Colors.background3.r, Colors.background3.g, Colors.background3.b, Bar.bgTransparency)
+ bottomRightRadius: Bar.moduleRadius
+
+ Behavior on color {
+ ColorAnimation {
+ duration: General.animationDuration
+ easing.type: Easing.InOutQuad
+ }
+ }
+ RowLayout {
+ id: leftInnerRow
+ height: child.height
+ spacing: Bar.leftModuleSpacing
+ anchors {
+ left: parent.left
+ leftMargin: Bar.moduleLeftMargin + Bar.leftMargin
+ }
+
+ Workspace {
+ id: workspace
+ // screen: barWindow.screen // multi monitor
+ // Layout.minimumWidth: 400 // FIXME
+ }
+ Mpris {
+ id: mpris
+ }
+ Item {
+ id: leftSpacer
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+ }
+ }
+
+ Item {
+ id: centerRow
+ anchors.centerIn: parent
+
+ ActiveWindow {
+ id: activeWindow
+ width: Math.min(implicitWidth, child.width - Math.max(leftRow.width, rightRow.width) * 2 - Bar.leftMargin - Bar.rightMargin) // we don't do child.width - leftRow.width - rightRow.width because left and right width isn't symetric, and we're centered meaning we will colide into the larger width side
+ }
+ }
+
+ IRect {
+ id: rightRow
+ anchors.right: parent.right
+ width: rightInnerRow.width + rightInnerRow.anchors.rightMargin - rightSpacer.width
+ height: rightInnerRow.height
+ color: Qt.rgba(Colors.background3.r, Colors.background3.g, Colors.background3.b, Bar.bgTransparency)
+ bottomLeftRadius: Bar.moduleRadius
+
+ RowLayout {
+ id: rightInnerRow
+ anchors {
+ right: parent.right
+ rightMargin: Bar.moduleRightMargin
+ }
+ layoutDirection: Qt.RightToLeft
+ height: child.height
+ spacing: Bar.rightModuleSpacing
+
+ Power {
+ id: power
+ }
+ // Tray {
+ // id: tray
+ // }
+ TimeDate {}
+ Network {}
+ // Temp {
+ // id: temp
+ // }
+ // Gpu {
+ // id: gpu
+ // }
+ // Memory {
+ // id: memory
+ // }
+ // Cpu {
+ // id: cpu
+ // }
+ Resources {}
+
+ Item {
+ id: rightSpacer
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+ }
+
+ Behavior on color {
+ ColorAnimation {
+ duration: General.animationDuration
+ easing.type: Easing.InOutQuad
+ }
+ }
+ }
+ }
+ }
+ }
}
diff --git a/bar/Mpris.qml b/bar/Mpris.qml
index 75f7e2d..4bed0fe 100644
--- a/bar/Mpris.qml
+++ b/bar/Mpris.qml
@@ -13,187 +13,187 @@ import qs.components
import "../utils/string_utils.js" as StringUtils
Item {
- id: root
- readonly property MprisPlayer activePlayer: Services.Mpris.activePlayer
- readonly property string cleanedTitle: StringUtils.cleanMusicTitle(activePlayer?.trackTitle)
-
- implicitWidth: activePlayer ? rect.width - General.rectMargin / 1.2 : 0
- height: Bar.height + General.rectMargin / 1.5
- opacity: activePlayer ? 1 : 0
-
- IRect {
- id: rect
- anchors.verticalCenter: parent.verticalCenter
- implicitWidth: (layout.width + General.rectMargin * 4) * (mouseArea.containsMouse ? Bar.hoverScale : 1.0)
- height: parent.height - General.rectMargin
- radius: Style.rounding.smaller
- color: "transparent"
-
- // FIXME: at the start, the progress bar's radius will make it go out of bounds. use OpacityMask or something
- Slider {
- id: pBar
- anchors.fill: parent
-
- handle: Item
- from: 0
- to: activePlayer?.length || 0
- value: activePlayer?.position || 0
- background: IRect {
- anchors.fill: parent
- color: Colors.accent
- radius: Style.rounding.smaller
- }
- contentItem: Item {
- IRect {
- width: pBar.visualPosition * parent.width
- height: parent.height
- color: Qt.rgba(Colors.accentAlt.r, Colors.accentAlt.g, Colors.accentAlt.b, General.accentTransparency * 1.5)
- radius: Style.rounding.smaller
-
- Behavior on width {
- NumberAnimation {
- duration: General.animationDuration / 2
- }
- }
- }
- }
-
- // onMoved: {
- // if (Math.round(root.activePlayer.position) !== Math.round(value)) {
- // root.activePlayer.position = value;
- // }
- // }
-
- // cannot remove and replace with modern non stealing handlers cuz otherwise slider will steal from us
- MouseArea {
- id: mouseArea
- anchors.fill: parent
- acceptedButtons: Qt.MiddleButton | Qt.RightButton | Qt.LeftButton
- cursorShape: Qt.PointingHandCursor
- hoverEnabled: true
- onClicked: mouse => {
- if (mouse.button === Qt.MiddleButton)
- root.activePlayer?.togglePlaying();
- else if (mouse.button === Qt.RightButton)
- root.activePlayer?.next();
- }
- onWheel: mouse => {
- root.activePlayer?.seek(-mouse.angleDelta.y * Bar.mediaScrollScale);
- }
- }
- }
-
- RowLayout {
- id: layout
-
- x: (parent.width - width) / 2
- y: (parent.height - height) / 2
- spacing: Bar.resourceIconTextSpacing / 1.5
-
- Behavior on x {
- ISpringAnimation {
- spring: General.springAnimationSpring * 2
- damping: General.springAnimationDamping * 1.3
- }
- }
-
- Item {
- Layout.preferredWidth: childrenRect.width
- Layout.preferredHeight: childrenRect.height
- width: General.appIconSize
- height: General.appIconSize
-
- opacity: activePlayer?.playbackState === MprisPlaybackState.Playing ? 1 : Bar.mediaPausedOpacity
-
- DropShadow {
- anchors.fill: image
- source: image
- opacity: activePlayer?.playbackState === MprisPlaybackState.Playing ? 1 : Bar.mediaPausedOpacity
- radius: 6
- color: Colors.background3
-
- Behavior on opacity {
- NumberAnimation {
- duration: General.animationDuration / 4
- easing.type: Easing.InOutQuad
- }
- }
- }
-
- ClippingWrapperRectangle {
- id: image
- anchors.fill: parent
- radius: 6
- color: "transparent"
- child: Image {
- id: albumArt
- // IconImage makes it less crisp and blurry
- anchors.fill: parent
- source: activePlayer?.trackArtUrl || Quickshell.iconPath(Services.AppSearch.guessIcon(activePlayer?.desktopEntry), "image-missing")
- antialiasing: true
- asynchronous: true
- ColorOverlay {
- property color rawColor: activePlayer?.playbackState === MprisPlaybackState.Playing ? Colors.background1 : Colors.background2
- anchors.fill: albumArt
- source: albumArt
- color: Qt.rgba(rawColor.r, rawColor.g, rawColor.b, General.accentTransparency)
-
- Behavior on color {
- ColorAnimation {
- duration: General.animationDuration / 4
- easing.type: Easing.InOutQuad
- }
- }
- }
- }
- }
-
- Behavior on opacity {
- NumberAnimation {
- duration: General.animationDuration / 4
- easing.type: Easing.InOutQuad
- }
- }
- }
- IText {
- animate: true
- color: activePlayer?.playbackState === MprisPlaybackState.Playing ? Qt.rgba(Colors.foreground1.r, Colors.foreground1.g, Colors.foreground1.b, Colors.foreground1.a) : Qt.rgba(Colors.foreground2.r, Colors.foreground2.g, Colors.foreground2.b, Bar.mediaPausedOpacity)
- text: root.cleanedTitle
-
- Behavior on opacity {
- NumberAnimation {
- duration: General.animationDuration / 4
- easing.type: Easing.InOutQuad
- }
- }
-
- Behavior on color {
- ColorAnimation {
- duration: General.animationDuration / 4
- easing.type: Easing.InOutQuad
- }
- }
- }
- }
- }
-
- Behavior on opacity {
- NumberAnimation {
- duration: General.animationDuration / 4
- }
- }
-
- Behavior on width {
- ISpringAnimation {
- spring: General.springAnimationSpring * 2
- damping: General.springAnimationDamping * 1.3
- }
- }
-
- Behavior on implicitWidth {
- ISpringAnimation {
- spring: General.springAnimationSpring * 2
- damping: General.springAnimationDamping * 1.3
- }
- }
+ id: root
+ readonly property MprisPlayer activePlayer: Services.Mpris.activePlayer
+ readonly property string cleanedTitle: StringUtils.cleanMusicTitle(activePlayer?.trackTitle)
+
+ implicitWidth: activePlayer ? rect.width - General.rectMargin / 1.2 : 0
+ height: Bar.height + General.rectMargin / 1.5
+ opacity: activePlayer ? 1 : 0
+
+ IRect {
+ id: rect
+ anchors.verticalCenter: parent.verticalCenter
+ implicitWidth: (layout.width + General.rectMargin * 4) * (mouseArea.containsMouse ? Bar.hoverScale : 1.0)
+ height: parent.height - General.rectMargin
+ radius: Style.rounding.smaller
+ color: "transparent"
+
+ // FIXME: at the start, the progress bar's radius will make it go out of bounds. use OpacityMask or something
+ Slider {
+ id: pBar
+ anchors.fill: parent
+
+ handle: Item
+ from: 0
+ to: activePlayer?.length || 0
+ value: activePlayer?.position || 0
+ background: IRect {
+ anchors.fill: parent
+ color: Colors.accent
+ radius: Style.rounding.smaller
+ }
+ contentItem: Item {
+ IRect {
+ width: pBar.visualPosition * parent.width
+ height: parent.height
+ color: Qt.rgba(Colors.accentAlt.r, Colors.accentAlt.g, Colors.accentAlt.b, General.accentTransparency * 1.5)
+ radius: Style.rounding.smaller
+
+ Behavior on width {
+ NumberAnimation {
+ duration: General.animationDuration / 2
+ }
+ }
+ }
+ }
+
+ // onMoved: {
+ // if (Math.round(root.activePlayer.position) !== Math.round(value)) {
+ // root.activePlayer.position = value;
+ // }
+ // }
+
+ // cannot remove and replace with modern non stealing handlers cuz otherwise slider will steal from us
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ acceptedButtons: Qt.MiddleButton | Qt.RightButton | Qt.LeftButton
+ cursorShape: Qt.PointingHandCursor
+ hoverEnabled: true
+ onClicked: mouse => {
+ if (mouse.button === Qt.MiddleButton)
+ root.activePlayer?.togglePlaying();
+ else if (mouse.button === Qt.RightButton)
+ root.activePlayer?.next();
+ }
+ onWheel: mouse => {
+ root.activePlayer?.seek(-mouse.angleDelta.y * Bar.mediaScrollScale);
+ }
+ }
+ }
+
+ RowLayout {
+ id: layout
+
+ x: (parent.width - width) / 2
+ y: (parent.height - height) / 2
+ spacing: Bar.resourceIconTextSpacing / 1.5
+
+ Behavior on x {
+ ISpringAnimation {
+ spring: General.springAnimationSpring * 2
+ damping: General.springAnimationDamping * 1.3
+ }
+ }
+
+ Item {
+ Layout.preferredWidth: childrenRect.width
+ Layout.preferredHeight: childrenRect.height
+ width: General.appIconSize
+ height: General.appIconSize
+
+ opacity: activePlayer?.playbackState === MprisPlaybackState.Playing ? 1 : Bar.mediaPausedOpacity
+
+ DropShadow {
+ anchors.fill: image
+ source: image
+ opacity: activePlayer?.playbackState === MprisPlaybackState.Playing ? 1 : Bar.mediaPausedOpacity
+ radius: 6
+ color: Colors.background3
+
+ Behavior on opacity {
+ NumberAnimation {
+ duration: General.animationDuration / 4
+ easing.type: Easing.InOutQuad
+ }
+ }
+ }
+
+ ClippingWrapperRectangle {
+ id: image
+ anchors.fill: parent
+ radius: 6
+ color: "transparent"
+ child: Image {
+ id: albumArt
+ // IconImage makes it less crisp and blurry
+ anchors.fill: parent
+ source: activePlayer?.trackArtUrl || Quickshell.iconPath(Services.AppSearch.guessIcon(activePlayer?.desktopEntry), "image-missing")
+ antialiasing: true
+ asynchronous: true
+ ColorOverlay {
+ property color rawColor: activePlayer?.playbackState === MprisPlaybackState.Playing ? Colors.background1 : Colors.background2
+ anchors.fill: albumArt
+ source: albumArt
+ color: Qt.rgba(rawColor.r, rawColor.g, rawColor.b, General.accentTransparency)
+
+ Behavior on color {
+ ColorAnimation {
+ duration: General.animationDuration / 4
+ easing.type: Easing.InOutQuad
+ }
+ }
+ }
+ }
+ }
+
+ Behavior on opacity {
+ NumberAnimation {
+ duration: General.animationDuration / 4
+ easing.type: Easing.InOutQuad
+ }
+ }
+ }
+ IText {
+ animate: true
+ color: activePlayer?.playbackState === MprisPlaybackState.Playing ? Qt.rgba(Colors.foreground1.r, Colors.foreground1.g, Colors.foreground1.b, Colors.foreground1.a) : Qt.rgba(Colors.foreground2.r, Colors.foreground2.g, Colors.foreground2.b, Bar.mediaPausedOpacity)
+ text: root.cleanedTitle
+
+ Behavior on opacity {
+ NumberAnimation {
+ duration: General.animationDuration / 4
+ easing.type: Easing.InOutQuad
+ }
+ }
+
+ Behavior on color {
+ ColorAnimation {
+ duration: General.animationDuration / 4
+ easing.type: Easing.InOutQuad
+ }
+ }
+ }
+ }
+ }
+
+ Behavior on opacity {
+ NumberAnimation {
+ duration: General.animationDuration / 4
+ }
+ }
+
+ Behavior on width {
+ ISpringAnimation {
+ spring: General.springAnimationSpring * 2
+ damping: General.springAnimationDamping * 1.3
+ }
+ }
+
+ Behavior on implicitWidth {
+ ISpringAnimation {
+ spring: General.springAnimationSpring * 2
+ damping: General.springAnimationDamping * 1.3
+ }
+ }
}
diff --git a/bar/Network.qml b/bar/Network.qml
index a343977..940f583 100644
--- a/bar/Network.qml
+++ b/bar/Network.qml
@@ -6,116 +6,116 @@ import qs.components
import qs.config
Item {
- id: root
- property int down: Services.NetworkUsage.down
- property string downUnit: Services.NetworkUsage.downUnit
- property int up: Services.NetworkUsage.up
- property string upUnit: Services.NetworkUsage.upUnit
+ id: root
+ property int down: Services.NetworkUsage.down
+ property string downUnit: Services.NetworkUsage.downUnit
+ property int up: Services.NetworkUsage.up
+ property string upUnit: Services.NetworkUsage.upUnit
- property int significantUsage: 30
- property string usageUnit: "M"
+ property int significantUsage: 30
+ property string usageUnit: "M"
- property bool isCollapsed: true
+ property bool isCollapsed: true
- implicitWidth: container.implicitWidth
- implicitHeight: container.implicitHeight - General.rectMargin
+ implicitWidth: container.implicitWidth
+ implicitHeight: container.implicitHeight - General.rectMargin
- IRect {
- id: container
- anchors {
- fill: parent
- verticalCenter: parent.verticalCenter
- horizontalCenter: parent.horizontalCenter
- }
+ IRect {
+ id: container
+ anchors {
+ fill: parent
+ verticalCenter: parent.verticalCenter
+ horizontalCenter: parent.horizontalCenter
+ }
- implicitWidth: layout.implicitWidth + General.rectMargin * 2
- implicitHeight: Bar.height
- color: Colors.accent
- radius: Style.rounding.large
+ implicitWidth: layout.implicitWidth + General.rectMargin * 2
+ implicitHeight: Bar.height
+ color: Colors.accent
+ radius: Style.rounding.large
- RowLayout {
- id: layout
- anchors {
- verticalCenter: parent.verticalCenter
- horizontalCenter: parent.horizontalCenter
- }
- spacing: Bar.resourceIconTextSpacing
+ RowLayout {
+ id: layout
+ anchors {
+ verticalCenter: parent.verticalCenter
+ horizontalCenter: parent.horizontalCenter
+ }
+ spacing: Bar.resourceIconTextSpacing
- Item {
- Layout.fillWidth: true
- }
+ Item {
+ Layout.fillWidth: true
+ }
- Icon {
- visible: root.isCollapsed
- text: Services.Network.state
- }
- IText {
- visible: !root.isCollapsed
- text: Services.Network.networkStrength
- renderType: Text.CurveRendering // it's not static and is rapidly updated
- }
+ Icon {
+ visible: root.isCollapsed
+ text: Services.Network.state
+ }
+ IText {
+ visible: !root.isCollapsed
+ text: Services.Network.networkStrength
+ renderType: Text.CurveRendering // it's not static and is rapidly updated
+ }
- ColumnLayout {
- // spacing: Bar.resourceIconTextSpacing / 2
- spacing: 0
- Item {
- Layout.fillHeight: true
- Layout.fillWidth: true
- }
- IText {
- animate: true
- Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
- text: root.down + root.downUnit
- color: root.downUnit == root.usageUnit && root.down > root.significantUsage ? Colors.cyan : Colors.foreground2
- renderType: Text.CurveRendering // it's not static and is rapidly updated
- }
- Icon {
- Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
- text: Icons.resource.network.download
- iconSize: Style.font.size.normal
- color: root.downUnit == root.usageUnit && root.down > root.significantUsage ? Colors.cyan : Colors.foreground2
- }
- Item {
- Layout.fillHeight: true
- Layout.fillWidth: true
- }
- }
- ColumnLayout {
- // spacing: Bar.resourceIconTextSpacing / 2
- spacing: 0
- Item {
- Layout.fillHeight: true
- Layout.fillWidth: true
- }
- Icon {
- Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
- text: Icons.resource.network.upload
- iconSize: Style.font.size.normal
- color: root.upUnit == root.usageUnit && root.up > root.significantUsage ? Colors.cyan : Colors.foreground2
- }
- IText {
- animate: true
- Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
- text: root.up + root.upUnit
- color: root.upUnit == root.usageUnit && root.up > root.significantUsage ? Colors.cyan : Colors.foreground2
- renderType: Text.CurveRendering // it's not static and is rapidly updated
- }
- Item {
- Layout.fillHeight: true
- Layout.fillWidth: true
- }
- }
+ ColumnLayout {
+ // spacing: Bar.resourceIconTextSpacing / 2
+ spacing: 0
+ Item {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+ IText {
+ animate: true
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
+ text: root.down + root.downUnit
+ color: root.downUnit == root.usageUnit && root.down > root.significantUsage ? Colors.cyan : Colors.foreground2
+ renderType: Text.CurveRendering // it's not static and is rapidly updated
+ }
+ Icon {
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
+ text: Icons.resource.network.download
+ iconSize: Style.font.size.normal
+ color: root.downUnit == root.usageUnit && root.down > root.significantUsage ? Colors.cyan : Colors.foreground2
+ }
+ Item {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+ }
+ ColumnLayout {
+ // spacing: Bar.resourceIconTextSpacing / 2
+ spacing: 0
+ Item {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+ Icon {
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
+ text: Icons.resource.network.upload
+ iconSize: Style.font.size.normal
+ color: root.upUnit == root.usageUnit && root.up > root.significantUsage ? Colors.cyan : Colors.foreground2
+ }
+ IText {
+ animate: true
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
+ text: root.up + root.upUnit
+ color: root.upUnit == root.usageUnit && root.up > root.significantUsage ? Colors.cyan : Colors.foreground2
+ renderType: Text.CurveRendering // it's not static and is rapidly updated
+ }
+ Item {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+ }
- Item {
- Layout.fillWidth: true
- }
- }
- }
- MouseArea {
- anchors.fill: container
- cursorShape: Qt.PointingHandCursor
- onClicked: {
- root.isCollapsed = !root.isCollapsed;
- }
- }
+ Item {
+ Layout.fillWidth: true
+ }
+ }
+ }
+ MouseArea {
+ anchors.fill: container
+ cursorShape: Qt.PointingHandCursor
+ onClicked: {
+ root.isCollapsed = !root.isCollapsed;
+ }
+ }
}
diff --git a/bar/Power.qml b/bar/Power.qml
index a29bc4a..289f8e8 100644
--- a/bar/Power.qml
+++ b/bar/Power.qml
@@ -8,117 +8,117 @@ import qs.components
// TODO: move to a full screen menu
Item {
- id: root
-
- implicitWidth: container.implicitWidth
- implicitHeight: container.implicitHeight
-
- property bool collapsed: true
-
- IRect {
- id: container
-
- anchors {
- fill: parent
- verticalCenter: parent.verticalCenter
- horizontalCenter: parent.horizontalCenter
- }
- implicitWidth: layout.implicitWidth + General.rectMargin * 2
- implicitHeight: Bar.height - General.rectMargin
-
- color: Colors.accent
- radius: Style.rounding.large
-
- RowLayout {
- id: layout
-
- anchors.fill: parent
- spacing: Bar.resourceIconTextSpacing
-
- Item {
- Layout.fillWidth: true
- }
-
- Icon {
- id: powerIcon
- text: Icons.power.shutdown
- font.pixelSize: Style.font.size.large
- color: Colors.red
- }
-
- Item {
- implicitWidth: root.collapsed ? 0 : loader.width
- visible: root.collapsed ? false : true
- Loader {
- id: loader
- anchors.verticalCenter: parent.verticalCenter
- active: !root.collapsed
- sourceComponent: Component {
- RowLayout {
- spacing: Bar.resourceIconTextSpacing
- Icon {
- text: Icons.power.dpms
- font.pixelSize: Style.font.size.large
- }
-
- Icon {
- text: Icons.power.lock
- font.pixelSize: Style.font.size.large
- }
-
- Icon {
- text: Icons.power.suspend
- font.pixelSize: Style.font.size.large
- }
-
- Icon {
- text: Icons.power.reboot
- font.pixelSize: Style.font.size.large
- }
- SequentialAnimation {
- running: true
- NumberAnimation {
- target: parent
- property: "opacity"
- from: 0
- to: 1
- duration: General.animationDuration / 2
- easing.type: Easing.InOutQuad
- }
- }
- }
- }
- }
- Behavior on implicitWidth {
- NumberAnimation {
- duration: General.animationDuration / 4
- easing.type: Easing.InOutQuad
- }
- }
-
- // no idea why when collapsing the width animation won't trigger
- Behavior on visible {
- NumberAnimation {
- duration: General.animationDuration / 4
- easing.type: Easing.InOutQuad
- }
- }
- }
-
- Item {
- Layout.fillWidth: true
- }
- }
-
- MouseArea {
- anchors.fill: parent
- hoverEnabled: true
- onEntered: {
- root.collapsed = false;
- }
- onExited: {
- root.collapsed = true;
- }
- }
- }
+ id: root
+
+ implicitWidth: container.implicitWidth
+ implicitHeight: container.implicitHeight
+
+ property bool collapsed: true
+
+ IRect {
+ id: container
+
+ anchors {
+ fill: parent
+ verticalCenter: parent.verticalCenter
+ horizontalCenter: parent.horizontalCenter
+ }
+ implicitWidth: layout.implicitWidth + General.rectMargin * 2
+ implicitHeight: Bar.height - General.rectMargin
+
+ color: Colors.accent
+ radius: Style.rounding.large
+
+ RowLayout {
+ id: layout
+
+ anchors.fill: parent
+ spacing: Bar.resourceIconTextSpacing
+
+ Item {
+ Layout.fillWidth: true
+ }
+
+ Icon {
+ id: powerIcon
+ text: Icons.power.shutdown
+ font.pixelSize: Style.font.size.large
+ color: Colors.red
+ }
+
+ Item {
+ implicitWidth: root.collapsed ? 0 : loader.width
+ visible: root.collapsed ? false : true
+ Loader {
+ id: loader
+ anchors.verticalCenter: parent.verticalCenter
+ active: !root.collapsed
+ sourceComponent: Component {
+ RowLayout {
+ spacing: Bar.resourceIconTextSpacing
+ Icon {
+ text: Icons.power.dpms
+ font.pixelSize: Style.font.size.large
+ }
+
+ Icon {
+ text: Icons.power.lock
+ font.pixelSize: Style.font.size.large
+ }
+
+ Icon {
+ text: Icons.power.suspend
+ font.pixelSize: Style.font.size.large
+ }
+
+ Icon {
+ text: Icons.power.reboot
+ font.pixelSize: Style.font.size.large
+ }
+ SequentialAnimation {
+ running: true
+ NumberAnimation {
+ target: parent
+ property: "opacity"
+ from: 0
+ to: 1
+ duration: General.animationDuration / 2
+ easing.type: Easing.InOutQuad
+ }
+ }
+ }
+ }
+ }
+ Behavior on implicitWidth {
+ NumberAnimation {
+ duration: General.animationDuration / 4
+ easing.type: Easing.InOutQuad
+ }
+ }
+
+ // no idea why when collapsing the width animation won't trigger
+ Behavior on visible {
+ NumberAnimation {
+ duration: General.animationDuration / 4
+ easing.type: Easing.InOutQuad
+ }
+ }
+ }
+
+ Item {
+ Layout.fillWidth: true
+ }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ hoverEnabled: true
+ onEntered: {
+ root.collapsed = false;
+ }
+ onExited: {
+ root.collapsed = true;
+ }
+ }
+ }
}
diff --git a/bar/Resources.qml b/bar/Resources.qml
index a4d2a2f..943bd52 100644
--- a/bar/Resources.qml
+++ b/bar/Resources.qml
@@ -7,53 +7,53 @@ import qs.config as Config
import qs.services as Services
Item {
- implicitWidth: container.implicitWidth
- implicitHeight: container.implicitHeight
+ implicitWidth: container.implicitWidth
+ implicitHeight: container.implicitHeight
- IRect {
- id: container
- implicitWidth: layout.implicitWidth + Config.General.rectMargin * 2
- implicitHeight: Config.Bar.height - Config.General.rectMargin
+ IRect {
+ id: container
+ implicitWidth: layout.implicitWidth + Config.General.rectMargin * 2
+ implicitHeight: Config.Bar.height - Config.General.rectMargin
- color: Config.Colors.accent
- radius: Config.Style.rounding.large
+ color: Config.Colors.accent
+ radius: Config.Style.rounding.large
- Row {
- id: layout
- anchors.centerIn: parent
- SimpleResource {
- value: Math.round(Services.Resource.cpuUsage * 100)
- altValue: Math.round(Services.Resource.cpuFreq / 10) / 100
- suffix: "%"
- altSuffix: "GHz"
- icon: Config.Icons.resource.cpu
- }
- SimpleResource {
- icon: Config.Icons.resource.memory
- value: Math.round(Services.Resource.memoryUsedPercentage * 100)
- altValue: Math.round(Services.Resource.memoryUsed / 1024 / 1024)
- suffix: "%"
- altSuffix: "GB"
- }
- SimpleResource {
- icon: Config.Icons.resource.gpu
- value: Services.Resource.gpuUsage
- altValue: Services.Resource.gpuTemp
- suffix: "%"
- altSuffix: "°C"
- altIcon: Config.Icons.resource.temp
- thresholdL1: 60
- thresholdL2: 70
- thresholdL3: 80
- }
- SimpleResource {
- icon: Config.Icons.resource.temp
- value: Math.round(Services.Resource.cpuTemp * 100)
- suffix: "°C"
- thresholdL1: 60
- thresholdL2: 80
- thresholdL3: 90
- }
- }
- }
+ Row {
+ id: layout
+ anchors.centerIn: parent
+ SimpleResource {
+ value: Math.round(Services.Resource.cpuUsage * 100)
+ altValue: Math.round(Services.Resource.cpuFreq / 10) / 100
+ suffix: "%"
+ altSuffix: "GHz"
+ icon: Config.Icons.resource.cpu
+ }
+ SimpleResource {
+ icon: Config.Icons.resource.memory
+ value: Math.round(Services.Resource.memoryUsedPercentage * 100)
+ altValue: Math.round(Services.Resource.memoryUsed / 1024 / 1024)
+ suffix: "%"
+ altSuffix: "GB"
+ }
+ SimpleResource {
+ icon: Config.Icons.resource.gpu
+ value: Services.Resource.gpuUsage
+ altValue: Services.Resource.gpuTemp
+ suffix: "%"
+ altSuffix: "°C"
+ altIcon: Config.Icons.resource.temp
+ thresholdL1: 60
+ thresholdL2: 70
+ thresholdL3: 80
+ }
+ SimpleResource {
+ icon: Config.Icons.resource.temp
+ value: Math.round(Services.Resource.cpuTemp * 100)
+ suffix: "°C"
+ thresholdL1: 60
+ thresholdL2: 80
+ thresholdL3: 90
+ }
+ }
+ }
}
diff --git a/bar/TimeDate.qml b/bar/TimeDate.qml
index 2716e6d..ddeca47 100644
--- a/bar/TimeDate.qml
+++ b/bar/TimeDate.qml
@@ -6,128 +6,128 @@ import qs.components
import qs.config
Item {
- id: root
+ id: root
- property bool isAlt: false
- property bool isCollapsed: false
+ property bool isAlt: false
+ property bool isCollapsed: false
- implicitWidth: container.implicitWidth
- implicitHeight: container.implicitHeight - General.rectMargin
- IRect {
- id: container
- anchors {
- fill: parent
- centerIn: parent
- }
+ implicitWidth: container.implicitWidth
+ implicitHeight: container.implicitHeight - General.rectMargin
+ IRect {
+ id: container
+ anchors {
+ fill: parent
+ centerIn: parent
+ }
- // implicitWidth: !isAlt ? nonAlt.implicitWidth + General.rectMargin * 2 : alt.implicitWidth + General.rectMargin * 2
- implicitWidth: layout.width + General.rectMargin * 2
- implicitHeight: Bar.height
+ // implicitWidth: !isAlt ? nonAlt.implicitWidth + General.rectMargin * 2 : alt.implicitWidth + General.rectMargin * 2
+ implicitWidth: layout.width + General.rectMargin * 2
+ implicitHeight: Bar.height
- color: Colors.accent
- radius: Style.rounding.large
+ color: Colors.accent
+ radius: Style.rounding.large
- RowLayout {
- id: layout
- anchors.centerIn: parent
- spacing: Bar.resourceIconTextSpacing
- Loader {
- sourceComponent: !root.isAlt ? main : alt
- readonly property Component main: Component {
- RowLayout {
- id: root
- property int h: Services.TimeDate.hours
- property int m: Services.TimeDate.minutes
- property int s: Services.TimeDate.seconds
+ RowLayout {
+ id: layout
+ anchors.centerIn: parent
+ spacing: Bar.resourceIconTextSpacing
+ Loader {
+ sourceComponent: !root.isAlt ? main : alt
+ readonly property Component main: Component {
+ RowLayout {
+ id: root
+ property int h: Services.TimeDate.hours
+ property int m: Services.TimeDate.minutes
+ property int s: Services.TimeDate.seconds
- Item {
- Layout.fillWidth: true
- }
- anchors.centerIn: parent
- spacing: Bar.resourceIconTextSpacing
+ Item {
+ Layout.fillWidth: true
+ }
+ anchors.centerIn: parent
+ spacing: Bar.resourceIconTextSpacing
- Icon {
- text: Icons.resource.clock[root.h - 1]
- font.pixelSize: Style.font.size.larger
- }
- RowLayout {
- spacing: 0
- IText {
- animate: true
- text: (root.h >= 10 ? "" : "0") + root.h
- }
- IText {
- text: ":"
- renderType: Text.CurveRendering
- }
- IText {
- animate: true
- text: (root.m >= 10 ? "" : "0") + root.m
- }
- IText {
- text: ":"
- renderType: Text.CurveRendering
- }
- IText {
- animate: true
- text: (root.s >= 10 ? "" : "0") + root.s
- renderType: Text.QtRendering // it's not static and is rapidly updated
- }
- }
- Item {
- Layout.fillWidth: true
- }
- SequentialAnimation {
- running: true
- NumberAnimation {
- target: parent
- property: "opacity"
- from: 0
- to: 1
- duration: General.animationDuration / 2
- }
- }
- }
- }
- readonly property Component alt: Component {
- RowLayout {
- Item {
- Layout.fillWidth: true
- }
- anchors.centerIn: parent
- spacing: Bar.resourceIconTextSpacing
+ Icon {
+ text: Icons.resource.clock[root.h - 1]
+ font.pixelSize: Style.font.size.larger
+ }
+ RowLayout {
+ spacing: 0
+ IText {
+ animate: true
+ text: (root.h >= 10 ? "" : "0") + root.h
+ }
+ IText {
+ text: ":"
+ renderType: Text.CurveRendering
+ }
+ IText {
+ animate: true
+ text: (root.m >= 10 ? "" : "0") + root.m
+ }
+ IText {
+ text: ":"
+ renderType: Text.CurveRendering
+ }
+ IText {
+ animate: true
+ text: (root.s >= 10 ? "" : "0") + root.s
+ renderType: Text.QtRendering // it's not static and is rapidly updated
+ }
+ }
+ Item {
+ Layout.fillWidth: true
+ }
+ SequentialAnimation {
+ running: true
+ NumberAnimation {
+ target: parent
+ property: "opacity"
+ from: 0
+ to: 1
+ duration: General.animationDuration / 2
+ }
+ }
+ }
+ }
+ readonly property Component alt: Component {
+ RowLayout {
+ Item {
+ Layout.fillWidth: true
+ }
+ anchors.centerIn: parent
+ spacing: Bar.resourceIconTextSpacing
- Icon {
- text: Icons.resource.calendar
- font.pixelSize: Style.font.size.larger
- }
- IText {
- animate: true
- text: Services.TimeDate.date
- }
- Item {
- Layout.fillWidth: true
- }
- SequentialAnimation {
- running: true
- NumberAnimation {
- target: parent
- property: "opacity"
- from: 0
- to: 1
- duration: General.animationDuration / 2
- }
- }
- }
- }
- }
- }
- }
- MouseArea {
- anchors.fill: parent
- cursorShape: Qt.PointingHandCursor
- onPressed: {
- root.isAlt = !root.isAlt;
- }
- }
+ Icon {
+ text: Icons.resource.calendar
+ font.pixelSize: Style.font.size.larger
+ }
+ IText {
+ animate: true
+ text: Services.TimeDate.date
+ }
+ Item {
+ Layout.fillWidth: true
+ }
+ SequentialAnimation {
+ running: true
+ NumberAnimation {
+ target: parent
+ property: "opacity"
+ from: 0
+ to: 1
+ duration: General.animationDuration / 2
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ MouseArea {
+ anchors.fill: parent
+ cursorShape: Qt.PointingHandCursor
+ onPressed: {
+ root.isAlt = !root.isAlt;
+ }
+ }
}
diff --git a/bar/Workspace.qml b/bar/Workspace.qml
index 52f2d1b..51c4ba4 100644
--- a/bar/Workspace.qml
+++ b/bar/Workspace.qml
@@ -6,241 +6,241 @@ import qs.config
import qs.components
Item {
- id: root
-
- implicitWidth: layout.implicitWidth
-
- property var ws: Hyprland.workspaces
- property var toplevels: Hyprland.toplevels.values // update activeOccupied when toplevels changes as getWorkspaceStat's return is non reactive
-
- property int activeIndex: -1
- property bool activeOccupied: false
- property bool toChild: false
-
- function getWorkspaceStats(index) {
- const w = ws.values.find(i => i.id === index + 1);
- return {
- isOccupied: w?.toplevels?.values?.length,
- isActive: w?.active,
- isUrgent: w?.urgent
- };
- }
-
- onToplevelsChanged: {
- Qt.callLater(() => {
- activeOccupied = getWorkspaceStats(activeIndex).isOccupied || false;
- });
- }
-
- DropShadow {
- anchors.fill: activeRect
- source: activeRect
- radius: 8
- cached: true
- color: root.activeOccupied ? Colors.accent : Colors.foreground1
- opacity: root.activeOccupied ? Bar.wsActiveOpacity : Bar.wsEmptyOpacity / 3
-
- Behavior on color {
- ColorAnimation {
- duration: Bar.wsAnimationDuration
- easing.type: Easing.InOutQuad
- }
- }
- Behavior on opacity {
- NumberAnimation {
- duration: Bar.wsAnimationDuration
- easing.type: Easing.InOutQuad
- }
- }
- }
- IRect {
- id: activeRect
- x: layout.x + root.activeIndex * Bar.wsIconSize + root.activeIndex * Bar.wsSpacing
- anchors.verticalCenter: layout.verticalCenter
- implicitWidth: Bar.wsActiveIconSize
- implicitHeight: Bar.wsIconSize - Bar.wsHorizontalSpacing
- radius: Bar.wsRounding
- color: root.activeOccupied ? Colors.accent : Colors.foreground1
- opacity: root.activeOccupied ? Bar.wsActiveOpacity : Bar.wsEmptyOpacity / 3
- Behavior on x {
- ISpringAnimation {}
- }
- Behavior on color {
- ColorAnimation {
- duration: Bar.wsAnimationDuration
- easing.type: Easing.InOutQuad
- }
- }
- Behavior on opacity {
- NumberAnimation {
- duration: Bar.wsAnimationDuration
- easing.type: Easing.InOutQuad
- }
- }
- Behavior on width {
- NumberAnimation {
- duration: Bar.wsAnimationDuration
- easing.type: Easing.InOutQuad
- }
- }
- }
-
- RowLayout {
- id: layout
- anchors.verticalCenter: parent.verticalCenter
- implicitWidth: repeater.width
- spacing: Bar.wsSpacing
-
- Repeater {
- id: repeater
- model: Bar.wss
-
- IRect {
- property var st: getWorkspaceStats(index)
- property bool active: st?.isActive || false
-
- implicitWidth: active ? Bar.wsActiveIconSize : Bar.wsIconSize
- implicitHeight: Bar.wsIconSize - Bar.wsHorizontalSpacing
- radius: Bar.wsRounding
- color: st.isOccupied ? Colors.accent : Colors.foreground1
- opacity: active && st.isOccupied ? Bar.wsActiveOpacity : st.isOccupied ? Bar.wsOpacity : Bar.wsEmptyOpacity
-
- Icon {
- anchors.centerIn: parent
- text: !st.isUrgent ? Icons.ws[index + 1] : Icons.ws['urgent']
- font.pixelSize: !active ? Bar.wsIconSize / 2 : Bar.wsActiveIconSize / 2.5
- opacity: !st.isOccupied ? 0 : 1
- color: !st.isUrgent ? !st.isActive ? Colors.foreground2 : Colors.foreground1 : Colors.red
- Behavior on font.pixelSize {
- ISpringAnimation {}
- }
- Behavior on color {
- ColorAnimation {
- duration: Bar.wsAnimationDuration
- easing.type: Easing.InOutQuad
- }
- }
- }
-
- MouseArea {
- anchors {
- fill: parent
- topMargin: Bar.wsExtraMouseArea * -1
- bottomMargin: Bar.wsExtraMouseArea * -1
- }
-
- acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
- hoverEnabled: true
-
- onPressed: {
- if (!parent.active)
- Hyprland.dispatch(`hl.dsp.focus({ workspace = '${index + 1}' })`);
- }
- function moveActive() {
- activeRect.x = parent.x;
- root.activeOccupied = st.isOccupied || false;
- activeRect.implicitWidth = active ? Bar.wsActiveIconSize : Bar.wsIconSize;
- }
- onEntered: {
- root.toChild = true;
- moveActive();
- }
- // https://github.com/quickshell-mirror/quickshell/issues/118
- // onEntered: {
- // moveActive();
- // }
- onExited: {
- root.toChild = false;
- // outer MouseArea will handle this
- // if (!active && previousActiveIndex >= 0) {
- // // just in case
- // activeRect.x = layout.x + previousActiveIndex * Bar.wsIconSize + previousActiveIndex * Bar.wsSpacing;
- // activeRect.implicitWidth = Bar.wsActiveIconSize;
- // // root.activeOccupied = parent.st.isOccupied || false;
- // root.activeOccupied = getWorkspaceStats(previousActiveIndex).isOccupied || false;
- // previousActiveIndex = -1;
- // }
- }
- onWheel: event => {
- // no idea wats wrong w/ prev so we just unify it to use +/- 1
- if (event.angleDelta.y < 0) {
- if (activeIndex + 1 < Bar.wss)
- Hyprland.dispatch(`hl.dsp.focus({ workspace = '+1' })`);
- else
- Hyprland.dispatch(`hl.dsp.focus({ workspace = '1' })`);
- } else if (event.angleDelta.y > 0) {
- if (activeIndex + 1 > 1) {
- Hyprland.dispatch(`hl.dsp.focus({ workspace = '-1' })`);
- } else if (Bar.wss > 1) {
- Hyprland.dispatch(`hl.dsp.focus({ workspace = '${Bar.wss}' })`);
- }
- }
- }
- }
-
- Behavior on opacity {
- NumberAnimation {
- duration: Bar.wsAnimationDuration
- easing.type: Easing.InOutQuad
- }
- }
- Behavior on implicitWidth {
- NumberAnimation {
- duration: Bar.wsAnimationDuration
- easing.type: Easing.InOutQuad
- }
- }
- Behavior on color {
- ColorAnimation {
- duration: Bar.wsAnimationDuration
- easing.type: Easing.InOutQuad
- }
- }
-
- onActiveChanged: if (active) {
- root.activeIndex = index;
- root.activeOccupied = st.isOccupied;
- activeRect.implicitWidth = Bar.wsActiveIconSize;
- }
- }
- }
- }
- MouseArea {
- height: Bar.height
- width: parent.width
- hoverEnabled: true
- z: -1000 // to be below the child's MouseArea
- acceptedButtons: Qt.MiddleButton
-
- // sync w the inner MouseArea
- // https://github.com/quickshell-mirror/quickshell/issues/118 // but onEnter won't update the mouseX
- onEntered: {
- const abovedItemIndex = Math.round((mouseX - layout.x) / (Bar.wsIconSize + Bar.wsSpacing)) - 1; // TODO: workspaceActiveIconSize might be before
- activeRect.x = mouseX - activeRect.width / 2;
- root.activeOccupied = root.getWorkspaceStats(abovedItemIndex).isOccupied || false;
- activeRect.implicitWidth = root.activeIndex === abovedItemIndex ? Bar.wsActiveIconSize : Bar.wsIconSize;
- }
- onExited: {
- if (!root.toChild && root.activeIndex >= 0) {
- // just in case
- activeRect.x = layout.x + root.activeIndex * Bar.wsIconSize + root.activeIndex * Bar.wsSpacing;
- activeRect.implicitWidth = Bar.wsActiveIconSize;
- root.activeOccupied = root.getWorkspaceStats(root.activeIndex).isOccupied || false;
- }
- }
- onWheel: event => {
- // no idea wats wrong w/ prev so we just unify it to use +/- 1
- if (event.angleDelta.y < 0) {
- if (root.activeIndex + 1 < Bar.wss)
- Hyprland.dispatch(`hl.dsp.focus({ workspace = '+1' })`);
- else
- Hyprland.dispatch(`hl.dsp.focus({ workspace = '1' })`);
- } else if (event.angleDelta.y > 0) {
- if (root.activeIndex + 1 > 1)
- Hyprland.dispatch(`hl.dsp.focus({ workspace = '1' })`);
- else if (Bar.wss > 1)
- Hyprland.dispatch(`hl.dsp.focus({ workspace = '${Bar.wss}' })`);
- }
- }
- }
+ id: root
+
+ implicitWidth: layout.implicitWidth
+
+ property var ws: Hyprland.workspaces
+ property var toplevels: Hyprland.toplevels.values // update activeOccupied when toplevels changes as getWorkspaceStat's return is non reactive
+
+ property int activeIndex: -1
+ property bool activeOccupied: false
+ property bool toChild: false
+
+ function getWorkspaceStats(index) {
+ const w = ws.values.find(i => i.id === index + 1);
+ return {
+ isOccupied: w?.toplevels?.values?.length,
+ isActive: w?.active,
+ isUrgent: w?.urgent
+ };
+ }
+
+ onToplevelsChanged: {
+ Qt.callLater(() => {
+ activeOccupied = getWorkspaceStats(activeIndex).isOccupied || false;
+ });
+ }
+
+ DropShadow {
+ anchors.fill: activeRect
+ source: activeRect
+ radius: 8
+ cached: true
+ color: root.activeOccupied ? Colors.accent : Colors.foreground1
+ opacity: root.activeOccupied ? Bar.wsActiveOpacity : Bar.wsEmptyOpacity / 3
+
+ Behavior on color {
+ ColorAnimation {
+ duration: Bar.wsAnimationDuration
+ easing.type: Easing.InOutQuad
+ }
+ }
+ Behavior on opacity {
+ NumberAnimation {
+ duration: Bar.wsAnimationDuration
+ easing.type: Easing.InOutQuad
+ }
+ }
+ }
+ IRect {
+ id: activeRect
+ x: layout.x + root.activeIndex * Bar.wsIconSize + root.activeIndex * Bar.wsSpacing
+ anchors.verticalCenter: layout.verticalCenter
+ implicitWidth: Bar.wsActiveIconSize
+ implicitHeight: Bar.wsIconSize - Bar.wsHorizontalSpacing
+ radius: Bar.wsRounding
+ color: root.activeOccupied ? Colors.accent : Colors.foreground1
+ opacity: root.activeOccupied ? Bar.wsActiveOpacity : Bar.wsEmptyOpacity / 3
+ Behavior on x {
+ ISpringAnimation {}
+ }
+ Behavior on color {
+ ColorAnimation {
+ duration: Bar.wsAnimationDuration
+ easing.type: Easing.InOutQuad
+ }
+ }
+ Behavior on opacity {
+ NumberAnimation {
+ duration: Bar.wsAnimationDuration
+ easing.type: Easing.InOutQuad
+ }
+ }
+ Behavior on width {
+ NumberAnimation {
+ duration: Bar.wsAnimationDuration
+ easing.type: Easing.InOutQuad
+ }
+ }
+ }
+
+ RowLayout {
+ id: layout
+ anchors.verticalCenter: parent.verticalCenter
+ implicitWidth: repeater.width
+ spacing: Bar.wsSpacing
+
+ Repeater {
+ id: repeater
+ model: Bar.wss
+
+ IRect {
+ property var st: getWorkspaceStats(index)
+ property bool active: st?.isActive || false
+
+ implicitWidth: active ? Bar.wsActiveIconSize : Bar.wsIconSize
+ implicitHeight: Bar.wsIconSize - Bar.wsHorizontalSpacing
+ radius: Bar.wsRounding
+ color: st.isOccupied ? Colors.accent : Colors.foreground1
+ opacity: active && st.isOccupied ? Bar.wsActiveOpacity : st.isOccupied ? Bar.wsOpacity : Bar.wsEmptyOpacity
+
+ Icon {
+ anchors.centerIn: parent
+ text: !st.isUrgent ? Icons.ws[index + 1] : Icons.ws['urgent']
+ font.pixelSize: !active ? Bar.wsIconSize / 2 : Bar.wsActiveIconSize / 2.5
+ opacity: !st.isOccupied ? 0 : 1
+ color: !st.isUrgent ? !st.isActive ? Colors.foreground2 : Colors.foreground1 : Colors.red
+ Behavior on font.pixelSize {
+ ISpringAnimation {}
+ }
+ Behavior on color {
+ ColorAnimation {
+ duration: Bar.wsAnimationDuration
+ easing.type: Easing.InOutQuad
+ }
+ }
+ }
+
+ MouseArea {
+ anchors {
+ fill: parent
+ topMargin: Bar.wsExtraMouseArea * -1
+ bottomMargin: Bar.wsExtraMouseArea * -1
+ }
+
+ acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
+ hoverEnabled: true
+
+ onPressed: {
+ if (!parent.active)
+ Hyprland.dispatch(`hl.dsp.focus({ workspace = '${index + 1}' })`);
+ }
+ function moveActive() {
+ activeRect.x = parent.x;
+ root.activeOccupied = st.isOccupied || false;
+ activeRect.implicitWidth = active ? Bar.wsActiveIconSize : Bar.wsIconSize;
+ }
+ onEntered: {
+ root.toChild = true;
+ moveActive();
+ }
+ // https://github.com/quickshell-mirror/quickshell/issues/118
+ // onEntered: {
+ // moveActive();
+ // }
+ onExited: {
+ root.toChild = false;
+ // outer MouseArea will handle this
+ // if (!active && previousActiveIndex >= 0) {
+ // // just in case
+ // activeRect.x = layout.x + previousActiveIndex * Bar.wsIconSize + previousActiveIndex * Bar.wsSpacing;
+ // activeRect.implicitWidth = Bar.wsActiveIconSize;
+ // // root.activeOccupied = parent.st.isOccupied || false;
+ // root.activeOccupied = getWorkspaceStats(previousActiveIndex).isOccupied || false;
+ // previousActiveIndex = -1;
+ // }
+ }
+ onWheel: event => {
+ // no idea wats wrong w/ prev so we just unify it to use +/- 1
+ if (event.angleDelta.y < 0) {
+ if (activeIndex + 1 < Bar.wss)
+ Hyprland.dispatch(`hl.dsp.focus({ workspace = '+1' })`);
+ else
+ Hyprland.dispatch(`hl.dsp.focus({ workspace = '1' })`);
+ } else if (event.angleDelta.y > 0) {
+ if (activeIndex + 1 > 1) {
+ Hyprland.dispatch(`hl.dsp.focus({ workspace = '-1' })`);
+ } else if (Bar.wss > 1) {
+ Hyprland.dispatch(`hl.dsp.focus({ workspace = '${Bar.wss}' })`);
+ }
+ }
+ }
+ }
+
+ Behavior on opacity {
+ NumberAnimation {
+ duration: Bar.wsAnimationDuration
+ easing.type: Easing.InOutQuad
+ }
+ }
+ Behavior on implicitWidth {
+ NumberAnimation {
+ duration: Bar.wsAnimationDuration
+ easing.type: Easing.InOutQuad
+ }
+ }
+ Behavior on color {
+ ColorAnimation {
+ duration: Bar.wsAnimationDuration
+ easing.type: Easing.InOutQuad
+ }
+ }
+
+ onActiveChanged: if (active) {
+ root.activeIndex = index;
+ root.activeOccupied = st.isOccupied;
+ activeRect.implicitWidth = Bar.wsActiveIconSize;
+ }
+ }
+ }
+ }
+ MouseArea {
+ height: Bar.height
+ width: parent.width
+ hoverEnabled: true
+ z: -1000 // to be below the child's MouseArea
+ acceptedButtons: Qt.MiddleButton
+
+ // sync w the inner MouseArea
+ // https://github.com/quickshell-mirror/quickshell/issues/118 // but onEnter won't update the mouseX
+ onEntered: {
+ const abovedItemIndex = Math.round((mouseX - layout.x) / (Bar.wsIconSize + Bar.wsSpacing)) - 1; // TODO: workspaceActiveIconSize might be before
+ activeRect.x = mouseX - activeRect.width / 2;
+ root.activeOccupied = root.getWorkspaceStats(abovedItemIndex).isOccupied || false;
+ activeRect.implicitWidth = root.activeIndex === abovedItemIndex ? Bar.wsActiveIconSize : Bar.wsIconSize;
+ }
+ onExited: {
+ if (!root.toChild && root.activeIndex >= 0) {
+ // just in case
+ activeRect.x = layout.x + root.activeIndex * Bar.wsIconSize + root.activeIndex * Bar.wsSpacing;
+ activeRect.implicitWidth = Bar.wsActiveIconSize;
+ root.activeOccupied = root.getWorkspaceStats(root.activeIndex).isOccupied || false;
+ }
+ }
+ onWheel: event => {
+ // no idea wats wrong w/ prev so we just unify it to use +/- 1
+ if (event.angleDelta.y < 0) {
+ if (root.activeIndex + 1 < Bar.wss)
+ Hyprland.dispatch(`hl.dsp.focus({ workspace = '+1' })`);
+ else
+ Hyprland.dispatch(`hl.dsp.focus({ workspace = '1' })`);
+ } else if (event.angleDelta.y > 0) {
+ if (root.activeIndex + 1 > 1)
+ Hyprland.dispatch(`hl.dsp.focus({ workspace = '1' })`);
+ else if (Bar.wss > 1)
+ Hyprland.dispatch(`hl.dsp.focus({ workspace = '${Bar.wss}' })`);
+ }
+ }
+ }
}
diff --git a/bar/components/SimpleResource.qml b/bar/components/SimpleResource.qml
index 5e873f9..cb2fef6 100644
--- a/bar/components/SimpleResource.qml
+++ b/bar/components/SimpleResource.qml
@@ -6,95 +6,95 @@ import qs.components
import QtQuick.Controls
Item {
- id: root
+ id: root
- // TODO: use https://quickshell.org/docs/master/types/Quickshell/PopupWindow/ for tooltip
+ // TODO: use https://quickshell.org/docs/master/types/Quickshell/PopupWindow/ for tooltip
- required property real value
- required property string suffix // unit
- required property string icon
- property string altValue: value
- property string altSuffix: suffix
- property string altIcon: icon
- property string text: root.value + root.suffix
- property string altText: root.altValue + root.altSuffix
- property real thresholdL1: 40
- property real thresholdL2: thresholdL1 * 1.5
- property real thresholdL3: thresholdL2 * 1.5
- property color thresholdColorL1: Colors.cyan
- property color thresholdColorL2: Colors.yellow
- property color thresholdColorL3: Colors.red
+ required property real value
+ required property string suffix // unit
+ required property string icon
+ property string altValue: value
+ property string altSuffix: suffix
+ property string altIcon: icon
+ property string text: root.value + root.suffix
+ property string altText: root.altValue + root.altSuffix
+ property real thresholdL1: 40
+ property real thresholdL2: thresholdL1 * 1.5
+ property real thresholdL3: thresholdL2 * 1.5
+ property color thresholdColorL1: Colors.cyan
+ property color thresholdColorL2: Colors.yellow
+ property color thresholdColorL3: Colors.red
- property bool isAlt: false
+ property bool isAlt: false
- property color color: value < thresholdL1 ? Colors.accentAlt : value >= thresholdL3 ? thresholdColorL3 : value >= thresholdL2 ? thresholdColorL2 : thresholdColorL1
+ property color color: value < thresholdL1 ? Colors.accentAlt : value >= thresholdL3 ? thresholdColorL3 : value >= thresholdL2 ? thresholdColorL2 : thresholdColorL1
- implicitWidth: layout.implicitWidth
- implicitHeight: layout.implicitHeight
+ implicitWidth: layout.implicitWidth
+ implicitHeight: layout.implicitHeight
- RowLayout {
- id: layout
+ RowLayout {
+ id: layout
- spacing: 0
+ spacing: 0
- Item {
- Layout.fillWidth: true
- }
+ Item {
+ Layout.fillWidth: true
+ }
- IRect {
- Layout.fillWidth: true
- Layout.fillHeight: true
- implicitWidth: m_icon.width + General.rectMargin * 2
- implicitHeight: Bar.height - General.rectMargin
- color: "transparent"
- Slider {
- id: pBar
- anchors.fill: parent
- handle: Item
- from: 0
- to: 100
- value: !root.isAlt ? root.value : root.altValue
- background: IRect {
- anchors.fill: parent
- color: "transparent"
- // radius: Style.rounding.smaller
- }
- contentItem: Item {
- IRect {
- anchors.bottom: parent.bottom
- width: parent.width
- height: parent.height * pBar.visualPosition
- color: Qt.rgba(root.color.r, root.color.g, root.color.b, General.accentTransparency * 1.5)
- radius: Style.rounding.smaller
+ IRect {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ implicitWidth: m_icon.width + General.rectMargin * 2
+ implicitHeight: Bar.height - General.rectMargin
+ color: "transparent"
+ Slider {
+ id: pBar
+ anchors.fill: parent
+ handle: Item
+ from: 0
+ to: 100
+ value: !root.isAlt ? root.value : root.altValue
+ background: IRect {
+ anchors.fill: parent
+ color: "transparent"
+ // radius: Style.rounding.smaller
+ }
+ contentItem: Item {
+ IRect {
+ anchors.bottom: parent.bottom
+ width: parent.width
+ height: parent.height * pBar.visualPosition
+ color: Qt.rgba(root.color.r, root.color.g, root.color.b, General.accentTransparency * 1.5)
+ radius: Style.rounding.smaller
- Behavior on height {
- NumberAnimation {
- duration: General.animationDuration / 2
- }
- }
- }
- }
- }
- Icon {
- id: m_icon
- anchors {
- centerIn: parent
- }
- iconSize: Style.font.size.small
- text: !root.isAlt ? root.icon : root.altIcon
- color: root.value < root.thresholdL1 ? Colors.foreground2 : root.value >= root.thresholdL3 ? root.thresholdColorL3 : root.value >= root.thresholdL2 ? root.thresholdColorL2 : root.thresholdColorL1
- }
- }
+ Behavior on height {
+ NumberAnimation {
+ duration: General.animationDuration / 2
+ }
+ }
+ }
+ }
+ }
+ Icon {
+ id: m_icon
+ anchors {
+ centerIn: parent
+ }
+ iconSize: Style.font.size.small
+ text: !root.isAlt ? root.icon : root.altIcon
+ color: root.value < root.thresholdL1 ? Colors.foreground2 : root.value >= root.thresholdL3 ? root.thresholdColorL3 : root.value >= root.thresholdL2 ? root.thresholdColorL2 : root.thresholdColorL1
+ }
+ }
- Item {
- Layout.fillWidth: true
- }
- }
- MouseArea {
- anchors.fill: parent
- cursorShape: altValue != value ? Qt.PointingHandCursor : Qt.ArrowCursor
- onPressed: {
- root.isAlt = !root.isAlt;
- }
- }
+ Item {
+ Layout.fillWidth: true
+ }
+ }
+ MouseArea {
+ anchors.fill: parent
+ cursorShape: altValue != value ? Qt.PointingHandCursor : Qt.ArrowCursor
+ onPressed: {
+ root.isAlt = !root.isAlt;
+ }
+ }
}