import { Astal, Gdk, Gtk } from "ags/gtk4"; import app from "ags/gtk4/app"; import { createBinding, createState, For, With, Accessor } from "ags"; import { createPoll } from "ags/time"; import Tray from "gi://AstalTray"; import { execAsync } from "ags/process"; import Hyprland from "gi://AstalHyprland"; import { getIconName } from "./utils"; import Wp from "gi://AstalWp"; import Battery from "gi://AstalBattery"; import GLib from "gi://GLib"; const battery = Battery.get_default(); const sensorsAvailable = await execAsync(["sensors"]) .then(() => true) .catch(() => false); const wirePlumber = Wp.get_default(); function SysTray(): JSX.Element { const tray = Tray.get_default(); let items = createBinding(tray, "items"); const init = (btn: Gtk.MenuButton, item: Tray.TrayItem) => { btn.menuModel = item.menuModel; btn.insert_action_group("dbusmenu", item.actionGroup); item.connect("notify::action-group", () => { btn.insert_action_group("dbusmenu", item.actionGroup); }); }; return ( {(item: Tray.TrayItem) => { if (item.iconThemePath) app.add_icons(item.iconThemePath); return ( init(self, item)} class="systray" tooltipMarkup={createBinding(item, "tooltipMarkup")} menuModel={createBinding(item, "menuModel")} > ); }} ); } function Left(): JSX.Element { return ( ); } function Center(): JSX.Element { return ( ); } function Date({ format = "%Y-%m-%d" }): JSX.Element { const time = createPoll( "", 60000, () => GLib.DateTime.new_now_local().format(format)!, ); return ( ); } function Icons() { return ( ); } function Volume(): JSX.Element { if (!wirePlumber) return ; const audio = wirePlumber.audio; const icon = createBinding(audio.default_speaker, "volume").as((volume) => { const vol = volume * 100; const icon = [ [101, "overamplified"], [67, "high"], [34, "medium"], [1, "low"], [0, "muted"], ].find(([threshold]) => Number(threshold) <= vol)?.[1]; return `audio-volume-${icon}-symbolic`; }); const css = createBinding(audio.default_speaker, "mute").as((mute) => { return mute ? "margin-left:0;" : "margin-left: 0.7em;"; }); let volume = createBinding(audio.default_speaker, "volume"); let mute = createBinding(audio.default_speaker, "mute"); return ( ); } function Workspaces(): JSX.Element { const hyprland = Hyprland.get_default(); let workspaces = createBinding(hyprland, "workspaces"); return ( {(wss: Array) => ( {(fm: Hyprland.Monitor) => { let filtered_wss = new Accessor(() => wss .sort((a, b) => a.id - b.id) .filter( (ws) => ws && ws.get_monitor() && ws.get_monitor().get_id() === fm.get_id(), ), ); return ( {(ws: Hyprland.Workspace, _index) => ( )} ); }} )} ); } function shorten(title: string) { return title.length > 40 ? title.slice(0, 20) + "..." : title; } function Clients(): JSX.Element { const hyprland = Hyprland.get_default(); let clients = createBinding(hyprland, "clients"); return ( {(fw: Hyprland.Workspace) => ( {(cls: Array) => { let filtered_clients = new Accessor(() => cls .sort((a, b) => a.pid - b.pid) .filter((cl) => !cl.title.includes("rofi")) .filter( (cl) => fw && cl.get_workspace().get_id() === fw.get_id(), ), ); return ( {(cl: Hyprland.Client, _index) => ( a && a.address === cl.address ? "focused" : "unfocused", )} > )} ); }} )} ); } export default function Bar(gdkmonitor: Gdk.Monitor, scaleFactor: number = 1) { console.log("Creating Bar on monitor:", gdkmonitor); return (
); }