AGS Bar¶
Índice¶
- Resumen
- Archivos
- Constantes y variables globales
- app.ts — Punto de entrada
- style.scss — Estilos
- Bar.tsx — Barra principal
- MusicBar.tsx — Barra de música
- CommandCenter.tsx
- Keybinds.tsx
- PowerMenu.tsx
- NotificationCenter.tsx
- NotificationPopup.tsx
- OSD.tsx
- cava.ts — Visualizador de audio
- Notas y recursos
Resumen¶
El directorio ~/.config/ags/ contiene la barra de escritorio construida con AGS v3 (Aylurs-GTK-Shell) y el framework Astal. Está escrita en TypeScript con sintaxis JSX similar a SolidJS y se compila/ejecuta en tiempo real via el runtime GJS (GNOME JavaScript).
La barra se divide en dos capas visibles:
- Barra inferior (
Bar.tsx): anclada al fondo de la pantalla, siempre visible. Contiene el lanzador de apps, reloj, calendario, taskbar, bandeja del sistema y controles de audio/red/bluetooth. - Barra superior de música (
MusicBar.tsx): tres píldoras flotantes en la parte superior que muestran info del reproductor actual, el visualizador CAVA y las letras sincronizadas.
Archivos¶
| Archivo | Propósito |
|---|---|
app.ts |
Punto de entrada, monta todas las ventanas |
style.scss |
Estilos globales (compilado a CSS por sassc) |
widget/Bar.tsx |
Barra inferior principal |
widget/MusicBar.tsx |
Barra de música flotante + flyout now-playing |
widget/WifiMenu.tsx |
Popup de gestión WiFi (reemplaza nm-connection-editor) |
widget/SettingsPanel.tsx |
Panel de configuración del usuario (SUPER+C → Settings) |
widget/CommandCenter.tsx |
Centro de comandos (SUPER+C) |
widget/Keybinds.tsx |
Visor de keybinds (SUPER+') |
widget/PowerMenu.tsx |
Menú de sesión (CTRL+ALT+DEL) |
widget/NotificationCenter.tsx |
Centro de notificaciones (panel lateral, historial) |
widget/NotificationPopup.tsx |
Toasts de notificación (popup transitorio, auto-dismiss) |
widget/OSD.tsx |
Indicador on-screen (volumen, brillo) |
widget/cava.ts |
Clase del visualizador de audio CAVA |
package.json |
Dependencias npm (solo ags: "*") |
tsconfig.json |
Configuración de TypeScript |
Constantes y variables globales¶
MusicBar.tsx¶
| Nombre | Valor | Descripción |
|---|---|---|
NO_TRACK |
'/org/mpris/MediaPlayer2/TrackList/NoTrack' |
ID especial de MPRIS que indica "sin pista" |
DECAY_λ |
0.001 |
Factor de decaimiento exponencial para la caché de letras |
LYRICS_DIR |
~/lyrics |
Directorio donde se buscan los archivos .lyr |
MAX_CACHE |
200 |
Máximo de entradas en la caché de letras en memoria |
NUM_BARS |
(definido en cava.ts) | Número de barras del visualizador |
lyricsIndex |
Map<string, LyricFile[]> |
Índice en memoria de todos los .lyr encontrados |
app.ts — Punto de entrada¶
Inicializa la aplicación AGS y monta todos los widgets en cada monitor detectado.
Función main()¶
Se ejecuta al lanzar ags run ~/.config/ags/app.ts -i ags-bar.
- Itera sobre los monitores con
app.get_monitors(). - Por cada monitor crea instancias de:
Bar,MusicBar,NotificationCenter,NotificationPopup. - Una sola vez (no por monitor):
OSD(monitors[0]),PowerMenu(),CommandCenter(),Keybinds(),SettingsPanel(). - Registra la app con el identificador
ags-barpara queags toggle -i ags-bar <nombre>funcione.
Daemon de notificaciones
AGS reclama el nombre D-Bus org.freedesktop.Notifications vía AstalNotifd apenas arranca. Para que esto funcione, dunst.service debe estar enmascarado (systemctl --user mask dunst.service) — si no, dunst lo reclama primero y AGS nunca recibe notificaciones. install.sh enmascara dunst automáticamente; ver Obsoleto.
style.scss — Estilos¶
Hoja de estilos SCSS compilada por dart-sass (binario sass). Define variables de color del sistema y los estilos de todos los widgets.
Variables de color principales¶
$bg-deep: #050505; /* Fondo más oscuro */
$bg-glass: #121212; /* Fondo de píldoras */
$accent: #89B19E; /* Verde claro — color principal */
$primary: #33473D; /* Verde oscuro */
$secondary: #4D6B5C; /* Verde medio */
$text-primary: #E8E8E8;
$text-dim: #7A7A7A;
$border: #2A2A2A;
$border-bright: #4D6B5C;
Los alias
$purple-light,$purple-midy$cyan-accentapuntan a$accent,$secondaryy$accentrespectivamente, para mantener compatibilidad con nombres heredados.
Bar.tsx — Barra principal¶
Ventana GTK anclada a BOTTOM | LEFT | RIGHT con exclusividad de espacio (EXCLUSIVE), es decir, las ventanas de aplicaciones no se superponen a ella.
Componentes¶
Launcher¶
Botón con el ícono de Arch Linux. Al hacer clic lanza rofi -show drun -show-icons.
ColorPicker¶
Botón con ícono de cuentagotas. Ejecuta hyprpicker -a (selecciona un color de pantalla y lo copia al portapapeles automáticamente).
Clock¶
Muestra la hora actual en formato HH:MM. Se actualiza cada segundo. Usa la zona horaria America/Santiago.
CalendarWidget¶
Muestra la fecha corta (lun 10 jun). Al hacer clic abre un popover con un Gtk.Calendar. Clic derecho abre calcure en una terminal.
VolumeWidget¶
Muestra el ícono y porcentaje del volumen del altavoz predeterminado (via WirePlumber/AstalWp). Funciones:
- Clic izquierdo: abre pavucontrol.
- Clic derecho: silencia/desilencia.
- Scroll: sube/baja volumen en 5%.
MicWidget¶
Igual que VolumeWidget pero para el micrófono predeterminado.
NetworkWidget¶
Muestra el estado de red (WiFi con intensidad de señal, o Ethernet). Lee /proc/net/route para detectar la interfaz activa y /proc/net/dev para calcular velocidades de descarga/subida en tiempo real (actualización cada 1.5 s). Las velocidades de red solo se muestran cuando hay conexión activa; se ocultan automáticamente si no hay interfaz online.
- Clic izquierdo: abre
WifiMenu— popup integrado de gestión WiFi (ver WifiMenu.tsx). - Requiere
gdkmonitorcomo prop para posicionar el popup en la pantalla correcta.
BluetoothWidget¶
Muestra el estado Bluetooth. Visible solo si hay adaptador disponible. Clic abre blueman-manager.
VpnWidget¶
Se hace visible automáticamente cuando detecta alguna interfaz VPN activa (tun0, wg0, ppp0, etc.) leyendo /proc/net/dev. Se comprueba cada 4 segundos.
NotifBell¶
Campana que abre/cierra el NotificationCenter.
WorkspacesWidget¶
Indicador de workspaces de Hyprland.
- Workspaces 1–5: punto fijo (
•), siempre visibles, clase.ws-dot. El activo se resalta con$accentvia la clase.active. - Workspaces 6+: solo se muestran si están enfocados o tienen ventanas (
extraIds), usando glifos Unicode de dígito circulado (①②③… víaCIRCLED_DIGIT_DIGITS/circledNum()) en vez de números planos, para mantener la estética de "punto" sin perder la identificación del número. - El clic despacha el cambio de workspace con
hyprctl dispatch 'hl.dsp.focus({workspace="N"})'(víaexecAsync), no con el método nativoAstalHyprland.dispatch()— este fork de Hyprland usa un wrapper Lua que espera sintaxis de llamada a función, no eldispatch workspace Nclásico. Ver Hyprland → hyprland.lua.
Taskbar¶
Lista de ventanas abiertas en Hyprland (vía AstalHyprland). Al hacer clic en una ventana, enfoca su workspace y luego la ventana.
Tray¶
Bandeja del sistema con los ítems de AstalTray. Filtra automáticamente nm-applet y blueman-applet (ya representados por NetworkWidget y BluetoothWidget).
MusicBar.tsx — Barra de música¶
Tres ventanas GTK flotantes ancladas a TOP. Siempre visibles con altura fija, independientemente de si hay un reproductor MPRIS activo. Cuando no hay reproductor, las píldoras permanecen en pantalla pero vacías.
Píldoras¶
| Píldora | Clase CSS | Contenido |
|---|---|---|
| Izquierda | .m-left-pill |
Carátula + título/artista + controles + barra de progreso |
| Centro | .m-center-pill |
Visualizador de barras CAVA |
| Derecha | .m-right-pill |
Letras sincronizadas |
Componentes internos¶
AlbumArt¶
Muestra la carátula del track actual. Usa GdkPixbuf.Pixbuf.new_from_file_at_scale para escalar la imagen a 36×36 (en la píldora) ó 128×128 (en el flyout). Se actualiza reactivamente cuando coverArt o artUrl cambian.
MediaInfo¶
Muestra el título y artista del track con texto truncado (ellipsize).
MediaControls¶
Botones de anterior, play/pause y siguiente. Usan la API de AstalMpris.
ProgressBar¶
Barra de progreso interactiva (Gtk.Scale) con clase song-seek-scale. Permite arrastrar para cambiar la posición de la canción. Se actualiza cada 250 ms. Al soltar ejecuta playerctl position <segundos>.
LyricsViewer¶
Muestra las letras sincronizadas en la píldora derecha. Ver Letras (.lyr) para la documentación del sistema de letras.
buildNowPlayingContent(player)¶
Construye el flyout "now-playing" completo (carátula grande, título, artista, barra de progreso arrastrable, visualizador CAVA). Se invoca al hacer clic en la píldora izquierda.
- La carátula en el flyout es de 128×128 px.
- La imagen se actualiza cuando cambia la canción, comparando el path del cover anterior con el nuevo.
- El visualizador en el flyout usa
Gtk.DrawingAreacon Cairo para renderizar las barras. - El flyout tiene 83 px de margen a cada lado.
openFlyoutWin(gdkmonitor, content)¶
Crea la ventana overlay del flyout:
- Capa OVERLAY, anclada a TOP, sin modo de teclado.
- Después de show_all(), usa GLib.idle_add para medir el ancho natural del contenido y asignarlo explícitamente con set_size_request() (necesario para que Wayland layer-shell respete los márgenes).
ProgressBar en flyout (progScale)¶
Gtk.Scale con clase npp-scale. Igual al de la píldora pero con detección de button-press-event / button-release-event para seeking preciso.
CommandCenter.tsx¶
Ventana overlay centrada, activada con SUPER+C. Keymode EXCLUSIVE (captura todas las teclas). Se cierra con Escape.
Botones disponibles¶
| Ícono | Acción | Comando |
|---|---|---|
|
Restart Bar | ags quit -i ags-bar; sleep 0.3; nohup ags run ... |
|
System Update | kitty --hold -e sudo pacman -Syyu |
|
Wallpaper | bash ~/.config/wallman/wallpicker.sh |
|
Clipboard | bash ~/.config/hypr/scripts/clipboard.sh |
|
Power | ags toggle -i ags-bar power-menu |
El título "COMMAND CENTER" usa un gradiente de color por carácter generado con markup Pango (<span foreground="...">) interpolando de #89B19E a #33473D.
Keybinds.tsx¶
Ventana overlay centrada, activada con SUPER+'. Muestra:
- Keybinds comunes: tabla de 2 columnas con los atajos más usados (hardcodeados en el array
COMMON). - Todos los keybinds: lista filtrable generada parseando
/home/fn-finixtavh/.config/hypr/keybinds.luaen tiempo real.
parseKeybinds()¶
Lee keybinds.lua línea por línea. Detecta comentarios de sección (-- ── Sección ──) como encabezados y extrae llamadas hl.bind(...). Ignora bucles for.
humanize(cmd)¶
Convierte comandos crudos (ej. ags toggle -i ags-bar command-center) a nombres amigables (ej. Command Center).
PowerMenu.tsx¶
Menú de sesión, activado con CTRL+ALT+DEL o el botón de encendido físico (si está configurado en logind). Opciones: Lock, Suspend, Logout, Reboot, Shutdown.
NotificationCenter.tsx¶
Panel lateral de notificaciones (historial). Ventana name="notif-center", por lo que también se puede abrir/cerrar con ags toggle -i ags-bar notif-center (usado por el keybind SUPER+N). Alternativamente, se activa con el botón de campana (NotifBell) en la barra inferior, o programáticamente via toggleNotifCenter(gdkmonitor).
Escucha las señales notified/resolved de AstalNotifd.get_default() y reconstruye la lista. Requiere que AGS sea el único propietario de org.freedesktop.Notifications en D-Bus (ver nota en app.ts).
Funciones exportadas¶
| Función | Descripción |
|---|---|
buildNotifItem(n, onDismiss) |
Construye el Gtk.Box de una notificación individual (ícono, app, tiempo, resumen, cuerpo, botón de descarte). Compartida con NotificationPopup.tsx. |
isDndEnabled() / subscribeDnd(cb) |
Estado de "No molestar" |
toggleNotifCenter(gdkmonitor) |
Abre/cierra el panel programáticamente |
NotificationPopup.tsx¶
Toasts de notificación transitorios, uno por monitor. Anclados a TOP | RIGHT, capa OVERLAY, fondo transparente (clase .NotifPopup); cada notificación individual recibe la clase .notif-toast además de las clases base de buildNotifItem.
- Reutiliza
buildNotifItem()deNotificationCenter.tsx— mismo diseño visual que el panel de historial. - Respeta el modo "No molestar" (
isDndEnabled()): si está activo, no muestra nada. - Timeout:
n.expireTimeoutsi está definido (>0); si no, 5 s por defecto o 8 s siurgency === 2(crítica). - Se apilan verticalmente si llegan varias notificaciones a la vez; cada una se puede descartar manualmente o se cierra sola al expirar el timer o recibir la señal
resolved.
GTK3 CSS no soporta max-width
Solo min-width/min-height son válidos como propiedades de tamaño en CSS de GTK3. Usar max-width rompe el parseo de CSS al arrancar AGS (Gtk.CssProviderError) y el proceso muere sin abrir ninguna ventana.
OSD.tsx¶
Indicador on-screen que aparece brevemente al cambiar el volumen o brillo. Se posiciona en la parte inferior central de la pantalla.
cava.ts — Visualizador de audio¶
Clase que lanza CAVA como subproceso y parsea su salida.
Configuración embebida¶
[general]
bars = 20
[input]
method = pipewire
source = auto
[output]
method = raw
raw_target = /dev/stdout
data_format = ascii
ascii_max_range = 255
Importante:
method=pipewirees necesario en sistemas con PipeWire puro. Sin esta línea CAVA intenta usar ALSA/PulseAudio y no recibe audio.
Propiedad bars¶
Array de números 0–255 representando la amplitud de cada banda de frecuencia. Se actualiza en cada frame de CAVA.
WifiMenu.tsx¶
Popup de gestión WiFi anclado a BOTTOM | RIGHT. Se abre al hacer clic en NetworkWidget. Se cierra con Escape o haciendo clic en el botón ✕.
Backend soportados¶
| Backend | Comandos usados |
|---|---|
| NetworkManager | nmcli device wifi list, nmcli device wifi connect, nmcli device wifi rescan |
| iwd | iwctl station IFACE get-networks, iwctl station IFACE connect, iwctl station IFACE scan |
El backend se resuelve al abrir el menú leyendo la preferencia en user-settings.json (networkBackend). Si está en auto, detecta cuál está corriendo y opcionalmente guarda el resultado en caché (networkBackendCached) para no repetir la detección en cada apertura.
Detección de interfaz¶
Usa /sys/class/net/*/wireless (sysfs) para encontrar la interfaz WiFi activa. No requiere iw ni nmcli.
Funciones principales¶
| Función | Descripción |
|---|---|
resolveBackend() |
Lee settings → cache → detecta NM/iwd → guarda en cache |
getWifiIface() |
Detecta interfaz WiFi via sysfs |
parseNmcli(raw) |
Parsea salida terse de nmcli -g ... |
parseIwctlNetworks(raw) |
Parsea salida de iwctl get-networks (maneja ANSI para señal real) |
openWifiMenu(gdkmonitor) |
Crea y muestra el popup; retorna función close() |
Características¶
- Lista de APs con ícono de señal, nombre, candado y porcentaje.
- Panel de detalle expandible por clic: SSID, BSSID (solo NM), Canal, Frecuencia, Security, barra de señal.
- Conectar con contraseña (campo de entrada en panel de detalle).
- Conectar a red oculta (panel plegable al pie del menú).
- Desconectar desde el AP activo.
- Botón de rescan (refresca lista con 2–2.5 s de espera).
SettingsPanel.tsx¶
Panel de configuración de usuario. Se abre desde CommandCenter (SUPER+C → botón Settings). Keymode EXCLUSIVE. Se cierra con Escape.
Páginas¶
| Página | Contenido |
|---|---|
| CAVA | Hz de refresco del visualizador (auto-detectado o manual) |
| YT-DLP | Filtro de música en historial de escucha |
| MUSIC BAR | Intervalo de guardado del historial; borrar datos |
| NETWORK | Backend WiFi (Auto/NetworkManager/iwd); toggle y borrado de cache de auto-detección |
Almacenamiento¶
~/.config/ags/user-settings.json — JSON plano. Claves relevantes:
| Clave | Tipo | Descripción |
|---|---|---|
networkBackend |
'auto'|'nm'|'iwd' |
Backend WiFi preferido |
networkAutoCache |
boolean |
Si se cachea el resultado de auto-detección |
networkBackendCached |
'nm'|'iwd'|'' |
Resultado cacheado de la última auto-detección |
cavaAutoHz |
boolean |
Auto-detectar Hz de CAVA desde monitor |
cavaManualHz |
number |
Hz manual de CAVA |
ytdlpMusicFilter |
boolean |
Filtrar solo música en historial |
historyIntervalS |
number |
Intervalo de guardado del historial (seg) |
Funciones exportadas¶
export function loadSettings(): Record<string, any>
export function saveSettings(updates: Record<string, any>): void
saveSettings hace merge shallow sobre el JSON existente. Se importa en WifiMenu.tsx para leer/escribir el backend cacheado.
Notas y recursos¶
- Documentación oficial de AGS v3 (Astal)
- GJS Documentation
- Referencia GTK3
- AstalMpris — MPRIS2 bindings
- Para el formato de archivos de letra: ver Letras (.lyr)