diff --git a/assets/wallpapers/ascii-nixos.png b/assets/wallpapers/ascii-nixos.png new file mode 100644 index 0000000..2cd684f Binary files /dev/null and b/assets/wallpapers/ascii-nixos.png differ diff --git a/assets/wallpapers/pixel-setup.jpeg b/assets/wallpapers/pixel-setup.jpeg new file mode 100644 index 0000000..3734f93 Binary files /dev/null and b/assets/wallpapers/pixel-setup.jpeg differ diff --git a/assets/wallpapers/ultrawide-nixos-default.png b/assets/wallpapers/ultrawide-nixos-default.png new file mode 100644 index 0000000..289e905 Binary files /dev/null and b/assets/wallpapers/ultrawide-nixos-default.png differ diff --git a/assets/wallpapers/ultrawide-tree-shadow.png b/assets/wallpapers/ultrawide-tree-shadow.png new file mode 100644 index 0000000..5638179 Binary files /dev/null and b/assets/wallpapers/ultrawide-tree-shadow.png differ diff --git a/modules/desktop.nix b/modules/desktop.nix index 18e055d..580e4fc 100644 --- a/modules/desktop.nix +++ b/modules/desktop.nix @@ -12,6 +12,7 @@ ../packages/matugen/default.nix ../packages/swww/default.nix ../packages/quickshell/default.nix + ../packages/ags/default.nix ] ++ lib.optionals (myConfig.linux.gaming == true) [ ../packages/mangohud/default.nix diff --git a/packages/ags/biscuit/.gitignore b/packages/ags/biscuit/.gitignore new file mode 100644 index 0000000..298eb4d --- /dev/null +++ b/packages/ags/biscuit/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +@girs/ diff --git a/packages/ags/biscuit/app.ts b/packages/ags/biscuit/app.ts new file mode 100644 index 0000000..8952ecf --- /dev/null +++ b/packages/ags/biscuit/app.ts @@ -0,0 +1,17 @@ +import { App } from "astal/gtk3" +import style from "./style.scss" +import Bar from "./widget/Bar" + +App.start({ + css: style, + instanceName: "js", + requestHandler(request, res) { + print(request) + res("ok") + }, + main: () => { + const monitors = App.get_monitors() + const primary = monitors.find(m => m.primary) || monitors[0] + return Bar(primary) + } +}) diff --git a/packages/ags/biscuit/colors.scss b/packages/ags/biscuit/colors.scss new file mode 100644 index 0000000..96044bb --- /dev/null +++ b/packages/ags/biscuit/colors.scss @@ -0,0 +1,3 @@ +$background: #131318; +$foreground: #e4e1e9; +$primary: #bec2ff; diff --git a/packages/ags/biscuit/env.d.ts b/packages/ags/biscuit/env.d.ts new file mode 100644 index 0000000..467c0a4 --- /dev/null +++ b/packages/ags/biscuit/env.d.ts @@ -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 +} diff --git a/packages/ags/biscuit/package.json b/packages/ags/biscuit/package.json new file mode 100644 index 0000000..23b6342 --- /dev/null +++ b/packages/ags/biscuit/package.json @@ -0,0 +1,6 @@ +{ + "name": "astal-shell", + "dependencies": { + "astal": "/home/biscuit/.local/share/ags" + } +} diff --git a/packages/ags/biscuit/style.scss b/packages/ags/biscuit/style.scss new file mode 100644 index 0000000..88d42f9 --- /dev/null +++ b/packages/ags/biscuit/style.scss @@ -0,0 +1,143 @@ +@use "sass:color"; +@use "./colors" as *; + +// default +// $bg: #212223; +// $fg: #f1f1f1; +// $accent: #378DF7; +// $radius: 7px; + +// Kanagawa Theme +// $bg: #1F1F28; +// $fg: #DCD7BA; +// $accent: #C0A36E; +// $radius: 7px; + +// mstcl +// $bg: #121212; +// $fg: #f1f1f1; +// $accent: #C0A36E; +// $radius: 7px; + +$bg: $background; +$fg: $foreground; +$accent: $primary; +$radius: 7px; + +window.Bar { + border: none; + box-shadow: none; + background-color: $bg; + color: $fg; + font-size: 1.1em; + font-weight: bold; + font-family: "JetBrainsMono Nerd Font"; + + label { + margin: 0 8px; + } + + .Workspaces { + button { + all: unset; + background-color: transparent; + + &:hover label { + background-color: color.adjust($fg, $alpha: -0.84); + border-color: color.adjust($accent, $alpha: -0.8); + } + + &:active label { + background-color: color.adjust($fg, $alpha: -0.8) + } + } + + label { + transition: 200ms; + padding: 0 8px; + margin: 2px; + border-radius: $radius; + border: 1pt solid transparent; + } + + .focused label { + color: $accent; + border-color: $accent; + } + } + + .SysTray { + margin-right: 8px; + + button { + padding: 0 4px; + } + } + + .Time { + .TimeHM { + font-weight: bold; + color: $accent; + } + + .TimeDate { + // color: color.adjust($fg, $lightness: -10%); + color: $fg; + opacity: 0.85; + font-weight: normal; + } + } + + + .FocusedClient { + color: color.adjust($fg, $lightness: -30%); + opacity: 0.7; + } + + .Media .Cover { + min-height: 1.2em; + min-width: 1.2em; + border-radius: $radius; + background-position: center; + background-size: contain; + } + + .Battery label { + padding-left: 0; + margin-left: 0; + } + + .AudioSlider { + * { + all: unset; + } + + icon { + margin-right: .6em; + } + + & { + margin: 0 1em; + } + + trough { + background-color: color.adjust($fg, $alpha: -0.8); + border-radius: $radius; + } + + highlight { + background-color: $accent; + min-height: .8em; + border-radius: $radius; + } + + slider { + background-color: $fg; + border-radius: $radius; + min-height: 1em; + min-width: 1em; + margin: -.2em; + } + } +} + diff --git a/packages/ags/biscuit/tsconfig.json b/packages/ags/biscuit/tsconfig.json new file mode 100644 index 0000000..9471e35 --- /dev/null +++ b/packages/ags/biscuit/tsconfig.json @@ -0,0 +1,14 @@ +{ + "$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/gtk3", + } +} diff --git a/packages/ags/biscuit/widget/Bar.tsx b/packages/ags/biscuit/widget/Bar.tsx new file mode 100644 index 0000000..9941dc4 --- /dev/null +++ b/packages/ags/biscuit/widget/Bar.tsx @@ -0,0 +1,189 @@ +import { App } from "astal/gtk3" +import { Variable, GLib, bind } from "astal" +import { Astal, Gtk, Gdk } from "astal/gtk3" +import Hyprland from "gi://AstalHyprland" +import Mpris from "gi://AstalMpris" +import Battery from "gi://AstalBattery" +import Wp from "gi://AstalWp" +import Network from "gi://AstalNetwork" +import Tray from "gi://AstalTray" + +function SysTray() { + const tray = Tray.get_default() + + return + {bind(tray, "items").as(items => items.map(item => ( + ["dbusmenu", ag])} + menuModel={bind(item, "menuModel")}> + + + )))} + +} + +function Wifi() { + const network = Network.get_default() + const wifi = bind(network, "wifi") + + return + {wifi.as(wifi => wifi && ( + + ))} + + +} + +function AudioSlider() { + const speaker = Wp.get_default()?.audio.defaultSpeaker! + + return + + speaker.volume = value} + value={bind(speaker, "volume")} + /> + +} + +function BatteryLevel() { + const bat = Battery.get_default() + + return + + +} + +function Media() { + const mpris = Mpris.get_default() + + return + {bind(mpris, "players").as(ps => ps[0] ? ( + + + `background-image: url('${cover}');` + )} + /> + + ) : ( + +} + + +function Workspaces() { + const hypr = Hyprland.get_default(); + + return ( + + {bind(hypr, "focusedWorkspace").as((fw) => { + if (!fw) return null; + + // Determine the current chunk of 5 visible workspace buttons + const currentChunkStart = Math.floor((fw.id - 1) / 5) * 5 + 1; + const visibleIds = Array.from({ length: 5 }, (_, i) => currentChunkStart + i); + + return visibleIds.map((id) => { + // Try to get the real workspace, fall back to a dummy one if it doesn't exist + const ws = + hypr.workspaces.find((w) => w.id === id) ?? + Hyprland.Workspace.dummy(id, null); + + return ( + + ); + }); + })} + + ); +} + +function FocusedClient() { + const hypr = Hyprland.get_default(); + const focused = bind(hypr, "focusedClient"); + + return ( + + {focused.as(client => { + if (!client) return null; + + return ( + + ); +} +function Time({ format = "%H:%M|%a %b %d" }) { + const time = Variable("").poll(1000, () => + GLib.DateTime.new_now_local().format(format)! + ); + + return bind(time).as(str => { + const [hm, date] = str.split("|"); + + return ( + + + ); + }); +} + +export default function Bar(monitor: Gdk.Monitor) { + const { TOP, LEFT, RIGHT } = Astal.WindowAnchor + + return + + + + + + + + + + + + + + + +} diff --git a/packages/ags/default.nix b/packages/ags/default.nix new file mode 100644 index 0000000..60f4e69 --- /dev/null +++ b/packages/ags/default.nix @@ -0,0 +1,28 @@ +{ + inputs, + pkgs, + system, + ... +}: { + imports = [inputs.ags.homeManagerModules.default]; + + programs.ags = { + enable = true; + configDir = ./biscuit; + + extraPackages = let + agsPkgs = inputs.ags.packages.${system}; + in + with pkgs; [ + agsPkgs.battery + agsPkgs.hyprland + agsPkgs.mpris + agsPkgs.wireplumber + agsPkgs.notifd + agsPkgs.apps + agsPkgs.network + agsPkgs.tray + fzf + ]; + }; +}