summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-04-04 21:41:34 +1100
committer2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-04-04 21:41:34 +1100
commita793205cc20c14709edebfd20ec9f3995f183874 (patch)
treeb436bec863329afdf8fa937f9ddd5924088293db
parentfeat: uwsm app -> app2unit (diff)
downloadcaelestia-shell-a793205cc20c14709edebfd20ec9f3995f183874.tar.gz
caelestia-shell-a793205cc20c14709edebfd20ec9f3995f183874.tar.bz2
caelestia-shell-a793205cc20c14709edebfd20ec9f3995f183874.zip
wallpapers: filter by size
-rw-r--r--src/config/defaults.ts1
-rw-r--r--src/config/funcs.ts6
-rw-r--r--src/config/types.ts2
-rw-r--r--src/services/wallpapers.ts30
4 files changed, 33 insertions, 6 deletions
diff --git a/src/config/defaults.ts b/src/config/defaults.ts
index 570ed16..763ccc2 100644
--- a/src/config/defaults.ts
+++ b/src/config/defaults.ts
@@ -133,6 +133,7 @@ export default {
{
recursive: true, // Whether to search recursively
path: "~/Pictures/Wallpapers", // Path to search
+ threshold: 0.8, // The threshold to filter wallpapers by size (e.g. 0.8 means wallpaper must be at least 80% of the screen size), 0 to disable
},
],
},
diff --git a/src/config/funcs.ts b/src/config/funcs.ts
index 5b9efa4..5d8ab44 100644
--- a/src/config/funcs.ts
+++ b/src/config/funcs.ts
@@ -29,12 +29,12 @@ const isCorrectType = (v: any, type: string | string[] | number[], path: string)
v.splice(0, v.length, ...v.filter((item, i) => isCorrectType(item, type, `${path}[${i}]`)));
} else {
const valid = v.filter((item, i) =>
- Object.entries(type).some(([k, t]) => {
- if (!item[k]) {
+ Object.entries(type).every(([k, t]) => {
+ if (!item.hasOwnProperty(k)) {
console.warn(`Invalid shape for ${path}[${i}]: ${JSON.stringify(item)} != ${arrType}`);
return false;
}
- return !isCorrectType(item[k], t as any, `${path}[${i}].${k}`);
+ return isCorrectType(item[k], t as any, `${path}[${i}].${k}`);
})
);
v.splice(0, v.length, ...valid); // In-place filter
diff --git a/src/config/types.ts b/src/config/types.ts
index f5ca03a..0d875ce 100644
--- a/src/config/types.ts
+++ b/src/config/types.ts
@@ -75,7 +75,7 @@ export default {
"gpu.interval": NUM,
"memory.interval": NUM,
"storage.interval": NUM,
- "wallpapers.paths": OBJ_ARR({ recursive: BOOL, path: STR }),
+ "wallpapers.paths": OBJ_ARR({ recursive: BOOL, path: STR, threshold: NUM }),
"calendar.webcals": ARR(STR),
"calendar.upcomingDays": NUM,
"calendar.notify": BOOL,
diff --git a/src/services/wallpapers.ts b/src/services/wallpapers.ts
index f1f13a5..77b22ad 100644
--- a/src/services/wallpapers.ts
+++ b/src/services/wallpapers.ts
@@ -2,6 +2,7 @@ import { monitorDirectory } from "@/utils/system";
import Thumbnailer from "@/utils/thumbnailer";
import { execAsync, GObject, property, register } from "astal";
import { wallpapers as config } from "config";
+import Monitors from "./monitors";
export interface IWallpaper {
path: string;
@@ -35,10 +36,35 @@ export default class Wallpapers extends GObject.Object {
return this.#categories;
}
- #listDir(path: { path: string; recursive: boolean }, type: "f" | "d") {
+ async #listDir(path: { path: string; recursive: boolean; threshold: number }, type: "f" | "d") {
const absPath = path.path.replace("~", HOME);
const maxDepth = path.recursive ? "" : "-maxdepth 1";
- return execAsync(`find ${absPath} ${maxDepth} -path '*/.*' -prune -o -type ${type} -print`);
+ const files = await execAsync(`find ${absPath} ${maxDepth} -path '*/.*' -prune -o -type ${type} -print`);
+
+ if (path.threshold > 0) {
+ const data = (
+ await execAsync([
+ "fish",
+ "-c",
+ `identify -ping -format '%i %w %h\n' ${files.replaceAll("\n", " ")} ; true`,
+ ])
+ ).split("\n");
+
+ return data
+ .filter(l => l && this.#filterSize(l, path.threshold))
+ .map(l => l.split(" ").slice(0, -2).join(" "))
+ .join("\n");
+ }
+
+ return files;
+ }
+
+ #filterSize(line: string, threshold: number) {
+ const [width, height] = line.split(" ").slice(-2).map(Number);
+ const mWidth = Math.max(...Monitors.get_default().list.map(m => m.width));
+ const mHeight = Math.max(...Monitors.get_default().list.map(m => m.height));
+
+ return width >= mWidth * threshold && height >= mHeight * threshold;
}
async update() {