diff options
| -rw-r--r-- | modules/launcher/WallpaperItem.qml | 10 | ||||
| -rw-r--r-- | services/Thumbnailer.qml | 45 | ||||
| -rw-r--r-- | services/Wallpapers.qml | 4 | ||||
| -rw-r--r-- | widgets/CachingImage.qml | 45 |
4 files changed, 95 insertions, 9 deletions
diff --git a/modules/launcher/WallpaperItem.qml b/modules/launcher/WallpaperItem.qml index bbd611c..c3dd57a 100644 --- a/modules/launcher/WallpaperItem.qml +++ b/modules/launcher/WallpaperItem.qml @@ -25,22 +25,18 @@ StyledRect { } } - Image { + CachingImage { id: image anchors.horizontalCenter: parent.horizontalCenter y: Appearance.padding.normal visible: false - source: `file://${root.modelData.path}` - asynchronous: true - fillMode: Image.PreserveAspectCrop + path: root.modelData.path smooth: !root.PathView.view.moving width: LauncherConfig.sizes.wallpaperWidth height: width / 16 * 9 - sourceSize.width: width - sourceSize.height: height } Rectangle { @@ -70,7 +66,7 @@ StyledRect { renderType: Text.QtRendering text: root.modelData.name - font.pointSize: Appearance.font.size.small + font.pointSize: Appearance.font.size.normal } Behavior on scale { diff --git a/services/Thumbnailer.qml b/services/Thumbnailer.qml new file mode 100644 index 0000000..1e22940 --- /dev/null +++ b/services/Thumbnailer.qml @@ -0,0 +1,45 @@ +pragma Singleton + +import Quickshell +import Quickshell.Io +import QtQuick +import Qt.labs.platform + +Singleton { + id: root + + readonly property string thumbDir: `${StandardPaths.standardLocations(StandardPaths.GenericCacheLocation)[0]}/caelestia/thumbnails`.slice(7) + + function go(sha: string, path: string, width: int, height: int): string { + if (!sha || !path || !width || !height) + return ""; + + const thumbPath = `${thumbDir}/${sha}@${width}x${height}-exact.png`; + + thumbProc.path = path; + thumbProc.thumbPath = thumbPath; + thumbProc.width = width; + thumbProc.height = height; + thumbProc.startDetached(); + + return thumbPath; + } + + Process { + id: thumbProc + + property string path + property string thumbPath + property int width + property int height + + command: ["fish", "-c", ` +if ! test -f ${thumbPath} + set -l size (identify -ping -format '%w\n%h' ${path}) + if test $size[1] -gt ${width} -o $size[2] -gt ${height} + magick ${path} -thumbnail ${width}x${height}^ -background none -gravity center -extent ${width}x${height} -unsharp 0x.5 ${thumbPath} + end +end +`] + } +} diff --git a/services/Wallpapers.qml b/services/Wallpapers.qml index 833e808..bd6528d 100644 --- a/services/Wallpapers.qml +++ b/services/Wallpapers.qml @@ -9,7 +9,7 @@ import Qt.labs.platform Singleton { id: root - readonly property string path: `${StandardPaths.standardLocations(StandardPaths.PicturesLocation)[0]}/Wallpapers` + readonly property string path: `${StandardPaths.standardLocations(StandardPaths.PicturesLocation)[0]}/Wallpapers`.slice(7) property list<Wallpaper> list @@ -28,7 +28,7 @@ Singleton { Process { running: true - command: ["fd", ".", root.path.slice(7), "-t", "f", "-e", "jpg", "-e", "jpeg", "-e", "png", "-e", "svg"] + command: ["fd", ".", root.path, "-t", "f", "-e", "jpg", "-e", "jpeg", "-e", "png", "-e", "svg"] stdout: SplitParser { splitMarker: "" onRead: data => { diff --git a/widgets/CachingImage.qml b/widgets/CachingImage.qml new file mode 100644 index 0000000..cff5676 --- /dev/null +++ b/widgets/CachingImage.qml @@ -0,0 +1,45 @@ +import "root:/services" +import Quickshell.Io +import QtQuick + +Image { + id: root + + required property string path + property string thumbnail: path + + source: `file://${thumbnail}` + asynchronous: true + fillMode: Image.PreserveAspectCrop + + onPathChanged: shaProc.running = true + onWidthChanged: shaProc.running = true + onHeightChanged: shaProc.running = true + onStatusChanged: { + if (status === Image.Error) + waitProc.running = true; + } + + Process { + id: shaProc + + command: ["sha1sum", root.path] + stdout: SplitParser { + onRead: data => root.thumbnail = Thumbnailer.go(data.split(" ")[0], root.path, root.width, root.height) + } + } + + Process { + id: waitProc + + command: ["inotifywait", "-q", "-e", "close_write", "--format", "%w%f", "-m", root.thumbnail.slice(0, root.thumbnail.lastIndexOf("/"))] + stdout: SplitParser { + onRead: file => { + if (file === root.thumbnail) { + root.source = file; + waitProc.running = false; + } + } + } + } +} |