diff --git a/quickshell/Modules/SurfaceWidgets/BarPill.qml b/quickshell/Modules/SurfaceWidgets/BarPill.qml index 8c64cc148..a78d33d80 100644 --- a/quickshell/Modules/SurfaceWidgets/BarPill.qml +++ b/quickshell/Modules/SurfaceWidgets/BarPill.qml @@ -37,6 +37,7 @@ Item { property real crossEdgeExtension: 0 property string segmentRole: "solo" property real splitOffset: 0 + property int pressedSegment: 0 readonly property color defaultContentColor: Theme.widgetTextColor property color contentColor: defaultContentColor readonly property real dpr: parentScreen ? CompositorService.getScreenScale(parentScreen) : 1 @@ -113,22 +114,34 @@ Item { signal rightClicked(real rootX, real rootY) signal wheel(var wheelEvent) - function cornerRadius(joined) { + function cornerRadius(joined, progress = pressProgress) { if (noBackground) return 0; - return BarMetrics.cornerRadius(widgetThickness, BarMetrics.widgetStyle(barConfig), joined, pressProgress); + return BarMetrics.cornerRadius(widgetThickness, BarMetrics.widgetStyle(barConfig), joined, progress); + } + + function segmentIndexAt(sourceItem, x, y) { + if (!visualContent.split) + return 0; + const pos = sourceItem.mapToItem(visualContent, x, y); + return (isVerticalOrientation ? pos.y : pos.x) >= splitOffset ? 1 : 0; } function triggerRipple(sourceItem, mouseX, mouseY) { if (sourceItem !== root && "pressed" in sourceItem) pressSource = sourceItem; - const pos = sourceItem.mapToItem(visualContent, mouseX, mouseY); - rippleLayer.trigger(pos.x, pos.y); + pressedSegment = segmentIndexAt(sourceItem, mouseX, mouseY); + const segment = segmentRepeater.itemAt(pressedSegment); + if (!segment) + return; + const pos = sourceItem.mapToItem(segment, mouseX, mouseY); + segment.ripple.trigger(pos.x, pos.y); } function handlePress(mouse, source) { if (source !== root && "pressed" in source) pressSource = source; + pressedSegment = segmentIndexAt(source, mouse.x, mouse.y); if (mouse.button === Qt.RightButton) { const rPos = source.mapToItem(root, mouse.x, mouse.y); root.rightClicked(rPos.x, rPos.y); @@ -220,11 +233,13 @@ Item { property bool hovered: false Repeater { + id: segmentRepeater model: visualContent.split ? 2 : 1 Item { id: segment required property int index + readonly property alias ripple: ripple readonly property bool leading: index === 0 readonly property bool joinedStart: visualContent.split && !leading readonly property bool joinedEnd: visualContent.split && leading @@ -235,10 +250,9 @@ Item { return full; return leading ? root.splitOffset - visualContent.splitGap / 2 : full - root.splitOffset - visualContent.splitGap / 2; } - readonly property real startRadiusA: joinedStart ? root.cornerRadius(true) : root.topLeftRadius - readonly property real startRadiusB: joinedStart ? root.cornerRadius(true) : (root.isVerticalOrientation ? root.topRightRadius : root.bottomLeftRadius) - readonly property real endRadiusA: joinedEnd ? root.cornerRadius(true) : (root.isVerticalOrientation ? root.bottomLeftRadius : root.topRightRadius) - readonly property real endRadiusB: joinedEnd ? root.cornerRadius(true) : root.bottomRightRadius + readonly property real pressProgress: !visualContent.split || index === root.pressedSegment ? root.pressProgress : 0 + readonly property real startRadius: root.cornerRadius(joinedStart || root.startJoined, pressProgress) + readonly property real endRadius: root.cornerRadius(joinedEnd || root.endJoined, pressProgress) x: root.isVerticalOrientation ? 0 : along y: root.isVerticalOrientation ? along : 0 @@ -263,10 +277,10 @@ Item { Rectangle { anchors.fill: parent anchors.margins: -root.outlineThickness - topLeftRadius: segment.startRadiusA + root.outlineThickness - topRightRadius: (root.isVerticalOrientation ? segment.startRadiusB : segment.endRadiusA) + root.outlineThickness - bottomLeftRadius: (root.isVerticalOrientation ? segment.endRadiusA : segment.startRadiusB) + root.outlineThickness - bottomRightRadius: segment.endRadiusB + root.outlineThickness + topLeftRadius: fill.topLeftRadius + root.outlineThickness + topRightRadius: fill.topRightRadius + root.outlineThickness + bottomLeftRadius: fill.bottomLeftRadius + root.outlineThickness + bottomRightRadius: fill.bottomRightRadius + root.outlineThickness color: "transparent" border.width: root.outlineThickness border.color: root.outlineColor @@ -276,10 +290,10 @@ Item { Rectangle { id: fill anchors.fill: parent - topLeftRadius: segment.startRadiusA - topRightRadius: root.isVerticalOrientation ? segment.startRadiusB : segment.endRadiusA - bottomLeftRadius: root.isVerticalOrientation ? segment.endRadiusA : segment.startRadiusB - bottomRightRadius: segment.endRadiusB + topLeftRadius: segment.startRadius + topRightRadius: root.isVerticalOrientation ? segment.startRadius : segment.endRadius + bottomLeftRadius: root.isVerticalOrientation ? segment.endRadius : segment.startRadius + bottomRightRadius: segment.endRadius color: root.fillColor } @@ -297,16 +311,16 @@ Item { onContainsMouseChanged: visualContent.hovered = containsMouse onPressed: mouse => root.handlePress(mouse, stateLayer) } - } - } - DRipple { - id: rippleLayer - rippleColor: Theme.surfaceText - topLeftRadius: root.topLeftRadius - topRightRadius: root.topRightRadius - bottomLeftRadius: root.bottomLeftRadius - bottomRightRadius: root.bottomRightRadius + DRipple { + id: ripple + rippleColor: Theme.surfaceText + topLeftRadius: fill.topLeftRadius + topRightRadius: fill.topRightRadius + bottomLeftRadius: fill.bottomLeftRadius + bottomRightRadius: fill.bottomRightRadius + } + } } FocusRing {