Files
Zephrynis b2ae32a078 feat: make AGS colorshell configuration fully declarative
- Add complete colorshell v2.0.3 configuration to home/ags-config/
- Disable runner plugin and NightLight tile (incompatible with NixOS)
- Customize SCSS with full opacity (no transparency)
- Add dark pale blue color scheme in home/pywal-colors/
- Configure Papirus-Dark icon theme via home-manager
- Make ~/.config/ags/ immutable and managed by Nix store
- Auto-deploy pywal colors to ~/.cache/wal/colors.json

All AGS configuration is now reproducible and version controlled.
2025-11-04 21:36:38 +00:00

106 lines
3.1 KiB
TypeScript

import { Gdk, Gtk } from "ags/gtk4";
import { execAsync } from "ags/process";
import AstalApps from "gi://AstalApps";
import AstalHyprland from "gi://AstalHyprland";
// Disabled uwsm - not installed in NixOS
export const uwsmIsActive: boolean = false;
const astalApps: AstalApps.Apps = new AstalApps.Apps();
let appsList: Array<AstalApps.Application> = astalApps.get_list();
export function getApps(): Array<AstalApps.Application> {
return appsList;
}
export function updateApps(): void {
astalApps.reload();
appsList = astalApps.get_list();
}
export function getAstalApps(): AstalApps.Apps {
return astalApps;
}
/** handles running with uwsm if it's installed */
export function execApp(app: AstalApps.Application|string, dispatchExecArgs?: string) {
const executable = (typeof app === "string") ? app
: app.executable.replace(/%[fFcuUik]/g, "");
AstalHyprland.get_default().dispatch("exec",
`${dispatchExecArgs ? `${dispatchExecArgs} ` : ""}${uwsmIsActive ? "uwsm-app -- " : ""}${executable}`
);
}
export function lookupIcon(name: string): boolean {
return Gtk.IconTheme.get_for_display(Gdk.Display.get_default()!)?.has_icon(name);
}
export function getAppsByName(appName: string): (Array<AstalApps.Application>|undefined) {
let found: Array<AstalApps.Application> = [];
getApps().map((app: AstalApps.Application) => {
if(app.get_name().trim().toLowerCase() === appName.trim().toLowerCase()
|| (app?.wmClass && app.wmClass.trim().toLowerCase() === appName.trim().toLowerCase()))
found.push(app);
});
return (found.length > 0 ? found : undefined);
}
export function getIconByAppName(appName: string): (string|undefined) {
if(!appName) return undefined;
if(lookupIcon(appName))
return appName;
if(lookupIcon(appName.toLowerCase()))
return appName.toLowerCase();
const nameReverseDNS = appName.split('.');
const lastItem = nameReverseDNS[nameReverseDNS.length - 1];
const lastPretty = `${lastItem.charAt(0).toUpperCase()}${lastItem.substring(1, lastItem.length)}`;
const uppercaseRDNS = nameReverseDNS.slice(0, nameReverseDNS.length - 1)
.concat(lastPretty).join('.');
if(lookupIcon(uppercaseRDNS))
return uppercaseRDNS;
if(lookupIcon(nameReverseDNS[nameReverseDNS.length - 1]))
return nameReverseDNS[nameReverseDNS.length - 1];
const found: (AstalApps.Application|undefined) = getAppsByName(appName)?.[0];
if(Boolean(found))
return found?.iconName;
return undefined;
}
export function getAppIcon(app: (string|AstalApps.Application)): (string|undefined) {
if(!app) return undefined;
if(typeof app === "string")
return getIconByAppName(app);
if(app.iconName && lookupIcon(app.iconName))
return app.iconName;
if(app.wmClass)
return getIconByAppName(app.wmClass);
return getIconByAppName(app.name);
}
export function getSymbolicIcon(app: (string|AstalApps.Application)): (string|undefined) {
const icon = getAppIcon(app);
return (icon && lookupIcon(`${icon}-symbolic`)) ?
`${icon}-symbolic`
: undefined;
}