Author SHA1 Message Date
zach 78a9577209 Merge branch 'main' into feat/device-pixel-alignment
C++ / fmt (pull_request) Failing after 6s
C++ / build (pull_request) Failing after 10s
C++ / clang-tidy (pull_request) Failing after 10s
JS/TS / fmt (pull_request) Successful in 7s
JS/TS / lint (pull_request) Successful in 9s
Python / static (pull_request) Successful in 26s
Rust / build (pull_request) Successful in 54s
Python / verify (pull_request) Failing after 1m29s
Rust / fmt (pull_request) Successful in 36s
Rust / clippy (pull_request) Successful in 50s
2026-10-29 20:11:33 +01:00
zach 90184bff58 Merge pull request 'feat: video wallpapers' (#163) from feat/video-wallpaper into main
Reviewed-on: #163
2026-10-29 19:55:05 +01:00
zach abdde2450d fix: don't use lambda expression
C++ / fmt (pull_request) Failing after 5s
C++ / build (pull_request) Failing after 10s
C++ / clang-tidy (pull_request) Failing after 11s
JS/TS / fmt (pull_request) Successful in 7s
JS/TS / lint (pull_request) Successful in 9s
Python / static (pull_request) Successful in 30s
Rust / build (pull_request) Successful in 50s
Python / verify (pull_request) Failing after 1m27s
Rust / fmt (pull_request) Successful in 31s
Rust / clippy (pull_request) Successful in 58s
2026-10-29 19:50:02 +01:00
zach fd05b3d4c4 Merge branch 'main' into feat/video-wallpaper
C++ / fmt (pull_request) Failing after 5s
C++ / build (pull_request) Failing after 9s
C++ / clang-tidy (pull_request) Failing after 10s
JS/TS / fmt (pull_request) Successful in 13s
JS/TS / lint (pull_request) Successful in 8s
Python / static (pull_request) Failing after 37s
Rust / build (pull_request) Successful in 50s
Python / verify (pull_request) Failing after 1m28s
Rust / fmt (pull_request) Successful in 39s
Rust / clippy (pull_request) Successful in 1m5s
2026-10-29 19:03:10 +01:00
zach 067291f478 fix: lockscreen notifdock
C++ / fmt (pull_request) Failing after 5s
C++ / build (pull_request) Failing after 9s
C++ / clang-tidy (pull_request) Failing after 10s
JS/TS / fmt (pull_request) Successful in 7s
JS/TS / lint (pull_request) Successful in 14s
Python / static (pull_request) Failing after 27s
Rust / build (pull_request) Successful in 47s
Python / verify (pull_request) Failing after 1m23s
Rust / fmt (pull_request) Successful in 35s
Rust / clippy (pull_request) Successful in 53s
2026-10-29 18:43:50 +01:00
zach 395d1dad3d fix: remove duped property 2026-10-29 17:51:20 +01:00
zach fe0ce991da feat: initial commit for pixel-snapping components and helpers 2026-10-29 17:47:19 +01:00
zach 858e4e5b12 rebase to feat/video-wallpapers 2026-10-29 17:46:27 +01:00
zach ed7e977eb5 fix: remove more uses of cliprect and finally fix workspace's layer texture 2026-10-29 17:44:19 +01:00
zach 4252812e82 fix: don't link eglDestroyImageKHR 2026-10-29 17:44:19 +01:00
zach a893e6cbe6 feat: add vaapi path for video wallpapers on generic gpus 2026-10-29 17:44:19 +01:00
zach 3792e9d73f feat: add wallpaper transitions, store crop in database per-wallpaper, move CUDA context creation to async thread 2026-10-29 17:44:19 +01:00
zach 906b15b092 fix: don't store dbPath as const 2026-10-29 17:44:19 +01:00
zach 811ad6b7f4 fix: restore code removed by incorrect replacement command 2026-10-29 17:44:19 +01:00
zach 76f5a23c2a feat: skip two-way copy for cuda devices when decoding video wallpapers + cache wallpapers as blobs in new database 2026-10-29 17:44:19 +01:00
zach c0744b29b6 chore: suppress more warnings 2026-10-29 17:44:19 +01:00
zach 5896256372 feat: initial video wallpaper implementation 2026-10-29 17:44:19 +01:00
zach 9cbb90f9e1 feat: initial commit for pixel-snapping components and helpers 2026-10-29 17:34:57 +01:00
zach 9d8bde1413 fix: update for hyprland 0.57 2026-10-29 11:59:50 +01:00
zach 118b8f482a fix: fix sub-pixel layout arrangement for normalized resolutions
C++ / fmt (pull_request) Failing after 7s
C++ / build (pull_request) Failing after 10s
C++ / clang-tidy (pull_request) Failing after 10s
JS/TS / fmt (pull_request) Successful in 11s
JS/TS / lint (pull_request) Successful in 9s
Python / static (pull_request) Failing after 31s
Rust / build (pull_request) Successful in 49s
Python / verify (pull_request) Failing after 1m28s
Rust / fmt (pull_request) Successful in 30s
Rust / clippy (pull_request) Successful in 54s
2026-10-27 23:00:26 +01:00
zach b58b4fdc9c fix: remove more uses of cliprect and finally fix workspace's layer texture
C++ / fmt (pull_request) Failing after 5s
C++ / build (pull_request) Failing after 10s
C++ / clang-tidy (pull_request) Failing after 10s
JS/TS / fmt (pull_request) Successful in 9s
JS/TS / lint (pull_request) Successful in 9s
Python / static (pull_request) Failing after 33s
Rust / build (pull_request) Successful in 48s
Python / verify (pull_request) Failing after 1m24s
Rust / fmt (pull_request) Successful in 32s
Rust / clippy (pull_request) Successful in 57s
2026-10-27 15:15:57 +01:00
zach a56afd7fac fix: don't link eglDestroyImageKHR
C++ / fmt (pull_request) Failing after 7s
C++ / build (pull_request) Failing after 10s
C++ / clang-tidy (pull_request) Failing after 10s
JS/TS / fmt (pull_request) Successful in 7s
JS/TS / lint (pull_request) Successful in 9s
Python / static (pull_request) Failing after 27s
Rust / build (pull_request) Successful in 47s
Python / verify (pull_request) Failing after 1m24s
Rust / fmt (pull_request) Successful in 29s
Rust / clippy (pull_request) Successful in 45s
2026-10-27 02:30:55 +01:00
zach b0cb43f75c feat: add vaapi path for video wallpapers on generic gpus
C++ / fmt (pull_request) Failing after 6s
C++ / build (pull_request) Failing after 10s
C++ / clang-tidy (pull_request) Failing after 11s
JS/TS / fmt (pull_request) Successful in 10s
JS/TS / lint (pull_request) Successful in 8s
Python / static (pull_request) Failing after 32s
Rust / build (pull_request) Successful in 52s
Python / verify (pull_request) Failing after 1m23s
Rust / fmt (pull_request) Successful in 51s
Rust / clippy (pull_request) Successful in 1m2s
2026-10-27 02:15:16 +01:00
zach e655ec5bc7 feat: add wallpaper transitions, store crop in database per-wallpaper, move CUDA context creation to async thread
C++ / fmt (pull_request) Failing after 5s
C++ / build (pull_request) Failing after 9s
C++ / clang-tidy (pull_request) Failing after 10s
JS/TS / fmt (pull_request) Successful in 10s
JS/TS / lint (pull_request) Successful in 8s
Python / static (pull_request) Failing after 28s
Python / verify (pull_request) Failing after 1m29s
Rust / build (pull_request) Successful in 53s
Rust / fmt (pull_request) Successful in 42s
Rust / clippy (pull_request) Successful in 1m4s
2026-10-26 14:47:47 +01:00
zach dc0f222ace fix: don't store dbPath as const
C++ / fmt (pull_request) Failing after 5s
C++ / build (pull_request) Failing after 10s
C++ / clang-tidy (pull_request) Failing after 10s
JS/TS / fmt (pull_request) Successful in 7s
JS/TS / lint (pull_request) Successful in 9s
Python / static (pull_request) Failing after 27s
Rust / build (pull_request) Successful in 47s
Python / verify (pull_request) Failing after 1m24s
Rust / fmt (pull_request) Successful in 30s
Rust / clippy (pull_request) Successful in 53s
2026-10-26 03:13:33 +01:00
zach de19fd6ac4 fix: restore code removed by incorrect replacement command
C++ / fmt (pull_request) Failing after 5s
C++ / clang-tidy (pull_request) Failing after 4s
C++ / build (pull_request) Failing after 9s
JS/TS / fmt (pull_request) Successful in 6s
JS/TS / lint (pull_request) Successful in 9s
Python / static (pull_request) Failing after 28s
Rust / build (pull_request) Successful in 48s
Python / verify (pull_request) Failing after 1m19s
Rust / fmt (pull_request) Successful in 36s
Rust / clippy (pull_request) Successful in 1m0s
2026-10-26 03:03:20 +01:00
zach 9edbcbd610 feat: skip two-way copy for cuda devices when decoding video wallpapers + cache wallpapers as blobs in new database
C++ / fmt (pull_request) Failing after 11s
C++ / build (pull_request) Failing after 14s
C++ / clang-tidy (pull_request) Failing after 9s
JS/TS / fmt (pull_request) Successful in 10s
JS/TS / lint (pull_request) Successful in 8s
Python / static (pull_request) Failing after 28s
Rust / build (pull_request) Successful in 47s
Python / verify (pull_request) Failing after 1m20s
Rust / fmt (pull_request) Successful in 28s
Rust / clippy (pull_request) Successful in 59s
2026-10-26 02:51:28 +01:00
zach cd44d27b74 chore: suppress more warnings
C++ / fmt (pull_request) Failing after 5s
C++ / build (pull_request) Failing after 10s
C++ / clang-tidy (pull_request) Failing after 10s
JS/TS / fmt (pull_request) Successful in 7s
JS/TS / lint (pull_request) Successful in 9s
Python / static (pull_request) Successful in 29s
Rust / build (pull_request) Successful in 59s
Python / verify (pull_request) Failing after 1m31s
Rust / fmt (pull_request) Successful in 33s
Rust / clippy (pull_request) Successful in 52s
2026-10-25 02:10:50 +02:00
zach 0d0faecb1c feat: initial video wallpaper implementation 2026-10-25 02:10:50 +02:00
zach 200a6a5d54 fix: suppress private headers cmake warning 2026-10-25 02:07:38 +02:00
zach 2d2231745c fix: remove layer from settings when fading 2026-10-25 01:49:53 +02:00
zach 187e97a081 fix: notifications no longer hide when dashboard is open 2026-10-24 17:29:17 +02:00
zach 0f54d93675 fix: suppress unnecessary log output 2026-10-24 17:12:35 +02:00
224 changed files with 10817 additions and 2241 deletions
+3
View File
@@ -0,0 +1,3 @@
#omz revision: d2b7f557cceaddb16ba89bbf8200d8a8df35c4d8
#omz fpath: /home/zach/.oh-my-zsh/plugins/colored-man-pages /home/zach/.oh-my-zsh/plugins/universalarchive /home/zach/.oh-my-zsh/plugins/tldr /home/zach/.oh-my-zsh/plugins/extract /home/zach/.oh-my-zsh/plugins/copypath /home/zach/.oh-my-zsh/plugins/cp /home/zach/.oh-my-zsh/plugins/conda-env /home/zach/.oh-my-zsh/plugins/command-not-found /home/zach/.oh-my-zsh/plugins/dirhistory /home/zach/.oh-my-zsh/plugins/copybuffer /home/zach/.oh-my-zsh/plugins/copyfile /home/zach/.oh-my-zsh/custom/plugins/fast-syntax-highlighting /home/zach/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting /home/zach/.oh-my-zsh/custom/plugins/zsh-autosuggestions /home/zach/.oh-my-zsh/plugins/archlinux /home/zach/.oh-my-zsh/plugins/web-search /home/zach/.oh-my-zsh/plugins/sudo /home/zach/.oh-my-zsh/plugins/git /home/zach/.oh-my-zsh/functions /home/zach/.oh-my-zsh/completions /home/zach/.oh-my-zsh/custom/functions /home/zach/.oh-my-zsh/custom/completions /home/zach/tools/ripgrep/complete /home/linuxbrew/.linuxbrew/share/zsh/site-functions /home/zach/.oh-my-zsh/plugins/colored-man-pages /home/zach/.oh-my-zsh/plugins/universalarchive /home/zach/.oh-my-zsh/plugins/tldr /home/zach/.oh-my-zsh/plugins/extract /home/zach/.oh-my-zsh/plugins/copypath /home/zach/.oh-my-zsh/plugins/cp /home/zach/.oh-my-zsh/plugins/conda-env /home/zach/.oh-my-zsh/plugins/command-not-found /home/zach/.oh-my-zsh/plugins/dirhistory /home/zach/.oh-my-zsh/plugins/copybuffer /home/zach/.oh-my-zsh/plugins/copyfile /home/zach/.oh-my-zsh/custom/plugins/fast-syntax-highlighting /home/zach/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting /home/zach/.oh-my-zsh/custom/plugins/zsh-autosuggestions /home/zach/.oh-my-zsh/plugins/archlinux /home/zach/.oh-my-zsh/plugins/web-search /home/zach/.oh-my-zsh/plugins/sudo /home/zach/.oh-my-zsh/plugins/git /home/zach/.oh-my-zsh/functions /home/zach/.oh-my-zsh/completions /home/zach/.oh-my-zsh/custom/functions /home/zach/.oh-my-zsh/custom/completions /home/zach/.oh-my-zsh/cache/completions /home/zach/tools/ripgrep/complete /home/linuxbrew/.linuxbrew/share/zsh/site-functions /usr/local/share/zsh/site-functions /usr/share/zsh/site-functions /usr/share/zsh/functions/Calendar /usr/share/zsh/functions/Chpwd /usr/share/zsh/functions/Completion /usr/share/zsh/functions/Completion/Base /usr/share/zsh/functions/Completion/Linux /usr/share/zsh/functions/Completion/Unix /usr/share/zsh/functions/Completion/X /usr/share/zsh/functions/Completion/Zsh /usr/share/zsh/functions/Exceptions /usr/share/zsh/functions/MIME /usr/share/zsh/functions/Math /usr/share/zsh/functions/Misc /usr/share/zsh/functions/Newuser /usr/share/zsh/functions/Prompts /usr/share/zsh/functions/TCP /usr/share/zsh/functions/VCS_Info /usr/share/zsh/functions/VCS_Info/Backends /usr/share/zsh/functions/Zftp /usr/share/zsh/functions/Zle /home/zach/.zfunc
+1
View File
@@ -50,6 +50,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(QT_NO_PRIVATE_MODULE_WARNING ON)
set(ENABLE_MODULES "plugin;shell;cli;m3shapes" CACHE STRING "Modules to build/install") set(ENABLE_MODULES "plugin;shell;cli;m3shapes" CACHE STRING "Modules to build/install")
set(INSTALL_LIBDIR "${CMAKE_INSTALL_LIBDIR}/ZShell" CACHE STRING "Library install dir") set(INSTALL_LIBDIR "${CMAKE_INSTALL_LIBDIR}/ZShell" CACHE STRING "Library install dir")
+3 -2
View File
@@ -1,4 +1,5 @@
import QtQuick import QtQuick
import Quickshell
import ZShell.Components import ZShell.Components
Item { Item {
@@ -19,7 +20,7 @@ Item {
} }
ShaderEffectSource { ShaderEffectSource {
id: source id: src
hideSource: true hideSource: true
sourceItem: contentItem sourceItem: contentItem
@@ -27,7 +28,7 @@ Item {
RoundedMask { RoundedMask {
anchors.fill: parent anchors.fill: parent
source: source source: src
topLeftRadius: root.topLeftRadius topLeftRadius: root.topLeftRadius
topRightRadius: root.topRightRadius topRightRadius: root.topRightRadius
bottomRightRadius: root.bottomRightRadius bottomRightRadius: root.bottomRightRadius
+3 -4
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
@@ -124,8 +125,7 @@ ProgressBar {
anchors.left: parent.left anchors.left: parent.left
Behavior on implicitWidth { Behavior on implicitWidth {
Anim { Anim {}
}
} }
Component.onCompleted: implicitWidth = Qt.binding(() => parent.width * root.visualPosition) Component.onCompleted: implicitWidth = Qt.binding(() => parent.width * root.visualPosition)
@@ -222,8 +222,7 @@ ProgressBar {
} }
} }
Behavior on color { Behavior on color {
CAnim { CAnim {}
}
} }
Anim on waveProgress { Anim on waveProgress {
duration: root.waveDuration duration: root.waveDuration
+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 {
+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 -62
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;
for (let i = 0; i < n - 1; i++) {
const p0 = pts[Math.max(i - 1, 0)];
const p1 = pts[i]; const p1 = pts[i];
const p2 = pts[i + 1]; const p2 = pts[i + 1];
const p3 = pts[Math.min(i + 2, n - 1)]; const [c1x, c1y, c2x, c2y] = segmentControls(pts, i);
let c1x = p1.x + (p2.x - p0.x) * k; const firstCol = Math.ceil(p1.x * dpr) + 1;
let c1y = p1.y + (p2.y - p0.y) * k; const lastCol = Math.floor(p2.x * dpr) - 1;
let c2x = p2.x - (p3.x - p1.x) * k; for (let col = firstCol; col <= lastCol; ++col) {
let c2y = p2.y - (p3.y - p1.y) * k; const x = col / dpr;
ctx.lineTo(x, bezierY(p1, c1x, c1y, c2x, c2y, p2, x));
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++) {
@@ -138,10 +147,16 @@ Item {
const t = (tlo + thi) / 2; const t = (tlo + thi) / 2;
const u = 1 - t; const u = 1 - t;
const y = u * u * u * p1.y + 3 * u * u * t * c1y + 3 * u * t * t * c2y + t * t * t * p2.y; const y = u * u * u * p1.y + 3 * u * u * t * c1y + 3 * u * t * t * c2y + t * t * t * p2.y;
return { x: targetX, y }; return {
x: targetX,
y
};
}
function cutPoint(pts, targetX) {
return pointAtX(pts, targetX);
} }
// Part of the curve left/right of a cut x, including the cut point
function cutLeft(pts, targetX) { function cutLeft(pts, targetX) {
if (targetX <= pts[0].x) if (targetX <= pts[0].x)
return []; return [];
@@ -158,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;
} }
@@ -184,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,
@@ -204,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);
@@ -279,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) {
@@ -292,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);
@@ -300,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);
@@ -313,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";
@@ -328,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);
} }
} }
@@ -341,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++) {
@@ -352,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)
@@ -369,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)
@@ -382,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);
@@ -390,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) {
@@ -398,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;
const lineX = snapLine(x, 1);
let dashY = plot.y;
let dashOn = true;
while (dashY < H) {
const dashEnd = Math.min(dashY + 4, H);
if (dashOn) {
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(crisp(x), plot.y); ctx.moveTo(lineX, snapV(dashY));
ctx.lineTo(crisp(x), H); ctx.lineTo(lineX, snapV(dashEnd));
ctx.stroke(); ctx.stroke();
ctx.setLineDash([]); }
dashY = dashEnd;
dashOn = !dashOn;
}
const i0 = Math.floor(root.markerX); const i0 = Math.floor(root.markerX);
const v0 = series[i0]; const v0 = series[i0];
@@ -430,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();
} }
} }
+9 -7
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
@@ -34,7 +35,7 @@ MouseArea {
cursorShape: expanded ? Qt.ArrowCursor : undefined cursorShape: expanded ? Qt.ArrowCursor : undefined
enabled: expanded enabled: expanded
hoverEnabled: expanded hoverEnabled: expanded
layer.enabled: opacity < 1 layer.enabled: false
opacity: expanded ? 1 : 0 opacity: expanded ? 1 : 0
parent: { parent: {
const win = QsWindow.window; const win = QsWindow.window;
@@ -101,8 +102,7 @@ MouseArea {
yScale: root.expanded ? 1 : 0.1 yScale: root.expanded ? 1 : 0.1
Behavior on yScale { Behavior on yScale {
Anim { Anim {}
}
} }
} }
@@ -111,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
@@ -137,8 +139,7 @@ MouseArea {
radius: menu.radius - column.anchors.margins radius: menu.radius - column.anchors.margins
Behavior on radius { Behavior on radius {
Anim { Anim {}
}
} }
StateLayer { StateLayer {
@@ -153,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 {
+2 -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
@@ -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
+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
-7
View File
@@ -43,13 +43,6 @@ Scope {
hasBar: root.geometry.barOnBottom hasBar: root.geometry.barOnBottom
} }
Timer {
interval: 5000
running: true
onTriggered: console.log("top height:", top.exclusiveZone, "left width:", left.exclusiveZone, "right width:", right.exclusiveZone, "bottom height:", bottom.exclusiveZone)
}
component ExclusionZone: CustomWindow { component ExclusionZone: CustomWindow {
property bool hasBar property bool hasBar
+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
+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
@@ -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 -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
+105 -43
View File
@@ -5,7 +5,7 @@ import Quickshell
import Quickshell.Io import Quickshell.Io
import QtQuick import QtQuick
import ZShell.Models import ZShell.Models
import ZShell.Internal import ZShell.Wallpaper
import ZShell.Config import ZShell.Config
import qs.Components import qs.Components
import qs.Services import qs.Services
@@ -16,24 +16,48 @@ Searcher {
id: root id: root
property string actualCurrent: WallpaperPath.currentWallpaperPath property string actualCurrent: WallpaperPath.currentWallpaperPath
property alias crops: adapter.monitorCrops
readonly property string current: showPreview ? previewPath : actualCurrent readonly property string current: showPreview ? previewPath : actualCurrent
property alias monitorCrops: monitorCrops readonly property string currentThumbnail: thumbnailFor(current)
readonly property bool currentIsVideo: isVideoPath(current)
property bool pendingPreviewClear property bool pendingPreviewClear
property bool previewColorLock property bool previewColorLock
property string previewPath property string previewPath
property bool recentlyChanged property bool recentlyChanged
property bool showPreview: false property bool showPreview: false
property int cropVersion: 0
function getCategoryFor(w: FileSystemEntry): string { function getCategoryFor(w: WallpaperEntry): string {
let category = w.parentDir.slice(Paths.wallsdir.length + 1); let category = w.parentDir.slice(Paths.wallsdir.length + 1);
if (category.includes("/")) if (category.includes("/"))
category = category.slice(0, category.indexOf("/")); category = category.slice(0, category.indexOf("/"));
return category; return category;
} }
readonly property var videoExts: ["mp4", "mkv", "webm", "avi", "mov", "wmv", "flv", "m4v", "mpg", "mpeg", "3gp", "ogv", "ts", "vob"]
function isVideoPath(path: string): bool {
if (!path)
return false;
const dot = path.lastIndexOf(".");
if (dot < 0)
return false;
return videoExts.includes(path.slice(dot + 1).toLowerCase());
}
function thumbnailFor(path: string): string {
if (!path)
return "";
for (const entry of root.list) {
if (entry.path === path)
return entry.thumbnailPath || path;
}
return path;
}
function getCrop(screen: string): var { function getCrop(screen: string): var {
return root.crops[screen]; return wallpapers.crop(root.current, screen);
} }
function preview(path: string): void { function preview(path: string): void {
@@ -50,19 +74,18 @@ Searcher {
else if (zoom > 5.0) else if (zoom > 5.0)
zoom = 5.0; zoom = 5.0;
root.crops[screen] = { wallpapers.setCrop(root.current, screen, {
x: rect.x, x: rect.x,
y: rect.y, y: rect.y,
width: rect.width, width: rect.width,
height: rect.height, height: rect.height,
zoom: zoom zoom: zoom
}; });
} }
function setWallpaper(path: string): void { function setWallpaper(path: string): void {
actualCurrent = path; actualCurrent = path;
WallpaperPath.currentWallpaperPath = path; WallpaperPath.currentWallpaperPath = path;
Quickshell.screens.forEach(n => setCrop(n.name, Qt.rect(0, 0, 1, 1), 1.0));
Quickshell.execDetached(["zshell-cli", "wallpaper", "lockscreen", "--input-image", `${root.actualCurrent}`, "--output-path", `${Paths.state}/lockscreen_bg.png`, "--blur-amount", `${Config.lock.blurAmount}`]); Quickshell.execDetached(["zshell-cli", "wallpaper", "lockscreen", "--input-image", `${root.actualCurrent}`, "--output-path", `${Paths.state}/lockscreen_bg.png`, "--blur-amount", `${Config.lock.blurAmount}`]);
if (Config.colors.schemeGen) if (Config.colors.schemeGen)
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--image-path", `${root.actualCurrent}`, "--scheme", `${Config.colors.schemeType}`, "--mode", `${Config.colors.mode}`]); Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--image-path", `${root.actualCurrent}`, "--scheme", `${Config.colors.schemeType}`, "--mode", `${Config.colors.mode}`]);
@@ -96,38 +119,13 @@ Searcher {
target: "wallpaper" target: "wallpaper"
} }
FileView { WallpaperDb {
id: monitorCrops
path: `${Paths.state}/wallpaper-crops.json`
watchChanges: true
onAdapterUpdated: cropWriteDelay.restart()
onFileChanged: reload()
JsonAdapter {
id: adapter
property var monitorCrops: ({})
}
}
Timer {
id: cropWriteDelay
interval: 100
repeat: false
running: false
onTriggered: monitorCrops.writeAdapter()
}
FileSystemModel {
id: wallpapers id: wallpapers
filter: FileSystemModel.Images dbPath: `${Paths.state}/wallpapers.sqlite`
cacheSize: wallpaper.largestBufferSize
requireHardwareCodec: true
path: Config.general.wallpaperPath path: Config.general.wallpaperPath
recursive: true
} }
Process { Process {
@@ -146,36 +144,100 @@ Searcher {
WallpaperService { WallpaperService {
id: wallpaper id: wallpaper
dbPath: wallpapers.dbPath
path: root.current path: root.current
} }
Connections {
target: wallpapers
function onCacheStored(path: string): void {
if (path === root.current)
wallpaper.invalidateCache();
}
function onCropsChanged(path: string): void {
if (path === root.current)
root.cropVersion++;
}
}
Variants { Variants {
id: screenVariants
model: Quickshell.screens model: Quickshell.screens
WallpaperObject { WallpaperObject {
readonly property var crops: root.getCrop(modelData.name) id: obj
required property var modelData required property var modelData
cropHeight: crops?.height ?? 1.0 // Crop animation only for edits, never for wallpaper swaps.
cropWidth: crops?.width ?? 1.0 property bool animateCrop: false
cropX: crops?.x ?? 0.0
cropY: crops?.y ?? 0.0
screen: modelData.name screen: modelData.name
service: wallpaper service: wallpaper
zoom: crops?.zoom ?? 1.0
// Apply the wallpaper's own crop. Driven off the service's pathChanged
// (which fires after applyPath has snapshotted the outgoing frame with
// the outgoing crop) and off crop edits, never as a reactive binding on
// the wallpaper path — so a swap applies the incoming crop atomically
// after the base is captured.
function seedCrop(): void {
// Load the current wallpaper's crop without pushing: the service
// already read it from the database. This only seeds the values so
// a later edit animates from the right starting point.
obj.syncCrop(root.getCrop(modelData.name));
}
// Apply an edited crop: assign via the setters so the Behaviors animate
// the numbers and push each intermediate value to the service.
function editCrop(): void {
const c = root.getCrop(modelData.name);
obj.cropX = c?.x ?? 0.0;
obj.cropY = c?.y ?? 0.0;
obj.cropWidth = c?.width ?? 1.0;
obj.cropHeight = c?.height ?? 1.0;
obj.zoom = c?.zoom ?? 1.0;
}
Component.onCompleted: seedCrop()
onScreenChanged: seedCrop()
Behavior on cropHeight { Behavior on cropHeight {
enabled: obj.animateCrop
Anim {} Anim {}
} }
Behavior on cropWidth { Behavior on cropWidth {
enabled: obj.animateCrop
Anim {} Anim {}
} }
Behavior on cropX { Behavior on cropX {
enabled: obj.animateCrop
Anim {} Anim {}
} }
Behavior on cropY { Behavior on cropY {
enabled: obj.animateCrop
Anim {} Anim {}
} }
} }
} }
Connections {
target: wallpaper
function onPathChanged(): void {
for (const obj of screenVariants.instances) {
obj.animateCrop = false;
obj.seedCrop();
}
}
}
Connections {
target: root
function onCropVersionChanged(): void {
for (const obj of screenVariants.instances) {
obj.animateCrop = true;
obj.editCrop();
}
}
}
} }
+57 -9
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
@@ -210,8 +249,7 @@ GridLayout {
roleValue: "network" roleValue: "network"
delegate: EntryWrapper { delegate: EntryWrapper {
NetworkWidget { NetworkWidget {}
}
} }
} }
@@ -229,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
+7 -3
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,9 +44,11 @@ WidgetBase {
timeTokens: timeTokens timeTokens: timeTokens
}; };
} }
required property GridLayout loader required property SnapLayout loader
required property Wrapper popouts required property Wrapper popouts
readonly property real size: horizontal ? timeText.contentWidth + Tokens.padding.medium * 2 : verticalColumn.implicitHeight + Tokens.padding.medium * 2 readonly property int roundedWidth: Math.round(timeText.implicitWidth)
readonly property int evenWidth: roundedWidth % 2 === 0 ? roundedWidth : roundedWidth + 1
readonly property real size: horizontal ? evenWidth + Tokens.padding.medium * 2 : verticalColumn.implicitHeight + Tokens.padding.medium * 2
required property ScreenState screenState required property ScreenState screenState
implicitHeight: horizontal ? baseSize : size implicitHeight: horizontal ? baseSize : size
@@ -67,7 +70,8 @@ WidgetBase {
} }
} }
ColumnLayout { SnapLayout {
orientation: Qt.Vertical
id: verticalColumn id: verticalColumn
anchors.centerIn: parent anchors.centerIn: parent
@@ -24,7 +24,7 @@ Row {
color: Battery.getColors(root.percentage, root.devState).bg color: Battery.getColors(root.percentage, root.devState).bg
height: root.batHeight height: root.batHeight
radius: root.radius radius: root.radius
width: root.batWidth width: root.batWidth - 1
CustomText { CustomText {
color: Battery.getColors(root.percentage, root.devState).fg color: Battery.getColors(root.percentage, root.devState).fg
+2 -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
@@ -13,7 +14,7 @@ WidgetBase {
readonly property int textWidth: Math.min(metrics.width, 200) readonly property int textWidth: Math.min(metrics.width, 200)
implicitHeight: horizontal ? baseSize : layout.implicitHeight + Tokens.padding.small * 2 implicitHeight: horizontal ? baseSize : layout.implicitHeight + Tokens.padding.small * 2
implicitWidth: horizontal ? layout.implicitWidth + Tokens.padding.small * 2 : baseSize implicitWidth: horizontal ? (layout.implicitWidth % 2 === 0 ? layout.implicitWidth : layout.implicitWidth + 1) + Tokens.padding.small * 2 : baseSize
radius: Tokens.rounding.full radius: Tokens.rounding.full
Behavior on implicitHeight { Behavior on implicitHeight {
+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
+9 -12
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
@@ -12,7 +13,6 @@ GridLayout {
property real animatedPercentage: 0 property real animatedPercentage: 0
readonly property real arcStartAngle: 0.75 * Math.PI readonly property real arcStartAngle: 0.75 * Math.PI
readonly property real arcSweep: 1.5 * Math.PI readonly property real arcSweep: 1.5 * Math.PI
readonly property real dpr: (QsWindow.window as QsWindow)?.devicePixelRatio ?? 1
required property bool horizontal required property bool horizontal
property string icon property string icon
required property color iconColor required property color iconColor
@@ -23,17 +23,12 @@ GridLayout {
property bool warning: percentage * 100 >= warningThreshold property bool warning: percentage * 100 >= warningThreshold
property int warningThreshold: 80 property int warningThreshold: 80
function snap(v) {
return Math.round(v * dpr) / dpr;
}
columnSpacing: Tokens.spacing.medium columnSpacing: Tokens.spacing.medium
columns: horizontal ? -1 : 1 columns: horizontal ? -1 : 1
percentage: 0 percentage: 0
Behavior on animatedPercentage { Behavior on animatedPercentage {
Anim { Anim {}
}
} }
Component.onCompleted: animatedPercentage = percentage Component.onCompleted: animatedPercentage = percentage
@@ -59,7 +54,7 @@ GridLayout {
Layout.preferredHeight: root.horizontal ? icon.implicitHeight - Tokens.padding.extraSmall : 4 Layout.preferredHeight: root.horizontal ? icon.implicitHeight - Tokens.padding.extraSmall : 4
Layout.preferredWidth: root.horizontal ? 4 : icon.implicitWidth Layout.preferredWidth: root.horizontal ? 4 : icon.implicitWidth
color: Colors.layer(Colors.palette.m3surfaceContainerHigh, 2) color: Colors.layer(Colors.palette.m3surfaceContainerHigh, 2)
radius: Math.min(width, height) / 2 radius: Tokens.rounding.full
Item { Item {
id: clipper id: clipper
@@ -69,18 +64,20 @@ GridLayout {
anchors.left: root.horizontal ? undefined : parent.left anchors.left: root.horizontal ? undefined : parent.left
anchors.verticalCenter: root.horizontal ? undefined : parent.verticalCenter anchors.verticalCenter: root.horizontal ? undefined : parent.verticalCenter
clip: true clip: true
height: root.horizontal ? root.snap(root.percentage * track.height) : track.height * 2 implicitHeight: root.horizontal ? root.percentage * track.height : track.height * 2
width: root.horizontal ? track.width * 2 : root.snap(root.percentage * track.width) implicitWidth: root.horizontal ? track.width * 2 : root.percentage * track.width
CustomRect { CustomRect {
anchors.bottom: root.horizontal ? parent.bottom : undefined anchors.bottom: root.horizontal ? parent.bottom : undefined
anchors.horizontalCenter: root.horizontal ? parent.horizontalCenter : undefined anchors.horizontalCenter: root.horizontal ? parent.horizontalCenter : undefined
anchors.left: root.horizontal ? undefined : parent.left anchors.left: root.horizontal ? undefined : parent.left
anchors.verticalCenter: root.horizontal ? undefined : parent.verticalCenter anchors.verticalCenter: root.horizontal ? undefined : parent.verticalCenter
color: root.mainColor color: root.mainColor
height: track.height
radius: track.radius radius: track.radius
width: track.width
implicitHeight: track.height
implicitWidth: track.width
} }
} }
} }
+3
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
@@ -33,6 +34,7 @@ WidgetBase {
anchors.horizontalCenterOffset: root.horizontal ? 0 : 1 anchors.horizontalCenterOffset: root.horizontal ? 0 : 1
anchors.verticalCenterOffset: root.horizontal ? 0 : -3 anchors.verticalCenterOffset: root.horizontal ? 0 : -3
columnSpacing: Tokens.spacing.small columnSpacing: Tokens.spacing.small
rowSpacing: 0
columns: root.horizontal ? -1 : 1 columns: root.horizontal ? -1 : 1
ServiceRef { ServiceRef {
@@ -51,6 +53,7 @@ WidgetBase {
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
Layout.fillHeight: root.horizontal Layout.fillHeight: root.horizontal
Layout.fillWidth: !root.horizontal Layout.fillWidth: !root.horizontal
horizontal: root.horizontal horizontal: root.horizontal
icon: "memory" icon: "memory"
iconColor: root.screenState.resources ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface iconColor: root.screenState.resources ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
+10 -11
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
@@ -31,7 +32,7 @@ WidgetBase {
return -1; return -1;
} }
readonly property real size: horizontal ? grid.implicitWidth + grid.anchors.leftMargin + grid.anchors.rightMargin : grid.implicitHeight + grid.anchors.bottomMargin + grid.anchors.topMargin readonly property real size: horizontal ? grid.implicitWidth + grid.anchors.leftMargin + grid.anchors.rightMargin : grid.implicitHeight + grid.anchors.bottomMargin + grid.anchors.topMargin
readonly property int spacing: Tokens.spacing.medium / 2 readonly property int spacing: Tokens.spacing.extraSmall
// Entries that can shrink to nothing, spacing included // Entries that can shrink to nothing, spacing included
function collapsed(entry: var): bool { function collapsed(entry: var): bool {
@@ -51,17 +52,15 @@ WidgetBase {
Behavior on implicitHeight { Behavior on implicitHeight {
enabled: !root.horizontal enabled: !root.horizontal
Anim { Anim {}
}
} }
Behavior on implicitWidth { Behavior on implicitWidth {
enabled: root.horizontal enabled: root.horizontal
Anim { Anim {}
}
} }
GridLayout { SnapLayout {
id: grid id: grid
anchors.bottomMargin: root.horizontal ? 0 : Tokens.padding.medium anchors.bottomMargin: root.horizontal ? 0 : Tokens.padding.medium
@@ -69,7 +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
spacing: root.horizontal ? Tokens.spacing.extraSmall : -2
Repeater { Repeater {
model: ScriptModel { model: ScriptModel {
@@ -111,8 +111,7 @@ WidgetBase {
delegate: EntryWrapper { delegate: EntryWrapper {
name: "upower" name: "upower"
UPowerWidget { UPowerWidget {}
}
} }
} }
} }
@@ -135,8 +134,8 @@ WidgetBase {
Layout.rightMargin: root.horizontal ? Math.round(rightGap) : 0 Layout.rightMargin: root.horizontal ? Math.round(rightGap) : 0
Layout.topMargin: root.horizontal ? 0 : Math.round(leftGap) Layout.topMargin: root.horizontal ? 0 : Math.round(leftGap)
children: item children: item
implicitHeight: item?.implicitHeight ?? 0 implicitHeight: item?.height ?? item?.implicitHeight ?? 0
implicitWidth: item?.implicitWidth ?? 0 implicitWidth: item?.width ?? item?.implicitWidth ?? 0
Behavior on leftGap { Behavior on leftGap {
Anim { Anim {
@@ -1,12 +1,13 @@
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
import qs.Services import qs.Services
MaterialIcon { MaterialIcon {
id: speaker id: root
required property bool horizontal required property bool horizontal
@@ -15,6 +16,8 @@ MaterialIcon {
fill: 1 fill: 1
fontStyle: Tokens.font.icon.small fontStyle: Tokens.font.icon.small
text: Audio.muted ? "volume_off" : "volume_up" text: Audio.muted ? "volume_off" : "volume_up"
width: Math.round(implicitWidth)
height: Math.round(implicitHeight)
Behavior on Layout.maximumWidth { Behavior on Layout.maximumWidth {
Anim {} Anim {}
@@ -1,12 +1,13 @@
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
import qs.Services import qs.Services
MaterialIcon { MaterialIcon {
id: mic id: root
required property bool horizontal required property bool horizontal
@@ -15,6 +16,8 @@ MaterialIcon {
fill: 1 fill: 1
fontStyle: Tokens.font.icon.small fontStyle: Tokens.font.icon.small
text: Audio.sourceMuted ? "mic_off" : "mic" text: Audio.sourceMuted ? "mic_off" : "mic"
width: Math.round(implicitWidth)
height: Math.round(implicitHeight)
Behavior on Layout.maximumWidth { Behavior on Layout.maximumWidth {
Anim {} Anim {}
@@ -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
+4 -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 {
@@ -79,6 +80,7 @@ Item {
anchors.centerIn: parent anchors.centerIn: parent
antialiasing: true antialiasing: true
backer.retainWhileLoading: true
color: root.current && !Config.bar.tray.showOnHover ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface color: root.current && !Config.bar.tray.showOnHover ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
implicitSize: Config.bar.tray.trayIconSize * root.dpr implicitSize: Config.bar.tray.trayIconSize * root.dpr
layer.enabled: Config.bar.tray.recolorIcons layer.enabled: Config.bar.tray.recolorIcons
+5 -4
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,8 +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
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
+18 -20
View File
@@ -12,13 +12,14 @@ import qs.Services
Item { Item {
id: root id: root
property real activeWorkspaceMargin: Math.ceil(Tokens.padding.medium / 4) property real activeWorkspaceMargin: Tokens.padding.extraSmall / 2
readonly property int spacing: Tokens.spacing.extraSmall / 2
readonly property int effectiveActiveWorkspaceId: monitor?.activeWorkspace?.id ?? 1 readonly property int effectiveActiveWorkspaceId: monitor?.activeWorkspace?.id ?? 1
required property bool horizontal required property bool horizontal
readonly property HyprlandMonitor monitor: Hyprland.monitorFor(root.screen) readonly property HyprlandMonitor monitor: Hyprland.monitorFor(root.screen)
required property ShellScreen screen required property ShellScreen screen
readonly property real shortSize: Math.max(Config.bar.height, Tokens.sizes.bar.innerSize) readonly property real shortSize: Math.max(Config.bar.height, Tokens.sizes.bar.innerSize)
readonly property real size: (workspaceButtonWidth * workspacesShown) + activeWorkspaceMargin * 2 readonly property real size: (workspaceButtonWidth * workspacesShown) + (spacing * Math.max(0, workspacesShown - 1)) + activeWorkspaceMargin * 2
property int workspaceButtonWidth: (horizontal ? bgRect.implicitHeight : bgRect.implicitWidth) - root.activeWorkspaceMargin * 2 property int workspaceButtonWidth: (horizontal ? bgRect.implicitHeight : bgRect.implicitWidth) - root.activeWorkspaceMargin * 2
property int workspaceIndexInGroup: (effectiveActiveWorkspaceId - 1) % root.workspacesShown property int workspaceIndexInGroup: (effectiveActiveWorkspaceId - 1) % root.workspacesShown
readonly property list<var> workspaces: Hyprland.workspaces.values.filter(w => w.monitor === root.monitor) readonly property list<var> workspaces: Hyprland.workspaces.values.filter(w => w.monitor === root.monitor)
@@ -59,15 +60,17 @@ Item {
anchors.fill: parent anchors.fill: parent
anchors.margins: root.activeWorkspaceMargin anchors.margins: root.activeWorkspaceMargin
columnSpacing: 0 columnSpacing: root.spacing
columns: root.horizontal ? root.workspacesShown : 1 columns: root.horizontal ? root.workspacesShown : 1
rowSpacing: 0 rowSpacing: root.spacing
rows: root.horizontal ? 1 : root.workspacesShown rows: root.horizontal ? 1 : root.workspacesShown
layer.enabled: true
layer.mipmap: true
Repeater { Repeater {
model: root.workspaces model: root.workspaces
Button { CustomRect {
id: button id: button
required property int index required property int index
@@ -75,24 +78,15 @@ Item {
implicitHeight: indicator.indicatorThickness implicitHeight: indicator.indicatorThickness
implicitWidth: indicator.indicatorThickness implicitWidth: indicator.indicatorThickness
width: root.workspaceButtonWidth radius: Tokens.rounding.full
background: Item {
id: workspaceButtonBackground
implicitHeight: root.workspaceButtonWidth
implicitWidth: root.workspaceButtonWidth
CustomText { CustomText {
anchors.centerIn: parent anchors.centerIn: parent
color: Colors.palette.m3onSecondaryContainer color: Colors.palette.m3onSecondaryContainer
elide: Text.ElideRight
horizontalAlignment: Text.AlignHCenter
text: button.modelData?.name ?? "" text: button.modelData?.name ?? ""
verticalAlignment: Text.AlignVCenter
}
} }
StateLayer {
onPressed: { onPressed: {
const ws = button.modelData.name; const ws = button.modelData.name;
Hyprland.dispatch(Hyprland.usingLua ? `hl.dsp.focus({ workspace= "${ws}"})` : `workspace ${ws}`); Hyprland.dispatch(Hyprland.usingLua ? `hl.dsp.focus({ workspace= "${ws}"})` : `workspace ${ws}`);
@@ -100,12 +94,15 @@ Item {
} }
} }
} }
}
CustomRect { CustomRect {
id: indicator id: indicator
property real indicatorLength: (Math.abs(idxPair.idx1 - idxPair.idx2) + 1) * root.workspaceButtonWidth readonly property real step: root.workspaceButtonWidth + root.spacing
property real indicatorPosition: Math.min(idxPair.idx1, idxPair.idx2) * root.workspaceButtonWidth + root.activeWorkspaceMargin
property real indicatorLength: (Math.abs(idxPair.idx1 - idxPair.idx2) + 1) * root.workspaceButtonWidth + Math.abs(idxPair.idx1 - idxPair.idx2) * root.spacing
property real indicatorPosition: Math.min(idxPair.idx1, idxPair.idx2) * step + root.activeWorkspaceMargin
property real indicatorThickness: root.workspaceButtonWidth property real indicatorThickness: root.workspaceButtonWidth
anchors.horizontalCenter: root.horizontal ? undefined : parent.horizontalCenter anchors.horizontalCenter: root.horizontal ? undefined : parent.horizontalCenter
@@ -129,9 +126,10 @@ Item {
implicitHeight: grid.height implicitHeight: grid.height
implicitWidth: grid.width implicitWidth: grid.width
source: grid source: grid
autoPaddingEnabled: false
sourceColor: Colors.palette.m3onSurface sourceColor: Colors.palette.m3onSurface
x: root.horizontal ? -indicator.x + 3 : 0 x: root.horizontal ? -indicator.x + root.activeWorkspaceMargin : 0
y: root.horizontal ? 0 : -indicator.y + 3 y: root.horizontal ? 0 : -indicator.y + root.activeWorkspaceMargin
} }
} }
} }
+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 {
+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
+3 -1
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
@@ -47,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
+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
+7 -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 qs.Helpers import qs.Helpers
import ZShell.Config import ZShell.Config
@@ -54,7 +55,7 @@ Item {
} }
} }
ClipRect { CustomRect {
id: preview id: preview
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
@@ -64,6 +65,7 @@ Item {
color: Colors.tPalette.m3surfaceContainer color: Colors.tPalette.m3surfaceContainer
implicitWidth: ClipHistory.previewIsImage ? Math.max(Math.min(imagePreview.sourceSize.width + Tokens.padding.large * 2, Config.clipboard.sizes.previewWidth), Config.clipboard.sizes.minPreviewWidth) : Math.max(Math.min(textPreviewColumn.width + textPreviewColumn.anchors.margins * 2, Config.clipboard.sizes.previewWidth), Config.clipboard.sizes.minPreviewWidth) implicitWidth: ClipHistory.previewIsImage ? Math.max(Math.min(imagePreview.sourceSize.width + Tokens.padding.large * 2, Config.clipboard.sizes.previewWidth), Config.clipboard.sizes.minPreviewWidth) : Math.max(Math.min(textPreviewColumn.width + textPreviewColumn.anchors.margins * 2, Config.clipboard.sizes.previewWidth), Config.clipboard.sizes.minPreviewWidth)
radius: 25 radius: 25
clip: true
Behavior on implicitWidth { Behavior on implicitWidth {
Anim {} Anim {}
@@ -110,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
@@ -224,15 +226,16 @@ Item {
} }
} }
RowLayout { SnapLayout {
anchors.fill: parent anchors.fill: parent
spacing: Tokens.spacing.small spacing: Tokens.spacing.small
ClipRect { Item {
id: textRect id: textRect
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
clip: true
Item { Item {
id: textWrapper id: textWrapper
+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
+31 -53
View File
@@ -1,60 +1,45 @@
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" Layout.fillWidth: true
target: root spacing: parent.spacing
to: 1
}
Anim { Rect {
property: "scale" id: weatherRect
target: root Layout.fillHeight: true
to: 1 Layout.preferredWidth: ZUtils.snap(Tokens.sizes.dashboard.weatherWidth, root)
} radius: root.radius
}
ParallelAnimation { Weather {}
id: closeAnim
Anim {
property: "opacity"
target: root
to: 0
}
Anim {
property: "scale"
target: root
to: 0.9
}
} }
Rect { Rect {
Layout.column: 2 id: userRect
Layout.columnSpan: 3 Layout.preferredHeight: ZUtils.snap(user.implicitHeight, root)
Layout.preferredHeight: user.implicitHeight Layout.preferredWidth: ZUtils.snap(user.implicitWidth, root)
Layout.preferredWidth: user.implicitWidth
radius: root.radius radius: root.radius
User { User {
@@ -63,23 +48,17 @@ GridLayout {
screenState: root.screenState screenState: root.screenState
} }
} }
Rect {
Layout.columnSpan: 2
Layout.fillHeight: true
Layout.preferredWidth: Tokens.sizes.dashboard.weatherWidth
Layout.row: 0
radius: root.radius
Weather {}
} }
Rect { SnapLayout {
Layout.column: 0
Layout.columnSpan: 3
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: calendar.implicitHeight spacing: parent.spacing
Layout.row: 1
Rect {
id: calendarRect
Layout.fillWidth: true
Layout.fillHeight: true
implicitHeight: ZUtils.snap(calendar.implicitHeight, root)
radius: root.radius radius: root.radius
Calendar { Calendar {
@@ -90,17 +69,16 @@ GridLayout {
} }
Rect { Rect {
Layout.column: 3 id: resourcesRect
Layout.columnSpan: 2
Layout.fillHeight: true Layout.fillHeight: true
Layout.preferredWidth: resources.implicitWidth implicitWidth: ZUtils.snap(resources.implicitWidth, root)
Layout.row: 1
radius: root.radius radius: root.radius
Resources { Resources {
id: resources id: resources
} }
} }
}
component Rect: CustomRect { component Rect: CustomRect {
color: Colors.tPalette.m3surfaceContainer color: Colors.tPalette.m3surfaceContainer
+4 -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 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
+11 -9
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,12 +77,10 @@ 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 {}
}
} }
MaterialIcon { MaterialIcon {
+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 {
+37 -13
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,7 +26,17 @@ ColumnLayout {
return `${mins}:${secs}`; return `${mins}:${secs}`;
} }
spacing: Tokens.spacing.extraSmall implicitHeight: ZUtils.snap(layout.implicitHeight, root)
implicitWidth: layout.implicitWidth
SnapLayout {
orientation: Qt.Vertical
id: layout
anchors.left: parent.left
anchors.right: parent.right
y: ZUtils.snap((parent.height - implicitHeight) / 2, root)
spacing: ZUtils.snap(Tokens.spacing.extraSmall, root)
Timer { Timer {
running: Players.active?.isPlaying ?? false running: Players.active?.isPlaying ?? false
@@ -36,7 +47,9 @@ ColumnLayout {
} }
CustomText { CustomText {
id: title
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: ZUtils.snapCeil(implicitHeight, root)
text: Players.active?.trackTitle ?? "" text: Players.active?.trackTitle ?? ""
font: Tokens.font.title.large font: Tokens.font.title.large
elide: Text.ElideRight elide: Text.ElideRight
@@ -44,7 +57,9 @@ ColumnLayout {
} }
CustomText { CustomText {
id: artist
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: ZUtils.snapCeil(implicitHeight, root)
text: Players.active?.trackArtist || qsTr("Unknown artist") text: Players.active?.trackArtist || qsTr("Unknown artist")
color: Colors.palette.m3onSurfaceVariant color: Colors.palette.m3onSurfaceVariant
font: Tokens.font.title.medium font: Tokens.font.title.medium
@@ -53,7 +68,9 @@ ColumnLayout {
} }
CustomText { CustomText {
id: album
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: ZUtils.snapCeil(implicitHeight, root)
text: Players.active?.trackAlbum || qsTr("Unknown album") text: Players.active?.trackAlbum || qsTr("Unknown album")
color: Colors.palette.m3secondary color: Colors.palette.m3secondary
font: Tokens.font.title.medium font: Tokens.font.title.medium
@@ -61,32 +78,29 @@ ColumnLayout {
animate: true animate: true
} }
RowLayout { SnapLayout {
id: sliderLayout
Layout.topMargin: Tokens.spacing.extraLargeIncreased Layout.topMargin: Tokens.spacing.extraLargeIncreased
Layout.fillWidth: true Layout.fillWidth: true
spacing: Tokens.spacing.small spacing: ZUtils.snap(Tokens.spacing.small, root)
TextMetrics {
id: timeMetrics
text: Players.active ? root.lengthStr(Math.max(Players.active.position, root.hasUnknownLength ? 0 : Players.active.length)).replace(/[1-9]/g, "0") : "00:00"
font: Tokens.font.label.medium
}
CustomText { CustomText {
id: positionLabel id: positionLabel
Layout.preferredWidth: timeMetrics.width Layout.preferredWidth: ZUtils.snapCeil(timeMetrics.width, root)
Layout.preferredHeight: positionSlider.implicitHeight
text: root.lengthStr(Players.active?.position ?? -1) text: root.lengthStr(Players.active?.position ?? -1)
color: Colors.palette.m3onSurfaceVariant color: Colors.palette.m3onSurfaceVariant
font: timeMetrics.font font: timeMetrics.font
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
} }
CustomSlider { CustomSlider {
id: positionSlider id: positionSlider
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: ZUtils.snap(implicitHeight, root)
value: Players.active ? Players.active.position / (Players.active.length || 1) : 0 value: Players.active ? Players.active.position / (Players.active.length || 1) : 0
enabled: (Players.active?.canSeek ?? false) && !root.hasUnknownLength enabled: (Players.active?.canSeek ?? false) && !root.hasUnknownLength
wavy: true wavy: true
@@ -109,11 +123,13 @@ ColumnLayout {
} }
CustomText { CustomText {
Layout.preferredWidth: timeMetrics.width Layout.preferredWidth: ZUtils.snapCeil(timeMetrics.width, root)
Layout.preferredHeight: positionSlider.implicitHeight
text: root.hasUnknownLength ? "--:--" : root.lengthStr(Players.active?.length ?? -1) text: root.hasUnknownLength ? "--:--" : root.lengthStr(Players.active?.length ?? -1)
color: Colors.palette.m3onSurfaceVariant color: Colors.palette.m3onSurfaceVariant
font: timeMetrics.font font: timeMetrics.font
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
} }
} }
@@ -191,4 +207,12 @@ ColumnLayout {
implicitWidth: Math.round(implicitHeight * 0.9) implicitWidth: Math.round(implicitHeight * 0.9)
} }
} }
TextMetrics {
id: timeMetrics
text: Players.active ? root.lengthStr(Math.max(Players.active.position, root.hasUnknownLength ? 0 : Players.active.length)).replace(/[1-9]/g, "0") : "00:00"
font: Tokens.font.label.medium
}
}
} }
+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
+40 -15
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,24 +161,33 @@ 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;
} }
}
SnapLayout {
id: snapLayout
anchors.fill: parent
spacing: 0
orientation: Qt.Vertical
MaterialIcon { MaterialIcon {
id: icon id: icon
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: label.top
text: tab.iconName 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 fill: tab.current ? 1 : 0
fontStyle: Tokens.font.icon.medium fontStyle: Tokens.font.icon.medium
Layout.fillHeight: true
Layout.alignment: Qt.AlignHCenter
Behavior on fill { Behavior on fill {
Anim { Anim {
type: Anim.DefaultEffects type: Anim.DefaultEffects
@@ -174,11 +198,12 @@ Item {
CustomText { CustomText {
id: label id: label
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
text: tab.text text: tab.text
color: tab.current ? Colors.palette.m3primary : Colors.palette.m3onSurfaceVariant 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 {
+7 -2
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 {
+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
+2 -3
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
@@ -41,8 +41,7 @@ CarouselView {
tileHeight: focalWidth / 16 * 9 tileHeight: focalWidth / 16 * 9
delegate: Component { delegate: Component {
WallpaperTile { WallpaperTile {}
}
} }
Component.onDestruction: Wallpapers.stopPreview() Component.onDestruction: Wallpapers.stopPreview()
+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
+60 -8
View File
@@ -1,3 +1,5 @@
pragma ComponentBehavior: Bound
import Quickshell import Quickshell
import QtQuick import QtQuick
import ZShell.Config import ZShell.Config
@@ -9,7 +11,7 @@ Item {
id: root id: root
required property bool isCurrent required property bool isCurrent
required property var modelData // FileSystemEntry-like {path, relativePath} required property var modelData
required property real tileHeight required property real tileHeight
required property real tileWidth required property real tileWidth
required property ScreenState screenState required property ScreenState screenState
@@ -29,25 +31,75 @@ Item {
radius: Tokens.rounding.small radius: Tokens.rounding.small
y: Tokens.padding.large y: Tokens.padding.large
MaterialIcon { Loader {
active: opacity > 0
anchors.centerIn: parent anchors.centerIn: parent
color: Colors.tPalette.m3outline opacity: img.status === Image.Ready ? 0 : 1
fontStyle: Tokens.font.icon.builders.extraLarge.scale(2).weight(Font.DemiBold).build()
text: "image" Behavior on opacity {
Anim {}
}
sourceComponent: CustomRect {
color: Colors.palette.m3primaryContainer
implicitHeight: loadingIndicator.implicitSize + Tokens.padding.large * 2
implicitWidth: loadingIndicator.implicitSize + Tokens.padding.large * 2
radius: Tokens.rounding.full
LoadingIndicator {
id: loadingIndicator
anchors.centerIn: parent
containsIcon: true
implicitSize: Math.min(image.width, image.height) * 0.3
}
}
} }
CachingImage { Image {
id: img
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top anchors.top: parent.top
cache: true asynchronous: true
fillMode: Image.PreserveAspectCrop fillMode: Image.PreserveAspectCrop
height: root.tileHeight height: root.tileHeight
path: root.modelData ? root.modelData.path : "" source: root.modelData ? root.modelData.thumbnailPath : ""
smooth: root.isCurrent smooth: root.isCurrent
sourceSize.height: root.tileHeight sourceSize.height: root.tileHeight
sourceSize.width: root.tileHeight * (16 / 9) sourceSize.width: root.tileHeight * (16 / 9)
width: root.tileHeight * (16 / 9) width: root.tileHeight * (16 / 9)
opacity: status === Image.Ready ? 1 : 0
Behavior on opacity {
Anim {
type: Anim.SlowEffects
}
}
Loader {
opacity: root.modelData.isVideo && img.status === Image.Ready ? 1 : 0
active: opacity > 0
anchors.centerIn: parent
Behavior on opacity {
Anim {
type: Anim.SlowEffects
}
}
sourceComponent: CustomRect {
implicitWidth: videoIcon.implicitWidth + Tokens.padding.extraLarge * 2
implicitHeight: implicitWidth
radius: Tokens.rounding.full
color: Colors.tPalette.m3surface
MaterialIcon {
id: videoIcon
anchors.centerIn: parent
text: "video_library"
fontStyle: Tokens.font.icon.extraLarge
}
}
}
} }
StateLayer { StateLayer {
+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 {
+10 -19
View File
@@ -1,28 +1,31 @@
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
ClipRect { Item {
id: root id: root
required property var lock required property var lock
implicitHeight: layout.implicitHeight implicitHeight: layout.implicitHeight
implicitWidth: layout.implicitWidth implicitWidth: layout.implicitWidth
radius: Tokens.rounding.largeIncreased
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
@@ -50,22 +53,10 @@ ClipRect {
lock: root.lock lock: root.lock
} }
ColumnLayout {
Layout.fillWidth: true
spacing: Tokens.spacing.medium
CustomRect {
Layout.fillHeight: true
Layout.fillWidth: true
bottomRightRadius: Tokens.rounding.largeIncreased
color: Colors.tPalette.m3surfaceContainer
radius: Tokens.rounding.small
topRightRadius: Tokens.rounding.largeIncreased
NotifDock { NotifDock {
Layout.fillWidth: true
Layout.fillHeight: true
lock: root.lock lock: root.lock
} }
} }
}
}
} }
+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 qs.Modules import qs.Modules
import qs.Components import qs.Components
import qs.Helpers import qs.Helpers
+1 -1
View File
@@ -221,9 +221,9 @@ WlSessionLockSurface {
anchors.fill: parent anchors.fill: parent
color: Colors.palette.m3surface color: Colors.palette.m3surface
layer.enabled: true
opacity: Colors.transparency.enabled ? Colors.transparency.base : 1 opacity: Colors.transparency.enabled ? Colors.transparency.base : 1
radius: lockContent.radius radius: lockContent.radius
layer.enabled: true
layer.effect: MultiEffect { layer.effect: MultiEffect {
blurMax: 15 blurMax: 15
+14 -7
View File
@@ -7,14 +7,19 @@ import qs.Components
import qs.Helpers import qs.Helpers
import qs.Services import qs.Services
ClipRect { Item {
id: root id: root
required property var lock required property var lock
color: Colors.tPalette.m3surfaceContainer
implicitHeight: layout.implicitHeight + layout.anchors.margins * 2 implicitHeight: layout.implicitHeight + layout.anchors.margins * 2
ClipRect {
anchors.fill: parent
color: Colors.tPalette.m3surfaceContainer
radius: Tokens.rounding.small radius: Tokens.rounding.small
bottomLeftRadius: Tokens.rounding.largeIncreased
FadeImage { FadeImage {
id: image id: image
@@ -22,7 +27,6 @@ ClipRect {
anchors.fill: parent anchors.fill: parent
asynchronous: true asynchronous: true
fillMode: Image.PreserveAspectCrop fillMode: Image.PreserveAspectCrop
layer.enabled: true
opacity: status === Image.Ready ? 1 : 0 opacity: status === Image.Ready ? 1 : 0
source: Players.getArtUrl(Players.active) source: Players.getArtUrl(Players.active)
sourceSize: { sourceSize: {
@@ -42,15 +46,18 @@ ClipRect {
opacity: 0.7 opacity: 0.7
} }
} }
}
ColumnLayout { SnapLayout {
id: layout id: layout
anchors.left: parent.left anchors.left: parent.left
anchors.margins: Tokens.padding.extraLarge anchors.margins: Tokens.padding.extraLarge
anchors.right: parent.right anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
spacing: Tokens.spacing.extraSmall spacing: Tokens.spacing.extraSmall
orientation: Qt.Vertical
CustomText { CustomText {
Layout.fillWidth: true Layout.fillWidth: true
@@ -77,7 +84,7 @@ ClipRect {
spacing: Tokens.spacing.extraSmall spacing: Tokens.spacing.extraSmall
IconButton { IconButton {
enabled: Players.active?.canGoPrevious enabled: Players.active?.canGoPrevious ?? false
icon: "skip_previous" icon: "skip_previous"
isRound: true isRound: true
shapeMorph: true shapeMorph: true
@@ -88,7 +95,7 @@ ClipRect {
IconButton { IconButton {
checked: Players.active?.isPlaying ?? false checked: Players.active?.isPlaying ?? false
enabled: Players.active?.canTogglePlaying enabled: Players.active?.canTogglePlaying ?? false
icon: Players.active?.isPlaying ? "pause" : "play_arrow" icon: Players.active?.isPlaying ? "pause" : "play_arrow"
implicitWidth: implicitHeight + Tokens.padding.largeIncreased * 2 implicitWidth: implicitHeight + Tokens.padding.largeIncreased * 2
isRound: true isRound: true
@@ -98,7 +105,7 @@ ClipRect {
} }
IconButton { IconButton {
enabled: Players.active?.canGoNext enabled: Players.active?.canGoNext ?? false
icon: "skip_next" icon: "skip_next"
isRound: true isRound: true
shapeMorph: true shapeMorph: true
+14 -26
View File
@@ -4,20 +4,29 @@ import Quickshell
import Quickshell.Widgets import Quickshell.Widgets
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import ZShell.Config
import qs.Modules import qs.Modules
import qs.Components import qs.Components
import qs.Helpers import qs.Helpers
import ZShell.Config
import qs.Daemons import qs.Daemons
import qs.Services import qs.Services
ColumnLayout { CustomRect {
id: root id: root
required property var lock required property var lock
bottomRightRadius: Tokens.rounding.largeIncreased
color: Colors.tPalette.m3surfaceContainer
radius: Tokens.rounding.small
topRightRadius: Tokens.rounding.largeIncreased
SnapLayout {
anchors.fill: parent anchors.fill: parent
anchors.margins: Tokens.padding.large anchors.margins: Tokens.padding.large
orientation: Qt.Vertical
spacing: Tokens.spacing.small spacing: Tokens.spacing.small
CustomText { CustomText {
@@ -28,13 +37,9 @@ ColumnLayout {
text: NotifServer.list.length > 0 ? qsTr("%1 notification%2").arg(NotifServer.list.length).arg(NotifServer.list.length === 1 ? "" : "s") : qsTr("Notifications") text: NotifServer.list.length > 0 ? qsTr("%1 notification%2").arg(NotifServer.list.length).arg(NotifServer.list.length === 1 ? "" : "s") : qsTr("Notifications")
} }
ClipRect { Item {
id: clipRect
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
color: "transparent"
radius: Tokens.rounding.small
Loader { Loader {
active: opacity > 0 active: opacity > 0
@@ -46,30 +51,12 @@ ColumnLayout {
duration: Tokens.anim.durations.extraLarge duration: Tokens.anim.durations.extraLarge
} }
} }
sourceComponent: ColumnLayout { sourceComponent: CustomText {
spacing: Tokens.spacing.largeIncreased
Image {
asynchronous: true
fillMode: Image.PreserveAspectFit
layer.enabled: true
source: Qt.resolvedUrl(`${Quickshell.shellDir}/assets/dino.png`)
sourceSize.width: clipRect.width * 0.8
layer.effect: Coloriser {
brightness: 1
colorizationColor: Colors.palette.m3outlineVariant
}
}
CustomText {
Layout.alignment: Qt.AlignHCenter
color: Colors.palette.m3outlineVariant color: Colors.palette.m3outlineVariant
font: Tokens.font.headline.builders.small.width(90).build() font: Tokens.font.headline.builders.small.width(90).build()
text: qsTr("No Notifications") text: qsTr("No Notifications")
} }
} }
}
CustomListView { CustomListView {
anchors.fill: parent anchors.fill: parent
@@ -135,4 +122,5 @@ ColumnLayout {
} }
} }
} }
}
} }
+16 -7
View File
@@ -5,10 +5,11 @@ import Quickshell.Widgets
import Quickshell.Services.Notifications import Quickshell.Services.Notifications
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import ZShell.Config
import qs.Modules import qs.Modules
import qs.Components import qs.Components
import qs.Helpers import qs.Helpers
import ZShell.Config
import qs.Daemons import qs.Daemons
import qs.Services import qs.Services
@@ -36,13 +37,14 @@ CustomRect {
} }
} }
RowLayout { SnapLayout {
id: content id: content
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
anchors.top: parent.top anchors.top: parent.top
spacing: Tokens.spacing.medium spacing: Tokens.spacing.medium
Item { Item {
@@ -118,15 +120,18 @@ CustomRect {
} }
} }
ColumnLayout { SnapLayout {
Layout.bottomMargin: -Tokens.padding.extraSmall / 2 - (root.expanded ? 0 : spacing) Layout.bottomMargin: -Tokens.padding.extraSmall / 2 - (root.expanded ? 0 : spacing)
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: -Tokens.padding.extraSmall Layout.topMargin: -Tokens.padding.extraSmall
spacing: Math.round(Tokens.spacing.small / 2)
RowLayout { spacing: Math.round(Tokens.spacing.small / 2)
orientation: Qt.Vertical
SnapLayout {
Layout.bottomMargin: -parent.spacing Layout.bottomMargin: -parent.spacing
Layout.fillWidth: true Layout.fillWidth: true
spacing: Tokens.spacing.small spacing: Tokens.spacing.small
CustomText { CustomText {
@@ -167,10 +172,11 @@ CustomRect {
} }
} }
RowLayout { SnapLayout {
id: expandBtn id: expandBtn
anchors.centerIn: parent anchors.centerIn: parent
spacing: Tokens.spacing.small / 2 spacing: Tokens.spacing.small / 2
CustomText { CustomText {
@@ -261,7 +267,10 @@ CustomRect {
Behavior on opacity { Behavior on opacity {
Anim {} Anim {}
} }
sourceComponent: ColumnLayout { sourceComponent: SnapLayout {
orientation: Qt.Vertical
spacing: Tokens.spacing.extraSmall
Repeater { Repeater {
model: ScriptModel { model: ScriptModel {
values: root.notifs.slice(Config.notifs.groupPreviewNum) values: root.notifs.slice(Config.notifs.groupPreviewNum)
+3 -1
View File
@@ -5,6 +5,7 @@ import QtQuick.Layouts
import M3Shapes import M3Shapes
import ZShell.Services import ZShell.Services
import ZShell.Config import ZShell.Config
import ZShell.Components
import qs.Components import qs.Components
import qs.Effects import qs.Effects
import qs.Services import qs.Services
@@ -33,11 +34,12 @@ CustomRect {
service: Storage service: Storage
} }
RowLayout { SnapLayout {
id: layout id: layout
anchors.fill: parent anchors.fill: parent
anchors.margins: Tokens.padding.large anchors.margins: Tokens.padding.large
spacing: Tokens.spacing.largeIncreased spacing: Tokens.spacing.largeIncreased
Resource { Resource {
+8 -5
View File
@@ -1,11 +1,13 @@
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.Helpers import qs.Helpers
import qs.Services import qs.Services
ColumnLayout { SnapLayout {
orientation: Qt.Vertical
id: root id: root
required property int rootHeight required property int rootHeight
@@ -16,11 +18,11 @@ ColumnLayout {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
animate: true animate: true
color: Colors.palette.m3onSurfaceVariant color: Colors.palette.m3onSurfaceVariant
font: Tokens.font.title.large font: Tokens.font.body.large
text: Weather.description text: Weather.description
} }
RowLayout { SnapLayout {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
spacing: Tokens.spacing.small spacing: Tokens.spacing.small
@@ -29,7 +31,7 @@ ColumnLayout {
animate: true animate: true
color: Colors.palette.m3primary color: Colors.palette.m3primary
font: Tokens.font.body.large font: Tokens.font.title.large
text: Weather.temp text: Weather.temp
} }
@@ -37,6 +39,7 @@ ColumnLayout {
animate: true animate: true
color: Colors.palette.m3secondary color: Colors.palette.m3secondary
text: Weather.icon text: Weather.icon
fontStyle: Tokens.font.icon.large
} }
} }
@@ -53,7 +56,7 @@ ColumnLayout {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
animate: true animate: true
color: Colors.palette.m3onSurfaceVariant color: Colors.palette.m3onSurfaceVariant
font: Tokens.font.body.normal font: Tokens.font.body.medium
text: { text: {
const today = Weather.forecast[0]; const today = Weather.forecast[0];
return qsTr("High %1 • Low %2").arg(Weather.formatTemp(today?.maxTempC)).arg(Weather.formatTemp(today?.minTempC)); return qsTr("High %1 • Low %2").arg(Weather.formatTemp(today?.maxTempC)).arg(Weather.formatTemp(today?.minTempC));
+16 -7
View File
@@ -1,5 +1,6 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import M3Shapes import M3Shapes
import ZShell import ZShell
import qs.Components import qs.Components
@@ -14,7 +15,7 @@ CustomRect {
implicitHeight: header.anchors.margins + header.implicitHeight + Tokens.spacing.small + layout.implicitHeight + layout.anchors.bottomMargin implicitHeight: header.anchors.margins + header.implicitHeight + Tokens.spacing.small + layout.implicitHeight + layout.anchors.bottomMargin
radius: Tokens.rounding.small radius: Tokens.rounding.small
RowLayout { SnapLayout {
id: header id: header
anchors.left: parent.left anchors.left: parent.left
@@ -36,7 +37,7 @@ CustomRect {
} }
} }
VerticalFadeListView { CustomListView {
id: layout id: layout
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
@@ -45,13 +46,21 @@ CustomRect {
anchors.margins: Tokens.padding.large anchors.margins: Tokens.padding.large
anchors.right: parent.right anchors.right: parent.right
implicitHeight: contentItem.childrenRect.height implicitHeight: contentItem.childrenRect.height
model: Weather.hourlyForecast currentIndex: Weather.currentHourIndex
// highlightFollowsCurrentItem: true
// preferredHighlightEnd: currentItem.implicitWidth
// preferredHighlightBegin: 0
// highlightRangeMode: ListView.ApplyRange
clip: true
model: Weather.hourlyForecast.slice(Weather.currentHourIndex - 1)
orientation: VerticalFadeListView.Horizontal orientation: VerticalFadeListView.Horizontal
spacing: Tokens.spacing.medium spacing: Tokens.spacing.medium
delegate: ColumnLayout { delegate: SnapLayout {
orientation: Qt.Vertical
id: hour id: hour
readonly property bool current: ListView.view.currentItem === this
readonly property var cond: modelData readonly property var cond: modelData
required property int index required property int index
required property var modelData required property var modelData
@@ -60,7 +69,7 @@ CustomRect {
MaterialShape { MaterialShape {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
color: Qt.alpha(Colors.palette.m3primary, hour.index === Weather.currentHourIndex ? 1 : 0) color: Qt.alpha(Colors.palette.m3primary, hour.current ? 1 : 0)
implicitSize: temp.implicitHeight + Tokens.padding.small * 2 implicitSize: temp.implicitHeight + Tokens.padding.small * 2
shape: MaterialShape.Cookie4Sided shape: MaterialShape.Cookie4Sided
@@ -72,7 +81,7 @@ CustomRect {
id: temp id: temp
anchors.centerIn: parent anchors.centerIn: parent
color: hour.index === Weather.currentHourIndex ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface color: hour.current ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
font: Tokens.font.body.medium font: Tokens.font.body.medium
text: Weather.formatTemp(hour.cond.tempC).slice(0, -1) // Remove C/F text: Weather.formatTemp(hour.cond.tempC).slice(0, -1) // Remove C/F
} }
@@ -96,7 +105,7 @@ CustomRect {
Layout.topMargin: Tokens.spacing.extraSmall Layout.topMargin: Tokens.spacing.extraSmall
color: Colors.palette.m3onSurfaceVariant color: Colors.palette.m3onSurfaceVariant
font: Tokens.font.body.small font: Tokens.font.body.small
text: hour.index === 0 ? qsTr("Now") : Qt.formatDateTime(new Date(hour.cond.timestamp.replace("T", " ")), Config.services.useTwelveHourClock ? "ha" : "hh:00") text: hour.current ? qsTr("Now") : Qt.formatDateTime(new Date(hour.cond.timestamp.replace("T", " ")), Config.services.useTwelveHourClock ? "ha" : "hh:00")
} }
} }
} }
+2 -2
View File
@@ -19,6 +19,7 @@ CustomRect {
return base + brief.anchors.topMargin; return base + brief.anchors.topMargin;
} }
radius: Tokens.rounding.small radius: Tokens.rounding.small
topLeftRadius: Tokens.rounding.largeIncreased
Timer { Timer {
interval: 900000 // 15 minutes interval: 900000 // 15 minutes
@@ -48,7 +49,6 @@ CustomRect {
anchors.right: parent.right anchors.right: parent.right
asynchronous: true asynchronous: true
sourceComponent: Forecast { sourceComponent: Forecast {}
}
} }
} }
+4 -1
View File
@@ -28,7 +28,10 @@ Item {
for (let i = 0; i < count; i++) for (let i = 0; i < count; i++)
height += (list.itemAtIndex(i) as NotifWrapper)?.nonAnimHeight ?? 0; height += (list.itemAtIndex(i) as NotifWrapper)?.nonAnimHeight ?? 0;
if (panels.popouts.hasCurrent && (panels.popouts.currentCenter + (panels.popouts.current?.width / 2)) > panels.notifications.x || screenState.dashboard) if (panels.popouts.hasCurrent && (panels.popouts.currentCenter + (panels.popouts.current?.width / 2)) > panels.notifications.x)
return 0;
if (screenState.dashboard && (panels.dashboard.x + panels.dashboard.width >= panels.notifications.x))
return 0; return 0;
if (screenState.osd) { if (screenState.osd) {
+17 -13
View File
@@ -2,9 +2,11 @@ pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell
import ZShell.Config
import ZShell.Components
import qs.Components import qs.Components
import qs.Helpers import qs.Helpers
import ZShell.Config
import qs.Daemons import qs.Daemons
import qs.Services import qs.Services
@@ -19,14 +21,17 @@ Item {
required property ScreenState screenState required property ScreenState screenState
required property real volume required property real volume
implicitHeight: layout.implicitHeight + Tokens.padding.smaller * 2 implicitHeight: layout.implicitHeight + layout.anchors.margins * 2
implicitWidth: layout.implicitWidth + Tokens.padding.smaller * 2 implicitWidth: layout.implicitWidth + layout.anchors.margins * 2
ColumnLayout { SnapLayout {
id: layout id: layout
anchors.centerIn: parent anchors.fill: parent
anchors.margins: Tokens.padding.extraSmall
spacing: Tokens.spacing.medium spacing: Tokens.spacing.medium
orientation: Qt.Vertical
// Speaker volume // Speaker volume
CustomMouseArea { CustomMouseArea {
@@ -37,8 +42,8 @@ Item {
Audio.decrementVolume(); Audio.decrementVolume();
} }
implicitHeight: Config.osd.sizes.sliderHeight implicitHeight: ZUtils.snap(Config.osd.sizes.sliderHeight, root)
implicitWidth: Config.osd.sizes.sliderWidth implicitWidth: ZUtils.snap(Config.osd.sizes.sliderWidth, root)
FilledSlider { FilledSlider {
anchors.fill: parent anchors.fill: parent
@@ -63,8 +68,8 @@ Item {
Audio.decrementSourceVolume(); Audio.decrementSourceVolume();
} }
implicitHeight: Config.osd.sizes.sliderHeight implicitHeight: ZUtils.snap(Config.osd.sizes.sliderHeight, root)
implicitWidth: Config.osd.sizes.sliderWidth implicitWidth: ZUtils.snap(Config.osd.sizes.sliderWidth, root)
FilledSlider { FilledSlider {
anchors.fill: parent anchors.fill: parent
@@ -93,8 +98,8 @@ Item {
monitor.setBrightness(monitor.brightness - Config.services.brightnessIncrement); monitor.setBrightness(monitor.brightness - Config.services.brightnessIncrement);
} }
implicitHeight: Config.osd.sizes.sliderHeight implicitHeight: ZUtils.snap(Config.osd.sizes.sliderHeight, root)
implicitWidth: Config.osd.sizes.sliderWidth implicitWidth: ZUtils.snap(Config.osd.sizes.sliderWidth, root)
FilledSlider { FilledSlider {
anchors.fill: parent anchors.fill: parent
@@ -131,8 +136,7 @@ Item {
} }
} }
Behavior on opacity { Behavior on opacity {
Anim { Anim {}
}
} }
} }
} }
+5 -5
View File
@@ -2,9 +2,10 @@ pragma ComponentBehavior: Bound
import Quickshell import Quickshell
import QtQuick import QtQuick
import ZShell
import ZShell.Config
import qs.Components import qs.Components
import qs.Helpers import qs.Helpers
import ZShell.Config
import qs.Daemons import qs.Daemons
Item { Item {
@@ -30,8 +31,8 @@ Item {
} }
anchors.rightMargin: (-implicitWidth - 5 - sidebarOffset) * offsetScale anchors.rightMargin: (-implicitWidth - 5 - sidebarOffset) * offsetScale
implicitHeight: content.implicitHeight implicitHeight: ZUtils.snap(content.implicitHeight, root)
implicitWidth: content.implicitWidth implicitWidth: ZUtils.snap(content.implicitWidth, root)
opacity: 1 - offsetScale opacity: 1 - offsetScale
visible: offsetScale < 1 visible: offsetScale < 1
@@ -98,8 +99,7 @@ Item {
id: content id: content
active: root.shouldBeActive || root.visible active: root.shouldBeActive || root.visible
anchors.left: parent.left anchors.fill: parent
anchors.verticalCenter: parent.verticalCenter
sourceComponent: Content { sourceComponent: Content {
brightness: root.brightness brightness: root.brightness
+14 -5
View File
@@ -83,13 +83,16 @@ Scope {
opacity: 0 opacity: 0
radius: Tokens.rounding.small * 2 radius: Tokens.rounding.small * 2
ColumnLayout { SnapLayout {
id: layout id: layout
anchors.fill: parent anchors.fill: parent
anchors.margins: Tokens.padding.medium anchors.margins: Tokens.padding.medium
RowLayout { spacing: Tokens.spacing.extraSmall
orientation: Qt.Vertical
SnapLayout {
id: contentRow id: contentRow
spacing: 24 spacing: 24
@@ -120,12 +123,15 @@ Scope {
} }
} }
ColumnLayout { SnapLayout {
id: contentColumn id: contentColumn
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
spacing: Tokens.spacing.extraSmall
orientation: Qt.Vertical
CustomText { CustomText {
Layout.alignment: Qt.AlignLeft Layout.alignment: Qt.AlignLeft
Layout.preferredWidth: Math.min(600, contentWidth) Layout.preferredWidth: Math.min(600, contentWidth)
@@ -210,13 +216,15 @@ Scope {
} }
} }
ColumnLayout { SnapLayout {
id: textDetailsColumn id: textDetailsColumn
anchors.fill: parent anchors.fill: parent
anchors.margins: Tokens.padding.small anchors.margins: Tokens.padding.small
opacity: 0 opacity: 0
spacing: Tokens.spacing.small spacing: Tokens.spacing.small
orientation: Qt.Vertical
CustomText { CustomText {
text: `actionId: ${polkitAgent.flow?.actionId}` text: `actionId: ${polkitAgent.flow?.actionId}`
@@ -230,8 +238,9 @@ Scope {
} }
} }
RowLayout { SnapLayout {
Layout.preferredWidth: contentRow.implicitWidth Layout.preferredWidth: contentRow.implicitWidth
spacing: 8 spacing: 8
IconButton { IconButton {
+4 -2
View File
@@ -1,5 +1,6 @@
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.Components import qs.Components
@@ -50,7 +51,8 @@ ClipRect {
} }
} }
component Contents: ColumnLayout { component Contents: SnapLayout {
orientation: Qt.Vertical
id: contents id: contents
required property color accentColor required property color accentColor
@@ -100,7 +102,7 @@ ClipRect {
} }
} }
RowLayout { SnapLayout {
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
Layout.bottomMargin: -Tokens.padding.extraSmall Layout.bottomMargin: -Tokens.padding.extraSmall
Layout.rightMargin: -Tokens.padding.extraSmall Layout.rightMargin: -Tokens.padding.extraSmall
+20 -12
View File
@@ -1,5 +1,7 @@
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
@@ -15,8 +17,8 @@ CustomRect {
required property real usage required property real usage
color: Colors.tPalette.m3surfaceContainer color: Colors.tPalette.m3surfaceContainer
implicitHeight: Math.max(tempProg.implicitHeight + detailsRow.implicitHeight + Tokens.spacing.largeIncreased, usageColumn.implicitHeight + usageLabel.implicitHeight) + Tokens.padding.large * 2 implicitHeight: ZUtils.snap(Math.max(tempProg.implicitHeight + detailsRow.implicitHeight + Tokens.spacing.largeIncreased, usageColumn.implicitHeight + usageLabel.implicitHeight) + Tokens.padding.large * 2, root)
implicitWidth: 450 implicitWidth: ZUtils.snapCeil(450, root)
radius: Tokens.rounding.largeIncreased radius: Tokens.rounding.largeIncreased
ClipRect { ClipRect {
@@ -43,7 +45,7 @@ CustomRect {
anchors.margins: Tokens.padding.large anchors.margins: Tokens.padding.large
anchors.top: parent.top anchors.top: parent.top
fgColor: root.accent fgColor: root.accent
implicitSize: Math.max(icon.implicitWidth, icon.implicitHeight) + Tokens.padding.small * 2 implicitSize: ZUtils.snap(Math.max(icon.implicitWidth, icon.implicitHeight) + Tokens.padding.small * 2, root)
spacing: Tokens.spacing.extraSmall spacing: Tokens.spacing.extraSmall
strokeWidth: Tokens.padding.extraSmall strokeWidth: Tokens.padding.extraSmall
value: root.usage value: root.usage
@@ -62,12 +64,14 @@ CustomRect {
} }
} }
ColumnLayout { SnapLayout {
anchors.left: tempProg.right anchors.left: tempProg.right
anchors.margins: Tokens.spacing.largeIncreased anchors.margins: Tokens.spacing.largeIncreased
anchors.right: usageColumn.left anchors.right: usageColumn.left
anchors.verticalCenter: tempProg.verticalCenter anchors.verticalCenter: tempProg.verticalCenter
spacing: Tokens.spacing.extraSmall spacing: Tokens.spacing.extraSmall
orientation: Qt.Vertical
CustomText { CustomText {
color: root.accent color: root.accent
@@ -82,15 +86,17 @@ CustomRect {
} }
} }
ColumnLayout { SnapLayout {
id: detailsRow id: detailsRow
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.left: parent.left anchors.left: parent.left
anchors.margins: Tokens.padding.largeIncreased anchors.margins: Tokens.padding.largeIncreased
spacing: Tokens.spacing.extraSmall
RowLayout { spacing: Tokens.spacing.extraSmall
orientation: Qt.Vertical
SnapLayout {
Layout.leftMargin: -Tokens.padding.extraSmall Layout.leftMargin: -Tokens.padding.extraSmall
spacing: Tokens.spacing.extraSmall spacing: Tokens.spacing.extraSmall
@@ -108,32 +114,34 @@ CustomRect {
CustomProgressBar { CustomProgressBar {
fgColor: root.accent fgColor: root.accent
implicitHeight: Tokens.padding.extraSmall implicitHeight: Tokens.padding.small
indeterminate: isNaN(root.usage) || isNaN(root.temperature) indeterminate: isNaN(root.usage) || isNaN(root.temperature)
value: root.temperature / 100 value: root.temperature / 100
} }
} }
Column { SnapLayout {
id: usageColumn id: usageColumn
anchors.margins: Tokens.padding.large anchors.margins: Tokens.padding.large
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: 32 anchors.rightMargin: Tokens.padding.extraLarge
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
spacing: 0 spacing: 0
orientation: Qt.Vertical
CustomText { CustomText {
id: usageLabel id: usageLabel
anchors.right: parent.right Layout.alignment: Qt.AlignRight
color: Colors.palette.m3onSurfaceVariant color: Colors.palette.m3onSurfaceVariant
font: Tokens.font.body.medium font: Tokens.font.body.medium
text: qsTr("Usage") text: qsTr("Usage")
} }
CustomText { CustomText {
anchors.right: parent.right Layout.alignment: Qt.AlignRight
color: root.accent color: root.accent
font: Tokens.font.headline.builders.small.width(50).build() font: Tokens.font.headline.builders.small.width(50).build()
text: isNaN(root.usage) ? "...%" : Math.round(root.usage * 100) + "%" text: isNaN(root.usage) ? "...%" : Math.round(root.usage * 100) + "%"
+24 -17
View File
@@ -1,5 +1,7 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell
import ZShell.Components
import ZShell.Services import ZShell.Services
import ZShell.Config import ZShell.Config
import qs.Components import qs.Components
@@ -10,34 +12,39 @@ CustomRect {
readonly property color accent: Colors.palette.m3tertiary readonly property color accent: Colors.palette.m3tertiary
required property real perc
required property int used
required property int total
required property string label
required property string icon
Layout.fillWidth: true Layout.fillWidth: true
color: Colors.tPalette.m3surfaceContainer color: Colors.tPalette.m3surfaceContainer
implicitHeight: layout.implicitHeight + Tokens.padding.large * 2 implicitHeight: layout.implicitHeight + Tokens.padding.large * 2
implicitWidth: layout.implicitWidth + Tokens.padding.extraLargeIncreased * 2 implicitWidth: layout.implicitWidth + Tokens.padding.extraLargeIncreased * 2
radius: Tokens.rounding.largeIncreased radius: Tokens.rounding.largeIncreased
ServiceRef { SnapLayout {
service: Memory
}
ColumnLayout {
id: layout id: layout
anchors.centerIn: parent anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
orientation: Qt.Vertical
spacing: Tokens.spacing.extraSmall spacing: Tokens.spacing.extraSmall
RowLayout { SnapLayout {
Layout.leftMargin: -Tokens.padding.extraSmall Layout.alignment: Qt.AlignHCenter
spacing: Tokens.spacing.small spacing: Tokens.spacing.small
MaterialIcon { MaterialIcon {
color: root.accent color: root.accent
fill: 1 fill: 1
text: "memory_alt" text: root.icon
} }
CustomText { CustomText {
text: qsTr("Memory") text: root.label
} }
} }
@@ -45,17 +52,17 @@ CustomRect {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
Layout.topMargin: Tokens.spacing.largeIncreased Layout.topMargin: Tokens.spacing.largeIncreased
fgColor: root.accent fgColor: root.accent
implicitSize: usageColumn.implicitHeight + thickness + Tokens.padding.largeIncreased * 2 implicitSize: ZUtils.snap(usageColumn.implicitHeight + thickness + Tokens.padding.largeIncreased * 2, root)
startAngle: -225 startAngle: -225
sweepAngle: 270 sweepAngle: 270
value: Memory.percentage value: root.perc
Behavior on clampedVal { Behavior on clampedVal {
Anim { Anim {}
}
} }
ColumnLayout { SnapLayout {
orientation: Qt.Vertical
id: usageColumn id: usageColumn
anchors.centerIn: parent anchors.centerIn: parent
@@ -66,7 +73,7 @@ CustomRect {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
color: root.accent color: root.accent
font: Tokens.font.body.large font: Tokens.font.body.large
text: Math.round(Memory.percentage * 100) + "%" text: Math.round(root.perc * 100) + "%"
} }
CustomText { CustomText {
@@ -80,7 +87,7 @@ CustomRect {
CustomText { CustomText {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
text: { text: {
const fmt = UsageFmt.formatKib(Memory.used, Memory.total); const fmt = UsageFmt.formatKib(root.used, root.total);
return `${fmt.value.toFixed(1)} / ${Math.floor(fmt.total)} ${fmt.unit}`; return `${fmt.value.toFixed(1)} / ${Math.floor(fmt.total)} ${fmt.unit}`;
} }
} }
+17 -6
View File
@@ -18,15 +18,17 @@ CustomRect {
service: NetworkUsage service: NetworkUsage
} }
ColumnLayout { SnapLayout {
id: layout id: layout
anchors.bottomMargin: Tokens.padding.small anchors.bottomMargin: Tokens.padding.small
anchors.fill: parent anchors.fill: parent
anchors.margins: Tokens.padding.large anchors.margins: Tokens.padding.large
spacing: 0
RowLayout { spacing: 0
orientation: Qt.Vertical
SnapLayout {
spacing: Tokens.spacing.small spacing: Tokens.spacing.small
MaterialIcon { MaterialIcon {
@@ -108,8 +110,11 @@ CustomRect {
} }
// Download row // Download row
RowLayout { SnapLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.maximumWidth: root.width > root.implicitWidth * 2 ? root.width / 2 : -1
Layout.alignment: Qt.AlignRight
spacing: Tokens.spacing.small spacing: Tokens.spacing.small
MaterialIcon { MaterialIcon {
@@ -136,8 +141,11 @@ CustomRect {
} }
// Upload row // Upload row
RowLayout { SnapLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.maximumWidth: root.width > root.implicitWidth * 2 ? root.width / 2 : -1
Layout.alignment: Qt.AlignRight
spacing: Tokens.spacing.small spacing: Tokens.spacing.small
MaterialIcon { MaterialIcon {
@@ -164,8 +172,11 @@ CustomRect {
} }
// Session totals // Session totals
RowLayout { SnapLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.maximumWidth: root.width > root.implicitWidth * 2 ? root.width / 2 : -1
Layout.alignment: Qt.AlignRight
spacing: Tokens.spacing.small spacing: Tokens.spacing.small
MaterialIcon { MaterialIcon {
+13 -6
View File
@@ -1,6 +1,8 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import Quickshell import Quickshell
import ZShell
import ZShell.Components
import ZShell.Services import ZShell.Services
import ZShell.Config import ZShell.Config
import qs.Components import qs.Components
@@ -21,23 +23,26 @@ CustomRect {
service: Storage service: Storage
} }
ColumnLayout { SnapLayout {
id: layout id: layout
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
spacing: 0
RowLayout { spacing: 0
orientation: Qt.Vertical
SnapLayout {
id: row id: row
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
spacing: Tokens.spacing.largeIncreased spacing: Tokens.spacing.largeIncreased
CircularProgress { CircularProgress {
fgColor: root.accent fgColor: root.accent
implicitSize: usageColumn.implicitHeight + thickness + Tokens.padding.large * 2 implicitSize: ZUtils.snap(usageColumn.implicitHeight + thickness + Tokens.padding.large * 2, root)
startAngle: -225 startAngle: -225
sweepAngle: 270 sweepAngle: 270
value: root.percentage value: root.percentage
@@ -46,7 +51,8 @@ CustomRect {
Anim {} Anim {}
} }
ColumnLayout { SnapLayout {
orientation: Qt.Vertical
id: usageColumn id: usageColumn
anchors.centerIn: parent anchors.centerIn: parent
@@ -74,8 +80,9 @@ CustomRect {
} }
} }
ColumnLayout { SnapLayout {
spacing: Tokens.spacing.extraSmall spacing: Tokens.spacing.extraSmall
orientation: Qt.Vertical
CustomText { CustomText {
text: qsTr("Storage") text: qsTr("Storage")
-89
View File
@@ -1,89 +0,0 @@
import QtQuick
import QtQuick.Layouts
import ZShell.Services
import ZShell.Config
import qs.Components
import qs.Services
CustomRect {
id: root
readonly property color accent: Colors.palette.m3tertiary
Layout.fillWidth: true
color: Colors.tPalette.m3surfaceContainer
implicitHeight: layout.implicitHeight + Tokens.padding.large * 2
implicitWidth: layout.implicitWidth + Tokens.padding.extraLargeIncreased
radius: Tokens.rounding.largeIncreased
ServiceRef {
service: Gpu
}
ColumnLayout {
id: layout
anchors.centerIn: parent
spacing: Tokens.spacing.extraSmall
RowLayout {
Layout.leftMargin: -Tokens.padding.extraSmall
spacing: Tokens.spacing.small
MaterialIcon {
color: root.accent
fill: 1
text: "memory_alt"
}
CustomText {
text: qsTr("Video memory")
}
}
CircularProgress {
id: circularIndicator
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: Tokens.spacing.largeIncreased
fgColor: root.accent
implicitSize: usageColumn.implicitHeight + thickness + Tokens.padding.largeIncreased * 2
startAngle: -225
sweepAngle: 270
value: Gpu.memoryUsed / Gpu.memoryTotal
Behavior on clampedVal {
Anim {}
}
ColumnLayout {
id: usageColumn
anchors.centerIn: parent
anchors.verticalCenterOffset: Tokens.padding.extraSmall
spacing: 0
CustomText {
Layout.alignment: Qt.AlignHCenter
color: root.accent
font: Tokens.font.body.large
text: Math.round(circularIndicator.value * 100) + "%"
}
CustomText {
Layout.alignment: Qt.AlignHCenter
color: Colors.palette.m3onSurfaceVariant
text: qsTr("Used")
}
}
}
CustomText {
Layout.alignment: Qt.AlignHCenter
text: {
const fmt = UsageFmt.formatKib(Gpu.memoryUsed, Gpu.memoryTotal);
return `${fmt.value.toFixed(1)} / ${Math.floor(fmt.total)} ${fmt.unit}`;
}
}
}
}
+34 -18
View File
@@ -1,7 +1,10 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell
import ZShell.Components
import ZShell.Services import ZShell.Services
import ZShell.Config import ZShell.Config
import qs.Components
import qs.Modules.Resources.Cards import qs.Modules.Resources.Cards
import qs.Helpers import qs.Helpers
import qs.Services import qs.Services
@@ -11,25 +14,25 @@ Item {
required property Wrapper wrapper required property Wrapper wrapper
implicitHeight: content.implicitHeight + Tokens.padding.small * 2 implicitHeight: ZUtils.snap(content.implicitHeight + Tokens.padding.small * 2, root)
implicitWidth: content.implicitWidth implicitWidth: ZUtils.snap(content.implicitWidth, root)
RowLayout { SnapLayout {
id: content id: content
anchors.left: parent.left anchors.fill: parent
anchors.margins: Tokens.padding.small anchors.margins: Tokens.padding.small
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
spacing: Tokens.spacing.large spacing: Tokens.spacing.large
ColumnLayout { SnapLayout {
id: mainColumn id: mainColumn
Layout.fillWidth: true Layout.fillWidth: true
spacing: Tokens.spacing.medium spacing: Tokens.spacing.medium
orientation: Qt.Vertical
RowLayout { SnapLayout {
id: hero
spacing: Tokens.spacing.medium spacing: Tokens.spacing.medium
visible: cpuCard.active || gpuCard.active visible: cpuCard.active || gpuCard.active
@@ -72,7 +75,10 @@ Item {
} }
} }
RowLayout { SnapLayout {
id: card
Layout.fillWidth: true
spacing: Tokens.spacing.medium spacing: Tokens.spacing.medium
visible: storageCard.active || memoryCard.active || vramCard.active || networkCard1.active visible: storageCard.active || memoryCard.active || vramCard.active || networkCard1.active
@@ -81,8 +87,7 @@ Item {
active: Config.dashboard.performance.showStorage active: Config.dashboard.performance.showStorage
sourceComponent: StorageCard { sourceComponent: StorageCard {}
}
} }
WrappedLoader { WrappedLoader {
@@ -91,6 +96,15 @@ Item {
active: Config.dashboard.performance.showMemory active: Config.dashboard.performance.showMemory
sourceComponent: MemoryCard { sourceComponent: MemoryCard {
used: Memory.used
total: Memory.total
perc: Memory.percentage
label: qsTr("Memory")
icon: "memory_alt"
ServiceRef {
service: Memory
}
} }
} }
@@ -99,7 +113,12 @@ Item {
active: Config.dashboard.performance.showVram active: Config.dashboard.performance.showVram
sourceComponent: VramCard { sourceComponent: MemoryCard {
used: Gpu.memoryUsed
total: Gpu.memoryTotal
perc: Gpu.memoryUsed / Gpu.memoryTotal
label: qsTr("Video memory")
icon: "memory_alt"
} }
} }
@@ -108,8 +127,7 @@ Item {
active: Config.dashboard.performance.showNetwork && !vramCard.active active: Config.dashboard.performance.showNetwork && !vramCard.active
sourceComponent: NetworkCard { sourceComponent: NetworkCard {}
}
} }
} }
@@ -118,8 +136,7 @@ Item {
active: Config.dashboard.performance.showNetwork && vramCard.active active: Config.dashboard.performance.showNetwork && vramCard.active
sourceComponent: NetworkCard { sourceComponent: NetworkCard {}
}
} }
} }
@@ -127,8 +144,7 @@ Item {
Layout.fillWidth: false Layout.fillWidth: false
active: Battery.isLaptop && Config.dashboard.performance.showBattery active: Battery.isLaptop && Config.dashboard.performance.showBattery
sourceComponent: BatteryTank { sourceComponent: BatteryTank {}
}
} }
} }
+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 import Quickshell
import Quickshell.Services.Pipewire import Quickshell.Services.Pipewire
import qs.Components import qs.Components
@@ -39,7 +40,7 @@ ItemList {
onClicked: root.selected(device.modelData) onClicked: root.selected(device.modelData)
} }
RowLayout { SnapLayout {
id: deviceLayout id: deviceLayout
anchors.fill: parent anchors.fill: parent
+4 -2
View File
@@ -2,6 +2,7 @@ pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import ZShell.Blobs import ZShell.Blobs
import qs.Components import qs.Components
import ZShell.Config import ZShell.Config
@@ -181,7 +182,8 @@ Item {
onWheel: event => event.accepted = true onWheel: event => event.accepted = true
ColumnLayout { SnapLayout {
orientation: Qt.Vertical
anchors.bottomMargin: Tokens.padding.largeIncreased anchors.bottomMargin: Tokens.padding.largeIncreased
anchors.fill: parent anchors.fill: parent
anchors.margins: Tokens.padding.extraLarge anchors.margins: Tokens.padding.extraLarge
@@ -222,7 +224,7 @@ Item {
} }
} }
RowLayout { SnapLayout {
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
spacing: Tokens.spacing.extraSmall spacing: Tokens.spacing.extraSmall
+4 -2
View File
@@ -2,6 +2,7 @@ pragma ComponentBehavior: Bound
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
@@ -29,7 +30,7 @@ ConnectedRect {
} }
} }
RowLayout { SnapLayout {
id: rowLayout id: rowLayout
anchors.fill: parent anchors.fill: parent
@@ -44,7 +45,8 @@ ConnectedRect {
visible: root.leadingComponent visible: root.leadingComponent
} }
ColumnLayout { SnapLayout {
orientation: Qt.Vertical
Layout.fillWidth: true Layout.fillWidth: true
spacing: 0 spacing: 0
+3 -1
View File
@@ -2,6 +2,7 @@ pragma ComponentBehavior: Bound
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
@@ -38,7 +39,8 @@ ConnectedRect {
type: Anim.DefaultEffects type: Anim.DefaultEffects
} }
} }
sourceComponent: ColumnLayout { sourceComponent: SnapLayout {
orientation: Qt.Vertical
spacing: Tokens.spacing.extraSmall spacing: Tokens.spacing.extraSmall
MaterialIcon { MaterialIcon {
+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 import Quickshell
import ZShell.Config import ZShell.Config
import qs.Components import qs.Components
@@ -265,7 +266,7 @@ ListView {
} }
} }
RowLayout { SnapLayout {
id: row id: row
anchors.fill: parent anchors.fill: parent
+4 -2
View File
@@ -2,12 +2,14 @@ pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import ZShell.Components
import qs.Modules.Settings import qs.Modules.Settings
import qs.Components import qs.Components
import ZShell.Config import ZShell.Config
import qs.Services import qs.Services
ColumnLayout { SnapLayout {
orientation: Qt.Vertical
id: root id: root
property bool animateScroll: false property bool animateScroll: false
@@ -118,7 +120,7 @@ ColumnLayout {
onClicked: focus = true onClicked: focus = true
RowLayout { SnapLayout {
id: header id: header
spacing: Tokens.spacing.largeIncreased spacing: Tokens.spacing.largeIncreased
+4 -2
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
@@ -27,7 +28,7 @@ ConnectedRect {
onClicked: popup.open = true onClicked: popup.open = true
} }
RowLayout { SnapLayout {
id: navLayout id: navLayout
anchors.fill: parent anchors.fill: parent
@@ -43,7 +44,8 @@ ConnectedRect {
fontStyle: Tokens.font.icon.medium fontStyle: Tokens.font.icon.medium
} }
ColumnLayout { SnapLayout {
orientation: Qt.Vertical
Layout.fillWidth: true Layout.fillWidth: true
spacing: 0 spacing: 0
+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 ZShell.Config import ZShell.Config
import qs.Components import qs.Components
import qs.Services import qs.Services
@@ -30,7 +31,7 @@ ConnectedRect {
onClicked: e => root.clicked(e) onClicked: e => root.clicked(e)
} }
RowLayout { SnapLayout {
id: row id: row
anchors.left: parent.left anchors.left: parent.left

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