The power menu runs anyrun in standalone stdin mode, which kills the daemon. Explicitly quit the daemon before, then restart it after the standalone invocation so the launcher stays fast. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
613 lines
23 KiB
Nix
613 lines
23 KiB
Nix
# settings/hyprland.nix
|
|
{ config, pkgs, lib, inputs, ... }:
|
|
let
|
|
hyprland-pkgs = inputs.hyprland.packages.${pkgs.stdenv.hostPlatform.system};
|
|
|
|
isMacbook = config.networking.hostName == "FredOS-Macbook";
|
|
isGaming = !isMacbook;
|
|
|
|
# hyprutils-0.13.1 requires GLIBCXX_3.4.34 (GCC 15) but Hyprland's RPATH
|
|
# was patched to gcc-14.3.0-lib which only provides up to GLIBCXX_3.4.33.
|
|
# Use our nixpkgs GCC 15 to supply the missing symbol via LD_PRELOAD.
|
|
gcc15-stdlib = pkgs.gcc15.cc.lib;
|
|
|
|
hyprland-wrapped = pkgs.symlinkJoin {
|
|
name = hyprland-pkgs.hyprland.name;
|
|
version = hyprland-pkgs.hyprland.version;
|
|
paths = [ hyprland-pkgs.hyprland ];
|
|
nativeBuildInputs = [ pkgs.makeWrapper ];
|
|
# passthru inside symlinkJoin flows through runCommand → mkDerivation,
|
|
# which correctly sets drv.passthru. The display manager requires
|
|
# providedSessions; HM's hyprland module requires override.
|
|
passthru = {
|
|
providedSessions = [ "hyprland" ];
|
|
override = _: hyprland-wrapped;
|
|
};
|
|
postBuild = ''
|
|
wrapProgram $out/bin/start-hyprland \
|
|
--set LD_PRELOAD "${gcc15-stdlib}/lib/libstdc++.so.6"
|
|
wrapProgram $out/bin/Hyprland \
|
|
--set LD_PRELOAD "${gcc15-stdlib}/lib/libstdc++.so.6"
|
|
|
|
# The session .desktop symlinks to the original package and contains
|
|
# its absolute store path. Rewrite Exec= to our wrapped binary so
|
|
# GDM actually launches the LD_PRELOAD wrapper, not the bare binary.
|
|
desktop=$out/share/wayland-sessions/hyprland.desktop
|
|
orig=$(readlink -f "$desktop")
|
|
rm "$desktop"
|
|
sed "s|^Exec=.*|Exec=$out/bin/start-hyprland|" "$orig" > "$desktop"
|
|
'';
|
|
};
|
|
in
|
|
{
|
|
config = lib.mkIf (lib.elem config.networking.hostName [ "FredOS-Gaming" "FredOS-Macbook" ]) {
|
|
programs.hyprland = {
|
|
enable = true;
|
|
xwayland.enable = true;
|
|
package = hyprland-wrapped;
|
|
portalPackage = hyprland-pkgs.xdg-desktop-portal-hyprland;
|
|
};
|
|
|
|
xdg.portal = {
|
|
enable = true;
|
|
# xdg-desktop-portal-hyprland is registered automatically by
|
|
# programs.hyprland.portalPackage; listing it here too produced a
|
|
# duplicate user-unit symlink during nixos-rebuild.
|
|
extraPortals = with pkgs; [
|
|
xdg-desktop-portal-gtk
|
|
];
|
|
config.hyprland.default = [ "hyprland" "gtk" ];
|
|
};
|
|
|
|
security.polkit.enable = true;
|
|
|
|
# Polkit GUI agent for GUI sudo prompts under Hyprland
|
|
systemd.user.services.polkit-gnome-authentication-agent-1 = {
|
|
description = "polkit-gnome-authentication-agent-1";
|
|
wantedBy = [ "graphical-session.target" ];
|
|
partOf = [ "graphical-session.target" ];
|
|
after = [ "graphical-session.target" ];
|
|
serviceConfig = {
|
|
Type = "simple";
|
|
ExecStart = "${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1";
|
|
Restart = "on-failure";
|
|
};
|
|
};
|
|
|
|
environment.systemPackages = with pkgs; [
|
|
ghostty
|
|
mako
|
|
grim
|
|
slurp
|
|
wl-clipboard
|
|
cliphist
|
|
brightnessctl
|
|
pamixer
|
|
swayosd
|
|
playerctl
|
|
hyprpaper
|
|
hyprlock
|
|
hypridle
|
|
hyprshot
|
|
networkmanagerapplet
|
|
pavucontrol
|
|
polkit_gnome
|
|
];
|
|
|
|
home-manager.users.fred = { config, lib, pkgs, inputs, ... }:
|
|
let
|
|
c = config.lib.stylix.colors;
|
|
rgb = hex: "rgb(${hex})";
|
|
rgba = hex: a: "rgba(${hex}${a})";
|
|
in {
|
|
# Stylix's Hyprland target injects settings.{general,decoration,group,misc}
|
|
# as top-level keys, which render as hl.general()/hl.decoration()/… in Lua
|
|
# mode — functions that don't exist. Disable it and absorb the colours
|
|
# into settings.config below.
|
|
stylix.targets.hyprland.enable = false;
|
|
|
|
# The disabled Hyprland target would normally enable this; do it
|
|
# manually. Stylix's hyprpaper target (auto-enabled) still handles
|
|
# preload/wallpaper settings.
|
|
services.hyprpaper.enable = true;
|
|
|
|
wayland.windowManager.hyprland = {
|
|
enable = true;
|
|
configType = "lua";
|
|
systemd.variables = [ "--all" ];
|
|
package = hyprland-wrapped;
|
|
|
|
settings = {
|
|
# hl.config({...}) — all static named-section configuration.
|
|
# monitor is set per-host in hosts/FredOS-{Gaming,Macbook}.nix.
|
|
config = {
|
|
general = {
|
|
gaps_in = 6;
|
|
gaps_out = 12;
|
|
border_size = 2;
|
|
layout = "dwindle";
|
|
resize_on_border = true;
|
|
"col.active_border" = rgb c.base0D;
|
|
"col.inactive_border" = rgb c.base03;
|
|
};
|
|
|
|
decoration = {
|
|
rounding = 8;
|
|
blur = {
|
|
enabled = true;
|
|
};
|
|
shadow.color = rgba c.base00 "99";
|
|
};
|
|
|
|
group = {
|
|
"col.border_active" = rgb c.base0D;
|
|
"col.border_inactive" = rgb c.base03;
|
|
"col.border_locked_active" = rgb c.base0C;
|
|
groupbar = {
|
|
text_color = rgb c.base05;
|
|
"col.active" = rgb c.base0D;
|
|
"col.inactive" = rgb c.base03;
|
|
};
|
|
};
|
|
|
|
render = {
|
|
direct_scanout = false;
|
|
};
|
|
|
|
animations = {
|
|
enabled = true;
|
|
};
|
|
|
|
input = {
|
|
kb_layout = "gb,no";
|
|
kb_options = "grp:alt_shift_toggle";
|
|
follow_mouse = 1;
|
|
accel_profile = "flat";
|
|
sensitivity = 0;
|
|
} // lib.optionalAttrs isMacbook {
|
|
touchpad = {
|
|
tap_to_click = true;
|
|
tap_button_map = "lrm";
|
|
natural_scroll = true;
|
|
};
|
|
};
|
|
|
|
cursor = {
|
|
no_warps = true;
|
|
};
|
|
|
|
dwindle = {
|
|
preserve_split = true;
|
|
};
|
|
|
|
misc = {
|
|
disable_hyprland_logo = true;
|
|
disable_splash_rendering = true;
|
|
# Apps demanding attention don't get to yank focus — they'll
|
|
# show as urgent in the bar instead.
|
|
focus_on_activate = false;
|
|
vrr = 2;
|
|
background_color = rgb c.base00;
|
|
};
|
|
|
|
# vfr moved from misc: to debug: in 0.55.0
|
|
debug = {
|
|
vfr = false; # keep compositor ticking, don't idle between frames
|
|
disable_logs = false;
|
|
};
|
|
};
|
|
};
|
|
|
|
extraConfig =
|
|
let
|
|
powerMenu = pkgs.writeShellScript "power-menu" ''
|
|
# Kill the daemon before using anyrun in standalone stdin mode;
|
|
# a concurrent standalone instance conflicts with the daemon.
|
|
${pkgs.anyrun}/bin/anyrun quit 2>/dev/null || true
|
|
choice=$(printf '%s\n' \
|
|
$'\uf023 Lock' \
|
|
$'\uf08b Logout' \
|
|
$'\uf01e Reboot' \
|
|
$'\uf011 Shutdown' \
|
|
| ${pkgs.anyrun}/bin/anyrun \
|
|
--plugins "${pkgs.anyrun}/lib/libstdin.so" \
|
|
--show-results-immediately true \
|
|
--hide-plugin-info true \
|
|
--close-on-click true)
|
|
# Restart the daemon for instant launcher opens.
|
|
${pkgs.anyrun}/bin/anyrun daemon &
|
|
case "$choice" in
|
|
*Lock) ${pkgs.hyprlock}/bin/hyprlock ;;
|
|
*Logout) hyprctl dispatch exit ;;
|
|
*Reboot) systemctl reboot ;;
|
|
*Shutdown) systemctl poweroff ;;
|
|
esac
|
|
'';
|
|
kbdBrightUp = pkgs.writeShellScript "kbd-bright-up" ''
|
|
${pkgs.brightnessctl}/bin/brightnessctl -d smc::kbd_backlight set +10%
|
|
brightness=$(${pkgs.brightnessctl}/bin/brightnessctl -d smc::kbd_backlight get)
|
|
max=$(${pkgs.brightnessctl}/bin/brightnessctl -d smc::kbd_backlight max)
|
|
echo $(( brightness * 100 / max )) > "$XDG_RUNTIME_DIR/wob.fifo"
|
|
'';
|
|
kbdBrightDown = pkgs.writeShellScript "kbd-bright-down" ''
|
|
${pkgs.brightnessctl}/bin/brightnessctl -d smc::kbd_backlight set 10%-
|
|
brightness=$(${pkgs.brightnessctl}/bin/brightnessctl -d smc::kbd_backlight get)
|
|
max=$(${pkgs.brightnessctl}/bin/brightnessctl -d smc::kbd_backlight max)
|
|
echo $(( brightness * 100 / max )) > "$XDG_RUNTIME_DIR/wob.fifo"
|
|
'';
|
|
in
|
|
''
|
|
-- Environment
|
|
hl.env("LD_PRELOAD", "")
|
|
hl.env("XCURSOR_THEME", "Bibata-Modern-Ice")
|
|
hl.env("XCURSOR_SIZE", "24")
|
|
hl.env("HYPRCURSOR_THEME", "Bibata-Modern-Ice")
|
|
hl.env("HYPRCURSOR_SIZE", "24")
|
|
hl.env("ELECTRON_OZONE_PLATFORM_HINT", "wayland")
|
|
hl.env("MOZ_ENABLE_WAYLAND", "1")
|
|
hl.env("QT_QPA_PLATFORM", "wayland;xcb")
|
|
hl.env("SDL_VIDEODRIVER", "wayland")
|
|
hl.env("_JAVA_AWT_WM_NONREPARENTING", "1")
|
|
${lib.optionalString isGaming ''
|
|
-- GPU pinning — Navi 22 is card1 on the dual-GPU gaming box.
|
|
hl.env("AQ_DRM_DEVICES", "/dev/dri/card1")
|
|
hl.env("WLR_DRM_DEVICES", "/dev/dri/card1")
|
|
hl.env("DRI_PRIME", "pci-0000_03_00_0")
|
|
''}
|
|
|
|
-- Startup
|
|
hl.on("hyprland.start", function()
|
|
-- Ensure hyprland-session.target starts even if HM's
|
|
-- dbus-update-activation-environment chain fails upstream.
|
|
hl.exec_cmd("systemctl --user start hyprland-session.target")
|
|
hl.exec_cmd("mako")
|
|
hl.exec_cmd("nm-applet --indicator")
|
|
hl.exec_cmd("wl-paste --type text --watch cliphist store")
|
|
hl.exec_cmd("wl-paste --type image --watch cliphist store")
|
|
hl.exec_cmd("hyprctl setcursor Bibata-Modern-Ice 24")
|
|
hl.exec_cmd("swayosd-server")
|
|
hl.exec_cmd("anyrun daemon")
|
|
${lib.optionalString isMacbook ''hl.exec_cmd("hypridle")''}
|
|
end)
|
|
|
|
-- Animation curve and definitions
|
|
hl.curve("snap", { type = "bezier", points = { {0.05, 0.9}, {0.1, 1.0} } })
|
|
hl.animation({ leaf = "windows", enabled = true, speed = 1, bezier = "snap" })
|
|
hl.animation({ leaf = "windowsOut", enabled = true, speed = 1, bezier = "snap", style = "popin 80%" })
|
|
hl.animation({ leaf = "layers", enabled = true, speed = 1, bezier = "snap" })
|
|
hl.animation({ leaf = "border", enabled = true, speed = 2, bezier = "default" })
|
|
hl.animation({ leaf = "fade", enabled = true, speed = 1, bezier = "default" })
|
|
hl.animation({ leaf = "workspaces", enabled = true, speed = 1, bezier = "snap" })
|
|
|
|
-- Window rules
|
|
-- Battle.net tray icon leaks as a tiny floating XWayland window.
|
|
hl.window_rule({
|
|
match = { class = "steam_app_0", title = "^$", float = true },
|
|
workspace = "special silent",
|
|
})
|
|
|
|
-- Binds
|
|
local mod = "SUPER"
|
|
|
|
-- Apps
|
|
hl.bind(mod .. " + T", hl.dsp.exec_cmd("ghostty"))
|
|
hl.bind(mod .. " + E", hl.dsp.exec_cmd("nemo"))
|
|
hl.bind(mod .. " + R", hl.dsp.exec_cmd("anyrun"))
|
|
hl.bind(mod .. " + Q", hl.dsp.window.close())
|
|
hl.bind(mod .. " + SHIFT + E", hl.dsp.exit())
|
|
|
|
-- Floating / layout
|
|
hl.bind(mod .. " + V", hl.dsp.window.float({ action = "toggle" }))
|
|
hl.bind(mod .. " + F", hl.dsp.window.fullscreen())
|
|
hl.bind(mod .. " + P", hl.dsp.window.pseudo())
|
|
hl.bind(mod .. " + S", hl.dsp.layout("togglesplit"))
|
|
|
|
-- Focus
|
|
hl.bind(mod .. " + left", hl.dsp.focus({ direction = "left" }))
|
|
hl.bind(mod .. " + right", hl.dsp.focus({ direction = "right" }))
|
|
hl.bind(mod .. " + up", hl.dsp.focus({ direction = "up" }))
|
|
hl.bind(mod .. " + down", hl.dsp.focus({ direction = "down" }))
|
|
hl.bind(mod .. " + H", hl.dsp.focus({ direction = "left" }))
|
|
hl.bind(mod .. " + K", hl.dsp.focus({ direction = "up" }))
|
|
hl.bind(mod .. " + J", hl.dsp.focus({ direction = "down" }))
|
|
|
|
-- Power menu — dismiss anyrun if open, then show menu
|
|
hl.bind(mod .. " + L", hl.dsp.exec_cmd("anyrun close; ${powerMenu}"))
|
|
|
|
-- Move windows
|
|
hl.bind(mod .. " + SHIFT + left", hl.dsp.window.move({ direction = "left" }))
|
|
hl.bind(mod .. " + SHIFT + right", hl.dsp.window.move({ direction = "right" }))
|
|
hl.bind(mod .. " + SHIFT + up", hl.dsp.window.move({ direction = "up" }))
|
|
hl.bind(mod .. " + SHIFT + down", hl.dsp.window.move({ direction = "down" }))
|
|
|
|
-- Workspaces
|
|
hl.bind(mod .. " + 1", hl.dsp.focus({ workspace = 1 }))
|
|
hl.bind(mod .. " + 2", hl.dsp.focus({ workspace = 2 }))
|
|
hl.bind(mod .. " + 3", hl.dsp.focus({ workspace = 3 }))
|
|
hl.bind(mod .. " + 4", hl.dsp.focus({ workspace = 4 }))
|
|
hl.bind(mod .. " + 5", hl.dsp.focus({ workspace = 5 }))
|
|
hl.bind(mod .. " + 6", hl.dsp.focus({ workspace = 6 }))
|
|
hl.bind(mod .. " + 7", hl.dsp.focus({ workspace = 7 }))
|
|
hl.bind(mod .. " + 8", hl.dsp.focus({ workspace = 8 }))
|
|
hl.bind(mod .. " + 9", hl.dsp.focus({ workspace = 9 }))
|
|
hl.bind(mod .. " + 0", hl.dsp.focus({ workspace = 10 }))
|
|
|
|
hl.bind(mod .. " + SHIFT + 1", hl.dsp.window.move({ workspace = 1, follow = false }))
|
|
hl.bind(mod .. " + SHIFT + 2", hl.dsp.window.move({ workspace = 2, follow = false }))
|
|
hl.bind(mod .. " + SHIFT + 3", hl.dsp.window.move({ workspace = 3, follow = false }))
|
|
hl.bind(mod .. " + SHIFT + 4", hl.dsp.window.move({ workspace = 4, follow = false }))
|
|
hl.bind(mod .. " + SHIFT + 5", hl.dsp.window.move({ workspace = 5, follow = false }))
|
|
hl.bind(mod .. " + SHIFT + 6", hl.dsp.window.move({ workspace = 6, follow = false }))
|
|
hl.bind(mod .. " + SHIFT + 7", hl.dsp.window.move({ workspace = 7, follow = false }))
|
|
hl.bind(mod .. " + SHIFT + 8", hl.dsp.window.move({ workspace = 8, follow = false }))
|
|
hl.bind(mod .. " + SHIFT + 9", hl.dsp.window.move({ workspace = 9, follow = false }))
|
|
hl.bind(mod .. " + SHIFT + 0", hl.dsp.window.move({ workspace = 10, follow = false }))
|
|
|
|
-- Screenshots — Shift+Super+S matches GNOME binding
|
|
hl.bind(mod .. " + SHIFT + S", hl.dsp.exec_cmd("hyprshot -m region --clipboard-only"))
|
|
hl.bind("Print", hl.dsp.exec_cmd("hyprshot -m output --clipboard-only"))
|
|
|
|
-- Settings shortcut — Super+I matches GNOME binding
|
|
hl.bind(mod .. " + I", hl.dsp.exec_cmd("pavucontrol"))
|
|
|
|
-- Custom shortcuts
|
|
hl.bind(mod .. " + Z", hl.dsp.exec_cmd("zen-beta"))
|
|
|
|
-- Mouse window manipulation
|
|
hl.bind(mod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true })
|
|
hl.bind(mod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true })
|
|
|
|
-- Volume / brightness (repeating)
|
|
hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("swayosd-client --output-volume raise"), { repeating = true })
|
|
hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("swayosd-client --output-volume lower"), { repeating = true })
|
|
hl.bind("XF86AudioMute", hl.dsp.exec_cmd("swayosd-client --output-volume mute-toggle"), { repeating = true })
|
|
hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd("swayosd-client --brightness raise"), { repeating = true })
|
|
hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd("swayosd-client --brightness lower"), { repeating = true })
|
|
${lib.optionalString isMacbook ''
|
|
hl.bind("XF86KbdBrightnessUp", hl.dsp.exec_cmd("${kbdBrightUp}"), { repeating = true })
|
|
hl.bind("XF86KbdBrightnessDown", hl.dsp.exec_cmd("${kbdBrightDown}"), { repeating = true })
|
|
''}
|
|
|
|
-- Media keys (locked — work through lockscreen)
|
|
hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("playerctl play-pause"), { locked = true })
|
|
hl.bind("XF86AudioNext", hl.dsp.exec_cmd("playerctl next"), { locked = true })
|
|
hl.bind("XF86AudioPrev", hl.dsp.exec_cmd("playerctl previous"), { locked = true })
|
|
'';
|
|
};
|
|
|
|
programs.anyrun = {
|
|
enable = true;
|
|
config = {
|
|
plugins = [ "${pkgs.anyrun}/lib/libapplications.so" ];
|
|
x.fraction = 0.5;
|
|
y.fraction = 0.25;
|
|
width.absolute = 350;
|
|
height.absolute = 0;
|
|
margin = 16;
|
|
hideIcons = false;
|
|
ignoreExclusiveZones = false;
|
|
layer = "overlay";
|
|
hidePluginInfo = true;
|
|
closeOnClick = true;
|
|
maxEntries = 8;
|
|
};
|
|
extraCss =
|
|
let c = config.lib.stylix.colors; in
|
|
''
|
|
* { all: unset; font-family: "FiraMono Nerd Font", monospace; font-size: 13px; }
|
|
window { background: transparent; }
|
|
box.main {
|
|
background: #${c.base00};
|
|
border: 1px solid #${c.base03};
|
|
border-radius: 10px;
|
|
padding: 8px;
|
|
margin: 16px;
|
|
}
|
|
text {
|
|
background: #${c.base01};
|
|
color: #${c.base05};
|
|
caret-color: #${c.base0D};
|
|
padding: 8px 16px;
|
|
border-radius: 6px;
|
|
min-height: 0;
|
|
}
|
|
list.plugin { background: transparent; }
|
|
.matches { background: transparent; }
|
|
.match {
|
|
padding: 4px 16px;
|
|
border-radius: 6px;
|
|
color: #${c.base05};
|
|
background: transparent;
|
|
}
|
|
.match:selected {
|
|
background: #${c.base02};
|
|
border: none;
|
|
}
|
|
label.match.description { color: #${c.base04}; font-size: 11px; }
|
|
'';
|
|
extraConfigFiles."applications.ron".text = ''
|
|
Config(
|
|
desktop_actions: false,
|
|
max_entries: 8,
|
|
terminal: "ghostty",
|
|
)
|
|
'';
|
|
};
|
|
|
|
programs.hyprlock.enable = true;
|
|
|
|
services.hypridle = lib.mkIf isMacbook {
|
|
enable = true;
|
|
settings = {
|
|
general = {
|
|
lock_cmd = "pidof hyprlock || hyprlock";
|
|
before_sleep_cmd = "loginctl lock-session";
|
|
after_sleep_cmd = "hyprctl dispatch dpms on";
|
|
};
|
|
listener = [
|
|
{
|
|
timeout = 300; # 5 min — lock
|
|
on-timeout = "loginctl lock-session";
|
|
}
|
|
{
|
|
timeout = 420; # 7 min — display off
|
|
on-timeout = "hyprctl dispatch dpms off";
|
|
on-resume = "hyprctl dispatch dpms on";
|
|
}
|
|
{
|
|
timeout = 600; # 10 min — suspend
|
|
on-timeout = "systemctl suspend";
|
|
}
|
|
];
|
|
};
|
|
};
|
|
|
|
# Scope all HM Wayland services (hyprpaper, waybar, …) to the
|
|
# Hyprland session so they don't crash-loop in a GNOME session.
|
|
wayland.systemd.target = "hyprland-session.target";
|
|
|
|
programs.waybar = {
|
|
enable = true;
|
|
systemd.enable = true;
|
|
|
|
settings.mainBar = {
|
|
layer = "top";
|
|
position = "top";
|
|
height = 30;
|
|
spacing = 6;
|
|
|
|
modules-left = [ "hyprland/workspaces" ];
|
|
modules-center = [ "clock" ];
|
|
modules-right = lib.optionals isMacbook [ "battery" ] ++ [ "group/tray-drawer" ];
|
|
|
|
"hyprland/workspaces" = {
|
|
format = "{name}";
|
|
on-click = "activate";
|
|
sort-by-number = true;
|
|
};
|
|
|
|
clock = {
|
|
format = "{:%H:%M}";
|
|
tooltip-format = "<big>{:%A, %d %B %Y}</big>\n<tt><small>{calendar}</small></tt>";
|
|
};
|
|
|
|
"group/tray-drawer" = {
|
|
orientation = "horizontal";
|
|
drawer = {
|
|
transition-duration = 500;
|
|
transition-left-to-right = false;
|
|
};
|
|
modules = [ "custom/tray-handle" "pulseaudio" "tray" ];
|
|
};
|
|
|
|
"custom/tray-handle" = {
|
|
format = builtins.fromJSON ''"\ue0b2"''; # U+E0B2 Nerd Font powerline filled left-arrow
|
|
tooltip = false;
|
|
};
|
|
|
|
# Pulseaudio module, now conditionally visible
|
|
pulseaudio = {
|
|
format = "{icon} {volume}%";
|
|
format-muted = " muted";
|
|
format-icons = {
|
|
default = [ "" "" "" ];
|
|
headphone = "";
|
|
headset = "";
|
|
};
|
|
on-click = "pavucontrol";
|
|
scroll-step = 5;
|
|
};
|
|
|
|
# Tray module, now conditionally visible
|
|
tray = {
|
|
icon-size = 16;
|
|
spacing = 8;
|
|
};
|
|
} // lib.optionalAttrs isMacbook {
|
|
battery = {
|
|
format = "{capacity}% {icon}";
|
|
format-charging = "{capacity}% ";
|
|
format-icons = [ "" "" "" "" "" ];
|
|
states = { warning = 30; critical = 15; };
|
|
};
|
|
};
|
|
|
|
style = ''
|
|
* {
|
|
font-family: "FiraMono Nerd Font", monospace;
|
|
font-size: 13px;
|
|
min-height: 0;
|
|
border: none;
|
|
border-radius: 0;
|
|
}
|
|
|
|
window#waybar {
|
|
background: alpha(@base00, 0.82);
|
|
color: @base05;
|
|
}
|
|
|
|
#workspaces {
|
|
margin-left: 6px;
|
|
}
|
|
|
|
#workspaces button {
|
|
padding: 0 8px;
|
|
color: @base03;
|
|
background: transparent;
|
|
}
|
|
|
|
#workspaces button.active {
|
|
color: @base05;
|
|
}
|
|
|
|
#workspaces button:hover {
|
|
background: alpha(@base05, 0.08);
|
|
color: @base05;
|
|
box-shadow: none;
|
|
text-shadow: none;
|
|
}
|
|
|
|
#clock {
|
|
color: @base05;
|
|
font-weight: 500;
|
|
}
|
|
|
|
#pulseaudio,
|
|
#tray {
|
|
padding: 0 10px;
|
|
color: @base05;
|
|
}
|
|
|
|
#pulseaudio.muted,
|
|
#network.disconnected {
|
|
color: @base03;
|
|
}
|
|
|
|
#tray {
|
|
margin-right: 6px;
|
|
}
|
|
|
|
#custom-tray-toggle {
|
|
padding: 0 0px;
|
|
color: @base05;
|
|
}
|
|
|
|
#battery {
|
|
padding: 0 10px;
|
|
color: @base05;
|
|
}
|
|
#battery.warning { color: @base0A; }
|
|
#battery.critical { color: @base08; }
|
|
'';
|
|
};
|
|
|
|
# The old hyprlang hyprland.conf (with `# autogenerated = 1`) is not
|
|
# managed by HM after switching to configType = "lua", so Hyprland still
|
|
# finds it and shows the "autogenerated config" banner. Remove it once on
|
|
# every activation so it can never linger.
|
|
home.activation.removeOldHyprlandConf = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
|
rm -f "${config.xdg.configHome}/hypr/hyprland.conf"
|
|
'';
|
|
};
|
|
};
|
|
}
|