From ca04c7d2f1affa69412b34f5975aca7eb212e97a Mon Sep 17 00:00:00 2001 From: Zacharias-Brohn Date: Wed, 25 Feb 2026 14:19:27 +0100 Subject: [PATCH 1/8] horizontal media widget --- Components/CollapsibleSection.qml | 135 +++++++++++++ Components/CustomSpinBox.qml | 166 +++++++++++++++ Components/MarqueeText.qml | 200 +++++++++++++++++++ Components/Menu.qml | 107 ++++++++++ Components/MenuItem.qml | 12 ++ Components/SpinBoxRow.qml | 50 +++++ Drawers/Bar.qml | 8 +- Modules/Dashboard/Dash.qml | 23 +-- Modules/Dashboard/Dash/Media.qml | 211 ++++++++++---------- Modules/Settings/Background.qml | 66 ------ Modules/Settings/Categories.qml | 178 ----------------- Modules/Settings/Categories/Appearance.qml | 66 ------ Modules/Settings/Categories/Background.qml | 13 -- Modules/Settings/Categories/General.qml | 55 ----- Modules/Settings/Content.qml | 102 ---------- Modules/Settings/Controls/SettingSwitch.qml | 36 ---- Modules/Settings/Settings.qml | 11 - Modules/Settings/Wrapper.qml | 61 ------ assets/shaders/opacitymask.frag.qsb | Bin 850 -> 1337 bytes 19 files changed, 787 insertions(+), 713 deletions(-) create mode 100644 Components/CollapsibleSection.qml create mode 100644 Components/CustomSpinBox.qml create mode 100644 Components/MarqueeText.qml create mode 100644 Components/Menu.qml create mode 100644 Components/MenuItem.qml create mode 100644 Components/SpinBoxRow.qml delete mode 100644 Modules/Settings/Background.qml delete mode 100644 Modules/Settings/Categories.qml delete mode 100644 Modules/Settings/Categories/Appearance.qml delete mode 100644 Modules/Settings/Categories/Background.qml delete mode 100644 Modules/Settings/Categories/General.qml delete mode 100644 Modules/Settings/Content.qml delete mode 100644 Modules/Settings/Controls/SettingSwitch.qml delete mode 100644 Modules/Settings/Settings.qml delete mode 100644 Modules/Settings/Wrapper.qml diff --git a/Components/CollapsibleSection.qml b/Components/CollapsibleSection.qml new file mode 100644 index 0000000..6d6fc3e --- /dev/null +++ b/Components/CollapsibleSection.qml @@ -0,0 +1,135 @@ +import QtQuick +import QtQuick.Layouts +import qs.Config + +ColumnLayout { + id: root + + default property alias content: contentColumn.data + property string description: "" + property bool expanded: false + property bool nested: false + property bool showBackground: false + required property string title + + signal toggleRequested + + Layout.fillWidth: true + spacing: Appearance.spacing.small + + Item { + id: sectionHeaderItem + + Layout.fillWidth: true + Layout.preferredHeight: Math.max(titleRow.implicitHeight + Appearance.padding.normal * 2, 48) + + RowLayout { + id: titleRow + + anchors.left: parent.left + anchors.leftMargin: Appearance.padding.normal + anchors.right: parent.right + anchors.rightMargin: Appearance.padding.normal + anchors.verticalCenter: parent.verticalCenter + spacing: Appearance.spacing.normal + + CustomText { + font.pointSize: Appearance.font.size.larger + font.weight: 500 + text: root.title + } + + Item { + Layout.fillWidth: true + } + + MaterialIcon { + color: DynamicColors.palette.m3onSurfaceVariant + font.pointSize: Appearance.font.size.normal + rotation: root.expanded ? 180 : 0 + text: "expand_more" + + Behavior on rotation { + Anim { + duration: Appearance.anim.durations.small + easing.bezierCurve: Appearance.anim.curves.standard + } + } + } + } + + StateLayer { + function onClicked(): void { + root.toggleRequested(); + root.expanded = !root.expanded; + } + + anchors.fill: parent + color: DynamicColors.palette.m3onSurface + radius: Appearance.rounding.normal + showHoverBackground: false + } + } + + Item { + id: contentWrapper + + Layout.fillWidth: true + Layout.preferredHeight: root.expanded ? (contentColumn.implicitHeight + Appearance.spacing.small * 2) : 0 + clip: true + + Behavior on Layout.preferredHeight { + Anim { + easing.bezierCurve: Appearance.anim.curves.standard + } + } + + CustomRect { + id: backgroundRect + + anchors.fill: parent + color: DynamicColors.transparency.enabled ? DynamicColors.layer(DynamicColors.palette.m3surfaceContainer, root.nested ? 3 : 2) : (root.nested ? DynamicColors.palette.m3surfaceContainerHigh : DynamicColors.palette.m3surfaceContainer) + opacity: root.showBackground && root.expanded ? 1.0 : 0.0 + radius: Appearance.rounding.normal + visible: root.showBackground + + Behavior on opacity { + Anim { + easing.bezierCurve: Appearance.anim.curves.standard + } + } + } + + ColumnLayout { + id: contentColumn + + anchors.bottomMargin: Appearance.spacing.small + anchors.left: parent.left + anchors.leftMargin: Appearance.padding.normal + anchors.right: parent.right + anchors.rightMargin: Appearance.padding.normal + opacity: root.expanded ? 1.0 : 0.0 + spacing: Appearance.spacing.small + y: Appearance.spacing.small + + Behavior on opacity { + Anim { + easing.bezierCurve: Appearance.anim.curves.standard + } + } + + CustomText { + id: descriptionText + + Layout.bottomMargin: root.description !== "" ? Appearance.spacing.small : 0 + Layout.fillWidth: true + Layout.topMargin: root.description !== "" ? Appearance.spacing.smaller : 0 + color: DynamicColors.palette.m3onSurfaceVariant + font.pointSize: Appearance.font.size.small + text: root.description + visible: root.description !== "" + wrapMode: Text.Wrap + } + } + } +} diff --git a/Components/CustomSpinBox.qml b/Components/CustomSpinBox.qml new file mode 100644 index 0000000..fe98e72 --- /dev/null +++ b/Components/CustomSpinBox.qml @@ -0,0 +1,166 @@ +pragma ComponentBehavior: Bound + +import QtQuick +import QtQuick.Layouts +import qs.Config + +RowLayout { + id: root + + property string displayText: root.value.toString() + property bool isEditing: false + property real max: Infinity + property real min: -Infinity + property alias repeatRate: timer.interval + property real step: 1 + property real value + + signal valueModified(value: real) + + spacing: Appearance.spacing.small + + onValueChanged: { + if (!root.isEditing) { + root.displayText = root.value.toString(); + } + } + + CustomTextField { + id: textField + + inputMethodHints: Qt.ImhFormattedNumbersOnly + leftPadding: Appearance.padding.normal + padding: Appearance.padding.small + rightPadding: Appearance.padding.normal + text: root.isEditing ? text : root.displayText + + background: CustomRect { + color: DynamicColors.tPalette.m3surfaceContainerHigh + implicitWidth: 100 + radius: Appearance.rounding.small + } + validator: DoubleValidator { + bottom: root.min + decimals: root.step < 1 ? Math.max(1, Math.ceil(-Math.log10(root.step))) : 0 + top: root.max + } + + onAccepted: { + const numValue = parseFloat(text); + if (!isNaN(numValue)) { + const clampedValue = Math.max(root.min, Math.min(root.max, numValue)); + root.value = clampedValue; + root.displayText = clampedValue.toString(); + root.valueModified(clampedValue); + } else { + text = root.displayText; + } + root.isEditing = false; + } + onActiveFocusChanged: { + if (activeFocus) { + root.isEditing = true; + } else { + root.isEditing = false; + root.displayText = root.value.toString(); + } + } + onEditingFinished: { + if (text !== root.displayText) { + const numValue = parseFloat(text); + if (!isNaN(numValue)) { + const clampedValue = Math.max(root.min, Math.min(root.max, numValue)); + root.value = clampedValue; + root.displayText = clampedValue.toString(); + root.valueModified(clampedValue); + } else { + text = root.displayText; + } + } + root.isEditing = false; + } + } + + CustomRect { + color: DynamicColors.palette.m3primary + implicitHeight: upIcon.implicitHeight + Appearance.padding.small * 2 + implicitWidth: implicitHeight + radius: Appearance.rounding.small + + StateLayer { + id: upState + + function onClicked(): void { + let newValue = Math.min(root.max, root.value + root.step); + // Round to avoid floating point precision errors + const decimals = root.step < 1 ? Math.max(1, Math.ceil(-Math.log10(root.step))) : 0; + newValue = Math.round(newValue * Math.pow(10, decimals)) / Math.pow(10, decimals); + root.value = newValue; + root.displayText = newValue.toString(); + root.valueModified(newValue); + } + + color: DynamicColors.palette.m3onPrimary + + onPressAndHold: timer.start() + onReleased: timer.stop() + } + + MaterialIcon { + id: upIcon + + anchors.centerIn: parent + color: DynamicColors.palette.m3onPrimary + text: "keyboard_arrow_up" + } + } + + CustomRect { + color: DynamicColors.palette.m3primary + implicitHeight: downIcon.implicitHeight + Appearance.padding.small * 2 + implicitWidth: implicitHeight + radius: Appearance.rounding.small + + StateLayer { + id: downState + + function onClicked(): void { + let newValue = Math.max(root.min, root.value - root.step); + // Round to avoid floating point precision errors + const decimals = root.step < 1 ? Math.max(1, Math.ceil(-Math.log10(root.step))) : 0; + newValue = Math.round(newValue * Math.pow(10, decimals)) / Math.pow(10, decimals); + root.value = newValue; + root.displayText = newValue.toString(); + root.valueModified(newValue); + } + + color: DynamicColors.palette.m3onPrimary + + onPressAndHold: timer.start() + onReleased: timer.stop() + } + + MaterialIcon { + id: downIcon + + anchors.centerIn: parent + color: DynamicColors.palette.m3onPrimary + text: "keyboard_arrow_down" + } + } + + Timer { + id: timer + + interval: 100 + repeat: true + triggeredOnStart: true + + onTriggered: { + if (upState.pressed) + upState.onClicked(); + else if (downState.pressed) + downState.onClicked(); + } + } +} diff --git a/Components/MarqueeText.qml b/Components/MarqueeText.qml new file mode 100644 index 0000000..02d123d --- /dev/null +++ b/Components/MarqueeText.qml @@ -0,0 +1,200 @@ +import QtQuick +import QtQuick.Effects + +Item { + id: root + + property color color: DynamicColors.palette.m3onSurface + property int fadeStrengthAnimMs: 180 + property real fadeStrengthIdle: 0.0 + property real fadeStrengthMoving: 1.0 + property alias font: elideText.font + property int gap: 40 + property alias horizontalAlignment: elideText.horizontalAlignment + property bool leftFadeEnabled: false + property real leftFadeStrength: overflowing && leftFadeEnabled ? fadeStrengthMoving : fadeStrengthIdle + property int leftFadeWidth: 28 + property bool marqueeEnabled: true + readonly property bool overflowing: metrics.width > root.width + property int pauseMs: 1200 + property real pixelsPerSecond: 40 + property real rightFadeStrength: overflowing ? fadeStrengthMoving : fadeStrengthIdle + property int rightFadeWidth: 28 + property bool sliding: false + property alias text: elideText.text + + function durationForDistance(px): int { + return Math.max(1, Math.round(Math.abs(px) / root.pixelsPerSecond * 1000)); + } + + clip: true + implicitHeight: elideText.implicitHeight + + Behavior on leftFadeStrength { + Anim { + } + } + Behavior on rightFadeStrength { + Anim { + } + } + + onTextChanged: strip.x = 0 + onVisibleChanged: if (!visible) + strip.x = 0 + onWidthChanged: strip.x = 0 + + TextMetrics { + id: metrics + + font: elideText.font + text: elideText.text + } + + CustomText { + id: elideText + + anchors.verticalCenter: parent.verticalCenter + color: root.color + elide: Text.ElideRight + visible: !root.overflowing + width: root.width + } + + Item { + id: marqueeViewport + + anchors.fill: parent + clip: true + layer.enabled: true + visible: root.overflowing + + layer.effect: OpacityMask { + maskSource: rightFadeMask + } + + Item { + id: strip + + anchors.verticalCenter: parent.verticalCenter + height: t1.implicitHeight + width: t1.width + root.gap + t2.width + x: 0 + + CustomText { + id: t1 + + color: root.color + text: elideText.text + } + + CustomText { + id: t2 + + color: root.color + text: t1.text + x: t1.width + root.gap + } + } + + SequentialAnimation { + id: marqueeAnim + + loops: Animation.Infinite + running: root.marqueeEnabled && root.overflowing && root.visible + + ScriptAction { + script: { + strip.x = 0; + root.sliding = false; + root.leftFadeEnabled = false; + } + } + + PauseAnimation { + duration: root.pauseMs + } + + ScriptAction { + script: { + root.sliding = true; + root.leftFadeEnabled = true; + } + } + + Anim { + duration: root.durationForDistance(t1.width) + easing.bezierCurve: Easing.Linear + easing.type: Easing.Linear + from: 0 + property: "x" + target: strip + to: -t1.width + } + + ScriptAction { + script: { + root.leftFadeEnabled = false; + } + } + + Anim { + duration: root.durationForDistance(root.gap) + easing.bezierCurve: Easing.Linear + easing.type: Easing.Linear + from: -t1.width + property: "x" + target: strip + to: -(t1.width + root.gap) + } + + ScriptAction { + script: { + root.sliding = false; + strip.x = 0; + } + } + } + } + + Rectangle { + id: rightFadeMask + + readonly property real fadeStartPos: { + const w = Math.max(1, width); + return Math.max(0, Math.min(1, (w - root.rightFadeWidth) / w)); + } + readonly property real leftFadeEndPos: { + const w = Math.max(1, width); + return Math.max(0, Math.min(1, root.leftFadeWidth / w)); + } + + anchors.fill: marqueeViewport + layer.enabled: true + visible: false + + gradient: Gradient { + orientation: Gradient.Horizontal + + GradientStop { + color: Qt.rgba(1, 1, 1, 1.0 - root.leftFadeStrength) + position: 0.0 + } + + GradientStop { + color: Qt.rgba(1, 1, 1, 1.0) + position: rightFadeMask.leftFadeEndPos + } + + GradientStop { + color: Qt.rgba(1, 1, 1, 1.0) + position: rightFadeMask.fadeStartPos + } + + GradientStop { + color: Qt.rgba(1, 1, 1, 1.0 - root.rightFadeStrength) + position: 1.0 + } + } + } +} diff --git a/Components/Menu.qml b/Components/Menu.qml new file mode 100644 index 0000000..d4ffb02 --- /dev/null +++ b/Components/Menu.qml @@ -0,0 +1,107 @@ +pragma ComponentBehavior: Bound + +import QtQuick +import QtQuick.Layouts +import qs.Config + +Elevation { + id: root + + property MenuItem active: items[0] ?? null + property bool expanded + property list items + + signal itemSelected(item: MenuItem) + + implicitHeight: root.expanded ? column.implicitHeight : 0 + implicitWidth: Math.max(200, column.implicitWidth) + level: 2 + opacity: root.expanded ? 1 : 0 + radius: Appearance.rounding.small / 2 + + Behavior on implicitHeight { + Anim { + duration: Appearance.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + } + } + Behavior on opacity { + Anim { + duration: Appearance.anim.durations.expressiveDefaultSpatial + } + } + + CustomClippingRect { + anchors.fill: parent + color: DynamicColors.palette.m3surfaceContainer + radius: parent.radius + + ColumnLayout { + id: column + + anchors.left: parent.left + anchors.right: parent.right + spacing: 0 + + Repeater { + model: root.items + + CustomRect { + id: item + + readonly property bool active: modelData === root.active + required property int index + required property MenuItem modelData + + Layout.fillWidth: true + color: Qt.alpha(DynamicColors.palette.m3secondaryContainer, active ? 1 : 0) + implicitHeight: menuOptionRow.implicitHeight + Appearance.padding.normal * 2 + implicitWidth: menuOptionRow.implicitWidth + Appearance.padding.normal * 2 + + StateLayer { + function onClicked(): void { + root.itemSelected(item.modelData); + root.active = item.modelData; + root.expanded = false; + } + + color: item.active ? DynamicColors.palette.m3onSecondaryContainer : DynamicColors.palette.m3onSurface + disabled: !root.expanded + } + + RowLayout { + id: menuOptionRow + + anchors.fill: parent + anchors.margins: Appearance.padding.normal + spacing: Appearance.spacing.small + + MaterialIcon { + Layout.alignment: Qt.AlignVCenter + color: item.active ? DynamicColors.palette.m3onSecondaryContainer : DynamicColors.palette.m3onSurfaceVariant + text: item.modelData.icon + } + + CustomText { + Layout.alignment: Qt.AlignVCenter + Layout.fillWidth: true + color: item.active ? DynamicColors.palette.m3onSecondaryContainer : DynamicColors.palette.m3onSurface + text: item.modelData.text + } + + Loader { + Layout.alignment: Qt.AlignVCenter + active: item.modelData.trailingIcon.length > 0 + visible: active + + sourceComponent: MaterialIcon { + color: item.active ? DynamicColors.palette.m3onSecondaryContainer : DynamicColors.palette.m3onSurface + text: item.modelData.trailingIcon + } + } + } + } + } + } + } +} diff --git a/Components/MenuItem.qml b/Components/MenuItem.qml new file mode 100644 index 0000000..2378dd9 --- /dev/null +++ b/Components/MenuItem.qml @@ -0,0 +1,12 @@ +import QtQuick + +QtObject { + property string activeIcon: icon + property string activeText: text + property string icon + required property string text + property string trailingIcon + property var value + + signal clicked +} diff --git a/Components/SpinBoxRow.qml b/Components/SpinBoxRow.qml new file mode 100644 index 0000000..6686ec7 --- /dev/null +++ b/Components/SpinBoxRow.qml @@ -0,0 +1,50 @@ +import QtQuick +import QtQuick.Layouts +import qs.Config + +CustomRect { + id: root + + required property string label + required property real max + required property real min + property var onValueModified: function (value) {} + property real step: 1 + required property real value + + Layout.fillWidth: true + color: DynamicColors.layer(DynamicColors.palette.m3surfaceContainer, 2) + implicitHeight: row.implicitHeight + Appearance.padding.large * 2 + radius: Appearance.rounding.normal + + Behavior on implicitHeight { + Anim { + } + } + + RowLayout { + id: row + + anchors.left: parent.left + anchors.margins: Appearance.padding.large + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + spacing: Appearance.spacing.normal + + CustomText { + Layout.fillWidth: true + text: root.label + } + + CustomSpinBox { + max: root.max + min: root.min + step: root.step + value: root.value + + onValueModified: value => { + root.onValueModified(value); + } + } + } +} diff --git a/Drawers/Bar.qml b/Drawers/Bar.qml index e8d1728..c5bbdde 100644 --- a/Drawers/Bar.qml +++ b/Drawers/Bar.qml @@ -28,7 +28,7 @@ Variants { property bool trayMenuVisible: false WlrLayershell.exclusionMode: ExclusionMode.Ignore - WlrLayershell.keyboardFocus: visibilities.launcher || visibilities.sidebar || visibilities.dashboard ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None + WlrLayershell.keyboardFocus: visibilities.launcher || visibilities.sidebar || visibilities.dashboard || visibilities.settings ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None WlrLayershell.namespace: "ZShell-Bar" color: "transparent" contentItem.focus: true @@ -37,8 +37,6 @@ Variants { mask: Region { id: region - property list nullRegions: [] - height: bar.screen.height - backgroundRect.implicitHeight intersection: Intersection.Xor regions: popoutRegions.instances @@ -53,6 +51,7 @@ Variants { visibilities.sidebar = false; visibilities.dashboard = false; visibilities.osd = false; + visibilities.settings = false; } PanelWindow { @@ -98,7 +97,7 @@ Variants { HyprlandFocusGrab { id: focusGrab - active: visibilities.launcher || visibilities.sidebar || visibilities.dashboard || (panels.popouts.hasCurrent && panels.popouts.currentName.startsWith("traymenu")) + active: visibilities.launcher || visibilities.sidebar || visibilities.dashboard || visibilities.settings || (panels.popouts.hasCurrent && panels.popouts.currentName.startsWith("traymenu")) windows: [bar] onCleared: { @@ -106,6 +105,7 @@ Variants { visibilities.sidebar = false; visibilities.dashboard = false; visibilities.osd = false; + visibilities.settings = false; panels.popouts.hasCurrent = false; } } diff --git a/Modules/Dashboard/Dash.qml b/Modules/Dashboard/Dash.qml index a9ae042..44851e8 100644 --- a/Modules/Dashboard/Dash.qml +++ b/Modules/Dashboard/Dash.qml @@ -3,7 +3,6 @@ import QtQuick import QtQuick.Layouts import qs.Helpers import qs.Components -import qs.Paths import qs.Modules import qs.Config import qs.Modules.Dashboard.Dash @@ -86,18 +85,6 @@ GridLayout { } } - // Rect { - // Layout.row: 1 - // Layout.preferredWidth: dateTime.implicitWidth - // Layout.fillHeight: true - // - // radius: root.radius - // - // DateTime { - // id: dateTime - // } - // } - Rect { Layout.column: 0 Layout.columnSpan: 3 @@ -128,11 +115,11 @@ GridLayout { } Rect { - Layout.column: 5 - Layout.fillHeight: true - Layout.preferredWidth: media.implicitWidth - Layout.row: 0 - Layout.rowSpan: 2 + Layout.column: 0 + Layout.columnSpan: 5 + Layout.fillWidth: true + Layout.preferredHeight: media.implicitHeight + Layout.row: 2 radius: root.radius Media { diff --git a/Modules/Dashboard/Dash/Media.qml b/Modules/Dashboard/Dash/Media.qml index 35b69d0..456bd3d 100644 --- a/Modules/Dashboard/Dash/Media.qml +++ b/Modules/Dashboard/Dash/Media.qml @@ -1,12 +1,10 @@ -import ZShell.Services import QtQuick +import QtQuick.Layouts import QtQuick.Shapes import qs.Daemons import qs.Components import qs.Config import qs.Helpers -import qs.Modules -import qs.Paths Item { id: root @@ -15,10 +13,11 @@ Item { const active = Players.active; return active?.length ? active.position / active.length : 0; } + property int rowHeight: Appearance.padding.large + Config.dashboard.sizes.mediaProgressThickness + Appearance.spacing.small - anchors.bottom: parent.bottom - anchors.top: parent.top - implicitWidth: Config.dashboard.sizes.mediaWidth + anchors.left: parent.left + anchors.right: parent.right + implicitHeight: cover.height + rowHeight * 2 Behavior on playerProgress { Anim { @@ -35,10 +34,6 @@ Item { onTriggered: Players.active?.positionChanged() } - ServiceRef { - service: Audio.beatTracker - } - Shape { preferredRendererType: Shape.CurveRenderer @@ -85,114 +80,124 @@ Item { } } - CustomClippingRect { - id: cover + RowLayout { + id: layout anchors.left: parent.left - anchors.margins: Appearance.padding.large + Config.dashboard.sizes.mediaProgressThickness + Appearance.spacing.small anchors.right: parent.right - anchors.top: parent.top - color: DynamicColors.tPalette.m3surfaceContainerHigh - implicitHeight: width - radius: Infinity + implicitHeight: root.implicitHeight - MaterialIcon { - anchors.centerIn: parent - color: DynamicColors.palette.m3onSurfaceVariant - font.pointSize: (parent.width * 0.4) || 1 - grade: 200 - text: "art_track" - } + CustomClippingRect { + id: cover - Image { - id: image + Layout.alignment: Qt.AlignLeft + Layout.bottomMargin: Appearance.padding.large + Config.dashboard.sizes.mediaProgressThickness + Appearance.spacing.small + Layout.leftMargin: Appearance.padding.large + Config.dashboard.sizes.mediaProgressThickness + Appearance.spacing.small + Layout.preferredHeight: Config.dashboard.sizes.mediaCoverArtSize + Layout.preferredWidth: Config.dashboard.sizes.mediaCoverArtSize + Layout.topMargin: Appearance.padding.large + Config.dashboard.sizes.mediaProgressThickness + Appearance.spacing.small + color: DynamicColors.tPalette.m3surfaceContainerHigh + radius: Infinity - anchors.fill: parent - asynchronous: true - fillMode: Image.PreserveAspectCrop - source: Players.active?.trackArtUrl ?? "" - sourceSize.height: height - sourceSize.width: width - } - } - - CustomText { - id: title - - anchors.horizontalCenter: parent.horizontalCenter - anchors.top: cover.bottom - anchors.topMargin: Appearance.spacing.normal - animate: true - color: DynamicColors.palette.m3primary - elide: Text.ElideRight - font.pointSize: Appearance.font.size.normal - horizontalAlignment: Text.AlignHCenter - text: (Players.active?.trackTitle ?? qsTr("No media")) || qsTr("Unknown title") - width: parent.implicitWidth - Appearance.padding.large * 2 - } - - CustomText { - id: album - - anchors.horizontalCenter: parent.horizontalCenter - anchors.top: title.bottom - anchors.topMargin: Appearance.spacing.small - animate: true - color: DynamicColors.palette.m3outline - elide: Text.ElideRight - font.pointSize: Appearance.font.size.small - horizontalAlignment: Text.AlignHCenter - text: (Players.active?.trackAlbum ?? qsTr("No media")) || qsTr("Unknown album") - width: parent.implicitWidth - Appearance.padding.large * 2 - } - - CustomText { - id: artist - - anchors.horizontalCenter: parent.horizontalCenter - anchors.top: album.bottom - anchors.topMargin: Appearance.spacing.small - animate: true - color: DynamicColors.palette.m3secondary - elide: Text.ElideRight - horizontalAlignment: Text.AlignHCenter - text: (Players.active?.trackArtist ?? qsTr("No media")) || qsTr("Unknown artist") - width: parent.implicitWidth - Appearance.padding.large * 2 - } - - Row { - id: controls - - anchors.horizontalCenter: parent.horizontalCenter - anchors.top: artist.bottom - anchors.topMargin: Appearance.spacing.smaller - spacing: Appearance.spacing.small - - Control { - function onClicked(): void { - Players.active?.previous(); + MaterialIcon { + anchors.centerIn: parent + color: DynamicColors.palette.m3onSurfaceVariant + font.pointSize: (parent.width * 0.4) || 1 + grade: 200 + text: "art_track" } - canUse: Players.active?.canGoPrevious ?? false - icon: "skip_previous" + Image { + id: image + + anchors.fill: parent + asynchronous: true + fillMode: Image.PreserveAspectCrop + source: Players.active?.trackArtUrl ?? "" + sourceSize.height: Math.floor(height) + sourceSize.width: Math.floor(width) + } } - Control { - function onClicked(): void { - Players.active?.togglePlaying(); + CustomRect { + Layout.fillWidth: true + Layout.preferredHeight: childrenRect.height + + MarqueeText { + id: title + + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + color: DynamicColors.palette.m3primary + font.pointSize: Appearance.font.size.normal + horizontalAlignment: Text.AlignHCenter + pauseMs: 4000 + text: (Players.active?.trackTitle ?? qsTr("No media")) || qsTr("Unknown title") + width: parent.width - Appearance.padding.large * 4 } - canUse: Players.active?.canTogglePlaying ?? false - icon: Players.active?.isPlaying ? "pause" : "play_arrow" - } + CustomText { + id: album - Control { - function onClicked(): void { - Players.active?.next(); + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: title.bottom + anchors.topMargin: Appearance.spacing.small + animate: true + color: DynamicColors.palette.m3outline + elide: Text.ElideRight + font.pointSize: Appearance.font.size.small + horizontalAlignment: Text.AlignHCenter + text: (Players.active?.trackAlbum ?? qsTr("No media")) || qsTr("Unknown album") } - canUse: Players.active?.canGoNext ?? false - icon: "skip_next" + CustomText { + id: artist + + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: album.bottom + anchors.topMargin: Appearance.spacing.small + animate: true + color: DynamicColors.palette.m3secondary + elide: Text.ElideRight + horizontalAlignment: Text.AlignHCenter + text: (Players.active?.trackArtist ?? qsTr("No media")) || qsTr("Unknown artist") + } + + Row { + id: controls + + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: artist.bottom + anchors.topMargin: Appearance.spacing.smaller + spacing: Appearance.spacing.small + + Control { + function onClicked(): void { + Players.active?.previous(); + } + + canUse: Players.active?.canGoPrevious ?? false + icon: "skip_previous" + } + + Control { + function onClicked(): void { + Players.active?.togglePlaying(); + } + + canUse: Players.active?.canTogglePlaying ?? false + icon: Players.active?.isPlaying ? "pause" : "play_arrow" + } + + Control { + function onClicked(): void { + Players.active?.next(); + } + + canUse: Players.active?.canGoNext ?? false + icon: "skip_next" + } + } } } diff --git a/Modules/Settings/Background.qml b/Modules/Settings/Background.qml deleted file mode 100644 index cc242f7..0000000 --- a/Modules/Settings/Background.qml +++ /dev/null @@ -1,66 +0,0 @@ -import QtQuick -import QtQuick.Shapes -import qs.Components -import qs.Config - -ShapePath { - id: root - - readonly property bool flatten: wrapper.height < rounding * 2 - readonly property real rounding: 8 - readonly property real roundingY: flatten ? wrapper.height / 2 : rounding - required property Wrapper wrapper - - fillColor: DynamicColors.palette.m3surface - strokeWidth: -1 - - Behavior on fillColor { - CAnim { - } - } - - PathArc { - radiusX: root.rounding - radiusY: Math.min(root.roundingY, root.wrapper.height) - relativeX: root.rounding - relativeY: root.roundingY - } - - PathLine { - relativeX: 0 - relativeY: root.wrapper.height - root.roundingY * 2 - } - - PathArc { - direction: PathArc.Counterclockwise - radiusX: root.rounding - radiusY: Math.min(root.rounding, root.wrapper.height) - relativeX: root.rounding - relativeY: root.roundingY - } - - PathLine { - relativeX: root.wrapper.width - root.rounding * 2 - relativeY: 0 - } - - PathArc { - direction: PathArc.Counterclockwise - radiusX: root.rounding - radiusY: Math.min(root.rounding, root.wrapper.height) - relativeX: root.rounding - relativeY: -root.roundingY - } - - PathLine { - relativeX: 0 - relativeY: -(root.wrapper.height - root.roundingY * 2) - } - - PathArc { - radiusX: root.rounding - radiusY: Math.min(root.rounding, root.wrapper.height) - relativeX: root.rounding - relativeY: -root.roundingY - } -} diff --git a/Modules/Settings/Categories.qml b/Modules/Settings/Categories.qml deleted file mode 100644 index 08bcacc..0000000 --- a/Modules/Settings/Categories.qml +++ /dev/null @@ -1,178 +0,0 @@ -pragma ComponentBehavior: Bound - -import Quickshell -import Quickshell.Widgets -import QtQuick -import QtQuick.Layouts -import qs.Components -import qs.Modules as Modules -import qs.Config -import qs.Helpers - -Item { - id: root - - required property Item content - - implicitHeight: clayout.contentHeight + Appearance.padding.smaller * 2 - implicitWidth: clayout.contentWidth + Appearance.padding.smaller * 2 - - ListModel { - id: listModel - - ListElement { - icon: "settings" - name: "General" - } - - ListElement { - icon: "wallpaper" - name: "Wallpaper" - } - - ListElement { - icon: "settop_component" - name: "Bar" - } - - ListElement { - icon: "lock" - name: "Lockscreen" - } - - ListElement { - icon: "build_circle" - name: "Services" - } - - ListElement { - icon: "notifications" - name: "Notifications" - } - - ListElement { - icon: "view_sidebar" - name: "Sidebar" - } - - ListElement { - icon: "handyman" - name: "Utilities" - } - - ListElement { - icon: "dashboard" - name: "Dashboard" - } - - ListElement { - icon: "colors" - name: "Appearance" - } - - ListElement { - icon: "display_settings" - name: "On screen display" - } - - ListElement { - icon: "rocket_launch" - name: "Launcher" - } - - ListElement { - icon: "colors" - name: "Colors" - } - } - - CustomRect { - anchors.fill: parent - color: DynamicColors.tPalette.m3surfaceContainer - radius: 4 - - CustomListView { - id: clayout - - anchors.centerIn: parent - contentHeight: contentItem.childrenRect.height - contentWidth: contentItem.childrenRect.width - highlightFollowsCurrentItem: false - implicitHeight: contentItem.childrenRect.height - implicitWidth: contentItem.childrenRect.width - model: listModel - spacing: 5 - - delegate: Category { - } - highlight: CustomRect { - color: DynamicColors.palette.m3primary - implicitHeight: clayout.currentItem?.implicitHeight ?? 0 - implicitWidth: clayout.width - radius: 4 - y: clayout.currentItem?.y ?? 0 - - Behavior on y { - Anim { - duration: Appearance.anim.durations.small - easing.bezierCurve: Appearance.anim.curves.expressiveEffects - } - } - } - } - } - - component Category: CustomRect { - id: categoryItem - - required property string icon - required property int index - required property string name - - implicitHeight: 42 - implicitWidth: 200 - radius: 4 - - RowLayout { - id: layout - - anchors.left: parent.left - anchors.margins: Appearance.padding.smaller - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - - MaterialIcon { - id: icon - - Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter - Layout.fillHeight: true - Layout.preferredWidth: icon.contentWidth - color: categoryItem.index === clayout.currentIndex ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface - font.pointSize: 22 - text: categoryItem.icon - verticalAlignment: Text.AlignVCenter - } - - CustomText { - id: text - - Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter - Layout.fillHeight: true - Layout.fillWidth: true - Layout.leftMargin: Appearance.spacing.normal - color: categoryItem.index === clayout.currentIndex ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface - text: categoryItem.name - verticalAlignment: Text.AlignVCenter - } - } - - StateLayer { - id: layer - - onClicked: { - root.content.currentCategory = categoryItem.name.toLowerCase(); - clayout.currentIndex = categoryItem.index; - } - } - } -} diff --git a/Modules/Settings/Categories/Appearance.qml b/Modules/Settings/Categories/Appearance.qml deleted file mode 100644 index a75b264..0000000 --- a/Modules/Settings/Categories/Appearance.qml +++ /dev/null @@ -1,66 +0,0 @@ -import Quickshell -import Quickshell.Widgets -import QtQuick -import QtQuick.Layouts -import qs.Components -import qs.Modules as Modules -import qs.Modules.Settings.Controls -import qs.Config -import qs.Helpers - -CustomRect { - id: root - - ColumnLayout { - id: clayout - - anchors.left: parent.left - anchors.right: parent.right - - CustomRect { - Layout.fillWidth: true - Layout.preferredHeight: colorLayout.implicitHeight - color: DynamicColors.tPalette.m3surfaceContainer - - ColumnLayout { - id: colorLayout - - anchors.left: parent.left - anchors.margins: Appearance.padding.large - anchors.right: parent.right - - Settings { - name: "smth" - } - - SettingSwitch { - name: "wallust" - object: Config.general.color - setting: "wallust" - } - } - } - } - - component Settings: CustomRect { - id: settingsItem - - required property string name - - Layout.preferredHeight: 42 - Layout.preferredWidth: 200 - radius: 4 - - CustomText { - id: text - - anchors.left: parent.left - anchors.margins: Appearance.padding.smaller - anchors.right: parent.right - font.bold: true - font.pointSize: 32 - text: settingsItem.name - verticalAlignment: Text.AlignVCenter - } - } -} diff --git a/Modules/Settings/Categories/Background.qml b/Modules/Settings/Categories/Background.qml deleted file mode 100644 index 2d24d68..0000000 --- a/Modules/Settings/Categories/Background.qml +++ /dev/null @@ -1,13 +0,0 @@ -import Quickshell -import Quickshell.Widgets -import QtQuick -import QtQuick.Layouts -import qs.Components -import qs.Modules as Modules -import qs.Config -import qs.Helpers - -CustomRect { - id: root - -} diff --git a/Modules/Settings/Categories/General.qml b/Modules/Settings/Categories/General.qml deleted file mode 100644 index 3e8335c..0000000 --- a/Modules/Settings/Categories/General.qml +++ /dev/null @@ -1,55 +0,0 @@ -import Quickshell -import Quickshell.Widgets -import QtQuick -import QtQuick.Layouts -import qs.Components -import qs.Modules as Modules -import qs.Config -import qs.Helpers - -CustomRect { - id: root - - ColumnLayout { - id: clayout - - anchors.fill: parent - - Settings { - name: "apps" - } - - Item { - } - } - - component Settings: CustomRect { - id: settingsItem - - required property string name - - implicitHeight: 42 - implicitWidth: 200 - radius: 4 - - RowLayout { - id: layout - - anchors.left: parent.left - anchors.margins: Appearance.padding.smaller - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - - CustomText { - id: text - - Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter - Layout.fillHeight: true - Layout.fillWidth: true - Layout.leftMargin: Appearance.spacing.normal - text: settingsItem.name - verticalAlignment: Text.AlignVCenter - } - } - } -} diff --git a/Modules/Settings/Content.qml b/Modules/Settings/Content.qml deleted file mode 100644 index 1037a21..0000000 --- a/Modules/Settings/Content.qml +++ /dev/null @@ -1,102 +0,0 @@ -import Quickshell -import Quickshell.Widgets -import QtQuick -import QtQuick.Controls -import qs.Components -import qs.Modules as Modules -import qs.Modules.Settings.Categories as Cat -import qs.Config -import qs.Helpers - -Item { - id: root - - property string currentCategory: "general" - readonly property real nonAnimHeight: view.implicitHeight + viewWrapper.anchors.margins * 2 - readonly property real nonAnimWidth: view.implicitWidth + 500 + viewWrapper.anchors.margins * 2 - required property PersistentProperties visibilities - - implicitHeight: nonAnimHeight - implicitWidth: nonAnimWidth - - Connections { - function onCurrentCategoryChanged() { - stack.pop(); - if (currentCategory === "general") { - stack.push(general); - } else if (currentCategory === "wallpaper") { - stack.push(background); - } else if (currentCategory === "appearance") { - stack.push(appearance); - } - } - - target: root - } - - ClippingRectangle { - id: viewWrapper - - anchors.fill: parent - anchors.margins: Appearance.padding.smaller - color: "transparent" - - Item { - id: view - - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.top: parent.top - implicitHeight: layout.implicitHeight - implicitWidth: layout.implicitWidth - - Categories { - id: layout - - anchors.fill: parent - content: root - } - } - - CustomClippingRect { - id: categoryContent - - anchors.bottom: parent.bottom - anchors.left: view.right - anchors.leftMargin: Appearance.spacing.smaller - anchors.right: parent.right - anchors.top: parent.top - color: DynamicColors.tPalette.m3surfaceContainer - radius: 4 - - StackView { - id: stack - - anchors.fill: parent - anchors.margins: Appearance.padding.smaller - initialItem: general - } - } - } - - Component { - id: general - - Cat.General { - } - } - - Component { - id: background - - Cat.Background { - } - } - - Component { - id: appearance - - Cat.Appearance { - } - } -} diff --git a/Modules/Settings/Controls/SettingSwitch.qml b/Modules/Settings/Controls/SettingSwitch.qml deleted file mode 100644 index 524e740..0000000 --- a/Modules/Settings/Controls/SettingSwitch.qml +++ /dev/null @@ -1,36 +0,0 @@ -import QtQuick -import QtQuick.Layouts -import qs.Components -import qs.Config - -RowLayout { - id: root - - required property string name - required property var object - required property string setting - - Layout.fillWidth: true - Layout.preferredHeight: 42 - - CustomText { - id: text - - Layout.alignment: Qt.AlignLeft - Layout.fillWidth: true - font.pointSize: 16 - text: root.name - } - - CustomSwitch { - id: cswitch - - Layout.alignment: Qt.AlignRight - checked: root.object[root.setting] - - onToggled: { - root.object[root.setting] = checked; - Config.save(); - } - } -} diff --git a/Modules/Settings/Settings.qml b/Modules/Settings/Settings.qml deleted file mode 100644 index dd3bfc3..0000000 --- a/Modules/Settings/Settings.qml +++ /dev/null @@ -1,11 +0,0 @@ -import Quickshell -import Quickshell.Widgets -import QtQuick -import QtQuick.Layouts -import qs.Components -import qs.Modules as Modules -import qs.Config -import qs.Helpers - -Item { -} diff --git a/Modules/Settings/Wrapper.qml b/Modules/Settings/Wrapper.qml deleted file mode 100644 index dec6264..0000000 --- a/Modules/Settings/Wrapper.qml +++ /dev/null @@ -1,61 +0,0 @@ -import Quickshell -import QtQuick -import qs.Components -import qs.Config -import qs.Helpers - -Item { - id: root - - required property var panels - required property PersistentProperties visibilities - - implicitHeight: 0 - implicitWidth: content.implicitWidth - visible: height > 0 - - states: State { - name: "visible" - when: root.visibilities.settings - - PropertyChanges { - root.implicitHeight: content.implicitHeight - } - } - transitions: [ - Transition { - from: "" - to: "visible" - - Anim { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects - property: "implicitHeight" - target: root - } - }, - Transition { - from: "visible" - to: "" - - Anim { - easing.bezierCurve: MaterialEasing.expressiveEffects - property: "implicitHeight" - target: root - } - } - ] - - Loader { - id: content - - active: true - anchors.bottom: parent.bottom - anchors.horizontalCenter: parent.horizontalCenter - visible: true - - sourceComponent: Content { - visibilities: root.visibilities - } - } -} diff --git a/assets/shaders/opacitymask.frag.qsb b/assets/shaders/opacitymask.frag.qsb index 4aedc3529f58b86dba7e775a3fbe2d304bf25981..7bf97c280f5b98e09f7e83c6dc2c678d7901e9ec 100644 GIT binary patch literal 1337 zcmV-91;+XS01%LPoZVM#Pa8)N9@`KXLtdaHAx%gwp^fYoxyEs-s1Aq<(l$~e+8Cvk zEOa`~XLG^6bME$tQN&;9$Nq+X>Hq7Os-4-L^R3S|L8>ZMJ#_eH_L*m9pPk*a0bmXQ zX7JA7y#jARfC>BHzyNl@$G-qtP{FY*-tZS+FySJCC1_)S1sxgOmEns1gQ1t;5F!kx zClemQ20ra-n5?8%^}WOt0;yfB5@4PY+Zy^>{IJX+d(g)q8$$$~a?0(vwrLmTT!0X# z5n(nPRRJjSBr=l%mZ67PLO6!T#GveX*)Dor;?Gv%%KethuH~tydH4t(vUd^lQJM1? zLZ9EgXuK$gqE)UvrWJ)NkdrtXy9#-!1>HT%^~gUbIY`W$^yi5KpU8igbC7)*KkqY7 zY(LP(7gP9U#%DD z9M4Hr==ladk=O>_HxZv_@n@uO29*YhC4ZgmIriPcrvl^CtrFX}5lPKkV7>+R&odv{ zm)S@8uQFej@z)?;JB25Ek$rLeGRI#>dxhsh*B5Nx;(AxmzQc2&`Q2sh?{H4acb9Xo zGC$e(*hl;Z^JkdffTS-d{sCi&?<-uREF}AnYWM>^w9cF8B@M3d{5N^-OFX}y5S5o} zrZ7ud%yph~9CITTbCWUT{}Fvu%O~uo8h&BiZRV%3Z_r1zukn2EGe5w!A`bN9!TcSSZc0F_! zLJ>r^Fb<=3;eEltt7nOt@m82GEfKhby7Wl~a_;pl+ZCtv!Wo7}p4;|=9>p5wqYcfY z5`D3u6IFkhcTM2A5!(7 zX-darHPJLDY}BCb1X7Bxjlk)+p>TrYVI{6H@ZXs|>kZZ@wX6+ll)@b9j8T~C*l)K( zM-=T!Nf(}xTucgDE2-7kkK5&`%CN=S>-7lYZKx$^2unDIsX!*Liw+J6JkFX3H^RIz z#+(2rvQq$dpCw$IHPIJe9~f%^?%Bo<&tJVZcLF~Q&F5Y}5^+C_2Vv&@XFu=k?Y-Kq zD7hwZ>_s9)qLqXUjo0SB6?7cI6tWWuU`}sGC2v_NQ%tEn-kphN!;ojSxW9Be@^MR2C? zNBYXLknG3o?`y7SccYeLJncEc>YDf!yXziq6%v2w_F7-kzw*%*9$X=v<(}1ZLKM(3 zWYna$_;B}L=!E2OsFj1R3UNPmecMaIiMr=_T59!F zj0y2u3P#4OdT_9A*uICRCnx)m+6l+isV2)>AHI)T>L?hVFU@9rrcS|WCq{zZkl6TO zP*e>xNDTHeUyMm;(m3KO4PRgJgz4Ti-k+%j@>4w)?@Yx})CyQfZOZ3tOpZvEGafbh vMWQvdulkr8c~+LqZj$rf>|60`}pe zi7oi>p-@5wKoS6cvf&b=1S2RzL84-Ut0uga{@Tzk93Vv5oC;V&7Ql9lL-j|vza2LF1H5ZbrRbWmK~t0epl|D8dDh=0{M13pR!tBmx{^ z@6sSM#G6{wa;XDZU#;X)H#OCV9^7Yi7)jG+AG*x{i&uNERs&sHU4KN1VgQ!m(cK`r zO=9}hq*o`LR%6%<(=vEB<$!JQIj%weEdUFgC-N6#_rvG-W6V#+{0`s3EZ@C^ZO&vV z<<0Mbgw2mB^ogWtP|BeEp2~aX#{Cmf-q>oG;1zp|*A{KKa9pMe#ISvT@j$ z;9wTMW z(K1sH-;p#rZ@@M)7~uDlPj4LI_q{>N^f}6$kyy+)zd4GTI2SX?9Kv5CWqP^IIQ8&_ zc{7}!?w%oKdZ%5Ac8Ky*>|MsAxO*H+_)}PB9|-$_1fH~%xB2@@@Hfoska)jz;;O*& z>mr-UI1S|%J>wmEmBWT8SAD7T7htch^Ntf}6&AHP2+Ph#M+hNmQm>0+UD%OYdCk1R zOa=mX8?xx>)4cO3?>J%IEBmTOv7)e+jUlZ9fvh#EuF7qTzzs~?D1Sj(=Sd9~x5RUxqwQ{i)4g|$pZxWWG}L{*;pp-xx*qSVyw zhR7@nKh&hmx+p7I+48Ht$~#{DH^pkl#B{n&rJHNC8Pn)nN2A Date: Wed, 25 Feb 2026 14:20:11 +0100 Subject: [PATCH 2/8] lmao --- thumb.jpg | Bin 4062 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 thumb.jpg diff --git a/thumb.jpg b/thumb.jpg deleted file mode 100644 index 21e36656a5413c33591e58cfcb8e3814265d65a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4062 zcmbW!c{J4jzX$No7>pT%>`P5(_uPBV{p;TQe4Y3EpZDv$&g*gBf5!gI0%xvk;k5t|2mnBT3-~hu zr~?f2^bmSF1_%TKg)+e4987RVMmR4UI|~Otp8%4d4}lOwONj`clRzO5q6%UXm!#$7 z9a_3!i&VDm&qxq**Up+`2}wZ-!P8h1=B+Qae-)j{~j8KvL+}>)^MBC z%A+5~g_fHW-uZ|2FWLVN7V`g+{TJ-NUE=^84EpH7u=_M?(ot_l=R>?NS|ixF zas!DUHg~%jK){+1oQbgs1SLXxcD)d=uQ*nm!9}(F#cG_D5?Ku|21^AaaY za+YwW_cAWfwCoJV?rm8lW~6)Dq0741weo7&O3n)C4G+V_TI=H_IlsYH&aCce3@WuH zPO1gR1?=z$~+jp8P235kHdopO{#CXZ?ixDqb*a^1JTXxXJ9fOa?e zBT7YL+xkYLLj=}ITU41gxV33Gk(ehlOEXvNK@Y|BK5~3hTUo{R66Iu|V<%gAYlC^`G1ax{xYa}i85(K(%FY?P zZf3npzkI0HRpak-t4Gx$Ekh65NDF&M!DZV1LfX9}vgA+m#CG#8oE-{^wynH6JpD5i zS6BPV^vfRdCf5;usSuK9(>CY$jNS92Lx7b3>E(p*>99R7nTOZxBvOkseGA)-1d*om z{FwPt;0MB_hIp`dR!1>aaQii-V;<%!&XnsdAcpW>W*|gmO1{s~Mb7HNPPWOf>F7+K zG%tnL`fSp|k@{GZAm<|8!WHh+FzG2dl#HCk`VrhuHREk#!*}k-xCevMmpfzDv4nct zqyoChRJ!dXND}Y3=>eS;!Pu(Sc`|+``0*8MplxaG4OuCLO*Rn{b0y#rzxWtddxzJq zDz)E7`eyX%WPLS-wdPfuemxx^%-16%51m)Y+)p+!_043>|Ol3BOzRlJqY4 zS*lud+TUQ#WZY6*u780`C(+xve&X$HDSBH*{~>db@%GUGh;6mbYhc5~bc0G{qz6J6 zESQ-|sH5Aq-?GvrsfqF!E!*g3fT7obqC&`2k2l^w_GLHw`mox#DqLLWV9C<1 z;d-1tZ%ZgDBT#8FX>pMSyb|Bx$bL4$YFjSl>xFJ1!I(@@i+u`?;>g(QpN-F1HkQ$_ z94b~Y?`9N1Q`*CuPSFy~ENZI!(e^(Z7N8+fDN+i*GHmL3~P_ZHBXn&h{dhkq{Yg4n-kmn-Y+(Pz%}$YDRY&fPim2_a zqX9m*zLE#S8w9duO<*@H=gQlSqh!yt{jHcZ@1D#Ujyugnk|P|C4J%Y~lP{T^Wj=m% z&yNCepw14J7Uv(|ST5NUf+v8hhN#wW6q~^LxMIk3+iy4Tyx1}4^wZ%&^L$e%8L z@{E2#Bs1CWM=u1!zjprD>Nqa!crF~{L`lv=tCy7uy<(V*=`AYedqp8T}2R+i()rWim4%LGe z%MGf=N4^6I0|re@ek+0Tq}9l$$4Rb4KLw= zSJw4;`ACfKQA%L`gv&>=<lc2pj($Zj<*a>zlroALr<6YMc(Jd>csa!bG@vOVDdbL{3HlZ z5ANV{K|m1i{R}qd8=yp%1zk6.inARNBr{*DUgghS8oXOd&}ynra;!GdWC| z(z7k9*^rC}X8vDX%iUzjtF*?n+&H@nVjvP5ELEQ-wCTdPYVJ)D(TRtaZr``{VMx zT?*8$itD>uIe$qkFAEp_^*BAxB=8O-K5EZkVNv&${MZ)!US8TLwQS7NW>T?73v|-{ z?h*TF&OjC8Gp3q!$*;DTSuZL*r=iF7UJacnbs})|uZ)U8k$A!OpUv`DSJ_uG+!Q-# zfADNRI!heM-#pk>M`5KYWq45v#d6}{U>&m-8ndLF_&cK_wc%BeIbZA4JC2jPZ*+V{ zxO}Ayp}a^(`*e@jY&f(XZAb*Z0fd84z15>3b4jB&5>X%i04m&c1A4xl@+C@e zDN;MHQ%v*H-oj?Hs&Kc`r%3&6PJgUDy?%5i>9)yg-c34{}nu1IN}vw`?(~UFi<--&OLOJIr|g$mzvNPv%KGH z*=e|vvV^bJ+#2(UI56OG#SRjJi6$7H_U~{me4*bx?W2*Q+{V|42;b4u;`AI8?#<%3 zm9R*RF?f#W^m^(lDJA7XD6jQ0xl~6fqF@+lZXZmw&kya4w=Q^%(8Jee(lr4}n^gBGZxQT| z!yJ?er`cagl z7@rd}loVrivxYDkAEO6gV`Q}DhStXe8QkrhoeP=^{8Bqj+~HA zzh>PoEF3rF1PPb?0fg}8rj2?$M~@uYu3SnsrNAkV-tyV~k_5e)j{_%?Xz7!^iuA}f#i>ebvNm`T?QgdunmuY3 z;zUVMsVjS;$=!=KVLWbm$}trskW#T1C>?xcV&G-v%6P{#R+d;3Z43R#_BKZ>Q80SK zXMb70RG4FdV}LKgq%5M~&XgJPSAXP)4)J3Dr8`=!FtspX31jS(7TTslDw-%hw_LsO zY+j`}1uA69ei|6iuPIte3VUV4TUls0ji0wa`Ea@uUp?!K_6El^e9yGqy}EX1&aZ?O zguBb&J4I$_U)leG0dpAW-R+1O6~9L;(2dlxo|08$NXK@Zef*Ziby-|pbDO&Jg{g5> z0atu-LmMOb2=JQ!Y!!)LTgI7w3;LpR$I7+b&wsdDNjz<`0YlNBIwC2vRQvUv9~Vzf laneEuhanvi8^(H(m$)CT$9aY`_JwM4idAoRUi Date: Wed, 25 Feb 2026 14:29:54 +0100 Subject: [PATCH 3/8] .qmlformat.ini --- .qmlformat.ini | 10 ++++++++++ Components/MarqueeText.qml | 8 +++++--- 2 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 .qmlformat.ini diff --git a/.qmlformat.ini b/.qmlformat.ini new file mode 100644 index 0000000..1fe488c --- /dev/null +++ b/.qmlformat.ini @@ -0,0 +1,10 @@ +[General] +FunctionsSpacing=true +IndentWidth=4 +MaxColumnWidth=80 +NewlineType=native +NormalizeOrder=true +ObjectsSpacing=true +SemicolonRule=always +SortImports=false +UseTabs=true diff --git a/Components/MarqueeText.qml b/Components/MarqueeText.qml index 02d123d..0035767 100644 --- a/Components/MarqueeText.qml +++ b/Components/MarqueeText.qml @@ -12,13 +12,15 @@ Item { property int gap: 40 property alias horizontalAlignment: elideText.horizontalAlignment property bool leftFadeEnabled: false - property real leftFadeStrength: overflowing && leftFadeEnabled ? fadeStrengthMoving : fadeStrengthIdle + property real leftFadeStrength: overflowing && leftFadeEnabled + ? fadeStrengthMoving : fadeStrengthIdle property int leftFadeWidth: 28 property bool marqueeEnabled: true readonly property bool overflowing: metrics.width > root.width property int pauseMs: 1200 property real pixelsPerSecond: 40 - property real rightFadeStrength: overflowing ? fadeStrengthMoving : fadeStrengthIdle + property real rightFadeStrength: overflowing ? fadeStrengthMoving : + fadeStrengthIdle property int rightFadeWidth: 28 property bool sliding: false property alias text: elideText.text @@ -41,7 +43,7 @@ Item { onTextChanged: strip.x = 0 onVisibleChanged: if (!visible) - strip.x = 0 + strip.x = 0 onWidthChanged: strip.x = 0 TextMetrics { -- 2.47.3 From 419214f4bd6313b3b17c52664141405095c6a450 Mon Sep 17 00:00:00 2001 From: Zacharias-Brohn Date: Wed, 25 Feb 2026 14:35:23 +0100 Subject: [PATCH 4/8] oops lol --- Drawers/Backgrounds.qml | 20 +++++++++++--------- Drawers/Panels.qml | 23 ++++++++++++----------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/Drawers/Backgrounds.qml b/Drawers/Backgrounds.qml index 00035c5..0abb605 100644 --- a/Drawers/Backgrounds.qml +++ b/Drawers/Backgrounds.qml @@ -8,7 +8,8 @@ import qs.Modules.Notifications.Sidebar.Utils as Utils import qs.Modules.Dashboard as Dashboard import qs.Modules.Osd as Osd import qs.Modules.Launcher as Launcher -import qs.Modules.Settings as Settings + +// import qs.Modules.Settings as Settings Shape { id: root @@ -22,7 +23,8 @@ Shape { anchors.topMargin: bar.implicitHeight preferredRendererType: Shape.CurveRenderer - Component.onCompleted: console.log(root.bar.implicitHeight, root.bar.anchors.topMargin) + Component.onCompleted: console.log(root.bar.implicitHeight, + root.bar.anchors.topMargin) Osd.Background { startX: root.width - root.panels.sidebar.width @@ -72,11 +74,11 @@ Shape { wrapper: root.panels.sidebar } - Settings.Background { - id: settings - - startX: (root.width - wrapper.width) / 2 - rounding - startY: 0 - wrapper: root.panels.settings - } + // Settings.Background { + // id: settings + // + // startX: (root.width - wrapper.width) / 2 - rounding + // startY: 0 + // wrapper: root.panels.settings + // } } diff --git a/Drawers/Panels.qml b/Drawers/Panels.qml index 4030e22..df0fba5 100644 --- a/Drawers/Panels.qml +++ b/Drawers/Panels.qml @@ -9,7 +9,7 @@ import qs.Modules.Dashboard as Dashboard import qs.Modules.Osd as Osd import qs.Components.Toast as Toasts import qs.Modules.Launcher as Launcher -import qs.Modules.Settings as Settings +// import qs.Modules.Settings as Settings import qs.Config Item { @@ -22,7 +22,7 @@ Item { readonly property alias osd: osd readonly property alias popouts: popouts required property ShellScreen screen - readonly property alias settings: settings + // readonly property alias settings: settings readonly property alias sidebar: sidebar readonly property alias toasts: toasts readonly property alias utilities: utilities @@ -30,7 +30,8 @@ Item { anchors.fill: parent // anchors.margins: 8 - anchors.topMargin: Config.barConfig.autoHide && !visibilities.bar ? 0 : bar.implicitHeight + anchors.topMargin: Config.barConfig.autoHide && !visibilities.bar ? 0 : + bar.implicitHeight Behavior on anchors.topMargin { Anim { @@ -117,12 +118,12 @@ Item { visibilities: root.visibilities } - Settings.Wrapper { - id: settings - - anchors.horizontalCenter: parent.horizontalCenter - anchors.top: parent.top - panels: root - visibilities: root.visibilities - } + // Settings.Wrapper { + // id: settings + // + // anchors.horizontalCenter: parent.horizontalCenter + // anchors.top: parent.top + // panels: root + // visibilities: root.visibilities + // } } -- 2.47.3 From eafb176d6e7a4b3f788b482c1777b5eea7a8d76e Mon Sep 17 00:00:00 2001 From: Zacharias-Brohn Date: Wed, 25 Feb 2026 17:08:04 +0100 Subject: [PATCH 5/8] notification cooldown --- Config/Config.qml | 19 +++++++++++++------ Config/NotifConfig.qml | 1 + Daemons/NotifServer.qml | 27 ++++++++++++++++++++++++++- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/Config/Config.qml b/Config/Config.qml index 716a02c..124ae6f 100644 --- a/Config/Config.qml +++ b/Config/Config.qml @@ -205,6 +205,7 @@ Singleton { return { expire: notifs.expire, defaultExpireTimeout: notifs.defaultExpireTimeout, + appNotifCooldown: notifs.appNotifCooldown, clearThreshold: notifs.clearThreshold, expandThreshold: notifs.expandThreshold, actionOnClick: notifs.actionOnClick, @@ -306,7 +307,8 @@ Singleton { fileView.setText(JSON.stringify(config, null, 4)); } catch (e) { - Toaster.toast(qsTr("Failed to serialize config"), e.message, "settings_alert", Toast.Error); + Toaster.toast(qsTr("Failed to serialize config"), e.message, + "settings_alert", Toast.Error); } } } @@ -337,7 +339,8 @@ Singleton { } onLoadFailed: err => { if (err !== FileViewError.FileNotFound) - Toaster.toast(qsTr("Failed to read config"), FileViewError.toString(err), "settings_alert", Toast.Warning); + Toaster.toast(qsTr("Failed to read config"), FileViewError.toString(err), + "settings_alert", Toast.Warning); } onLoaded: { ModeScheduler.checkStartup(); @@ -346,15 +349,19 @@ Singleton { const elapsed = timer.elapsedMs(); if (adapter.utilities.toasts.configLoaded && !root.recentlySaved) { - Toaster.toast(qsTr("Config loaded"), qsTr("Config loaded in %1ms").arg(elapsed), "rule_settings"); + Toaster.toast(qsTr("Config loaded"), qsTr("Config loaded in %1ms").arg( + elapsed), "rule_settings"); } else if (adapter.utilities.toasts.configLoaded && root.recentlySaved) { - Toaster.toast(qsTr("Config saved"), qsTr("Config reloaded in %1ms").arg(elapsed), "settings_alert"); + Toaster.toast(qsTr("Config saved"), qsTr("Config reloaded in %1ms").arg( + elapsed), "settings_alert"); } } catch (e) { - Toaster.toast(qsTr("Failed to load config"), e.message, "settings_alert", Toast.Error); + Toaster.toast(qsTr("Failed to load config"), e.message, "settings_alert", + Toast.Error); } } - onSaveFailed: err => Toaster.toast(qsTr("Failed to save config"), FileViewError.toString(err), "settings_alert", Toast.Error) + onSaveFailed: err => Toaster.toast(qsTr("Failed to save config"), + FileViewError.toString(err), "settings_alert", Toast.Error) JsonAdapter { id: adapter diff --git a/Config/NotifConfig.qml b/Config/NotifConfig.qml index fde337b..0a11d46 100644 --- a/Config/NotifConfig.qml +++ b/Config/NotifConfig.qml @@ -2,6 +2,7 @@ import Quickshell.Io JsonObject { property bool actionOnClick: false + property int appNotifCooldown: 0 property real clearThreshold: 0.3 property int defaultExpireTimeout: 5000 property int expandThreshold: 20 diff --git a/Daemons/NotifServer.qml b/Daemons/NotifServer.qml index 8937e57..c4cec7a 100644 --- a/Daemons/NotifServer.qml +++ b/Daemons/NotifServer.qml @@ -23,6 +23,29 @@ Singleton { readonly property list popups: list.filter(n => n.popup) property alias server: server + readonly property var appCooldownMap: new Map() + + function shouldThrottle(appName: string): bool { + if ( props.dnd ) + return false; + + const key = ( appName || "unknown" ).trim().toLowerCase(); + const cooldownSec = Config.notifs.appNotifCooldown; + const cooldownMs = Math.max(0, cooldownSec * 1000); + + if ( cooldownMs <= 0 ) + return true; + + const now = Date.now(); + const until = appCooldownMap.get( key ) ?? 0; + + if ( now < until ) + return false; + + appCooldownMap.set( key, now + cooldownMs ) + return true; + } + onListChanged: { if (loaded) { saveTimer.restart(); @@ -77,8 +100,10 @@ Singleton { onNotification: notif => { notif.tracked = true; + const is_popup = root.shouldThrottle(notif.appName); + const comp = notifComp.createObject(root, { - popup: !props.dnd, + popup: is_popup, notification: notif }); root.list = [comp, ...root.list]; -- 2.47.3 From 15a112eaf71ecf0c5eeffb3bccbe18e76e999321 Mon Sep 17 00:00:00 2001 From: Zacharias-Brohn Date: Wed, 25 Feb 2026 17:28:09 +0100 Subject: [PATCH 6/8] ideas --- plans/ideas.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plans/ideas.md b/plans/ideas.md index af8e1a0..d4e827c 100644 --- a/plans/ideas.md +++ b/plans/ideas.md @@ -9,11 +9,13 @@ - [x] Maybe already possible; have keybinds to show certain menus. I do not want to touch my mouse to see notifications for example. Not everything in the bar needs this, but some would be good to have. - [x] Pressing ESC or some obvious button to close nc. - [x] Another branch for development, hold off big changes so that a working bar or if there are big config changes. +- [ ] Notification audio cue integration (with config option to disable). +- [x] Notification timeout per service. Example: If Discord pushes two notifications, the following notifications are muted for 10 minutes from Discord only. Perhaps a global mute is easier initially. # Stupid idea's from Daivin - [ ] An on screen pencil to draw on your screen :). - [ ] Audio module + cava / audio wave ;) ( Don't make it into minecraft blocks - but aan actual wave) + but aan actual wave) -- Probably not planned - [ ] Update module: When there is 1 package it still looks extremely off -- [ ] Bluetooth device battery view +- [ ] Bluetooth device battery view -- Also not planned (I don't have bluetooth) -- 2.47.3 From 11da456048c017c1cf4066553515c6b9cb54ccad Mon Sep 17 00:00:00 2001 From: Zacharias-Brohn Date: Wed, 25 Feb 2026 17:29:14 +0100 Subject: [PATCH 7/8] formatter --- .qmlformat.ini | 2 +- Daemons/NotifServer.qml | 15 +++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/.qmlformat.ini b/.qmlformat.ini index 1fe488c..405a8d1 100644 --- a/.qmlformat.ini +++ b/.qmlformat.ini @@ -1,7 +1,7 @@ [General] FunctionsSpacing=true IndentWidth=4 -MaxColumnWidth=80 +MaxColumnWidth=-1 NewlineType=native NormalizeOrder=true ObjectsSpacing=true diff --git a/Daemons/NotifServer.qml b/Daemons/NotifServer.qml index c4cec7a..ca87549 100644 --- a/Daemons/NotifServer.qml +++ b/Daemons/NotifServer.qml @@ -16,6 +16,7 @@ import qs.Config Singleton { id: root + readonly property var appCooldownMap: new Map() property alias dnd: props.dnd property list list: [] property bool loaded @@ -23,26 +24,24 @@ Singleton { readonly property list popups: list.filter(n => n.popup) property alias server: server - readonly property var appCooldownMap: new Map() - function shouldThrottle(appName: string): bool { - if ( props.dnd ) + if (props.dnd) return false; - const key = ( appName || "unknown" ).trim().toLowerCase(); + const key = (appName || "unknown").trim().toLowerCase(); const cooldownSec = Config.notifs.appNotifCooldown; const cooldownMs = Math.max(0, cooldownSec * 1000); - if ( cooldownMs <= 0 ) + if (cooldownMs <= 0) return true; const now = Date.now(); - const until = appCooldownMap.get( key ) ?? 0; + const until = appCooldownMap.get(key) ?? 0; - if ( now < until ) + if (now < until) return false; - appCooldownMap.set( key, now + cooldownMs ) + appCooldownMap.set(key, now + cooldownMs); return true; } -- 2.47.3 From ed9e0d1c85cee0faf415cc3c93f4569c85e56287 Mon Sep 17 00:00:00 2001 From: Zacharias-Brohn Date: Wed, 25 Feb 2026 18:13:09 +0100 Subject: [PATCH 8/8] updates module + remove pixelSize usage --- Modules/AudioWidget.qml | 19 +++++++++-------- Modules/NotifBell.qml | 4 ++-- Modules/Resources.qml | 15 +++++++------ Modules/UpdatesWidget.qml | 44 ++++++++++----------------------------- plans/ideas.md | 26 ++++++++++++----------- 5 files changed, 44 insertions(+), 64 deletions(-) diff --git a/Modules/AudioWidget.qml b/Modules/AudioWidget.qml index 125747b..4e3fa41 100644 --- a/Modules/AudioWidget.qml +++ b/Modules/AudioWidget.qml @@ -11,12 +11,11 @@ Item { id: root property color barColor: DynamicColors.palette.m3primary - property bool expanded: false property color textColor: DynamicColors.palette.m3onSurface anchors.bottom: parent.bottom anchors.top: parent.top - implicitWidth: expanded ? 300 : 150 + implicitWidth: 150 Behavior on implicitWidth { NumberAnimation { @@ -49,16 +48,18 @@ Item { } RowLayout { - anchors { - fill: parent - leftMargin: 10 - rightMargin: 15 - } + id: layout + + anchors.left: parent.left + anchors.leftMargin: Appearance.padding.small + anchors.right: parent.right + anchors.rightMargin: Appearance.padding.small * 2 + anchors.verticalCenter: parent.verticalCenter MaterialIcon { Layout.alignment: Qt.AlignVCenter color: Audio.muted ? DynamicColors.palette.m3error : root.textColor - font.pixelSize: 18 + font.pointSize: 14 text: Audio.muted ? "volume_off" : "volume_up" } @@ -91,7 +92,7 @@ Item { MaterialIcon { Layout.alignment: Qt.AlignVCenter color: (Audio.sourceMuted ?? false) ? DynamicColors.palette.m3error : root.textColor - font.pixelSize: 18 + font.pointSize: 14 text: Audio.sourceMuted ? "mic_off" : "mic" } diff --git a/Modules/NotifBell.qml b/Modules/NotifBell.qml index 314c7a9..ebe9746 100644 --- a/Modules/NotifBell.qml +++ b/Modules/NotifBell.qml @@ -13,7 +13,7 @@ Item { anchors.bottom: parent.bottom anchors.top: parent.top - implicitWidth: 25 + implicitWidth: 30 CustomRect { anchors.bottomMargin: 3 @@ -30,7 +30,7 @@ Item { anchors.centerIn: parent color: iconColor font.family: "Material Symbols Rounded" - font.pixelSize: 20 + font.pointSize: 16 text: HasNotifications.hasNotifications ? "\uf4fe" : "\ue7f4" Behavior on color { diff --git a/Modules/Resources.qml b/Modules/Resources.qml index 5343d68..829251f 100644 --- a/Modules/Resources.qml +++ b/Modules/Resources.qml @@ -14,7 +14,7 @@ Item { clip: true implicitHeight: 34 - implicitWidth: rowLayout.implicitWidth + rowLayout.anchors.leftMargin + rowLayout.anchors.rightMargin + implicitWidth: rowLayout.implicitWidth + Appearance.padding.small * 2 Rectangle { id: backgroundRect @@ -37,19 +37,18 @@ Item { RowLayout { id: rowLayout - anchors.fill: parent - anchors.leftMargin: 5 - anchors.rightMargin: 5 + anchors.centerIn: parent spacing: 6 MaterialIcon { Layout.alignment: Qt.AlignVCenter color: DynamicColors.palette.m3onSurface - font.pixelSize: 18 + font.pointSize: 14 text: "memory_alt" } Resource { + Layout.alignment: Qt.AlignVCenter mainColor: DynamicColors.palette.m3primary percentage: ResourceUsage.memoryUsedPercentage warningThreshold: 95 @@ -58,7 +57,7 @@ Item { MaterialIcon { Layout.alignment: Qt.AlignVCenter color: DynamicColors.palette.m3onSurface - font.pixelSize: 18 + font.pointSize: 14 text: "memory" } @@ -71,7 +70,7 @@ Item { MaterialIcon { Layout.alignment: Qt.AlignVCenter color: DynamicColors.palette.m3onSurface - font.pixelSize: 18 + font.pointSize: 14 text: "gamepad" } @@ -83,7 +82,7 @@ Item { MaterialIcon { Layout.alignment: Qt.AlignVCenter color: DynamicColors.palette.m3onSurface - font.pixelSize: 18 + font.pointSize: 14 text: "developer_board" } diff --git a/Modules/UpdatesWidget.qml b/Modules/UpdatesWidget.qml index bb59f29..7bb4b51 100644 --- a/Modules/UpdatesWidget.qml +++ b/Modules/UpdatesWidget.qml @@ -12,62 +12,40 @@ Item { anchors.bottom: parent.bottom anchors.top: parent.top - implicitWidth: textMetrics.width + contentRow.spacing + 30 + implicitWidth: contentRow.childrenRect.width + Appearance.spacing.smaller - Rectangle { + CustomRect { anchors.left: parent.left anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter color: DynamicColors.tPalette.m3surfaceContainer implicitHeight: 22 radius: height / 2 - - Behavior on color { - CAnim { - } - } } RowLayout { id: contentRow - spacing: 10 + anchors.centerIn: parent + implicitHeight: 22 + spacing: Appearance.spacing.small - anchors { - fill: parent - leftMargin: 5 - rightMargin: 5 - } - - Text { - Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft - color: root.textColor - font.family: "Material Symbols Rounded" - font.pixelSize: 18 - text: "\uf569" - - Behavior on color { - CAnim { - } - } + MaterialIcon { + Layout.alignment: Qt.AlignVCenter + font.pointSize: 14 + text: "package_2" } TextMetrics { id: textMetrics - font.pixelSize: 16 text: root.countUpdates } - Text { - Layout.alignment: Qt.AlignVCenter | Qt.AlignRight + CustomText { color: root.textColor + font.pointSize: 12 text: textMetrics.text - - Behavior on color { - CAnim { - } - } } } } diff --git a/plans/ideas.md b/plans/ideas.md index d4e827c..085bc59 100644 --- a/plans/ideas.md +++ b/plans/ideas.md @@ -1,21 +1,23 @@ # Ideas/Features -- [x] Media showing; what song/media is playing? -- [x] Brightness control for Laptops. -- [x] Battery icon for Laptops. Broken? - [ ] Change volume for `$BROWSER` environment variable? Most general media source apart from separate music/video players. -- [ ] Quick toggle for BT, WiFi (modules in the tray do this too) -- [x] Auto hide unless on mouse hover. Also implement bar changes to mute/volume to show notif or show bar for a couple seconds. -- [x] Maybe already possible; have keybinds to show certain menus. I do not want to touch my mouse to see notifications for example. Not everything in the bar needs this, but some would be good to have. -- [x] Pressing ESC or some obvious button to close nc. -- [x] Another branch for development, hold off big changes so that a working bar or if there are big config changes. -- [ ] Notification audio cue integration (with config option to disable). -- [x] Notification timeout per service. Example: If Discord pushes two notifications, the following notifications are muted for 10 minutes from Discord only. Perhaps a global mute is easier initially. # Stupid idea's from Daivin - [ ] An on screen pencil to draw on your screen :). - [ ] Audio module + cava / audio wave ;) ( Don't make it into minecraft blocks but aan actual wave) -- Probably not planned -- [ ] Update module: When there is 1 package it still looks extremely off -- [ ] Bluetooth device battery view -- Also not planned (I don't have bluetooth) +- [ ] Bluetooth device battery view -- Not planned ( Don't have a bluetooth + receiver ) + +# Completed features + +- [x] Auto hide unless on mouse hover. Also implement bar changes to mute/volume to show notif or show bar for a couple seconds. +- [x] Maybe already possible; have keybinds to show certain menus. I do not want to touch my mouse to see notifications for example. Not everything in the bar needs this, but some would be good to have. +- [x] Pressing ESC or some obvious button to close nc. +- [x] Another branch for development, hold off big changes so that a working bar or if there are big config changes. +- [x] Media showing; what song/media is playing? +- [x] Brightness control for Laptops. +- [x] Battery icon for Laptops. Broken? +- [x] Quick toggle for BT, WiFi (modules in the tray do this too) +- [x] Update module: When there is 1 package it still looks extremely off -- 2.47.3