From 28e75a0ba2903c2ec4e90fa51a9a6211e2ebc79f Mon Sep 17 00:00:00 2001 From: retrozinndev Date: Sat, 26 Apr 2025 22:38:55 -0300 Subject: [PATCH] :sparkles: ags(scripts/wallpaper): use a undependent-script way of setting wallpaper, add method to reload colors --- ags/scripts/wallpaper.ts | 137 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 ags/scripts/wallpaper.ts diff --git a/ags/scripts/wallpaper.ts b/ags/scripts/wallpaper.ts new file mode 100644 index 0000000..31826b1 --- /dev/null +++ b/ags/scripts/wallpaper.ts @@ -0,0 +1,137 @@ +import { execAsync, Gio, GLib, GObject, monitorFile, property, register } from "astal"; + +export { Wallpaper }; + +@register({ GTypeName: "Wallpaper" }) +class Wallpaper extends GObject.Object { + private static instance: Wallpaper; + #wallpaper: (string|undefined); + #splash: boolean = true; + #monitor: Gio.FileMonitor; + #hyprpaperFile: Gio.File; + #wallpapersPath: string; + + @property(Boolean) + public get splash() { return this.#splash; } + public set splash(showSplash: boolean) { + this.#splash = showSplash; + this.notify("splash"); + + this.writeChanges(); + } + + @property(String) + public get wallpaper(): (string|undefined) { return this.#wallpaper; } + public set wallpaper(newValue: string) { this.setWallpaper(newValue); } + + public get wallpapersPath() { return this.#wallpapersPath; } + + constructor() { + super(); + this.#wallpapersPath = GLib.getenv("WALLPAPERS") ?? `${GLib.get_home_dir()}/wallpapers`; + this.#hyprpaperFile = Gio.File.new_for_path(`${GLib.get_user_config_dir()}/hypr/hyprpaper.conf`); + this.getWallpaper().then((wall) => this.#wallpaper = wall).catch(r => { + throw new Error(`Wallpaper: Couldn't get wallpaper. Stderr: ${r}`) + }); + + this.#monitor = monitorFile(this.#hyprpaperFile.get_path()!, async (_, event) => { + if(event == Gio.FileMonitorEvent.CHANGED) { + const [loaded, , content ] = this.#hyprpaperFile.load_contents(null); + if(loaded) + for(const line of content.split('\n')) { + const [ key, value ] = line.split('='); + if(key.trim().startsWith('#')) + continue; + + switch(key) { + case "splash": + this.#splash = /(yes|true|on)/.test(value.trim()) ? true : false; + break; + + case "wallpaper": + this.#wallpaper = value; + break; + } + }; + } + }); + } + + vfunc_dispose(): void { + this.#monitor.cancel(); + } + + public static getDefault(): Wallpaper { + if(!this.instance) + this.instance = new Wallpaper(); + + return this.instance; + } + + private async writeChanges(): Promise { + if(!this.#wallpaper) return; + + const hyprpaperFile = Gio.File.new_for_path(`${GLib.get_user_config_dir()}/hypr/hyprpaper.conf`); + hyprpaperFile.create(Gio.FileCreateFlags.REPLACE_DESTINATION, null); + return hyprpaperFile.replace_contents_async(`# This file is automatically generated when choosing a new wallpaper in colorshell + preload = ${this.#wallpaper} + splash = ${this.#splash} + wallpaper = , ${this.#wallpaper}`.split('\n').map(str => str.trimStart()).join('\n'), null, false, + Gio.FileCreateFlags.REPLACE_DESTINATION, null + ).then(() => {}).catch(r => { + throw new Error(`Wallpaper: Couldn't write hyprpaper file. Stderr: ${r}`); + }); + } + + public async getWallpaper(): Promise { + return await execAsync("hyprctl hyprpaper listactive | tail -n 1").then(stdout => { + const loaded: (string|undefined) = stdout.split('=')[1]?.trim(); + if(!loaded) + throw new Error(`Wallpaper: Couldn't get wallpaper. There are no loaded wallpaper(s)`); + + return loaded; + }).catch(stderr => { + throw new Error(`Wallpaper: Couldn't get wallpaper. Stderr: ${stderr}`); + }); + } + + public async reloadColors(): Promise { + return await execAsync(`wal -t --cols16 darken -i "${this.#wallpaper}"`).then(() => { + }).catch(r => { + throw new Error(`Wallpaper: Couldn't update shell colors. Stderr: ${r}`); + }); + } + + public async setWallpaper(path: string|Gio.File): Promise { + return await execAsync("hyprctl hyprpaper unload all").then(async () => + await execAsync(`hyprctl hyprpaper preload ${path}`).then(async () => + await execAsync(`hyprctl hyprpaper wallpaper ${path}`).then(async () => { + this.#wallpaper = (typeof path === "string") ? path : path.get_path()!; + this.reloadColors(); + this.writeChanges().catch(r => { + throw new Error(`Wallpaper: Couldn't write changes to hyprpaper config file. Stderr: ${r}`); + }); + }).catch(r => { + throw new Error(`Wallpaper: Couldn't set wallpaper. Stderr: ${r}`); + }) + ).catch(r => { + throw new Error(`Wallpaper: Couldn't preload image. Stderr: ${r}`); + }) + ).catch(r => { + throw new Error(`Wallpaper: Couldn't unload images from memory. Stderr: ${r}`); + }); + } + + public async pickWallpaper(): Promise { + return execAsync(`zenity --file-selection`).then(wall => { + if(!wall.trim()) return undefined; + + this.setWallpaper(wall).catch(r => { + throw new Error(`Wallpaper: An error occurred in \`setWallpaper()\`. Stderr: ${r}`); + }); + return wall; + }).catch(r => { + throw new Error(`Wallpaper: Couldn't pick wallpaper, is zenity installed? Stderr: ${r}`); + }); + } +}