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.
This commit is contained in:
2025-11-04 21:36:38 +00:00
parent 593735370a
commit b2ae32a078
240 changed files with 1024921 additions and 3 deletions

View File

@@ -0,0 +1,162 @@
import { CompositorHyprland } from "./hyprland";
import GObject, { getter, gtype, property, register } from "ags/gobject";
import GLib from "gi://GLib?version=2.0";
/** WIP modular implementation of a system that supports implementing
* a variety of Wayland Compositors
* @todo implement more general compositor info + a lot of stuff
* */
export namespace Compositors {
let compositor: Compositor|null = null;
@register({ GTypeName: "CompositorMonitor" })
export class Monitor extends GObject.Object {
#width: number;
#height: number;
@getter(Number)
get width() { return this.#width; }
@getter(Number)
get height() { return this.#height; }
@property(Number)
scaling: number;
constructor(width: number, height: number, scaling: number = 1) {
super();
this.#width = width;
this.#height = height;
this.scaling = scaling;
}
}
@register({ GTypeName: "CompositorWorkspace" })
export class Workspace extends GObject.Object {
#id: number;
#monitor: Monitor;
@getter(Number)
get id() { return this.#id; }
@getter(Monitor)
get monitor() { return this.#monitor; }
constructor(monitor: Monitor, id: number = 0) {
super();
this.#monitor = monitor;
this.#id = id;
}
}
@register({ GTypeName: "CompositorClient" })
export class Client extends GObject.Object {
readonly #address: string|null = null;
#initialClass: string;
#class: string;
#title: string = "";
#mapped: boolean = true;
#position: [number, number] = [0, 0];
#xwayland: boolean = false;
@getter(gtype<string|null>(String))
get address() { return this.#address; }
@getter(String)
get title() { return this.#title; }
@getter(String)
get class() { return this.#class; }
@getter(String)
get initialClass() { return this.#initialClass; }
@getter(gtype<[number, number]>(Array))
get position() { return this.#position; }
@getter(Boolean)
get xwayland() { return this.#xwayland; }
@getter(Boolean)
get mapped() { return this.#mapped; }
constructor(props: {
address?: string;
title?: string;
mapped?: boolean;
class: string;
initialClass?: string;
/** [x, y] */
position?: [number, number];
}) {
super();
this.#class = props.class;
if(props.title !== undefined)
this.#title = props.title;
if(props.mapped !== undefined)
this.#mapped = props.mapped;
if(props.address !== undefined)
this.#address = props.address;
if(props.position !== undefined)
this.#position = props.position;
this.#initialClass = props.initialClass !== undefined ?
props.initialClass
: props.class;
}
}
@register({ GTypeName: "Compositor" })
export class Compositor extends GObject.Object {
protected _workspaces: Array<Workspace> = [];
protected _focusedClient: Client|null = null;
@getter(Array<Workspace>)
get workspaces() { return this._workspaces; }
@getter(gtype<Client|null>(Client))
get focusedClient() { return this._focusedClient; }
constructor() {
super();
}
};
export function getDefault(): Compositor {
if(!compositor)
throw new Error("Compositors haven't been initialized correctly, please call `Compositors.init()` before calling any method in `Compositors`");
return compositor;
}
/** Uses the XDG_CURRENT_DESKTOP variable to detect running compositor's name.
* ---
* @returns running wayland compositor's name (lowercase) or `undefined` if variable's not set */
export function getName(): string|undefined {
return GLib.getenv("XDG_CURRENT_DESKTOP")?.toLowerCase() ?? undefined;
}
/** initialize colorshell's wayland compositor implementation abstraction.
* when called, and if it's implemented, sets the default compositor to an equivalent implementation for the current desktop(checks from XDG_CURRENT_DESKTOP) */
export function init(): void {
switch(Compositors.getName()) {
case "hyprland":
compositor = new CompositorHyprland();
break;
default:
console.error(`This compositor(${Compositors.getName()}) is not yet implemented to colorshell. Please contribute by implementing it if you can! :)`);
}
}
}