home/services: set PATH env vars (#103)

* mako: setup binPath

* swayidle: setup binPath

* randomWallpaper: make bin PATH and move script to separate file

* waybar: setup binPath

* hyprland,sway: don't import all vars for systemd services
This commit is contained in:
Aly Raffauf 2024-08-29 21:04:57 -04:00 committed by GitHub
parent 84615ef784
commit 069576df3d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 206 additions and 150 deletions

View file

@ -10,11 +10,7 @@ in {
wayland.windowManager.hyprland = { wayland.windowManager.hyprland = {
enable = true; enable = true;
settings = import ./settings.nix {inherit config lib pkgs;}; settings = import ./settings.nix {inherit config lib pkgs;};
systemd.enable = true;
systemd = {
enable = true;
variables = ["--all"];
};
extraConfig = let extraConfig = let
moveMonitorBinds = moveMonitorBinds =

View file

@ -23,8 +23,6 @@ in {
"systemctl --user stop sway-session.target" "systemctl --user stop sway-session.target"
"systemctl --user start sway-session.target" "systemctl --user start sway-session.target"
]; ];
variables = ["--all"];
}; };
config = { config = {

View file

@ -25,7 +25,7 @@ in {
width = 400; width = 400;
extraConfig = '' extraConfig = ''
on-notify=exec ${lib.getExe pkgs.mpv} ${pkgs.sound-theme-freedesktop}/share/sounds/freedesktop/stereo/message.oga on-notify=exec mpv ${pkgs.sound-theme-freedesktop}/share/sounds/freedesktop/stereo/message.oga
outer-margin=20 outer-margin=20
[mode=do-not-disturb] [mode=do-not-disturb]
@ -44,6 +44,7 @@ in {
Service = { Service = {
BusName = "org.freedesktop.Notifications"; BusName = "org.freedesktop.Notifications";
Environment = ["PATH=${lib.makeBinPath [pkgs.bash pkgs.mpv]}"];
ExecReload = ''${lib.getExe' pkgs.mako "makoctl"} reload''; ExecReload = ''${lib.getExe' pkgs.mako "makoctl"} reload'';
ExecStart = "${lib.getExe pkgs.mako}"; ExecStart = "${lib.getExe pkgs.mako}";
Restart = lib.mkForce "no"; Restart = lib.mkForce "no";

View file

@ -4,86 +4,7 @@
pkgs, pkgs,
... ...
}: let }: let
wallpaperD = pkgs.writers.writeRuby "randomWallpaperD" {} '' wallpaperD = pkgs.writers.writeRuby "randomWallpaperD" {} (builtins.readFile ./script.rb);
require 'fileutils'
directory = "${config.xdg.dataHome}/backgrounds/"
current_pids = {}
known_monitors = {}
last_update_time = {}
update_interval = 900 # 15 minutes in seconds
xdg_runtime_dir = ENV['XDG_RUNTIME_DIR']
hyprland_instance_signature = ENV['HYPRLAND_INSTANCE_SIGNATURE']
sway_sock = ENV['SWAYSOCK']
hyprland_lock_path = nil
unless hyprland_instance_signature.nil?
hyprland_lock_path = File.join(xdg_runtime_dir, 'hypr', hyprland_instance_signature, 'hyprland.lock')
end
def wm_dead? (hyprland_lock_path, sway_sock)
sway_running = system("pidof sway > /dev/null")
hypr_running = system("pidof Hyprland > /dev/null")
(hyprland_lock_path.nil? || !File.exist?(hyprland_lock_path) || !hypr_running) && (sway_sock.nil? || !File.exist?(sway_sock) || !sway_running)
end
def get_outputs
hyprctl = IO.popen(["${lib.getExe' config.wayland.windowManager.hyprland.package "hyprctl"}", 'monitors']).read
swaymsg = IO.popen(["${lib.getExe' config.wayland.windowManager.sway.package "swaymsg"}", '-t', 'get_outputs', '-p']).readlines
hypr_outputs = hyprctl.each_line.map { |line| line.split[1] if line.include?('Monitor') }.compact
sway_outputs = swaymsg.select { |line| line.include?('Output') }.map { |line| line.split[1] }
return (sway_outputs | hypr_outputs)
end
sleep 1
loop do
active_monitors = get_outputs
break if wm_dead? hyprland_lock_path, sway_sock
next if active_monitors.empty?
added_monitors = active_monitors - known_monitors.keys
removed_monitors = known_monitors.keys - active_monitors
# Handle newly added monitors
added_monitors.each do |monitor|
random_background = Dir.glob(File.join(directory, '*.{png,jpg}')).sample
pid = spawn("${lib.getExe pkgs.swaybg}", '-o', monitor, '-i', random_background, '-m', 'fill')
current_pids[monitor] = pid
last_update_time[monitor] = Time.now
known_monitors[monitor] = random_background
end
# Remove wallpapers from removed monitors
removed_monitors.each do |monitor|
Process.kill('TERM', current_pids[monitor]) if current_pids[monitor]
current_pids.delete(monitor)
last_update_time.delete(monitor)
known_monitors.delete(monitor)
end
# Update wallpapers after the set interval
active_monitors.each do |monitor|
if Time.now - last_update_time[monitor] >= update_interval
random_background = Dir.glob(File.join(directory, '*.{png,jpg}')).sample
pid = spawn("${lib.getExe pkgs.swaybg}", '-o', monitor, '-i', random_background, '-m', 'fill')
sleep 1
Process.kill('TERM', current_pids[monitor]) if current_pids[monitor]
current_pids[monitor] = pid
last_update_time[monitor] = Time.now
known_monitors[monitor] = random_background
end
end
sleep 3
end
'';
in { in {
config = lib.mkIf config.ar.home.services.randomWallpaper.enable { config = lib.mkIf config.ar.home.services.randomWallpaper.enable {
services.hyprpaper.enable = lib.mkForce false; services.hyprpaper.enable = lib.mkForce false;
@ -99,8 +20,20 @@ in {
}; };
Service = { Service = {
Environment = [
"PATH=${
lib.makeBinPath [
config.wayland.windowManager.hyprland.package
config.wayland.windowManager.sway.package
pkgs.procps
pkgs.swaybg
]
}"
];
ExecStart = "${wallpaperD}"; ExecStart = "${wallpaperD}";
Restart = "no"; Restart = "no";
TasksMax = "infinity";
}; };
Install.WantedBy = lib.optional (config.ar.home.desktop.hyprland.enable) "hyprland-session.target" ++ lib.optional (config.ar.home.desktop.sway.enable) "sway-session.target"; Install.WantedBy = lib.optional (config.ar.home.desktop.hyprland.enable) "hyprland-session.target" ++ lib.optional (config.ar.home.desktop.sway.enable) "sway-session.target";

View file

@ -0,0 +1,82 @@
#!/usr/bin/env ruby
require "fileutils"
# Set the wallpaper directory to the first argument if it exists, else use the default value
directory = ARGV[0] || File.expand_path("~/.local/share/backgrounds")
current_pids = {}
known_monitors = {}
last_update_time = {}
update_interval = 900 # 15 minutes in seconds
xdg_runtime_dir = ENV["XDG_RUNTIME_DIR"]
hyprland_instance_signature = ENV["HYPRLAND_INSTANCE_SIGNATURE"]
sway_sock = ENV["SWAYSOCK"]
hyprland_lock_path = nil
unless hyprland_instance_signature.nil?
hyprland_lock_path = File.join(xdg_runtime_dir, "hypr", hyprland_instance_signature, "hyprland.lock")
end
def wm_dead?(hyprland_lock_path, sway_sock)
sway_running = system("pidof sway > /dev/null")
hypr_running = system("pidof Hyprland > /dev/null")
(hyprland_lock_path.nil? || !File.exist?(hyprland_lock_path) || !hypr_running) && (sway_sock.nil? || !File.exist?(sway_sock) || !sway_running)
end
def get_outputs
hyprctl = IO.popen(["hyprctl", "monitors"]).read
swaymsg = IO.popen(["swaymsg", "-t", "get_outputs", "-p"]).readlines
hypr_outputs = hyprctl.each_line.map { |line| line.split[1] if line.include?("Monitor") }.compact
sway_outputs = swaymsg.select { |line| line.include?("Output") }.map { |line| line.split[1] }
return (sway_outputs | hypr_outputs)
end
sleep 1
loop do
active_monitors = get_outputs
break if wm_dead? hyprland_lock_path, sway_sock
next if active_monitors.empty?
added_monitors = active_monitors - known_monitors.keys
removed_monitors = known_monitors.keys - active_monitors
# Handle newly added monitors
added_monitors.each do |monitor|
random_background = Dir.glob(File.join(directory, "*.{png,jpg}")).sample
pid = spawn("swaybg", "-o", monitor, "-i", random_background, "-m", "fill")
current_pids[monitor] = pid
last_update_time[monitor] = Time.now
known_monitors[monitor] = random_background
end
# Remove wallpapers from removed monitors
removed_monitors.each do |monitor|
Process.kill("TERM", current_pids[monitor]) if current_pids[monitor]
current_pids.delete(monitor)
last_update_time.delete(monitor)
known_monitors.delete(monitor)
end
# Update wallpapers after the set interval
active_monitors.each do |monitor|
if Time.now - last_update_time[monitor] >= update_interval
random_background = Dir.glob(File.join(directory, "*.{png,jpg}")).sample
pid = spawn("swaybg", "-o", monitor, "-i", random_background, "-m", "fill")
sleep 1
Process.kill("TERM", current_pids[monitor]) if current_pids[monitor]
current_pids[monitor] = pid
last_update_time[monitor] = Time.now
known_monitors[monitor] = random_background
end
end
sleep 3
end

View file

@ -5,8 +5,6 @@
... ...
}: let }: let
cfg = config.ar.home; cfg = config.ar.home;
hyprctl = lib.getExe' config.wayland.windowManager.hyprland.package "hyprctl";
swaymsg = lib.getExe' config.wayland.windowManager.sway.package "swaymsg";
in { in {
config = lib.mkIf cfg.services.swayidle.enable { config = lib.mkIf cfg.services.swayidle.enable {
services.swayidle = { services.swayidle = {
@ -15,15 +13,15 @@ in {
events = [ events = [
{ {
event = "before-sleep"; event = "before-sleep";
command = "${lib.getExe pkgs.playerctl} pause"; command = "playerctl pause";
} }
{ {
event = "before-sleep"; event = "before-sleep";
command = "${lib.getExe pkgs.swaylock} && ${lib.getExe' pkgs.coreutils "sleep"} 2"; command = "swaylock && sleep 2";
} }
{ {
event = "lock"; event = "lock";
command = "${lib.getExe pkgs.swaylock}"; command = "swaylock";
} }
]; ];
@ -31,36 +29,54 @@ in {
[ [
{ {
timeout = 120; timeout = 120;
command = "${lib.getExe pkgs.brightnessctl} -s set 10"; command = "brightnessctl -s set 10";
resumeCommand = "${lib.getExe pkgs.brightnessctl} -r"; resumeCommand = "brightnessctl -r";
} }
] ]
++ lib.optional cfg.desktop.autoSuspend { ++ lib.optional cfg.desktop.autoSuspend {
timeout = 600; timeout = 600;
command = "${lib.getExe' pkgs.systemd "systemctl"} suspend"; command = "systemctl suspend";
} }
++ lib.optional (!cfg.desktop.autoSuspend) ++ lib.optional (!cfg.desktop.autoSuspend)
{ {
timeout = 600; timeout = 600;
command = "${lib.getExe pkgs.swaylock}"; command = "swaylock";
} }
++ lib.optional (!cfg.desktop.autoSuspend && cfg.desktop.hyprland.enable) ++ lib.optional (!cfg.desktop.autoSuspend && cfg.desktop.hyprland.enable)
{ {
timeout = 630; timeout = 630;
command = "${hyprctl} dispatch dpms off"; command = "hyprctl dispatch dpms off";
resumeCommand = "${hyprctl} dispatch dpms on"; resumeCommand = "hyprctl dispatch dpms on";
} }
++ lib.optional (!cfg.desktop.autoSuspend && cfg.desktop.sway.enable) ++ lib.optional (!cfg.desktop.autoSuspend && cfg.desktop.sway.enable)
{ {
timeout = 630; timeout = 630;
command = "${swaymsg} \"output * dpms off\""; command = "swaymsg \"output * dpms off\"";
resumeCommand = "${swaymsg} \"output * dpms on\""; resumeCommand = "swaymsg \"output * dpms on\"";
}; };
}; };
systemd.user.services.swayidle = { systemd.user.services.swayidle = {
Install.WantedBy = lib.mkForce (lib.optional (cfg.desktop.hyprland.enable) "hyprland-session.target" ++ lib.optional (cfg.desktop.sway.enable) "sway-session.target"); Install.WantedBy = lib.mkForce (lib.optional (cfg.desktop.hyprland.enable) "hyprland-session.target" ++ lib.optional (cfg.desktop.sway.enable) "sway-session.target");
Service.Restart = lib.mkForce "no";
Service = {
Environment = lib.mkForce [
"PATH=${
lib.makeBinPath ((with pkgs; [
bash
brightnessctl
coreutils
playerctl
swaylock
systemd
])
++ lib.optional (cfg.desktop.hyprland.enable) config.wayland.windowManager.hyprland.package
++ lib.optional (cfg.desktop.sway.enable) config.wayland.windowManager.sway.package)
}"
];
Restart = lib.mkForce "no";
};
Unit.BindsTo = lib.optional (cfg.desktop.hyprland.enable) "hyprland-session.target" ++ lib.optional (cfg.desktop.sway.enable) "sway-session.target"; Unit.BindsTo = lib.optional (cfg.desktop.hyprland.enable) "hyprland-session.target" ++ lib.optional (cfg.desktop.sway.enable) "sway-session.target";
}; };
}; };

View file

@ -50,8 +50,7 @@ in {
}; };
"hyprland/submap" = { "hyprland/submap" = {
on-click = ''${lib.getExe' on-click = ''hyprctl dispatch submap reset'';
config.wayland.windowManager.hyprland.package "hyprctl"} dispatch submap reset'';
}; };
"sway/workspaces" = { "sway/workspaces" = {
@ -68,21 +67,20 @@ in {
}; };
"sway/mode" = { "sway/mode" = {
on-click = ''${lib.getExe' config.wayland.windowManager.sway.package "swaymsg"} mode default''; on-click = ''swaymsg mode default'';
}; };
"sway/scratchpad" = { "sway/scratchpad" = {
format = "{icon} {count}"; format = "{icon} {count}";
format-icons = ["" ""]; format-icons = ["" ""];
on-click = "${lib.getExe' config.wayland.windowManager.sway.package "swaymsg"} scratchpad show"; on-click = "swaymsg scratchpad show";
show-empty = false; show-empty = false;
tooltip = true; tooltip = true;
tooltip-format = "{app}: {title}"; tooltip-format = "{app}: {title}";
}; };
"custom/app-close" = { "custom/app-close" = {
on-click = ''${lib.getExe' on-click = ''hyprctl dispatch killactive || swaymsg kill'';
config.wayland.windowManager.hyprland.package "hyprctl"} dispatch killactive || ${lib.getExe' config.wayland.windowManager.sway.package "swaymsg"} kill'';
format = "󰅗"; format = "󰅗";
tooltip-format = "Close the focused window."; tooltip-format = "Close the focused window.";
}; };
@ -94,25 +92,7 @@ in {
}; };
battery = let battery = let
checkBattery = pkgs.writeShellScript "check-battery" '' checkBattery = pkgs.writeShellScript "check-battery" (builtins.readFile ./scripts/check-battery.sh);
if [ -d /sys/class/power_supply/BAT0 ]; then
BAT=/sys/class/power_supply/BAT0
elif [ -d /sys/class/power_supply/BAT1 ]; then
BAT=/sys/class/power_supply/BAT1
else
echo "No battery found."
exit 1
fi
CRIT=''${1:-10}
NOTIFY=${lib.getExe' pkgs.libnotify "notify-send"}
stat=$(${lib.getExe' pkgs.coreutils "cat"} $BAT/status)
perc=$(${lib.getExe' pkgs.coreutils "cat"} $BAT/capacity)
if [[ $perc -le $CRIT ]] && [[ $stat == "Discharging" ]]; then
$NOTIFY --urgency=critical --icon=dialog-error "Battery Critical" "Current charge: $perc%".
fi
'';
in { in {
format = "{icon}"; format = "{icon}";
format-icons = ["󰁺" "󰁻" "󰁼" "󰁽" "󰁾" "󰁿" "󰂀" "󰂁" "󰂂" "󰁹"]; format-icons = ["󰁺" "󰁻" "󰁼" "󰁽" "󰁾" "󰁿" "󰂀" "󰂁" "󰂂" "󰁹"];
@ -148,7 +128,7 @@ in {
format = ""; format = "";
format-connected = " {num_connections}"; format-connected = " {num_connections}";
format-disabled = ""; # an empty format will hide the module format-disabled = ""; # an empty format will hide the module
on-clic = lib.getExe' pkgs.blueberry "blueberry"; on-click = "blueberry";
tooltip-format = "{controller_alias} {controller_address}"; tooltip-format = "{controller_alias} {controller_address}";
tooltip-format-connected = '' tooltip-format-connected = ''
@ -172,7 +152,7 @@ in {
}; };
ignored-sinks = ["Easy Effects Sink"]; ignored-sinks = ["Easy Effects Sink"];
on-click = "${lib.getExe pkgs.pavucontrol} -t 3"; on-click = "pavucontrol -t 3";
scroll-step = 5; scroll-step = 5;
}; };
@ -182,7 +162,7 @@ in {
format-ethernet = "󰈀"; format-ethernet = "󰈀";
format-icons = ["󰤟" "󰤢" "󰤥" "󰤨"]; format-icons = ["󰤟" "󰤢" "󰤥" "󰤨"];
format-wifi = "{icon}"; format-wifi = "{icon}";
on-click = "${lib.getExe pkgs.networkmanager_dmenu} -i"; on-click = "networkmanager_dmenu -i";
tooltip-format = "{ifname} via {gwaddr} 󰊗"; tooltip-format = "{ifname} via {gwaddr} 󰊗";
tooltip-format-disconnected = "Disconnected"; tooltip-format-disconnected = "Disconnected";
tooltip-format-ethernet = "{ifname} "; tooltip-format-ethernet = "{ifname} ";
@ -192,23 +172,8 @@ in {
tray = {spacing = 15;}; tray = {spacing = 15;};
"custom/dnd" = let "custom/dnd" = let
mako-dnd = pkgs.writeShellScript "mako-dnd" '' mako-dnd =
show() { pkgs.writeShellScript "mako-dnd" (builtins.readFile ./scripts/mako-dnd.sh);
MAKO_MODE=$(${lib.getExe' pkgs.mako "makoctl"} mode)
if ${lib.getExe' pkgs.coreutils "echo"} "$MAKO_MODE" | ${lib.getExe' pkgs.gnugrep "grep"} -q "do-not-disturb"; then
${lib.getExe' pkgs.coreutils "printf"} '{"text": "󰂛", "class": "on", "tooltip": "Notifications snoozed."}\n'
else
${lib.getExe' pkgs.coreutils "printf"} '{"text": "󰂚", "class": "off","tooltip": "Notifications enabled."}\n'
fi
}
toggle() {
${lib.getExe' pkgs.mako "makoctl"} mode -t do-not-disturb
${lib.getExe' pkgs.procps "pkill"} -SIGRTMIN+2 .waybar-wrapped
}
[ $# -gt 0 ] && toggle || show
'';
in { in {
exec = "${mako-dnd}"; exec = "${mako-dnd}";
interval = "once"; interval = "once";
@ -219,13 +184,13 @@ in {
"custom/logout" = { "custom/logout" = {
format = "󰤆"; format = "󰤆";
on-click = ''${lib.getExe config.programs.rofi.package} -i -show power-menu -modi "power-menu:${lib.getExe pkgs.rofi-power-menu} --choices=logout/lockscreen/suspend/shutdown/reboot"''; on-click = ''rofi -i -show power-menu -modi "power-menu:rofi-power-menu --choices=logout/lockscreen/suspend/shutdown/reboot"'';
tooltip-format = "Manage your session."; tooltip-format = "Manage your session.";
}; };
"custom/menu" = { "custom/menu" = {
format = "󰀻"; format = "󰀻";
on-click = "${lib.getExe pkgs.nwg-drawer}"; on-click = "nwg-drawer";
tooltip-format = "Touch-friendly application menu."; tooltip-format = "Touch-friendly application menu.";
}; };
@ -354,7 +319,37 @@ in {
systemd.user.services.waybar = { systemd.user.services.waybar = {
Install.WantedBy = lib.mkForce (lib.optional (cfg.desktop.hyprland.enable) "hyprland-session.target" ++ lib.optional (cfg.desktop.sway.enable) "sway-session.target"); Install.WantedBy = lib.mkForce (lib.optional (cfg.desktop.hyprland.enable) "hyprland-session.target" ++ lib.optional (cfg.desktop.sway.enable) "sway-session.target");
Service.Restart = lib.mkForce "no";
Service = {
Environment = lib.mkForce [
"PATH=${
lib.makeBinPath ([
config.programs.rofi.package
config.wayland.windowManager.hyprland.package
config.wayland.windowManager.sway.package
]
++ (with pkgs; [
blueberry
bluez
coreutils
getopt
gnugrep
libnotify
mako
networkmanager
networkmanager_dmenu
nwg-drawer
pavucontrol
procps
rofi-power-menu
systemd
]))
}"
];
Restart = lib.mkForce "no";
};
Unit.BindsTo = lib.optional (cfg.desktop.hyprland.enable) "hyprland-session.target" ++ lib.optional (cfg.desktop.sway.enable) "sway-session.target"; Unit.BindsTo = lib.optional (cfg.desktop.hyprland.enable) "hyprland-session.target" ++ lib.optional (cfg.desktop.sway.enable) "sway-session.target";
}; };

View file

@ -0,0 +1,18 @@
#!/usr/bin/env bash
if [ -d /sys/class/power_supply/BAT0 ]; then
BAT=/sys/class/power_supply/BAT0
elif [ -d /sys/class/power_supply/BAT1 ]; then
BAT=/sys/class/power_supply/BAT1
else
echo "No battery found."
exit 1
fi
CRIT=''${1:-10}
STAT=$(cat $BAT/status)
PERC=$(cat $BAT/capacity)
if [[ $PERC -le $CRIT ]] && [[ $STAT == "Discharging" ]]; then
notify-send --urgency=critical --icon=dialog-error "Battery Critical" "Current charge: $PERC%".
fi

View file

@ -0,0 +1,17 @@
#!/usr/bin/env bash
show() {
MAKO_MODE=$(makoctl mode)
if echo "$MAKO_MODE" | grep -q "do-not-disturb"; then
printf '{"text": "󰂛", "class": "on", "tooltip": "Notifications snoozed."}\n'
else
printf '{"text": "󰂚", "class": "off","tooltip": "Notifications enabled."}\n'
fi
}
toggle() {
makoctl mode -t do-not-disturb
pkill -SIGRTMIN+2 .waybar-wrapped
}
[ $# -gt 0 ] && toggle || show