mirror of
https://github.com/zephrynis/nix-flake.git
synced 2026-02-18 20:21:53 +00:00
Fix: add AGS configuration and replace Waybar with AGS for enhanced desktop widget management
This commit is contained in:
@@ -16,11 +16,14 @@
|
|||||||
# Vicinae - Application launcher
|
# Vicinae - Application launcher
|
||||||
vicinae.url = "github:vicinaehq/vicinae";
|
vicinae.url = "github:vicinaehq/vicinae";
|
||||||
|
|
||||||
|
# AGS - Aylur's GTK Shell for custom widgets/bar
|
||||||
|
ags.url = "github:Aylur/ags";
|
||||||
|
|
||||||
# Optional: Other useful inputs
|
# Optional: Other useful inputs
|
||||||
# nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
|
# nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, home-manager, hyprland, vicinae, ... }@inputs: {
|
outputs = { self, nixpkgs, home-manager, hyprland, vicinae, ags, ... }@inputs: {
|
||||||
# NixOS configuration for your hostname(s)
|
# NixOS configuration for your hostname(s)
|
||||||
nixosConfigurations = {
|
nixosConfigurations = {
|
||||||
# Desktop PC configuration
|
# Desktop PC configuration
|
||||||
|
|||||||
252
home/ags.nix
Normal file
252
home/ags.nix
Normal file
@@ -0,0 +1,252 @@
|
|||||||
|
{ config, pkgs, inputs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# AGS - Aylur's GTK Shell configuration
|
||||||
|
imports = [ inputs.ags.homeManagerModules.default ];
|
||||||
|
|
||||||
|
programs.ags = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
# Add additional packages needed for AGS
|
||||||
|
extraPackages = with pkgs; [
|
||||||
|
gtksourceview
|
||||||
|
webkitgtk
|
||||||
|
accountsservice
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# AGS configuration files will go in ~/.config/ags/
|
||||||
|
home.file.".config/ags/config.js".text = ''
|
||||||
|
// AGS Configuration
|
||||||
|
import { Bar } from "./bar.js"
|
||||||
|
|
||||||
|
App.config({
|
||||||
|
windows: [
|
||||||
|
Bar(0), // Monitor 0 (DP-2)
|
||||||
|
Bar(1), // Monitor 1 (DP-1)
|
||||||
|
],
|
||||||
|
style: "./style.css",
|
||||||
|
})
|
||||||
|
'';
|
||||||
|
|
||||||
|
home.file.".config/ags/bar.js".text = ''
|
||||||
|
const hyprland = await Service.import("hyprland")
|
||||||
|
const battery = await Service.import("battery")
|
||||||
|
const audio = await Service.import("audio")
|
||||||
|
const bluetooth = await Service.import("bluetooth")
|
||||||
|
const network = await Service.import("network")
|
||||||
|
const systemtray = await Service.import("systemtray")
|
||||||
|
|
||||||
|
// Workspaces widget
|
||||||
|
const Workspaces = (monitor) => Widget.Box({
|
||||||
|
class_name: "workspaces",
|
||||||
|
children: Array.from({ length: 10 }, (_, i) => i + 1).map(i => Widget.Button({
|
||||||
|
attribute: i,
|
||||||
|
label: `''${i}`,
|
||||||
|
on_clicked: () => hyprland.messageAsync(`dispatch workspace ''${i}`),
|
||||||
|
setup: self => self.hook(hyprland, () => {
|
||||||
|
self.toggleClassName("active", hyprland.active.workspace.id === i)
|
||||||
|
// Show only relevant workspaces per monitor
|
||||||
|
if (monitor === 0) {
|
||||||
|
self.visible = [1, 3, 5, 7, 9].includes(i)
|
||||||
|
} else {
|
||||||
|
self.visible = [2, 4, 6, 8, 10].includes(i)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
})),
|
||||||
|
})
|
||||||
|
|
||||||
|
// Window title
|
||||||
|
const ClientTitle = () => Widget.Label({
|
||||||
|
class_name: "client-title",
|
||||||
|
label: hyprland.active.client.bind("title"),
|
||||||
|
max_width_chars: 50,
|
||||||
|
truncate: "end",
|
||||||
|
})
|
||||||
|
|
||||||
|
// Clock
|
||||||
|
const Clock = () => Widget.Label({
|
||||||
|
class_name: "clock",
|
||||||
|
setup: self => self.poll(1000, self => {
|
||||||
|
const date = new Date()
|
||||||
|
self.label = date.toLocaleTimeString("en-US", {
|
||||||
|
hour: "2-digit",
|
||||||
|
minute: "2-digit",
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|
||||||
|
// Volume
|
||||||
|
const Volume = () => Widget.Button({
|
||||||
|
class_name: "volume",
|
||||||
|
on_clicked: () => audio.speaker.is_muted = !audio.speaker.is_muted,
|
||||||
|
child: Widget.Icon().hook(audio.speaker, self => {
|
||||||
|
const vol = audio.speaker.volume * 100
|
||||||
|
const icon = [
|
||||||
|
[101, "overamplified"],
|
||||||
|
[67, "high"],
|
||||||
|
[34, "medium"],
|
||||||
|
[1, "low"],
|
||||||
|
[0, "muted"],
|
||||||
|
].find(([threshold]) => threshold <= vol)?.[1]
|
||||||
|
|
||||||
|
self.icon = `audio-volume-''${audio.speaker.is_muted ? "muted" : icon}-symbolic`
|
||||||
|
self.tooltip_text = `Volume ''${Math.floor(vol)}%`
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|
||||||
|
// Bluetooth
|
||||||
|
const Bluetooth = () => Widget.Button({
|
||||||
|
class_name: "bluetooth",
|
||||||
|
on_clicked: () => Utils.execAsync("blueman-manager"),
|
||||||
|
child: Widget.Icon({
|
||||||
|
icon: bluetooth.bind("enabled").as(on =>
|
||||||
|
`bluetooth-''${on ? "active" : "disabled"}-symbolic`
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
setup: self => self.hook(bluetooth, self => {
|
||||||
|
const connected = bluetooth.connected_devices.length
|
||||||
|
self.tooltip_text = bluetooth.enabled
|
||||||
|
? `Bluetooth: ''${connected} connected`
|
||||||
|
: "Bluetooth: Off"
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|
||||||
|
// Network
|
||||||
|
const Network = () => Widget.Icon().hook(network, self => {
|
||||||
|
const icon = network[network.primary || "wired"]?.icon_name
|
||||||
|
self.icon = icon || ""
|
||||||
|
self.visible = !!icon
|
||||||
|
})
|
||||||
|
|
||||||
|
// Battery
|
||||||
|
const Battery = () => Widget.Box({
|
||||||
|
class_name: "battery",
|
||||||
|
visible: battery.bind("available"),
|
||||||
|
children: [
|
||||||
|
Widget.Icon({ icon: battery.bind("icon_name") }),
|
||||||
|
Widget.Label({
|
||||||
|
label: battery.bind("percent").as(p => `''${p}%`),
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
|
||||||
|
// System tray
|
||||||
|
const SysTray = () => Widget.Box({
|
||||||
|
class_name: "systray",
|
||||||
|
children: 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"),
|
||||||
|
}))),
|
||||||
|
})
|
||||||
|
|
||||||
|
// Main bar
|
||||||
|
export const Bar = (monitor = 0) => Widget.Window({
|
||||||
|
name: `bar-''${monitor}`,
|
||||||
|
class_name: "bar",
|
||||||
|
monitor,
|
||||||
|
anchor: ["top", "left", "right"],
|
||||||
|
exclusivity: "exclusive",
|
||||||
|
child: Widget.CenterBox({
|
||||||
|
start_widget: Widget.Box({
|
||||||
|
spacing: 8,
|
||||||
|
children: [
|
||||||
|
Workspaces(monitor),
|
||||||
|
ClientTitle(),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
center_widget: Clock(),
|
||||||
|
end_widget: Widget.Box({
|
||||||
|
hpack: "end",
|
||||||
|
spacing: 8,
|
||||||
|
children: [
|
||||||
|
Volume(),
|
||||||
|
Bluetooth(),
|
||||||
|
Network(),
|
||||||
|
Battery(),
|
||||||
|
SysTray(),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
'';
|
||||||
|
|
||||||
|
home.file.".config/ags/style.css".text = ''
|
||||||
|
* {
|
||||||
|
all: unset;
|
||||||
|
font-family: "JetBrainsMono Nerd Font", "FiraCode Nerd Font";
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar {
|
||||||
|
background-color: rgba(30, 30, 46, 0.8);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
color: #cdd6f4;
|
||||||
|
padding: 4px 10px;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.workspaces button {
|
||||||
|
padding: 4px 10px;
|
||||||
|
margin: 0 2px;
|
||||||
|
border-radius: 6px;
|
||||||
|
background-color: transparent;
|
||||||
|
color: #585b70;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.workspaces button.active {
|
||||||
|
background: linear-gradient(45deg, rgba(51, 204, 255, 0.8), rgba(0, 255, 153, 0.8));
|
||||||
|
color: #1e1e2e;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.workspaces button:hover {
|
||||||
|
background-color: rgba(88, 91, 112, 0.4);
|
||||||
|
color: #cdd6f4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.client-title {
|
||||||
|
margin-left: 10px;
|
||||||
|
color: #cdd6f4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clock {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #89dceb;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.volume, .bluetooth {
|
||||||
|
padding: 4px 8px;
|
||||||
|
margin: 0 2px;
|
||||||
|
border-radius: 6px;
|
||||||
|
background-color: transparent;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.volume:hover, .bluetooth:hover {
|
||||||
|
background-color: rgba(88, 91, 112, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.battery {
|
||||||
|
padding: 4px 8px;
|
||||||
|
margin: 0 2px;
|
||||||
|
border-radius: 6px;
|
||||||
|
color: #a6e3a1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.systray button {
|
||||||
|
padding: 4px 8px;
|
||||||
|
margin: 0 2px;
|
||||||
|
border-radius: 6px;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.systray button:hover {
|
||||||
|
background-color: rgba(88, 91, 112, 0.4);
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./hyprland.nix
|
./hyprland.nix
|
||||||
|
./ags.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
# Home Manager configuration for user-level dotfiles and applications
|
# Home Manager configuration for user-level dotfiles and applications
|
||||||
@@ -57,9 +58,10 @@
|
|||||||
# obs-studio
|
# obs-studio
|
||||||
|
|
||||||
# Hyprland essentials
|
# Hyprland essentials
|
||||||
waybar # Status bar
|
# waybar # Status bar - replaced by AGS
|
||||||
dunst # Notifications
|
dunst # Notifications
|
||||||
wofi # App launcher
|
wofi # App launcher
|
||||||
|
rofi-bluetooth # Bluetooth menu for Waybar
|
||||||
networkmanagerapplet # WiFi manager applet for system tray
|
networkmanagerapplet # WiFi manager applet for system tray
|
||||||
# rofi-wayland # Alternative launcher
|
# rofi-wayland # Alternative launcher
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
"mpvpaper -o 'no-audio loop' DP-2 ~/nix-flake/assets/wallpaper.mp4"
|
"mpvpaper -o 'no-audio loop' DP-2 ~/nix-flake/assets/wallpaper.mp4"
|
||||||
"mpvpaper -o 'no-audio loop' DP-1 ~/nix-flake/assets/wallpaper.mp4"
|
"mpvpaper -o 'no-audio loop' DP-1 ~/nix-flake/assets/wallpaper.mp4"
|
||||||
|
|
||||||
"waybar"
|
"ags" # Start AGS (bar and widgets)
|
||||||
"dunst"
|
"dunst"
|
||||||
"nm-applet --indicator" # WiFi manager in system tray
|
"nm-applet --indicator" # WiFi manager in system tray
|
||||||
"vicinae server" # Start Vicinae server
|
"vicinae server" # Start Vicinae server
|
||||||
@@ -118,6 +118,8 @@
|
|||||||
windowrulev2 = [
|
windowrulev2 = [
|
||||||
"float,class:^(pavucontrol)$"
|
"float,class:^(pavucontrol)$"
|
||||||
"float,class:^(blueman-manager)$"
|
"float,class:^(blueman-manager)$"
|
||||||
|
"size 600 400,class:^(blueman-manager)$"
|
||||||
|
"center,class:^(blueman-manager)$"
|
||||||
];
|
];
|
||||||
|
|
||||||
# Keybindings
|
# Keybindings
|
||||||
|
|||||||
@@ -98,7 +98,7 @@
|
|||||||
"tooltip-format-connected": "{controller_alias}\t{controller_address}\n\n{num_connections} connected\n\n{device_enumerate}",
|
"tooltip-format-connected": "{controller_alias}\t{controller_address}\n\n{num_connections} connected\n\n{device_enumerate}",
|
||||||
"tooltip-format-enumerate-connected": "{device_alias}\t{device_address}",
|
"tooltip-format-enumerate-connected": "{device_alias}\t{device_address}",
|
||||||
"tooltip-format-enumerate-connected-battery": "{device_alias}\t{device_address}\t{device_battery_percentage}%",
|
"tooltip-format-enumerate-connected-battery": "{device_alias}\t{device_address}\t{device_battery_percentage}%",
|
||||||
"on-click": "blueman-manager"
|
"on-click": "rofi-bluetooth"
|
||||||
},
|
},
|
||||||
|
|
||||||
"tray": {
|
"tray": {
|
||||||
|
|||||||
Reference in New Issue
Block a user