refactor!: start migration to latest ags

This commit is contained in:
2025-12-05 17:00:22 -08:00
parent 1759e2d976
commit 42b4f99c37
12 changed files with 191 additions and 147 deletions

34
app.ts
View File

@@ -1,29 +1,25 @@
import { App, Gdk } from "astal/gtk3";
import style from "./style.scss";
import Bar from "./widget/Bar";
import { GLib } from "astal";
import app from "ags/gtk4/app"
import style from "./style.scss"
import Bar from "./widget/Bar"
import { interval } from "ags/time"
App.start({
app.start({
css: style,
icons: "icons",
main() {},
});
main() {
checkMonitors()
interval(10000, () => checkMonitors())
},
})
let knownMonitors = new Set();
let knownMonitors = new Set()
function checkMonitors() {
const currentMonitors = App.get_monitors();
const currentMonitors = app.get_monitors()
currentMonitors.forEach((monitor) => {
if (!knownMonitors.has(monitor.model)) {
knownMonitors.add(monitor.model);
Bar(monitor);
knownMonitors.add(monitor.model)
Bar(monitor)
}
});
})
}
checkMonitors();
GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 10, () => {
checkMonitors();
return true;
});

View File

@@ -1,14 +0,0 @@
{
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "astal-shell",
"dependencies": {
"astal": "/nix/store/pvb3x021mr6xknm91gqq76gy32n96vj0-astal-gjs/share/astal/gjs",
},
},
},
"packages": {
"astal": ["astal@file:../../../../nix/store/pvb3x021mr6xknm91gqq76gy32n96vj0-astal-gjs/share/astal/gjs", {}],
}
}

21
flake.lock generated
View File

@@ -42,6 +42,26 @@
"type": "github"
}
},
"astal_2": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1764173295,
"narHash": "sha256-Jh4VtPcK2Ov+RTcV9FtyQRsxiJmXFQGfqX6jjM7/mgc=",
"owner": "aylur",
"repo": "astal",
"rev": "7d1fac8a4b2a14954843a978d2ddde86168c75ef",
"type": "github"
},
"original": {
"owner": "aylur",
"repo": "astal",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1764667669,
@@ -61,6 +81,7 @@
"root": {
"inputs": {
"ags": "ags",
"astal": "astal_2",
"nixpkgs": "nixpkgs"
}
}

View File

@@ -4,6 +4,11 @@
inputs = {
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
astal = {
url = "github:aylur/astal";
inputs.nixpkgs.follows = "nixpkgs";
};
ags = {
url = "github:aylur/ags";
inputs.nixpkgs.follows = "nixpkgs";
@@ -15,6 +20,7 @@
self,
nixpkgs,
ags,
astal,
}:
let
system = "x86_64-linux";
@@ -28,20 +34,52 @@
];
in
{
packages.${system} = {
status-bar = ags.lib.bundle {
inherit pkgs;
src = ./.;
name = "status-bar";
entry = "app.ts";
# packages.${system} = {
# status-bar = ags.lib.bundle {
# inherit pkgs;
# src = ./.;
# name = "status-bar";
# entry = "app.ts";
#
# extraPackages =
# with pkgs;
# extraPkgs
# ++ [
# libgtop
# ];
# };
# };
packages.${system}.default = pkgs.stdenv.mkDerivation rec {
pname = "status-bar";
name = "status-bar";
extraPackages =
with pkgs;
extraPkgs
++ [
libgtop
];
};
src = ./.;
nativeBuildInputs = with pkgs; [
wrapGAppsHook3
gobject-introspection
ags.packages.${system}.default
];
buildInputs = [
pkgs.glib
pkgs.libgtop
pkgs.gjs
astal.packages.${system}.io
astal.packages.${system}.astal4
astal.packages.${system}.battery
astal.packages.${system}.hyprland
astal.packages.${system}.network
astal.packages.${system}.wireplumber
];
installPhase = ''
mkdir -p $out/bin
mkdir -p $out/share
cp -r * $out/share
jj
ags bundle app.ts $out/bin/${pname} -d "SRC='$out/share'"
'';
};
devShells.${system} = {

21
package-lock.json generated
View File

@@ -1,21 +0,0 @@
{
"name": "astal-shell",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "astal-shell",
"dependencies": {
"astal": "/nix/store/pvb3x021mr6xknm91gqq76gy32n96vj0-astal-gjs/share/astal/gjs"
}
},
"../../../../nix/store/pvb3x021mr6xknm91gqq76gy32n96vj0-astal-gjs/share/astal/gjs": {
"name": "astal",
"license": "LGPL-2.1"
},
"node_modules/astal": {
"resolved": "../../../../nix/store/pvb3x021mr6xknm91gqq76gy32n96vj0-astal-gjs/share/astal/gjs",
"link": true
}
}
}

View File

@@ -1,6 +1,10 @@
{
"name": "astal-shell",
"dependencies": {
"astal": "/nix/store/pvb3x021mr6xknm91gqq76gy32n96vj0-astal-gjs/share/astal/gjs"
}
"dependencies": {
"ags": "*",
"gnim": "*"
},
"prettier": {
"semi": false,
"tabWidth": 2
}
}

View File

@@ -1,14 +1,14 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"experimentalDecorators": true,
"strict": false,
"target": "ES2022",
"module": "ES2022",
"moduleResolution": "Bundler",
// "checkJs": true,
// "allowJs": true,
"jsx": "react-jsx",
"jsxImportSource": "astal/gtk3",
}
}
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "ags/gtk4",
"lib": [
"ES2023"
],
"module": "ES2022",
"moduleResolution": "Bundler",
"strict": true,
"target": "ES2020"
}
}

View File

@@ -1,43 +1,35 @@
import { App, Astal, Gtk, Gdk } from "astal/gtk3";
import Workspaces from "./workspaces";
import Audio from "./audio";
import NetworkModule from "./network";
import Cpu from "./cpu-widget";
import Ram from "./ram";
import Disk from "./disk";
import Battery from "./battery";
import { Astal, Gtk, Gdk } from "ags/gtk4";
// import Workspaces from "./workspaces";
// import Audio from "./audio";
// import NetworkModule from "./network";
// import Cpu from "./cpu-widget";
// import Ram from "./ram";
// import Disk from "./disk";
// import Battery from "./battery";
import Time from "./time";
import Title from "./title";
import app from "ags/gtk4/app";
import Workspaces from "./workspaces";
export default function Bar(gdkmonitor: Gdk.Monitor) {
const { TOP, LEFT, RIGHT } = Astal.WindowAnchor;
//@ts-ignore
return (
<window
className="Bar"
visible
name="bar"
class="Bar"
gdkmonitor={gdkmonitor}
exclusivity={Astal.Exclusivity.EXCLUSIVE}
anchor={TOP | LEFT | RIGHT}
application={App}
application={app}
>
<centerbox>
<box hexpand halign={Gtk.Align.START}>
<box className="nix-icon">
<icon icon="nixos-3" />
</box>
<Workspaces monitor={gdkmonitor} />
</box>
<box className="client-title">
<Workspaces $type="start" monitor={gdkmonitor} />
<box $type="center" class="client-title">
<Title />
</box>
<box hexpand halign={Gtk.Align.END}>
<Audio />
<NetworkModule />
<Cpu />
<Ram />
<Disk />
<Battery />
<box $type="end">
<Time />
</box>
</centerbox>

View File

@@ -3,15 +3,16 @@ import AstalWp from "gi://AstalWp?version=0.1"
export default function Audio() {
const speaker = AstalWp.get_default()?.default_speaker!
const derived = Variable.derive([bind(speaker, "volume"), bind(speaker, "mute")], (volume: number, muted: boolean) => {
if (muted) {
return { label: ` (muted)`, muted }
}
return { label: `${Math.floor(volume * 100)}% ` }
})
// const derived = Variable.derive([bind(speaker, "volume"), bind(speaker, "mute")], (volume: number, muted: boolean) => {
// if (muted) {
// return { label: ` (muted)`, muted }
// }
// return { label: `${Math.floor(volume * 100)}% ` }
// })
// return <box className={derived((v) => ["status-box", v.muted && "inactive"].filter(Boolean).join(" "))}>
// <label
// label={derived((v) => v.label)} />
// </box>
return <box className={derived((v) => ["status-box", v.muted && "inactive"].filter(Boolean).join(" "))}>
<label
label={derived((v) => v.label)} />
</box>
}

View File

@@ -1,15 +1,24 @@
import { bind, GLib, Variable } from "astal"
// let current_time = Variable(GLib.DateTime.new_now_local().format("%H:%M"))
// GLib.timeout_add(GLib.PRIORITY_DEFAULT, 1000, () => {
// const now = GLib.DateTime.new_now_local()
// current_time.set(now.format("%b %e (%a) %H:%M"))
// return true
let current_time = Variable(GLib.DateTime.new_now_local().format("%H:%M"))
GLib.timeout_add(GLib.PRIORITY_DEFAULT, 1000, () => {
const now = GLib.DateTime.new_now_local()
current_time.set(now.format("%b %e (%a) %H:%M"))
return true
})
import { createPoll } from "ags/time"
// })
export default function Time() {
const time = createPoll("", 500, () => {
return new Date().toLocaleString(undefined, {
hour12: false
})
})
return <box className="status-box">
<label label={bind(current_time)} />
return <box class="status-box">
<label label={time} />
</box>
// return <box class="status-box">
// <label label={bind(current_time)} />
// </box>
}

View File

@@ -1,5 +1,6 @@
import { bind, Variable } from "astal"
import { createPoll } from "ags/time";
import AstalHyprland from "gi://AstalHyprland?version=0.1";
import { createState } from "gnim";
const hyprland = AstalHyprland.get_default()
@@ -7,10 +8,15 @@ function get_title() {
return hyprland.focusedClient?.title ?? ""
}
const title = Variable(get_title()).poll(200, () => get_title())
// const title = Variable(get_title()).poll(200, () => get_title())
export default function Title() {
const title = createPoll("", 200, () => get_title())
return (
<label label={title(t => t)} />
<label label={title} />
)
// return (
// <label label={title(t => t)} />
// )
}

View File

@@ -1,23 +1,35 @@
import { bind } from "astal"
import { Gdk } from "astal/gtk3"
import { Gdk } from "ags/gtk4"
import AstalHyprland from "gi://AstalHyprland?version=0.1"
import { createBinding, For } from "gnim"
export default function Workspaces({ monitor }: { monitor: Gdk.Monitor }) {
const hypr = AstalHyprland.get_default()
const workspaces = createBinding(hypr, "workspaces").as(wss => wss.sort((a, b) => a.id - b.id))
return <box className="workspaces">
{bind(hypr, "workspaces").as(wss => wss.filter(ws => !(ws.id >= -99 && ws.id <= -2))
.sort((a, b) => a.id - b.id)
.map(ws => {
if (ws.monitor.model !== monitor.model) return <></>
return (
<button
className={bind(hypr, "focusedWorkspace").as(fw =>
ws === fw ? "focused" : "")}
onClicked={() => ws.focus()}>
{ws.id}
return (
<box class="workspaces">
<For each={workspaces}>
{(ws) => (
<button class={createBinding(hypr, "focusedWorkspace").as((fw) => ws === fw ? "focused" : "")}>
<label label={ws.id.toString()} />
</button>
)
}))}
</box>
)}
</For>
</box>
)
// return <box className="workspaces">
// {bind(hypr, "workspaces").as(wss => wss.filter(ws => !(ws.id >= -99 && ws.id <= -2))
// .sort((a, b) => a.id - b.id)
// .map(ws => {
// if (ws.monitor.model !== monitor.model) return <></>
// return (
// <button
// className={bind(hypr, "focusedWorkspace").as(fw =>
// ws === fw ? "focused" : "")}
// onClicked={() => ws.focus()}>
// {ws.id}
// </button>
// )
// }))}
// </box>
}