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,94 @@
import { Astal, Gtk } from "ags/gtk4";
import { createBinding, createComputed, For } from "ags";
import { Notifications } from "../../modules/notifications";
import { NotificationWidget } from "../../widget/Notification";
import { generalConfig } from "../../config";
import AstalNotifd from "gi://AstalNotifd";
import Adw from "gi://Adw?version=1";
const size = 450;
export const FloatingNotifications = (mon: number) =>
<Astal.Window namespace={"floating-notifications"} monitor={mon} layer={Astal.Layer.OVERLAY}
anchor={createComputed([
generalConfig.bindProperty("notifications.position_h", "string"),
generalConfig.bindProperty("notifications.position_v", "string")
]).as(([posH, posV]) => {
const pos: Array<Astal.WindowAnchor> = [];
switch(posH) {
case "left":
pos.push(Astal.WindowAnchor.LEFT);
break;
case "center":
pos.push(Astal.WindowAnchor.LEFT);
pos.push(Astal.WindowAnchor.RIGHT);
break;
case "right":
pos.push(Astal.WindowAnchor.RIGHT);
break;
}
switch(posV) {
case "top":
pos.push(Astal.WindowAnchor.TOP);
break;
case "center":
pos.push(Astal.WindowAnchor.TOP);
pos.push(Astal.WindowAnchor.BOTTOM);
break;
case "bottom":
pos.push(Astal.WindowAnchor.BOTTOM);
break;
}
let finalPos: Astal.WindowAnchor;
pos.forEach(pos => finalPos = (finalPos !== undefined ?
finalPos | pos
: pos));
return finalPos!;
})} exclusivity={Astal.Exclusivity.NORMAL}
resizable={false} widthRequest={450}>
<Gtk.Box class={"floating-notifications-container"} spacing={12}
orientation={Gtk.Orientation.VERTICAL}>
<For each={createBinding(Notifications.getDefault(), "notifications")}>
{(notif: AstalNotifd.Notification) =>
<Gtk.Stack transitionType={createComputed([
generalConfig.bindProperty("notifications.position_h", "string"),
generalConfig.bindProperty("notifications.position_v", "string")
]).as(([posH, posV]) => {
//TODO: support different animations depending on screen position
return Gtk.StackTransitionType.SLIDE_RIGHT
})} transitionDuration={300}>
<Gtk.StackPage name={"notification"} child={
<Adw.Clamp maximumSize={size}>
<Gtk.Box class={"float-notification"} widthRequest={size} vexpand={false}
valign={Gtk.Align.CENTER} halign={Gtk.Align.CENTER}>
<NotificationWidget notification={notif} showTime={false}
actionClose={() => Notifications.getDefault().removeNotification(notif)}
holdOnHover actionClicked={() => {
const viewAction = notif.actions.filter(a =>
a.id.toLowerCase() === "view" ||
a.label.toLowerCase() === "view"
)?.[0];
viewAction && notif.invoke(viewAction.id);
}}
/>
</Gtk.Box>
</Adw.Clamp> as Gtk.Widget
}>
</Gtk.StackPage>
</Gtk.Stack>
}
</For>
</Gtk.Box>
</Astal.Window> as Astal.Window;