2 Commits
Author SHA1 Message Date
AramJonghu 5a01c4b472 chore: added missing dependency to pyproject
C++ / fmt (pull_request) Successful in 3s
JS/TS / fmt (pull_request) Successful in 8s
JS/TS / lint (pull_request) Successful in 22s
Python / verify (pull_request) Failing after 19s
Python / static (pull_request) Failing after 22s
C++ / build (pull_request) Canceled after 9m5s
C++ / clang-tidy (pull_request) Canceled after 9m3s
Rust / build (pull_request) Canceled after 8m57s
Rust / fmt (pull_request) Canceled after 8m41s
Rust / clippy (pull_request) Canceled after 8m39s
2026-08-15 22:01:22 +02:00
AramJonghu 9271fa47bc ci(python): rework of jobs + fix import issue 2026-08-15 22:01:22 +02:00
229 changed files with 2977 additions and 5429 deletions
+2 -2
View File
@@ -9,7 +9,7 @@ on:
jobs:
static:
runs-on: debian
container: node:26-trixie-slim
container: python:3.13-slim
steps:
- name: Checkout
@@ -36,7 +36,7 @@ jobs:
verify:
if: always()
runs-on: debian
container: node:26-trixie-slim
container: python:3.13-slim
steps:
- name: Checkout
+9 -9
View File
@@ -27,25 +27,25 @@ AnchorAnimation {
if (type == AnchorAnim.DefaultSpatial)
return Tokens.anim.durations.expressiveDefaultSpatial;
if (type == AnchorAnim.SlowSpatial)
return Tokens.anim.durations.expressiveSlowSpatial;
return Tokens.anim.durations.large;
const types = ["small", "normal", "large", "extraLarge"];
const idx = type % 4; // 0-7 are the 4 standard types
const idx = type % 4;
return Tokens.anim.durations[types[idx]];
}
easing: {
easing.bezierCurve: {
if (type == AnchorAnim.FastSpatial)
return Tokens.anim.expressiveFastSpatial;
return Tokens.anim.curves.expressiveFastSpatial;
if (type == AnchorAnim.DefaultSpatial)
return Tokens.anim.expressiveDefaultSpatial;
return Tokens.anim.curves.expressiveDefaultSpatial;
if (type == AnchorAnim.SlowSpatial)
return Tokens.anim.expressiveSlowSpatial;
return Tokens.anim.curves.expressiveSlowSpatial;
if (type >= AnchorAnim.StandardSmall && type <= AnchorAnim.StandardExtraLarge)
return Tokens.anim.standard;
return Tokens.anim.curves.standard;
if (type >= AnchorAnim.EmphasizedSmall && type <= AnchorAnim.EmphasizedExtraLarge)
return Tokens.anim.emphasized;
return Tokens.anim.curves.emphasized;
return Tokens.anim.expressiveDefaultSpatial;
return Tokens.anim.curves.expressiveDefaultSpatial;
}
}
+12 -12
View File
@@ -30,34 +30,34 @@ NumberAnimation {
if (type === Anim.DefaultSpatial)
return Tokens.anim.durations.expressiveDefaultSpatial;
if (type === Anim.SlowSpatial)
return Tokens.anim.durations.expressiveSlowSpatial;
return Tokens.anim.durations.large;
if (type === Anim.FastEffects)
return Tokens.anim.durations.expressiveFastEffects;
if (type === Anim.DefaultEffects)
return Tokens.anim.durations.expressiveDefaultEffects;
return Tokens.anim.durations.expressiveEffects;
if (type === Anim.SlowEffects)
return Tokens.anim.durations.expressiveSlowEffects;
const types = ["small", "normal", "large", "extraLarge"];
const idx = type % 4; // 0-7 are the 4 standard types
const idx = type % 4;
return Tokens.anim.durations[types[idx]];
}
easing: {
easing.bezierCurve: {
if (type === Anim.FastSpatial)
return Tokens.anim.expressiveFastSpatial;
return Tokens.anim.curves.expressiveFastSpatial;
if (type === Anim.DefaultSpatial)
return Tokens.anim.expressiveDefaultSpatial;
return Tokens.anim.curves.expressiveDefaultSpatial;
if (type === Anim.SlowSpatial)
return Tokens.anim.expressiveSlowSpatial;
return Tokens.anim.curves.expressiveSlowSpatial;
if (type === Anim.FastEffects)
return Tokens.anim.expressiveFastEffects;
return Tokens.anim.curves.expressiveFastEffects;
if (type === Anim.DefaultEffects)
return Tokens.anim.expressiveDefaultEffects;
return Tokens.anim.curves.expressiveDefaultEffects;
if (type === Anim.SlowEffects)
return Tokens.anim.expressiveSlowEffects;
return Tokens.anim.curves.expressiveSlowEffects;
if (type >= Anim.EmphasizedSmall && type <= Anim.EmphasizedExtraLarge)
return Tokens.anim.emphasized;
return Tokens.anim.standard;
return Tokens.anim.curves.emphasized;
return Tokens.anim.curves.standard;
}
}
+2 -2
View File
@@ -107,7 +107,7 @@ Slider {
Anim {
duration: Tokens.anim.durations.normal / 2
easing: Tokens.anim.standardAccel
easing.bezierCurve: Tokens.anim.curves.standardAccel
property: "scale"
target: icon
to: 0
@@ -119,7 +119,7 @@ Slider {
Anim {
duration: Tokens.anim.durations.normal / 2
easing: Tokens.anim.standardDecel
easing.bezierCurve: Tokens.anim.curves.standardDecel
property: "scale"
target: icon
to: 1
+1 -2
View File
@@ -1,6 +1,5 @@
import QtQuick
import ZShell.Config
import qs.Components
import qs.Services
CustomRect {
@@ -37,7 +36,7 @@ CustomRect {
readonly property color onColor: !enabled ? disabledOnColor : internalChecked ? activeOnColor : inactiveOnColor
property real padding
readonly property alias pressed: stateLayer.pressed
property real pressedRadius: Tokens.rounding.small
property real pressedRadius: Tokens.rounding.smallest
readonly property alias radiusAnim: radiusAnim
property bool radiusMorph: true
property alias shapeMorph: stateLayer.shapeMorph
+58 -2
View File
@@ -2,6 +2,62 @@ import QtQuick
import ZShell.Config
ColorAnimation {
duration: Tokens.anim.durations.expressiveSlowEffects
easing: Tokens.anim.expressiveSlowEffects
enum Type {
StandardSmall = 0,
Standard,
StandardLarge,
StandardExtraLarge,
EmphasizedSmall,
Emphasized,
EmphasizedLarge,
EmphasizedExtraLarge,
FastSpatial,
DefaultSpatial,
SlowSpatial,
FastEffects,
DefaultEffects,
SlowEffects
}
property int type: CAnim.DefaultSpatial
duration: {
if (type < CAnim.StandardSmall || type > Anim.SlowEffects)
return Tokens.anim.durations.normal;
if (type === CAnim.FastSpatial)
return Tokens.anim.durations.expressiveFastSpatial;
if (type === CAnim.DefaultSpatial)
return Tokens.anim.durations.expressiveDefaultSpatial;
if (type === CAnim.SlowSpatial)
return Tokens.anim.durations.large;
if (type === CAnim.FastEffects)
return Tokens.anim.durations.expressiveFastEffects;
if (type === CAnim.DefaultEffects)
return Tokens.anim.durations.expressiveEffects;
if (type === CAnim.SlowEffects)
return Tokens.anim.durations.expressiveSlowEffects;
const types = ["small", "normal", "large", "extraLarge"];
const idx = type % 4;
return Tokens.anim.durations[types[idx]];
}
easing.bezierCurve: {
if (type === CAnim.FastSpatial)
return Tokens.anim.curves.expressiveFastSpatial;
if (type === CAnim.DefaultSpatial)
return Tokens.anim.curves.expressiveDefaultSpatial;
if (type === CAnim.SlowSpatial)
return Tokens.anim.curves.expressiveSlowSpatial;
if (type === CAnim.FastEffects)
return Tokens.anim.curves.expressiveFastEffects;
if (type === CAnim.DefaultEffects)
return Tokens.anim.curves.expressiveDefaultEffects;
if (type === CAnim.SlowEffects)
return Tokens.anim.curves.expressiveSlowEffects;
if (type >= CAnim.EmphasizedSmall && type <= Anim.EmphasizedExtraLarge)
return Tokens.anim.curves.emphasized;
return Tokens.anim.curves.standard;
}
}
+1 -1
View File
@@ -23,7 +23,7 @@ BusyIndicator {
property real implicitSize: Tokens.font.size.normal * 3
property real internalStrokeWidth: strokeWidth
readonly property alias progress: manager.progress
property real strokeWidth: Tokens.padding.extraSmall * 0.8
property real strokeWidth: Tokens.padding.small * 0.8
property alias type: manager.indeterminateAnimationType
implicitHeight: implicitSize
+1 -1
View File
@@ -21,7 +21,7 @@ Item {
readonly property real size: Math.min(width, height)
property int spacing: Tokens.spacing.small
property int startAngle: -90
property int strokeWidth: Tokens.padding.extraSmall
property int strokeWidth: Tokens.padding.small
property int sweepAngle: 360
readonly property real thickness: strokeWidth * (1 + waveAmplitude) * 2
property real value
+1 -1
View File
@@ -23,7 +23,7 @@ CheckBox {
color: Colors.palette.m3surfaceVariant
implicitHeight: control.checkHeight
implicitWidth: control.checkWidth
radius: Tokens.rounding.small / 2
radius: Tokens.rounding.smallest / 2
CustomRect {
color: Colors.palette.m3primary
+1 -4
View File
@@ -13,13 +13,11 @@ Slider {
property bool animateWave
property color bgColor: enabled ? Colors.palette.m3secondaryContainer : Qt.alpha(Colors.palette.m3onSurface, 0.1)
readonly property bool dragging: mouse.pressed
property color fgColor: enabled ? Colors.palette.m3primary : Qt.alpha(Colors.palette.m3onSurface, 0.38)
property real filledWidth
property alias inset: inset
property color insetColor: enabled ? (inset.attached ? Colors.palette.m3onSecondaryContainer : Colors.palette.m3onPrimary) : Colors.palette.m3onSurface
property string insetIcon: ""
property bool interactionOnMove: true
property real pos: visualPosition
property int radius: Tokens.rounding.small
property int waveDuration: 1000
@@ -188,8 +186,7 @@ Slider {
onPositionChanged: e => {
dragMovement = (e.x - pressStartX) / width;
if (root.interactionOnMove)
root.interaction(posBinding.value);
root.interaction(posBinding.value);
}
onPressed: e => {
widthBehavior.enabled = false;
+2 -2
View File
@@ -38,9 +38,9 @@ DoubleSpinBox {
horizontalAlignment: TextField.AlignHCenter
implicitWidth: 65
inputMethodHints: Qt.ImhFormattedNumbersOnly
leftPadding: Tokens.padding.small
leftPadding: Tokens.padding.larger
readOnly: !root.editable
rightPadding: Tokens.padding.small
rightPadding: Tokens.padding.larger
text: root.textFromValue(root.value, root.locale)
validator: root.validator
@@ -12,14 +12,14 @@ Row {
}
property alias active: menu.active
property color color: type == SplitButton.Filled ? Colors.palette.m3primary : Colors.palette.m3secondaryContainer
property color color: type == CustomSplitButton.Filled ? Colors.palette.m3primary : Colors.palette.m3secondaryContainer
property color disabledColor: Qt.alpha(Colors.palette.m3onSurface, 0.1)
property color disabledTextColor: Qt.alpha(Colors.palette.m3onSurface, 0.38)
readonly property alias expandBtn: expandBtn
property alias expanded: menu.expanded
property string fallbackIcon
property string fallbackText
property real horizontalPadding: Tokens.padding.medium
property real horizontalPadding: Tokens.padding.larger
readonly property alias iconLabel: iconLabel
readonly property alias label: label
readonly property alias menu: menu
@@ -27,20 +27,20 @@ Row {
property bool menuOnTop
property real minLeftWidth
readonly property alias stateLayer: stateLayer
property color textColor: type == SplitButton.Filled ? Colors.palette.m3onPrimary : Colors.palette.m3onSecondaryContainer
property color textColor: type == CustomSplitButton.Filled ? Colors.palette.m3onPrimary : Colors.palette.m3onSecondaryContainer
readonly property alias textRow: textRow
property int type: SplitButton.Filled
property int type: CustomSplitButton.Filled
property real verticalPadding: Tokens.padding.small
spacing: Math.floor(Tokens.spacing.extraSmall / 2)
spacing: Math.floor(Tokens.spacing.extraSmall)
CustomRect {
bottomRightRadius: Tokens.rounding.medium / 2
bottomRightRadius: Tokens.rounding.small / 2
color: !root.enabled ? root.disabledColor : root.color
implicitHeight: expandBtn.implicitHeight
implicitWidth: Math.max(root.minLeftWidth, textRow.implicitWidth + root.horizontalPadding * 2)
radius: implicitHeight / 2 * Math.min(1, Tokens.rounding.scale)
topRightRadius: Tokens.rounding.medium / 2
topRightRadius: Tokens.rounding.small / 2
StateLayer {
id: stateLayer
@@ -92,7 +92,7 @@ Row {
CustomRect {
id: expandBtn
property real rad: root.expanded ? implicitHeight / 2 * Math.min(1, Tokens.rounding.scale) : Tokens.rounding.medium / 2
property real rad: root.expanded ? implicitHeight / 2 * Math.min(1, Tokens.rounding.scale) : Tokens.rounding.small / 2
bottomLeftRadius: rad
color: !root.enabled ? root.disabledColor : root.color
+70
View File
@@ -0,0 +1,70 @@
pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Layouts
import ZShell.Config
import qs.Services
Item {
id: root
property alias active: splitButton.active
property alias buttonAlias: splitButton
property alias expanded: splitButton.expanded
property int expandedZ: 100
required property string label
property alias menuItems: splitButton.menuItems
property bool shouldBeActive: true
property alias type: splitButton.type
signal selected(item: MenuItem)
anchors.left: parent.left
anchors.right: parent.right
clip: false
implicitHeight: row.implicitHeight + Tokens.padding.smaller * 2
opacity: shouldBeActive ? 1 : 0
scale: shouldBeActive ? 1 : 0.8
z: splitButton.menu.implicitHeight > 0 ? expandedZ : 1
Behavior on opacity {
Anim {
}
}
Behavior on scale {
Anim {
}
}
RowLayout {
id: row
anchors.left: parent.left
anchors.margins: Tokens.padding.small
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
spacing: Tokens.spacing.normal
CustomText {
Layout.fillWidth: true
color: root.enabled ? Colors.palette.m3onSurface : Colors.palette.m3onSurfaceVariant
font.pointSize: Tokens.font.size.larger
text: root.label
}
CustomSplitButton {
id: splitButton
enabled: root.enabled
type: CustomSplitButton.Filled
z: 2
menu.onItemSelected: item => {
root.selected(item);
}
stateLayer.onClicked: {
splitButton.expanded = !splitButton.expanded;
}
}
}
}
+8 -20
View File
@@ -13,12 +13,8 @@ Switch {
implicitWidth: implicitIndicatorWidth
indicator: CustomRect {
color: {
if (!root.enabled)
return root.checked ? Qt.alpha(Colors.palette.m3onSurface, 0.12) : Qt.alpha(Colors.palette.m3surfaceContainerHighest, 0.38);
return root.checked ? Colors.palette.m3primary : Colors.layer(Colors.palette.m3surfaceContainerHighest, root.cLayer);
}
implicitHeight: 14 + Tokens.padding.small * 2
color: root.checked && root.enabled ? Colors.palette.m3primary : Colors.layer(Colors.palette.m3surfaceContainerHighest, root.cLayer)
implicitHeight: Tokens.font.size.medium + Tokens.padding.normal * 2
implicitWidth: implicitHeight * 1.7
radius: Tokens.rounding.full
@@ -26,11 +22,7 @@ Switch {
readonly property real nonAnimWidth: root.pressed ? implicitHeight * 1.2 : implicitHeight
anchors.verticalCenter: parent.verticalCenter
color: {
if (!root.enabled)
return root.checked ? Qt.alpha(Colors.palette.m3surface, 0.7) : Qt.alpha(Colors.palette.m3onSurface, 0.12);
return root.checked ? Colors.palette.m3onPrimary : Colors.layer(Colors.palette.m3outline, root.cLayer + 1);
}
color: root.checked && root.enabled ? Colors.palette.m3onPrimary : Colors.layer(Colors.palette.m3outline, root.cLayer + 1)
implicitHeight: parent.implicitHeight - Tokens.padding.extraSmall
implicitWidth: nonAnimWidth
radius: Tokens.rounding.full
@@ -100,7 +92,7 @@ Switch {
anchors.centerIn: parent
asynchronous: true
height: parent.implicitHeight - Tokens.padding.medium
height: parent.implicitHeight - Tokens.padding.larger
preferredRendererType: Shape.CurveRenderer
width: height
@@ -122,16 +114,12 @@ Switch {
}
ShapePath {
capStyle: Tokens.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap
capStyle: ShapePath.RoundCap
fillColor: "transparent"
startX: icon.start1.x
startY: icon.start1.y
strokeColor: {
if (!root.enabled)
return root.checked ? Colors.palette.m3outline : Colors.palette.m3surfaceContainer;
return root.checked ? Colors.palette.m3primary : Colors.palette.m3surfaceContainerHighest;
}
strokeWidth: 16 * 0.15
strokeColor: root.checked && root.enabled ? Colors.palette.m3primary : Colors.palette.m3surfaceContainerHighest
strokeWidth: Tokens.font.size.larger * 0.15
Behavior on strokeColor {
CAnim {
@@ -165,6 +153,6 @@ Switch {
component PropAnim: PropertyAnimation {
duration: Tokens.anim.durations.expressiveFastSpatial
easing: Tokens.anim.expressiveFastSpatial
easing.bezierCurve: Tokens.anim.curves.expressiveFastSpatial
}
}
+4 -4
View File
@@ -129,8 +129,8 @@ TextFieldBase {
}
AnchorAnim {
duration: Tokens.anim.durations.expressiveDefaultEffects
easing: Tokens.anim.expressiveDefaultEffects
duration: Tokens.anim.durations.expressiveEffects
easing.bezierCurve: Tokens.anim.curves.expressiveEffects
}
}
}
@@ -140,7 +140,7 @@ TextFieldBase {
active: root.leadingIcon
anchors.left: parent.left
anchors.leftMargin: Tokens.padding.small
anchors.leftMargin: Tokens.padding.normal
anchors.verticalCenter: parent.verticalCenter
sourceComponent: MaterialIcon {
@@ -154,7 +154,7 @@ TextFieldBase {
active: root.trailingIcon
anchors.right: parent.right
anchors.rightMargin: Tokens.padding.small
anchors.rightMargin: Tokens.padding.normal
anchors.verticalCenter: parent.verticalCenter
sourceComponent: MaterialIcon {
+1 -1
View File
@@ -27,7 +27,7 @@ ButtonBase {
return Colors.palette.m3onPrimary;
return type === IconButton.Tonal ? Colors.palette.m3onSecondaryContainer : Colors.palette.m3onSurfaceVariant;
}
padding: type === IconButton.Text ? Tokens.padding.extraSmall / 2 : Tokens.padding.extraSmall
padding: type === IconButton.Text ? Tokens.padding.extraSmall / 2 : Tokens.padding.small
MaterialIcon {
id: label
+2 -2
View File
@@ -17,7 +17,7 @@ ButtonBase {
return Colors.palette.m3primary;
return type === TextButton.Filled ? Colors.palette.m3onPrimary : Colors.palette.m3onSecondary;
}
horizontalPadding: Tokens.padding.small
horizontalPadding: Tokens.padding.larger
implicitHeight: row.implicitHeight + verticalPadding * 2
implicitWidth: row.implicitWidth + horizontalPadding * 2
inactiveColor: {
@@ -32,7 +32,7 @@ ButtonBase {
return Colors.palette.m3primary;
return type === TextButton.Filled ? Colors.palette.m3onSurface : Colors.palette.m3onSecondaryContainer;
}
verticalPadding: Tokens.padding.extraSmall
verticalPadding: Tokens.padding.small
RowLayout {
id: row
+130 -148
View File
@@ -18,14 +18,13 @@ Item {
property real leftFadeStrength: overflowing && leftFadeEnabled ? fadeStrengthMoving : fadeStrengthIdle
property int leftFadeWidth: 28
property bool marqueeEnabled: true
readonly property bool overflowing: metrics.width > content.width
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
property bool vertical: false
function durationForDistance(px): int {
return Math.max(1, Math.round(Math.abs(px) / root.pixelsPerSecond * 1000));
@@ -42,9 +41,8 @@ Item {
}
}
clip: false
implicitHeight: vertical ? elideText.implicitWidth : elideText.implicitHeight
implicitWidth: vertical ? elideText.implicitHeight : elideText.implicitWidth
clip: true
implicitHeight: elideText.implicitHeight
Behavior on leftFadeStrength {
Anim {
@@ -55,187 +53,171 @@ Item {
}
}
onHeightChanged: resetMarquee()
onTextChanged: resetMarquee()
onVerticalChanged: resetMarquee()
onVisibleChanged: if (!visible)
resetMarquee()
onWidthChanged: resetMarquee()
TextMetrics {
id: metrics
font: elideText.font
text: elideText.text
}
CustomText {
id: elideText
anchors.verticalCenter: parent.verticalCenter
animate: root.animate
animateProp: "scale,opacity"
color: root.color
elide: Text.ElideNone
visible: !root.overflowing
width: root.width
}
Item {
id: content
id: marqueeViewport
anchors.centerIn: parent
height: root.vertical ? root.width : root.height
width: root.vertical ? root.height : root.width
anchors.fill: parent
clip: true
layer.enabled: true
visible: root.overflowing
transform: Rotation {
angle: root.vertical ? -90 : 0
origin.x: content.width / 2
origin.y: content.height / 2
}
TextMetrics {
id: metrics
font: elideText.font
text: elideText.text
}
CustomText {
id: elideText
anchors.verticalCenter: parent.verticalCenter
animate: root.animate
animateProp: "scale,opacity"
color: root.color
elide: Text.ElideNone
visible: !root.overflowing
width: content.width
layer.effect: OpacityMask {
maskSource: rightFadeMask
}
Item {
id: marqueeViewport
id: strip
anchors.fill: parent
clip: false
layer.enabled: true
visible: root.overflowing
anchors.verticalCenter: parent.verticalCenter
height: t1.implicitHeight
width: t1.width + root.gap + t2.width
x: 0
layer.effect: OpacityMask {
maskSource: rightFadeMask
CustomText {
id: t1
animate: root.animate
animateProp: "opacity"
color: root.color
font.pointSize: elideText.font.pointSize
text: elideText.text
}
Item {
id: strip
CustomText {
id: t2
anchors.verticalCenter: parent.verticalCenter
height: t1.implicitHeight
width: t1.width + root.gap + t2.width
x: 0
animate: root.animate
animateProp: "opacity"
color: root.color
font.pointSize: elideText.font.pointSize
text: t1.text
x: t1.width + root.gap
}
}
CustomText {
id: t1
SequentialAnimation {
id: marqueeAnim
animate: root.animate
animateProp: "opacity"
color: root.color
font.pointSize: elideText.font.pointSize
text: elideText.text
}
running: false
CustomText {
id: t2
onFinished: pauseTimer.restart()
animate: root.animate
animateProp: "opacity"
color: root.color
font.pointSize: elideText.font.pointSize
text: t1.text
x: t1.width + root.gap
ScriptAction {
script: {
root.sliding = true;
root.leftFadeEnabled = true;
}
}
SequentialAnimation {
id: marqueeAnim
Anim {
duration: root.durationForDistance(t1.width)
easing.bezierCurve: Easing.Linear
easing.type: Easing.Linear
from: 0
property: "x"
target: strip
to: -t1.width
}
running: false
onFinished: pauseTimer.restart()
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;
}
ScriptAction {
script: {
root.leftFadeEnabled = false;
}
}
Timer {
id: pauseTimer
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)
}
interval: root.pauseMs
repeat: false
running: true
onTriggered: {
if (root.marqueeEnabled)
marqueeAnim.start();
ScriptAction {
script: {
root.sliding = false;
strip.x = 0;
}
}
}
Rectangle {
id: rightFadeMask
Timer {
id: pauseTimer
readonly property real fadeStartPos: {
const w = Math.max(1, width);
return Math.max(0, Math.min(1, (w - root.rightFadeWidth) / w));
interval: root.pauseMs
repeat: false
running: true
onTriggered: {
if (root.marqueeEnabled)
marqueeAnim.start();
}
readonly property real leftFadeEndPos: {
const w = Math.max(1, width);
return Math.max(0, Math.min(1, root.leftFadeWidth / w));
}
}
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
}
anchors.fill: marqueeViewport
layer.enabled: true
visible: false
GradientStop {
color: Qt.rgba(1, 1, 1, 1.0)
position: rightFadeMask.leftFadeEndPos
}
gradient: Gradient {
orientation: Gradient.Horizontal
GradientStop {
color: Qt.rgba(1, 1, 1, 1.0)
position: rightFadeMask.fadeStartPos
}
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
}
GradientStop {
color: Qt.rgba(1, 1, 1, 1.0 - root.rightFadeStrength)
position: 1.0
}
}
}
+9 -9
View File
@@ -78,7 +78,7 @@ MouseArea {
implicitHeight: column.implicitHeight + column.anchors.margins * 2
implicitWidth: Math.max(200, column.implicitWidth + column.anchors.margins * 2)
level: 2
radius: Tokens.rounding.large
radius: Tokens.rounding.medium
x: {
watcher.transform;
const item = root.attachTo;
@@ -126,15 +126,15 @@ MouseArea {
CustomRect {
id: item
readonly property bool active: modelData === root?.active
readonly property bool active: modelData === root.active
required property int index
required property MenuItem modelData
Layout.fillWidth: true
color: Qt.alpha(Colors.palette.m3tertiaryContainer, active ? 1 : 0)
implicitHeight: menuOptionRow.implicitHeight + Tokens.padding.medium * 2
implicitWidth: menuOptionRow.implicitWidth + Tokens.padding.medium * 2
radius: menu.radius - column.anchors.margins
implicitHeight: menuOptionRow.implicitHeight + Tokens.padding.larger * 2
implicitWidth: menuOptionRow.implicitWidth + Tokens.padding.larger * 2
radius: Tokens.rounding.small
Behavior on radius {
Anim {
@@ -157,25 +157,25 @@ MouseArea {
id: menuOptionRow
anchors.fill: parent
anchors.margins: Tokens.padding.medium
anchors.margins: Tokens.padding.larger
spacing: Tokens.spacing.small
MaterialIcon {
Layout.alignment: Qt.AlignVCenter
color: item.active ? Colors.palette.m3onTertiaryContainer : Colors.palette.m3onSurfaceVariant
text: item.modelData?.icon ?? ""
text: item.modelData.icon
}
CustomText {
Layout.alignment: Qt.AlignVCenter
Layout.fillWidth: true
color: item.active ? Colors.palette.m3onTertiaryContainer : Colors.palette.m3onSurface
text: item.modelData?.text ?? ""
text: item.modelData.text
}
Loader {
Layout.alignment: Qt.AlignVCenter
active: item.modelData?.trailingIcon.length > 0
active: item.modelData.trailingIcon.length > 0
asynchronous: true
visible: active
+1 -1
View File
@@ -70,7 +70,7 @@ TextFieldBase {
id: clearIcon
anchors.right: parent.right
anchors.rightMargin: Tokens.padding.small
anchors.rightMargin: Tokens.padding.larger
anchors.verticalCenter: parent.verticalCenter
enabled: root.text
icon: "clear"
+3 -2
View File
@@ -1,8 +1,9 @@
import QtQuick
import QtQuick.Shapes
import ZShell
import ZShell.Config
import ZShell.Components
import qs.Helpers
import ZShell.Config
import qs.Services
MouseArea {
@@ -80,7 +81,7 @@ MouseArea {
alwaysRunToEnd: true
duration: Tokens.anim.durations.expressiveSlowEffects * 2
easing: Tokens.anim.standard
easing.bezierCurve: Tokens.anim.curves.standard
property: "circleRadius"
target: root
to: root.endRadius
+2 -2
View File
@@ -14,7 +14,7 @@ ButtonBase {
return Colors.palette.m3primary;
return type === TextButton.Filled ? Colors.palette.m3onPrimary : Colors.palette.m3onSecondary;
}
horizontalPadding: Tokens.padding.small
horizontalPadding: Tokens.padding.normal
implicitHeight: label.implicitHeight + verticalPadding * 2
implicitWidth: label.implicitWidth + horizontalPadding * 2
inactiveColor: {
@@ -29,7 +29,7 @@ ButtonBase {
return Colors.palette.m3primary;
return type === TextButton.Filled ? Colors.palette.m3onSurface : Colors.palette.m3onSecondaryContainer;
}
verticalPadding: Tokens.padding.extraSmall
verticalPadding: Tokens.padding.small
CustomText {
id: label
+1 -1
View File
@@ -36,7 +36,7 @@ TextField {
color: Colors.palette.m3primary
implicitHeight: root.cursorRectangle.height
implicitWidth: 1.5
radius: Tokens.rounding.largeIncreased
radius: Tokens.rounding.large
x: root.cursorRectangle.x
y: root.cursorRectangle.y
+8 -8
View File
@@ -32,8 +32,8 @@ CustomRect {
return Colors.palette.m3errorContainer;
return Colors.palette.m3surface;
}
implicitHeight: layout.implicitHeight + Tokens.padding.small * 2
radius: Tokens.rounding.medium
implicitHeight: layout.implicitHeight + Tokens.padding.smaller * 2
radius: Tokens.rounding.normal
Behavior on border.color {
CAnim {
@@ -52,10 +52,10 @@ CustomRect {
id: layout
anchors.fill: parent
anchors.leftMargin: Tokens.padding.small
anchors.margins: Tokens.padding.small
anchors.rightMargin: Tokens.padding.small
spacing: Tokens.spacing.medium
anchors.leftMargin: Tokens.padding.normal
anchors.margins: Tokens.padding.smaller
anchors.rightMargin: Tokens.padding.normal
spacing: Tokens.spacing.normal
CustomRect {
color: {
@@ -67,9 +67,9 @@ CustomRect {
return Colors.palette.m3error;
return Colors.palette.m3surfaceContainerHigh;
}
implicitHeight: icon.implicitHeight + Tokens.padding.small * 2
implicitHeight: icon.implicitHeight + Tokens.padding.smaller * 2
implicitWidth: implicitHeight
radius: Tokens.rounding.medium
radius: Tokens.rounding.normal
MaterialIcon {
id: icon
+3 -3
View File
@@ -21,7 +21,7 @@ Item {
}
return h;
}
implicitWidth: Config.utilities.sizes.toastWidth - Tokens.padding.small * 2
implicitWidth: Config.utilities.sizes.toastWidth - Tokens.padding.normal * 2
Repeater {
id: repeater
@@ -82,7 +82,7 @@ Item {
Behavior on anchors.bottomMargin {
Anim {
duration: Tokens.anim.durations.expressiveDefaultSpatial
easing: Tokens.anim.expressiveDefaultSpatial
easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial
}
}
Behavior on opacity {
@@ -105,7 +105,7 @@ Item {
id: initAnim
duration: Tokens.anim.durations.expressiveDefaultSpatial
easing: Tokens.anim.expressiveDefaultSpatial
easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial
from: 0
properties: "opacity,scale"
target: toast
+2 -33
View File
@@ -11,46 +11,15 @@ Variants {
required property ShellScreen modelData
function rebuild(): void {
loader.active = false;
loader.active = true;
}
LazyLoader {
id: loader
active: true
Drawer {
screen: scope.modelData
}
}
Connections {
function onConfigPositionChanged(): void {
Qt.callLater(scope.rebuild);
}
target: (loader.item as Drawer)?.geometry ?? null
}
}
component Drawer: Scope {
id: drawer
readonly property alias geometry: content.geometry
required property ShellScreen screen
Exclusions {
bar: content.bar
geometry: content.geometry
screen: drawer.screen
screen: scope.modelData
}
Windows {
id: content
screen: drawer.screen
screen: scope.modelData
}
}
}
-55
View File
@@ -1,55 +0,0 @@
import QtQuick
import qs.Modules.Bar as Bar
QtObject {
id: root
required property Bar.BarLoader bar
readonly property real barClamped: bar.clampedExtent
readonly property real barExtent: bar.extent
readonly property bool barOnBottom: position === "bottom"
readonly property bool barOnLeft: position === "left"
readonly property bool barOnTop: position === "top"
required property string configPosition
readonly property bool horizontal: position !== "left"
readonly property string position: configPosition === "top" || configPosition === "bottom" ? configPosition : "left"
required property var win
function axisPos(x: real, y: real): real {
return horizontal ? x : y;
}
function barContains(x: real, y: real, clamped = false): bool {
const extent = clamped ? barClamped : barExtent;
if (barOnTop)
return y < extent;
if (barOnBottom)
return y > win.height - extent;
return x < extent;
}
function insetBottom(border: real, clamped = false): real {
return barOnBottom ? (clamped ? barClamped : barExtent) : border;
}
function insetLeft(border: real, clamped = false): real {
return barOnLeft ? (clamped ? barClamped : barExtent) : border;
}
function insetTop(border: real, clamped = false): real {
return barOnTop ? (clamped ? barClamped : barExtent) : border;
}
function inwardDrag(dragX: real, dragY: real): real {
if (barOnTop)
return dragY;
if (barOnBottom)
return -dragY;
return dragX;
}
onConfigPositionChanged: {
if (!["left", "top", "bottom"].includes(configPosition))
console.warn(`Invalid bar position '${configPosition}', falling back to left`);
}
}
+2 -11
View File
@@ -1,7 +1,6 @@
pragma ComponentBehavior: Bound
import Quickshell
import Quickshell.Wayland
import QtQuick
import ZShell.Config
import qs.Components
@@ -10,24 +9,19 @@ Scope {
id: root
required property Item bar
required property EdgeGeometry geometry
required property ShellScreen screen
ExclusionZone {
id: top
WlrLayershell.layer: WlrLayer.Overlay
anchors.left: true
anchors.right: true
anchors.top: true
hasBar: root.geometry.barOnTop
exclusiveZone: root.bar.exclusiveZone
}
ExclusionZone {
id: left
anchors.left: true
hasBar: root.geometry.barOnLeft
}
ExclusionZone {
@@ -40,7 +34,6 @@ Scope {
id: bottom
anchors.bottom: true
hasBar: root.geometry.barOnBottom
}
Timer {
@@ -51,9 +44,7 @@ Scope {
}
component ExclusionZone: CustomWindow {
property bool hasBar
exclusiveZone: hasBar ? root.bar.exclusiveZone : Config.bar.border
exclusiveZone: Config.bar.border
implicitHeight: 1
implicitWidth: 1
name: "Bar-Exclusion"
+23 -41
View File
@@ -3,7 +3,7 @@ import QtQuick
import qs.Components
import ZShell.Config
import qs.Helpers
import qs.Modules.Bar.Popouts
import qs.Modules as BarPopouts
Item {
id: root
@@ -12,47 +12,43 @@ Item {
required property real borderThickness
property bool dashboardShortcutActive
required property Drawing drawing
required property EdgeGeometry geometry
property bool osdShortcutActive
required property Panels panels
required property Wrapper popouts
required property BarPopouts.Wrapper popouts
required property ShellScreen screen
property bool singleGestureTriggered: false
property bool utilitiesShortcutActive
required property PersistentProperties visibilities
function inBottomPanel(panel: Item, x: real, y: real): bool {
const panelHeight = panel.height * (1 - (panel.offsetScale ?? 0));
return y > root.height - (panelHeight + geometry.insetBottom(borderThickness)) && withinPanelWidth(panel, x, y);
return y > root.height - panel.height - Config.bar.border && withinPanelWidth(panel, x, y);
}
function inLeftPanel(panel: Item, x: real, y: real): bool {
return x < panel.x + panel.width + geometry.insetLeft(borderThickness) && withinPanelHeight(panel, x, y);
}
function inPopoutArea(x: real, y: real): bool {
const panel = panels.popoutsWrapper;
if (!geometry.horizontal)
return inLeftPanel(panel, x, y);
return withinPanelWidth(panel, x, y) && withinPanelHeight(panel, x, y);
return x < panel.x + panel.width + Config.bar.border && withinPanelHeight(panel, x, y);
}
function inRightPanel(panel: Item, x: real, y: real): bool {
return x > panel.x + geometry.insetLeft(borderThickness) && withinPanelHeight(panel, x, y);
return x > panel.x - Config.bar.border && withinPanelHeight(panel, x, y);
}
function inTopPanel(panel: Item, x: real, y: real): bool {
const panelHeight = panel.height * (1 - (panel.offsetScale ?? 0));
return y < geometry.insetTop(borderThickness) + panelHeight && withinPanelWidth(panel, x, y);
return y < bar.implicitHeight + panel.height && withinPanelWidth(panel, x, y);
}
function onWheel(event: WheelEvent): void {
if (event.x < bar.implicitWidth) {
bar.handleWheel(event.y, event.angleDelta);
}
}
function withinPanelHeight(panel: Item, x: real, y: real): bool {
const panelY = panel.y + geometry.insetTop(borderThickness);
const panelY = panel.y + bar.implicitHeight;
return y >= panelY && y <= panelY + panel.height;
}
function withinPanelWidth(panel: Item, x: real, y: real): bool {
const panelX = panel.x + geometry.insetLeft(borderThickness);
const panelX = panel.x + root.borderThickness;
return x >= panelX && x <= panelX + panel.width;
}
@@ -85,7 +81,7 @@ Item {
if (root.singleGestureTriggered)
return;
if (root.geometry.insetTop(root.borderThickness) > centroid.pressPosition.y) {
if (centroid.pressPosition.y < root.bar.implicitHeight) {
if (dragY > 20) {
root.visibilities.settings = true;
root.singleGestureTriggered = true;
@@ -95,10 +91,10 @@ Item {
}
}
if (centroid.pressPosition.y > root.screen.height - root.geometry.insetBottom(root.borderThickness) && centroid.pressPosition.x < root.screen.width / 5 && dragY < -50)
if (centroid.pressPosition.y > root.screen.height - Config.bar.border && centroid.pressPosition.x < root.screen.width / 5 && dragY < -50)
root.visibilities.clipboard = true;
if (!Config.dock.hoverToReveal && centroid.pressPosition.y > root.screen.height - root.geometry.insetTop(root.borderThickness) && centroid.pressPosition.x > root.screen.width / 5 && !root.visibilities.launcher)
if (!Config.dock.hoverToReveal && centroid.pressPosition.y > root.screen.height - root.bar.implicitHeight && centroid.pressPosition.x > root.screen.width / 5 && !root.visibilities.launcher)
if (dragY < -10) {
root.visibilities.dock = true;
root.singleGestureTriggered = true;
@@ -162,19 +158,6 @@ Item {
}
}
Timer {
id: unhideTimer
interval: Config.bar.revealDelay
repeat: false
running: false
onTriggered: {
if (hoverHandler.hovered)
root.bar.isHovered = true;
}
}
HoverHandler {
id: hoverHandler
@@ -191,7 +174,7 @@ Item {
root.popouts.hasCurrent = false;
}
if (Config.bar.autoHide || root.bar.fullscreen)
if (Config.bar.autoHide)
root.bar.isHovered = false;
}
}
@@ -210,12 +193,9 @@ Item {
return;
}
if (!root.visibilities.bar && Config.bar.autoHide && root.geometry.barContains(x, y, true))
if (!root.visibilities.bar && Config.bar.autoHide && y < root.bar.implicitHeight)
root.bar.isHovered = true;
if (root.bar.fullscreen && !root.bar.isHovered)
unhideTimer.start();
if (root.panels.sidebar.offsetScale === 1) {
const showOsd = root.inRightPanel(root.panels.osdWrapper, x, y);
@@ -239,8 +219,8 @@ Item {
if (Config.dock.enable && Config.dock.hoverToReveal && !root.visibilities.dock && !root.visibilities.launcher && root.inBottomPanel(root.panels.dock, x, y))
root.visibilities.dock = true;
if (root.geometry.barContains(x, y))
root.bar.checkPopout(root.geometry.axisPos(x, y));
if (y < root.bar.implicitHeight)
root.bar.checkPopout(x);
}
}
@@ -318,6 +298,8 @@ Item {
root.visibilities.sidebar = false;
root.panels.popouts.hasCurrent = false;
root.visibilities.launcher = false;
} else {
Config.save();
}
}
+18 -21
View File
@@ -1,7 +1,7 @@
import Quickshell
import QtQuick
import qs.Components
import qs.Modules.Bar.Popouts as Popouts
import qs.Modules as Modules
import qs.Modules.Notifications as Notifications
import qs.Modules.Notifications.Sidebar as Sidebar
import qs.Modules.Notifications.Sidebar.Utils as Utils
@@ -27,7 +27,6 @@ Item {
readonly property alias dock: dock
readonly property alias drawing: drawing
required property var drawingItem
required property EdgeGeometry geometry
readonly property alias launcher: launcher
readonly property alias notifications: notifications
readonly property alias osd: osd
@@ -44,26 +43,24 @@ Item {
readonly property alias utilities: utilities
required property PersistentProperties visibilities
anchors.bottomMargin: geometry.insetBottom(borderThickness)
anchors.fill: parent
anchors.leftMargin: geometry.insetLeft(borderThickness)
anchors.margins: borderThickness
anchors.topMargin: geometry.insetTop(borderThickness)
anchors.topMargin: bar.implicitHeight
Item {
id: resourcesWrapper
anchors.bottom: root.geometry.position === "bottom" ? parent.bottom : undefined
anchors.left: parent.left
anchors.top: root.geometry.position !== "bottom" ? parent.top : undefined
anchors.top: parent.top
clip: true
implicitHeight: root.geometry.horizontal ? resources.implicitHeight * (1 - resources.offsetScale) : resources.implicitHeight
implicitWidth: root.geometry.horizontal ? resources.implicitWidth : resources.implicitWidth * (1 - resources.offsetScale)
implicitHeight: resources.implicitHeight * (1 - resources.offsetScale)
implicitWidth: resources.implicitWidth
Resources.Wrapper {
id: resources
position: root.geometry.position
anchors.left: parent.left
anchors.top: parent.top
visibilities: root.visibilities
}
}
@@ -99,11 +96,11 @@ Item {
visibilities: root.visibilities
}
Popouts.ClipWrapper {
Modules.ClipWrapper {
id: popouts
anchors.top: parent.top
borderThickness: root.borderThickness
position: root.geometry.position
screen: root.screen
}
@@ -111,7 +108,7 @@ Item {
id: toasts
anchors.bottom: sidebar.visible ? parent.bottom : utilities.top
anchors.margins: Tokens.padding.small
anchors.margins: Tokens.padding.normal
anchors.right: sidebar.left
}
@@ -150,26 +147,26 @@ Item {
property real offsetScale: dashboard.shouldBeActive ? 0 : 1
anchors.bottom: root.geometry.barOnLeft || root.geometry.barOnBottom ? parent.bottom : undefined
anchors.left: root.geometry.barOnLeft ? parent.left : undefined
anchors.right: root.geometry.barOnLeft ? undefined : parent.right
anchors.top: root.geometry.barOnBottom || root.geometry.barOnLeft ? undefined : parent.top
anchors.right: parent.right
anchors.top: parent.top
clip: true
implicitHeight: root.geometry.horizontal ? dashboard.implicitHeight * (1 - offsetScale) : dashboard.implicitHeight
implicitWidth: root.geometry.horizontal ? dashboard.implicitWidth : dashboard.implicitWidth * (1 - offsetScale)
implicitHeight: dashboard.implicitHeight * (1 - offsetScale)
implicitWidth: dashboard.implicitWidth
Behavior on offsetScale {
Anim {
duration: Tokens.anim.durations.expressiveDefaultSpatial
easing: Tokens.anim.expressiveDefaultSpatial
easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial
}
}
Dashboard.Wrapper {
id: dashboard
anchors.right: parent.right
anchors.top: parent.top
anchors.topMargin: (-implicitHeight - 5) * offsetScale
offsetScale: dashboardWrapper.offsetScale
position: root.geometry.position
visibilities: root.visibilities
}
}
+8 -13
View File
@@ -7,18 +7,17 @@ import qs.Modules.Bar as Bar
Region {
id: root
// required property Bar.BarLoader bar
required property Bar.BarLoader bar
readonly property real borderThickness: win.borderThickness
required property EdgeGeometry geometry
readonly property alias menuPopoutRegion: menuPopoutRegion
required property Panels panels
required property var win
height: win.height - geometry.insetTop(borderThickness, true) - geometry.insetBottom(borderThickness, true) - win.dragMaskPadding * 2
height: win.height - bar.implicitHeight - win.borderThickness - win.dragMaskPadding * 2
intersection: Intersection.Xor
width: win.width - geometry.insetLeft(borderThickness, true) * 2 - win.dragMaskPadding * 2
x: geometry.insetLeft(borderThickness, true) + win.dragMaskPadding
y: geometry.insetTop(borderThickness, true) + win.dragMaskPadding
width: win.width - win.borderThickness * 2 - win.dragMaskPadding * 2
x: win.borderThickness + win.dragMaskPadding
y: bar.implicitHeight + win.dragMaskPadding
R {
panel: root.panels.dashboardWrapper
@@ -42,21 +41,17 @@ Region {
}
R {
height: panel.height + root.geometry.insetTop(root.borderThickness)
panel: root.panels.notifications
y: 0
}
R {
height: panel.height * (1 - root.panels.utilities.offsetScale) + root.geometry.insetBottom(root.borderThickness)
height: panel.height * (1 - root.panels.utilities.offsetScale) + root.borderThickness
panel: root.panels.utilities
y: root.win.height - height
}
R {
height: root.geometry.horizontal ? panel.height * (1 - root.panels.popoutsWrapper.offsetScale) : panel.height
panel: root.panels.popoutsWrapper
width: root.geometry.horizontal ? panel.width : panel.width * (1 - root.panels.popoutsWrapper.offsetScale)
}
R {
@@ -87,7 +82,7 @@ Region {
height: panel.height
intersection: Intersection.Subtract
width: panel.width
x: panel.x + root.geometry.insetLeft(root.borderThickness)
y: panel.y + root.geometry.insetTop(root.borderThickness)
x: panel.x + root.borderThickness
y: panel.y + root.bar.implicitHeight
}
}
+36 -56
View File
@@ -33,7 +33,6 @@ CustomWindow {
return 100;
}
property real fsTransitionProg: hasFullscreen ? 1 : 0
readonly property alias geometry: geometry
readonly property bool hasFullscreen: {
if (hasSpecialWorkspace) {
const specialName = monitor?.lastIpcObject.specialWorkspace?.name;
@@ -51,7 +50,7 @@ CustomWindow {
readonly property HyprlandMonitor monitor: Hypr.monitorFor(screen)
property var root: Quickshell.shellDir
readonly property real sdfBorderOffset: 2 * fsTransitionProg
readonly property real shadowOpacity: 0.7 * (1 - (bar.isHovered ? 0 : fsTransitionProg))
readonly property real shadowOpacity: 0.7 * (1 - fsTransitionProg)
property color surfaceColor: Colors.tPalette.m3surface
WlrLayershell.exclusionMode: ExclusionMode.Ignore
@@ -59,7 +58,7 @@ CustomWindow {
WlrLayershell.layer: (fsTransitionProg > 0 && Config.general.showOverFullscreen) || (hasSpecialWorkspace && hasFullscreenOnNormalWs) ? WlrLayer.Overlay : WlrLayer.Top
color: "transparent"
contentItem.focus: true
mask: visibilities.isDrawing ? null : (hasFullscreen && !bar.isHovered ? emptyRegion : regions)
mask: visibilities.isDrawing ? null : (hasFullscreen ? emptyRegion : regions)
name: "Bar"
Behavior on fsTransitionProg {
@@ -96,21 +95,13 @@ CustomWindow {
panels.popouts.hasCurrent = false;
}
EdgeGeometry {
id: geometry
bar: bar
configPosition: Config.bar.position
win: root
}
Region {
id: emptyRegion
height: panels.notifications.height
width: panels.notifications.width
x: panels.notifications.x + geometry.insetLeft(root.borderThickness)
y: panels.notifications.y + geometry.insetTop(root.borderThickness)
x: panels.notifications.x + root.borderThickness
y: panels.notifications.y + bar.implicitHeight
Region {
height: panels.osd.height
@@ -118,18 +109,12 @@ CustomWindow {
x: root.width - width
y: panels.osdWrapper.y + bar.implicitHeight
}
Region {
height: geometry.horizontal ? 1 : root.screen.height
width: geometry.horizontal ? root.screen.width : 1
y: geometry.position === "bottom" ? root.screen.height - 1 : 0
}
}
Regions {
id: regions
geometry: geometry
bar: bar
panels: panels
win: root
}
@@ -208,10 +193,10 @@ CustomWindow {
BlobInvertedRect {
anchors.fill: parent
anchors.margins: -50
borderBottom: geometry.insetBottom(root.borderThickness) - anchors.margins - root.sdfBorderOffset
borderLeft: geometry.insetLeft(root.borderThickness) - anchors.margins - root.sdfBorderOffset
borderBottom: root.borderThickness - anchors.margins - root.sdfBorderOffset
borderLeft: root.borderThickness - anchors.margins - root.sdfBorderOffset
borderRight: root.borderThickness - anchors.margins - root.sdfBorderOffset
borderTop: geometry.insetTop(root.borderThickness) - anchors.margins - root.sdfBorderOffset
borderTop: bar.implicitHeight - anchors.margins - root.sdfBorderOffset
group: blobGroup
radius: root.borderRounding
}
@@ -219,15 +204,15 @@ CustomWindow {
PanelBg {
id: dashBg
property real extraExtent: 0.2
property real extraHeight: 0.2
deformAmount: 0.06
implicitHeight: panels.dashboard.height * (geometry.horizontal ? 1 + extraExtent : 1)
implicitWidth: panels.dashboard.width * (geometry.horizontal ? 1 : 1 + extraExtent)
implicitHeight: panels.dashboard.height * (1 + extraHeight)
implicitWidth: panels.dashboard.width
panel: panels.dashboardWrapper
radius: Tokens.rounding.extraLarge
x: panels.dashboardWrapper.x + panels.dashboard.x + geometry.insetLeft(root.borderThickness) - (geometry.horizontal ? 0 : panels.dashboard.width * extraExtent)
y: panels.dashboardWrapper.y + panels.dashboard.y + geometry.insetTop(root.borderThickness) - (geometry.horizontal && geometry.position !== "bottom" ? panels.dashboard.height * extraExtent : 0)
radius: Tokens.rounding.normal
x: panels.dashboardWrapper.x + panels.dashboard.x + root.borderThickness
y: panels.dashboardWrapper.y + panels.dashboard.y + bar.implicitHeight - panels.dashboard.height * extraHeight
}
PanelBg {
@@ -238,8 +223,8 @@ CustomWindow {
deformAmount: 0.06
implicitHeight: panels.launcher.height * (1 + extraHeight)
panel: panels.launcher
radius: Tokens.rounding.medium + (Tokens.padding.largeIncreased / 4)
y: panels.launcher.y + geometry.insetTop(root.borderThickness)
radius: Tokens.rounding.smallest + 5
y: panels.launcher.y + bar.implicitHeight
}
PanelBg {
@@ -260,14 +245,15 @@ CustomWindow {
implicitWidth: panels.osd.width
panel: panels.osdWrapper
radius: 20
x: panels.osdWrapper.x + panels.osd.x + geometry.insetLeft(root.borderThickness)
x: panels.osdWrapper.x + panels.osd.x + root.borderThickness
y: panels.osdWrapper.y + panels.osd.y + bar.implicitHeight
}
PanelBg {
id: notifsBg
panel: panels.notifications
radius: Tokens.rounding.large
radius: Tokens.rounding.normal
}
PanelBg {
@@ -282,17 +268,17 @@ CustomWindow {
PanelBg {
id: popoutBg
property real extraExtent: 0.2
property real extraHeight: 0.2
deformAmount: panels.popouts.currentName.startsWith("traymenu") ? 0.15 : 0.08
implicitHeight: panels.popouts.height * (geometry.horizontal ? 1 + extraExtent : 1)
implicitWidth: panels.popouts.width * (geometry.horizontal ? 1 : 1 + extraExtent)
implicitHeight: panels.popouts.height * (1 + extraHeight)
implicitWidth: panels.popouts.width
panel: panels.popoutsWrapper
radius: panels.popouts.current?.panelRadius ?? Tokens.rounding.large
x: panels.popoutsWrapper.x + panels.popouts.x + geometry.insetLeft(root.borderThickness) - (geometry.horizontal ? 0 : panels.popouts.width * extraExtent)
y: panels.popoutsWrapper.y + panels.popouts.y + geometry.insetTop(root.borderThickness) - (geometry.barOnTop ? panels.popouts.height * extraExtent : 0)
radius: panels.popouts.current?.panelRadius ?? Tokens.rounding.normal
x: panels.popoutsWrapper.x + panels.popouts.x + root.borderThickness
y: panels.popoutsWrapper.y + panels.popouts.y + bar.implicitHeight - panels.popouts.height * extraHeight
Behavior on extraExtent {
Behavior on extraHeight {
Anim {
}
}
@@ -305,9 +291,9 @@ CustomWindow {
implicitHeight: panels.resources.height
implicitWidth: panels.resources.width
panel: panels.resourcesWrapper
radius: Tokens.rounding.largeIncreased + Tokens.padding.small
x: panels.resourcesWrapper.x + panels.resources.x + geometry.insetLeft(root.borderThickness)
y: panels.resourcesWrapper.y + panels.resources.y + geometry.insetTop(root.borderThickness)
radius: Tokens.rounding.large
x: panels.resourcesWrapper.x + panels.resources.x + root.borderThickness
y: panels.resourcesWrapper.y + panels.resources.y + bar.implicitHeight
}
PanelBg {
@@ -315,7 +301,7 @@ CustomWindow {
deformAmount: 0.03
panel: panels.settings
radius: Tokens.rounding.largeIncreased + Tokens.padding.small
radius: Tokens.rounding.large + Tokens.padding.normal
}
PanelBg {
@@ -323,7 +309,7 @@ CustomWindow {
deformAmount: 0.08
panel: panels.dock
radius: Tokens.rounding.medium
radius: Tokens.rounding.normal
}
PanelBg {
@@ -331,7 +317,7 @@ CustomWindow {
deformAmount: 0.08
panel: panels.drawing
radius: Tokens.rounding.medium
radius: Tokens.rounding.normal
}
PanelBg {
@@ -385,7 +371,6 @@ CustomWindow {
borderThickness: root.borderLayoutThickness
drawing: drawing
enabled: true
geometry: geometry
panels: panels
popouts: panels.popouts
screen: root.screen
@@ -397,7 +382,6 @@ CustomWindow {
bar: bar
borderThickness: root.borderThickness
drawingItem: drawing
geometry: geometry
screen: root.screen
visibilities: visibilities
@@ -439,18 +423,14 @@ CustomWindow {
BarLoader {
id: bar
anchors.bottom: geometry.barOnBottom ? parent.bottom : undefined
anchors.left: parent.left
anchors.top: geometry.barOnBottom ? undefined : parent.top
anchors.right: parent.right
enabled: !visibilities.isDrawing
fullscreen: root.hasFullscreen
height: geometry.horizontal ? implicitHeight : parent.height
popouts: panels.popouts
popoutsWrapper: panels.popoutsWrapper
position: geometry.position
screen: root.screen
visibilities: visibilities
width: geometry.horizontal ? parent.width : implicitWidth
}
}
@@ -462,8 +442,8 @@ CustomWindow {
group: blobGroup
implicitHeight: panel.height
implicitWidth: panel.width
radius: Tokens.rounding.small
x: panel.x + geometry.insetLeft(root.borderThickness)
y: panel.y + geometry.insetTop(root.borderThickness)
radius: Tokens.rounding.smallest
x: panel.x + root.borderThickness
y: panel.y + bar.implicitHeight
}
}
+33
View File
@@ -0,0 +1,33 @@
import QtQuick
import QtQuick.Effects
Item {
id: root
property real radius
Rectangle {
id: shadowRect
anchors.fill: root
color: "black"
layer.enabled: true
radius: root.radius
visible: false
}
MultiEffect {
id: effects
anchors.fill: shadowRect
autoPaddingEnabled: true
maskEnabled: true
maskInverted: true
maskSource: shadowRect
shadowBlur: 2.0
shadowColor: "black"
shadowEnabled: true
shadowOpacity: 1
source: shadowRect
}
}
+8 -8
View File
@@ -18,7 +18,7 @@ ColumnLayout {
Layout.fillHeight: true
Layout.fillWidth: false
Layout.preferredWidth: centerWidth
spacing: Tokens.spacing.largeIncreased * 2
spacing: Tokens.spacing.large * 2
RowLayout {
Layout.alignment: Qt.AlignHCenter
@@ -64,7 +64,7 @@ ColumnLayout {
CustomClippingRect {
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: Tokens.spacing.largeIncreased * 2
Layout.topMargin: Tokens.spacing.large * 2
color: Colors.tPalette.m3surfaceContainer
implicitHeight: root.centerWidth / 2
implicitWidth: root.centerWidth / 2
@@ -99,7 +99,7 @@ ColumnLayout {
Layout.alignment: Qt.AlignHCenter
color: Colors.tPalette.m3surfaceContainer
focus: true
implicitHeight: input.implicitHeight + Tokens.padding.extraSmall * 2
implicitHeight: input.implicitHeight + Tokens.padding.small * 2
implicitWidth: root.centerWidth * 0.8
radius: Tokens.rounding.full
@@ -130,11 +130,11 @@ ColumnLayout {
id: input
anchors.fill: parent
anchors.margins: Tokens.padding.extraSmall
spacing: Tokens.spacing.medium
anchors.margins: Tokens.padding.small
spacing: Tokens.spacing.normal
Item {
implicitHeight: statusIcon.implicitHeight + Tokens.padding.extraSmall * 2
implicitHeight: statusIcon.implicitHeight + Tokens.padding.small * 2
implicitWidth: implicitHeight
MaterialIcon {
@@ -174,7 +174,7 @@ ColumnLayout {
CustomRect {
color: root.greeter.buffer && !root.greeter.launching ? Colors.palette.m3primary : Colors.layer(Colors.palette.m3surfaceContainerHigh, 2)
implicitHeight: enterIcon.implicitHeight + Tokens.padding.extraSmall * 2
implicitHeight: enterIcon.implicitHeight + Tokens.padding.small * 2
implicitWidth: implicitHeight
radius: Tokens.rounding.full
@@ -200,7 +200,7 @@ ColumnLayout {
Item {
Layout.fillWidth: true
Layout.topMargin: -Tokens.spacing.largeIncreased
Layout.topMargin: -Tokens.spacing.large
implicitHeight: Math.max(message.implicitHeight, stateMessage.implicitHeight)
Behavior on implicitHeight {
+11 -11
View File
@@ -30,11 +30,11 @@ NumberAnimation {
if (type === Anim.DefaultSpatial)
return Tokens.anim.durations.expressiveDefaultSpatial;
if (type === Anim.SlowSpatial)
return Tokens.anim.durations.expressiveSlowSpatial;
return Tokens.anim.durations.large;
if (type === Anim.FastEffects)
return Tokens.anim.durations.expressiveFastEffects;
if (type === Anim.DefaultEffects)
return Tokens.anim.durations.expressiveDefaultEffects;
return Tokens.anim.durations.expressiveEffects;
if (type === Anim.SlowEffects)
return Tokens.anim.durations.expressiveSlowEffects;
@@ -42,22 +42,22 @@ NumberAnimation {
const idx = type % 4; // 0-7 are the 4 standard types
return Tokens.anim.durations[types[idx]];
}
easing: {
easing.bezierCurve: {
if (type === Anim.FastSpatial)
return Tokens.anim.expressiveFastSpatial;
return Tokens.anim.curves.expressiveFastSpatial;
if (type === Anim.DefaultSpatial)
return Tokens.anim.expressiveDefaultSpatial;
return Tokens.anim.curves.expressiveDefaultSpatial;
if (type === Anim.SlowSpatial)
return Tokens.anim.expressiveSlowSpatial;
return Tokens.anim.curves.expressiveSlowSpatial;
if (type === Anim.FastEffects)
return Tokens.anim.expressiveFastEffects;
return Tokens.anim.curves.expressiveFastEffects;
if (type === Anim.DefaultEffects)
return Tokens.anim.expressiveDefaultEffects;
return Tokens.anim.curves.expressiveDefaultEffects;
if (type === Anim.SlowEffects)
return Tokens.anim.expressiveSlowEffects;
return Tokens.anim.curves.expressiveSlowEffects;
if (type >= Anim.EmphasizedSmall && type <= Anim.EmphasizedExtraLarge)
return Tokens.anim.emphasized;
return Tokens.anim.standard;
return Tokens.anim.curves.emphasized;
return Tokens.anim.curves.standard;
}
}
+58 -2
View File
@@ -2,6 +2,62 @@ import QtQuick
import ZShell.Config
ColorAnimation {
duration: Tokens.anim.durations.expressiveSlowEffects
easing: Tokens.anim.expressiveSlowEffects
enum Type {
StandardSmall = 0,
Standard,
StandardLarge,
StandardExtraLarge,
EmphasizedSmall,
Emphasized,
EmphasizedLarge,
EmphasizedExtraLarge,
FastSpatial,
DefaultSpatial,
SlowSpatial,
FastEffects,
DefaultEffects,
SlowEffects
}
property int type: CAnim.DefaultSpatial
duration: {
if (type < CAnim.StandardSmall || type > Anim.SlowEffects)
return Tokens.anim.durations.normal;
if (type === CAnim.FastSpatial)
return Tokens.anim.durations.expressiveFastSpatial;
if (type === CAnim.DefaultSpatial)
return Tokens.anim.durations.expressiveDefaultSpatial;
if (type === CAnim.SlowSpatial)
return Tokens.anim.durations.large;
if (type === CAnim.FastEffects)
return Tokens.anim.durations.expressiveFastEffects;
if (type === CAnim.DefaultEffects)
return Tokens.anim.durations.expressiveEffects;
if (type === CAnim.SlowEffects)
return Tokens.anim.durations.expressiveSlowEffects;
const types = ["small", "normal", "large", "extraLarge"];
const idx = type % 4;
return Tokens.anim.durations[types[idx]];
}
easing.bezierCurve: {
if (type === CAnim.FastSpatial)
return Tokens.anim.curves.expressiveFastSpatial;
if (type === CAnim.DefaultSpatial)
return Tokens.anim.curves.expressiveDefaultSpatial;
if (type === CAnim.SlowSpatial)
return Tokens.anim.curves.expressiveSlowSpatial;
if (type === CAnim.FastEffects)
return Tokens.anim.curves.expressiveFastEffects;
if (type === CAnim.DefaultEffects)
return Tokens.anim.curves.expressiveDefaultEffects;
if (type === CAnim.SlowEffects)
return Tokens.anim.curves.expressiveSlowEffects;
if (type >= CAnim.EmphasizedSmall && type <= Anim.EmphasizedExtraLarge)
return Tokens.anim.curves.emphasized;
return Tokens.anim.curves.standard;
}
}
+1 -1
View File
@@ -23,7 +23,7 @@ BusyIndicator {
property real implicitSize: Tokens.font.size.normal * 3
property real internalStrokeWidth: strokeWidth
readonly property alias progress: manager.progress
property real strokeWidth: Tokens.padding.extraSmall * 0.8
property real strokeWidth: Tokens.padding.small * 0.8
property alias type: manager.indeterminateAnimationType
implicitHeight: implicitSize
+1 -1
View File
@@ -21,7 +21,7 @@ Item {
readonly property real size: Math.min(width, height)
property int spacing: Tokens.spacing.small
property int startAngle: -90
property int strokeWidth: Tokens.padding.extraSmall
property int strokeWidth: Tokens.padding.small
property int sweepAngle: 360
readonly property real thickness: strokeWidth * (1 + waveAmplitude) * 2
property real value
+1 -1
View File
@@ -27,7 +27,7 @@ TextField {
color: Colors.palette.m3primary
implicitWidth: 2
radius: Tokens.rounding.medium
radius: Tokens.rounding.normal
Behavior on opacity {
Anim {
+2 -1
View File
@@ -1,4 +1,5 @@
import QtQuick
import QtQuick.Controls
import ZShell.Config
import qs.Services
@@ -10,6 +11,6 @@ TextInput {
font {
family: Config.appearance?.font.family.sans ?? "sans-serif"
hintingPreference: Font.PreferFullHinting
pixelSize: Tokens?.font.size.normal ?? 15
pixelSize: Config.appearance?.font.size.normal ?? 15
}
}
+1 -1
View File
@@ -81,7 +81,7 @@ MouseArea {
alwaysRunToEnd: true
duration: Tokens.anim.durations.expressiveSlowEffects * 2
easing: Tokens.anim.standard
easing.bezierCurve: Tokens.anim.curves.standard
property: "circleRadius"
target: root
to: root.endRadius
+7 -7
View File
@@ -11,18 +11,18 @@ RowLayout {
required property var greeter
required property real screenHeight
spacing: Tokens.spacing.largeIncreased * 2
spacing: Tokens.spacing.large * 2
ColumnLayout {
Layout.fillWidth: true
spacing: Tokens.spacing.medium
spacing: Tokens.spacing.normal
CustomRect {
Layout.fillWidth: true
color: Colors.tPalette.m3surfaceContainer
implicitHeight: weather.implicitHeight
radius: Tokens.rounding.small
topLeftRadius: Tokens.rounding.largeIncreased
topLeftRadius: Tokens.rounding.large
WeatherInfo {
id: weather
@@ -34,7 +34,7 @@ RowLayout {
CustomClippingRect {
Layout.fillHeight: true
Layout.fillWidth: true
bottomLeftRadius: Tokens.rounding.largeIncreased
bottomLeftRadius: Tokens.rounding.large
color: Colors.tPalette.m3surfaceContainer
radius: Tokens.rounding.small
@@ -51,15 +51,15 @@ RowLayout {
ColumnLayout {
Layout.fillWidth: true
spacing: Tokens.spacing.medium
spacing: Tokens.spacing.normal
CustomRect {
Layout.fillHeight: true
Layout.fillWidth: true
bottomRightRadius: Tokens.rounding.largeIncreased
bottomRightRadius: Tokens.rounding.large
color: Colors.tPalette.m3surfaceContainer
radius: Tokens.rounding.small
topRightRadius: Tokens.rounding.largeIncreased
topRightRadius: Tokens.rounding.large
SessionDock {
greeter: root.greeter
+5 -5
View File
@@ -43,7 +43,7 @@ Scope {
ParallelAnimation {
Anim {
duration: Tokens.anim.durations.expressiveFastSpatial
easing: Tokens.anim.expressiveFastSpatial
easing.bezierCurve: Tokens.anim.curves.expressiveFastSpatial
property: "scale"
target: lockContent
to: 1
@@ -65,7 +65,7 @@ Scope {
Anim {
duration: Tokens.anim.durations.expressiveDefaultSpatial
easing: Tokens.anim.expressiveDefaultSpatial
easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial
property: "scale"
target: content
to: 1
@@ -74,12 +74,12 @@ Scope {
Anim {
property: "radius"
target: lockBg
to: Tokens.rounding.largeIncreased * 1.5
to: Tokens.rounding.large * 1.5
}
Anim {
duration: Tokens.anim.durations.expressiveDefaultSpatial
easing: Tokens.anim.expressiveDefaultSpatial
easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial
property: "implicitWidth"
target: lockContent
to: (win.screen?.height ?? 0) * Config.lock.sizes.heightMult * Config.lock.sizes.ratio
@@ -87,7 +87,7 @@ Scope {
Anim {
duration: Tokens.anim.durations.expressiveDefaultSpatial
easing: Tokens.anim.expressiveDefaultSpatial
easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial
property: "implicitHeight"
target: lockContent
to: (win.screen?.height ?? 0) * Config.lock.sizes.heightMult
+1 -1
View File
@@ -113,7 +113,7 @@ Item {
Behavior on scale {
Anim {
duration: Tokens.anim.durations.expressiveFastSpatial
easing: Tokens.anim.expressiveFastSpatial
easing.bezierCurve: Tokens.anim.curves.expressiveFastSpatial
}
}
+8 -8
View File
@@ -13,7 +13,7 @@ ColumnLayout {
anchors.fill: parent
anchors.margins: Tokens.padding.large
spacing: Tokens.spacing.small
spacing: Tokens.spacing.smaller
CustomText {
Layout.fillWidth: true
@@ -41,7 +41,7 @@ ColumnLayout {
}
}
sourceComponent: ColumnLayout {
spacing: Tokens.spacing.largeIncreased
spacing: Tokens.spacing.large
MaterialIcon {
Layout.alignment: Qt.AlignHCenter
@@ -79,8 +79,8 @@ ColumnLayout {
anchors.left: parent?.left
anchors.right: parent?.right
implicitHeight: row.implicitHeight + Tokens.padding.small * 2
radius: Tokens.rounding.medium - Tokens.padding.small
implicitHeight: row.implicitHeight + Tokens.padding.normal * 2
radius: Tokens.rounding.normal - Tokens.padding.smaller
StateLayer {
onClicked: {
@@ -92,8 +92,8 @@ ColumnLayout {
id: row
anchors.fill: parent
anchors.margins: Tokens.padding.small
spacing: Tokens.spacing.medium
anchors.margins: Tokens.padding.normal
spacing: Tokens.spacing.normal
MaterialIcon {
color: session.index === sessions.currentIndex ? Colors.palette.m3onPrimary : Colors.palette.m3onSurfaceVariant
@@ -129,13 +129,13 @@ ColumnLayout {
color: Colors.palette.m3primary
implicitHeight: sessions.currentItem?.implicitHeight ?? 0
implicitWidth: sessions.width
radius: Tokens.rounding.medium - Tokens.padding.small
radius: Tokens.rounding.normal - Tokens.padding.smaller
y: sessions.currentItem?.y ?? 0
Behavior on y {
Anim {
duration: Tokens.anim.durations.small
easing: Tokens.anim.expressiveDefaultEffects
easing.bezierCurve: Tokens.anim.curves.expressiveEffects
}
}
}
+9 -9
View File
@@ -14,7 +14,7 @@ ColumnLayout {
anchors.fill: parent
anchors.margins: Tokens.padding.large
spacing: Tokens.spacing.small
spacing: Tokens.spacing.smaller
CustomText {
Layout.fillWidth: true
@@ -42,7 +42,7 @@ ColumnLayout {
}
}
sourceComponent: ColumnLayout {
spacing: Tokens.spacing.largeIncreased
spacing: Tokens.spacing.large
MaterialIcon {
Layout.alignment: Qt.AlignHCenter
@@ -81,8 +81,8 @@ ColumnLayout {
anchors.left: parent?.left
anchors.right: parent?.right
implicitHeight: row.implicitHeight + Tokens.padding.small * 2
radius: Tokens.rounding.medium - Tokens.padding.small
implicitHeight: row.implicitHeight + Tokens.padding.normal * 2
radius: Tokens.rounding.normal - Tokens.padding.smaller
StateLayer {
onClicked: {
@@ -94,8 +94,8 @@ ColumnLayout {
id: row
anchors.fill: parent
anchors.margins: Tokens.padding.small
spacing: Tokens.spacing.medium
anchors.margins: Tokens.padding.normal
spacing: Tokens.spacing.normal
CustomClippingRect {
Layout.preferredHeight: 50
@@ -135,13 +135,13 @@ ColumnLayout {
color: Colors.palette.m3primary
implicitHeight: users.currentItem?.implicitHeight ?? 0
implicitWidth: users.width
radius: Tokens.rounding.medium - Tokens.padding.small
radius: Tokens.rounding.normal - Tokens.padding.smaller
y: users.currentItem?.y ?? 0
Behavior on y {
Anim {
duration: Tokens.anim.durations.expressiveDefaultEffects
easing: Tokens.anim.expressiveDefaultEffects
duration: Tokens.anim.durations.small
easing.bezierCurve: Tokens.anim.curves.expressiveEffects
}
}
}
+4 -4
View File
@@ -34,7 +34,7 @@ ColumnLayout {
RowLayout {
Layout.fillWidth: true
spacing: Tokens.spacing.largeIncreased
spacing: Tokens.spacing.large
MaterialIcon {
animate: true
@@ -67,7 +67,7 @@ ColumnLayout {
}
Loader {
Layout.rightMargin: Tokens.padding.small
Layout.rightMargin: Tokens.padding.smaller
active: root.width > 400
visible: active
@@ -103,12 +103,12 @@ ColumnLayout {
Layout.bottomMargin: Tokens.padding.large * 2
Layout.fillWidth: true
Layout.topMargin: Tokens.spacing.small
Layout.topMargin: Tokens.spacing.smaller
active: root.rootHeight > 820
visible: active
sourceComponent: RowLayout {
spacing: Tokens.spacing.largeIncreased
spacing: Tokens.spacing.large
Repeater {
model: {
+70
View File
@@ -0,0 +1,70 @@
pragma Singleton
import QtQuick
import Quickshell
import Quickshell.Wayland
import qs.Components
import ZShell.Config
Singleton {
id: root
property list<var> apps: {
var map = new Map();
const pinnedApps = Config.dock?.pinnedApps ?? [];
for (const appId of pinnedApps) {
if (!map.has(appId.toLowerCase()))
map.set(appId.toLowerCase(), ({
pinned: true,
toplevels: []
}));
}
if (pinnedApps.length > 0) {
map.set("SEPARATOR", {
pinned: false,
toplevels: []
});
}
var values = [];
for (const [key, value] of map) {
values.push(appEntryComp.createObject(null, {
appId: key,
toplevels: value.toplevels,
pinned: value.pinned
}));
}
return values;
}
function isPinned(appId) {
return Config.dock.pinnedApps.indexOf(appId) !== -1;
}
function togglePin(appId) {
if (root.isPinned(appId)) {
Config.dock.pinnedApps = Config.dock.pinnedApps.filter(id => id !== appId);
} else {
Config.dock.pinnedApps = Config.dock.pinnedApps.concat([appId]);
}
}
Component {
id: appEntryComp
TaskbarAppEntry {
}
}
component TaskbarAppEntry: QtObject {
id: wrapper
required property string appId
required property bool pinned
required property list<var> toplevels
}
}
+63
View File
@@ -0,0 +1,63 @@
// FetchPresets.qml
pragma Singleton
import QtQuick
import Quickshell
import Quickshell.Io
Singleton {
id: root
property var parsedPresets: ({})
readonly property var presets: parsedPresets
property bool ready: false
function accents(presetName, variantName) {
const variant = parsedPresets[presetName]?.variants?.[variantName];
return variant?.accents ?? [];
}
function defaultAccent(presetName, variantName) {
const variant = parsedPresets[presetName]?.variants?.[variantName];
return variant?.default_accent ?? "";
}
function modes(presetName, variantName) {
const variant = parsedPresets[presetName]?.variants?.[variantName];
return variant?.modes ?? [];
}
function presetNames() {
return Object.keys(parsedPresets);
}
function variantNames(presetName) {
const preset = parsedPresets[presetName];
if (!preset || !preset.variants)
return [];
return Object.keys(preset.variants);
}
Process {
command: ["zshell-cli", "scheme", "list-presets", "--json"]
running: true
stdout: StdioCollector {
onStreamFinished: {
try {
const parsed = JSON.parse(text);
root.parsedPresets = parsed.presets ?? {};
root.ready = true;
} catch (e) {
console.error("Failed to parse presets JSON:", e);
}
}
}
}
}
+2 -51
View File
@@ -1,8 +1,9 @@
pragma Singleton
import QtQuick
import ZShell.Config
import Quickshell
import Quickshell.Services.Notifications
import QtQuick
Singleton {
id: root
@@ -94,15 +95,6 @@ Singleton {
return Quickshell.iconPath(icon);
}
function getBatteryIcon(percentage: real, charging = false): string {
if (percentage === 1)
return charging ? "battery_charging_full" : "battery_full";
let level = Math.floor(percentage * 7);
if (charging && (level === 4 || level === 1))
level--;
return charging ? `battery_charging_${(level + 3) * 10}` : `battery_${level}_bar`;
}
function getBluetoothIcon(icon: string): string {
if (icon.includes("headset") || icon.includes("headphones"))
return "headphones";
@@ -176,32 +168,6 @@ Singleton {
return "chat";
}
function getSpecialWsIcon(name: string): string {
name = name.toLowerCase().slice("special:".length);
if (name === "special")
return "star";
if (name === "communication")
return "forum";
if (name === "music")
return "music_cast";
if (name === "todo")
return "checklist";
if (name === "sysmon")
return "monitor_heart";
return name[0].toUpperCase();
}
function getTrayIcon(id: string, icon: string): string {
if (icon.includes("?path=")) {
const [name, path] = icon.split("?path=");
const file = name.slice(name.lastIndexOf("/") + 1);
const themed = Quickshell.iconPath(file, true);
icon = themed ? themed : Qt.resolvedUrl(`${path}/${file}`);
}
return icon;
}
function getVolumeIcon(volume: real, isMuted: bool): string {
if (isMuted)
return "no_sound";
@@ -217,19 +183,4 @@ Singleton {
return weatherIcons[code];
return "air";
}
function matchIconConfig(name: string, iconConfig: var): bool {
if (!iconConfig.icon)
return false;
if (iconConfig.regex) {
const re = new RegExp(iconConfig.regex, iconConfig.flags ?? "");
if (re.test(name))
return true;
} else if (iconConfig.name === name) {
return true;
}
return false;
}
}
+1 -1
View File
@@ -391,7 +391,7 @@ Item {
tool: root.tool
visible: root.mode === "edit"
x: Math.max(8, Math.min(root.rsx + root.sw / 2 - width / 2, root.screen.width - width - 8))
y: (root.rsy + root.sh + height + Tokens.padding.small <= root.screen.height) ? root.rsy + root.sh + Tokens.padding.small : (root.rsy - height - Tokens.padding.small <= 0) ? root.rsy + root.sh - height - Tokens.padding.small : root.rsy - height - Tokens.padding.small
y: (root.rsy + root.sh + height + Tokens.padding.normal <= root.screen.height) ? root.rsy + root.sh + Tokens.padding.normal : (root.rsy - height - Tokens.padding.normal <= 0) ? root.rsy + root.sh - height - Tokens.padding.normal : root.rsy - height - Tokens.padding.normal
onCancelRequested: root.cancel()
onClearRequested: annotations.clearAll()
+4 -10
View File
@@ -49,9 +49,9 @@ CustomRect {
signal undoRequested
color: Colors.palette.m3surface
height: row.implicitHeight + Tokens.padding.small * 2
height: row.implicitHeight + Tokens.padding.normal * 2
radius: Tokens.rounding.full
width: row.implicitWidth + Tokens.padding.small * 2
width: row.implicitWidth + Tokens.padding.normal * 2
RowLayout {
id: row
@@ -73,7 +73,6 @@ CustomRect {
required property var modelData
color: root.tool === modelData.id ? "#3584e4" : "transparent"
font.pointSize: Tokens.font.size.large
icon: tool.modelData.glyph
inactiveColor: root.tool === modelData.id ? Colors.palette.m3primary : "transparent"
inactiveOnColor: root.tool === modelData.id ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
@@ -99,11 +98,11 @@ CustomRect {
model: root.colorPalette
delegate: IconButton {
readonly property real buttonSize: toolRow.implicitHeight - Tokens.padding.small
readonly property real buttonSize: toolRow.implicitHeight - Tokens.padding.normal
required property color modelData
fillWidth: false
font.pointSize: Tokens.font.size.large
font.pointSize: 0
icon: ""
implicitHeight: buttonSize
implicitWidth: buttonSize
@@ -128,7 +127,6 @@ CustomRect {
spacing: Tokens.spacing.extraSmall
IconButton {
font.pointSize: Tokens.font.size.large
icon: "undo"
inactiveColor: "transparent"
inactiveOnColor: Colors.palette.m3onSurface
@@ -140,7 +138,6 @@ CustomRect {
}
IconButton {
font.pointSize: Tokens.font.size.large
icon: "delete_history"
inactiveColor: "transparent"
inactiveOnColor: Colors.palette.m3onSurface
@@ -152,7 +149,6 @@ CustomRect {
}
IconButton {
font.pointSize: Tokens.font.size.large
icon: "content_copy"
inactiveColor: "transparent"
inactiveOnColor: Colors.palette.m3onSurface
@@ -164,7 +160,6 @@ CustomRect {
}
IconButton {
font.pointSize: Tokens.font.size.large
icon: "delete_forever"
inactiveColor: "transparent"
inactiveOnColor: Colors.palette.m3onSurface
@@ -176,7 +171,6 @@ CustomRect {
}
IconButton {
font.pointSize: Tokens.font.size.large
icon: "check"
inactiveColor: "transparent"
inactiveOnColor: Colors.palette.m3onSurface
+1
View File
@@ -73,6 +73,7 @@ Singleton {
Config.dock.pinnedApps = pinnedApps;
root.unpinnedOrder = visibleUnpinned.concat(root.unpinnedOrder.map(normalizeId).filter(id => !pinnedApps.includes(id) && !visibleUnpinned.includes(id)));
Config.saveNoToast();
}
function isPinned(appId) {
+41 -8
View File
@@ -11,8 +11,8 @@ Singleton {
id: root
property int availableUpdates: 0
property string cmd: ""
property bool commandReady
property bool hasHelper
property bool loaded
property double now: Date.now()
property var updates: ({})
@@ -38,12 +38,18 @@ Singleton {
}
function performPackageUpdate(pkg: string): void {
pkgUpdateProc.command = ["pkexec", "pacman", "--noconfirm", "-Sy", pkg];
if (root.cmd === "pacman")
pkgUpdateProc.command = ["pkexec", root.cmd, "--noconfirm", "-Sy", pkg];
else
pkgUpdateProc.command = [root.cmd, "--noconfirm", "--sudo", "pkexec", "-Sy", pkg];
pkgUpdateProc.running = true;
}
function performSystemUpdate(): void {
sysUpdateProc.command = ["pkexec", "pacman", "--noconfirm", "-Syu"];
if (root.cmd === "pacman")
sysUpdateProc.command = ["pkexec", root.cmd, "--noconfirm", "-Syu"];
else
sysUpdateProc.command = [root.cmd, "--noconfirm", "--sudo", "pkexec", "-Syu"];
sysUpdateProc.running = true;
}
@@ -81,7 +87,7 @@ Singleton {
Process {
id: cmdDetect
command: ["sh", "-c", "command -v checkupdates"]
command: ["sh", "-c", "command -v checkupdates || command -v yay || command -v paru"]
running: true
stdout: StdioCollector {
@@ -90,20 +96,47 @@ Singleton {
let helper;
if (cmd.length > 0) {
helper = true;
helper = cmd.split("/").pop();
} else {
helper = false;
helper = "pacman";
}
if (helper === "checkupdates") {
updatesProc.command = [helper];
} else {
updatesProc.command = [helper, "-Qu"];
}
root.hasHelper = helper;
root.commandReady = true;
}
}
}
Process {
id: updateCmdDetect
command: ["sh", "-c", "command -v yay || command -v paru"]
running: true
stdout: StdioCollector {
onStreamFinished: {
const cmd = this.text.trim();
let helper;
if (cmd.length > 0) {
helper = cmd.split("/").pop();
} else {
helper = "pacman";
}
root.cmd = helper;
}
}
}
Process {
id: updatesProc
command: root.hasHelper ? ["checkupdates"] : []
command: []
running: false
stdout: StdioCollector {
+1 -4
View File
@@ -17,10 +17,7 @@ Singleton {
watchChanges: true
onAdapterUpdated: writeAdapter()
onFileChanged: {
reload();
Wallpapers.previewColorLock = false;
}
onFileChanged: reload()
JsonAdapter {
id: adapter
+6 -28
View File
@@ -6,7 +6,7 @@ import Quickshell.Io
import QtQuick
import ZShell.Models
import ZShell.Config
import qs.Services
import qs.Modules
import qs.Helpers
import qs.Paths
@@ -17,8 +17,6 @@ Searcher {
property alias crops: adapter.monitorCrops
readonly property string current: showPreview ? previewPath : actualCurrent
property alias monitorCrops: monitorCrops
property bool pendingPreviewClear
property bool previewColorLock
property string previewPath
property bool recentlyChanged
property bool showPreview: false
@@ -36,10 +34,9 @@ Searcher {
function preview(path: string): void {
previewPath = path;
showPreview = true;
if (Config.general.color.schemeGeneration)
previewColorsProc.running = true;
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--image-path", `${previewPath}`, "--scheme", `${Config.colors.schemeType}`, "--mode", `${Config.general.color.mode}`]);
showPreview = true;
}
function setCrop(screen: string, rect: rect, zoom: real): void {
@@ -55,6 +52,7 @@ Searcher {
height: rect.height,
zoom: zoom
};
// root.crops = updated;
}
function setWallpaper(path: string): void {
@@ -68,10 +66,8 @@ Searcher {
function stopPreview(): void {
showPreview = false;
if (previewColorLock)
pendingPreviewClear = true;
else
Colors.showPreview = false;
if (Config.general.color.schemeGeneration)
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--image-path", `${root.actualCurrent}`, "--scheme", `${Config.colors.schemeType}`, "--mode", `${Config.general.color.mode}`]);
}
extraOpts: useFuzzy ? ({}) : ({
@@ -81,11 +77,6 @@ Searcher {
list: wallpapers.entries
useFuzzy: true
onPreviewColorLockChanged: {
if (!previewColorLock && pendingPreviewClear)
Colors.showPreview = false;
}
IpcHandler {
function set(path: string): void {
root.setWallpaper(path);
@@ -127,17 +118,4 @@ Searcher {
path: Config.general.wallpaperPath
recursive: true
}
Process {
id: previewColorsProc
command: ["zshell-cli", "scheme", "generate", "-p", "-i", root.previewPath]
stdout: StdioCollector {
onStreamFinished: {
Colors.load(text, true);
Colors.showPreview = true;
}
}
}
}
+31 -52
View File
@@ -3,29 +3,24 @@ pragma ComponentBehavior: Bound
import Quickshell
import QtQuick
import QtQuick.Layouts
import qs.Modules
import ZShell.Config
import qs.Modules.Bar.Components
import qs.Modules.Bar.Popouts
import qs.Modules.SysTray
import qs.Modules.Network
import qs.Modules.Updates
GridLayout {
RowLayout {
id: root
required property bool fullscreen
required property bool horizontal
required property bool isHovered
required property Wrapper popouts
required property ClipWrapper popoutsWrapper
required property ShellScreen screen
readonly property int vPadding: 6
required property PersistentProperties visibilities
function axisCenterOf(item: Item): real {
const c = item.mapToItem(root, item.implicitWidth / 2, item.implicitHeight / 2);
return horizontal ? c.x : c.y;
}
function checkPopout(pos: real): void {
const ch = (horizontal ? childAt(pos, height / 2) : childAt(width / 2, pos)) as EntryWrapper;
function checkPopout(x: real): void {
const ch = childAt(x, height / 2) as EntryWrapper;
const id = ch?.entryId;
if (!ch || id === undefined) {
@@ -39,21 +34,26 @@ GridLayout {
if (id === "statusIcons" && Config.bar.popouts.statusIcons) {
const items = (ch.item as StatusIcons).items;
const icon = horizontal ? items.childAt(mapToItem(items, pos, 0).x, items.height / 2) : items.childAt(items.width / 2, mapToItem(items, 0, pos).y);
const localX = mapToItem(items, x, 0).x;
const icon = items.childAt(localX, items.height / 2);
if (icon) {
popouts.currentName = icon.name;
popouts.currentCenter = Qt.binding(() => axisCenterOf(icon));
popouts.currentCenter = Qt.binding(() => icon.mapToItem(root, icon.implicitWidth / 2, 0).x);
popouts.hasCurrent = true;
}
} else if (id === "tray" && Config.bar.popouts.tray && Config.bar.tray.showOnHover) {
const tray = ch.item as TrayIcons;
const layout = tray.layout;
const trayItem = horizontal ? layout.childAt(mapToItem(layout, pos, 0).x, layout.height / 2) : layout.childAt(tray.width / 2, mapToItem(layout, 0, pos).y);
const localX = mapToItem(layout, x, 0).x;
const trayItem = layout.childAt(localX, layout.height / 2);
if (trayItem) {
const idx = trayItem.index;
popouts.currentName = `traymenu${idx}`;
popouts.currentCenter = Qt.binding(() => axisCenterOf(trayItem));
popouts.currentCenter = Qt.binding(() => {
const it = tray.items.itemAt(idx);
return it ? it.mapToItem(root, it.implicitWidth / 2, 0).x : popouts.currentCenter;
});
popouts.hasCurrent = true;
}
@@ -63,19 +63,12 @@ GridLayout {
if (id === "updates") {
popouts.currentName = "updates";
popouts.currentCenter = Qt.binding(() => axisCenterOf(ch.item as Item));
popouts.currentCenter = Qt.binding(() => ch.item.mapToItem(root, (ch.item as Item).implicitWidth / 2, 0).x);
popouts.hasCurrent = true;
}
}
function entryAt(pos: real): string {
const ch = (horizontal ? childAt(pos, height / 2) : childAt(width / 2, pos)) as EntryWrapper;
return ch?.entryId ?? "";
}
columnSpacing: Tokens.spacing.small
columns: horizontal ? -1 : 1
rowSpacing: Tokens.spacing.small
spacing: Tokens.spacing.small
Repeater {
id: repeater
@@ -92,8 +85,7 @@ GridLayout {
delegate: EntryWrapper {
HyprsunsetWidget {
horizontal: root.horizontal
visible: !root.fullscreen || root.isHovered
visible: !root.fullscreen
}
}
}
@@ -102,8 +94,7 @@ GridLayout {
roleValue: "spacer"
delegate: EntryWrapper {
Layout.fillHeight: !root.horizontal
Layout.fillWidth: root.horizontal
Layout.fillWidth: true
}
}
@@ -112,9 +103,8 @@ GridLayout {
delegate: EntryWrapper {
Workspaces {
horizontal: root.horizontal
screen: root.screen
visible: !root.fullscreen || root.isHovered
visible: !root.fullscreen
}
}
}
@@ -124,10 +114,9 @@ GridLayout {
delegate: EntryWrapper {
TrayIcons {
horizontal: root.horizontal
loader: root
popouts: root.popouts
visible: !root.fullscreen || root.isHovered
visible: !root.fullscreen
}
}
}
@@ -137,8 +126,6 @@ GridLayout {
delegate: EntryWrapper {
StatusIcons {
horizontal: root.horizontal
visible: !root.fullscreen || root.isHovered
}
}
}
@@ -148,9 +135,8 @@ GridLayout {
delegate: EntryWrapper {
Resources {
horizontal: root.horizontal
visibilities: root.visibilities
visible: !root.fullscreen || root.isHovered
visible: !root.fullscreen
}
}
}
@@ -160,8 +146,7 @@ GridLayout {
delegate: EntryWrapper {
UpdatesWidget {
horizontal: root.horizontal
visible: !root.fullscreen || root.isHovered
visible: !root.fullscreen
}
}
}
@@ -171,10 +156,9 @@ GridLayout {
delegate: EntryWrapper {
NotifBell {
horizontal: root.horizontal
popouts: root.popouts
visibilities: root.visibilities
visible: !root.fullscreen || root.isHovered
visible: !root.fullscreen
}
}
}
@@ -184,11 +168,10 @@ GridLayout {
delegate: EntryWrapper {
Clock {
horizontal: root.horizontal
loader: root
popouts: root.popouts
visibilities: root.visibilities
visible: !root.fullscreen || root.isHovered
visible: !root.fullscreen
}
}
}
@@ -199,8 +182,7 @@ GridLayout {
delegate: EntryWrapper {
WindowTitle {
bar: root
horizontal: root.horizontal
visible: !root.fullscreen || root.isHovered
visible: !root.fullscreen
}
}
}
@@ -219,8 +201,7 @@ GridLayout {
delegate: EntryWrapper {
MediaWidget {
horizontal: root.horizontal
visible: !root.fullscreen || root.isHovered
visible: !root.fullscreen
}
}
}
@@ -233,11 +214,9 @@ GridLayout {
default property Item item
required property var modelData
Layout.alignment: root.horizontal ? Qt.AlignVCenter : Qt.AlignHCenter
Layout.bottomMargin: !root.horizontal && index === repeater.count - 1 ? root.vPadding : 0
Layout.leftMargin: root.horizontal && index === 0 ? root.vPadding : (entryId === "statusIcons" && root.horizontal) ? -root.rowSpacing + Tokens.spacing.extraSmall : 0
Layout.rightMargin: root.horizontal && index === repeater.count - 1 ? root.vPadding : 0
Layout.topMargin: !root.horizontal && index === 0 ? root.vPadding : (entryId === "statusIcons" && !root.horizontal) ? -root.columnSpacing + Tokens.spacing.extraSmall : 0
Layout.alignment: Qt.AlignVCenter
Layout.leftMargin: index === 0 ? root.vPadding : (entryId === "statusIcons") ? -root.spacing + Tokens.spacing.extraSmall : 0
Layout.rightMargin: index === repeater.count - 1 ? root.vPadding : 0
children: item
implicitHeight: item?.implicitHeight ?? 0
implicitWidth: item?.implicitWidth ?? 0
+22 -30
View File
@@ -1,48 +1,45 @@
pragma ComponentBehavior: Bound
import Quickshell
import Quickshell.Hyprland
import QtQuick
import ZShell.Config
import qs.Modules.Bar.Popouts
import QtQuick.Layouts
import qs.Components
import qs.Modules
import ZShell.Config
import qs.Helpers
import qs.Modules.SysTray
import qs.Modules.SysTray.Widgets
import qs.Modules.Network
Item {
id: root
readonly property int clampedExtent: Math.max(Config.bar.border, extent)
readonly property int contentThickness: Math.floor(Math.max(Config.bar.height, Tokens.bar.innerSize * (horizontal ? 1 : 1.5))) + padding * 2
readonly property int exclusiveZone: Config.bar.autoHide ? Config.bar.border : contentThickness
property real extent: fullscreen ? 0 : Config.bar.border
readonly property int contentHeight: Config.bar.height + padding * 2
readonly property int exclusiveZone: Config.bar.autoHide ? Config.bar.border : contentHeight
required property bool fullscreen
readonly property bool horizontal: position !== "left"
property bool isHovered
readonly property int padding: Math.max(Tokens.padding.small, Config.bar.border)
readonly property int padding: Math.max(Tokens.padding.smaller, Config.bar.border)
required property Wrapper popouts
required property ClipWrapper popoutsWrapper
required property string position
required property ShellScreen screen
readonly property bool shouldBeVisible: (!fullscreen && (!Config.bar.autoHide || visibilities.bar)) || isHovered
readonly property bool shouldBeVisible: !fullscreen && (!Config.bar.autoHide || visibilities.bar || isHovered)
readonly property int vPadding: 6
required property PersistentProperties visibilities
function checkPopout(pos: real): void {
(content.item as Bar)?.checkPopout(pos);
function checkPopout(x: real): void {
content.item?.checkPopout(x);
}
function entryAt(pos: real): string {
return (content.item as Bar)?.entryAt(pos) ?? "";
}
implicitHeight: extent
implicitWidth: extent
visible: extent > Config.bar.border
implicitHeight: fullscreen ? 0 : Config.bar.border
visible: height > Config.bar.border
states: State {
name: "visible"
when: root.shouldBeVisible
PropertyChanges {
root.extent: root.contentThickness
root.implicitHeight: root.contentHeight
}
}
transitions: [
@@ -51,7 +48,7 @@ Item {
to: "visible"
Anim {
property: "extent"
property: "implicitHeight"
target: root
}
},
@@ -60,7 +57,7 @@ Item {
to: ""
Anim {
property: "extent"
property: "implicitHeight"
target: root
}
}
@@ -70,18 +67,13 @@ Item {
id: content
active: root.shouldBeVisible || root.visible
anchors.bottom: root.position !== "bottom" ? parent.bottom : undefined
anchors.left: root.horizontal ? parent.left : undefined
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.top: root.position !== "top" ? parent.top : undefined
height: root.contentThickness
width: root.contentThickness
sourceComponent: Bar {
fullscreen: root.fullscreen
height: root.contentThickness
horizontal: root.horizontal
isHovered: root.isHovered
height: root.contentHeight
popouts: root.popouts
popoutsWrapper: root.popoutsWrapper
screen: root.screen
-157
View File
@@ -1,157 +0,0 @@
pragma ComponentBehavior: Bound
import Quickshell
import QtQuick
import QtQuick.Layouts
import ZShell.Config
import qs.Modules.Bar.Popouts
import qs.Modules.Bar.Components.Common
import qs.Helpers
import qs.Components
import qs.Services
WidgetBase {
id: root
readonly property color contentColor: visibilities.dashboard ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
readonly property string effectiveFormat: {
let fmt = Config.general.dateFormat;
if (!root.horizontal)
fmt = fmt.replace("dddd", "ddd");
return fmt;
}
readonly property var formatParts: {
const segments = root.effectiveFormat.split(" - ");
let datePart = "";
let timePart = "";
if (segments.length > 1) {
datePart = segments[0];
timePart = segments[1];
} else if (/[hms]/.test(segments[0])) {
timePart = segments[0];
} else {
datePart = segments[0];
}
const dateTokens = datePart.trim().length ? datePart.trim().split(/\s+/) : [];
const timeTokens = timePart.trim().length ? timePart.trim().split(":") : [];
return {
dateTokens: dateTokens,
timeTokens: timeTokens
};
}
required property GridLayout loader
required property Wrapper popouts
readonly property real size: horizontal ? timeText.contentWidth + Tokens.padding.small * 2 : verticalColumn.implicitHeight + Tokens.padding.small * 2
required property PersistentProperties visibilities
color: visibilities.dashboard ? Colors.palette.m3primary : Colors.tPalette.m3surfaceContainer
implicitHeight: horizontal ? baseSize : size
implicitWidth: horizontal ? size : baseSize
radius: Tokens.rounding.full
CustomText {
id: timeText
anchors.centerIn: parent
color: root.contentColor
font.family: Config.appearance.font.family.mono // qmllint disable incompatible-type
height: implicitHeight
text: Time.dateStr
visible: root.horizontal
Behavior on color {
CAnim {
}
}
}
ColumnLayout {
id: verticalColumn
anchors.centerIn: parent
spacing: Tokens.padding.extraSmall ?? 2
visible: !root.horizontal
width: root.baseSize
Repeater {
model: root.formatParts.dateTokens
CustomText {
required property string modelData
Layout.alignment: Qt.AlignHCenter
color: root.contentColor
font.family: Config.appearance.font.family.mono // qmllint disable incompatible-type
text: Qt.formatDateTime(Time.date, modelData)
Behavior on color {
CAnim {
}
}
}
}
Rectangle {
Layout.alignment: Qt.AlignHCenter
Layout.bottomMargin: Tokens.padding.extraSmall ?? 2
Layout.topMargin: Tokens.padding.extraSmall ?? 2
color: root.contentColor
height: 1
implicitWidth: root.baseSize * 0.5
opacity: 0.4
radius: 1
visible: root.formatParts.dateTokens.length > 0 && root.formatParts.timeTokens.length > 0
}
Repeater {
model: root.formatParts.timeTokens
CustomText {
required property string modelData
Layout.alignment: Qt.AlignHCenter
color: root.contentColor
font.family: Config.appearance.font.family.mono // qmllint disable incompatible-type
text: {
if (modelData.includes("h"))
return Time.hourStr;
if (modelData.includes("m"))
return Time.minuteStr;
if (modelData.includes("s"))
return Time.secondStr;
return "";
}
Behavior on color {
CAnim {
}
}
}
}
CustomText {
Layout.alignment: Qt.AlignHCenter
color: root.contentColor
font.family: Config.appearance.font.family.mono // qmllint disable incompatible-type
text: Qt.formatDateTime(Time.date, "AP")
visible: Config.services.useTwelveHourClock && root.formatParts.timeTokens.length > 0
Behavior on color {
CAnim {
}
}
}
}
StateLayer {
acceptedButtons: Qt.LeftButton
color: root.contentColor
onClicked: {
root.visibilities.dashboard = !root.visibilities.dashboard;
}
}
}
@@ -1,16 +0,0 @@
import QtQuick
import ZShell.Config
import qs.Components
import qs.Services
CustomRect {
id: root
readonly property int baseSize: horizontal ? Math.max(Config.bar.height, Tokens.bar.innerSize) : Math.max(Config.bar.height, Math.floor(Tokens.bar.innerSize * 1.5))
required property bool horizontal
color: Colors.tPalette.m3surfaceContainer
implicitHeight: horizontal ? baseSize : width
implicitWidth: horizontal ? height : baseSize
radius: Tokens.rounding.full
}
-92
View File
@@ -1,92 +0,0 @@
import QtQuick
import QtQuick.Layouts
import ZShell.Config
import qs.Components
import qs.Modules.Bar.Components.Common
import qs.Helpers
import qs.Services
WidgetBase {
id: root
readonly property string currentMedia: (Players.active?.trackTitle ?? qsTr("No media")) || qsTr("Unknown title")
readonly property int textWidth: Math.min(metrics.width, 200)
implicitHeight: horizontal ? baseSize : layout.implicitHeight + Tokens.padding.small * 2
implicitWidth: horizontal ? layout.implicitWidth + Tokens.padding.small * 2 : baseSize
radius: Tokens.rounding.full
Behavior on implicitHeight {
enabled: !root.horizontal
Anim {
}
}
Behavior on implicitWidth {
enabled: root.horizontal
Anim {
}
}
TextMetrics {
id: metrics
font: mediatext.font
text: mediatext.text
}
GridLayout {
id: layout
anchors.bottomMargin: root.horizontal ? 0 : Tokens.padding.small
anchors.fill: parent
anchors.leftMargin: root.horizontal ? Tokens.padding.small : 0
anchors.rightMargin: root.horizontal ? Tokens.padding.small : 0
anchors.topMargin: root.horizontal ? 0 : Tokens.padding.small
columns: root.horizontal ? -1 : 1
Behavior on implicitWidth {
Anim {
}
}
MaterialIcon {
Layout.alignment: root.horizontal ? Qt.AlignVCenter : Qt.AlignHCenter
animate: true
color: Players.active?.isPlaying ? Colors.palette.m3primary : Colors.palette.m3onSurface
font.pointSize: Tokens.font.size.larger
text: Players.active?.isPlaying ? "music_note" : "music_off"
}
MarqueeText {
id: mediatext
Layout.alignment: root.horizontal ? Qt.AlignVCenter : Qt.AlignHCenter
animate: true
color: Players.active?.isPlaying ? Colors.palette.m3primary : Colors.palette.m3onSurface
font.pointSize: Tokens.font.size.normal
horizontalAlignment: Text.AlignHCenter
implicitHeight: root.horizontal ? root.implicitHeight : root.textWidth
implicitWidth: root.horizontal ? root.textWidth : root.implicitWidth
marqueeEnabled: false
pauseMs: 4000
text: root.currentMedia
vertical: !root.horizontal
}
}
CustomMouseArea {
anchors.fill: parent
hoverEnabled: true
onContainsMouseChanged: {
if (!containsMouse) {
mediatext.marqueeEnabled = false;
} else {
mediatext.marqueeEnabled = true;
mediatext.anim.start();
}
}
}
}
-63
View File
@@ -1,63 +0,0 @@
pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Layouts
import Quickshell.Services.SystemTray
import ZShell.Config
import qs.Components
import qs.Modules.Bar.Components.Common
import qs.Modules.Bar.Components.Tray
import qs.Modules.Bar.Popouts
import qs.Services
WidgetBase {
id: root
readonly property alias items: repeater
readonly property alias layout: sysGrid
required property GridLayout loader
readonly property int padding: Tokens.padding.extraSmall
required property Wrapper popouts
readonly property real size: horizontal ? sysGrid.implicitWidth + sysGrid.anchors.leftMargin + sysGrid.anchors.rightMargin : sysGrid.implicitHeight + sysGrid.anchors.topMargin + sysGrid.anchors.bottomMargin
bottomLeftRadius: horizontal ? Tokens.rounding.full : Tokens.rounding.small / 2
bottomRightRadius: Tokens.rounding.small / 2
color: Colors.tPalette.m3surfaceContainer
implicitHeight: horizontal ? baseSize : size
implicitWidth: horizontal ? size : baseSize
radius: Tokens.rounding.full
topRightRadius: horizontal ? Tokens.rounding.small / 2 : Tokens.rounding.full
GridLayout {
id: sysGrid
anchors.bottomMargin: root.horizontal ? 0 : Tokens.padding.extraSmall
anchors.centerIn: parent
anchors.leftMargin: root.horizontal ? Tokens.padding.extraSmall : 0
anchors.rightMargin: root.horizontal ? Tokens.padding.extraSmall : 0
anchors.topMargin: root.horizontal ? 0 : Tokens.padding.extraSmall
columns: root.horizontal ? -1 : 1
rowSpacing: -2
Repeater {
id: repeater
model: SystemTray.items
TrayItem {
id: trayItem
required property int index
required property SystemTrayItem modelData
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
implicitHeight: 34
implicitWidth: 34
ind: index
item: modelData
loader: root.loader
popouts: root.popouts
}
}
}
}
-41
View File
@@ -1,41 +0,0 @@
import QtQuick
import QtQuick.Layouts
import ZShell.Config
import qs.Components
import qs.Modules.Bar.Components.Common
import qs.Helpers
import qs.Services
WidgetBase {
id: root
property int countUpdates: Updates.availableUpdates
property color textColor: Colors.palette.m3onSurface
color: Colors.tPalette.m3surfaceContainer
implicitHeight: horizontal ? baseSize : content.implicitHeight + Tokens.spacing.small
implicitWidth: horizontal ? content.implicitWidth + Tokens.spacing.small * 2 : baseSize
radius: Tokens.rounding.full
GridLayout {
id: content
anchors.centerIn: parent
columnSpacing: Tokens.spacing.small
columns: root.horizontal ? -1 : 1
rowSpacing: -Tokens.spacing.extraSmall / 2
MaterialIcon {
Layout.alignment: root.horizontal ? Qt.AlignVCenter : Qt.AlignHCenter
font.pointSize: root.horizontal ? Tokens.font.size.larger : Tokens.font.size.large
text: "package_2"
}
CustomText {
Layout.alignment: root.horizontal ? Qt.AlignVCenter : Qt.AlignHCenter
color: root.textColor
font.pointSize: Tokens.font.size.normal
text: root.countUpdates
}
}
}
-98
View File
@@ -1,98 +0,0 @@
pragma ComponentBehavior: Bound
import QtQuick
import ZShell.Config
import qs.Components
import qs.Helpers
import qs.Services
Item {
id: root
required property var bar
property color color: Colors.palette.m3primary
property Title current: text1
required property bool horizontal
// readonly property int maxWidth: 300
readonly property int maxSize: {
const otherModules = bar.children.filter(c => c.enabled && c.entryId && c.item !== this && c.entryId !== "spacer");
const otherSize = otherModules.reduce((acc, curr) => acc + (horizontal ? (curr.item?.nonAnimWidth ?? curr.width ?? 0) : (curr.item.nonAnimHeight ?? curr.height ?? 0)), 0);
return horizontal ? (bar.width - otherSize - bar.columnSpacing * (bar.children.length - 1) - bar.vPadding * 2) : (bar.height - otherSize - bar.rowSpacing * (bar.children.length - 1) - bar.vPadding * 4);
}
clip: true
implicitHeight: horizontal ? current.implicitHeight : current.implicitWidth + current.anchors.topMargin
implicitWidth: horizontal ? current.implicitWidth + current.anchors.leftMargin : current.implicitHeight + current.anchors.topMargin
Behavior on implicitHeight {
enabled: !root.horizontal
Anim {
type: Anim.DefaultEffects
}
}
Behavior on implicitWidth {
enabled: root.horizontal
Anim {
type: Anim.DefaultEffects
}
}
Title {
id: text1
}
Title {
id: text2
}
TextMetrics {
id: metrics
elide: Qt.ElideRight
elideWidth: root.maxSize - (root.horizontal ? root.current.anchors.leftMargin : 0)
font.family: "Rubik"
font.pointSize: Tokens.font.size.normal
text: Hypr.activeToplevel?.title ?? qsTr("Desktop")
onElideWidthChanged: root.current.text = elidedText
onTextChanged: {
const next = root.current === text1 ? text2 : text1;
next.text = elidedText;
root.current = next;
}
}
component Title: CustomText {
id: text
anchors.horizontalCenter: root.horizontal ? undefined : parent.horizontalCenter
anchors.left: root.horizontal ? parent.left : undefined
anchors.leftMargin: root.horizontal ? Tokens.spacing.small : 0
anchors.top: root.horizontal ? undefined : parent.top
anchors.topMargin: root.horizontal ? 0 : Tokens.spacing.small
anchors.verticalCenter: root.horizontal ? parent.verticalCenter : undefined
color: root.color
font.family: metrics.font.family
font.pointSize: metrics.font.pointSize
height: root.horizontal ? implicitHeight : implicitWidth
opacity: root.current === this ? 1 : 0
width: root.horizontal ? implicitWidth : implicitHeight
Behavior on opacity {
Anim {
}
}
transform: [
Translate {
x: !root.horizontal ? -text.implicitWidth + text.implicitHeight : 0
},
Rotation {
angle: root.horizontal ? 0 : 270
origin.x: text.implicitHeight / 2
origin.y: text.implicitHeight / 2
}
]
}
}
-88
View File
@@ -1,88 +0,0 @@
pragma ComponentBehavior: Bound
import QtQuick
import Quickshell
import qs.Components
import ZShell.Config
Item {
id: root
required property real borderThickness
readonly property alias content: content
readonly property bool horizontal: position !== "left"
// property real offsetScale: y > 0 || content.hasCurrent ? 0 : 1
property real offsetScale: {
if (content.hasCurrent)
return 0;
if (position === "top")
return y > 0 ? 0 : 1;
if (position === "bottom")
return 1;
return x > 0 ? 0 : 1;
}
required property string position
required property ShellScreen screen
anchors.bottom: position === "bottom" ? parent.bottom : undefined
clip: true
implicitHeight: horizontal ? content.implicitHeight * (1 - offsetScale) : content.implicitHeight
implicitWidth: horizontal ? content.implicitWidth : content.implicitWidth * (1 - offsetScale)
visible: width > 0 && height > 0
x: {
if (!horizontal)
return 0;
const off = content.currentCenter - borderThickness - content.nonAnimWidth / 2;
const diff = parent.width - Math.floor(off + content.nonAnimWidth);
if (diff < 0)
return off + diff;
return Math.floor(Math.max(off, 0));
}
y: {
if (horizontal)
return 0;
const off = content.currentCenter - borderThickness - content.nonAnimHeight / 2;
const diff = parent.height - Math.floor(off + content.nonAnimHeight);
if (diff < 0)
return off + diff;
return Math.max(off, 0);
}
Behavior on offsetScale {
Anim {
}
}
Behavior on x {
enabled: !root.horizontal || root.offsetScale < 1
Anim {
duration: content.animLength
easing: content.animCurve
}
}
Behavior on y {
enabled: root.horizontal || root.offsetScale < 1
Anim {
duration: content.animLength
easing: content.animCurve
}
}
Wrapper {
id: content
anchors.bottom: root.position === "bottom" ? parent.bottom : undefined
anchors.bottomMargin: (-implicitHeight - 5) * root.offsetScale
anchors.horizontalCenter: root.horizontal ? parent.horizontalCenter : undefined
anchors.left: root.horizontal ? undefined : parent.left
anchors.leftMargin: (-implicitWidth - 5) * root.offsetScale
anchors.top: root.position === "top" ? parent.top : undefined
anchors.topMargin: (-implicitHeight - 5) * root.offsetScale
anchors.verticalCenter: root.horizontal ? undefined : parent.verticalCenter
horizontal: root.horizontal
offsetScale: root.offsetScale
screen: root.screen
}
}
+56
View File
@@ -0,0 +1,56 @@
pragma ComponentBehavior: Bound
import QtQuick
import Quickshell
import qs.Components
import ZShell.Config
Item {
id: root
required property real borderThickness
readonly property alias content: content
property real offsetScale: y > 0 || content.hasCurrent ? 0 : 1
required property ShellScreen screen
clip: true
implicitHeight: content.implicitHeight * (1 - offsetScale)
implicitWidth: content.implicitWidth
visible: width > 0 && height > 0
x: {
const off = content.currentCenter - borderThickness - content.nonAnimWidth / 2;
const diff = parent.width - Math.floor(off + content.nonAnimWidth);
if (diff < 0)
return off + diff;
return Math.floor(Math.max(off, 0));
}
Behavior on offsetScale {
Anim {
}
}
Behavior on x {
enabled: root.offsetScale < 1
Anim {
duration: content.animLength
easing.bezierCurve: content.animCurve
}
}
Behavior on y {
Anim {
duration: content.animLength
easing.bezierCurve: content.animCurve
}
}
Wrapper {
id: content
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: (-implicitHeight - 5) * root.offsetScale
offsetScale: root.offsetScale
screen: root.screen
}
}
+9 -9
View File
@@ -59,7 +59,7 @@ Item {
anchors.bottom: parent.bottom
anchors.left: entries.right
anchors.leftMargin: Tokens.spacing.medium
anchors.leftMargin: Tokens.spacing.normal
anchors.top: parent.top
color: Colors.tPalette.m3surfaceContainer
implicitWidth: ClipHistory.previewIsImage ? Math.max(Math.min(imagePreview.sourceSize.width + Tokens.padding.large * 2, Config.clipboard.sizes.previewWidth), Config.clipboard.sizes.minPreviewWidth) : Math.max(Math.min(textPreviewColumn.width + textPreviewColumn.anchors.margins * 2, Config.clipboard.sizes.previewWidth), Config.clipboard.sizes.minPreviewWidth)
@@ -75,7 +75,7 @@ Item {
anchors.left: parent.left
anchors.leftMargin: 0
anchors.margins: Tokens.padding.small
anchors.margins: Tokens.padding.normal
anchors.top: parent.top
visible: !ClipHistory.previewIsImage
@@ -90,7 +90,7 @@ Item {
required property int index
required property var modelData
spacing: Tokens.spacing.medium
spacing: Tokens.spacing.normal
CustomRect {
color: lineRow.index % 2 ? Colors.tPalette.m3surfaceContainer : "transparent"
@@ -192,7 +192,7 @@ Item {
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.top: search.bottom
anchors.topMargin: Tokens.spacing.medium
anchors.topMargin: Tokens.spacing.normal
implicitWidth: Config.clipboard.sizes.width
CustomListView {
@@ -204,7 +204,7 @@ Item {
highlightRangeMode: ListView.ApplyRange
preferredHighlightBegin: 0
preferredHighlightEnd: height
spacing: Tokens.spacing.medium
spacing: Tokens.spacing.normal
CustomScrollBar.vertical: CustomScrollBar {
flickable: view
@@ -250,7 +250,7 @@ Item {
id: icon
anchors.left: parent.left
anchors.margins: Tokens.padding.small
anchors.margins: Tokens.padding.normal
anchors.verticalCenter: parent.verticalCenter
font.pointSize: Tokens.font.size.large
text: clipItem.isImage ? "image" : "text_fields"
@@ -260,7 +260,7 @@ Item {
id: text
anchors.left: icon.right
anchors.margins: Tokens.spacing.medium
anchors.margins: Tokens.spacing.normal
anchors.verticalCenter: parent.verticalCenter
elide: Text.ElideRight
text: clipItem.isImage ? qsTr("Image") : ClipHistory.displayText(clipItem.modelData)
@@ -292,7 +292,7 @@ Item {
IconButton {
Layout.fillHeight: true
Layout.margins: Tokens.padding.small
Layout.margins: Tokens.padding.normal
Layout.preferredWidth: height
icon: "delete"
inactiveColor: Qt.alpha(Colors.palette.m3error, 0.8)
@@ -320,7 +320,7 @@ Item {
Behavior on y {
Anim {
duration: Tokens.anim.durations.small
easing: Tokens.anim.expressiveDefaultEffects
easing.bezierCurve: Tokens.anim.curves.expressiveEffects
}
}
}
+3 -3
View File
@@ -15,15 +15,15 @@ Item {
required property PersistentProperties visibilities
anchors.bottomMargin: (-implicitHeight - 5) * offsetScale
implicitHeight: content.implicitHeight + Tokens.padding.small * 2
implicitWidth: content.implicitWidth + Tokens.padding.small * 2 || 400
implicitHeight: content.implicitHeight + Tokens.padding.normal * 2
implicitWidth: content.implicitWidth + Tokens.padding.normal * 2 || 400
opacity: 1 - offsetScale
visible: offsetScale < 1
Behavior on offsetScale {
Anim {
duration: Tokens.anim.durations.expressiveDefaultSpatial
easing: Tokens.anim.expressiveDefaultSpatial
easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial
}
}
+44
View File
@@ -0,0 +1,44 @@
import Quickshell
import QtQuick
import QtQuick.Layouts
import ZShell.Config
import qs.Modules
import qs.Helpers
import qs.Components
import qs.Services
CustomRect {
id: root
required property RowLayout loader
required property Wrapper popouts
required property PersistentProperties visibilities
color: visibilities.dashboard ? Colors.palette.m3primary : Colors.tPalette.m3surfaceContainer
implicitHeight: Config.bar.height + Tokens.padding.smallest * 2
implicitWidth: timeText.contentWidth + Tokens.padding.normal * 2
radius: Tokens.rounding.full
CustomText {
id: timeText
anchors.centerIn: parent
color: root.visibilities.dashboard ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
font: Config.appearance.font.family.mono
text: Time.dateStr
Behavior on color {
CAnim {
}
}
}
StateLayer {
acceptedButtons: Qt.LeftButton
color: root.visibilities.dashboard ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
onClicked: {
root.visibilities.dashboard = !root.visibilities.dashboard;
}
}
}
@@ -5,17 +5,20 @@ import Quickshell.Services.SystemTray
import QtQuick
import ZShell.Config
import qs.Components
import qs.Modules.WSOverview
import qs.Modules.Network
import qs.Modules.SysTray.Popouts
import qs.Modules.Updates
Item {
id: root
readonly property Item current: currentPopout?.item ?? null
readonly property Popout currentPopout: content.children.find(c => c.shouldBeActive) ?? null
required property bool horizontal
required property PopoutState popouts
implicitHeight: (currentPopout?.implicitHeight ?? 0) + Tokens.padding.smaller * 2
implicitWidth: (currentPopout?.implicitWidth ?? 0) + Tokens.padding.smaller * 2
implicitHeight: (currentPopout?.implicitHeight ?? 0) + Tokens.padding.small * 2
implicitWidth: (currentPopout?.implicitWidth ?? 0) + Tokens.padding.small * 2
Item {
id: content
@@ -70,7 +73,6 @@ Item {
name: "upower"
sourceComponent: UPowerPopout {
horizontal: root.horizontal
}
}
@@ -98,10 +100,10 @@ Item {
readonly property bool shouldBeActive: root.popouts.currentName === name
active: false
anchors.centerIn: opacity === 1 ? undefined : parent
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: opacity === 1 ? parent.top : undefined
anchors.topMargin: Tokens.padding.smaller
// anchors.horizontalCenter: parent.horizontalCenter
// anchors.top: parent.top
// anchors.topMargin: 5
anchors.centerIn: parent
opacity: 0
scale: 0.8
+3 -3
View File
@@ -32,16 +32,16 @@ Item {
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.margins: Tokens.padding.small
anchors.margins: Tokens.padding.smaller
anchors.right: parent.right
anchors.top: parent.top
color: "transparent"
radius: Tokens.rounding.extraLarge - anchors.margins
radius: Tokens.rounding.normal - anchors.margins
Item {
id: view
readonly property int currentIndex: root.dashState?.currentTab
readonly property int currentIndex: root.state.currentTab
readonly property Item currentItem: row.children[currentIndex]
anchors.fill: parent
+4 -5
View File
@@ -13,11 +13,11 @@ GridLayout {
required property PersistentProperties dashState
readonly property bool dashboardVisible: visibilities.dashboard
property int radius: Tokens.rounding.medium
property int radius: Tokens.rounding.smallest
required property PersistentProperties visibilities
columnSpacing: Tokens.spacing.small
rowSpacing: Tokens.spacing.small
columnSpacing: Tokens.spacing.smaller
rowSpacing: Tokens.spacing.smaller
ParallelAnimation {
id: openAnim
@@ -104,13 +104,12 @@ GridLayout {
}
}
CustomClippingRect {
Rect {
Layout.column: 0
Layout.columnSpan: 5
Layout.fillWidth: true
Layout.preferredHeight: media.implicitHeight
Layout.row: 2
color: Colors.tPalette.m3surfaceContainer
radius: root.radius
Media {
+4 -4
View File
@@ -132,7 +132,7 @@ CustomMouseArea {
IconButton {
icon: "chevron_left"
padding: Tokens.padding.extraSmall
padding: Tokens.padding.small
type: IconButton.Text
onClicked: root.dashState.currentDate = new Date(root.realCurrYear, root.realCurrMonth - 1, 1)
@@ -150,7 +150,7 @@ CustomMouseArea {
const now = new Date();
return root.realCurrMonth !== now.getMonth() || root.realCurrYear !== now.getFullYear();
}
radius: pressed ? Tokens.rounding.small : Tokens.rounding.largeIncreased
radius: pressed ? Tokens.rounding.small : Tokens.rounding.large
Behavior on radius {
Anim {
@@ -203,7 +203,7 @@ CustomMouseArea {
IconButton {
icon: "chevron_right"
padding: Tokens.padding.extraSmall
padding: Tokens.padding.small
type: IconButton.Text
onClicked: root.dashState.currentDate = new Date(root.realCurrYear, root.realCurrMonth + 1, 1)
@@ -259,7 +259,7 @@ CustomMouseArea {
required property var model
implicitHeight: text.implicitHeight + Tokens.padding.small * 2
implicitHeight: text.implicitHeight + Tokens.padding.normal * 2
implicitWidth: implicitHeight
CustomText {
+190 -162
View File
@@ -1,15 +1,12 @@
pragma ComponentBehavior: Bound
import Quickshell
import Quickshell.Services.Mpris
import QtQuick
import QtQuick.Layouts
import QtQuick.Shapes
import QtQuick.Effects
import ZShell.Components
import ZShell.Services
import ZShell.Config
import qs.Modules.Dashboard.Dash.Media
import qs.Daemons
import qs.Components
import qs.Helpers
@@ -17,7 +14,7 @@ import qs.Services
Item {
id: root
readonly property bool hasUnknownLength: (Players.active?.length ?? 0) > 2147483647
property real playerProgress: {
const active = Players.active;
return active?.length ? (active.position % active.length) / active.length : 0;
@@ -26,19 +23,7 @@ Item {
anchors.left: parent.left
anchors.right: parent.right
implicitHeight: layout.implicitHeight + layout.anchors.margins * 2
function lengthStr(length: int): string {
if (length < 0)
return "-1:-1";
const hours = Math.floor(length / 3600);
const mins = Math.floor((length % 3600) / 60);
const secs = Math.floor(length % 60).toString().padStart(2, "0");
if (hours > 0)
return `${hours}:${mins.toString().padStart(2, "0")}:${secs}`;
return `${mins}:${secs}`;
}
implicitHeight: cover.height + rowHeight * 2
Behavior on playerProgress {
Anim {
@@ -47,10 +32,11 @@ Item {
}
Timer {
running: Players.active?.isPlaying ?? false
interval: Config.dashboard.mediaUpdateInterval
triggeredOnStart: true
repeat: true
running: Players.active?.isPlaying ?? false
triggeredOnStart: true
onTriggered: Players.active?.positionChanged()
}
@@ -58,18 +44,14 @@ Item {
service: Audio.cava
}
BackgroundShapes {
anchors.fill: parent
}
Shape {
id: visualizer
readonly property int bars: Config.services.visualizerBars
property color color: Qt.alpha(Colors.palette.m3primary, 0.5)
property color fillColor: Qt.alpha(color, 0.1)
property color color: Colors.palette.m3tertiary
property color fillColor: Qt.alpha(color, 0.25)
anchors.fill: parent
anchors.fill: layout
anchors.leftMargin: -(shape.strokeWidth / 2)
layer.enabled: true
asynchronous: true
@@ -90,17 +72,17 @@ Item {
const n = values.length;
if (n < 2)
return "";
return "";
const h = root.height + shape.strokeWidth / 2;
const w = root.width + shape.strokeWidth;
const h = layout.height + shape.strokeWidth / 2;
const w = layout.width + shape.strokeWidth;
function x(i) {
return i * w / (n - 1);
}
function y(i) {
return h - (values[i] * Config.dashboard.sizes.mediaVisualizerSize) / 2;
return h - values[i] * Config.dashboard.sizes.mediaVisualizerSize;
}
let d = `M 0 ${h} `;
@@ -144,186 +126,232 @@ Item {
}
}
Shape {
preferredRendererType: Shape.CurveRenderer
ShapePath {
capStyle: Tokens.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap
fillColor: "transparent"
strokeColor: Colors.layer(Colors.palette.m3surfaceContainerHigh, 2)
strokeWidth: Config.dashboard.sizes.mediaProgressThickness
Behavior on strokeColor {
CAnim {
}
}
PathAngleArc {
centerX: cover.x + cover.width / 2
centerY: cover.y + cover.height / 2
radiusX: (cover.width + Config.dashboard.sizes.mediaProgressThickness) / 2 + Tokens.spacing.small
radiusY: (cover.height + Config.dashboard.sizes.mediaProgressThickness) / 2 + Tokens.spacing.small
startAngle: -90 - Config.dashboard.sizes.mediaProgressSweep / 2
sweepAngle: Config.dashboard.sizes.mediaProgressSweep
}
}
ShapePath {
capStyle: Tokens.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap
fillColor: "transparent"
strokeColor: Colors.palette.m3primary
strokeWidth: Config.dashboard.sizes.mediaProgressThickness
Behavior on strokeColor {
CAnim {
}
}
PathAngleArc {
centerX: cover.x + cover.width / 2
centerY: cover.y + cover.height / 2
radiusX: (cover.width + Config.dashboard.sizes.mediaProgressThickness) / 2 + Tokens.spacing.small
radiusY: (cover.height + Config.dashboard.sizes.mediaProgressThickness) / 2 + Tokens.spacing.small
startAngle: -90 - Config.dashboard.sizes.mediaProgressSweep / 2
sweepAngle: Config.dashboard.sizes.mediaProgressSweep * root.playerProgress
}
}
}
RowLayout {
id: layout
anchors.fill: parent
anchors.margins: Tokens.padding.large
anchors.leftMargin: Tokens.padding.extraLarge
anchors.left: parent.left
anchors.right: parent.right
implicitHeight: root.implicitHeight
CoverVisualizer {
Layout.fillHeight: true
implicitWidth: Config.dashboard.sizes.mediaCoverArtSize
CustomClippingRect {
id: cover
Layout.alignment: Qt.AlignLeft
Layout.bottomMargin: Tokens.padding.large + Config.dashboard.sizes.mediaProgressThickness + Tokens.spacing.small
Layout.leftMargin: Tokens.padding.large + Config.dashboard.sizes.mediaProgressThickness + Tokens.spacing.small
Layout.preferredHeight: Config.dashboard.sizes.mediaCoverArtSize
Layout.preferredWidth: Config.dashboard.sizes.mediaCoverArtSize
Layout.topMargin: Tokens.padding.large + Config.dashboard.sizes.mediaProgressThickness + Tokens.spacing.small
color: Colors.tPalette.m3surfaceContainerHigh
radius: Infinity
MaterialIcon {
anchors.centerIn: parent
color: Colors.palette.m3onSurfaceVariant
font.pointSize: (parent.width * 0.4) || 1
grade: 200
text: "art_track"
}
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)
}
}
ColumnLayout {
CustomRect {
Layout.fillWidth: true
Layout.leftMargin: Tokens.spacing.largeIncreased
Layout.rightMargin: Tokens.spacing.largeIncreased
spacing: Tokens.spacing.small
Layout.preferredHeight: childrenRect.height
MarqueeText {
id: title
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
color: Colors.palette.m3primary
font.pointSize: Tokens.font.size.normal
horizontalAlignment: Text.AlignHCenter
pauseMs: 4000
text: (Players.active?.trackTitle ?? qsTr("No media")) || qsTr("Unknown title")
implicitWidth: parent.width - Tokens.padding.large * 4
width: parent.width - Tokens.padding.large * 4
}
MarqueeText {
id: album
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: title.bottom
anchors.topMargin: Tokens.spacing.small
color: Colors.palette.m3outline
font.pointSize: Tokens.font.size.small
horizontalAlignment: Text.AlignHCenter
pauseMs: 4000
text: (Players.active?.trackAlbum ?? qsTr("No media")) || qsTr("Unknown album")
implicitWidth: parent.width - Tokens.padding.large * 4
width: parent.width - Tokens.padding.large * 4
}
MarqueeText {
id: artist
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: album.bottom
anchors.topMargin: Tokens.spacing.small
color: Colors.palette.m3secondary
horizontalAlignment: Text.AlignHCenter
pauseMs: 4000
text: (Players.active?.trackArtist ?? qsTr("No media")) || qsTr("Unknown artist")
implicitWidth: parent.width - Tokens.padding.large * 4
width: parent.width - Tokens.padding.large * 4
}
RowLayout {
id: positionSliderLayout
Layout.topMargin: Tokens.spacing.large
Layout.fillWidth: true
id: controls
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: artist.bottom
anchors.topMargin: Tokens.spacing.smaller
spacing: Tokens.spacing.small
TextMetrics {
id: timeMetrics
text: Players.active ? root.lengthStr(Math.max(Players.active.position, root.hasUnknownLength ? 0 : Players.active.length)).replace(/[1-9]/g, "0") : "00:00"
}
CustomText {
id: positionLabel
Layout.preferredWidth: timeMetrics.width
text: root.lengthStr(Players.active?.position ?? -1)
color: Colors.palette.m3onSurfaceVariant
font: timeMetrics.font
horizontalAlignment: Text.AlignHCenter
}
CustomSlider {
id: positionSlider
Layout.fillWidth: true
value: Players.active ? Players.active.position / (Players.active.length || 1) : 0
enabled: (Players.active?.canSeek ?? false) && !root.hasUnknownLength
wavy: true
animateWave: Players.active?.isPlaying ?? false
waveFrequency: 5
waveDuration: 2000
interactionOnMove: false
onInteraction: value => {
const active = Players.active;
if (active?.canSeek && active?.positionSupported)
active.position = value * active.length;
Control {
function onClicked(): void {
Players.active?.previous();
}
Binding {
target: positionLabel
property: "text"
value: root.lengthStr(positionSlider.pos * (Players.active?.length ?? 0))
when: positionSlider.dragging
}
}
CustomText {
Layout.preferredWidth: timeMetrics.width
text: root.hasUnknownLength ? "--:--" : root.lengthStr(Players.active?.length ?? -1)
color: Colors.palette.m3onSurfaceVariant
font: timeMetrics.font
horizontalAlignment: Text.AlignHCenter
}
}
ButtonRow {
Layout.topMargin: Tokens.spacing.largeIncreased
Layout.fillWidth: true
spacing: Tokens.spacing.extraSmall
Layout.leftMargin: positionSliderLayout.implicitWidth / 4
Layout.rightMargin: positionSliderLayout.implicitWidth / 4
IconButton {
type: IconButton.Tonal
icon: "shuffle"
isRound: true
shapeMorph: true
checked: Players.active?.shuffle ?? false
enabled: Players.active?.shuffleSupported
onClicked: Players.active.shuffle = !Players.active?.shuffle
}
IconButton {
id: previousBtn
type: IconButton.Tonal
canUse: Players.active?.canGoPrevious ?? false
icon: "skip_previous"
isRound: true
shapeMorph: true
enabled: Players.active?.canGoPrevious
onClicked: Players.active?.previous()
font.pointSize: Tokens.font.size.large
}
IconButton {
id: playPauseBtn
icon: Players.active?.isPlaying ? "pause" : "play_arrow"
isRound: true
shapeMorph: true
fillWidth: true
checked: Players.active?.isPlaying ?? false
enabled: Players.active?.canTogglePlaying
onClicked: Players.active?.togglePlaying()
font.pointSize: Tokens.font.size.large
}
IconButton {
id: nextBtn
type: IconButton.Tonal
icon: "skip_next"
isRound: true
shapeMorph: true
enabled: Players.active?.canGoNext
onClicked: Players.active?.next()
font.pointSize: Tokens.font.size.large
}
IconButton {
type: IconButton.Tonal
icon: Players.active?.loopState === MprisLoopState.Track ? "repeat_one" : "repeat"
isRound: true
shapeMorph: true
checked: Players.active?.loopState === MprisLoopState.Track || Players.active?.loopState === MprisLoopState.Playlist
enabled: Players.active?.loopSupported
onClicked: {
const state = Players.active.loopState;
if (state === MprisLoopState.None)
Players.active.loopState = MprisLoopState.Track;
else if (state === MprisLoopState.Track)
Players.active.loopState = MprisLoopState.Playlist;
else
Players.active.loopState = MprisLoopState.None;
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"
}
}
}
}
component Control: CustomRect {
id: control
required property bool canUse
required property string icon
property int level: 1
property string set_color: "Secondary"
function onClicked(): void {
}
Layout.preferredWidth: implicitWidth + (controlState.pressed ? Tokens.padding.normal * 2 : 0)
color: canUse ? Colors.palette[`m3${set_color.toLowerCase()}`] : Colors.palette[`m3${set_color.toLowerCase()}Container`]
implicitHeight: implicitWidth
implicitWidth: Math.max(icon.implicitHeight, icon.implicitHeight) + Tokens.padding.small
radius: Tokens.rounding.full
Behavior on Layout.preferredWidth {
Anim {
duration: Tokens.anim.durations.expressiveFastSpatial
easing.bezierCurve: Tokens.anim.curves.expressiveFastSpatial
}
}
Behavior on radius {
Anim {
duration: Tokens.anim.durations.expressiveFastSpatial
easing.bezierCurve: Tokens.anim.curves.expressiveFastSpatial
}
}
Elevation {
anchors.fill: parent
level: controlState.containsMouse && !controlState.pressed ? control.level + 1 : control.level
radius: parent.radius
z: -1
}
StateLayer {
id: controlState
color: control.canUse ? Colors.palette[`m3on${control.set_color}`] : Colors.palette[`m3on${control.set_color}Container`]
enabled: control.canUse
onClicked: {
control.onClicked();
}
// radius: Tokens.rounding.full
}
MaterialIcon {
id: icon
anchors.centerIn: parent
anchors.verticalCenterOffset: font.pointSize * 0.05
animate: true
color: control.canUse ? Colors.palette[`m3on${control.set_color}`] : Colors.palette[`m3on${control.set_color}Container`]
fill: control.canUse ? 1 : 0
font.pointSize: Tokens.font.size.large
text: control.icon
}
}
}
@@ -1,97 +0,0 @@
pragma ComponentBehavior: Bound
import QtQuick
import M3Shapes
import qs.Components
import qs.Services
import qs.Helpers
Item {
id: root
property int count: 14
property list<real> darkOpacities: [0.10, 0.20, 0.10, 0.20]
property list<real> lightOpacities: [0.34, 0.34, 0.08, 0.2]
property real maxRotSpeed: 12
property real maxSize: 124
property real maxSpeed: 18
property real minRotSpeed: -12
property real minSize: 36
property real minSpeed: 4
readonly property list<int> shapePool: [MaterialShape.Circle, MaterialShape.Cookie4Sided, MaterialShape.Cookie6Sided, MaterialShape.Cookie7Sided, MaterialShape.Cookie9Sided, MaterialShape.Cookie12Sided, MaterialShape.Sunny, MaterialShape.VerySunny, MaterialShape.SoftBurst, MaterialShape.Pentagon, MaterialShape.Gem, MaterialShape.Arch, MaterialShape.Arrow, MaterialShape.Pill, MaterialShape.Triangle, MaterialShape.Fan, MaterialShape.Oval]
function rand(min: real, max: real): real {
return min + Math.random() * (max - min);
}
function signedRand(min: real, max: real): real {
return rand(min, max) * (Math.random() < 0.5 ? -1 : 1);
}
Component.onCompleted: shapes.model = count
Repeater {
id: shapes
DriftingShape {
}
}
FrameAnimation {
running: root.visible && root.width > 0 && root.height > 0 && (Players.active?.isPlaying ?? false)
onTriggered: {
const dt = frameTime;
for (let i = 0; i < shapes.count; i++) {
const s = shapes.itemAt(i) as DriftingShape;
if (!s)
continue;
s.x += s.vx * dt;
s.y += s.vy * dt;
s.rotation += s.vr * dt;
if (s.x + s.width < 0)
s.x = root.width;
else if (s.x > root.width)
s.x = -s.width;
if (s.y + s.height < 0)
s.y = root.height;
else if (s.y > root.height)
s.y = -s.height;
}
}
}
component DriftingShape: MaterialShape {
id: shapeItem
readonly property int colorIdx: Math.floor(Math.random() * 4)
required property int index
property real vr: root.rand(root.minRotSpeed, root.maxRotSpeed)
property real vx: root.signedRand(root.minSpeed, root.maxSpeed)
property real vy: root.signedRand(root.minSpeed, root.maxSpeed)
color: [Colors.palette.m3primaryContainer, Colors.palette.m3secondaryContainer, Colors.palette.m3tertiaryContainer, Colors.palette.m3outlineVariant][colorIdx]
implicitSize: root.minSize + (index / root.count) * (root.maxSize - root.minSize)
opacity: Colors.light ? root.lightOpacities[colorIdx] : root.darkOpacities[colorIdx]
rotation: root.rand(0, 360)
shape: root.shapePool[Math.floor(Math.random() * root.shapePool.length)]
Behavior on color {
CAnim {
}
}
Behavior on opacity {
Anim {
type: Anim.SlowEffects
}
}
Component.onCompleted: {
x = root.rand(0, root.width - implicitSize);
y = root.rand(0, root.height - implicitSize);
}
}
}
-100
View File
@@ -1,100 +0,0 @@
pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Effects
import M3Shapes
import qs.Helpers
import qs.Effects
import qs.Components
import qs.Services
Item {
id: root
property color fallbackColor: Colors.layer(Colors.palette.m3surfaceContainerHighest, 2)
property bool hadPrevious
readonly property alias shape: shape
layer.enabled: true
Behavior on fallbackColor {
CAnim {
}
}
layer.effect: MultiEffect {
blurMax: 1
shadowColor: Colors.palette.m3outline
shadowEnabled: true
shadowOpacity: 0.3
}
Item {
id: shapeWrapper
anchors.fill: parent
layer.enabled: true
opacity: root.fallbackColor.a
MaterialShape {
id: shape
color: Qt.alpha(root.fallbackColor, 1)
implicitSize: root.width
shape: MaterialShape.Cookie12Sided
Anim on rotation {
duration: 23500
easing.type: Easing.Linear
from: 360
loops: Animation.Infinite
paused: !Players.active?.isPlaying
running: true
to: 0
}
}
}
MaterialIcon {
anchors.centerIn: parent
animate: true
color: Colors.palette.m3onSurfaceVariant
grade: 200
opacity: image.status === Image.Null || image.status === Image.Error ? 1 : 0
text: image.status === Image.Error ? "broken_image" : "art_track"
Behavior on opacity {
Anim {
type: Anim.DefaultEffects
}
}
}
Loader {
active: opacity > 0
anchors.centerIn: parent
asynchronous: true
opacity: image.status === Image.Loading ? 1 : 0
Behavior on opacity {
Anim {
type: Anim.DefaultEffects
}
}
sourceComponent: LoadingIndicator {
color: Colors.palette.m3primaryContainer
implicitSize: root.width * 0.3
}
}
FadeImage {
id: image
anchors.fill: parent
layer.enabled: true
source: Players.getArtUrl(Players.active)
layer.effect: Mask {
maskSource: shapeWrapper
}
}
}
@@ -1,18 +0,0 @@
pragma ComponentBehavior: Bound
import QtQuick
import M3Shapes
import ZShell.Config
Item {
id: root
CoverArt {
id: cover
anchors.centerIn: parent
implicitHeight: Config.dashboard.sizes.mediaCoverArtSize
implicitWidth: Config.dashboard.sizes.mediaCoverArtSize
shape.shape: MaterialShape.Cookie9Sided
}
}
+1 -1
View File
@@ -35,7 +35,7 @@ Item {
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: Tokens.padding.large
anchors.top: parent.top
spacing: Tokens.spacing.medium
spacing: Tokens.spacing.normal
Resource {
fgColor: Colors.palette.m3primary
+1 -1
View File
@@ -18,7 +18,7 @@ Row {
color: Colors.layer(Colors.palette.m3surfaceContainerHigh, 2)
implicitHeight: info.implicitHeight
implicitWidth: info.implicitHeight
radius: Tokens.rounding.small
radius: Tokens.rounding.smallest
MaterialIcon {
anchors.centerIn: parent
+1 -1
View File
@@ -27,7 +27,7 @@ Item {
id: info
anchors.left: icon.right
anchors.leftMargin: Tokens.spacing.largeIncreased
anchors.leftMargin: Tokens.spacing.large
anchors.verticalCenter: parent.verticalCenter
spacing: 8
+1 -1
View File
@@ -181,7 +181,7 @@ Item {
anchors.verticalCenter: parent.verticalCenter
color: "transparent"
implicitHeight: parent.height + 8 * 2
radius: Tokens.rounding.small
radius: Tokens.rounding.smallest
CustomRect {
id: stateLayer
+2 -12
View File
@@ -16,16 +16,9 @@ Item {
}
readonly property real nonAnimHeight: state === "visible" ? (content.item?.nonAnimHeight ?? 0) : 0
required property real offsetScale
required property string position
readonly property bool shouldBeActive: root.visibilities.dashboard && Config.dashboard.enabled
required property PersistentProperties visibilities
anchors.bottom: position === "bottom" ? parent.bottom : undefined
anchors.bottomMargin: position === "bottom" ? (-implicitHeight - 5) * offsetScale : 0
anchors.left: position === "left" ? parent.left : undefined
anchors.leftMargin: position === "left" ? (-implicitWidth - 5) * offsetScale : 0
anchors.top: position === "top" ? parent.top : undefined
anchors.topMargin: position === "top" ? (-implicitHeight - 5) * offsetScale : 0
implicitHeight: content.implicitHeight
implicitWidth: content.implicitWidth || 854
opacity: 1 - offsetScale
@@ -35,11 +28,8 @@ Item {
id: content
active: root.shouldBeActive || root.visible
anchors.bottom: root.position === "top" ? parent.bottom : undefined
anchors.horizontalCenter: root.position !== "left" ? parent.horizontalCenter : undefined
anchors.right: root.position !== "left" ? undefined : parent.right
anchors.top: root.position === "bottom" ? parent.top : undefined
anchors.verticalCenter: root.position === "left" ? undefined : parent.verticalCenter
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
sourceComponent: Content {
dashState: root.dashState
@@ -32,7 +32,7 @@ Item {
y: root.menuY
color: Colors.tPalette.m3surface
radius: Tokens.rounding.medium
radius: Tokens.rounding.normal
implicitWidth: menuLayout.implicitWidth + padding * 2
implicitHeight: menuLayout.implicitHeight + padding * 2
@@ -48,13 +48,13 @@ Item {
CustomRect {
Layout.preferredWidth: 200
radius: popupBackground.radius - popupBackground.padding
implicitHeight: openTerminalRow.implicitHeight + Tokens.padding.extraSmall * 2
implicitHeight: openTerminalRow.implicitHeight + Tokens.padding.small * 2
RowLayout {
id: openTerminalRow
spacing: 8
anchors.fill: parent
anchors.leftMargin: Tokens.padding.small
anchors.leftMargin: Tokens.padding.smaller
MaterialIcon { text: "terminal"; font.pointSize: 20 }
CustomText { text: "Open terminal"; Layout.fillWidth: true }
@@ -81,13 +81,13 @@ Item {
CustomRect {
Layout.fillWidth: true
radius: popupBackground.radius - popupBackground.padding
implicitHeight: settingsRow.implicitHeight + Tokens.padding.extraSmall * 2
implicitHeight: settingsRow.implicitHeight + Tokens.padding.small * 2
RowLayout {
id: settingsRow
spacing: 8
anchors.fill: parent
anchors.leftMargin: Tokens.padding.small
anchors.leftMargin: Tokens.padding.smaller
MaterialIcon { text: "settings"; font.pointSize: 20 }
CustomText { text: "ZShell settings"; Layout.fillWidth: true }
@@ -115,13 +115,13 @@ Item {
CustomRect {
Layout.fillWidth: true
radius: popupBackground.radius - popupBackground.padding
implicitHeight: logoutRow.implicitHeight + Tokens.padding.extraSmall * 2
implicitHeight: logoutRow.implicitHeight + Tokens.padding.small * 2
RowLayout {
id: logoutRow
spacing: 8
anchors.fill: parent
anchors.leftMargin: Tokens.padding.small
anchors.leftMargin: Tokens.padding.smaller
MaterialIcon { text: "logout"; font.pointSize: 20 }
CustomText { text: "Logout"; Layout.fillWidth: true }
@@ -148,13 +148,13 @@ Item {
// CustomRect {
// Layout.fillWidth: true
// radius: popupBackground.radius - popupBackground.padding
// implicitHeight: desktopIconsRow.implicitHeight + Tokens.padding.extraSmall * 2
// implicitHeight: desktopIconsRow.implicitHeight + Tokens.padding.small * 2
//
// RowLayout {
// id: desktopIconsRow
// spacing: 8
// anchors.fill: parent
// anchors.leftMargin: Tokens.padding.small
// anchors.leftMargin: Tokens.padding.smaller
//
// MaterialIcon { text: Config.options.background.showDesktopIcons ? "visibility_off" : "visibility"; font.pointSize: 20 }
// CustomText { text: Config.options.background.showDesktopIcons ? "Hide icons" : "Show icons"; Layout.fillWidth: true }
+12 -12
View File
@@ -43,13 +43,13 @@ Item {
CustomClippingRect {
id: popupBackground
readonly property real padding: Tokens.padding.extraSmall
readonly property real padding: Tokens.padding.small
color: Colors.tPalette.m3surface
implicitHeight: menuLayout.implicitHeight + padding * 2
implicitWidth: menuLayout.implicitWidth + padding * 2
opacity: contextMenu.visible ? 1 : 0
radius: Tokens.rounding.medium
radius: Tokens.rounding.normal
x: contextMenu.menuX
y: contextMenu.menuY
@@ -66,14 +66,14 @@ Item {
CustomRect {
Layout.preferredWidth: 160
implicitHeight: openRow.implicitHeight + Tokens.padding.extraSmall * 2
implicitHeight: openRow.implicitHeight + Tokens.padding.small * 2
radius: popupBackground.radius - popupBackground.padding
RowLayout {
id: openRow
anchors.fill: parent
anchors.leftMargin: Tokens.padding.small
anchors.leftMargin: Tokens.padding.smaller
spacing: 8
MaterialIcon {
@@ -109,14 +109,14 @@ Item {
CustomRect {
Layout.fillWidth: true
implicitHeight: openWithRow.implicitHeight + Tokens.padding.extraSmall * 2
implicitHeight: openWithRow.implicitHeight + Tokens.padding.small * 2
radius: popupBackground.radius - popupBackground.padding
RowLayout {
id: openWithRow
anchors.fill: parent
anchors.leftMargin: Tokens.padding.small
anchors.leftMargin: Tokens.padding.smaller
spacing: 8
MaterialIcon {
@@ -154,14 +154,14 @@ Item {
CustomRect {
Layout.fillWidth: true
implicitHeight: copyPathRow.implicitHeight + Tokens.padding.extraSmall * 2
implicitHeight: copyPathRow.implicitHeight + Tokens.padding.small * 2
radius: popupBackground.radius - popupBackground.padding
RowLayout {
id: copyPathRow
anchors.fill: parent
anchors.leftMargin: Tokens.padding.small
anchors.leftMargin: Tokens.padding.smaller
spacing: 8
MaterialIcon {
@@ -187,7 +187,7 @@ Item {
CustomRect {
Layout.fillWidth: true
implicitHeight: renameRow.implicitHeight + Tokens.padding.extraSmall * 2
implicitHeight: renameRow.implicitHeight + Tokens.padding.small * 2
radius: popupBackground.radius - popupBackground.padding
visible: contextMenu.targetPaths.length === 1
@@ -195,7 +195,7 @@ Item {
id: renameRow
anchors.fill: parent
anchors.leftMargin: Tokens.padding.small
anchors.leftMargin: Tokens.padding.smaller
spacing: 8
MaterialIcon {
@@ -229,14 +229,14 @@ Item {
CustomRect {
Layout.fillWidth: true
implicitHeight: deleteRow.implicitHeight + Tokens.padding.extraSmall * 2
implicitHeight: deleteRow.implicitHeight + Tokens.padding.small * 2
radius: popupBackground.radius - popupBackground.padding
RowLayout {
id: deleteRow
anchors.fill: parent
anchors.leftMargin: Tokens.padding.small
anchors.leftMargin: Tokens.padding.smaller
spacing: 8
MaterialIcon {
+2 -2
View File
@@ -205,7 +205,7 @@ Item {
anchors.margins: 4
color: "white"
opacity: root.iconsRoot.selectedIcons.includes(root.filePath) ? 0.2 : 0.0
radius: Tokens.rounding.small
radius: Tokens.rounding.smallest
Behavior on opacity {
Anim {
@@ -265,7 +265,7 @@ Item {
anchors.margins: 4
color: "white"
opacity: parent.containsMouse ? 0.1 : 0.0
radius: Tokens.rounding.small
radius: Tokens.rounding.smallest
Behavior on opacity {
Anim {
+4 -4
View File
@@ -22,10 +22,10 @@ Item {
property string draggedAppId: ""
property var draggedModelData: null
property bool dropAnimating: false
readonly property int padding: Tokens.padding.extraSmall
readonly property int padding: Tokens.padding.small
required property var panels
property var pendingCommitIds: []
readonly property int rounding: Tokens.rounding.largeIncreased
readonly property int rounding: Tokens.rounding.large
required property ShellScreen screen
required property PersistentProperties visibilities
property var visualIds: []
@@ -247,7 +247,7 @@ Item {
property bool enableAddAnimation: false
anchors.left: parent.left
anchors.margins: Tokens.padding.extraSmall
anchors.margins: Tokens.padding.small
anchors.top: parent.top
boundsBehavior: Flickable.StopAtBounds
height: Config.dock.height
@@ -255,7 +255,7 @@ Item {
interactive: !(root.dragActive || root.dropAnimating)
model: visualModel
orientation: ListView.Horizontal
spacing: Tokens.padding.small
spacing: Tokens.padding.smaller
add: Transition {
ParallelAnimation {
+1 -1
View File
@@ -23,7 +23,7 @@ CustomRect {
implicitHeight: Config.dock.height
implicitWidth: isSeparator ? 1 : implicitHeight
radius: Tokens.rounding.medium - Tokens.padding.extraSmall
radius: Tokens.rounding.normal - Tokens.padding.small
Loader {
active: !isSeparator
+2 -2
View File
@@ -5,9 +5,9 @@ import ZShell.Config
import qs.Services
CustomRect {
Layout.bottomMargin: dockRow.padding + Tokens.rounding.medium
Layout.bottomMargin: dockRow.padding + Tokens.rounding.normal
Layout.fillHeight: true
Layout.topMargin: dockRow.padding + Tokens.rounding.medium
Layout.topMargin: dockRow.padding + Tokens.rounding.normal
color: Colors.palette.m3outlineVariant
implicitWidth: 1
}
+1 -1
View File
@@ -24,7 +24,7 @@ Item {
Behavior on offsetScale {
Anim {
duration: Tokens.anim.durations.expressiveDefaultSpatial
easing: Tokens.anim.expressiveDefaultSpatial
easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial
}
}
+5 -5
View File
@@ -33,8 +33,8 @@ Item {
drawing.drawingState.penColor = Qt.hsva(huePicker.currentHue, saturationSlider.value, brightnessSlider.value, drawing.drawingState.penColor.a);
}
implicitHeight: column.height + Tokens.padding.small * 2
implicitWidth: huePicker.implicitWidth + Tokens.padding.small * 2
implicitHeight: column.height + Tokens.padding.larger * 2
implicitWidth: huePicker.implicitWidth + Tokens.padding.normal * 2
Component.onCompleted: syncFromPenColor()
@@ -97,7 +97,7 @@ Item {
anchors.left: parent.left
anchors.right: parent.right
spacing: Tokens.spacing.medium
spacing: Tokens.spacing.normal
Repeater {
model: root.colors1
@@ -113,7 +113,7 @@ Item {
anchors.left: parent.left
anchors.right: parent.right
spacing: Tokens.spacing.medium
spacing: Tokens.spacing.normal
Repeater {
model: root.colors2
@@ -172,7 +172,7 @@ Item {
}
IconButton {
anchors.margins: Tokens.padding.small
anchors.margins: Tokens.padding.normal
anchors.right: parent.right
anchors.top: parent.top
checked: root.wrapper.pinned
+2 -2
View File
@@ -49,13 +49,13 @@ Item {
Behavior on implicitWidth {
Anim {
duration: Tokens.anim.durations.expressiveDefaultSpatial
easing: Tokens.anim.expressiveDefaultSpatial
easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial
}
}
Behavior on offsetScale {
Anim {
duration: Tokens.anim.durations.expressiveDefaultSpatial
easing: Tokens.anim.expressiveDefaultSpatial
easing.bezierCurve: Tokens.anim.curves.expressiveDefaultSpatial
}
}
@@ -1,16 +1,17 @@
import QtQuick
import ZShell.Config
import qs.Components
import qs.Modules.Bar.Components.Common
import qs.Helpers
import ZShell.Config
import qs.Services
WidgetBase {
CustomRect {
id: root
property bool tempEnabled: Hyprsunset.enabled
color: root.tempEnabled ? Colors.palette.m3primary : Colors.tPalette.m3surfaceContainer
implicitHeight: Config.bar.height + Tokens.padding.smallest * 2
implicitWidth: implicitHeight
radius: Tokens.rounding.full
StateLayer {
@@ -25,7 +26,6 @@ WidgetBase {
animate: true
color: root.tempEnabled ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
fill: root.tempEnabled ? 1 : 0
font.pointSize: Tokens.font.size.larger
text: root.tempEnabled ? "lightbulb" : "light_off"
Behavior on fill {
+33 -84
View File
@@ -1,36 +1,28 @@
pragma ComponentBehavior: Bound
import QtQuick
import Quickshell
import ZShell.Config
import qs.Components
import qs.Services
import qs.Modules.Launcher.Items
import QtQuick
import qs.Modules.Launcher.Services
import qs.Modules.Launcher.Items
import qs.Components
import ZShell.Config
import qs.Services
CustomListView {
id: root
readonly property string displayState: stateForText(displayText)
property string displayText
readonly property string requestedState: stateForText(search.text)
required property SearchBar search
required property PersistentProperties visibilities
function resultsForText(text: string): var {
switch (stateForText(text)) {
case "actions":
return Actions.query(text);
case "calc":
return [0];
case "variant":
return SchemeVariants.query(text);
default:
return Apps.search(text);
}
}
function stateForText(text: string): string {
highlightFollowsCurrentItem: false
highlightRangeMode: ListView.ApplyRange
implicitHeight: (Config.launcher.sizes.itemHeight + spacing) * Math.min(Config.launcher.maxAppsShown, count) - spacing
orientation: Qt.Vertical
preferredHighlightBegin: 0
preferredHighlightEnd: height
spacing: Tokens.spacing.small
state: {
const text = search.text;
const prefix = Config.launcher.actionPrefix;
if (text.startsWith(prefix)) {
for (const action of ["calc", "scheme", "variant"])
@@ -42,20 +34,6 @@ CustomListView {
return "apps";
}
function syncDisplayText(): void {
if (visibilities.launcher && requestedState === displayState)
displayText = search.text;
}
highlightFollowsCurrentItem: false
highlightRangeMode: ListView.ApplyRange
implicitHeight: (Config.launcher.sizes.itemHeight + spacing) * Math.min(Config.launcher.maxAppsShown, count) - spacing
orientation: Qt.Vertical
preferredHighlightBegin: 0
preferredHighlightEnd: height
spacing: Tokens.spacing.small
state: visibilities.launcher ? requestedState : displayState
verticalLayoutDirection: ListView.BottomToTop
CustomScrollBar.vertical: CustomScrollBar {
@@ -66,21 +44,19 @@ CustomListView {
Anim {
from: 0
property: "opacity"
properties: "opacity,scale"
to: 1
type: Anim.DefaultEffects
}
}
addDisplaced: Transition {
Anim {
duration: Tokens.anim.durations.small
property: "y"
type: Anim.StandardSmall
}
Anim {
property: "opacity"
properties: "opacity,scale"
to: 1
type: Anim.DefaultEffects
}
}
displaced: Transition {
@@ -89,9 +65,8 @@ CustomListView {
}
Anim {
property: "opacity"
properties: "opacity,scale"
to: 1
type: Anim.DefaultEffects
}
}
highlight: CustomRect {
@@ -99,18 +74,18 @@ CustomListView {
implicitHeight: root.currentItem?.implicitHeight ?? 0
implicitWidth: root.width
opacity: 0.08
radius: Tokens.rounding.medium
radius: Tokens.rounding.smallest
y: root.currentItem?.y ?? 0
Behavior on y {
Anim {
duration: Tokens.anim.durations.small
easing: Tokens.anim.expressiveDefaultEffects
easing.bezierCurve: Tokens.anim.curves.expressiveEffects
}
}
}
model: ScriptModel {
values: root.resultsForText(root.displayText)
id: model
onValuesChanged: root.currentIndex = 0
}
@@ -120,9 +95,8 @@ CustomListView {
}
Anim {
property: "opacity"
properties: "opacity,scale"
to: 1
type: Anim.DefaultEffects
}
}
remove: Transition {
@@ -130,9 +104,8 @@ CustomListView {
Anim {
from: 1
property: "opacity"
properties: "opacity,scale"
to: 0
type: Anim.DefaultEffects
}
}
states: [
@@ -140,6 +113,7 @@ CustomListView {
name: "apps"
PropertyChanges {
model.values: Apps.search(search.text)
root.delegate: appItem
}
},
@@ -147,6 +121,7 @@ CustomListView {
name: "actions"
PropertyChanges {
model.values: Actions.query(search.text)
root.delegate: actionItem
}
},
@@ -154,6 +129,7 @@ CustomListView {
name: "calc"
PropertyChanges {
model.values: [0]
root.delegate: calcItem
}
},
@@ -161,6 +137,7 @@ CustomListView {
name: "variant"
PropertyChanges {
model.values: SchemeVariants.query(search.text)
root.delegate: variantItem
}
}
@@ -170,7 +147,7 @@ CustomListView {
ParallelAnimation {
Anim {
duration: Tokens.anim.durations.small
easing: Tokens.anim.standardAccel
easing.bezierCurve: Tokens.anim.curves.expressiveEffects
from: 1
property: "opacity"
target: root
@@ -179,7 +156,7 @@ CustomListView {
Anim {
duration: Tokens.anim.durations.small
easing: Tokens.anim.standardAccel
easing.bezierCurve: Tokens.anim.curves.expressiveEffects
from: 1
property: "scale"
target: root
@@ -188,24 +165,14 @@ CustomListView {
}
PropertyAction {
property: "delegate"
target: root
value: null
}
ScriptAction {
script: root.displayText = root.search.text
}
PropertyAction {
property: "delegate"
target: root
properties: "values,delegate"
targets: [model, root]
}
ParallelAnimation {
Anim {
duration: Tokens.anim.durations.small
easing: Tokens.anim.standardDecel
easing.bezierCurve: Tokens.anim.curves.expressiveEffects
from: 0
property: "opacity"
target: root
@@ -214,7 +181,7 @@ CustomListView {
Anim {
duration: Tokens.anim.durations.small
easing: Tokens.anim.standardDecel
easing.bezierCurve: Tokens.anim.curves.expressiveEffects
from: 0.9
property: "scale"
target: root
@@ -230,8 +197,6 @@ CustomListView {
}
}
Component.onCompleted: displayText = search.text
Component {
id: appItem
@@ -263,20 +228,4 @@ CustomListView {
list: root
}
}
Connections {
function onTextChanged() {
root.syncDisplayText();
}
target: root.search
}
Connections {
function onLauncherChanged() {
root.syncDisplayText();
}
target: root.visibilities
}
}
-53
View File
@@ -1,53 +0,0 @@
import Quickshell
import QtQuick
import ZShell.Components
import ZShell.Config
import qs.Modules.Launcher.Items
import qs.Components
import qs.Helpers
CarouselView {
id: root
required property var panels
readonly property var screen: QsWindow.window?.screen
required property SearchBar search
readonly property var values: Wallpapers.query(root.search.text.split(" ").slice(1).join(" "))
required property var visibilities
currentIndex: {
const idx = Wallpapers.list.findIndex(w => w.path === Wallpapers.actualCurrent);
return idx >= 0 ? idx : 0;
}
delegateProperties: ({
visibilities: root.visibilities
})
focalWidth: Config.launcher.sizes.wallpaperWidth
glideDuration: 250
glideEasingType: Easing.OutCubic
implicitHeight: tileHeight + Tokens.spacing.small / 2 + Tokens.padding.large + Tokens.padding.small
itemSpacing: Tokens.spacing.small
maxWidth: {
if (!screen)
return 0;
const barMargins = Config.bar.border * 2;
let margins = Math.round(screen.width / 6);
if (visibilities.utilities || visibilities.sidebar)
margins = Config.sidebar.sizes.width;
return screen.width - (barMargins + margins) * 2 - Config.bar.rounding * 4;
}
minEdgeWidth: 56
model: values
tileHeight: focalWidth / 16 * 9
delegate: Component {
WallpaperTile {
}
}
Component.onDestruction: Wallpapers.stopPreview()
onCurrentItemChanged: {
if (currentItem)
Wallpapers.preview(currentItem.modelData.path);
}
}
+5 -5
View File
@@ -12,9 +12,9 @@ Item {
id: root
required property real maxHeight
readonly property int padding: Tokens.padding.largeIncreased / 4
readonly property int padding: Tokens.padding.small
required property var panels
readonly property int rounding: Tokens.rounding.largeIncreased
readonly property int rounding: Tokens.rounding.large
required property PersistentProperties visibilities
implicitHeight: search.height + listWrapper.height + padding * 2
@@ -49,9 +49,9 @@ Item {
anchors.left: parent.left
anchors.margins: root.padding
anchors.right: parent.right
bottomPadding: Tokens.padding.medium
bottomPadding: Tokens.padding.larger
placeholderText: qsTr("Type \"%1\" for commands").arg(Config.launcher.actionPrefix)
topPadding: Tokens.padding.medium
topPadding: Tokens.padding.larger
Component.onCompleted: forceActiveFocus()
Keys.onDownPressed: list.currentList?.decrementCurrentIndex()
@@ -79,7 +79,7 @@ Item {
if (currentItem) {
if (list.showWallpapers) {
if (Colors.scheme === "dynamic" && currentItem.modelData.path !== Wallpapers.actualCurrent)
Wallpapers.previewColorLock = true;
Wallpapers.previewColourLock = true;
Wallpapers.setWallpaper(currentItem.modelData.path);
root.visibilities.launcher = false;
} else if (text.startsWith(Config.launcher.actionPrefix)) {
+5 -5
View File
@@ -32,7 +32,7 @@ Item {
Anim {
duration: Tokens.anim.durations.small
easing: Tokens.anim.expressiveDefaultEffects
easing.bezierCurve: Tokens.anim.curves.expressiveEffects
}
}
Behavior on implicitWidth {
@@ -40,7 +40,7 @@ Item {
Anim {
duration: Tokens.anim.durations.small
easing: Tokens.anim.expressiveDefaultEffects
easing.bezierCurve: Tokens.anim.curves.expressiveEffects
}
}
Behavior on state {
@@ -110,9 +110,9 @@ Item {
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
width: root.implicitWidth
sourceComponent: CarouselView {
sourceComponent: WallpaperList {
content: root.content
panels: root.panels
search: root.search
visibilities: root.visibilities
@@ -127,7 +127,7 @@ Item {
opacity: root.currentList?.count === 0 ? 1 : 0
padding: Tokens.padding.large
scale: root.currentList?.count === 0 ? 1 : 0.5
spacing: Tokens.spacing.medium
spacing: Tokens.spacing.normal
Behavior on opacity {
Anim {
+6 -6
View File
@@ -16,7 +16,7 @@ Item {
implicitHeight: Config.launcher.sizes.itemHeight
StateLayer {
radius: Tokens.rounding.small
radius: Tokens.rounding.smallest
onClicked: {
root.modelData?.onClicked(root.list);
@@ -25,9 +25,9 @@ Item {
Item {
anchors.fill: parent
anchors.leftMargin: Tokens.padding.small
anchors.margins: Tokens.padding.small
anchors.rightMargin: Tokens.padding.small
anchors.leftMargin: Tokens.padding.larger
anchors.margins: Tokens.padding.smaller
anchors.rightMargin: Tokens.padding.larger
MaterialIcon {
id: icon
@@ -39,7 +39,7 @@ Item {
Item {
anchors.left: icon.right
anchors.leftMargin: Tokens.spacing.medium
anchors.leftMargin: Tokens.spacing.normal
anchors.verticalCenter: icon.verticalCenter
implicitHeight: name.implicitHeight + desc.implicitHeight
implicitWidth: parent.width - icon.width
@@ -59,7 +59,7 @@ Item {
elide: Text.ElideRight
font.pointSize: Tokens.font.size.small
text: root.modelData?.desc ?? ""
width: root.width - icon.width - Tokens.rounding.medium * 2
width: root.width - icon.width - Tokens.rounding.normal * 2
}
}
}
+6 -6
View File
@@ -19,7 +19,7 @@ Item {
implicitHeight: Config.launcher.sizes.itemHeight
StateLayer {
radius: Tokens.rounding.small
radius: Tokens.rounding.smallest
onClicked: {
Apps.launch(root.modelData);
@@ -29,9 +29,9 @@ Item {
Item {
anchors.fill: parent
anchors.leftMargin: Tokens.padding.medium
anchors.margins: Tokens.padding.small
anchors.rightMargin: Tokens.padding.medium
anchors.leftMargin: Tokens.padding.larger
anchors.margins: Tokens.padding.smaller
anchors.rightMargin: Tokens.padding.larger
IconImage {
id: icon
@@ -43,7 +43,7 @@ Item {
Item {
anchors.left: icon.right
anchors.leftMargin: Tokens.spacing.medium
anchors.leftMargin: Tokens.spacing.normal
anchors.verticalCenter: icon.verticalCenter
implicitHeight: name.implicitHeight + comment.implicitHeight
implicitWidth: parent.width - icon.width
@@ -63,7 +63,7 @@ Item {
elide: Text.ElideRight
font.pointSize: Tokens.font.size.small
text: (root.modelData?.comment || root.modelData?.genericName || root.modelData?.name) ?? ""
width: root.width - icon.width - Tokens.rounding.medium - Tokens.padding.medium * 2
width: root.width - icon.width - Tokens.rounding.normal * 2
}
}
+8 -8
View File
@@ -24,7 +24,7 @@ Item {
implicitHeight: Config.launcher.sizes.itemHeight
StateLayer {
radius: Tokens.rounding.small
radius: Tokens.rounding.smallest
onClicked: {
root.onClicked();
@@ -33,10 +33,10 @@ Item {
RowLayout {
anchors.left: parent.left
anchors.margins: Tokens.padding.small
anchors.margins: Tokens.padding.larger
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
spacing: Tokens.spacing.medium
spacing: Tokens.spacing.normal
MaterialIcon {
Layout.alignment: Qt.AlignVCenter
@@ -64,13 +64,13 @@ Item {
Layout.alignment: Qt.AlignVCenter
clip: true
color: Colors.palette.m3tertiary
implicitHeight: Math.max(label.implicitHeight, icon.implicitHeight) + Tokens.padding.extraSmall * 2
implicitWidth: (stateLayer.containsMouse ? label.implicitWidth + label.anchors.rightMargin : 0) + icon.implicitWidth + Tokens.padding.small * 2
radius: Tokens.rounding.medium
implicitHeight: Math.max(label.implicitHeight, icon.implicitHeight) + Tokens.padding.small * 2
implicitWidth: (stateLayer.containsMouse ? label.implicitWidth + label.anchors.rightMargin : 0) + icon.implicitWidth + Tokens.padding.normal * 2
radius: Tokens.rounding.normal
Behavior on implicitWidth {
Anim {
easing: Tokens.anim.expressiveDefaultEffects
easing.bezierCurve: Tokens.anim.curves.expressiveEffects
}
}
@@ -106,7 +106,7 @@ Item {
id: icon
anchors.right: parent.right
anchors.rightMargin: Tokens.padding.small
anchors.rightMargin: Tokens.padding.normal
anchors.verticalCenter: parent.verticalCenter
color: Colors.palette.m3onTertiary
font.pointSize: Tokens.font.size.large

Some files were not shown because too many files have changed in this diff Show More