feat(quickshell): add dense telemetry bar #4
@@ -5,7 +5,6 @@ import qs.widgets.bar
|
|||||||
import qs.widgets.launcher
|
import qs.widgets.launcher
|
||||||
import qs.widgets.notifications
|
import qs.widgets.notifications
|
||||||
import qs.widgets.osd
|
import qs.widgets.osd
|
||||||
import qs.widgets.sidebar
|
|
||||||
import qs.widgets.systray
|
import qs.widgets.systray
|
||||||
import qs.widgets.vitals
|
import qs.widgets.vitals
|
||||||
|
|
||||||
@@ -13,11 +12,7 @@ Scope {
|
|||||||
// Dense multi-monitor status rail; visual core is headlessly renderable.
|
// Dense multi-monitor status rail; visual core is headlessly renderable.
|
||||||
DenseBar {}
|
DenseBar {}
|
||||||
|
|
||||||
// Left sidebar in the Slant (V6) style — toggle with SUPER CTRL S.
|
// App launcher variants — SUPER CTRL 1–8; variant 8 is the primary HUD.
|
||||||
SideBar {}
|
|
||||||
BarBottom {}
|
|
||||||
|
|
||||||
// App launcher variants — 1–10; variant 8 remains the primary HUD.
|
|
||||||
LauncherStack {} // 1 — left vertical list
|
LauncherStack {} // 1 — left vertical list
|
||||||
LauncherGrid {} // 2 — centered icon grid
|
LauncherGrid {} // 2 — centered icon grid
|
||||||
LauncherSpotlight {} // 3 — top-center command bar
|
LauncherSpotlight {} // 3 — top-center command bar
|
||||||
|
|||||||
@@ -1,81 +0,0 @@
|
|||||||
pragma ComponentBehavior: Bound
|
|
||||||
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Widgets
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
|
|
||||||
import qs.widgets.launcher
|
|
||||||
import qs.widgets.theme
|
|
||||||
|
|
||||||
Scope {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
Variants {
|
|
||||||
model: Quickshell.screens
|
|
||||||
|
|
||||||
PanelWindow {
|
|
||||||
required property var modelData
|
|
||||||
screen: modelData
|
|
||||||
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
bottom: true
|
|
||||||
left: true
|
|
||||||
right: true
|
|
||||||
}
|
|
||||||
|
|
||||||
implicitHeight: wrapper.implicitHeight
|
|
||||||
|
|
||||||
WrapperRectangle {
|
|
||||||
id: wrapper
|
|
||||||
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
leftMargin: 12
|
|
||||||
rightMargin: 12
|
|
||||||
bottomMargin: 12
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
implicitHeight: 12
|
|
||||||
|
|
||||||
// Brightens when the Dock launcher (variant 5) opens.
|
|
||||||
color: LauncherState.dockOpen ? Theme.accentSoft : Theme.accent
|
|
||||||
|
|
||||||
Behavior on color {
|
|
||||||
ColorAnimation {
|
|
||||||
duration: 250
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gentle "listening" pulse while the dock is open.
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
color: Theme.highlight
|
|
||||||
opacity: 0
|
|
||||||
visible: LauncherState.dockOpen
|
|
||||||
|
|
||||||
SequentialAnimation on opacity {
|
|
||||||
running: LauncherState.dockOpen
|
|
||||||
loops: Animation.Infinite
|
|
||||||
|
|
||||||
NumberAnimation {
|
|
||||||
to: 0.4
|
|
||||||
duration: 700
|
|
||||||
easing.type: Easing.InOutSine
|
|
||||||
}
|
|
||||||
NumberAnimation {
|
|
||||||
to: 0.0
|
|
||||||
duration: 700
|
|
||||||
easing.type: Easing.InOutSine
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
pragma ComponentBehavior: Bound
|
|
||||||
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Widgets
|
|
||||||
import QtQuick
|
|
||||||
|
|
||||||
import qs.widgets.launcher
|
|
||||||
import qs.widgets.theme
|
|
||||||
|
|
||||||
Scope {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
Variants {
|
|
||||||
model: Quickshell.screens
|
|
||||||
|
|
||||||
PanelWindow {
|
|
||||||
id: topBar
|
|
||||||
|
|
||||||
required property var modelData
|
|
||||||
screen: modelData
|
|
||||||
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
top: true
|
|
||||||
left: true
|
|
||||||
right: true
|
|
||||||
}
|
|
||||||
|
|
||||||
implicitHeight: wrapper.implicitHeight
|
|
||||||
|
|
||||||
WrapperRectangle {
|
|
||||||
id: wrapper
|
|
||||||
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
margin: 12
|
|
||||||
bottomMargin: 0
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
implicitHeight: 6
|
|
||||||
|
|
||||||
// Brightens when the Console launcher (variant 4) opens.
|
|
||||||
color: LauncherState.consoleOpen ? Theme.accentSoft : Theme.accent
|
|
||||||
|
|
||||||
Behavior on color {
|
|
||||||
ColorAnimation {
|
|
||||||
duration: 250
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gentle "listening" pulse while the console is open.
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
color: Theme.highlight
|
|
||||||
opacity: 0
|
|
||||||
visible: LauncherState.consoleOpen
|
|
||||||
|
|
||||||
SequentialAnimation on opacity {
|
|
||||||
running: LauncherState.consoleOpen
|
|
||||||
loops: Animation.Infinite
|
|
||||||
|
|
||||||
NumberAnimation {
|
|
||||||
to: 0.4
|
|
||||||
duration: 700
|
|
||||||
easing.type: Easing.InOutSine
|
|
||||||
}
|
|
||||||
NumberAnimation {
|
|
||||||
to: 0.0
|
|
||||||
duration: 700
|
|
||||||
easing.type: Easing.InOutSine
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -96,9 +96,8 @@ Item {
|
|||||||
height: 92
|
height: 92
|
||||||
|
|
||||||
readonly property real identityWidth: root.compact ? 250 : 320
|
readonly property real identityWidth: root.compact ? 250 : 320
|
||||||
readonly property real radarWidth: root.compact ? 130 : 164
|
readonly property real stateWidth: root.compact ? 300 : 350
|
||||||
readonly property real stateWidth: root.compact ? 210 : 250
|
readonly property real flexWidth: Math.max(250, (width - identityWidth - stateWidth - 32) / 2)
|
||||||
readonly property real flexWidth: Math.max(250, (width - identityWidth - radarWidth - stateWidth - 32) / 2)
|
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
@@ -234,24 +233,10 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusBarPanel {
|
|
||||||
width: array.radarWidth
|
|
||||||
height: array.height
|
|
||||||
panelId: "03"
|
|
||||||
title: "SCAN"
|
|
||||||
|
|
||||||
RadarGauge {
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
y: 28
|
|
||||||
size: 57
|
|
||||||
level: root.cpuFraction
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusBarPanel {
|
StatusBarPanel {
|
||||||
width: array.flexWidth
|
width: array.flexWidth
|
||||||
height: array.height
|
height: array.height
|
||||||
panelId: "04"
|
panelId: "03"
|
||||||
title: "CARRIER UPLINK"
|
title: "CARRIER UPLINK"
|
||||||
meta: root.networkInterface.toUpperCase()
|
meta: root.networkInterface.toUpperCase()
|
||||||
|
|
||||||
@@ -298,7 +283,7 @@ Item {
|
|||||||
StatusBarPanel {
|
StatusBarPanel {
|
||||||
width: array.stateWidth
|
width: array.stateWidth
|
||||||
height: array.height
|
height: array.height
|
||||||
panelId: "05"
|
panelId: "04"
|
||||||
title: "SYSTEM STATE"
|
title: "SYSTEM STATE"
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
|
|||||||
@@ -1,477 +0,0 @@
|
|||||||
pragma ComponentBehavior: Bound
|
|
||||||
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Hyprland
|
|
||||||
import Quickshell.Services.Pipewire
|
|
||||||
import Quickshell.Wayland
|
|
||||||
import Quickshell.Widgets
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import QtQuick.Shapes
|
|
||||||
import qs.widgets.theme
|
|
||||||
|
|
||||||
// A vertical sidebar carrying the "Slant" (launcher V6) visual language —
|
|
||||||
// chamfered panel, thick trapezoid bevel accents, an outward bracket, a
|
|
||||||
// floating triangle cap and a slanted divider. Right-anchored, mirrored.
|
|
||||||
Scope {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property bool active: true
|
|
||||||
|
|
||||||
function toggle() {
|
|
||||||
root.active = !root.active;
|
|
||||||
}
|
|
||||||
|
|
||||||
GlobalShortcut {
|
|
||||||
name: "sidebar"
|
|
||||||
description: "Toggle the Slant sidebar"
|
|
||||||
onPressed: root.toggle()
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly property PwNode sink: Pipewire.defaultAudioSink
|
|
||||||
readonly property real volume: sink?.audio?.volume ?? 0
|
|
||||||
readonly property bool muted: sink?.audio?.muted ?? false
|
|
||||||
readonly property real maxVolume: 1.5
|
|
||||||
|
|
||||||
PwObjectTracker {
|
|
||||||
objects: [root.sink]
|
|
||||||
}
|
|
||||||
|
|
||||||
PanelWindow {
|
|
||||||
id: win
|
|
||||||
|
|
||||||
visible: root.active
|
|
||||||
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
top: true
|
|
||||||
right: true
|
|
||||||
bottom: true
|
|
||||||
}
|
|
||||||
|
|
||||||
margins {
|
|
||||||
top: 8
|
|
||||||
}
|
|
||||||
|
|
||||||
// Frame width plus the gutter the outward bracket grows into.
|
|
||||||
readonly property int pad: 10
|
|
||||||
implicitWidth: 72 + 2 * pad
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: frame
|
|
||||||
|
|
||||||
// Inset so the outward bracket has room in the gutter.
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: win.pad
|
|
||||||
|
|
||||||
readonly property int chamfer: 18 // big cut corners (top-right, bottom-left)
|
|
||||||
readonly property int smallChamfer: 7 // small bevel (top-left, bottom-right)
|
|
||||||
readonly property int bevel: 4 // inward thickness of the trapezoid accents
|
|
||||||
readonly property int chunkThick: 7 // outward thickness of the bracket
|
|
||||||
readonly property int chunkSlant: 10 // slant of the bracket end pieces
|
|
||||||
readonly property int capSize: 10 // floating triangle cap
|
|
||||||
readonly property int armSide: 58 // bracket arm down the left edge
|
|
||||||
readonly property int armTop: 34 // bracket arm along the top edge
|
|
||||||
|
|
||||||
Shape {
|
|
||||||
id: panelShape
|
|
||||||
anchors.fill: parent
|
|
||||||
preferredRendererType: Shape.CurveRenderer
|
|
||||||
|
|
||||||
// Panel: big chamfers on top-right & bottom-left, small bevels
|
|
||||||
// on top-left & bottom-right (mirror of the left-anchored panel).
|
|
||||||
ShapePath {
|
|
||||||
fillColor: Theme.surface
|
|
||||||
strokeColor: Theme.accent
|
|
||||||
strokeWidth: 2
|
|
||||||
|
|
||||||
startX: panelShape.width - frame.chamfer
|
|
||||||
startY: 0
|
|
||||||
PathLine {
|
|
||||||
x: frame.smallChamfer
|
|
||||||
y: 0
|
|
||||||
}
|
|
||||||
PathLine {
|
|
||||||
x: 0
|
|
||||||
y: frame.smallChamfer
|
|
||||||
}
|
|
||||||
PathLine {
|
|
||||||
x: 0
|
|
||||||
y: panelShape.height - frame.chamfer
|
|
||||||
}
|
|
||||||
PathLine {
|
|
||||||
x: frame.chamfer
|
|
||||||
y: panelShape.height
|
|
||||||
}
|
|
||||||
PathLine {
|
|
||||||
x: panelShape.width - frame.smallChamfer
|
|
||||||
y: panelShape.height
|
|
||||||
}
|
|
||||||
PathLine {
|
|
||||||
x: panelShape.width
|
|
||||||
y: panelShape.height - frame.smallChamfer
|
|
||||||
}
|
|
||||||
PathLine {
|
|
||||||
x: panelShape.width
|
|
||||||
y: frame.chamfer
|
|
||||||
}
|
|
||||||
PathLine {
|
|
||||||
x: panelShape.width - frame.chamfer
|
|
||||||
y: 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Thick top-right bevel accent (trapezoid to the edges).
|
|
||||||
ShapePath {
|
|
||||||
strokeWidth: 0
|
|
||||||
fillColor: Theme.accent
|
|
||||||
|
|
||||||
startX: panelShape.width
|
|
||||||
startY: frame.chamfer
|
|
||||||
PathLine {
|
|
||||||
x: panelShape.width - frame.chamfer
|
|
||||||
y: 0
|
|
||||||
}
|
|
||||||
PathLine {
|
|
||||||
x: panelShape.width - frame.chamfer - 2 * frame.bevel
|
|
||||||
y: 0
|
|
||||||
}
|
|
||||||
PathLine {
|
|
||||||
x: panelShape.width
|
|
||||||
y: frame.chamfer + 2 * frame.bevel
|
|
||||||
}
|
|
||||||
PathLine {
|
|
||||||
x: panelShape.width
|
|
||||||
y: frame.chamfer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Thick bottom-left bevel accent.
|
|
||||||
ShapePath {
|
|
||||||
strokeWidth: 0
|
|
||||||
fillColor: Theme.accent
|
|
||||||
|
|
||||||
startX: 0
|
|
||||||
startY: panelShape.height - frame.chamfer
|
|
||||||
PathLine {
|
|
||||||
x: frame.chamfer
|
|
||||||
y: panelShape.height
|
|
||||||
}
|
|
||||||
PathLine {
|
|
||||||
x: frame.chamfer + 2 * frame.bevel
|
|
||||||
y: panelShape.height
|
|
||||||
}
|
|
||||||
PathLine {
|
|
||||||
x: 0
|
|
||||||
y: panelShape.height - frame.chamfer - 2 * frame.bevel
|
|
||||||
}
|
|
||||||
PathLine {
|
|
||||||
x: 0
|
|
||||||
y: panelShape.height - frame.chamfer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Floating triangle cap in the bottom-left notch.
|
|
||||||
ShapePath {
|
|
||||||
strokeWidth: 0
|
|
||||||
fillColor: Theme.accent
|
|
||||||
|
|
||||||
startX: 0
|
|
||||||
startY: panelShape.height
|
|
||||||
PathLine {
|
|
||||||
x: 0
|
|
||||||
y: panelShape.height - frame.capSize
|
|
||||||
}
|
|
||||||
PathLine {
|
|
||||||
x: frame.capSize
|
|
||||||
y: panelShape.height
|
|
||||||
}
|
|
||||||
PathLine {
|
|
||||||
x: 0
|
|
||||||
y: panelShape.height
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Outward bracket wrapping the top-left corner: down the left
|
|
||||||
// edge and along the top edge, with slanted ends and a beveled
|
|
||||||
// corner following the small chamfer.
|
|
||||||
ShapePath {
|
|
||||||
strokeWidth: 0
|
|
||||||
fillColor: Theme.accent
|
|
||||||
|
|
||||||
startX: 0
|
|
||||||
startY: frame.armSide
|
|
||||||
PathLine {
|
|
||||||
x: -frame.chunkThick
|
|
||||||
y: frame.armSide - frame.chunkSlant
|
|
||||||
}
|
|
||||||
PathLine {
|
|
||||||
x: -frame.chunkThick
|
|
||||||
y: frame.smallChamfer
|
|
||||||
}
|
|
||||||
PathLine {
|
|
||||||
x: frame.smallChamfer
|
|
||||||
y: -frame.chunkThick
|
|
||||||
}
|
|
||||||
PathLine {
|
|
||||||
x: frame.armTop - frame.chunkSlant
|
|
||||||
y: -frame.chunkThick
|
|
||||||
}
|
|
||||||
PathLine {
|
|
||||||
x: frame.armTop
|
|
||||||
y: 0
|
|
||||||
}
|
|
||||||
PathLine {
|
|
||||||
x: frame.smallChamfer
|
|
||||||
y: 0
|
|
||||||
}
|
|
||||||
PathLine {
|
|
||||||
x: 0
|
|
||||||
y: frame.smallChamfer
|
|
||||||
}
|
|
||||||
PathLine {
|
|
||||||
x: 0
|
|
||||||
y: frame.armSide
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Content ────────────────────────────────────────────────────
|
|
||||||
ColumnLayout {
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.topMargin: 16
|
|
||||||
anchors.bottomMargin: 16
|
|
||||||
anchors.leftMargin: 10
|
|
||||||
anchors.rightMargin: 8
|
|
||||||
spacing: 10
|
|
||||||
|
|
||||||
// Clock — readout font, hh over mm
|
|
||||||
Text {
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
text: Qt.formatDateTime(clock.date, "hh\nmm")
|
|
||||||
font.family: Theme.readoutFont
|
|
||||||
font.pointSize: 22
|
|
||||||
font.letterSpacing: 1
|
|
||||||
color: Theme.text
|
|
||||||
|
|
||||||
SystemClock {
|
|
||||||
id: clock
|
|
||||||
precision: SystemClock.Minutes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Date
|
|
||||||
Text {
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
text: Qt.formatDateTime(clock.date, "dd\nMMM").toUpperCase()
|
|
||||||
font.family: Theme.readoutFont
|
|
||||||
font.pointSize: 13
|
|
||||||
color: Theme.accent
|
|
||||||
}
|
|
||||||
|
|
||||||
// Slanted divider
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
implicitHeight: 4
|
|
||||||
|
|
||||||
Shape {
|
|
||||||
id: divider
|
|
||||||
anchors.fill: parent
|
|
||||||
preferredRendererType: Shape.CurveRenderer
|
|
||||||
ShapePath {
|
|
||||||
strokeWidth: 0
|
|
||||||
fillColor: Theme.accent
|
|
||||||
startX: 8
|
|
||||||
startY: 0
|
|
||||||
PathLine { x: divider.width; y: 0 }
|
|
||||||
PathLine { x: divider.width - 8; y: divider.height }
|
|
||||||
PathLine { x: 0; y: divider.height }
|
|
||||||
PathLine { x: 8; y: 0 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillHeight: true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Volume — vertical meter with a sheared fill and a % readout
|
|
||||||
Text {
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
text: "VOL"
|
|
||||||
font.family: Theme.readoutFont
|
|
||||||
font.pointSize: 10
|
|
||||||
color: Theme.muted
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
spacing: 3
|
|
||||||
|
|
||||||
// Overflow — three floating slanted segments for volume
|
|
||||||
// pushed above 100%, lit with the same overload color as
|
|
||||||
// the volume OSD.
|
|
||||||
Repeater {
|
|
||||||
model: 3
|
|
||||||
|
|
||||||
delegate: Item {
|
|
||||||
id: seg
|
|
||||||
required property int index
|
|
||||||
|
|
||||||
readonly property real segStart: 1 + (2 - index) / 3 * (root.maxVolume - 1)
|
|
||||||
readonly property real segEnd: 1 + (3 - index) / 3 * (root.maxVolume - 1)
|
|
||||||
readonly property real frac: root.muted ? 0 : Math.max(0, Math.min(1, (root.volume - segStart) / (segEnd - segStart)))
|
|
||||||
readonly property int chamfer: 4
|
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
implicitWidth: 16
|
|
||||||
implicitHeight: 12
|
|
||||||
|
|
||||||
// Empty track, chamfered to match the main meter.
|
|
||||||
Shape {
|
|
||||||
anchors.fill: parent
|
|
||||||
preferredRendererType: Shape.CurveRenderer
|
|
||||||
|
|
||||||
ShapePath {
|
|
||||||
strokeWidth: 1
|
|
||||||
strokeColor: Theme.muted
|
|
||||||
fillColor: Theme.raised
|
|
||||||
|
|
||||||
startX: seg.chamfer
|
|
||||||
startY: 0
|
|
||||||
PathLine { x: seg.width; y: 0 }
|
|
||||||
PathLine { x: seg.width; y: seg.height - seg.chamfer }
|
|
||||||
PathLine { x: seg.width - seg.chamfer; y: seg.height }
|
|
||||||
PathLine { x: 0; y: seg.height }
|
|
||||||
PathLine { x: 0; y: seg.chamfer }
|
|
||||||
PathLine { x: seg.chamfer; y: 0 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Overload fill — reveals a fixed copy of the same
|
|
||||||
// chamfered hexagon from the bottom, so filled and
|
|
||||||
// empty states always share one silhouette.
|
|
||||||
Item {
|
|
||||||
id: segFillClip
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: 2
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: 2
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.bottomMargin: 2
|
|
||||||
clip: true
|
|
||||||
height: seg.frac * (seg.height - 4)
|
|
||||||
|
|
||||||
Shape {
|
|
||||||
id: segFill
|
|
||||||
width: seg.width - 4
|
|
||||||
height: seg.height - 4
|
|
||||||
y: segFillClip.height - height
|
|
||||||
preferredRendererType: Shape.CurveRenderer
|
|
||||||
|
|
||||||
readonly property int chamfer: seg.chamfer - 2
|
|
||||||
|
|
||||||
ShapePath {
|
|
||||||
strokeWidth: 0
|
|
||||||
fillColor: Theme.hot
|
|
||||||
startX: segFill.chamfer
|
|
||||||
startY: 0
|
|
||||||
PathLine { x: segFill.width; y: 0 }
|
|
||||||
PathLine { x: segFill.width; y: segFill.height - segFill.chamfer }
|
|
||||||
PathLine { x: segFill.width - segFill.chamfer; y: segFill.height }
|
|
||||||
PathLine { x: 0; y: segFill.height }
|
|
||||||
PathLine { x: 0; y: segFill.chamfer }
|
|
||||||
PathLine { x: segFill.chamfer; y: 0 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: volMeter
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
implicitWidth: 16
|
|
||||||
implicitHeight: 96
|
|
||||||
|
|
||||||
readonly property int chamfer: 6
|
|
||||||
|
|
||||||
// Track — chamfered top-left/bottom-right to match the
|
|
||||||
// panel's slant, so the sheared fill sits in a shape that
|
|
||||||
// agrees with it rather than a plain rectangle.
|
|
||||||
Shape {
|
|
||||||
anchors.fill: parent
|
|
||||||
preferredRendererType: Shape.CurveRenderer
|
|
||||||
|
|
||||||
ShapePath {
|
|
||||||
strokeWidth: 1
|
|
||||||
strokeColor: Theme.muted
|
|
||||||
fillColor: Theme.raised
|
|
||||||
|
|
||||||
startX: volMeter.chamfer
|
|
||||||
startY: 0
|
|
||||||
PathLine { x: volMeter.width; y: 0 }
|
|
||||||
PathLine { x: volMeter.width; y: volMeter.height - volMeter.chamfer }
|
|
||||||
PathLine { x: volMeter.width - volMeter.chamfer; y: volMeter.height }
|
|
||||||
PathLine { x: 0; y: volMeter.height }
|
|
||||||
PathLine { x: 0; y: volMeter.chamfer }
|
|
||||||
PathLine { x: volMeter.chamfer; y: 0 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Accent fill — reveals a fixed copy of the same
|
|
||||||
// chamfered hexagon as the track from the bottom, so
|
|
||||||
// the fill and background always share one silhouette.
|
|
||||||
Item {
|
|
||||||
id: fillClip
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: 2
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: 2
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.bottomMargin: 2
|
|
||||||
clip: true
|
|
||||||
|
|
||||||
readonly property real frac: root.muted ? 0 : Math.min(root.volume, 1)
|
|
||||||
height: frac * (volMeter.height - 4)
|
|
||||||
|
|
||||||
Shape {
|
|
||||||
id: vol
|
|
||||||
width: volMeter.width - 4
|
|
||||||
height: volMeter.height - 4
|
|
||||||
y: fillClip.height - height
|
|
||||||
preferredRendererType: Shape.CurveRenderer
|
|
||||||
|
|
||||||
readonly property int chamfer: volMeter.chamfer - 2
|
|
||||||
|
|
||||||
ShapePath {
|
|
||||||
strokeWidth: 0
|
|
||||||
fillColor: root.muted ? Theme.muted : Theme.accent
|
|
||||||
startX: vol.chamfer
|
|
||||||
startY: 0
|
|
||||||
PathLine { x: vol.width; y: 0 }
|
|
||||||
PathLine { x: vol.width; y: vol.height - vol.chamfer }
|
|
||||||
PathLine { x: vol.width - vol.chamfer; y: vol.height }
|
|
||||||
PathLine { x: 0; y: vol.height }
|
|
||||||
PathLine { x: 0; y: vol.chamfer }
|
|
||||||
PathLine { x: vol.chamfer; y: 0 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
text: root.muted ? "--" : Math.round(root.volume * 100)
|
|
||||||
font.family: Theme.readoutFont
|
|
||||||
font.pointSize: 14
|
|
||||||
color: root.muted ? Theme.muted : Theme.text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Generated
+18
-18
@@ -14,11 +14,11 @@
|
|||||||
"uv2nix": "uv2nix"
|
"uv2nix": "uv2nix"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1786986906,
|
"lastModified": 1787577519,
|
||||||
"narHash": "sha256-DJ1oU9szQJNdEM0dysh4NnKOB1HwOKtNukrUYKpawVs=",
|
"narHash": "sha256-YNAXQTgR26RJiX2vtYjk6OtBu2jMWeq4qUN6sUrt6Lc=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "authentik-nix",
|
"repo": "authentik-nix",
|
||||||
"rev": "afdb2eeca1e0b38fabb93c4a8944be73d3581268",
|
"rev": "30c37930450d7a5fefa8ffec613f037fc75c3071",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -270,11 +270,11 @@
|
|||||||
"treefmt-nix": "treefmt-nix"
|
"treefmt-nix": "treefmt-nix"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1787124618,
|
"lastModified": 1787728766,
|
||||||
"narHash": "sha256-aKf1k2hvYgaxP9oxDPRiv9npEJLODC9eKxk7nR69lzQ=",
|
"narHash": "sha256-g2oZlrBU3AI2ubCiY/UyE9ALTIDueTcF//QP3vaY9IQ=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "nixos-anywhere",
|
"repo": "nixos-anywhere",
|
||||||
"rev": "ad8fa24e11eef167fd72d49fafefa3f840312d71",
|
"rev": "6b77f26ec4538ced04bf1d02f374b0ec02e9c27e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -291,11 +291,11 @@
|
|||||||
"nixos-unstable": "nixos-unstable"
|
"nixos-unstable": "nixos-unstable"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1787222173,
|
"lastModified": 1787826771,
|
||||||
"narHash": "sha256-acp6QJnWVnLvnanC59CMkiDC/i0ZhdFKiB7prru9SHw=",
|
"narHash": "sha256-gWkyr3I/cg4SHWGkAoUo24+BQaqoi+S0T2JxDjsA+pw=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "nixos-images",
|
"repo": "nixos-images",
|
||||||
"rev": "e17386d9193d6d5a90f1b4b6a8a5cd2620d34b56",
|
"rev": "f6714acc84ce92df7286c89a571ad1e946057a5b",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -354,11 +354,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs-unstable": {
|
"nixpkgs-unstable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1787209939,
|
"lastModified": 1787814960,
|
||||||
"narHash": "sha256-WvvHR4kSQLAbtouMC/ruZ5UpLwlUcY3K4FAllMN+yGk=",
|
"narHash": "sha256-PYZq1qzCJXC2zGI0mH07vrZBsw6DRBAOX0jN1pPtqOQ=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "391b592eb44808b3bd0cb80bb71b63a5a118b8bb",
|
"rev": "c27cdad491a991b11ed731760aa2ef8db0cb0410",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -370,11 +370,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1787204541,
|
"lastModified": 1787753485,
|
||||||
"narHash": "sha256-OURZPknrTjQrlNyxPdqzyqmU/81Wes1CUP/Ft1Rv/YI=",
|
"narHash": "sha256-BZWCi9ZRJiARTuKTbbtvFTj7t1TK4G3UEckT3HyNfRg=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "5880666fd9eb563038431edb35c2d0aa595884e6",
|
"rev": "062346a6d85bc4b49dfaa61c986e9c5be21217d1",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -400,11 +400,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1785730568,
|
"lastModified": 1786936886,
|
||||||
"narHash": "sha256-NjSPsgjJ7MSpBtTkUcmNhRe6AFZ96+zsca2M8YuQi8Y=",
|
"narHash": "sha256-8SFyOdmcG6Nsh/JzlH812lTI/v+ur06fpQhj/acNn8k=",
|
||||||
"owner": "pyproject-nix",
|
"owner": "pyproject-nix",
|
||||||
"repo": "build-system-pkgs",
|
"repo": "build-system-pkgs",
|
||||||
"rev": "90fde00db3687922d39d95fc591475fd0bbbcd72",
|
"rev": "90ffdeee1a4929b231913df067448cd9803d3e07",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ in
|
|||||||
pkgs.hyprcursor
|
pkgs.hyprcursor
|
||||||
pkgs.bibata-cursors
|
pkgs.bibata-cursors
|
||||||
pkgs.papirus-icon-theme
|
pkgs.papirus-icon-theme
|
||||||
tome
|
|
||||||
];
|
];
|
||||||
|
|
||||||
xdg.desktopEntries.btop = {
|
xdg.desktopEntries.btop = {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ let
|
|||||||
# here rather than at runtime, since hyprpaper has no built-in "random"
|
# here rather than at runtime, since hyprpaper has no built-in "random"
|
||||||
# mode; re-pick and rebuild (or swap in real per-monitor selection) when
|
# mode; re-pick and rebuild (or swap in real per-monitor selection) when
|
||||||
# this stops being a placeholder.
|
# this stops being a placeholder.
|
||||||
wallpaper = "/mnt/hdd_01/data/Pictures/Wallhaven/wallhaven-4yjyd4.png";
|
wallpaper = "/mnt/hdd_01/data/Pictures/Wallhaven/wallhaven-ym81rl.png";
|
||||||
|
|
||||||
# Dispatchers → the new hl.dsp.* API (signatures verified against hyprland
|
# Dispatchers → the new hl.dsp.* API (signatures verified against hyprland
|
||||||
# 0.55's src/config/lua/bindings/LuaBindingsDispatchers.cpp).
|
# 0.55's src/config/lua/bindings/LuaBindingsDispatchers.cpp).
|
||||||
|
|||||||
Reference in New Issue
Block a user