diff --git a/Modules/Bar/Bar.qml b/Modules/Bar/Bar.qml index 521b84f..6b78479 100644 --- a/Modules/Bar/Bar.qml +++ b/Modules/Bar/Bar.qml @@ -65,7 +65,10 @@ Variants { delegate: NWidgetLoader { widgetName: modelData widgetProps: { - "screen": root.modelData || null + "screen": root.modelData || null, + "barSection": parent.objectName, + "sectionWidgetIndex": index, + "sectionWidgetsCount": Settings.data.bar.widgets.left.length } anchors.verticalCenter: parent.verticalCenter } @@ -87,7 +90,10 @@ Variants { delegate: NWidgetLoader { widgetName: modelData widgetProps: { - "screen": root.modelData || null + "screen": root.modelData || null, + "barSection": parent.objectName, + "sectionWidgetIndex": index, + "sectionWidgetsCount": Settings.data.bar.widgets.center.length } anchors.verticalCenter: parent.verticalCenter } @@ -110,7 +116,10 @@ Variants { delegate: NWidgetLoader { widgetName: modelData widgetProps: { - "screen": root.modelData || null + "screen": root.modelData || null, + "barSection": parent.objectName, + "sectionWidgetIndex": index, + "sectionWidgetsCount": Settings.data.bar.widgets.right.length } anchors.verticalCenter: parent.verticalCenter } diff --git a/Modules/Bar/Widgets/Battery.qml b/Modules/Bar/Widgets/Battery.qml index f149b9b..fccfe0e 100644 --- a/Modules/Bar/Widgets/Battery.qml +++ b/Modules/Bar/Widgets/Battery.qml @@ -8,14 +8,20 @@ import qs.Widgets Item { id: root + property ShellScreen screen property real scaling: ScalingService.scale(screen) - implicitWidth: pill.width - implicitHeight: pill.height + property string barSection: "" + property int sectionWidgetIndex: 0 + property int sectionWidgetsCount: 0 // Track if we've already notified to avoid spam property bool hasNotifiedLowBattery: false + implicitWidth: pill.width + implicitHeight: pill.height + + // Helper to evaluate and possibly notify function maybeNotify(percent, charging) { const p = Math.round(percent) @@ -57,8 +63,9 @@ Item { NPill { id: pill + // Test mode - property bool testMode: false + property bool testMode: true property int testPercent: 20 property bool testCharging: false property var battery: UPower.displayDevice @@ -91,8 +98,9 @@ Item { return "battery_android_0" } + rightOpen: BarWidgetRegistry.getNPillDirection(root) icon: batteryIcon() - text: (isReady && battery.isLaptopBattery) ? Math.round(percent) + "%" : "-" + text: ((isReady && battery.isLaptopBattery) || testMode) ? Math.round(percent) + "%" : "-" textColor: charging ? Color.mPrimary : Color.mOnSurface iconCircleColor: Color.mPrimary collapsedIconColor: Color.mOnSurface diff --git a/Modules/Bar/Widgets/Brightness.qml b/Modules/Bar/Widgets/Brightness.qml index bc09dca..3fd8c88 100644 --- a/Modules/Bar/Widgets/Brightness.qml +++ b/Modules/Bar/Widgets/Brightness.qml @@ -10,6 +10,9 @@ Item { property ShellScreen screen property real scaling: ScalingService.scale(screen) + property string barSection: "" + property int sectionWidgetIndex: 0 + property int sectionWidgetsCount: 0 // Used to avoid opening the pill on Quickshell startup property bool firstBrightnessReceived: false @@ -58,6 +61,8 @@ Item { NPill { id: pill + + rightOpen: BarWidgetRegistry.getNPillDirection(root) icon: getIcon() iconCircleColor: Color.mPrimary collapsedIconColor: Color.mOnSurface diff --git a/Modules/Bar/Widgets/KeyboardLayout.qml b/Modules/Bar/Widgets/KeyboardLayout.qml index d655055..b452c72 100644 --- a/Modules/Bar/Widgets/KeyboardLayout.qml +++ b/Modules/Bar/Widgets/KeyboardLayout.qml @@ -11,6 +11,9 @@ Row { property ShellScreen screen property real scaling: ScalingService.scale(screen) + property string barSection: "" + property int sectionWidgetIndex: 0 + property int sectionWidgetsCount: 0 // Use the shared service for keyboard layout property string currentLayout: KeyboardLayoutService.currentLayout @@ -20,6 +23,8 @@ Row { NPill { id: pill + + rightOpen: BarWidgetRegistry.getNPillDirection(root) icon: "keyboard_alt" iconCircleColor: Color.mPrimary collapsedIconColor: Color.mOnSurface diff --git a/Modules/Bar/Widgets/Volume.qml b/Modules/Bar/Widgets/Volume.qml index 8819cc9..7a0f0c5 100644 --- a/Modules/Bar/Widgets/Volume.qml +++ b/Modules/Bar/Widgets/Volume.qml @@ -12,6 +12,9 @@ Item { property ShellScreen screen property real scaling: ScalingService.scale(screen) + property string barSection: "" + property int sectionWidgetIndex: 0 + property int sectionWidgetsCount: 0 // Used to avoid opening the pill on Quickshell startup property bool firstVolumeReceived: false @@ -53,6 +56,8 @@ Item { NPill { id: pill + + rightOpen: BarWidgetRegistry.getNPillDirection(root) icon: getIcon() iconCircleColor: Color.mPrimary collapsedIconColor: Color.mOnSurface diff --git a/Services/BarWidgetRegistry.qml b/Services/BarWidgetRegistry.qml index 4ea47bd..32b66d2 100644 --- a/Services/BarWidgetRegistry.qml +++ b/Services/BarWidgetRegistry.qml @@ -2,6 +2,7 @@ pragma Singleton import QtQuick import Quickshell +import qs.Commons import qs.Modules.Bar.Widgets Singleton { @@ -104,4 +105,24 @@ Singleton { function getAvailableWidgets() { return Object.keys(widgets) } + + function getNPillDirection(widget) { + try { + if (widget.barSection === "leftSection") { + return true + } else if (widget.barSection === "rightSection") { + return false + } else { + // middle section + if (widget.sectionWidgetIndex < widget.sectionWidgetsCount / 2) { + return false + } else { + return true + } + } + } catch (e) { + Logger.error(e) + } + return false + } } diff --git a/Widgets/NPill.qml b/Widgets/NPill.qml index addb6d7..1be58c4 100644 --- a/Widgets/NPill.qml +++ b/Widgets/NPill.qml @@ -18,6 +18,7 @@ Item { property bool autoHide: false property bool forceOpen: false property bool disableOpen: false + property bool rightOpen: false // Effective shown state (true if hovered/animated open or forced) readonly property bool effectiveShown: forceOpen || showPill @@ -48,11 +49,17 @@ Item { id: pill width: effectiveShown ? maxPillWidth : 1 height: pillHeight - x: (iconCircle.x + iconCircle.width / 2) - width + + x: rightOpen ? (iconCircle.x + iconCircle.width / 2) : // Opens right + (iconCircle.x + iconCircle.width / 2) - width // Opens left + opacity: effectiveShown ? Style.opacityFull : Style.opacityNone color: pillColor - topLeftRadius: pillHeight * 0.5 - bottomLeftRadius: pillHeight * 0.5 + + topLeftRadius: rightOpen ? 0 : pillHeight * 0.5 + bottomLeftRadius: rightOpen ? 0 : pillHeight * 0.5 + topRightRadius: rightOpen ? pillHeight * 0.5 : 0 + bottomRightRadius: rightOpen ? pillHeight * 0.5 : 0 anchors.verticalCenter: parent.verticalCenter NText { @@ -89,7 +96,9 @@ Item { // When forced shown, match pill background; otherwise use accent when hovered color: forceOpen ? pillColor : (showPill ? iconCircleColor : Color.mSurfaceVariant) anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right + + anchors.left: rightOpen ? parent.left : undefined + anchors.right: rightOpen ? undefined : parent.right Behavior on color { ColorAnimation {