diff --git a/.gitignore b/.gitignore
index 298eb4d..8456525 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
node_modules/
@girs/
+env.d.ts
diff --git a/app.ts b/app.ts
index 6ed1e1a..b901b12 100644
--- a/app.ts
+++ b/app.ts
@@ -1,16 +1,14 @@
-import { App } from "astal/gtk4";
+import app from "ags/gtk4/app";
+import GLib from "gi://GLib";
import style from "./style.scss";
import windows from "./windows";
-import GLib from "gi://GLib";
-import { reqHandler } from "./handler";
const icons = `${GLib.get_user_config_dir()}/tpanel/assets/icons`;
-App.start({
+app.start({
css: style,
icons: icons,
- requestHandler: reqHandler,
main() {
- windows.map((win) => App.get_monitors().map(win));
+ windows.map((win) => app.get_monitors().map(win));
},
});
diff --git a/flake.lock b/flake.lock
index 4ceda29..02d8e82 100644
--- a/flake.lock
+++ b/flake.lock
@@ -8,11 +8,11 @@
]
},
"locked": {
- "lastModified": 1744557573,
- "narHash": "sha256-XAyj0iDuI51BytJ1PwN53uLpzTDdznPDQFG4RwihlTQ=",
+ "lastModified": 1758577685,
+ "narHash": "sha256-iHT0kvsQJG+Z89quGi7rNCXEg2e3DBGfuuCMu/UwiIo=",
"owner": "aylur",
"repo": "ags",
- "rev": "3ed9737bdbc8fc7a7c7ceef2165c9109f336bff6",
+ "rev": "aa7a8a2dd6e54aaeb4e13a73ed3bc2283995090b",
"type": "github"
},
"original": {
@@ -29,31 +29,11 @@
]
},
"locked": {
- "lastModified": 1742571008,
- "narHash": "sha256-5WgfJAeBpxiKbTR/gJvxrGYfqQRge5aUDcGKmU1YZ1Q=",
+ "lastModified": 1756474652,
+ "narHash": "sha256-iiBU6itpEqE0spXeNJ3uJTfioSyKYjt5bNepykpDXTE=",
"owner": "aylur",
"repo": "astal",
- "rev": "dc0e5d37abe9424c53dcbd2506a4886ffee6296e",
- "type": "github"
- },
- "original": {
- "owner": "aylur",
- "repo": "astal",
- "type": "github"
- }
- },
- "astal_2": {
- "inputs": {
- "nixpkgs": [
- "nixpkgs"
- ]
- },
- "locked": {
- "lastModified": 1748416910,
- "narHash": "sha256-FEQcs58HL8Fe4i7XlqVEUwthjxwvRvgX15gTTfW17sU=",
- "owner": "aylur",
- "repo": "astal",
- "rev": "c1bd89a47c81c66ab5fc6872db5a916c0433fb89",
+ "rev": "20bd8318e4136fbd3d4eb2d64dbabc3acbc915dd",
"type": "github"
},
"original": {
@@ -64,11 +44,11 @@
},
"nixpkgs": {
"locked": {
- "lastModified": 1748026106,
- "narHash": "sha256-6m1Y3/4pVw1RWTsrkAK2VMYSzG4MMIj7sqUy7o8th1o=",
+ "lastModified": 1758427187,
+ "narHash": "sha256-pHpxZ/IyCwoTQPtFIAG2QaxuSm8jWzrzBGjwQZIttJc=",
"owner": "nixos",
"repo": "nixpkgs",
- "rev": "063f43f2dbdef86376cc29ad646c45c46e93234c",
+ "rev": "554be6495561ff07b6c724047bdd7e0716aa7b46",
"type": "github"
},
"original": {
@@ -81,7 +61,6 @@
"root": {
"inputs": {
"ags": "ags",
- "astal": "astal_2",
"nixpkgs": "nixpkgs"
}
}
diff --git a/flake.nix b/flake.nix
index c135a9d..9c4a99e 100644
--- a/flake.nix
+++ b/flake.nix
@@ -1,11 +1,9 @@
{
description = "tux's widgets for wayland";
+
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,29 +13,54 @@
outputs = {
self,
nixpkgs,
- astal,
ags,
}: let
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
+ pname = "tpanel";
+ entry = "app.ts";
+
+ agsPackages = with ags.packages.${system}; [
+ io
+ astal4
+ hyprland
+ apps
+ battery
+ tray
+ network
+ notifd
+ ];
+
+ extraPackages =
+ agsPackages
+ ++ [
+ pkgs.libadwaita
+ ];
in {
packages.${system} = {
default = let
- tpanel = ags.lib.bundle {
- inherit pkgs;
+ tpanel = pkgs.stdenv.mkDerivation {
+ name = pname;
src = ./.;
- name = "tpanel";
- entry = "app.ts";
- gtk4 = true;
- extraPackages = with ags.packages.${system}; [
- hyprland
- apps
- battery
- tray
- network
- notifd
+ nativeBuildInputs = with pkgs; [
+ wrapGAppsHook
+ gobject-introspection
+ ags.packages.${system}.default
];
+
+ buildInputs = extraPackages ++ [pkgs.gjs];
+
+ installPhase = ''
+ runHook preInstall
+
+ mkdir -p $out/bin
+ mkdir -p $out/share
+ cp -r * $out/share
+ ags bundle ${entry} $out/bin/${pname} -d "SRC='$out/share'"
+
+ runHook postInstall
+ '';
};
in
pkgs.runCommand "tpanel" {
@@ -67,7 +90,7 @@
'';
- astal = astal.packages.${system};
+ ags = ags.packages.${system};
};
apps.default = {
@@ -77,20 +100,9 @@
devShells.${system} = {
default = pkgs.mkShell {
- nativeBuildInputs = [
- astal.packages.${system}.default
- ];
buildInputs = [
- # includes astal3 astal4 astal-io by default
(ags.packages.${system}.default.override {
- extraPackages = with ags.packages.${system}; [
- hyprland
- apps
- battery
- tray
- network
- notifd
- ];
+ inherit extraPackages;
})
];
};
diff --git a/handler.ts b/handler.ts
deleted file mode 100644
index 174d870..0000000
--- a/handler.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { App } from "astal/gtk4";
-import { WINDOW_NAME } from "./widgets/bar";
-
-export const reqHandler = (req: string, res: (res: any) => void) => {
- switch (req) {
- case "toggle-bar":
- const win = App.get_window(WINDOW_NAME);
- win?.is_visible() ? win.hide() : win?.set_visible(true);
- break;
-
- default:
- res("uknown command");
- }
-};
diff --git a/package-lock.json b/package-lock.json
deleted file mode 100644
index 98d7200..0000000
--- a/package-lock.json
+++ /dev/null
@@ -1,35 +0,0 @@
-{
- "name": "astal-shell",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "astal-shell",
- "dependencies": {
- "astal": "/nix/store/8cl58ip2nasg6rdyj59cwg2f0qbixs28-astal-gjs/share/astal/gjs",
- "typescript": "^5.7.3"
- }
- },
- "../../../../nix/store/8cl58ip2nasg6rdyj59cwg2f0qbixs28-astal-gjs/share/astal/gjs": {
- "name": "astal",
- "license": "LGPL-2.1"
- },
- "node_modules/astal": {
- "resolved": "../../../../nix/store/8cl58ip2nasg6rdyj59cwg2f0qbixs28-astal-gjs/share/astal/gjs",
- "link": true
- },
- "node_modules/typescript": {
- "version": "5.7.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz",
- "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==",
- "license": "Apache-2.0",
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=14.17"
- }
- }
- }
-}
diff --git a/package.json b/package.json
deleted file mode 100644
index 74960ce..0000000
--- a/package.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "name": "astal-shell",
- "dependencies": {
- "astal": "/nix/store/8cl58ip2nasg6rdyj59cwg2f0qbixs28-astal-gjs/share/astal/gjs",
- "typescript": "^5.7.3"
- }
-}
diff --git a/tsconfig.json b/tsconfig.json
index a92bc43..9078586 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,14 +1,10 @@
{
- "$schema": "https://json.schemastore.org/tsconfig",
- "compilerOptions": {
- "experimentalDecorators": true,
- "strict": true,
- "target": "ES2022",
- "module": "ES2022",
- "moduleResolution": "Bundler",
- // "checkJs": true,
- // "allowJs": true,
- "jsx": "react-jsx",
- "jsxImportSource": "astal/gtk4",
- }
-}
+ "compilerOptions": {
+ "jsx": "react-jsx",
+ "jsxImportSource": "ags/gtk4",
+ "module": "ES2022",
+ "moduleResolution": "Bundler",
+ "strict": true,
+ "target": "ES2020"
+ }
+}
\ No newline at end of file
diff --git a/widgets/app-launcher/index.tsx b/widgets/app-launcher/index.tsx
index a636f60..643bc2d 100644
--- a/widgets/app-launcher/index.tsx
+++ b/widgets/app-launcher/index.tsx
@@ -1,13 +1,16 @@
-import { Variable } from "astal";
-import { App, Astal, Gdk, Gtk, hook } from "astal/gtk4";
+import { createState, For } from "ags";
+import { Astal, Gdk, Gtk } from "ags/gtk4";
+import app from "ags/gtk4/app";
import AstalApps from "gi://AstalApps";
export const WINDOW_NAME = "app-launcher";
+
+let searchEntry: Gtk.Entry;
const apps = new AstalApps.Apps();
-const text = Variable("");
+const [searchText, setSearchText] = createState("");
const hide = () => {
- App.get_window(WINDOW_NAME)?.set_visible(false);
+ app.get_window(WINDOW_NAME)?.set_visible(false);
};
const AppButton = ({ app }: { app: AstalApps.Application }) => {
@@ -29,42 +32,29 @@ const AppButton = ({ app }: { app: AstalApps.Application }) => {
};
const AppList = () => {
- const appList = text((text) => apps.fuzzy_query(text));
+ const appList = searchText((text) => apps.fuzzy_query(text));
return (
-
- {appList.as((list) => list.map((app) => ))}
+
+ {(app) => }
);
};
const AppSearch = () => {
- const onEnter = () => {
- apps.fuzzy_query(text.get())?.[0].launch();
- hide();
- };
return (
(searchEntry = ref)}
cssClasses={["search"]}
- vexpand
- text={text.get()}
+ text={searchText}
placeholderText="Search..."
- onChanged={(self) => text.set(self.text)}
- onActivate={onEnter}
- setup={(self) => {
- hook(self, App, "window-toggled", (_, win) => {
- const winName = win.name;
- const visible = win.visible;
-
- if (winName == WINDOW_NAME && visible) {
- text.set("");
- self.set_text("");
- self.grab_focus();
- }
- });
- }}
+ onNotifyText={({ text }) => setSearchText(text)}
/>
);
};
@@ -75,16 +65,17 @@ export const AppLauncher = (gdkmonitor: Gdk.Monitor) => {
name={WINDOW_NAME}
cssClasses={["app-launcher"]}
gdkmonitor={gdkmonitor}
+ application={app}
exclusivity={Astal.Exclusivity.EXCLUSIVE}
- application={App}
keymode={Astal.Keymode.ON_DEMAND}
- onKeyPressed={(_, keyval) => {
- if (keyval === Gdk.KEY_Escape) {
- App.toggle_window(WINDOW_NAME);
- }
+ onNotifyVisible={({ visible }) => {
+ if (visible) searchEntry.grab_focus();
+ else searchEntry.set_text("");
}}
>
-
+
+
+
@@ -92,3 +83,15 @@ export const AppLauncher = (gdkmonitor: Gdk.Monitor) => {
);
};
+
+const onKey = (
+ _e: Gtk.EventControllerKey,
+ keyval: number,
+ _: number,
+ mod: number,
+) => {
+ if (keyval === Gdk.KEY_Escape) {
+ app.toggle_window(WINDOW_NAME);
+ return;
+ }
+};
diff --git a/widgets/bar/battery.tsx b/widgets/bar/battery.tsx
index 3d992c3..525d8db 100644
--- a/widgets/bar/battery.tsx
+++ b/widgets/bar/battery.tsx
@@ -1,14 +1,15 @@
-import { bind, Variable } from "astal";
+import { createBinding, createComputed } from "ags";
import AstalBattery from "gi://AstalBattery";
export const Battery = () => {
const battery = AstalBattery.get_default();
- const chargingIcon = Variable.derive(
- [
- bind(battery, "percentage"),
- bind(battery, "charging"),
- bind(battery, "state"),
- ],
+
+ const percentage = createBinding(battery, "percentage");
+ const charging = createBinding(battery, "charging");
+ const state = createBinding(battery, "state");
+
+ const chargingIcon = createComputed(
+ [percentage, charging, state],
(percentage, charging, state) => {
const batFull = state === AstalBattery.State.FULLY_CHARGED;
const p = percentage * 100;
@@ -21,11 +22,13 @@ export const Battery = () => {
);
return (
-
- chargingIcon.drop()} />
-