diff --git a/nixosModules/ags-v2/config/app.ts b/nixosModules/ags-v2/config/app.ts
index 1b056979..460fdcd0 100644
--- a/nixosModules/ags-v2/config/app.ts
+++ b/nixosModules/ags-v2/config/app.ts
@@ -2,7 +2,6 @@
// TODO: quick-settings
// TODO: music player stuff
// TODO: on-screen-keyboard
-// TODO: Greetd
// TODO: GSR
import GLib from 'gi://GLib';
diff --git a/nixosModules/ags-v2/config/configurations/greeter.ts b/nixosModules/ags-v2/config/configurations/greeter.ts
new file mode 100644
index 00000000..3403d29b
--- /dev/null
+++ b/nixosModules/ags-v2/config/configurations/greeter.ts
@@ -0,0 +1,20 @@
+export default async() => {
+ const { execAsync } = await import('astal');
+ const { App } = await import('astal/gtk3');
+
+ const Greeter = (await import('../widgets/greeter/main')).default;
+
+ const style = (await import('../style/greeter.scss')).default;
+
+
+ App.start({
+ css: style,
+ instanceName: 'greeter',
+
+ main: () => {
+ execAsync('hyprpaper').catch(() => { /**/ });
+
+ Greeter();
+ },
+ });
+};
diff --git a/nixosModules/ags-v2/config/style/greeter.scss b/nixosModules/ags-v2/config/style/greeter.scss
new file mode 100644
index 00000000..823e51ca
--- /dev/null
+++ b/nixosModules/ags-v2/config/style/greeter.scss
@@ -0,0 +1,18 @@
+@use 'colors';
+
+window {
+ all: unset;
+ background-color: transparent;
+}
+
+
+.base {
+ background-color: colors.$window_bg_color;
+ border: 1.3px solid colors.$accent_bg_color;
+ border-radius: 12px;
+ padding: 5px;
+}
+
+dropdown popover.menu {
+ padding-top: 0;
+}
diff --git a/nixosModules/ags-v2/config/widgets/greeter/main.tsx b/nixosModules/ags-v2/config/widgets/greeter/main.tsx
new file mode 100644
index 00000000..48d71574
--- /dev/null
+++ b/nixosModules/ags-v2/config/widgets/greeter/main.tsx
@@ -0,0 +1,118 @@
+import { idle, readFile } from 'astal';
+import { Astal, Gtk, Widget } from 'astal/gtk3';
+
+import AstalGreet from 'gi://AstalGreet';
+
+
+const DEFAULT_NAME = 'matt';
+const PARSED_INDEX = {
+ name: 0,
+ uid: 2,
+ gid: 3,
+ desc: 4,
+ home: 5,
+ shell: 6,
+};
+
+const parsePasswd = (fileContent: string) => {
+ const splitUsers = fileContent.split('\n');
+ const parsedUsers = splitUsers.map((u) => {
+ const user = u.split(':');
+
+ return {
+ name: user[PARSED_INDEX.name],
+ uid: Number(user[PARSED_INDEX.uid]),
+ gid: Number(user[PARSED_INDEX.gid]),
+ desc: user[PARSED_INDEX.desc],
+ home: user[PARSED_INDEX.home],
+ shell: user[PARSED_INDEX.shell],
+ };
+ });
+
+ // Filter out system users, nixbld users and nobody
+ return parsedUsers.filter((u) => {
+ return u.uid >= 1000 &&
+ !u.name.includes('nixbld') &&
+ u.name !== 'nobody';
+ });
+};
+
+const users = parsePasswd(readFile('/etc/passwd'));
+
+const dropdown = new Gtk.ComboBoxText();
+
+dropdown.show_all();
+
+users.forEach((u) => {
+ dropdown.append(null, u.name);
+});
+
+const response = as Widget.Label;
+
+const password = (
+ idle(() => {
+ self.grab_focus();
+ })}
+
+ onActivate={(self) => {
+ AstalGreet.login(
+ dropdown.get_active_text() ?? '',
+ self.text || '',
+ 'Hyprland',
+ (_, res) => {
+ try {
+ AstalGreet.login_finish(res);
+ }
+ catch (error) {
+ response.label = JSON.stringify(error);
+ }
+ },
+ );
+ }}
+ />
+);
+
+
+export default () => (
+
+
+ {
+ idle(() => {
+ const usernames = users.map((u) => u.name);
+
+ if (usernames.includes(DEFAULT_NAME)) {
+ dropdown.set_active(usernames.indexOf(DEFAULT_NAME));
+ }
+ });
+ }}
+ >
+ {dropdown}
+ {password}
+
+
+ {response}
+
+
+);
diff --git a/nixosModules/desktop/manager/ags.nix b/nixosModules/desktop/manager/ags.nix
new file mode 100644
index 00000000..eaed3425
--- /dev/null
+++ b/nixosModules/desktop/manager/ags.nix
@@ -0,0 +1,112 @@
+self: {
+ config,
+ lib,
+ pkgs,
+ ...
+}: let
+ # TODO: clean this up
+ inherit (self.inputs) agsV2 gtk-session-lock;
+in {
+ config = let
+ # Libs
+ inherit (lib) attrValues boolToString removeAttrs;
+
+ # Cfg info
+ inherit (config.networking) hostName;
+ cfgDesktop = config.roles.desktop;
+
+ # Astal libraries
+ gtkSessionLock = gtk-session-lock.packages.${pkgs.system}.default;
+ agsV2Packages = agsV2.packages.${pkgs.system};
+ astalLibs = attrValues (removeAttrs agsV2.inputs.astal.packages.${pkgs.system} ["docs" "gjs"]) ++ [gtkSessionLock];
+
+ # Final ags package
+ agsFull = agsV2Packages.ags.override {extraPackages = astalLibs;};
+
+ agsConfig = let
+ tsconfig = pkgs.writers.writeJSON "tsconfig.json" {
+ "$schema" = "https://json.schemastore.org/tsconfig";
+ "compilerOptions" = {
+ "experimentalDecorators" = true;
+ "strict" = true;
+ "target" = "ES2023";
+ "moduleResolution" = "Bundler";
+ "jsx" = "react-jsx";
+ "jsxImportSource" = "${agsV2Packages.gjs}/share/astal/gjs/gtk3";
+ "paths" = {
+ "astal" = ["${agsV2Packages.gjs}/share/astal/gjs"];
+ "astal/*" = ["${agsV2Packages.gjs}/share/astal/gjs/*"];
+ };
+ "skipLibCheck" = true;
+ "module" = "ES2022";
+ "lib" = ["ES2023"];
+ };
+ };
+
+ varsTs =
+ pkgs.writeText "vars.ts"
+ # javascript
+ ''
+ export default {
+ mainMonitor: '${cfgDesktop.mainMonitor}',
+ dupeLockscreen: ${boolToString cfgDesktop.displayManager.duplicateScreen},
+ hasFprintd: ${boolToString (hostName == "wim")},
+ };
+ '';
+
+ flakeDir = config.environment.variables.FLAKE;
+ modulesDir = "${lib.removePrefix "/home/${cfg.user}/" flakeDir}/nixosModules";
+ nodeModules = config.home-manager.users.${cfg.user}.home.file."${modulesDir}/ags/config/node_modules".source
+ or config.home-manager.users.${cfg.user}.home.file."${modulesDir}/ags-v2/config/node_modules".source;
+ in
+ pkgs.runCommandLocal "agsConfig" {} ''
+ cp -ar ${tsconfig} ./tsconfig.json
+ cp -ar ${../../../ags-v2/config}/* ./.
+ chmod +w -R ./.
+ cp -ar ${varsTs} ./widgets/lockscreen/vars.ts
+ cp -ar ${nodeModules} ./node_modules
+ ${agsFull}/bin/ags bundle ./app.ts $out
+ '';
+
+ cfg = config.roles.desktop;
+
+ hyprland =
+ config
+ .home-manager
+ .users
+ .${cfg.user}
+ .wayland
+ .windowManager
+ .hyprland
+ .finalPackage;
+ in {
+ # Add home folder for home-manager to work
+ users.users.greeter = {
+ home = "/var/lib/greeter";
+ createHome = true;
+ };
+
+ home-manager.users.greeter = {
+ home.packages = [
+ hyprland
+
+ (pkgs.writeShellApplication {
+ name = "agsGreeter";
+
+ runtimeInputs = [
+ agsFull
+ hyprland
+ ];
+
+ text = ''
+ export CONF="greeter"
+ exec ags run ${agsConfig}
+ '';
+ })
+ ];
+ };
+ };
+
+ # For accurate stack trace
+ _file = ./default.nix;
+}
diff --git a/nixosModules/desktop/manager/ags/.envrc b/nixosModules/desktop/manager/ags/.envrc
deleted file mode 120000
index d48d741e..00000000
--- a/nixosModules/desktop/manager/ags/.envrc
+++ /dev/null
@@ -1 +0,0 @@
-../../../ags/config/.envrc
\ No newline at end of file
diff --git a/nixosModules/desktop/manager/ags/default.nix b/nixosModules/desktop/manager/ags/default.nix
deleted file mode 100644
index e1f8edfd..00000000
--- a/nixosModules/desktop/manager/ags/default.nix
+++ /dev/null
@@ -1,90 +0,0 @@
-self: {
- config,
- lib,
- pkgs,
- ...
-}: let
- inherit (self.inputs) ags;
-in {
- config = let
- cfg = config.roles.desktop;
-
- hyprland =
- config
- .home-manager
- .users
- .${cfg.user}
- .wayland
- .windowManager
- .hyprland
- .finalPackage;
- in {
- # Add home folder for home-manager to work
- users.users.greeter = {
- home = "/var/lib/greeter";
- createHome = true;
- };
-
- # Setup node modules for dev env
- home-manager.users.${cfg.user}.home.file = let
- flakeDir = config.environment.variables.FLAKE;
- modulesDir = "${lib.removePrefix "/home/${cfg.user}/" flakeDir}/nixosModules";
- nodeModules =
- config.home-manager.users.${cfg.user}.home.file."${modulesDir}/ags/config/node_modules".source
- or config.home-manager.users.${cfg.user}.home.file."${modulesDir}/ags-v2/config/node_modules".source;
- in {
- "${modulesDir}/desktop/manager/ags/node_modules".source = nodeModules;
- };
-
- home-manager.users.greeter = {
- imports = [ags.homeManagerModules.default];
-
- programs.ags.enable = true;
-
- home.packages = [
- hyprland
- pkgs.gtk3
- pkgs.glib
- ];
-
- xdg.configFile = {
- "ags".source = pkgs.stdenv.mkDerivation {
- name = "ags-greeter";
- src = lib.fileset.toSource {
- root = ./.;
- fileset = lib.fileset.unions [
- ./scss
- ./greeter.ts
- ./ts
- ./tsconfig.json
- ];
- };
-
- buildInputs = builtins.attrValues {
- inherit
- (pkgs)
- bun
- dart-sass
- ;
- };
-
- buildPhase = ''
- sass ./scss/greeter.scss style.css
- bun build ./greeter.ts \
- --external resource:///* \
- --external gi://* \
- --external cairo > config.js
- '';
-
- installPhase = ''
- mkdir $out
- mv style.css config.js $out/
- '';
- };
- };
- };
- };
-
- # For accurate stack trace
- _file = ./default.nix;
-}
diff --git a/nixosModules/desktop/manager/ags/eslint.config.ts b/nixosModules/desktop/manager/ags/eslint.config.ts
deleted file mode 120000
index cd9e2c8b..00000000
--- a/nixosModules/desktop/manager/ags/eslint.config.ts
+++ /dev/null
@@ -1 +0,0 @@
-../../../ags/config/eslint.config.ts
\ No newline at end of file
diff --git a/nixosModules/desktop/manager/ags/greeter.ts b/nixosModules/desktop/manager/ags/greeter.ts
deleted file mode 100644
index cc4e06ca..00000000
--- a/nixosModules/desktop/manager/ags/greeter.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-Utils.execAsync('hyprpaper');
-
-import Greeter from './ts/greetd/main.ts';
-
-App.config({
- style: './style.css',
-
- windows: () => [
- Greeter(),
- ],
-});
diff --git a/nixosModules/desktop/manager/ags/package-lock.json b/nixosModules/desktop/manager/ags/package-lock.json
deleted file mode 120000
index 015339c8..00000000
--- a/nixosModules/desktop/manager/ags/package-lock.json
+++ /dev/null
@@ -1 +0,0 @@
-../../../ags/config/package-lock.json
\ No newline at end of file
diff --git a/nixosModules/desktop/manager/ags/package.json b/nixosModules/desktop/manager/ags/package.json
deleted file mode 120000
index c8b7d8ce..00000000
--- a/nixosModules/desktop/manager/ags/package.json
+++ /dev/null
@@ -1 +0,0 @@
-../../../ags/config/package.json
\ No newline at end of file
diff --git a/nixosModules/desktop/manager/ags/scss/greeter.scss b/nixosModules/desktop/manager/ags/scss/greeter.scss
deleted file mode 100644
index 34cf7798..00000000
--- a/nixosModules/desktop/manager/ags/scss/greeter.scss
+++ /dev/null
@@ -1,16 +0,0 @@
-window {
- all: unset;
- background-color: transparent;
-}
-
-
-.base {
- background-color: #{"@window_bg_color"};
- border: 1.3px solid #{"@accent_bg_color"};
- border-radius: 12px;
- padding: 5px;
-}
-
-dropdown popover.menu {
- padding-top: 0;
-}
diff --git a/nixosModules/desktop/manager/ags/ts/greetd/main.ts b/nixosModules/desktop/manager/ags/ts/greetd/main.ts
deleted file mode 100644
index 31a2336b..00000000
--- a/nixosModules/desktop/manager/ags/ts/greetd/main.ts
+++ /dev/null
@@ -1,103 +0,0 @@
-const { Box, Entry, Label, Window } = Widget;
-const { idle, readFileAsync } = Utils;
-
-const greetd = await Service.import('greetd');
-
-const { Gtk } = imports.gi;
-
-const DEFAULT_NAME = 'matt';
-
-
-const parsePasswd = (fileContent: string) => {
- const splitUsers = fileContent.split('\n');
- const parsedUsers = splitUsers.map((u) => {
- const user = u.split(':');
-
- return {
- name: user[0],
- uid: Number(user[2]),
- gid: Number(user[3]),
- desc: user[4],
- home: user[5],
- shell: user[6],
- };
- });
-
- // Filter out system users, nixbld users and nobody
- return parsedUsers.filter((u) => {
- return u.uid >= 1000 &&
- !u.name.includes('nixbld') &&
- u.name !== 'nobody';
- });
-};
-const users = parsePasswd(await readFileAsync('/etc/passwd'));
-
-const dropdown = new Gtk.ComboBoxText();
-
-users.forEach((u) => {
- dropdown.append(null, u.name);
-});
-
-const password = Entry({
- placeholderText: 'Password',
- visibility: false,
-
- setup: (self) => idle(() => {
- self.grab_focus();
- }),
-
- on_accept: () => {
- greetd.login(
- dropdown.get_active_text() ?? '',
- password.text || '',
- 'Hyprland',
-
- ).catch((error) => {
- response.label = JSON.stringify(error);
- });
- },
-
-});
-
-const response = Label();
-
-export default () => Window({
- name: 'greeter',
- keymode: 'on-demand',
-
- child: Box({
- vertical: true,
- hpack: 'center',
- vpack: 'center',
- hexpand: true,
- vexpand: true,
- class_names: ['base'],
-
- children: [
- Box({
- vertical: true,
- hpack: 'center',
- vpack: 'center',
- hexpand: true,
- vexpand: true,
- class_names: ['linked'],
-
- setup: () => {
- idle(() => {
- const usernames = users.map((u) => u.name);
-
- if (usernames.includes(DEFAULT_NAME)) {
- dropdown.set_active(usernames.indexOf(DEFAULT_NAME));
- }
- });
- },
-
- children: [
- dropdown,
- password,
- ],
- }),
- response,
- ],
- }),
-});
diff --git a/nixosModules/desktop/manager/ags/tsconfig.json b/nixosModules/desktop/manager/ags/tsconfig.json
deleted file mode 100644
index d429a672..00000000
--- a/nixosModules/desktop/manager/ags/tsconfig.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "compilerOptions": {
- "target": "ES2022",
- "module": "ES2022",
- "lib": ["ES2022"],
- "noEmit": true,
- "allowImportingTsExtensions": true,
- "allowSyntheticDefaultImports": true,
- "allowJs": true,
- "checkJs": true,
- "strict": true,
- "noImplicitAny": false,
- "baseUrl": ".",
- "paths": {
- "fzf": ["./node_modules/fzf/dist/types"]
- },
- "typeRoots": [
- "./types",
- "./global-types.d.ts",
- "./node_modules"
- ],
- "skipLibCheck": true,
- "forceConsistentCasingInFileNames": true
- }
-}
diff --git a/nixosModules/desktop/manager/default.nix b/nixosModules/desktop/manager/default.nix
index 36827402..0c8df6db 100644
--- a/nixosModules/desktop/manager/default.nix
+++ b/nixosModules/desktop/manager/default.nix
@@ -4,7 +4,7 @@ self: {
...
}: {
imports = [
- (import ./ags self)
+ (import ./ags.nix self)
(import ./hyprland.nix self)
];
diff --git a/nixosModules/desktop/manager/hyprland.nix b/nixosModules/desktop/manager/hyprland.nix
index e4ba03ac..d056d329 100644
--- a/nixosModules/desktop/manager/hyprland.nix
+++ b/nixosModules/desktop/manager/hyprland.nix
@@ -54,7 +54,7 @@ self: {
exec-once = [
setupMonitors
- "ags -b greeter &> /tmp/ags-greetd.log; hyprctl dispatch exit"
+ "agsGreeter &> /tmp/ags-greetd.log; hyprctl dispatch exit"
];
}
// devices;