213 changed files with 3020 additions and 1198 deletions
+1 -1
View File
@@ -18,7 +18,7 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Install Docker CLI - name: Install Docker CLI
run: apk add --no-cache docker-cli docker-cli-buildx run: apk add --no-cache docker-cli
- name: Login to registry - name: Login to registry
run: echo "${{ secrets.REGISTRY_TOKEN }}" | docker login git.aramjonghu.dev --username aramjonghu --password-stdin run: echo "${{ secrets.REGISTRY_TOKEN }}" | docker login git.aramjonghu.dev --username aramjonghu --password-stdin
+20 -21
View File
@@ -17,47 +17,46 @@ jobs:
run: | run: |
find . \( -name '*.cpp' -o -name '*.h' -o -name '*.hpp' \) \ find . \( -name '*.cpp' -o -name '*.h' -o -name '*.hpp' \) \
-not -path './build/*' \ -not -path './build/*' \
-exec clang-format --dry-run -Werror --style=file {} + -exec clang-format -i --style=file {} +
git diff --exit-code && echo "clang-format: passed"
build & lint: build:
runs-on: alpine runs-on: alpine
container: container:
image: git.aramjonghu.dev/aramjonghu/zshell-ci:latest image: git.aramjonghu.dev/aramjonghu/zshell-ci:latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Cache CMake build - name: Configure
uses: actions/cache@v4 run: cmake -B build -G Ninja -DENABLE_MODULES=plugin -DCMAKE_BUILD_TYPE=Release
with:
path: build
key: cpp-build-${{ hashFiles('CMakeLists.txt', '**/CMakeLists.txt') }}
restore-keys: |
cpp-build-
- name: Cache ccache - name: Build
uses: actions/cache@v4 run: ninja -C build
clang-tidy:
runs-on: alpine
container:
image: git.aramjonghu.dev/aramjonghu/zshell-ci:latest
steps:
- name: Checkout
uses: actions/checkout@v4
with: with:
path: ~/.ccache fetch-depth: 0
key: ccache-${{ runner.os }}-${{ github.sha }}
restore-keys: |
ccache-${{ runner.os }}-
- name: Configure - name: Configure
run: cmake -B build -G Ninja -DENABLE_MODULES=plugin -DCMAKE_BUILD_TYPE=Release run: cmake -B build -G Ninja -DENABLE_MODULES=plugin -DCMAKE_BUILD_TYPE=Release
- name: Build - name: Build
run: ninja -C build run: ninja -C build
env:
CMAKE_CXX_COMPILER_LAUNCHER: ccache
- name: clang-tidy - name: clang-tidy
run: | run: |
sed -i 's/-mno-direct-extern-access //g' build/compile_commands.json sed -i 's/-mno-direct-extern-access //g' build/compile_commands.json
set -o pipefail set -o pipefail
run-clang-tidy -p build -j "$(nproc)" \ run-clang-tidy -p build -j $(nproc) -header-filter="Plugins/.*" 2>&1 | \
-source-filter="^$(pwd)/Plugins/" \ grep -v 'Suppressed\|non-user\|non-system\|unknown argument.*mno-direct\|Found compiler error\|warnings generated\.\|^Use -header-filter'
-header-filter=".*Plugins/.*" \
-removed-arg=-mno-direct-extern-access
+15 -1
View File
@@ -4,7 +4,7 @@ on:
pull_request: pull_request:
jobs: jobs:
fmt & lint: fmt:
runs-on: alpine runs-on: alpine
container: node:26-alpine container: node:26-alpine
@@ -24,6 +24,20 @@ jobs:
else else
echo "No JS/TS files found" echo "No JS/TS files found"
fi fi
lint:
runs-on: alpine
container: node:26-alpine
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install tools
run: |
apk add --no-cache \
git
- name: ESLint - name: ESLint
run: | run: |
if [ -n "$(find . \( -iname "*.js" -o -iname "*.jsx" -o -iname "*.ts" -o -iname "*.tsx" -o -iname "*.mjs" -o -iname "*.cjs" \) -print -quit)" ]; then if [ -n "$(find . \( -iname "*.js" -o -iname "*.jsx" -o -iname "*.ts" -o -iname "*.tsx" -o -iname "*.mjs" -o -iname "*.cjs" \) -print -quit)" ]; then
+3 -3
View File
@@ -7,7 +7,7 @@ on:
pull_request: pull_request:
jobs: jobs:
fmt & lint: static:
runs-on: debian runs-on: debian
container: node:26-trixie-slim container: node:26-trixie-slim
@@ -33,7 +33,7 @@ jobs:
. .venv/bin/activate . .venv/bin/activate
ruff check . ruff check .
test & nuitka build: verify:
if: always() if: always()
runs-on: debian runs-on: debian
container: node:26-trixie-slim container: node:26-trixie-slim
@@ -64,4 +64,4 @@ jobs:
- name: Nuitka module check - name: Nuitka module check
run: | run: |
. .venv/bin/activate . .venv/bin/activate
nuitka --module --include-package=zshell cli/src/zshell/ nuitka --module --include-package=zshell cli/src/zshell/
+99 -11
View File
@@ -4,9 +4,9 @@ on:
pull_request: pull_request:
jobs: jobs:
clippy & fmt: build:
runs-on: alpine runs-on: alpine
container: node:26-alpine # keep node image for checkout to work container: node:26-alpine
env: env:
CARGO_HOME: ${{ github.workspace }}/.cargo CARGO_HOME: ${{ github.workspace }}/.cargo
@@ -16,29 +16,34 @@ jobs:
- name: Cache cargo packages - name: Cache cargo packages
uses: actions/cache@v4 uses: actions/cache@v4
env:
cache-name: cache-cargo-packages
with: with:
path: | path: |
.cargo/registry .cargo/registry
.cargo/git .cargo/git
target target
key: rust-build-${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} key: rust-build-${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('**/Cargo.lock') }}
restore-keys: | restore-keys: |
rust-${{ runner.os }}-cargo- rust-${{ runner.os }}-build-${{ env.cache-name }}-
rust-${{ runner.os }}-build-
rust-
- name: Install tools - name: Install tools
run: | run: |
apk add --no-cache git cargo rust rust-clippy rustfmt apk add --no-cache \
git \
cargo \
rust
- name: Clippy (with compile check) - name: Cargo check
run: | run: |
if [ -n "$(find . -name "Cargo.toml" -print -quit)" ]; then if [ -n "$(find . -name "Cargo.toml" -print -quit)" ]; then
status=0
for manifest in $(find . -name "Cargo.toml"); do for manifest in $(find . -name "Cargo.toml"); do
cargo clippy --manifest-path "$manifest" -- -D warnings && \ cargo check --manifest-path "$manifest" && \
echo "$manifest: Clippy passed" || \ echo "$manifest: check passed" || \
{ echo "$manifest: Clippy failed"; status=1; } { echo "$manifest: check failed"; exit 1; }
done done
exit $status
elif [ -n "$(find . -name "*.rs" -print -quit)" ]; then elif [ -n "$(find . -name "*.rs" -print -quit)" ]; then
echo "Rust files found but no Cargo.toml" echo "Rust files found but no Cargo.toml"
exit 1 exit 1
@@ -46,6 +51,39 @@ jobs:
echo "No Rust project found" echo "No Rust project found"
fi fi
fmt:
runs-on: alpine
container: node:26-alpine
env:
CARGO_HOME: ${{ github.workspace }}/.cargo
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Cache cargo packages
uses: actions/cache@v4
env:
cache-name: cache-cargo-packages
with:
path: |
.cargo/registry
.cargo/git
target
key: rust-fmt-${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
rust-${{ runner.os }}-build-${{ env.cache-name }}-
rust-${{ runner.os }}-build-
rust-
- name: Install tools
run: |
apk add --no-cache \
git \
cargo \
rust \
rustfmt
- name: Format check - name: Format check
run: | run: |
if [ -n "$(find . -name "Cargo.toml" -print -quit)" ]; then if [ -n "$(find . -name "Cargo.toml" -print -quit)" ]; then
@@ -62,3 +100,53 @@ jobs:
else else
echo "No Rust project found" echo "No Rust project found"
fi fi
clippy:
runs-on: alpine
container: node:26-alpine
env:
CARGO_HOME: ${{ github.workspace }}/.cargo
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Cache cargo packages
uses: actions/cache@v4
env:
cache-name: cache-cargo-packages
with:
path: |
.cargo/registry
.cargo/git
target
key: rust-clippy-${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
rust-${{ runner.os }}-build-${{ env.cache-name }}-
rust-${{ runner.os }}-build-
rust-
- name: Install tools
run: |
apk add --no-cache \
git \
cargo \
rust \
rust-clippy
- name: Clippy
run: |
if [ -n "$(find . -name "Cargo.toml" -print -quit)" ]; then
status=0
for manifest in $(find . -name "Cargo.toml"); do
cargo clippy --manifest-path "$manifest" --all-targets --all-features -- -D warnings && \
echo "$manifest: Clippy passed" || \
{ echo "$manifest: Clippy failed"; status=1; }
done
exit $status
elif [ -n "$(find . -name "*.rs" -print -quit)" ]; then
echo "Rust files found but no Cargo.toml"
exit 1
else
echo "No Rust project found"
fi
+10 -22
View File
@@ -1,35 +1,23 @@
**/__pycache__/
./result/ ./result/
.pyre/ .pyre/
.cache/
.venv/
.qmlls.ini
build/
compile_commands.json
testpython
pkg/ pkg/
*.tar.* *.tar.*
uv.lock
.qtcreator/
dist/ dist/
**/target/ **/target/
**/test-plugins/ **/test-plugins/
**/Charts/ **/Charts/
network-dev/ network-dev/
**/zshell.dist/
# Qml
.qtcreator/
.qmlls.ini
# CMake compile artifacts
.cache/
compile_commands.json
build/
# Python
uv.lock
testpython
.venv/
**/__pycache__/
# Nuitka compile
**/zshell.pyi
**/zshell.cpython-*
**/zshell.build/ **/zshell.build/
**/zshell.dist/
# Agents stuff
.opencode/ .opencode/
run-agent.sh run-agent.sh
AGENTS.md AGENTS.md
+4 -2
View File
@@ -46,7 +46,8 @@ Item {
strokeWidth: Math.min(1, remainingArc.sweepAngle) * root.strokeWidth strokeWidth: Math.min(1, remainingArc.sweepAngle) * root.strokeWidth
Behavior on strokeColor { Behavior on strokeColor {
CAnim {} CAnim {
}
} }
PathAngleArc { PathAngleArc {
@@ -83,7 +84,8 @@ Item {
} }
} }
Behavior on color { Behavior on color {
CAnim {} CAnim {
}
} }
Anim on waveProgress { Anim on waveProgress {
id: waveProgAnim id: waveProgAnim
+2 -1
View File
@@ -160,7 +160,8 @@ Item {
Behavior on color { Behavior on color {
enabled: false enabled: false
CAnim {} CAnim {
}
} }
} }
+2 -1
View File
@@ -8,6 +8,7 @@ MultiEffect {
colorization: 1 colorization: 1
Behavior on colorizationColor { Behavior on colorizationColor {
CAnim {} CAnim {
}
} }
} }
+2 -1
View File
@@ -7,6 +7,7 @@ ClippingRectangle {
color: "transparent" color: "transparent"
Behavior on color { Behavior on color {
CAnim {} CAnim {
}
} }
} }
+2 -1
View File
@@ -7,6 +7,7 @@ ClippingWrapperRectangle {
color: "transparent" color: "transparent"
Behavior on color { Behavior on color {
CAnim {} CAnim {
}
} }
} }
+1
View File
@@ -99,6 +99,7 @@ ProgressBar {
} }
Line { Line {
id: dot
property real implicitSize property real implicitSize
anchors.right: parent.right anchors.right: parent.right
+6 -6
View File
@@ -2,10 +2,10 @@ pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Templates import QtQuick.Templates
import ZShell.Components
import ZShell import ZShell
import qs.Components import ZShell.Components
import ZShell.Config import ZShell.Config
import qs.Components
import qs.Services import qs.Services
Slider { Slider {
@@ -28,7 +28,7 @@ Slider {
signal interaction(v: real) signal interaction(v: real)
implicitHeight: 12 implicitHeight: ZUtils.snap(12, root)
implicitWidth: 200 implicitWidth: 200
contentItem: Item { contentItem: Item {
@@ -123,7 +123,7 @@ Slider {
bottomRightRadius: Tokens.rounding.extraSmall / 2 bottomRightRadius: Tokens.rounding.extraSmall / 2
color: root.fgColor color: root.fgColor
implicitHeight: root.height implicitHeight: root.height
implicitWidth: root.filledWidth implicitWidth: ZUtils.snap(root.filledWidth, root)
radius: root.radius radius: root.radius
topRightRadius: Tokens.rounding.extraSmall / 2 topRightRadius: Tokens.rounding.extraSmall / 2
} }
@@ -137,8 +137,8 @@ Slider {
frequency: root.waveFrequency frequency: root.waveFrequency
fullLength: root.width - handle.implicitWidth - handle.anchors.leftMargin fullLength: root.width - handle.implicitWidth - handle.anchors.leftMargin
implicitHeight: lineWidth * amplitudeMultiplier * 2 + lineWidth implicitHeight: lineWidth * amplitudeMultiplier * 2 + lineWidth
implicitWidth: root.filledWidth implicitWidth: ZUtils.snap(root.filledWidth, root)
lineWidth: root.height * 0.7 lineWidth: ZUtils.snap(root.height * 0.7, root)
startX: x startX: x
Behavior on color { Behavior on color {
+10 -5
View File
@@ -105,16 +105,20 @@ Switch {
width: height width: height
Behavior on end1 { Behavior on end1 {
PropAnim {} PropAnim {
}
} }
Behavior on end2 { Behavior on end2 {
PropAnim {} PropAnim {
}
} }
Behavior on start1 { Behavior on start1 {
PropAnim {} PropAnim {
}
} }
Behavior on start2 { Behavior on start2 {
PropAnim {} PropAnim {
}
} }
ShapePath { ShapePath {
@@ -130,7 +134,8 @@ Switch {
strokeWidth: 16 * 0.15 strokeWidth: 16 * 0.15
Behavior on strokeColor { Behavior on strokeColor {
CAnim {} CAnim {
}
} }
PathLine { PathLine {
+4 -2
View File
@@ -20,7 +20,8 @@ Text {
textFormat: Text.PlainText textFormat: Text.PlainText
Behavior on color { Behavior on color {
CAnim {} CAnim {
}
} }
Behavior on text { Behavior on text {
enabled: root.animate enabled: root.animate
@@ -32,7 +33,8 @@ Text {
type: Anim.FastEffects type: Anim.FastEffects
} }
PropertyAction {} PropertyAction {
}
TAnim { TAnim {
target: root target: root
+2 -1
View File
@@ -65,7 +65,8 @@ Image {
value: root.source value: root.source
} }
PropertyAction {} PropertyAction {
}
ScriptAction { ScriptAction {
script: root.maybeStartInAnim() script: root.maybeStartInAnim()
+3 -2
View File
@@ -1,4 +1,5 @@
import QtQuick import QtQuick
import ZShell
import ZShell.Config import ZShell.Config
import qs.Services import qs.Services
@@ -15,9 +16,9 @@ ButtonBase {
const h = label.implicitHeight + padding * 2; const h = label.implicitHeight + padding * 2;
if (h % 2 !== 0) if (h % 2 !== 0)
return h + 1; return h + 1;
return h; return ZUtils.snap(h, root);
} }
implicitWidth: implicitHeight implicitWidth: ZUtils.snap(implicitHeight, root)
inactiveColor: { inactiveColor: {
if (!isToggle && type === IconButton.Filled) if (!isToggle && type === IconButton.Filled)
return Colors.palette.m3primary; return Colors.palette.m3primary;
+3 -1
View File
@@ -1,5 +1,6 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import ZShell.Config import ZShell.Config
import qs.Services import qs.Services
@@ -34,10 +35,11 @@ ButtonBase {
} }
verticalPadding: Tokens.padding.extraSmall verticalPadding: Tokens.padding.extraSmall
RowLayout { SnapLayout {
id: row id: row
anchors.centerIn: parent anchors.centerIn: parent
spacing: Tokens.spacing.small spacing: Tokens.spacing.small
MaterialIcon { MaterialIcon {
+85 -65
View File
@@ -1,6 +1,8 @@
pragma ComponentBehavior: Bound pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtCanvas2D
import ZShell
Item { Item {
id: root id: root
@@ -36,54 +38,62 @@ Item {
property real fillAlpha: 0.15 property real fillAlpha: 0.15
property real lineWidth: 2 property real lineWidth: 2
property real markerDotRadius: 4 property real markerDotRadius: 4
property real labelFontSize: 10 property real labelFontSize: 8
Canvas { Canvas2D {
id: canvas id: canvas
anchors.fill: parent anchors.fill: parent
renderStrategy: Canvas.Immediate
alphaBlending: true
fillColor: "transparent"
onWidthChanged: requestPaint() onWidthChanged: requestPaint()
onHeightChanged: requestPaint() onHeightChanged: requestPaint()
function snapV(v) {
return ZUtils.snap(v, canvas);
}
function strokeCurve(ctx, pts) { function strokeCurve(ctx, pts) {
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(pts[0].x, pts[0].y); ctx.moveTo(pts[0].x, pts[0].y);
if (root.curveSmoothing && pts.length > 2) { const dpr = ZUtils.dprFor(canvas);
const k = 1 / 6; for (let i = 0; i < pts.length - 1; i++) {
const n = pts.length; const p1 = pts[i];
const p2 = pts[i + 1];
const [c1x, c1y, c2x, c2y] = segmentControls(pts, i);
for (let i = 0; i < n - 1; i++) { const firstCol = Math.ceil(p1.x * dpr) + 1;
const p0 = pts[Math.max(i - 1, 0)]; const lastCol = Math.floor(p2.x * dpr) - 1;
const p1 = pts[i]; for (let col = firstCol; col <= lastCol; ++col) {
const p2 = pts[i + 1]; const x = col / dpr;
const p3 = pts[Math.min(i + 2, n - 1)]; ctx.lineTo(x, bezierY(p1, c1x, c1y, c2x, c2y, p2, x));
let c1x = p1.x + (p2.x - p0.x) * k;
let c1y = p1.y + (p2.y - p0.y) * k;
let c2x = p2.x - (p3.x - p1.x) * k;
let c2y = p2.y - (p3.y - p1.y) * k;
const minY = Math.min(p1.y, p2.y);
const maxY = Math.max(p1.y, p2.y);
c1y = Math.max(minY, Math.min(maxY, c1y));
c2y = Math.max(minY, Math.min(maxY, c2y));
ctx.bezierCurveTo(c1x, c1y, c2x, c2y, p2.x, p2.y);
}
} else {
for (let i = 0; i < pts.length - 1; i++) {
const p0 = pts[i];
const p1 = pts[i + 1];
const cx = (p0.x + p1.x) * 0.5;
ctx.bezierCurveTo(cx, p0.y, cx, p1.y, p1.x, p1.y);
} }
ctx.lineTo(p2.x, p2.y);
} }
} }
// Control points for segment i (pts[i] -> pts[i+1]), matching strokeCurve function bezierY(p1, c1x, c1y, c2x, c2y, p2, targetX) {
let tlo = 0;
let thi = 1;
for (let it = 0; it < 16; it++) {
const tm = (tlo + thi) / 2;
const u = 1 - tm;
const x = u * u * u * p1.x + 3 * u * u * tm * c1x + 3 * u * tm * tm * c2x + tm * tm * tm * p2.x;
if (x < targetX)
tlo = tm;
else
thi = tm;
}
const t = (tlo + thi) / 2;
const u = 1 - t;
return u * u * u * p1.y + 3 * u * u * t * c1y + 3 * u * t * t * c2y + t * t * t * p2.y;
}
function segmentControls(pts, i) { function segmentControls(pts, i) {
const p0 = pts[Math.max(i - 1, 0)]; const p0 = pts[Math.max(i - 1, 0)];
const p1 = pts[i]; const p1 = pts[i];
@@ -109,7 +119,6 @@ Item {
return [cx, p1.y, cx, p2.y]; return [cx, p1.y, cx, p2.y];
} }
// Point on the curve at a given x (x is monotonic per segment)
function pointAtX(pts, targetX) { function pointAtX(pts, targetX) {
let j = pts.length - 2; let j = pts.length - 2;
for (let i = 0; i < pts.length - 1; i++) { for (let i = 0; i < pts.length - 1; i++) {
@@ -144,7 +153,10 @@ Item {
}; };
} }
// Part of the curve left/right of a cut x, including the cut point function cutPoint(pts, targetX) {
return pointAtX(pts, targetX);
}
function cutLeft(pts, targetX) { function cutLeft(pts, targetX) {
if (targetX <= pts[0].x) if (targetX <= pts[0].x)
return []; return [];
@@ -161,7 +173,7 @@ Item {
const left = pts.slice(0, j + 1); const left = pts.slice(0, j + 1);
if (targetX > pts[j].x) if (targetX > pts[j].x)
left.push(pointAtX(pts, targetX)); left.push(cutPoint(pts, targetX));
return left; return left;
} }
@@ -187,17 +199,20 @@ Item {
onPaint: { onPaint: {
const ctx = getContext("2d"); const ctx = getContext("2d");
if (!ctx)
return;
ctx.reset(); ctx.reset();
ctx.clearRect(0, 0, width, height);
const W = width; const W = width;
const H = height; const H = height;
if (W < 2 || H < 2) if (W < 2 || H < 2)
return; return;
const padLeft = root.labelFontSize * 3.4; const padLeft = root.labelFontSize * 5;
const padRight = 2; const padRight = 0;
const padTop = 2; const padTop = 0;
const padBottom = root.labelFontSize + 8; const padBottom = root.labelFontSize + 14;
const plot = { const plot = {
x: padLeft, x: padLeft,
y: padTop, y: padTop,
@@ -207,8 +222,6 @@ Item {
if (plot.w < 2 || plot.h < 2) if (plot.w < 2 || plot.h < 2)
return; return;
// Auto-fit: NaN yMin/yMax derive from the data, snapped to the
// horizontal step grid, honoring minHorizontalLines
let lo = root.yMin; let lo = root.yMin;
let hi = root.yMax; let hi = root.yMax;
const loAuto = Number.isNaN(lo); const loAuto = Number.isNaN(lo);
@@ -282,11 +295,17 @@ Item {
const xAt = i => plot.x + (i / root.xSteps) * plot.w; const xAt = i => plot.x + (i / root.xSteps) * plot.w;
const yAt = v => plot.y + (1 - (v - scaleBottom) / range) * plot.h; const yAt = v => plot.y + (1 - (v - scaleBottom) / range) * plot.h;
const crisp = v => Math.floor(v) + 0.5;
// 1. Grid lines const dpr = ZUtils.dprFor(canvas);
const devW = w => Math.max(1, Math.round(w * dpr));
const snapLine = (v, w) => {
const dw = devW(w);
return (Math.round(v * dpr - dw / 2) + dw / 2) / dpr;
};
const gridW = devW(1) / dpr;
ctx.strokeStyle = Qt.alpha(root.gridColor, root.gridAlpha); ctx.strokeStyle = Qt.alpha(root.gridColor, root.gridAlpha);
ctx.lineWidth = 1; ctx.lineWidth = gridW;
if (root.verticalLineStep > 0) { if (root.verticalLineStep > 0) {
for (let i = 0; i <= root.xSteps; i += root.verticalLineStep) { for (let i = 0; i <= root.xSteps; i += root.verticalLineStep) {
@@ -295,7 +314,7 @@ Item {
if (i === root.xSteps && !root.lastXLine) if (i === root.xSteps && !root.lastXLine)
continue; continue;
const x = crisp(xAt(i)); const x = snapLine(xAt(i), 1);
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(x, plot.y); ctx.moveTo(x, plot.y);
ctx.lineTo(x, H); ctx.lineTo(x, H);
@@ -303,12 +322,11 @@ Item {
} }
} }
// Lines extend down into yPaddingBottom, snapped to the grid
const vStart = lo - (root.yPaddingBottom > 0 ? Math.floor(root.yPaddingBottom / root.horizontalLineStep) * root.horizontalLineStep : 0); const vStart = lo - (root.yPaddingBottom > 0 ? Math.floor(root.yPaddingBottom / root.horizontalLineStep) * root.horizontalLineStep : 0);
if (root.horizontalLineStep > 0) { if (root.horizontalLineStep > 0) {
for (let v = vStart; v <= hi + 0.001; v += root.horizontalLineStep) { for (let v = vStart; v <= hi + 0.001; v += root.horizontalLineStep) {
const y = crisp(yAt(v)); const y = snapLine(yAt(v), 1);
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(0, y); ctx.moveTo(0, y);
ctx.lineTo(plot.x + plot.w, y); ctx.lineTo(plot.x + plot.w, y);
@@ -316,9 +334,8 @@ Item {
} }
} }
// 2. Labels
ctx.fillStyle = Qt.alpha(root.labelColor, root.labelAlpha); ctx.fillStyle = Qt.alpha(root.labelColor, root.labelAlpha);
ctx.font = root.labelFontSize + "px sans-serif"; ctx.font = root.labelFontSize + "pt 'sans-serif'";
ctx.textAlign = "left"; ctx.textAlign = "left";
ctx.textBaseline = "top"; ctx.textBaseline = "top";
@@ -331,7 +348,7 @@ Item {
const text = root.xLabel(i); const text = root.xLabel(i);
if (text) if (text)
ctx.fillText(text, xAt(i) + 4, plot.y + plot.h + 4); ctx.fillText(text, xAt(i) + 4, plot.y + plot.h + 8);
} }
} }
@@ -344,7 +361,6 @@ Item {
} }
} }
// 3. Curve, split into segments at null gaps
const segments = []; const segments = [];
let current = null; let current = null;
for (let i = 0; i < series.length; i++) { for (let i = 0; i < series.length; i++) {
@@ -355,7 +371,7 @@ Item {
continue; continue;
} }
const pt = { const pt = {
x: xAt(i), x: snapV(xAt(i)),
y: yAt(series[i]) y: yAt(series[i])
}; };
if (!current) if (!current)
@@ -372,8 +388,6 @@ Item {
const markerPx = hasMarker ? xAt(root.markerX) : 0; const markerPx = hasMarker ? xAt(root.markerX) : 0;
let gapPx = 0; let gapPx = 0;
if (hasMarker) { if (hasMarker) {
// markerGap is measured from the dot edge, perpendicular to the
// curve; project onto x via the local curve slope
let slope = 0; let slope = 0;
const seg = segments.find(s => s[0].x <= markerPx && markerPx <= s[s.length - 1].x); const seg = segments.find(s => s[0].x <= markerPx && markerPx <= s[s.length - 1].x);
if (seg && seg.length > 2 && markerPx - 1 >= seg[0].x && markerPx + 1 <= seg[seg.length - 1].x) if (seg && seg.length > 2 && markerPx - 1 >= seg[0].x && markerPx + 1 <= seg[seg.length - 1].x)
@@ -385,7 +399,6 @@ Item {
if (seg.length < 2) if (seg.length < 2)
continue; continue;
// Fill stays continuous under the marker
ctx.fillStyle = Qt.alpha(root.lineColor, root.fillAlpha); ctx.fillStyle = Qt.alpha(root.lineColor, root.fillAlpha);
strokeCurve(ctx, seg); strokeCurve(ctx, seg);
ctx.lineTo(seg[seg.length - 1].x, plot.y + plot.h); ctx.lineTo(seg[seg.length - 1].x, plot.y + plot.h);
@@ -393,7 +406,6 @@ Item {
ctx.closePath(); ctx.closePath();
ctx.fill(); ctx.fill();
// Stroke has a gap around the marker
const pieces = hasMarker ? [cutLeft(seg, markerPx - gapPx), cutRight(seg, markerPx + gapPx)] : [seg]; const pieces = hasMarker ? [cutLeft(seg, markerPx - gapPx), cutRight(seg, markerPx + gapPx)] : [seg];
for (const pts of pieces) { for (const pts of pieces) {
@@ -401,24 +413,32 @@ Item {
continue; continue;
ctx.strokeStyle = root.lineColor; ctx.strokeStyle = root.lineColor;
ctx.lineWidth = root.lineWidth; ctx.lineWidth = ZUtils.snap(root.lineWidth, root);
strokeCurve(ctx, pts); strokeCurve(ctx, pts);
ctx.stroke(); ctx.stroke();
} }
} }
// 4. Marker: dashed vertical + dot
if (root.markerX >= 0 && root.markerX <= root.xSteps) { if (root.markerX >= 0 && root.markerX <= root.xSteps) {
const x = markerPx; const x = markerPx;
ctx.setLineDash([4, 4]);
ctx.strokeStyle = Qt.alpha(root.markerColor, 0.6); ctx.strokeStyle = Qt.alpha(root.markerColor, 0.6);
ctx.lineWidth = 1; ctx.lineWidth = gridW;
ctx.beginPath(); const lineX = snapLine(x, 1);
ctx.moveTo(crisp(x), plot.y); let dashY = plot.y;
ctx.lineTo(crisp(x), H); let dashOn = true;
ctx.stroke();
ctx.setLineDash([]); while (dashY < H) {
const dashEnd = Math.min(dashY + 4, H);
if (dashOn) {
ctx.beginPath();
ctx.moveTo(lineX, snapV(dashY));
ctx.lineTo(lineX, snapV(dashEnd));
ctx.stroke();
}
dashY = dashEnd;
dashOn = !dashOn;
}
const i0 = Math.floor(root.markerX); const i0 = Math.floor(root.markerX);
const v0 = series[i0]; const v0 = series[i0];
@@ -433,7 +453,7 @@ Item {
if (y != null) { if (y != null) {
ctx.fillStyle = root.markerColor; ctx.fillStyle = root.markerColor;
ctx.beginPath(); ctx.beginPath();
ctx.arc(x, y, root.markerDotRadius, 0, Math.PI * 2); ctx.circle(snapV(x), y, root.markerDotRadius);
ctx.fill(); ctx.fill();
} }
} }
+2 -1
View File
@@ -64,7 +64,8 @@ MaterialShape {
to: 360 to: 360
} }
Behavior on color { Behavior on color {
CAnim {} CAnim {
}
} }
ElapsedTimer { ElapsedTimer {
+4 -2
View File
@@ -47,10 +47,12 @@ Item {
implicitWidth: vertical ? elideText.implicitHeight : elideText.implicitWidth implicitWidth: vertical ? elideText.implicitHeight : elideText.implicitWidth
Behavior on leftFadeStrength { Behavior on leftFadeStrength {
Anim {} Anim {
}
} }
Behavior on rightFadeStrength { Behavior on rightFadeStrength {
Anim {} Anim {
}
} }
onHeightChanged: resetMarquee() onHeightChanged: resetMarquee()
+6 -2
View File
@@ -4,6 +4,7 @@ import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import Quickshell import Quickshell
import ZShell.Config import ZShell.Config
import ZShell.Components
import qs.Drawers import qs.Drawers
import qs.Services import qs.Services
@@ -110,12 +111,14 @@ MouseArea {
color: Colors.palette.m3surfaceContainerLow color: Colors.palette.m3surfaceContainerLow
radius: parent.radius radius: parent.radius
ColumnLayout { SnapLayout {
id: column id: column
anchors.fill: parent anchors.fill: parent
anchors.margins: Tokens.padding.extraSmall anchors.margins: Tokens.padding.extraSmall
spacing: Tokens.spacing.extraSmall spacing: Tokens.spacing.extraSmall
orientation: Qt.Vertical
Repeater { Repeater {
id: repeater id: repeater
@@ -151,11 +154,12 @@ MouseArea {
} }
} }
RowLayout { SnapLayout {
id: menuOptionRow id: menuOptionRow
anchors.fill: parent anchors.fill: parent
anchors.margins: Tokens.padding.medium anchors.margins: Tokens.padding.medium
spacing: Tokens.spacing.small spacing: Tokens.spacing.small
MaterialIcon { MaterialIcon {
+8 -4
View File
@@ -1,5 +1,6 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import ZShell.Config import ZShell.Config
import qs.Services import qs.Services
@@ -53,7 +54,7 @@ Row {
onClicked: root.active?.clicked() onClicked: root.active?.clicked()
} }
RowLayout { SnapLayout {
id: textRow id: textRow
anchors.centerIn: parent anchors.centerIn: parent
@@ -102,7 +103,8 @@ Row {
topLeftRadius: rad topLeftRadius: rad
Behavior on rad { Behavior on rad {
Anim {} Anim {
}
} }
StateLayer { StateLayer {
@@ -126,10 +128,12 @@ Row {
text: "expand_more" text: "expand_more"
Behavior on anchors.horizontalCenterOffset { Behavior on anchors.horizontalCenterOffset {
Anim {} Anim {
}
} }
Behavior on rotation { Behavior on rotation {
Anim {} Anim {
}
} }
} }
} }
+5 -2
View File
@@ -1,4 +1,5 @@
import ZShell import ZShell
import ZShell.Components
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import qs.Components import qs.Components
@@ -47,7 +48,7 @@ CustomRect {
z: -1 z: -1
} }
RowLayout { SnapLayout {
id: layout id: layout
anchors.fill: parent anchors.fill: parent
@@ -88,9 +89,11 @@ CustomRect {
} }
} }
ColumnLayout { SnapLayout {
Layout.fillWidth: true Layout.fillWidth: true
spacing: 0 spacing: 0
orientation: Qt.Vertical
CustomText { CustomText {
id: title id: title
+6 -3
View File
@@ -44,7 +44,8 @@ Item {
onValuesChanged: root.flagChanged() onValuesChanged: root.flagChanged()
} }
ToastWrapper {} ToastWrapper {
}
} }
component ToastWrapper: MouseArea { component ToastWrapper: MouseArea {
@@ -85,10 +86,12 @@ Item {
} }
} }
Behavior on opacity { Behavior on opacity {
Anim {} Anim {
}
} }
Behavior on scale { Behavior on scale {
Anim {} Anim {
}
} }
Component.onCompleted: modelData.lock(this) Component.onCompleted: modelData.lock(this)
+2 -1
View File
@@ -20,7 +20,8 @@ Shape {
strokeWidth: 0 strokeWidth: 0
Behavior on fillColor { Behavior on fillColor {
CAnim {} CAnim {
}
} }
PathSvg { PathSvg {
+1
View File
@@ -141,6 +141,7 @@ Singleton {
BeatTracker { BeatTracker {
id: beatTracker id: beatTracker
} }
PwObjectTracker { PwObjectTracker {
+2 -1
View File
@@ -295,7 +295,8 @@ Singleton {
Component { Component {
id: apComp id: apComp
AccessPoint {} AccessPoint {
}
} }
Process { Process {
+5 -2
View File
@@ -1081,13 +1081,15 @@ Singleton {
Component { Component {
id: commandProc id: commandProc
CommandProcess {} CommandProcess {
}
} }
Component { Component {
id: apComp id: apComp
AccessPoint {} AccessPoint {
}
} }
Timer { Timer {
@@ -1308,6 +1310,7 @@ Singleton {
} }
stdout: StdioCollector { stdout: StdioCollector {
id: stdoutCollector id: stdoutCollector
} }
onExited: code => { onExited: code => {
+2 -1
View File
@@ -164,7 +164,8 @@ Singleton {
Component { Component {
id: notifComp id: notifComp
Notif {} Notif {
}
} }
component Notif: QtObject { component Notif: QtObject {
+9 -5
View File
@@ -1,5 +1,7 @@
import Quickshell import Quickshell
import QtQuick import QtQuick
import ZShell.Config
import ZShell
import qs.Components import qs.Components
import qs.Modules.Bar.Popouts as Popouts import qs.Modules.Bar.Popouts as Popouts
import qs.Modules.Notifications as Notifications import qs.Modules.Notifications as Notifications
@@ -14,7 +16,6 @@ import qs.Modules.Settings as Settings
import qs.Modules.Drawing as Drawing import qs.Modules.Drawing as Drawing
import qs.Modules.Dock as Dock import qs.Modules.Dock as Dock
import qs.Modules.Clipboard as Clipboard import qs.Modules.Clipboard as Clipboard
import ZShell.Config
Item { Item {
id: root id: root
@@ -74,7 +75,10 @@ Item {
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: sidebar.width * (1 - sidebar.offsetScale) anchors.rightMargin: sidebar.width * (1 - sidebar.offsetScale)
anchors.verticalCenter: parent.verticalCenter
y: ZUtils.snap((parent.height - implicitHeight) / 2, root)
// anchors.verticalCenter: parent.verticalCenter
clip: sidebar.visible clip: sidebar.visible
implicitHeight: osd.implicitHeight implicitHeight: osd.implicitHeight
implicitWidth: osd.implicitWidth * (1 - osd.offsetScale) implicitWidth: osd.implicitWidth * (1 - osd.offsetScale)
@@ -82,8 +86,7 @@ Item {
Osd.Wrapper { Osd.Wrapper {
id: osd id: osd
anchors.right: parent.right anchors.fill: parent
anchors.verticalCenter: parent.verticalCenter
screen: root.screen screen: root.screen
screenState: root.screenState screenState: root.screenState
sidebarOrSessionVisible: sidebar.visible sidebarOrSessionVisible: sidebar.visible
@@ -129,8 +132,9 @@ Item {
Launcher.Wrapper { Launcher.Wrapper {
id: launcher id: launcher
x: ZUtils.snap((parent.width - implicitWidth) / 2, root)
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
panels: root panels: root
screen: root.screen screen: root.screen
screenState: root.screenState screenState: root.screenState
+6 -3
View File
@@ -3,11 +3,12 @@ pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Config import ZShell.Config
import ZShell.Components
import qs.Components import qs.Components
import qs.Helpers import qs.Helpers
import qs.Services import qs.Services
ColumnLayout { SnapLayout {
id: root id: root
readonly property real centerScale: Math.min(1, screenHeight / 1440) readonly property real centerScale: Math.min(1, screenHeight / 1440)
@@ -18,9 +19,11 @@ ColumnLayout {
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: false Layout.fillWidth: false
Layout.preferredWidth: centerWidth Layout.preferredWidth: centerWidth
orientation: Qt.Vertical
spacing: Tokens.spacing.largeIncreased * 2 spacing: Tokens.spacing.largeIncreased * 2
RowLayout { SnapLayout {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
spacing: Tokens.spacing.small spacing: Tokens.spacing.small
@@ -116,7 +119,7 @@ ColumnLayout {
} }
} }
RowLayout { SnapLayout {
id: input id: input
anchors.fill: parent anchors.fill: parent
+4 -2
View File
@@ -46,7 +46,8 @@ Item {
strokeWidth: Math.min(1, remainingArc.sweepAngle) * root.strokeWidth strokeWidth: Math.min(1, remainingArc.sweepAngle) * root.strokeWidth
Behavior on strokeColor { Behavior on strokeColor {
CAnim {} CAnim {
}
} }
PathAngleArc { PathAngleArc {
@@ -83,7 +84,8 @@ Item {
} }
} }
Behavior on color { Behavior on color {
CAnim {} CAnim {
}
} }
Anim on waveProgress { Anim on waveProgress {
id: waveProgAnim id: waveProgAnim
+2 -1
View File
@@ -7,6 +7,7 @@ ClippingRectangle {
color: "transparent" color: "transparent"
Behavior on color { Behavior on color {
CAnim {} CAnim {
}
} }
} }
+4 -2
View File
@@ -20,7 +20,8 @@ Text {
textFormat: Text.PlainText textFormat: Text.PlainText
Behavior on color { Behavior on color {
CAnim {} CAnim {
}
} }
Behavior on text { Behavior on text {
enabled: root.animate enabled: root.animate
@@ -32,7 +33,8 @@ Text {
type: Anim.FastEffects type: Anim.FastEffects
} }
PropertyAction {} PropertyAction {
}
TAnim { TAnim {
target: root target: root
+2 -1
View File
@@ -65,7 +65,8 @@ Image {
value: root.source value: root.source
} }
PropertyAction {} PropertyAction {
}
ScriptAction { ScriptAction {
script: root.maybeStartInAnim() script: root.maybeStartInAnim()
+2 -1
View File
@@ -64,7 +64,8 @@ MaterialShape {
to: 360 to: 360
} }
Behavior on color { Behavior on color {
CAnim {} CAnim {
}
} }
ElapsedTimer { ElapsedTimer {
+3 -2
View File
@@ -1,11 +1,12 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Config
import ZShell.Components
import qs.Components import qs.Components
import qs.Helpers import qs.Helpers
import ZShell.Config
import qs.Services import qs.Services
RowLayout { SnapLayout {
id: root id: root
required property var greeter required property var greeter
+1
View File
@@ -200,5 +200,6 @@ Singleton {
ElapsedTimer { ElapsedTimer {
id: timer id: timer
} }
} }
+1
View File
@@ -3,6 +3,7 @@ pragma ComponentBehavior: Bound
import Quickshell import Quickshell
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import ZShell.Config import ZShell.Config
import qs.Components import qs.Components
import qs.Services import qs.Services
+10 -4
View File
@@ -3,17 +3,20 @@ pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Config import ZShell.Config
import ZShell.Components
import qs.Components import qs.Components
import qs.Services import qs.Services
ColumnLayout { SnapLayout {
id: root id: root
required property var greeter required property var greeter
anchors.fill: parent anchors.fill: parent
anchors.margins: Tokens.padding.large anchors.margins: Tokens.padding.large
spacing: Tokens.spacing.large spacing: Tokens.spacing.large
orientation: Qt.Vertical
CustomText { CustomText {
Layout.fillWidth: true Layout.fillWidth: true
@@ -37,8 +40,9 @@ ColumnLayout {
duration: Tokens.anim.durations.extraLarge duration: Tokens.anim.durations.extraLarge
} }
} }
sourceComponent: ColumnLayout { sourceComponent: SnapLayout {
spacing: Tokens.spacing.largeIncreased spacing: Tokens.spacing.largeIncreased
orientation: Qt.Vertical
MaterialIcon { MaterialIcon {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
@@ -84,7 +88,7 @@ ColumnLayout {
} }
} }
RowLayout { SnapLayout {
id: row id: row
anchors.fill: parent anchors.fill: parent
@@ -97,9 +101,11 @@ ColumnLayout {
text: modelData.kind === "x11" ? "tv" : "desktop_windows" text: modelData.kind === "x11" ? "tv" : "desktop_windows"
} }
ColumnLayout { SnapLayout {
Layout.fillWidth: true Layout.fillWidth: true
spacing: Tokens.spacing.small / 2 spacing: Tokens.spacing.small / 2
orientation: Qt.Vertical
CustomText { CustomText {
Layout.fillWidth: true Layout.fillWidth: true
+10 -4
View File
@@ -3,18 +3,21 @@ pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Config import ZShell.Config
import ZShell.Components
import qs.Components import qs.Components
import qs.Helpers import qs.Helpers
import qs.Services import qs.Services
ColumnLayout { SnapLayout {
id: root id: root
required property var greeter required property var greeter
anchors.fill: parent anchors.fill: parent
anchors.margins: Tokens.padding.large anchors.margins: Tokens.padding.large
spacing: Tokens.spacing.large spacing: Tokens.spacing.large
orientation: Qt.Vertical
CustomText { CustomText {
Layout.fillWidth: true Layout.fillWidth: true
@@ -38,8 +41,9 @@ ColumnLayout {
duration: Tokens.anim.durations.extraLarge duration: Tokens.anim.durations.extraLarge
} }
} }
sourceComponent: ColumnLayout { sourceComponent: SnapLayout {
spacing: Tokens.spacing.largeIncreased spacing: Tokens.spacing.largeIncreased
orientation: Qt.Vertical
MaterialIcon { MaterialIcon {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
@@ -86,7 +90,7 @@ ColumnLayout {
} }
} }
RowLayout { SnapLayout {
id: row id: row
anchors.fill: parent anchors.fill: parent
@@ -112,9 +116,11 @@ ColumnLayout {
} }
} }
ColumnLayout { SnapLayout {
Layout.fillWidth: true Layout.fillWidth: true
spacing: Tokens.spacing.small / 2 spacing: Tokens.spacing.small / 2
orientation: Qt.Vertical
CustomText { CustomText {
Layout.fillWidth: true Layout.fillWidth: true
+1
View File
@@ -16,6 +16,7 @@ ShellRoot {
GreeterState { GreeterState {
id: greeter id: greeter
} }
GreeterSurface { GreeterSurface {
+2 -1
View File
@@ -69,7 +69,8 @@ Singleton {
model: Quickshell.screens model: Quickshell.screens
Monitor {} Monitor {
}
} }
Process { Process {
+2 -1
View File
@@ -33,7 +33,8 @@ Singleton {
implicitHeight: 0 implicitHeight: 0
implicitWidth: 0 implicitWidth: 0
mask: Region {} mask: Region {
}
} }
} }
+1 -1
View File
@@ -53,7 +53,7 @@ CustomRect {
radius: Tokens.rounding.full radius: Tokens.rounding.full
width: row.implicitWidth + Tokens.padding.small * 2 width: row.implicitWidth + Tokens.padding.small * 2
RowLayout { SnapLayout {
id: row id: row
anchors.centerIn: parent anchors.centerIn: parent
+56 -7
View File
@@ -4,11 +4,12 @@ import Quickshell
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Config import ZShell.Config
import ZShell.Components
import qs.Components import qs.Components
import qs.Modules.Bar.Components import qs.Modules.Bar.Components
import qs.Modules.Bar.Popouts import qs.Modules.Bar.Popouts
GridLayout { SnapLayout {
id: root id: root
required property bool fullscreen required property bool fullscreen
@@ -74,9 +75,47 @@ GridLayout {
return ch?.entryId ?? ""; return ch?.entryId ?? "";
} }
columnSpacing: Tokens.spacing.small readonly property var sectionRects: {
columns: horizontal ? -1 : 1 const count = repeater.count; // dependency: re-run when items are added/removed
rowSpacing: Tokens.spacing.small const names = ["start", "middle", "end"]; // constant ids by position
const bounds = [null];
let spacers = 0;
for (let i = 0; i < count; i++) {
const it = repeater.itemAt(i) as EntryWrapper;
if (!it)
continue;
if (it.entryId === "spacer") {
bounds.push(null);
spacers++;
continue;
}
const l = it.x, t = it.y, r = it.x + it.width, b = it.y + it.height;
const cur = bounds[spacers];
bounds[spacers] = cur ? {
l: Math.min(cur.l, l),
t: Math.min(cur.t, t),
r: Math.max(cur.r, r),
b: Math.max(cur.b, b)
} : {
l,
t,
r,
b
};
}
return bounds.map((c, n) => ({
id: names[n] ?? `section${n}`,
rect: c ? Qt.rect(c.l, c.t, c.r - c.l, c.b - c.t) : Qt.rect(0, 0, 0, 0)
}));
}
spacing: Tokens.spacing.small
orientation: horizontal ? Qt.Horizontal : Qt.Vertical
Repeater { Repeater {
id: repeater id: repeater
@@ -228,16 +267,26 @@ GridLayout {
} }
component EntryWrapper: Item { component EntryWrapper: Item {
readonly property int section: {
let n = 0;
for (let i = 0; i < index; i++) {
if (repeater.model.values[i].id === "spacer")
n++;
}
return n;
}
readonly property string entryId: modelData.id readonly property string entryId: modelData.id
required property int index required property int index
default property Item item
required property var modelData required property var modelData
default property Item item
Layout.alignment: root.horizontal ? Qt.AlignVCenter : Qt.AlignHCenter Layout.alignment: root.horizontal ? Qt.AlignVCenter : Qt.AlignHCenter
Layout.bottomMargin: !root.horizontal && index === repeater.count - 1 ? root.vPadding : 0 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.leftMargin: root.horizontal && index === 0 ? root.vPadding : (entryId === "statusIcons" && root.horizontal) ? -root.spacing + Tokens.spacing.extraSmall : 0
Layout.rightMargin: root.horizontal && index === repeater.count - 1 ? root.vPadding : 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.topMargin: !root.horizontal && index === 0 ? root.vPadding : (entryId === "statusIcons" && !root.horizontal) ? -root.spacing + Tokens.spacing.extraSmall : 0
children: item children: item
implicitHeight: item?.implicitHeight ?? 0 implicitHeight: item?.implicitHeight ?? 0
implicitWidth: item?.implicitWidth ?? 0 implicitWidth: item?.implicitWidth ?? 0
+1
View File
@@ -9,6 +9,7 @@ import qs.Components
Item { Item {
id: root id: root
readonly property var sections: (content.item as Bar)?.sectionRects ?? []
readonly property int clampedExtent: Math.max(Config.bar.border, extent) readonly property int clampedExtent: Math.max(Config.bar.border, extent)
readonly property int contentThickness: Math.floor(Math.max(Config.bar.height, Tokens.sizes.bar.innerSize * (horizontal ? 1 : 1.5))) + padding * 2 readonly property int contentThickness: Math.floor(Math.max(Config.bar.height, Tokens.sizes.bar.innerSize * (horizontal ? 1 : 1.5))) + padding * 2
readonly property int exclusiveZone: Config.bar.autoHide ? Config.bar.border : contentThickness readonly property int exclusiveZone: Config.bar.autoHide ? Config.bar.border : contentThickness
+4 -2
View File
@@ -4,6 +4,7 @@ import Quickshell
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Config import ZShell.Config
import ZShell.Components
import qs.Modules.Bar.Popouts import qs.Modules.Bar.Popouts
import qs.Modules.Bar.Components.Common import qs.Modules.Bar.Components.Common
import qs.Helpers import qs.Helpers
@@ -43,7 +44,7 @@ WidgetBase {
timeTokens: timeTokens timeTokens: timeTokens
}; };
} }
required property GridLayout loader required property SnapLayout loader
required property Wrapper popouts required property Wrapper popouts
readonly property int roundedWidth: Math.round(timeText.implicitWidth) readonly property int roundedWidth: Math.round(timeText.implicitWidth)
readonly property int evenWidth: roundedWidth % 2 === 0 ? roundedWidth : roundedWidth + 1 readonly property int evenWidth: roundedWidth % 2 === 0 ? roundedWidth : roundedWidth + 1
@@ -69,7 +70,8 @@ WidgetBase {
} }
} }
ColumnLayout { SnapLayout {
orientation: Qt.Vertical
id: verticalColumn id: verticalColumn
anchors.centerIn: parent anchors.centerIn: parent
+1
View File
@@ -1,5 +1,6 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import ZShell.Config import ZShell.Config
import qs.Components import qs.Components
import qs.Modules.Bar.Components.Common import qs.Modules.Bar.Components.Common
+2 -1
View File
@@ -1,6 +1,7 @@
import Quickshell import Quickshell
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import qs.Components import qs.Components
import qs.Modules import qs.Modules
@@ -11,7 +12,7 @@ Item {
anchors.top: parent.top anchors.top: parent.top
implicitWidth: layout.implicitWidth implicitWidth: layout.implicitWidth
RowLayout { SnapLayout {
id: layout id: layout
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
+1
View File
@@ -1,5 +1,6 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import Quickshell import Quickshell
import qs.Components import qs.Components
import ZShell.Config import ZShell.Config
+1
View File
@@ -3,6 +3,7 @@ pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import Quickshell import Quickshell
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import ZShell.Config import ZShell.Config
import ZShell.Services import ZShell.Services
import qs.Services import qs.Services
+4 -4
View File
@@ -4,6 +4,7 @@ import Quickshell
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Config import ZShell.Config
import ZShell.Components
import qs.Helpers import qs.Helpers
import qs.Modules.Bar.Components.StatusIcons import qs.Modules.Bar.Components.StatusIcons
import qs.Modules.Bar.Components.Common import qs.Modules.Bar.Components.Common
@@ -59,7 +60,7 @@ WidgetBase {
Anim {} Anim {}
} }
GridLayout { SnapLayout {
id: grid id: grid
anchors.bottomMargin: root.horizontal ? 0 : Tokens.padding.medium anchors.bottomMargin: root.horizontal ? 0 : Tokens.padding.medium
@@ -67,9 +68,8 @@ WidgetBase {
anchors.leftMargin: root.horizontal ? Tokens.padding.extraSmall : 0 anchors.leftMargin: root.horizontal ? Tokens.padding.extraSmall : 0
anchors.rightMargin: root.horizontal ? Tokens.padding.extraSmall : 0 anchors.rightMargin: root.horizontal ? Tokens.padding.extraSmall : 0
anchors.topMargin: root.horizontal ? 0 : Tokens.padding.extraSmall anchors.topMargin: root.horizontal ? 0 : Tokens.padding.extraSmall
columns: root.horizontal ? -1 : 1 orientation: root.horizontal ? Qt.Horizontal : Qt.Vertical
columnSpacing: root.spacing spacing: root.horizontal ? Tokens.spacing.extraSmall : -2
rowSpacing: root.spacing
Repeater { Repeater {
model: ScriptModel { model: ScriptModel {
@@ -1,5 +1,6 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import ZShell.Config import ZShell.Config
import qs.Daemons import qs.Daemons
import qs.Components import qs.Components
@@ -1,5 +1,6 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import ZShell.Config import ZShell.Config
import qs.Daemons import qs.Daemons
import qs.Components import qs.Components
@@ -1,6 +1,7 @@
import Quickshell.Services.UPower import Quickshell.Services.UPower
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import ZShell.Config import ZShell.Config
import qs.Modules.Bar.Components.Common import qs.Modules.Bar.Components.Common
import qs.Components import qs.Components
+3 -2
View File
@@ -2,10 +2,11 @@ import QtQuick.Layouts
import QtQuick import QtQuick
import Quickshell import Quickshell
import Quickshell.Services.SystemTray import Quickshell.Services.SystemTray
import ZShell.Config
import ZShell.Components
import qs.Helpers import qs.Helpers
import qs.Modules.Bar.Popouts import qs.Modules.Bar.Popouts
import qs.Components import qs.Components
import ZShell.Config
import qs.Services import qs.Services
Item { Item {
@@ -15,7 +16,7 @@ Item {
readonly property real dpr: Hypr.monitorFor(loader?.screen).scale readonly property real dpr: Hypr.monitorFor(loader?.screen).scale
required property int ind required property int ind
required property SystemTrayItem item required property SystemTrayItem item
required property GridLayout loader required property SnapLayout loader
required property Wrapper popouts required property Wrapper popouts
function resolveIcon(app: string, icon: string): string { function resolveIcon(app: string, icon: string): string {
+5 -5
View File
@@ -4,6 +4,7 @@ import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import Quickshell.Services.SystemTray import Quickshell.Services.SystemTray
import ZShell.Config import ZShell.Config
import ZShell.Components
import qs.Components import qs.Components
import qs.Modules.Bar.Components.Common import qs.Modules.Bar.Components.Common
import qs.Modules.Bar.Components.Tray import qs.Modules.Bar.Components.Tray
@@ -15,7 +16,7 @@ WidgetBase {
readonly property alias items: repeater readonly property alias items: repeater
readonly property alias layout: sysGrid readonly property alias layout: sysGrid
required property GridLayout loader required property SnapLayout loader
readonly property int padding: Tokens.padding.extraSmall readonly property int padding: Tokens.padding.extraSmall
required property Wrapper popouts 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 readonly property real size: horizontal ? sysGrid.implicitWidth + sysGrid.anchors.leftMargin + sysGrid.anchors.rightMargin : sysGrid.implicitHeight + sysGrid.anchors.topMargin + sysGrid.anchors.bottomMargin
@@ -28,7 +29,7 @@ WidgetBase {
radius: Tokens.rounding.full radius: Tokens.rounding.full
topRightRadius: horizontal ? Tokens.rounding.small / 2 : Tokens.rounding.full topRightRadius: horizontal ? Tokens.rounding.small / 2 : Tokens.rounding.full
GridLayout { SnapLayout {
id: sysGrid id: sysGrid
anchors.bottomMargin: root.horizontal ? 0 : Tokens.padding.extraSmall anchors.bottomMargin: root.horizontal ? 0 : Tokens.padding.extraSmall
@@ -36,9 +37,8 @@ WidgetBase {
anchors.leftMargin: root.horizontal ? Tokens.padding.extraSmall : 0 anchors.leftMargin: root.horizontal ? Tokens.padding.extraSmall : 0
anchors.rightMargin: root.horizontal ? Tokens.padding.extraSmall : 0 anchors.rightMargin: root.horizontal ? Tokens.padding.extraSmall : 0
anchors.topMargin: root.horizontal ? 0 : Tokens.padding.extraSmall anchors.topMargin: root.horizontal ? 0 : Tokens.padding.extraSmall
columns: root.horizontal ? -1 : 1 orientation: root.horizontal ? Qt.Horizontal : Qt.Vertical
rowSpacing: -2 spacing: root.horizontal ? Tokens.spacing.extraSmall : -2
columnSpacing: Tokens.spacing.extraSmall
Repeater { Repeater {
id: repeater id: repeater
+1
View File
@@ -1,5 +1,6 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import ZShell.Config import ZShell.Config
import qs.Components import qs.Components
import qs.Modules.Bar.Components.Common import qs.Modules.Bar.Components.Common
+1 -1
View File
@@ -17,7 +17,7 @@ Item {
readonly property int maxSize: { readonly property int maxSize: {
const otherModules = bar.children.filter(c => c.enabled && c.entryId && c.item !== this && c.entryId !== "spacer"); 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); 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); return horizontal ? (bar.width - otherSize - bar.spacing * (bar.children.length - 1) - bar.vPadding * 2) : (bar.height - otherSize - bar.spacing * (bar.children.length - 1) - bar.vPadding * 4);
} }
clip: true clip: true
+15 -10
View File
@@ -5,6 +5,7 @@ import Quickshell.Services.Pipewire
import Quickshell.Widgets import Quickshell.Widgets
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import QtQuick.Controls import QtQuick.Controls
import ZShell.Config import ZShell.Config
import qs.Components import qs.Components
@@ -46,7 +47,8 @@ Item {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
component VolumesTab: ColumnLayout { component VolumesTab: SnapLayout {
orientation: Qt.Vertical
spacing: 12 spacing: 12
CustomRect { CustomRect {
@@ -56,14 +58,15 @@ Item {
color: Colors.tPalette.m3surfaceContainer color: Colors.tPalette.m3surfaceContainer
radius: root.rounding - vol.anchors.margins radius: root.rounding - vol.anchors.margins
ColumnLayout { SnapLayout {
orientation: Qt.Vertical
anchors.bottomMargin: Tokens.padding.small anchors.bottomMargin: Tokens.padding.small
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: Tokens.padding.small anchors.leftMargin: Tokens.padding.small
anchors.rightMargin: Tokens.padding.small anchors.rightMargin: Tokens.padding.small
anchors.topMargin: Tokens.padding.small anchors.topMargin: Tokens.padding.small
RowLayout { SnapLayout {
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
@@ -81,7 +84,7 @@ Item {
} }
} }
RowLayout { SnapLayout {
spacing: Tokens.spacing.largeIncreased spacing: Tokens.spacing.largeIncreased
CustomMouseArea { CustomMouseArea {
@@ -153,14 +156,15 @@ Item {
} }
} }
ColumnLayout { SnapLayout {
orientation: Qt.Vertical
anchors.bottomMargin: Tokens.padding.small anchors.bottomMargin: Tokens.padding.small
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: Tokens.padding.small anchors.leftMargin: Tokens.padding.small
anchors.rightMargin: Tokens.padding.small anchors.rightMargin: Tokens.padding.small
anchors.topMargin: Tokens.padding.small anchors.topMargin: Tokens.padding.small
RowLayout { SnapLayout {
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
@@ -178,7 +182,7 @@ Item {
} }
} }
RowLayout { SnapLayout {
spacing: Tokens.spacing.largeIncreased spacing: Tokens.spacing.largeIncreased
CustomMouseArea { CustomMouseArea {
@@ -276,14 +280,15 @@ Item {
text: Audio.getStreamName(appBox.modelData) text: Audio.getStreamName(appBox.modelData)
} }
ColumnLayout { SnapLayout {
orientation: Qt.Vertical
anchors.bottomMargin: Tokens.padding.small anchors.bottomMargin: Tokens.padding.small
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: Tokens.padding.small anchors.leftMargin: Tokens.padding.small
anchors.rightMargin: Tokens.padding.small anchors.rightMargin: Tokens.padding.small
anchors.topMargin: Tokens.padding.small anchors.topMargin: Tokens.padding.small
RowLayout { SnapLayout {
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
@@ -302,7 +307,7 @@ Item {
} }
} }
RowLayout { SnapLayout {
spacing: Tokens.spacing.largeIncreased spacing: Tokens.spacing.largeIncreased
CustomMouseArea { CustomMouseArea {
+2 -1
View File
@@ -50,7 +50,8 @@ Item {
} }
Behavior on offsetScale { Behavior on offsetScale {
Anim {} Anim {
}
} }
Behavior on x { Behavior on x {
enabled: !root.horizontal || root.offsetScale < 1 enabled: !root.horizontal || root.offsetScale < 1
+3 -1
View File
@@ -4,6 +4,7 @@ import Quickshell
import Quickshell.Networking import Quickshell.Networking
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import qs.Components import qs.Components
import ZShell.Config import ZShell.Config
import qs.Modules import qs.Modules
@@ -14,7 +15,8 @@ Item {
required property var wrapper required property var wrapper
ColumnLayout { SnapLayout {
orientation: Qt.Vertical
id: layout id: layout
spacing: 8 spacing: 8
+17 -8
View File
@@ -4,6 +4,7 @@ import Quickshell
import Quickshell.Widgets import Quickshell.Widgets
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Effects import QtQuick.Effects
import qs.Components import qs.Components
@@ -26,15 +27,20 @@ StackView {
initialItem: SubMenu { initialItem: SubMenu {
handle: root.trayItem handle: root.trayItem
} }
popEnter: NoAnim {} popEnter: NoAnim {
popExit: NoAnim {} }
pushEnter: NoAnim {} popExit: NoAnim {
pushExit: NoAnim {} }
pushEnter: NoAnim {
}
pushExit: NoAnim {
}
Component { Component {
id: subMenuComp id: subMenuComp
SubMenu {} SubMenu {
}
} }
component NoAnim: Transition { component NoAnim: Transition {
@@ -42,7 +48,8 @@ StackView {
duration: 0 duration: 0
} }
} }
component SubMenu: ColumnLayout { component SubMenu: SnapLayout {
orientation: Qt.Vertical
id: menu id: menu
required property QsMenuHandle handle required property QsMenuHandle handle
@@ -54,10 +61,12 @@ StackView {
spacing: Tokens.spacing.extraSmall spacing: Tokens.spacing.extraSmall
Behavior on opacity { Behavior on opacity {
Anim {} Anim {
}
} }
Behavior on scale { Behavior on scale {
Anim {} Anim {
}
} }
Component.onCompleted: shown = true Component.onCompleted: shown = true
+2 -1
View File
@@ -2,6 +2,7 @@ pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import Quickshell.Services.UPower import Quickshell.Services.UPower
import ZShell.Config import ZShell.Config
import qs.Modules.Bar.Components.Common import qs.Modules.Bar.Components.Common
@@ -35,7 +36,7 @@ Column {
Repeater { Repeater {
model: Battery.allPeripherals model: Battery.allPeripherals
RowLayout { SnapLayout {
id: layout id: layout
required property var modelData required property var modelData
+5 -3
View File
@@ -2,6 +2,7 @@ pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import Quickshell import Quickshell
import ZShell.Config import ZShell.Config
import qs.Components import qs.Components
@@ -86,7 +87,7 @@ CustomRect {
implicitWidth: 600 implicitWidth: 600
radius: root.radius - Tokens.padding.extraSmall radius: root.radius - Tokens.padding.extraSmall
RowLayout { SnapLayout {
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: Tokens.padding.small anchors.leftMargin: Tokens.padding.small
anchors.rightMargin: Tokens.padding.small anchors.rightMargin: Tokens.padding.small
@@ -96,7 +97,8 @@ CustomRect {
text: "package_2" text: "package_2"
} }
ColumnLayout { SnapLayout {
orientation: Qt.Vertical
Layout.fillWidth: true Layout.fillWidth: true
CustomText { CustomText {
@@ -114,7 +116,7 @@ CustomRect {
} }
} }
RowLayout { SnapLayout {
Layout.fillHeight: true Layout.fillHeight: true
Layout.preferredWidth: 300 Layout.preferredWidth: 300
+3 -2
View File
@@ -4,6 +4,7 @@ import Quickshell
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import qs.Components import qs.Components
import qs.Helpers import qs.Helpers
import ZShell.Config import ZShell.Config
@@ -111,7 +112,7 @@ Item {
Repeater { Repeater {
model: lineRow.modelData.text.split("\t").slice(1) model: lineRow.modelData.text.split("\t").slice(1)
RowLayout { SnapLayout {
height: lineText.height height: lineText.height
width: lineText.height + Tokens.spacing.extraSmall width: lineText.height + Tokens.spacing.extraSmall
@@ -225,7 +226,7 @@ Item {
} }
} }
RowLayout { SnapLayout {
anchors.fill: parent anchors.fill: parent
spacing: Tokens.spacing.small spacing: Tokens.spacing.small
+5 -4
View File
@@ -3,6 +3,7 @@ pragma ComponentBehavior: Bound
import Quickshell import Quickshell
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import ZShell.Config import ZShell.Config
import ZShell import ZShell
import qs.Components import qs.Components
@@ -39,8 +40,8 @@ Item {
]; ];
return allTabs.filter(tab => tab.enabled); return allTabs.filter(tab => tab.enabled);
} }
readonly property real nonAnimHeight: tabs.implicitHeight + tabs.anchors.topMargin + view.implicitHeight + viewWrapper.anchors.margins + viewWrapper.anchors.topMargin readonly property real nonAnimHeight: ZUtils.snap(tabs.implicitHeight + tabs.anchors.topMargin + view.implicitHeight + viewWrapper.anchors.margins + viewWrapper.anchors.topMargin, root)
readonly property real nonAnimWidth: view.implicitWidth + viewWrapper.anchors.margins * 2 readonly property real nonAnimWidth: ZUtils.snap(view.implicitWidth + viewWrapper.anchors.margins * 2, root)
required property ScreenState screenState required property ScreenState screenState
implicitHeight: nonAnimHeight implicitHeight: nonAnimHeight
@@ -93,8 +94,8 @@ Item {
} }
anchors.fill: parent anchors.fill: parent
implicitHeight: currentItem?.implicitHeight ?? 0 implicitHeight: currentItem?.height ?? currentItem?.implicitHeight ?? 0
implicitWidth: currentItem?.implicitWidth ?? 0 implicitWidth: currentItem?.width ?? currentItem?.implicitWidth ?? 0
Repeater { Repeater {
id: repeater id: repeater
+55 -77
View File
@@ -1,104 +1,82 @@
import Quickshell import Quickshell
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell
import ZShell.Config
import ZShell.Components
import qs.Helpers import qs.Helpers
import qs.Components import qs.Components
import qs.Modules import qs.Modules
import ZShell.Config
import qs.Modules.Dashboard.Dash import qs.Modules.Dashboard.Dash
import qs.Services import qs.Services
GridLayout { SnapLayout {
orientation: Qt.Vertical
id: root id: root
readonly property bool dashboardVisible: screenState.dashboard readonly property bool dashboardVisible: screenState.dashboard
required property int radius required property int radius
required property ScreenState screenState required property ScreenState screenState
columnSpacing: Tokens.spacing.small spacing: ZUtils.snap(Tokens.spacing.small, root)
rowSpacing: Tokens.spacing.small
ParallelAnimation { height: ZUtils.snap(implicitHeight, root)
id: openAnim width: ZUtils.snap(implicitWidth, root)
Anim { SnapLayout {
property: "opacity"
target: root
to: 1
}
Anim {
property: "scale"
target: root
to: 1
}
}
ParallelAnimation {
id: closeAnim
Anim {
property: "opacity"
target: root
to: 0
}
Anim {
property: "scale"
target: root
to: 0.9
}
}
Rect {
Layout.column: 2
Layout.columnSpan: 3
Layout.preferredHeight: user.implicitHeight
Layout.preferredWidth: user.implicitWidth
radius: root.radius
User {
id: user
screenState: root.screenState
}
}
Rect {
Layout.columnSpan: 2
Layout.fillHeight: true
Layout.preferredWidth: Tokens.sizes.dashboard.weatherWidth
Layout.row: 0
radius: root.radius
Weather {}
}
Rect {
Layout.column: 0
Layout.columnSpan: 3
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: calendar.implicitHeight spacing: parent.spacing
Layout.row: 1
radius: root.radius
Calendar { Rect {
id: calendar id: weatherRect
Layout.fillHeight: true
Layout.preferredWidth: ZUtils.snap(Tokens.sizes.dashboard.weatherWidth, root)
radius: root.radius
screenState: root.screenState Weather {}
}
Rect {
id: userRect
Layout.preferredHeight: ZUtils.snap(user.implicitHeight, root)
Layout.preferredWidth: ZUtils.snap(user.implicitWidth, root)
radius: root.radius
User {
id: user
screenState: root.screenState
}
} }
} }
Rect { SnapLayout {
Layout.column: 3 Layout.fillWidth: true
Layout.columnSpan: 2 spacing: parent.spacing
Layout.fillHeight: true
Layout.preferredWidth: resources.implicitWidth
Layout.row: 1
radius: root.radius
Resources { Rect {
id: resources id: calendarRect
Layout.fillWidth: true
Layout.fillHeight: true
implicitHeight: ZUtils.snap(calendar.implicitHeight, root)
radius: root.radius
Calendar {
id: calendar
screenState: root.screenState
}
}
Rect {
id: resourcesRect
Layout.fillHeight: true
implicitWidth: ZUtils.snap(resources.implicitWidth, root)
radius: root.radius
Resources {
id: resources
}
} }
} }
+8 -4
View File
@@ -4,6 +4,7 @@ import Quickshell
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import qs.Components import qs.Components
import ZShell.Config import ZShell.Config
import qs.Services import qs.Services
@@ -117,14 +118,15 @@ CustomMouseArea {
} }
} }
ColumnLayout { SnapLayout {
orientation: Qt.Vertical
id: inner id: inner
anchors.fill: parent anchors.fill: parent
anchors.margins: Tokens.padding.large anchors.margins: Tokens.padding.large
spacing: Tokens.spacing.extraSmall spacing: Tokens.spacing.extraSmall
RowLayout { SnapLayout {
id: monthNavigationRow id: monthNavigationRow
Layout.fillWidth: true Layout.fillWidth: true
@@ -307,10 +309,12 @@ CustomMouseArea {
} }
} }
Behavior on x { Behavior on x {
Anim {} Anim {
}
} }
Behavior on y { Behavior on y {
Anim {} Anim {
}
} }
onTodayItemChanged: { onTodayItemChanged: {
+10 -7
View File
@@ -1,5 +1,7 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import ZShell
import ZShell.Services import ZShell.Services
import ZShell.Config import ZShell.Config
import qs.Components import qs.Components
@@ -8,9 +10,8 @@ import qs.Services
Item { Item {
id: root id: root
anchors.bottom: parent.bottom anchors.fill: parent
anchors.top: parent.top implicitWidth: ZUtils.snap(layout.implicitWidth + layout.anchors.margins * 2, root)
implicitWidth: layout.implicitWidth + layout.anchors.margins * 4
ServiceRef { ServiceRef {
service: Storage service: Storage
@@ -28,13 +29,16 @@ Item {
service: Gpu service: Gpu
} }
ColumnLayout { SnapLayout {
orientation: Qt.Vertical
id: layout id: layout
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: Tokens.padding.large anchors.margins: Tokens.padding.large
anchors.top: parent.top anchors.top: parent.top
x: ZUtils.snap((root.width - implicitWidth) / 2, root)
spacing: Tokens.spacing.medium spacing: Tokens.spacing.medium
Resource { Resource {
@@ -73,8 +77,7 @@ Item {
required property string icon required property string icon
Layout.fillHeight: true implicitSize: ZUtils.snap((root.height - layout.anchors.margins * 2 - layout.spacing * 4) / 5, root)
implicitSize: height
Behavior on clampedVal { Behavior on clampedVal {
Anim {} Anim {}
+9 -5
View File
@@ -1,6 +1,8 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import M3Shapes import M3Shapes
import ZShell
import ZShell.Config import ZShell.Config
import qs.Modules.Dashboard.Media import qs.Modules.Dashboard.Media
import qs.Components import qs.Components
@@ -13,8 +15,8 @@ Item {
property ScreenState screenState property ScreenState screenState
required property int radius required property int radius
implicitWidth: 1000 implicitWidth: ZUtils.snap(1000, root)
implicitHeight: 320 implicitHeight: ZUtils.snap(320, root)
ClipRect { ClipRect {
anchors.fill: parent anchors.fill: parent
@@ -25,7 +27,7 @@ Item {
} }
} }
RowLayout { SnapLayout {
anchors.fill: parent anchors.fill: parent
anchors.margins: Tokens.padding.large anchors.margins: Tokens.padding.large
spacing: Tokens.spacing.extraLarge spacing: Tokens.spacing.extraLarge
@@ -94,7 +96,8 @@ Item {
active: opacity > 0 active: opacity > 0
opacity: 0 opacity: 0
sourceComponent: ColumnLayout { sourceComponent: SnapLayout {
orientation: Qt.Vertical
spacing: Tokens.spacing.small spacing: Tokens.spacing.small
MaterialShape { MaterialShape {
@@ -140,11 +143,12 @@ Item {
asynchronous: true asynchronous: true
active: opacity > 0 active: opacity > 0
sourceComponent: RowLayout { sourceComponent: SnapLayout {
spacing: Tokens.spacing.extraLarge spacing: Tokens.spacing.extraLarge
Details { Details {
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true
} }
LyricsAndSelector { LyricsAndSelector {
+4 -2
View File
@@ -33,7 +33,8 @@ Item {
Repeater { Repeater {
id: shapes id: shapes
DriftingShape {} DriftingShape {
}
} }
FrameAnimation { FrameAnimation {
@@ -79,7 +80,8 @@ Item {
shape: root.shapePool[Math.floor(Math.random() * root.shapePool.length)] shape: root.shapePool[Math.floor(Math.random() * root.shapePool.length)]
Behavior on color { Behavior on color {
CAnim {} CAnim {
}
} }
Behavior on opacity { Behavior on opacity {
Anim { Anim {
+2 -1
View File
@@ -18,7 +18,8 @@ Item {
layer.enabled: true layer.enabled: true
Behavior on fallbackColor { Behavior on fallbackColor {
CAnim {} CAnim {
}
} }
layer.effect: MultiEffect { layer.effect: MultiEffect {
blurMax: 1 blurMax: 1
+178 -154
View File
@@ -1,13 +1,14 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import Quickshell.Services.Mpris import Quickshell.Services.Mpris
import ZShell
import ZShell.Components import ZShell.Components
import ZShell.Config import ZShell.Config
import qs.Components import qs.Components
import qs.Services import qs.Services
import qs.Helpers import qs.Helpers
ColumnLayout { Item {
id: root id: root
readonly property bool hasUnknownLength: (Players.active?.length ?? 0) > 2147483647 readonly property bool hasUnknownLength: (Players.active?.length ?? 0) > 2147483647
@@ -25,46 +26,187 @@ ColumnLayout {
return `${mins}:${secs}`; return `${mins}:${secs}`;
} }
spacing: Tokens.spacing.extraSmall implicitHeight: ZUtils.snap(layout.implicitHeight, root)
implicitWidth: layout.implicitWidth
Timer { SnapLayout {
running: Players.active?.isPlaying ?? false orientation: Qt.Vertical
interval: Config.dashboard.mediaUpdateInterval id: layout
triggeredOnStart: true anchors.left: parent.left
repeat: true anchors.right: parent.right
onTriggered: Players.active?.positionChanged() y: ZUtils.snap((parent.height - implicitHeight) / 2, root)
}
CustomText { spacing: ZUtils.snap(Tokens.spacing.extraSmall, root)
Layout.fillWidth: true
text: Players.active?.trackTitle ?? ""
font: Tokens.font.title.large
elide: Text.ElideRight
animate: true
}
CustomText { Timer {
Layout.fillWidth: true running: Players.active?.isPlaying ?? false
text: Players.active?.trackArtist || qsTr("Unknown artist") interval: Config.dashboard.mediaUpdateInterval
color: Colors.palette.m3onSurfaceVariant triggeredOnStart: true
font: Tokens.font.title.medium repeat: true
elide: Text.ElideRight onTriggered: Players.active?.positionChanged()
animate: true }
}
CustomText { CustomText {
Layout.fillWidth: true id: title
text: Players.active?.trackAlbum || qsTr("Unknown album") Layout.fillWidth: true
color: Colors.palette.m3secondary Layout.preferredHeight: ZUtils.snapCeil(implicitHeight, root)
font: Tokens.font.title.medium text: Players.active?.trackTitle ?? ""
elide: Text.ElideRight font: Tokens.font.title.large
animate: true elide: Text.ElideRight
} animate: true
}
RowLayout { CustomText {
Layout.topMargin: Tokens.spacing.extraLargeIncreased id: artist
Layout.fillWidth: true Layout.fillWidth: true
spacing: Tokens.spacing.small Layout.preferredHeight: ZUtils.snapCeil(implicitHeight, root)
text: Players.active?.trackArtist || qsTr("Unknown artist")
color: Colors.palette.m3onSurfaceVariant
font: Tokens.font.title.medium
elide: Text.ElideRight
animate: true
}
CustomText {
id: album
Layout.fillWidth: true
Layout.preferredHeight: ZUtils.snapCeil(implicitHeight, root)
text: Players.active?.trackAlbum || qsTr("Unknown album")
color: Colors.palette.m3secondary
font: Tokens.font.title.medium
elide: Text.ElideRight
animate: true
}
SnapLayout {
id: sliderLayout
Layout.topMargin: Tokens.spacing.extraLargeIncreased
Layout.fillWidth: true
spacing: ZUtils.snap(Tokens.spacing.small, root)
CustomText {
id: positionLabel
Layout.preferredWidth: ZUtils.snapCeil(timeMetrics.width, root)
Layout.preferredHeight: positionSlider.implicitHeight
text: root.lengthStr(Players.active?.position ?? -1)
color: Colors.palette.m3onSurfaceVariant
font: timeMetrics.font
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
CustomSlider {
id: positionSlider
Layout.fillWidth: true
Layout.preferredHeight: ZUtils.snap(implicitHeight, root)
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;
}
Binding {
target: positionLabel
property: "text"
value: root.lengthStr(positionSlider.pos * (Players.active?.length ?? 0))
when: positionSlider.dragging
}
}
CustomText {
Layout.preferredWidth: ZUtils.snapCeil(timeMetrics.width, root)
Layout.preferredHeight: positionSlider.implicitHeight
text: root.hasUnknownLength ? "--:--" : root.lengthStr(Players.active?.length ?? -1)
color: Colors.palette.m3onSurfaceVariant
font: timeMetrics.font
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
ButtonRow {
Layout.topMargin: Tokens.spacing.largeIncreased
Layout.fillWidth: true
spacing: Tokens.spacing.extraSmall
IconButton {
type: IconButton.Tonal
icon: "shuffle"
isRound: true
shapeMorph: true
checked: Players.active?.shuffle ?? false
font: Tokens.font.icon.builders.medium.weight(Font.Medium).build()
enabled: Players.active?.shuffleSupported
onClicked: Players.active.shuffle = !Players.active?.shuffle
implicitWidth: Math.round(implicitHeight * 0.9)
}
IconButton {
id: previousBtn
type: IconButton.Tonal
icon: "skip_previous"
isRound: true
shapeMorph: true
font: Tokens.font.icon.large
enabled: Players.active?.canGoPrevious
onClicked: Players.active?.previous()
}
IconButton {
id: playPauseBtn
icon: Players.active?.isPlaying ? "pause" : "play_arrow"
isRound: true
shapeMorph: true
fillWidth: true
checked: Players.active?.isPlaying ?? false
font: Tokens.font.icon.large
enabled: Players.active?.canTogglePlaying
onClicked: Players.active?.togglePlaying()
}
IconButton {
id: nextBtn
type: IconButton.Tonal
icon: "skip_next"
isRound: true
shapeMorph: true
font: Tokens.font.icon.large
enabled: Players.active?.canGoNext
onClicked: Players.active?.next()
}
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
font: Tokens.font.icon.builders.medium.weight(Font.Medium).build()
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;
}
implicitWidth: Math.round(implicitHeight * 0.9)
}
}
TextMetrics { TextMetrics {
id: timeMetrics id: timeMetrics
@@ -72,123 +214,5 @@ ColumnLayout {
text: Players.active ? root.lengthStr(Math.max(Players.active.position, root.hasUnknownLength ? 0 : Players.active.length)).replace(/[1-9]/g, "0") : "00:00" text: Players.active ? root.lengthStr(Math.max(Players.active.position, root.hasUnknownLength ? 0 : Players.active.length)).replace(/[1-9]/g, "0") : "00:00"
font: Tokens.font.label.medium font: Tokens.font.label.medium
} }
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;
}
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
IconButton {
type: IconButton.Tonal
icon: "shuffle"
isRound: true
shapeMorph: true
checked: Players.active?.shuffle ?? false
font: Tokens.font.icon.builders.medium.weight(Font.Medium).build()
enabled: Players.active?.shuffleSupported
onClicked: Players.active.shuffle = !Players.active?.shuffle
implicitWidth: Math.round(implicitHeight * 0.9)
}
IconButton {
id: previousBtn
type: IconButton.Tonal
icon: "skip_previous"
isRound: true
shapeMorph: true
font: Tokens.font.icon.large
enabled: Players.active?.canGoPrevious
onClicked: Players.active?.previous()
}
IconButton {
id: playPauseBtn
icon: Players.active?.isPlaying ? "pause" : "play_arrow"
isRound: true
shapeMorph: true
fillWidth: true
checked: Players.active?.isPlaying ?? false
font: Tokens.font.icon.large
enabled: Players.active?.canTogglePlaying
onClicked: Players.active?.togglePlaying()
}
IconButton {
id: nextBtn
type: IconButton.Tonal
icon: "skip_next"
isRound: true
shapeMorph: true
font: Tokens.font.icon.large
enabled: Players.active?.canGoNext
onClicked: Players.active?.next()
}
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
font: Tokens.font.icon.builders.medium.weight(Font.Medium).build()
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;
}
implicitWidth: Math.round(implicitHeight * 0.9)
}
} }
} }
+5 -2
View File
@@ -3,6 +3,7 @@ pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Effects import QtQuick.Effects
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import ZShell.Config import ZShell.Config
import ZShell.Services import ZShell.Services
import qs.Components import qs.Components
@@ -157,7 +158,8 @@ Item {
active: opacity > 0 active: opacity > 0
opacity: 0 opacity: 0
sourceComponent: ColumnLayout { sourceComponent: SnapLayout {
orientation: Qt.Vertical
spacing: Tokens.spacing.large spacing: Tokens.spacing.large
CustomRect { CustomRect {
@@ -198,7 +200,8 @@ Item {
active: opacity > 0 active: opacity > 0
opacity: 0 opacity: 0
sourceComponent: ColumnLayout { sourceComponent: SnapLayout {
orientation: Qt.Vertical
spacing: Tokens.spacing.small spacing: Tokens.spacing.small
MaterialIcon { MaterialIcon {
@@ -1,5 +1,6 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import Quickshell import Quickshell
import Quickshell.Services.Mpris import Quickshell.Services.Mpris
import ZShell.Config import ZShell.Config
@@ -8,14 +9,15 @@ import qs.Helpers
import qs.Services import qs.Services
Item { Item {
ColumnLayout { SnapLayout {
orientation: Qt.Vertical
id: layout id: layout
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: Tokens.padding.medium anchors.leftMargin: Tokens.padding.medium
spacing: Tokens.spacing.medium spacing: Tokens.spacing.medium
RowLayout { SnapLayout {
Layout.bottomMargin: -Tokens.spacing.medium Layout.bottomMargin: -Tokens.spacing.medium
spacing: Tokens.spacing.medium spacing: Tokens.spacing.medium
z: 1 z: 1
+3 -1
View File
@@ -1,5 +1,6 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import ZShell import ZShell
import ZShell.Blobs import ZShell.Blobs
import ZShell.Config import ZShell.Config
@@ -141,7 +142,8 @@ Item {
} }
] ]
ColumnLayout { SnapLayout {
orientation: Qt.Vertical
id: layout id: layout
anchors.centerIn: parent anchors.centerIn: parent
@@ -2,6 +2,7 @@ pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import Quickshell import Quickshell
import ZShell.Config import ZShell.Config
import ZShell.Internal import ZShell.Internal
@@ -2,6 +2,7 @@ pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import Quickshell import Quickshell
import Quickshell.Widgets import Quickshell.Widgets
import ZShell.Config import ZShell.Config
@@ -38,7 +39,7 @@ CustomListView {
id: rowHover id: rowHover
} }
RowLayout { SnapLayout {
id: rowLayout id: rowLayout
anchors.left: parent.left anchors.left: parent.left
+6 -4
View File
@@ -23,7 +23,7 @@ Item {
service: Memory service: Memory
} }
RowLayout { SnapLayout {
id: layout id: layout
anchors.fill: parent anchors.fill: parent
spacing: Tokens.spacing.medium spacing: Tokens.spacing.medium
@@ -60,13 +60,14 @@ Item {
Layout.fillHeight: true Layout.fillHeight: true
implicitHeight: mainLayout.implicitHeight + mainLayout.anchors.margins * 2 implicitHeight: mainLayout.implicitHeight + mainLayout.anchors.margins * 2
ColumnLayout { SnapLayout {
orientation: Qt.Vertical
id: mainLayout id: mainLayout
anchors.fill: parent anchors.fill: parent
anchors.margins: Tokens.padding.large anchors.margins: Tokens.padding.large
spacing: 0 spacing: 0
RowLayout { SnapLayout {
spacing: Tokens.spacing.small spacing: Tokens.spacing.small
MaterialIcon { MaterialIcon {
@@ -131,7 +132,8 @@ Item {
} }
} }
ColumnLayout { SnapLayout {
orientation: Qt.Vertical
id: infoColumn id: infoColumn
anchors.right: parent.right anchors.right: parent.right
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
+57 -32
View File
@@ -4,6 +4,8 @@ import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Templates import QtQuick.Templates
import Quickshell import Quickshell
import ZShell
import ZShell.Components
import ZShell.Config import ZShell.Config
import qs.Components import qs.Components
import qs.Services import qs.Services
@@ -16,9 +18,17 @@ Item {
required property var tabs required property var tabs
readonly property alias count: bar.count readonly property alias count: bar.count
readonly property int tabIndicatorSpacing: Tokens.spacing.small readonly property int tabIndicatorSpacing: ZUtils.snap(Tokens.spacing.small, root)
implicitHeight: bar.implicitHeight + bar.anchors.topMargin + indicator.implicitHeight + indicator.anchors.topMargin + separator.implicitHeight function snapLayoutHeight(v) {
const dpr = ZUtils.dprFor(root);
let h = Math.ceil(v);
while (Math.abs(h * dpr - Math.round(h * dpr)) > 1e-6)
++h;
return h;
}
implicitHeight: ZUtils.snap(bar.implicitHeight + bar.anchors.topMargin + indicator.implicitHeight + indicator.anchors.topMargin + separator.implicitHeight, root)
TabBar { TabBar {
id: bar id: bar
@@ -31,9 +41,11 @@ Item {
currentIndex: root.screenState.dashboardTab currentIndex: root.screenState.dashboardTab
onCurrentIndexChanged: root.screenState.dashboardTab = currentIndex onCurrentIndexChanged: root.screenState.dashboardTab = currentIndex
implicitHeight: contentHeight topPadding: 0
bottomPadding: 0
implicitHeight: implicitContentHeight
background: null background: null
contentItem: RowLayout { contentItem: SnapLayout {
spacing: 0 spacing: 0
Repeater { Repeater {
@@ -116,10 +128,13 @@ Item {
readonly property bool current: TabBar.tabBar.currentItem === this readonly property bool current: TabBar.tabBar.currentItem === this
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredWidth: 1 // Uniform width across all tabs Layout.fillHeight: true
Layout.preferredWidth: 1
implicitWidth: implicitContentWidth implicitWidth: implicitContentWidth
implicitHeight: implicitContentHeight implicitHeight: implicitContentHeight
background: null background: null
topPadding: 0
bottomPadding: 0
contentItem: CustomMouseArea { contentItem: CustomMouseArea {
id: mouse id: mouse
@@ -131,8 +146,8 @@ Item {
root.screenState.dashboardTab = Math.max(root.screenState.dashboardTab - 1, 0); root.screenState.dashboardTab = Math.max(root.screenState.dashboardTab - 1, 0);
} }
implicitWidth: Math.max(icon.width, label.width) implicitWidth: Math.max(icon.implicitWidth, label.implicitWidth)
implicitHeight: icon.height + label.height implicitHeight: snapLayout.implicitHeight
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
@@ -146,39 +161,49 @@ Item {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
implicitHeight: parent.height + root.tabIndicatorSpacing * 2 anchors.alignWhenCentered: false
implicitHeight: ZUtils.snap(parent.height + Tokens.sizes.dashboard.tabIndicatorSpacing * 2, stateLayer)
radius: Tokens.rounding.medium radius: Tokens.rounding.medium
color: tab.current ? Colors.palette.m3primary : Colors.palette.m3onSurface color: tab.current ? Colors.palette.m3primary : Colors.palette.m3onSurface
onClicked: root.screenState.dashboardTab = tab.TabBar.index onClicked: {
} root.screenState.dashboardTab = tab.TabBar.index;
MaterialIcon {
id: icon
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: label.top
text: tab.iconName
color: tab.current ? Colors.palette.m3primary : Colors.palette.m3onSurfaceVariant
fill: tab.current ? 1 : 0
fontStyle: Tokens.font.icon.medium
Behavior on fill {
Anim {
type: Anim.DefaultEffects
}
} }
} }
CustomText { SnapLayout {
id: label id: snapLayout
anchors.fill: parent
spacing: 0
orientation: Qt.Vertical
anchors.horizontalCenter: parent.horizontalCenter MaterialIcon {
anchors.bottom: parent.bottom id: icon
text: tab.text text: tab.iconName
color: tab.current ? Colors.palette.m3primary : Colors.palette.m3onSurfaceVariant color: tab.current ? Colors.palette.m3primary : Colors.palette.m3onSurfaceVariant
fill: tab.current ? 1 : 0
fontStyle: Tokens.font.icon.medium
Layout.fillHeight: true
Layout.alignment: Qt.AlignHCenter
Behavior on fill {
Anim {
type: Anim.DefaultEffects
}
}
}
CustomText {
id: label
text: tab.text
color: tab.current ? Colors.palette.m3primary : Colors.palette.m3onSurfaceVariant
Layout.fillHeight: true
Layout.alignment: Qt.AlignHCenter
}
} }
} }
} }
+12 -6
View File
@@ -1,11 +1,13 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell
import ZShell.Components
import ZShell.Config import ZShell.Config
import qs.Components import qs.Components
import qs.Services import qs.Services
import qs.Helpers import qs.Helpers
RowLayout { SnapLayout {
id: root id: root
spacing: Tokens.spacing.largeIncreased spacing: Tokens.spacing.largeIncreased
@@ -20,7 +22,7 @@ RowLayout {
readonly property real markerX: { readonly property real markerX: {
const d = root.now; const d = root.now;
return d.getHours() + d.getMinutes() / 60; return ZUtils.snap(d.getHours() + d.getMinutes() / 60, root);
} }
function formatHour(h) { function formatHour(h) {
@@ -39,11 +41,13 @@ RowLayout {
onTriggered: root.now = new Date() onTriggered: root.now = new Date()
} }
ColumnLayout { SnapLayout {
orientation: Qt.Vertical
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true
Layout.preferredWidth: root.width / 2 Layout.preferredWidth: root.width / 2
RowLayout { SnapLayout {
Layout.fillWidth: true Layout.fillWidth: true
MaterialIcon { MaterialIcon {
@@ -90,11 +94,13 @@ RowLayout {
} }
} }
ColumnLayout { SnapLayout {
orientation: Qt.Vertical
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true
Layout.preferredWidth: root.width / 2 Layout.preferredWidth: root.width / 2
RowLayout { SnapLayout {
Layout.fillWidth: true Layout.fillWidth: true
MaterialIcon { MaterialIcon {
+14 -7
View File
@@ -3,6 +3,7 @@ pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Config import ZShell.Config
import ZShell.Components
import qs.Components import qs.Components
import qs.Modules.Dashboard.Weather import qs.Modules.Dashboard.Weather
import qs.Services import qs.Services
@@ -18,13 +19,14 @@ Item {
implicitHeight: layout.implicitHeight implicitHeight: layout.implicitHeight
Component.onCompleted: Weather.reload() Component.onCompleted: Weather.reload()
ColumnLayout { SnapLayout {
orientation: Qt.Vertical
id: layout id: layout
anchors.fill: parent anchors.fill: parent
spacing: Tokens.spacing.medium spacing: Tokens.spacing.medium
RowLayout { SnapLayout {
Layout.leftMargin: Tokens.padding.large Layout.leftMargin: Tokens.padding.large
Layout.rightMargin: Tokens.padding.large Layout.rightMargin: Tokens.padding.large
Layout.fillWidth: true Layout.fillWidth: true
@@ -82,7 +84,7 @@ Item {
} }
} }
RowLayout { SnapLayout {
Layout.fillWidth: true Layout.fillWidth: true
spacing: Tokens.spacing.medium spacing: Tokens.spacing.medium
@@ -121,7 +123,9 @@ Item {
color: Colors.palette.m3onSurface color: Colors.palette.m3onSurface
} }
RowLayout { SnapLayout {
id: forecastLayout
Layout.fillWidth: true Layout.fillWidth: true
spacing: Tokens.spacing.medium spacing: Tokens.spacing.medium
@@ -137,12 +141,14 @@ Item {
required property var modelData required property var modelData
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true
implicitHeight: forecastItemColumn.implicitHeight + Tokens.padding.medium * 2 implicitHeight: forecastItemColumn.implicitHeight + Tokens.padding.medium * 2
radius: root.radius radius: root.radius
color: Colors.tPalette.m3surfaceContainer color: Colors.tPalette.m3surfaceContainer
ColumnLayout { SnapLayout {
orientation: Qt.Vertical
id: forecastItemColumn id: forecastItemColumn
anchors.centerIn: parent anchors.centerIn: parent
@@ -196,7 +202,8 @@ Item {
property color colour property color colour
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: 60 Layout.fillHeight: true
implicitHeight: 60
radius: Tokens.rounding.medium radius: Tokens.rounding.medium
color: Colors.tPalette.m3surfaceContainer color: Colors.tPalette.m3surfaceContainer
@@ -230,7 +237,7 @@ Item {
} }
} }
component WeatherStat: RowLayout { component WeatherStat: SnapLayout {
id: weatherStat id: weatherStat
property string icon property string icon
@@ -1,5 +1,6 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import Quickshell import Quickshell
import Quickshell.Widgets import Quickshell.Widgets
import Quickshell.Hyprland import Quickshell.Hyprland
@@ -43,7 +44,8 @@ Item {
} }
opacity: root.visible ? 1 : 0 opacity: root.visible ? 1 : 0
ColumnLayout { SnapLayout {
orientation: Qt.Vertical
id: menuLayout id: menuLayout
anchors.centerIn: parent anchors.centerIn: parent
spacing: 0 spacing: 0
@@ -53,7 +55,7 @@ Item {
radius: popupBackground.radius - popupBackground.padding radius: popupBackground.radius - popupBackground.padding
implicitHeight: openTerminalRow.implicitHeight + Tokens.padding.extraSmall * 2 implicitHeight: openTerminalRow.implicitHeight + Tokens.padding.extraSmall * 2
RowLayout { SnapLayout {
id: openTerminalRow id: openTerminalRow
spacing: 8 spacing: 8
anchors.fill: parent anchors.fill: parent
@@ -92,7 +94,7 @@ Item {
radius: popupBackground.radius - popupBackground.padding radius: popupBackground.radius - popupBackground.padding
implicitHeight: settingsRow.implicitHeight + Tokens.padding.extraSmall * 2 implicitHeight: settingsRow.implicitHeight + Tokens.padding.extraSmall * 2
RowLayout { SnapLayout {
id: settingsRow id: settingsRow
spacing: 8 spacing: 8
anchors.fill: parent anchors.fill: parent
@@ -132,7 +134,7 @@ Item {
radius: popupBackground.radius - popupBackground.padding radius: popupBackground.radius - popupBackground.padding
implicitHeight: logoutRow.implicitHeight + Tokens.padding.extraSmall * 2 implicitHeight: logoutRow.implicitHeight + Tokens.padding.extraSmall * 2
RowLayout { SnapLayout {
id: logoutRow id: logoutRow
spacing: 8 spacing: 8
anchors.fill: parent anchors.fill: parent
@@ -171,7 +173,7 @@ Item {
// radius: popupBackground.radius - popupBackground.padding // radius: popupBackground.radius - popupBackground.padding
// implicitHeight: desktopIconsRow.implicitHeight + Tokens.padding.extraSmall * 2 // implicitHeight: desktopIconsRow.implicitHeight + Tokens.padding.extraSmall * 2
// //
// RowLayout { // SnapLayout {
// id: desktopIconsRow // id: desktopIconsRow
// spacing: 8 // spacing: 8
// anchors.fill: parent // anchors.fill: parent
@@ -3,6 +3,7 @@ import QtQuick.Layouts
import Quickshell import Quickshell
import Quickshell.Widgets import Quickshell.Widgets
import qs.Components import qs.Components
import ZShell.Components
import ZShell.Config import ZShell.Config
import qs.Services import qs.Services
@@ -57,22 +58,25 @@ Item {
Anim {} Anim {}
} }
ColumnLayout { SnapLayout {
id: menuLayout id: menuLayout
anchors.centerIn: parent anchors.centerIn: parent
spacing: 0 spacing: 0
orientation: Qt.Vertical
CustomRect { CustomRect {
Layout.preferredWidth: 160 Layout.preferredWidth: 160
implicitHeight: openRow.implicitHeight + Tokens.padding.extraSmall * 2 implicitHeight: openRow.implicitHeight + Tokens.padding.extraSmall * 2
radius: popupBackground.radius - popupBackground.padding radius: popupBackground.radius - popupBackground.padding
RowLayout { SnapLayout {
id: openRow id: openRow
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: Tokens.padding.small anchors.leftMargin: Tokens.padding.small
spacing: 8 spacing: 8
MaterialIcon { MaterialIcon {
@@ -111,11 +115,12 @@ Item {
implicitHeight: openWithRow.implicitHeight + Tokens.padding.extraSmall * 2 implicitHeight: openWithRow.implicitHeight + Tokens.padding.extraSmall * 2
radius: popupBackground.radius - popupBackground.padding radius: popupBackground.radius - popupBackground.padding
RowLayout { SnapLayout {
id: openWithRow id: openWithRow
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: Tokens.padding.small anchors.leftMargin: Tokens.padding.small
spacing: 8 spacing: 8
MaterialIcon { MaterialIcon {
@@ -156,11 +161,12 @@ Item {
implicitHeight: copyPathRow.implicitHeight + Tokens.padding.extraSmall * 2 implicitHeight: copyPathRow.implicitHeight + Tokens.padding.extraSmall * 2
radius: popupBackground.radius - popupBackground.padding radius: popupBackground.radius - popupBackground.padding
RowLayout { SnapLayout {
id: copyPathRow id: copyPathRow
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: Tokens.padding.small anchors.leftMargin: Tokens.padding.small
spacing: 8 spacing: 8
MaterialIcon { MaterialIcon {
@@ -190,11 +196,12 @@ Item {
radius: popupBackground.radius - popupBackground.padding radius: popupBackground.radius - popupBackground.padding
visible: contextMenu.targetPaths.length === 1 visible: contextMenu.targetPaths.length === 1
RowLayout { SnapLayout {
id: renameRow id: renameRow
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: Tokens.padding.small anchors.leftMargin: Tokens.padding.small
spacing: 8 spacing: 8
MaterialIcon { MaterialIcon {
@@ -231,11 +238,12 @@ Item {
implicitHeight: deleteRow.implicitHeight + Tokens.padding.extraSmall * 2 implicitHeight: deleteRow.implicitHeight + Tokens.padding.extraSmall * 2
radius: popupBackground.radius - popupBackground.padding radius: popupBackground.radius - popupBackground.padding
RowLayout { SnapLayout {
id: deleteRow id: deleteRow
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: Tokens.padding.small anchors.leftMargin: Tokens.padding.small
spacing: 8 spacing: 8
MaterialIcon { MaterialIcon {
+10 -5
View File
@@ -54,12 +54,14 @@ Item {
Behavior on x { Behavior on x {
enabled: !mouseArea.drag.active && !root.isSnapping && !root.iconsRoot.selectedIcons.includes(root.filePath) enabled: !mouseArea.drag.active && !root.isSnapping && !root.iconsRoot.selectedIcons.includes(root.filePath)
Anim {} Anim {
}
} }
Behavior on y { Behavior on y {
enabled: !mouseArea.drag.active && !root.isSnapping && !root.iconsRoot.selectedIcons.includes(root.filePath) enabled: !mouseArea.drag.active && !root.isSnapping && !root.iconsRoot.selectedIcons.includes(root.filePath)
Anim {} Anim {
}
} }
Item { Item {
@@ -83,7 +85,8 @@ Item {
y: (root.iconsRoot.selectedIcons.includes(root.filePath) && root.iconsRoot.dragLeader !== "" && root.iconsRoot.dragLeader !== root.filePath) ? root.iconsRoot.groupDragY : 0 y: (root.iconsRoot.selectedIcons.includes(root.filePath) && root.iconsRoot.dragLeader !== "" && root.iconsRoot.dragLeader !== root.filePath) ? root.iconsRoot.groupDragY : 0
} }
transitions: Transition { transitions: Transition {
Anim {} Anim {
}
} }
onXChanged: { onXChanged: {
@@ -205,7 +208,8 @@ Item {
radius: Tokens.rounding.small radius: Tokens.rounding.small
Behavior on opacity { Behavior on opacity {
Anim {} Anim {
}
} }
} }
@@ -264,7 +268,8 @@ Item {
radius: Tokens.rounding.small radius: Tokens.rounding.small
Behavior on opacity { Behavior on opacity {
Anim {} Anim {
}
} }
} }
} }
+9 -3
View File
@@ -4,6 +4,7 @@ import Quickshell
import Quickshell.Widgets import Quickshell.Widgets
import qs.Components import qs.Components
import qs.Helpers import qs.Helpers
import ZShell.Components
import ZShell.Config import ZShell.Config
import qs.Services import qs.Services
@@ -29,7 +30,10 @@ CustomRect {
active: !isSeparator active: !isSeparator
anchors.centerIn: parent anchors.centerIn: parent
sourceComponent: ColumnLayout { sourceComponent: SnapLayout {
spacing: Tokens.spacing.extraSmall
orientation: Qt.Vertical
IconImage { IconImage {
id: icon id: icon
@@ -38,8 +42,9 @@ CustomRect {
source: Quickshell.iconPath(AppSearch.guessIcon(appToplevel?.appId), "image-missing") source: Quickshell.iconPath(AppSearch.guessIcon(appToplevel?.appId), "image-missing")
} }
RowLayout { SnapLayout {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
spacing: 3 spacing: 3
Repeater { Repeater {
@@ -82,7 +87,8 @@ CustomRect {
Loader { Loader {
active: isSeparator active: isSeparator
sourceComponent: DockSeparator {} sourceComponent: DockSeparator {
}
anchors { anchors {
fill: parent fill: parent
+1
View File
@@ -1,5 +1,6 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import qs.Components import qs.Components
import ZShell.Config import ZShell.Config
import qs.Services import qs.Services
+3 -1
View File
@@ -2,6 +2,7 @@ pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import Quickshell import Quickshell
import ZShell
import ZShell.Config import ZShell.Config
import qs.Components import qs.Components
import qs.Services import qs.Services
@@ -52,7 +53,7 @@ CustomListView {
highlightFollowsCurrentItem: false highlightFollowsCurrentItem: false
highlightRangeMode: ListView.ApplyRange highlightRangeMode: ListView.ApplyRange
implicitHeight: (Config.launcher.sizes.itemHeight + spacing) * Math.min(Config.launcher.maxAppsShown, count) - spacing implicitHeight: (Tokens.sizes.launcher.itemHeight + spacing) * Math.min(Config.launcher.maxAppsShown, count) - spacing
orientation: Qt.Vertical orientation: Qt.Vertical
preferredHighlightBegin: 0 preferredHighlightBegin: 0
preferredHighlightEnd: height preferredHighlightEnd: height
@@ -97,6 +98,7 @@ CustomListView {
} }
} }
highlight: CustomRect { highlight: CustomRect {
id: hl
color: Colors.palette.m3onSurface color: Colors.palette.m3onSurface
implicitHeight: root.currentItem?.implicitHeight ?? 0 implicitHeight: root.currentItem?.implicitHeight ?? 0
implicitWidth: root.width implicitWidth: root.width
+1 -1
View File
@@ -22,7 +22,7 @@ CarouselView {
delegateProperties: ({ delegateProperties: ({
screenState: root.screenState screenState: root.screenState
}) })
focalWidth: Config.launcher.sizes.wallpaperWidth focalWidth: Tokens.sizes.launcher.wallpaperWidth
glideDuration: 250 glideDuration: 250
glideEasingType: Easing.OutCubic glideEasingType: Easing.OutCubic
implicitHeight: tileHeight + Tokens.spacing.small / 2 + Tokens.padding.large + Tokens.padding.small implicitHeight: tileHeight + Tokens.spacing.small / 2 + Tokens.padding.large + Tokens.padding.small
+3 -2
View File
@@ -2,17 +2,18 @@ pragma ComponentBehavior: Bound
import Quickshell import Quickshell
import QtQuick import QtQuick
import ZShell
import ZShell.Config
import qs.Modules.Launcher.Services import qs.Modules.Launcher.Services
import qs.Components import qs.Components
import qs.Helpers import qs.Helpers
import ZShell.Config
import qs.Services import qs.Services
Item { Item {
id: root id: root
required property real maxHeight required property real maxHeight
readonly property int padding: Tokens.padding.largeIncreased / 4 readonly property int padding: ZUtils.snap(Tokens.padding.medium / 2, root)
required property var panels required property var panels
readonly property int rounding: Tokens.rounding.largeIncreased readonly property int rounding: Tokens.rounding.largeIncreased
required property ScreenState screenState required property ScreenState screenState
+5 -4
View File
@@ -2,11 +2,12 @@ pragma ComponentBehavior: Bound
import Quickshell import Quickshell
import QtQuick import QtQuick
import ZShell
import ZShell.Config
import qs.Paths import qs.Paths
import qs.Modules import qs.Modules
import qs.Components import qs.Components
import qs.Helpers import qs.Helpers
import ZShell.Config
import qs.Services import qs.Services
Item { Item {
@@ -71,7 +72,7 @@ Item {
PropertyChanges { PropertyChanges {
appList.active: true appList.active: true
root.implicitHeight: Math.min(root.maxHeight, appList.implicitHeight > 0 ? appList.implicitHeight : empty.implicitHeight) root.implicitHeight: Math.min(root.maxHeight, appList.implicitHeight > 0 ? appList.implicitHeight : empty.implicitHeight)
root.implicitWidth: Config.launcher.sizes.itemWidth root.implicitWidth: Tokens.sizes.launcher.itemWidth
} }
AnchorChanges { AnchorChanges {
@@ -83,8 +84,8 @@ Item {
name: "wallpapers" name: "wallpapers"
PropertyChanges { PropertyChanges {
root.implicitHeight: Config.launcher.sizes.wallpaperHeight root.implicitHeight: Tokens.sizes.launcher.wallpaperHeight
root.implicitWidth: Math.max(Config.launcher.sizes.itemWidth * 1.2, wallpaperList.implicitWidth) root.implicitWidth: Math.max(Tokens.sizes.launcher.itemWidth * 1.2, wallpaperList.implicitWidth)
wallpaperList.active: true wallpaperList.active: true
} }
} }
+1 -1
View File
@@ -13,7 +13,7 @@ Item {
anchors.left: parent?.left anchors.left: parent?.left
anchors.right: parent?.right anchors.right: parent?.right
implicitHeight: Config.launcher.sizes.itemHeight implicitHeight: Tokens.sizes.launcher.itemHeight
StateLayer { StateLayer {
radius: Tokens.rounding.medium radius: Tokens.rounding.medium
+42 -18
View File
@@ -1,10 +1,13 @@
import Quickshell import Quickshell
import Quickshell.Widgets import Quickshell.Widgets
import QtQuick import QtQuick
import QtQuick.Layouts
import ZShell.Config
import ZShell.Components
import ZShell
import qs.Modules.Launcher.Services import qs.Modules.Launcher.Services
import qs.Components import qs.Components
import qs.Helpers import qs.Helpers
import ZShell.Config
import qs.Modules import qs.Modules
import qs.Services import qs.Services
@@ -16,53 +19,72 @@ Item {
anchors.left: parent?.left anchors.left: parent?.left
anchors.right: parent?.right anchors.right: parent?.right
implicitHeight: Config.launcher.sizes.itemHeight implicitHeight: ZUtils.snap(Tokens.sizes.launcher.itemHeight, root)
StateLayer { StateLayer {
radius: Tokens.rounding.medium radius: Tokens.rounding.medium
onClicked: { onClicked: {
Apps.launch(root.modelData); // Apps.launch(root.modelData);
root.screenState.launcher = false; // root.screenState.launcher = false;
ZUtils.logPlacement(icon, "icon");
ZUtils.logPlacement(name, "name");
ZUtils.logPlacement(favoriteIcon, "favoriteIcon");
ZUtils.logPlacement(comment, "comment");
ZUtils.logPlacement(text, "text");
ZUtils.logPlacement(mainLayout, "main");
} }
} }
Item { SnapLayout {
id: mainLayout
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: Tokens.padding.medium anchors.leftMargin: Tokens.padding.medium
anchors.margins: Tokens.padding.small
anchors.rightMargin: Tokens.padding.medium anchors.rightMargin: Tokens.padding.medium
spacing: Tokens.spacing.medium
IconImage { IconImage {
id: icon id: icon
anchors.verticalCenter: parent.verticalCenter implicitSize: parent.height - Tokens.padding.small * 2
implicitSize: parent.height
source: Quickshell.iconPath(root.modelData?.icon, "image-missing") source: Quickshell.iconPath(root.modelData?.icon, "image-missing")
} }
Item { SnapLayout {
anchors.left: icon.right id: text
anchors.leftMargin: Tokens.spacing.medium
anchors.verticalCenter: icon.verticalCenter Layout.fillHeight: true
implicitHeight: name.implicitHeight + comment.implicitHeight Layout.fillWidth: true
implicitWidth: parent.width - icon.width Layout.topMargin: Tokens.padding.extraSmall
Layout.bottomMargin: Tokens.padding.extraSmall
orientation: Qt.Vertical
spacing: 0
CustomText { CustomText {
id: name id: name
Layout.fillHeight: true
Layout.fillWidth: true
text: root.modelData?.name ?? "" text: root.modelData?.name ?? ""
verticalAlignment: CustomText.AlignVCenter
horizontalAlignment: CustomText.AlignLeft
} }
CustomText { CustomText {
id: comment id: comment
anchors.top: name.bottom Layout.fillHeight: true
Layout.fillWidth: true
color: Colors.palette.m3outline color: Colors.palette.m3outline
elide: Text.ElideRight elide: Text.ElideRight
font: Tokens.font.body.small font: Tokens.font.body.small
text: (root.modelData?.comment || root.modelData?.genericName || root.modelData?.name) ?? "" text: (root.modelData?.comment || root.modelData?.genericName || root.modelData?.name) ?? ""
width: root.width - icon.width - Tokens.rounding.medium - Tokens.padding.medium * 2 verticalAlignment: CustomText.AlignVCenter
horizontalAlignment: CustomText.AlignLeft
} }
} }
@@ -70,14 +92,16 @@ Item {
id: favoriteIcon id: favoriteIcon
active: root.modelData && Strings.testRegexList(Config.launcher.favoriteApps, root.modelData.id) active: root.modelData && Strings.testRegexList(Config.launcher.favoriteApps, root.modelData.id)
anchors.right: parent.right Layout.fillHeight: true
anchors.verticalCenter: parent.verticalCenter
asynchronous: true asynchronous: true
sourceComponent: MaterialIcon { sourceComponent: MaterialIcon {
color: Colors.palette.m3primary color: Colors.palette.m3primary
fill: 1 fill: 1
text: "favorite" text: "favorite"
verticalAlignment: MaterialIcon.AlignVCenter
} }
} }
} }
+2 -1
View File
@@ -2,6 +2,7 @@ import ZShell
import Quickshell import Quickshell
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import qs.Components import qs.Components
import qs.Modules import qs.Modules
import qs.Helpers import qs.Helpers
@@ -31,7 +32,7 @@ Item {
} }
} }
RowLayout { SnapLayout {
anchors.left: parent.left anchors.left: parent.left
anchors.margins: Tokens.padding.small anchors.margins: Tokens.padding.small
anchors.right: parent.right anchors.right: parent.right
+2 -1
View File
@@ -22,7 +22,8 @@ Searcher {
model: Config.launcher.actions.values.filter(a => (a.enabled ?? true) && (Config.launcher.enableDangerousActions || !(a.dangerous ?? false))) model: Config.launcher.actions.values.filter(a => (a.enabled ?? true) && (Config.launcher.enableDangerousActions || !(a.dangerous ?? false)))
Action {} Action {
}
} }
component Action: QtObject { component Action: QtObject {
+9 -4
View File
@@ -2,14 +2,15 @@ pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Config
import ZShell.Components
import qs.Paths import qs.Paths
import qs.Components import qs.Components
import qs.Helpers import qs.Helpers
import ZShell.Config
import qs.Modules import qs.Modules
import qs.Services import qs.Services
ColumnLayout { SnapLayout {
id: root id: root
readonly property real centerScale: Math.min(1, (lock.screen?.height ?? 1440) / 1440) readonly property real centerScale: Math.min(1, (lock.screen?.height ?? 1440) / 1440)
@@ -19,10 +20,13 @@ ColumnLayout {
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: false Layout.fillWidth: false
Layout.preferredWidth: centerWidth Layout.preferredWidth: centerWidth
orientation: Qt.Vertical
spacing: Tokens.spacing.largeIncreased * 2 spacing: Tokens.spacing.largeIncreased * 2
RowLayout { SnapLayout {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
spacing: Tokens.spacing.small spacing: Tokens.spacing.small
CustomText { CustomText {
@@ -109,11 +113,12 @@ ColumnLayout {
} }
} }
RowLayout { SnapLayout {
id: input id: input
anchors.fill: parent anchors.fill: parent
anchors.margins: Tokens.padding.extraSmall anchors.margins: Tokens.padding.extraSmall
spacing: Tokens.spacing.medium spacing: Tokens.spacing.medium
Item { Item {
+24 -6
View File
@@ -1,8 +1,9 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import ZShell.Config
import qs.Components import qs.Components
import qs.Helpers import qs.Helpers
import ZShell.Config
import qs.Services import qs.Services
Item { Item {
@@ -13,15 +14,18 @@ Item {
implicitHeight: layout.implicitHeight implicitHeight: layout.implicitHeight
implicitWidth: layout.implicitWidth implicitWidth: layout.implicitWidth
RowLayout { SnapLayout {
id: layout id: layout
anchors.fill: parent anchors.fill: parent
spacing: Tokens.spacing.largeIncreased * 2 spacing: Tokens.spacing.largeIncreased * 2
ColumnLayout { SnapLayout {
Layout.fillWidth: true Layout.fillWidth: true
spacing: Tokens.spacing.medium spacing: Tokens.spacing.medium
orientation: Qt.Vertical
WeatherInfo { WeatherInfo {
id: weather id: weather
@@ -49,10 +53,24 @@ Item {
lock: root.lock lock: root.lock
} }
NotifDock { SnapLayout {
Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
lock: root.lock
spacing: Tokens.spacing.medium
orientation: Qt.Vertical
CustomRect {
Layout.fillHeight: true
Layout.fillWidth: true
bottomRightRadius: Tokens.rounding.largeIncreased
color: Colors.tPalette.m3surfaceContainer
radius: Tokens.rounding.small
topRightRadius: Tokens.rounding.largeIncreased
NotifDock {
lock: root.lock
}
}
} }
} }
} }

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