From 42b4f99c37a080da7d3e3d3bf9d932c697c3f37d Mon Sep 17 00:00:00 2001 From: rocketcamel Date: Fri, 5 Dec 2025 17:00:22 -0800 Subject: [PATCH] refactor!: start migration to latest ags --- app.ts | 34 ++++++++++------------- bun.lock | 14 ---------- flake.lock | 21 ++++++++++++++ flake.nix | 64 ++++++++++++++++++++++++++++++++++--------- package-lock.json | 21 -------------- package.json | 12 +++++--- tsconfig.json | 26 +++++++++--------- widget/Bar.tsx | 42 ++++++++++++---------------- widget/audio.tsx | 21 +++++++------- widget/time.tsx | 27 ++++++++++++------ widget/title.tsx | 12 ++++++-- widget/workspaces.tsx | 44 ++++++++++++++++++----------- 12 files changed, 191 insertions(+), 147 deletions(-) delete mode 100644 bun.lock delete mode 100644 package-lock.json diff --git a/app.ts b/app.ts index 20076c2..82c55d7 100644 --- a/app.ts +++ b/app.ts @@ -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; -}); diff --git a/bun.lock b/bun.lock deleted file mode 100644 index 56a42a2..0000000 --- a/bun.lock +++ /dev/null @@ -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", {}], - } -} diff --git a/flake.lock b/flake.lock index 7d516c6..4dde1ce 100644 --- a/flake.lock +++ b/flake.lock @@ -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" } } diff --git a/flake.nix b/flake.nix index 7554ded..6ff83d0 100644 --- a/flake.nix +++ b/flake.nix @@ -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} = { diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 635a9c5..0000000 --- a/package-lock.json +++ /dev/null @@ -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 - } - } -} diff --git a/package.json b/package.json index 32f5d43..cbf736c 100644 --- a/package.json +++ b/package.json @@ -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 + } } diff --git a/tsconfig.json b/tsconfig.json index 58e16ed..3eb304c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -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" + } +} \ No newline at end of file diff --git a/widget/Bar.tsx b/widget/Bar.tsx index 8b9990c..341dfe8 100644 --- a/widget/Bar.tsx +++ b/widget/Bar.tsx @@ -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 ( - - - - - - - + + </box> - <box hexpand halign={Gtk.Align.END}> - <Audio /> - <NetworkModule /> - <Cpu /> - <Ram /> - <Disk /> - <Battery /> + <box $type="end"> <Time /> </box> </centerbox> diff --git a/widget/audio.tsx b/widget/audio.tsx index ec3db8a..72a4fd7 100644 --- a/widget/audio.tsx +++ b/widget/audio.tsx @@ -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> } diff --git a/widget/time.tsx b/widget/time.tsx index b453be8..0464568 100644 --- a/widget/time.tsx +++ b/widget/time.tsx @@ -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> } diff --git a/widget/title.tsx b/widget/title.tsx index 8d18d12..97b2b52 100644 --- a/widget/title.tsx +++ b/widget/title.tsx @@ -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)} /> + // ) } diff --git a/widget/workspaces.tsx b/widget/workspaces.tsx index 0dffed8..828ed90 100644 --- a/widget/workspaces.tsx +++ b/widget/workspaces.tsx @@ -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> }