Configure niri + add ags

This commit is contained in:
Christopher Mühl 2025-12-15 10:32:43 +01:00
parent 6da818cbca
commit fa16e5232f
No known key found for this signature in database
GPG key ID: E919B0F59E14FD47
20 changed files with 288 additions and 40 deletions

45
flake.lock generated
View file

@ -73,6 +73,49 @@
"type": "github"
}
},
"ags": {
"inputs": {
"astal": [
"astal"
],
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1764289441,
"narHash": "sha256-ak+lgFiYE5PHByN1/BRkO5JP498hno6Ix24C1Qf/vec=",
"owner": "aylur",
"repo": "ags",
"rev": "e169694390548dfd38ff40f1ef2163d6c3ffe3ea",
"type": "github"
},
"original": {
"owner": "aylur",
"repo": "ags",
"type": "github"
}
},
"astal": {
"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"
}
},
"awww": {
"inputs": {
"flake-compat": "flake-compat_4",
@ -965,6 +1008,8 @@
"affinity-nix": "affinity-nix",
"agenix": "agenix",
"agenix-rekey": "agenix-rekey",
"ags": "ags",
"astal": "astal",
"awww": "awww",
"darwin": "darwin_2",
"disko": "disko",

View file

@ -117,5 +117,16 @@
url = "github:nix-community/NUR";
inputs.nixpkgs.follows = "nixpkgs";
};
astal = {
url = "github:aylur/astal";
inputs.nixpkgs.follows = "nixpkgs";
};
ags = {
url = "github:aylur/ags";
inputs.nixpkgs.follows = "nixpkgs";
inputs.astal.follows = "astal";
};
};
}

View file

@ -42,7 +42,6 @@
quick-zeal
spawn-term
to-s3
tofi-hg
generate-wallpaper
];
};

View file

@ -0,0 +1,2 @@
node_modules/
@girs/

View file

@ -0,0 +1,10 @@
import app from "ags/gtk4/app"
import style from "./style.scss"
import Bar from "./widget/Bar"
app.start({
css: style,
main() {
app.get_monitors().map(Bar)
},
})

View file

@ -0,0 +1,21 @@
declare const SRC: string
declare module "inline:*" {
const content: string
export default content
}
declare module "*.scss" {
const content: string
export default content
}
declare module "*.blp" {
const content: string
export default content
}
declare module "*.css" {
const content: string
export default content
}

View file

@ -0,0 +1,10 @@
{
"dependencies": {
"ags": "*",
"gnim": "*"
},
"prettier": {
"semi": false,
"tabWidth": 2
}
}

View file

@ -0,0 +1,20 @@
// https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gtk/theme/Adwaita/_colors-public.scss
$fg-color: #{"@theme_fg_color"};
$bg-color: #{"@theme_bg_color"};
window.Bar {
background: transparent;
color: $fg-color;
font-weight: bold;
> centerbox {
background: $bg-color;
border-radius: 10px;
margin: 8px;
}
button {
border-radius: 8px;
margin: 2px;
}
}

View file

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

View file

@ -0,0 +1,39 @@
import app from "ags/gtk4/app"
import { Astal, Gtk, Gdk } from "ags/gtk4"
import { execAsync } from "ags/process"
import { createPoll } from "ags/time"
export default function Bar(gdkmonitor: Gdk.Monitor) {
const time = createPoll("", 1000, "date")
const { TOP, LEFT, RIGHT } = Astal.WindowAnchor
return (
<window
visible
name="bar"
class="Bar"
gdkmonitor={gdkmonitor}
exclusivity={Astal.Exclusivity.EXCLUSIVE}
anchor={TOP | LEFT | RIGHT}
application={app}
>
<centerbox cssName="centerbox">
<button
$type="start"
onClicked={() => execAsync("echo hello").then(console.log)}
hexpand
halign={Gtk.Align.CENTER}
>
<label label="Welcome to AGS!" />
</button>
<box $type="center" />
<menubutton $type="end" hexpand halign={Gtk.Align.CENTER}>
<label label={time} />
<popover>
<Gtk.Calendar />
</popover>
</menubutton>
</centerbox>
</window>
)
}

View file

@ -4,8 +4,10 @@
...
}: {
programs.niri.settings.spawn-at-startup = with lib._elements; [
{argv = ["kitty"];}
{argv = ["mako"];}
{argv = ["awww-daemon"];}
{argv = ["awww" "img" "${fixture "wallpapers/cat-vibes.webp"}"];}
{argv = ["kitty"];}
];
}

View file

@ -8,6 +8,8 @@
./window-rules.nix
./keybinds.nix
./autostart.nix
./shell.nix
./notifications.nix
];
programs.niri.package = pkgs.niri;

View file

@ -1,17 +1,31 @@
{
lib,
config,
pkgs,
...
}: let
in {
}: {
programs.niri.settings = {
binds = with config.lib.niri.actions; {
"Mod+q".action = close-window;
"Mod+t".action = spawn "${pkgs._elements.spawn-term}/bin/spawn-term";
"Mod+space".action = spawn "fuzzel";
"Mod+e".action = spawn "dolphin";
"Mod+c".action = spawn "${pkgs._elements.spawn-term}/bin/spawn-term";
"Mod+g".action = spawn "${pkgs._elements.hg-picker}/bin/hg-picker";
"Mod+q".action = close-window;
"Mod+f".action = fullscreen-window;
"Mod+t".action = toggle-window-floating;
"Mod+w".action = toggle-column-tabbed-display;
"Mod+1".action = focus-workspace 1;
"Mod+2".action = focus-workspace 2;
"Mod+3".action = focus-workspace 3;
"Mod+4".action = focus-workspace 4;
"Mod+5".action = focus-workspace 5;
"Mod+Ctrl+1".action.move-window-to-workspace = 1;
"Mod+Ctrl+2".action.move-window-to-workspace = 2;
"Mod+Ctrl+3".action.move-window-to-workspace = 3;
"Mod+Ctrl+4".action.move-window-to-workspace = 4;
"Mod+Ctrl+5".action.move-window-to-workspace = 5;
"Mod+WheelScrollDown".cooldown-ms = 150;
"Mod+WheelScrollDown".action = focus-workspace-down;
@ -25,8 +39,8 @@ in {
"Mod+k".action = focus-workspace-down;
"Mod+l".action = focus-column-right;
"Mod+Ctrl+h".action = move-column-left;
"Mod+Ctrl+j".action = move-window-up;
"Mod+Ctrl+k".action = move-window-down;
"Mod+Ctrl+j".action = move-window-up-or-to-workspace-up;
"Mod+Ctrl+k".action = move-window-down-or-to-workspace-down;
"Mod+Ctrl+l".action = move-column-right;
};
};

View file

@ -0,0 +1,18 @@
{
config,
pkgs,
...
}: {
services.mako = {
enable = true;
settings = {
max-visible = 5;
#actions = true;
# icons = true;
# default-timeout = 10000; # in ms
# border-radius = 3;
# markup = true;
};
};
}

View file

@ -2,7 +2,19 @@
config,
pkgs,
...
}: {
}: let
round = tl: tr: bl: br: {
bottom-left = bl;
bottom-right = br;
top-left = tl;
top-right = tr;
};
r = 24.0;
# rounded-corners = round r r r r;
# rounded-corners-l = round r 0.0 0.0 r;
rounded-corners-r = round 0.0 r r 0.0;
in {
programs.niri = {
settings = {
prefer-no-csd = true;
@ -21,12 +33,7 @@
{
opacity = 0.95;
clip-to-geometry = true;
geometry-corner-radius = {
bottom-left = 12.0;
bottom-right = 0.0;
top-left = 0.0;
top-right = 12.0;
};
geometry-corner-radius = rounded-corners-r;
}
{
matches = [{is-focused = true;}];
@ -39,13 +46,17 @@
];
input = {
keyboard.xkb.layout = "en";
# disable-power-key-handling = true;
keyboard.xkb = {
layout = "us";
variant = "intl";
};
};
outputs = {
"DP-3" = {
position.x = 3840;
position.y = -370;
position.y = -430;
transform = {
rotation = 90;
};
@ -58,10 +69,9 @@
};
environment = {
CLUTTER_BACKEND = "wayland";
GDK_BACKEND = "wayland.x11";
# CLUTTER_BACKEND = "wayland";
MOZ_ENABLE_WAYLAND = "1";
QT_QPA_PLATFORM = "wayland";
# QT_QPA_PLATFORM = "wayland";
QT_WAYLAND_DISABLE_WINDOWDECORATION = "1";
ELECTRON_OZONE_PLATFORM_HINT = "auto";
XDG_SESSION_TYPE = "wayland";

View file

@ -0,0 +1,17 @@
{
inputs,
pkgs,
...
}: {
imports = [inputs.ags.homeManagerModules.default];
programs.ags = {
enable = true;
configDir = ./ags;
extraPackages = with pkgs; [
# inputs.astal.packages.${pkgs.system}
fzf
];
};
}

View file

@ -0,0 +1,13 @@
{pkgs, ...}:
pkgs.writeShellApplication {
name = "hg-picker";
text = ''
BASE_URI="https://github.com/hausgold/"
REPO=$(cat "$HOME/.gh/hausgold-repos" | fuzzel -d)
if [[ -n $REPO ]]; then
open-url "$BASE_URI$REPO"
fi
'';
}

View file

@ -8,10 +8,26 @@ lib._elements.writeNushellApplication pkgs {
runtimeInputs = with pkgs; [kdotool];
text = ''
let focused_window = (kdotool getactivewindow)
let compositor = $env.XDG_CURRENT_DESKTOP? | default ""
if (kdotool getwindowclassname $focused_window) == "kitty" {
let kitty_pid = (kdotool getwindowpid $focused_window | into int)
let window_info = if ($compositor | str contains "niri") {
let focused_window = (niri msg --json focused-window | from json | get id?)
if ($focused_window | is-empty) {
{ is_kitty: false, pid: null }
} else {
let info = (niri msg --json windows | from json | where id == $focused_window | first)
{ is_kitty: ($info.app_id? == "kitty"), pid: $info.pid? }
}
} else {
let focused_window = (kdotool getactivewindow)
{
is_kitty: ((kdotool getwindowclassname $focused_window) == "kitty"),
pid: (kdotool getwindowpid $focused_window | into int)
}
}
if $window_info.is_kitty {
let kitty_pid = $window_info.pid
if ($kitty_pid | is-empty) {
kitty
exit 0

View file

@ -1,5 +0,0 @@
{pkgs, ...}:
pkgs.writeShellApplication {
name = "tofi-hg";
text = builtins.readFile ./tofi-hg;
}

View file

@ -1,10 +0,0 @@
#!/usr/bin/env bash
HOME=/home/$(whoami)
BASE_URI="https://github.com/hausgold/"
REPO=$(< "$HOME/.gh/hausgold-repos" tofi)
if [[ -n $REPO ]]; then
open-url "$BASE_URI$REPO"
fi