✨ ags(scripts/wallpaper): use a undependent-script way of setting wallpaper, add method to reload colors
This commit is contained in:
@@ -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<void> {
|
||||
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<string|undefined> {
|
||||
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<void> {
|
||||
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<void> {
|
||||
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<string|undefined> {
|
||||
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}`);
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user