600 lines
18 KiB
Nix
Executable File
600 lines
18 KiB
Nix
Executable File
{
|
|
config,
|
|
lib,
|
|
namespace,
|
|
...
|
|
}:
|
|
with lib;
|
|
let
|
|
cfg = config.${namespace}.programs.waybar;
|
|
|
|
baseStyle =
|
|
if cfg.style.file != null then
|
|
builtins.readFile cfg.style.file
|
|
else
|
|
''
|
|
/* =============================================================================
|
|
ANIMATIONS & GLOBAL OVERRIDES
|
|
============================================================================= */
|
|
@keyframes blinker {
|
|
50% { color: @base08; }
|
|
}
|
|
|
|
/* Override Stylix font settings */
|
|
* {
|
|
font-family: "Jetbrains Mono Nerd Font", monospace;
|
|
font-size: 14px;
|
|
min-height: 0;
|
|
}
|
|
|
|
/* =============================================================================
|
|
MAIN BAR & TOOLTIPS
|
|
============================================================================= */
|
|
window#waybar {
|
|
background: transparent;
|
|
}
|
|
|
|
#waybar {
|
|
background: transparent;
|
|
color: @base06;
|
|
margin: 5px 5px;
|
|
}
|
|
|
|
#tooltip {
|
|
background: @base00;
|
|
border-color: @base00;
|
|
border-radius: 1rem;
|
|
border-width: 2px; /* Reduced from 1rem which is usually too thick */
|
|
border-style: solid;
|
|
}
|
|
|
|
/* Right-click menu styling */
|
|
menu {
|
|
border-radius: 15px;
|
|
background: @base00;
|
|
color: @base06;
|
|
}
|
|
menuitem {
|
|
border-radius: 15px;
|
|
}
|
|
|
|
/* =============================================================================
|
|
WORKSPACES
|
|
============================================================================= */
|
|
#workspaces {
|
|
background-color: @base00;
|
|
border-radius: 1rem;
|
|
opacity: 0.85;
|
|
padding: 0.2rem 0.5rem;
|
|
margin: 3px 0 3px 0.6rem;
|
|
}
|
|
|
|
#workspaces button {
|
|
color: @base0F;
|
|
border-radius: 1rem;
|
|
padding: 0.4rem;
|
|
/* Border handled by stylix, but we add specific colors below */
|
|
}
|
|
|
|
#workspaces button.active,
|
|
#workspaces button:hover {
|
|
color: @base0C;
|
|
border-radius: 1rem;
|
|
}
|
|
|
|
#workspaces button.focused {
|
|
color: @base06;
|
|
background: @base0A;
|
|
border-radius: 1rem;
|
|
}
|
|
|
|
#workspaces button.urgent {
|
|
color: @base00;
|
|
background: @base06;
|
|
border-radius: 1rem;
|
|
}
|
|
|
|
/* =============================================================================
|
|
WINDOW TITLE
|
|
============================================================================= */
|
|
#window {
|
|
color: @base0E;
|
|
background-color: @base00;
|
|
opacity: 0.85;
|
|
border-radius: 1rem;
|
|
padding: 0.2rem 0.5rem;
|
|
margin: 3px 0;
|
|
|
|
margin-left: 4rem;
|
|
margin-right: 75rem; /* This is very large, likely a centering hack */
|
|
}
|
|
|
|
#window.empty {
|
|
background-color: transparent;
|
|
}
|
|
|
|
/* =============================================================================
|
|
SHARED MODULE STYLES
|
|
============================================================================= */
|
|
/* This block applies the standard "Nord Background" style to all modules
|
|
to avoid repeating code for every single ID. */
|
|
#custom-power,
|
|
#custom-weather,
|
|
#custom-notifications,
|
|
#battery,
|
|
#clock,
|
|
#idle_inhibitor,
|
|
#network,
|
|
#bluetooth,
|
|
#wireplumber,
|
|
#keyboard-state,
|
|
#temperature,
|
|
#custom-left-end,
|
|
#custom-right-end,
|
|
#custom-lights,
|
|
#tray {
|
|
background-color: @base00;
|
|
opacity: 0.85;
|
|
padding: 0.2rem 0.5rem;
|
|
margin: 3px 0;
|
|
border-radius: 0; /* Default to square, rounded manually below */
|
|
}
|
|
|
|
/* Common Hover Effect */
|
|
#idle_inhibitor:hover,
|
|
#network:hover,
|
|
#bluetooth:hover,
|
|
#wireplumber:hover,
|
|
#temperature:hover,
|
|
#custom-lights:hover {
|
|
background: @base02;
|
|
}
|
|
|
|
/* =============================================================================
|
|
MODULE SPECIFIC COLORS
|
|
============================================================================= */
|
|
|
|
#custom-power,
|
|
#custom-weather,
|
|
#custom-notifications {
|
|
color: @base0F;
|
|
}
|
|
|
|
#custom-notifications.notify { color: @base08; }
|
|
#custom-notifications.alert {
|
|
animation: blinker 3s linear infinite;
|
|
}
|
|
|
|
#battery {
|
|
color: @base0E;
|
|
min-width: 3rem;
|
|
}
|
|
|
|
#clock { color: @base0F; }
|
|
|
|
#idle_inhibitor {
|
|
color: @base0F;
|
|
padding-right: 1rem;
|
|
}
|
|
|
|
#network {
|
|
color: @base0E;
|
|
padding-right: 15px;
|
|
}
|
|
|
|
#bluetooth { color: @base0F; }
|
|
|
|
/* --- Audio source/sink --- */
|
|
#wireplumber.source,
|
|
#wireplumber.sink {
|
|
color: @base0C;
|
|
}
|
|
|
|
#wireplumber.source.muted {
|
|
animation: blinker 2s linear infinite;
|
|
padding-right: 1rem;
|
|
}
|
|
|
|
#wireplumber.sink.muted {
|
|
animation: blinker 5s linear infinite;
|
|
}
|
|
|
|
/* --- Keyboard --- */
|
|
#keyboard-state.numlock { color: @base0C; }
|
|
#keyboard-state.capslock { color: @base0F; }
|
|
|
|
/* --- Temperature --- */
|
|
#temperature,
|
|
#temperature.gpu {
|
|
color: @base0F;
|
|
}
|
|
|
|
/* --- Tray --- */
|
|
#tray {
|
|
border-radius: 1rem;
|
|
margin-right: 0.6rem;
|
|
}
|
|
|
|
/* =============================================================================
|
|
DECORATIVE END CAPS & EXTRAS
|
|
============================================================================= */
|
|
#custom-left-end {
|
|
border-radius: 1rem 0 0 1rem;
|
|
margin-left: 0.5rem;
|
|
}
|
|
|
|
#custom-right-end {
|
|
border-radius: 0 1rem 1rem 0;
|
|
margin-right: 0.5rem;
|
|
}
|
|
|
|
#custom-lights {
|
|
color: @base0C;
|
|
/* Re-declaring background here to ensure specific override logic if needed */
|
|
background-color: @base00;
|
|
border-radius: 1rem 0 0 1rem;
|
|
margin-left: 0.5rem;
|
|
}
|
|
'';
|
|
in
|
|
{
|
|
imports = [
|
|
./options.nix
|
|
./scripts/audio-control.nix
|
|
./scripts/hass.nix
|
|
./scripts/media.nix
|
|
./scripts/notifications.nix
|
|
./scripts/weather.nix
|
|
];
|
|
|
|
config = mkIf cfg.enable {
|
|
# https://github.com/Alexays/Waybar/wiki/Module:-Hyprland
|
|
# https://www.nerdfonts.com/cheat-sheet
|
|
|
|
home.file = {
|
|
".config/waybar/power_menu.xml".text = ''
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<interface>
|
|
<object class="GtkMenu" id="menu">
|
|
<child>
|
|
<object class="GtkMenuItem" id="suspend">
|
|
<property name="label">Suspend</property>
|
|
</object>
|
|
</child>
|
|
<child>
|
|
<object class="GtkMenuItem" id="hibernat">
|
|
<property name="label">Hibernate</property>
|
|
</object>
|
|
</child>
|
|
<child>
|
|
<object class="GtkMenuItem" id="shutdown">
|
|
<property name="label">Shutdown</property>
|
|
</object>
|
|
</child>
|
|
<child>
|
|
<object class="GtkSeparatorMenuItem" id="delimiter1" />
|
|
</child>
|
|
<child>
|
|
<object class="GtkMenuItem" id="reboot">
|
|
<property name="label">Reboot</property>
|
|
</object>
|
|
</child>
|
|
<child>
|
|
<object class="GtkMenuItem" id="lock">
|
|
<property name="label">Lock</property>
|
|
</object>
|
|
</child>
|
|
</object>
|
|
</interface>
|
|
'';
|
|
};
|
|
|
|
programs.waybar = {
|
|
enable = true;
|
|
systemd.enable = true;
|
|
|
|
settings = {
|
|
mainBar =
|
|
(mkMerge [
|
|
{
|
|
inherit (cfg) layer;
|
|
position = "top";
|
|
mod = "dock";
|
|
exclusive = true;
|
|
passthrough = false;
|
|
gtk-layer-shell = true;
|
|
height = 0;
|
|
|
|
# Module Layout
|
|
modules-left = cfg.layout.left;
|
|
modules-center = cfg.layout.center;
|
|
modules-right = cfg.layout.right;
|
|
|
|
# Base module definitions always present unless individually gated
|
|
"hyprland/workspaces" = {
|
|
disable-scroll = true;
|
|
all-outputs = true;
|
|
on-click = "activate";
|
|
persistent_workspaces = {
|
|
"*" = 1;
|
|
};
|
|
};
|
|
|
|
"hyprland/window" = {
|
|
separate-outputs = true;
|
|
format = { };
|
|
};
|
|
|
|
temperature = {
|
|
hwmon-path-abs = cfg.temperature.cpu.hwmonPath;
|
|
input-filename = cfg.temperature.cpu.hwmonFile;
|
|
critical-threshold = 110;
|
|
format-critical = "{temperatureC}°C ";
|
|
format = "{temperatureC}°C {icon}";
|
|
format-icons = [
|
|
""
|
|
""
|
|
""
|
|
""
|
|
""
|
|
];
|
|
tooltip-format = "CPU: {temperatureC}°C";
|
|
};
|
|
|
|
network = {
|
|
inherit (cfg.network) interface;
|
|
on-click = "nm-connection-editor";
|
|
format = "{icon}";
|
|
tooltip-format = "{ifname} via {gwaddr} ";
|
|
tooltip-format-wifi = ''
|
|
{essid} ({signalStrength}%) {icon}
|
|
{bandwidthDownBits} {bandwidthUpBits}
|
|
'';
|
|
tooltip-format-ethernet = "{ifname} ";
|
|
tooltip-format-disconnected = "Disconnected";
|
|
max-length = 50;
|
|
format-icons = {
|
|
wifi = [
|
|
""
|
|
""
|
|
""
|
|
""
|
|
""
|
|
];
|
|
ethernet = "";
|
|
linked = "";
|
|
disconnected = "";
|
|
};
|
|
};
|
|
|
|
"custom/notifications" = {
|
|
interval = 30;
|
|
format = { };
|
|
tooltip = true;
|
|
exec = "waybar-notifications";
|
|
return-type = "json";
|
|
on-click-middle = "makoctl restore && makoctl dismiss --all --no-history"; # todo
|
|
};
|
|
|
|
"custom/left-end" = {
|
|
format = "&nbsp";
|
|
tooltip = false;
|
|
};
|
|
|
|
"custom/right-end" = {
|
|
format = "&nbsp";
|
|
tooltip = false;
|
|
};
|
|
|
|
"custom/power" = {
|
|
format = "⏻ ";
|
|
tooltip = false;
|
|
menu = "on-click";
|
|
menu-file = "~/.config/waybar/power_menu.xml";
|
|
menu-actions = {
|
|
shutdown = "shutdown";
|
|
reboot = "reboot";
|
|
suspend = "systemctl suspend";
|
|
hibernate = "systemctl hibernate";
|
|
lock = "pidof hyprlock || hyprlock";
|
|
};
|
|
};
|
|
}
|
|
|
|
(mkIf cfg.features.tray.enable {
|
|
tray = {
|
|
icon-size = 16;
|
|
spacing = 10;
|
|
};
|
|
})
|
|
|
|
(mkIf cfg.features.keyboardIndicators.enable {
|
|
"keyboard-state#capslock" = {
|
|
capslock = true;
|
|
format = "{icon}";
|
|
tooltip-format = "Caps Lock {state}";
|
|
format-icons = {
|
|
locked = "";
|
|
unlocked = "";
|
|
};
|
|
};
|
|
|
|
"keyboard-state#numlock" = {
|
|
numlock = true;
|
|
format = "{icon}";
|
|
tooltip-format = "Num Lock {state}";
|
|
format-icons = {
|
|
locked = "";
|
|
unlocked = "";
|
|
};
|
|
};
|
|
})
|
|
|
|
(mkIf cfg.features.audio.sink.enable {
|
|
"wireplumber#sink" = {
|
|
format = "{icon} {volume}%";
|
|
tooltip-format = "{icon}\n{node_name}\n{format_source}\n{source_desc}";
|
|
format-muted = "{icon} Muted";
|
|
on-click = "wpctl set-mute @DEFAULT_SINK@ toggle";
|
|
on-click-right = "pavucontrol -t 1";
|
|
on-scroll-up = "wpctl set-volume @DEFAULT_SINK@ 5%+";
|
|
on-scroll-down = "wpctl set-volume @DEFAULT_SINK@ 5%-";
|
|
on-click-middle = "waybar-audio";
|
|
scroll-step = 5;
|
|
format-icons = {
|
|
headphone = "";
|
|
headphone-muted = "";
|
|
hands-free = "";
|
|
headset = "";
|
|
phone = "";
|
|
portable = "";
|
|
car = "";
|
|
default = [
|
|
""
|
|
""
|
|
""
|
|
""
|
|
];
|
|
};
|
|
};
|
|
})
|
|
|
|
(mkIf cfg.features.audio.source.enable {
|
|
"wireplumber#source" = {
|
|
node-type = "Audio/Source";
|
|
format = "";
|
|
format-muted = "";
|
|
tooltip = false;
|
|
on-click = "wpctl set-mute @DEFAULT_SOURCE@ toggle";
|
|
on-click-right = "pavucontrol -t 2";
|
|
on-scroll-up = "wpctl set-volume @DEFAULT_SOURCE@ 5%+";
|
|
on-scroll-down = "wpctl set-volume @DEFAULT_SOURCE@ 5%-";
|
|
scroll-step = 5;
|
|
};
|
|
})
|
|
|
|
(mkIf cfg.features.bluetooth.enable {
|
|
bluetooth = {
|
|
on-click = "overskride";
|
|
tooltip = true;
|
|
format = "{icon}";
|
|
tooltip-format = "{status}";
|
|
tooltip-format-disabled = "{status}";
|
|
tooltip-format-off = "{status}";
|
|
tooltip-format-on = "{status}";
|
|
tooltip-format-connected = "{status}";
|
|
tooltip-format-enumerate-connected = { };
|
|
format-icons = {
|
|
disabled = "";
|
|
off = "";
|
|
on = "";
|
|
connected = "";
|
|
};
|
|
};
|
|
})
|
|
|
|
(mkIf cfg.features.idleInhibitor.enable {
|
|
idle_inhibitor = {
|
|
format = "{icon}";
|
|
format-icons = {
|
|
activated = "";
|
|
deactivated = "";
|
|
};
|
|
};
|
|
})
|
|
|
|
(mkIf cfg.features.clock.enable {
|
|
clock = {
|
|
format = "{:%I:%M %p}";
|
|
tooltip-format = "<tt><small>{calendar}</small></tt>";
|
|
calendar = {
|
|
mode = "month";
|
|
format = {
|
|
months = "<span color='@base0F'><b>{}</b></span>";
|
|
days = "<span color='@base0F'><b>{}</b></span>";
|
|
weekdays = "<span color='@base0C'><b>{}</b></span>";
|
|
today = "<span color='${config.lib.stylix.colors.base0B}'><b><u>{}</u></b></span>";
|
|
};
|
|
};
|
|
};
|
|
})
|
|
|
|
(mkIf cfg.features.battery.enable {
|
|
battery = {
|
|
interval = 60;
|
|
states = {
|
|
warning = 30;
|
|
critical = 15;
|
|
};
|
|
format = "{capacity}% {icon}";
|
|
format-icons = {
|
|
default = [
|
|
""
|
|
""
|
|
""
|
|
""
|
|
""
|
|
""
|
|
""
|
|
""
|
|
""
|
|
""
|
|
""
|
|
];
|
|
charging = [
|
|
""
|
|
""
|
|
""
|
|
""
|
|
""
|
|
""
|
|
""
|
|
""
|
|
""
|
|
""
|
|
""
|
|
];
|
|
};
|
|
max-length = 25;
|
|
};
|
|
})
|
|
|
|
(mkIf cfg.temperature.gpu.enable {
|
|
"temperature#gpu" = {
|
|
hwmon-path-abs = cfg.temperature.gpu.hwmonPath;
|
|
input-filename = cfg.temperature.gpu.hwmonFile;
|
|
critical-threshold = 110;
|
|
format-critical = "{temperatureC}°C ";
|
|
format = "{temperatureC}°C {icon}";
|
|
format-icons = [
|
|
""
|
|
""
|
|
""
|
|
""
|
|
""
|
|
];
|
|
on-click = "lact";
|
|
tooltip-format = "GPU: {temperatureC}°C";
|
|
};
|
|
})
|
|
|
|
(mkIf cfg.features.weather.enable {
|
|
"custom/weather" = {
|
|
tooltip = true;
|
|
format = { };
|
|
interval = 30;
|
|
exec = "waybar-weather --waybar";
|
|
return-type = "json";
|
|
markup = "pango";
|
|
};
|
|
})
|
|
])
|
|
// cfg.extra.settings;
|
|
}
|
|
// cfg.extraModules; # keep legacy top-level extra modules for compatibility
|
|
|
|
style = baseStyle + (cfg.extra.style or "") + (cfg.extraModulesStyle or "");
|
|
};
|
|
};
|
|
}
|