From 782d2dacac3957ba32795428a145d72199c32974 Mon Sep 17 00:00:00 2001 From: Christoph Urlacher Date: Sun, 13 Oct 2024 19:29:28 +0200 Subject: [PATCH] Ags: Add starter config --- .gitignore | 2 + home/christoph/default.nix | 7 +- home/christoph/nixinator/default.nix | 1 - home/modules/ags/config/config.js | 202 +++++++++++++++++++++++++++ home/modules/ags/config/style.css | 40 ++++++ home/modules/ags/default.nix | 18 ++- home/modules/default.nix | 1 + home/modules/hyprland/default.nix | 1 + 8 files changed, 265 insertions(+), 7 deletions(-) create mode 100644 home/modules/ags/config/config.js create mode 100644 home/modules/ags/config/style.css diff --git a/.gitignore b/.gitignore index bb12dc06..0efb26f8 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ result config/neovim/store +home/modules/ags/config/types +home/modules/ags/config/tsconfig.json diff --git a/home/christoph/default.nix b/home/christoph/default.nix index d758e6f6..30711f2a 100644 --- a/home/christoph/default.nix +++ b/home/christoph/default.nix @@ -33,6 +33,8 @@ rec { # Enable and configure my custom HM modules. modules = { + ags.enable = true; + chromium = { enable = true; google = false; @@ -170,10 +172,7 @@ rec { theme = "Foggy-Lake"; }; - waybar = { - enable = true; - }; - + waybar.enable = false; zathura.enable = true; }; diff --git a/home/christoph/nixinator/default.nix b/home/christoph/nixinator/default.nix index 719d3d71..ad0d8aca 100644 --- a/home/christoph/nixinator/default.nix +++ b/home/christoph/nixinator/default.nix @@ -48,7 +48,6 @@ ]; }; - # TODO: Also set the dunst monitor waybar.monitor = "HDMI-A-1"; }; diff --git a/home/modules/ags/config/config.js b/home/modules/ags/config/config.js new file mode 100644 index 00000000..9713263a --- /dev/null +++ b/home/modules/ags/config/config.js @@ -0,0 +1,202 @@ +const hyprland = await Service.import("hyprland"); +const notifications = await Service.import("notifications"); +const mpris = await Service.import("mpris"); +const audio = await Service.import("audio"); +const battery = await Service.import("battery"); +const systemtray = await Service.import("systemtray"); + +const date = Variable("", { + poll: [1000, 'date "+%H:%M:%S %b %e."'], +}); + +// widgets can be only assigned as a child in one container +// so to make a reuseable widget, make it a function +// then you can simply instantiate one by calling it + +function Workspaces() { + const activeId = hyprland.active.workspace.bind("id"); + const workspaces = hyprland.bind("workspaces").as((ws) => + ws.map(({ id }) => + Widget.Button({ + on_clicked: () => hyprland.messageAsync(`dispatch workspace ${id}`), + child: Widget.Label(`${id}`), + class_name: activeId.as((i) => `${i === id ? "focused" : ""}`), + }), + ), + ); + + return Widget.Box({ + class_name: "workspaces", + children: workspaces, + }); +} + +function ClientTitle() { + return Widget.Label({ + class_name: "client-title", + label: hyprland.active.client.bind("title"), + }); +} + +function Clock() { + return Widget.Label({ + class_name: "clock", + label: date.bind(), + }); +} + +// we don't need dunst or any other notification daemon +// because the Notifications module is a notification daemon itself +function Notification() { + const popups = notifications.bind("popups"); + return Widget.Box({ + class_name: "notification", + visible: popups.as((p) => p.length > 0), + children: [ + Widget.Icon({ + icon: "preferences-system-notifications-symbolic", + }), + Widget.Label({ + label: popups.as((p) => p[0]?.summary || ""), + }), + ], + }); +} + +function Media() { + const label = Utils.watch("", mpris, "player-changed", () => { + if (mpris.players[0]) { + const { track_artists, track_title } = mpris.players[0]; + return `${track_artists.join(", ")} - ${track_title}`; + } else { + return "Nothing is playing"; + } + }); + + return Widget.Button({ + class_name: "media", + on_primary_click: () => mpris.getPlayer("")?.playPause(), + on_scroll_up: () => mpris.getPlayer("")?.next(), + on_scroll_down: () => mpris.getPlayer("")?.previous(), + child: Widget.Label({ label }), + }); +} + +function Volume() { + const icons = { + 101: "overamplified", + 67: "high", + 34: "medium", + 1: "low", + 0: "muted", + }; + + function getIcon() { + const icon = audio.speaker.is_muted + ? 0 + : [101, 67, 34, 1, 0].find( + (threshold) => threshold <= audio.speaker.volume * 100, + ); + + return `audio-volume-${icons[icon]}-symbolic`; + } + + const icon = Widget.Icon({ + icon: Utils.watch(getIcon(), audio.speaker, getIcon), + }); + + const slider = Widget.Slider({ + hexpand: true, + draw_value: false, + on_change: ({ value }) => (audio.speaker.volume = value), + setup: (self) => + self.hook(audio.speaker, () => { + self.value = audio.speaker.volume || 0; + }), + }); + + return Widget.Box({ + class_name: "volume", + css: "min-width: 180px", + children: [icon, slider], + }); +} + +function BatteryLabel() { + const value = battery.bind("percent").as((p) => (p > 0 ? p / 100 : 0)); + const icon = battery + .bind("percent") + .as((p) => `battery-level-${Math.floor(p / 10) * 10}-symbolic`); + + return Widget.Box({ + class_name: "battery", + visible: battery.bind("available"), + children: [ + Widget.Icon({ icon }), + Widget.LevelBar({ + widthRequest: 140, + vpack: "center", + value, + }), + ], + }); +} + +function SysTray() { + const items = systemtray.bind("items").as((items) => + items.map((item) => + Widget.Button({ + child: Widget.Icon({ icon: item.bind("icon") }), + on_primary_click: (_, event) => item.activate(event), + on_secondary_click: (_, event) => item.openMenu(event), + tooltip_markup: item.bind("tooltip_markup"), + }), + ), + ); + + return Widget.Box({ + children: items, + }); +} + +function Left() { + return Widget.Box({ + spacing: 8, + children: [Workspaces(), ClientTitle()], + }); +} + +function Center() { + return Widget.Box({ + spacing: 8, + children: [Media(), Notification()], + }); +} + +function Right() { + return Widget.Box({ + hpack: "end", + spacing: 8, + children: [Volume(), Clock(), SysTray()], + }); +} + +function Bar(monitor = 0) { + return Widget.Window({ + name: `bar-${monitor}`, + class_name: "ags_bar", + monitor, + anchor: ["top", "left", "right"], + exclusivity: "exclusive", + child: Widget.CenterBox({ + start_widget: Left(), + center_widget: Center(), + end_widget: Right(), + }), + }); +} + +App.config({ + style: "./style.css", + windows: [Bar(0)], +}); diff --git a/home/modules/ags/config/style.css b/home/modules/ags/config/style.css new file mode 100644 index 00000000..29f8fdd4 --- /dev/null +++ b/home/modules/ags/config/style.css @@ -0,0 +1,40 @@ +window.bar { + background-color: @theme_bg_color; + color: @theme_fg_color; +} + +button { + min-width: 0; + padding-top: 0; + padding-bottom: 0; + background-color: transparent; +} + +button:active { + background-color: @theme_selected_bg_color; +} + +button:hover { + border-bottom: 3px solid @theme_fg_color; +} + +label { + font-weight: bold; +} + +.workspaces button.focused { + border-bottom: 3px solid @theme_selected_bg_color; +} + +.client-title { + color: @theme_selected_bg_color; +} + +.notification { + color: yellow; +} + +levelbar block, +highlight { + min-height: 10px; +} diff --git a/home/modules/ags/default.nix b/home/modules/ags/default.nix index 5506974d..b2153aa5 100644 --- a/home/modules/ags/default.nix +++ b/home/modules/ags/default.nix @@ -2,6 +2,7 @@ config, lib, mylib, + pkgs, ... }: with lib; @@ -10,7 +11,20 @@ with mylib.modules; let in { options.modules.ags = import ./options.nix {inherit lib mylib;}; - config = - mkIf cfg.enable { + config = mkIf cfg.enable { + programs.ags = { + enable = true; + systemd.enable = true; + + # configDir = ./config; }; + + home.file = { + # NOTE: Keep this symlinked as long as I'm configuring + ".config/ags".source = config.lib.file.mkOutOfStoreSymlink "/home/christoph/NixFlake/home/modules/ags/config"; + + # LSP typechecking support + # ".config/ags/types".source = config.lib.file.mkOutOfStoreSymlink "${pkgs.ags}/share/com.github.Aylur.ags/types"; + }; + }; } diff --git a/home/modules/default.nix b/home/modules/default.nix index 416478af..57de4295 100644 --- a/home/modules/default.nix +++ b/home/modules/default.nix @@ -3,6 +3,7 @@ # Obsolete modules are kept in "1_deprecated" for reference. # My own HM modules + ./ags ./chromium ./color ./firefox diff --git a/home/modules/hyprland/default.nix b/home/modules/hyprland/default.nix index 8f77587c..1906e970 100644 --- a/home/modules/hyprland/default.nix +++ b/home/modules/hyprland/default.nix @@ -318,6 +318,7 @@ in { }; # Notification service + # TODO: Allow setting the dunst monitor dunst = { enable = true;