sway,hyprland: convert startup apps to systemd (#73)

* home: switch hyprland and sway to new swayidle systemd service

* home: add swayosd service

* home: move swayidle and swayosd to services

* home/services: add swayidle and swayosd services

* hyprland,sway: don't start swayosd

* user playerctld as systemd service

* home: run gammastep as service for redShift"

* cleanup

* home: set swayosd and swayidle as wanted by hyprland and sway

* nix fmt

* home/services/swayidle: fixed resume command

* home/swayidle: fix command syntax

* home: better systemd defaults for swayidle and swayosd

* home: convert mako to systemd service

* home: make wayland-ipewire-idle-inhibit a systemd service

* home/waybar: use as systemd service

* home: move waybar to services

* home/desktop: convert randomWallpaper to systemd service

* migrate home options
This commit is contained in:
Aly Raffauf 2024-08-02 17:58:08 -04:00 committed by GitHub
parent 78491e655c
commit 3663469066
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 329 additions and 204 deletions

View file

@ -12,14 +12,12 @@
./kitty ./kitty
./keepassxc ./keepassxc
./librewolf ./librewolf
./mako
./nemo ./nemo
./rofi ./rofi
./swaylock ./swaylock
./thunar ./thunar
./tmux ./tmux
./vsCodium ./vsCodium
./waybar
./wlogout ./wlogout
./yazi ./yazi
./zed ./zed

View file

@ -1,28 +0,0 @@
{
config,
lib,
...
}: {
config = lib.mkIf config.ar.home.apps.mako.enable {
services.mako = {
enable = true;
anchor = "top-center";
backgroundColor = "${config.ar.home.theme.colors.background}CC";
borderColor = "${config.ar.home.theme.colors.primary}EE";
borderSize = 2;
borderRadius = 10;
defaultTimeout = 10000;
font = "${config.gtk.font.name} Regular ${toString config.gtk.font.size}";
height = 300;
layer = "top";
padding = "15";
textColor = "${config.ar.home.theme.colors.text}";
width = 400;
margin = "20,0";
extraConfig = ''
[mode=do-not-disturb]
invisible=1
'';
};
};
}

View file

@ -26,28 +26,6 @@ in {
fi fi
''; '';
idleD = let
timeouts =
["timeout 120 '${lib.getExe pkgs.brightnessctl} -s set 10' resume '${lib.getExe pkgs.brightnessctl} -r'"]
++ (
if cfg.desktop.autoSuspend
then ["timeout 600 'sleep 2 && ${lib.getExe' pkgs.systemd "systemctl"} suspend'"]
else [
"timeout 600 '${lib.getExe pkgs.swaylock}'"
"timeout 630 '${hyprctl} dispatch dpms off' resume '${hyprctl} dispatch dpms on'"
]
);
beforeSleeps =
lib.optionals cfg.desktop.autoSuspend
[
"before-sleep '${lib.getExe pkgs.playerctl} pause'"
"before-sleep '${lib.getExe pkgs.swaylock}'"
];
in
pkgs.writeShellScript "hyprland-idled"
"${lib.getExe pkgs.swayidle} -w lock '${lib.getExe pkgs.swaylock}' ${lib.strings.concatStringsSep " " (timeouts ++ beforeSleeps)}";
tablet = pkgs.writeShellScript "hyprland-tablet" '' tablet = pkgs.writeShellScript "hyprland-tablet" ''
STATE=`${lib.getExe pkgs.dconf} read /org/gnome/desktop/a11y/applications/screen-keyboard-enabled` STATE=`${lib.getExe pkgs.dconf} read /org/gnome/desktop/a11y/applications/screen-keyboard-enabled`

View file

@ -126,18 +126,8 @@ in {
exec-once = exec-once =
[ [
"${pkgs.mate.mate-polkit}/libexec/polkit-mate-authentication-agent-1" "${pkgs.mate.mate-polkit}/libexec/polkit-mate-authentication-agent-1"
(lib.getExe pkgs.mako)
(lib.getExe pkgs.waybar)
(lib.getExe pkgs.wayland-pipewire-idle-inhibit)
(lib.getExe' pkgs.playerctl "playerctld")
(lib.getExe' pkgs.swayosd "swayosd-server")
scripts.idleD
] ]
++ lib.lists.optional (cfg.desktop.redShift) ++ lib.lists.optional (!cfg.services.randomWallpaper.enable)
"${lib.getExe pkgs.gammastep} -l 33.74:-84.38"
++ lib.lists.optional (cfg.desktop.randomWallpaper)
helpers.wallpaperD
++ lib.lists.optional (!cfg.desktop.randomWallpaper)
"${lib.getExe pkgs.swaybg} -i ${cfg.theme.wallpaper}"; "${lib.getExe pkgs.swaybg} -i ${cfg.theme.wallpaper}";
input = { input = {

View file

@ -1,31 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.ar.home;
swaymsg = lib.getExe' config.wayland.windowManager.sway.package "swaymsg";
in {
idleD = let
timeouts =
["timeout 120 '${lib.getExe pkgs.brightnessctl} -s set 10' resume '${lib.getExe pkgs.brightnessctl} -r'"]
++ (
if cfg.desktop.autoSuspend
then ["timeout 600 'sleep 2 && ${lib.getExe' pkgs.systemd "systemctl"} suspend'"]
else [
"timeout 600 '${lib.getExe pkgs.swaylock}'"
"timeout 630 '${swaymsg} \"output * dpms off\"' resume '${swaymsg} \"output * dpms on\"'"
]
);
beforeSleeps =
lib.optionals cfg.desktop.autoSuspend
[
"before-sleep '${lib.getExe pkgs.playerctl} pause'"
"before-sleep '${lib.getExe pkgs.swaylock}'"
];
in
pkgs.writeShellScript "sway-idled"
"${lib.getExe pkgs.swayidle} -w lock '${lib.getExe pkgs.swaylock}' ${lib.strings.concatStringsSep " " (timeouts ++ beforeSleeps)}";
}

View file

@ -5,7 +5,6 @@
... ...
}: let }: let
cfg = config.ar.home; cfg = config.ar.home;
scripts = import ./scripts.nix {inherit config lib pkgs;};
helpers = import ../wayland/helpers.nix {inherit config lib pkgs;}; helpers = import ../wayland/helpers.nix {inherit config lib pkgs;};
modifier = "Mod4"; modifier = "Mod4";
in { in {
@ -15,7 +14,7 @@ in {
wrapperFeatures.gtk = true; wrapperFeatures.gtk = true;
config = { config = {
bars = [{command = lib.getExe pkgs.waybar;}]; bars = [];
modifier = modifier; modifier = modifier;
colors = { colors = {
@ -159,17 +158,9 @@ in {
startup = startup =
[ [
{command = "${pkgs.mate.mate-polkit}/libexec/polkit-mate-authentication-agent-1";} {command = "${pkgs.mate.mate-polkit}/libexec/polkit-mate-authentication-agent-1";}
{command = "${scripts.idleD}";}
{command = lib.getExe pkgs.autotiling;} {command = lib.getExe pkgs.autotiling;}
{command = lib.getExe pkgs.mako;}
{command = lib.getExe pkgs.wayland-pipewire-idle-inhibit;}
{command = lib.getExe' pkgs.playerctl "playerctld";}
{command = lib.getExe' pkgs.swayosd "swayosd-server";}
] ]
++ lib.optional cfg.desktop.redShift ++ lib.optional (!cfg.services.randomWallpaper.enable) {command = "${lib.getExe pkgs.swaybg} -i ${cfg.theme.wallpaper}";};
{command = "${lib.getExe pkgs.gammastep} -l 33.74:-84.38";}
++ lib.optional cfg.desktop.randomWallpaper {command = "${helpers.wallpaperD}";}
++ lib.optional (!cfg.desktop.randomWallpaper) {command = "${lib.getExe pkgs.swaybg} -i ${cfg.theme.wallpaper}";};
floating.criteria = [ floating.criteria = [
{app_id = ".blueman-manager-wrapped";} {app_id = ".blueman-manager-wrapped";}

View file

@ -5,13 +5,20 @@
... ...
}: { }: {
config = lib.mkIf (config.ar.home.desktop.hyprland.enable || config.ar.home.desktop.sway.enable) { config = lib.mkIf (config.ar.home.desktop.hyprland.enable || config.ar.home.desktop.sway.enable) {
ar.home.apps = { ar.home = {
apps = {
kitty.enable = lib.mkDefault true; kitty.enable = lib.mkDefault true;
mako.enable = lib.mkDefault true;
rofi.enable = lib.mkDefault true; rofi.enable = lib.mkDefault true;
swaylock.enable = lib.mkDefault true; swaylock.enable = lib.mkDefault true;
};
services = {
mako.enable = lib.mkDefault true;
pipewire-inhibit.enable = lib.mkDefault true;
swayidle.enable = lib.mkDefault true;
waybar.enable = lib.mkDefault true; waybar.enable = lib.mkDefault true;
}; };
};
dconf = { dconf = {
enable = true; enable = true;
@ -28,6 +35,19 @@
swayosd swayosd
]; ];
services = {
playerctld.enable = lib.mkDefault true;
swayosd.enable = lib.mkDefault true;
};
systemd.user.services.swayosd = {
Install.WantedBy = lib.mkForce ["hyprland-session.target" "sway-session.target"];
Service = {
Restart = lib.mkForce "on-failure";
RestartSec = 5;
};
};
xdg.portal = { xdg.portal = {
enable = true; enable = true;
configPackages = configPackages =

View file

@ -48,72 +48,4 @@
mute = "${bin} --output-volume=mute-toggle"; mute = "${bin} --output-volume=mute-toggle";
micMute = "${bin} --input-volume=mute-toggle"; micMute = "${bin} --input-volume=mute-toggle";
}; };
wallpaperD = pkgs.writers.writeRuby "randomWallpaperD" {} ''
require 'fileutils'
directory = "${config.xdg.dataHome}/backgrounds/"
current_pids = {}
known_monitors = {}
last_update_time = {}
update_interval = 900 # 15 minutes in seconds
def process_running?(process_name)
system("pidof #{process_name} > /dev/null 2>&1")
end
def get_outputs
if process_running?("sway")
outputs = IO.popen(["${lib.getExe' config.wayland.windowManager.sway.package "swaymsg"}", '-t', 'get_outputs', '-p']).readlines
outputs.select { |line| line.include?('Output') }.map { |line| line.split[1] }
elsif process_running?("Hyprland")
outputs = IO.popen(["${lib.getExe' config.wayland.windowManager.hyprland.package "hyprctl"}", 'monitors']).read
outputs.each_line.map { |line| line.split[1] if line.include?('Monitor') }.compact
end
end
sleep 1
if Dir.exist?(directory)
loop do
active_monitors = get_outputs
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 5 # Check for monitor changes and update intervals every 5 seconds
end
end
'';
} }

View file

@ -53,7 +53,6 @@ in {
kitty.enable = lib.mkEnableOption "Kitty terminal."; kitty.enable = lib.mkEnableOption "Kitty terminal.";
librewolf.enable = lib.mkEnableOption "Librewolf web browser."; librewolf.enable = lib.mkEnableOption "Librewolf web browser.";
mako.enable = lib.mkEnableOption "Mako notification daemon.";
nemo.enable = lib.mkOption { nemo.enable = lib.mkOption {
description = "Cinnamon Nemo file manager."; description = "Cinnamon Nemo file manager.";
@ -72,7 +71,6 @@ in {
tmux.enable = lib.mkEnableOption "Tmux shell session manager."; tmux.enable = lib.mkEnableOption "Tmux shell session manager.";
vsCodium.enable = lib.mkEnableOption "VSCodium text editor."; vsCodium.enable = lib.mkEnableOption "VSCodium text editor.";
waybar.enable = lib.mkEnableOption "Waybar wayland panel.";
wlogout.enable = lib.mkEnableOption "Wlogout session prompt."; wlogout.enable = lib.mkEnableOption "Wlogout session prompt.";
yazi.enable = lib.mkEnableOption "Yazi terminal file manager."; yazi.enable = lib.mkEnableOption "Yazi terminal file manager.";
@ -114,18 +112,6 @@ in {
type = lib.types.bool; type = lib.types.bool;
}; };
randomWallpaper = lib.mkOption {
description = "Whether to enable random wallpaper script.";
default = cfg.desktop.hyprland.enable || cfg.desktop.sway.enable;
type = lib.types.bool;
};
redShift = lib.mkOption {
description = "Whether to redshift display colors at night.";
default = cfg.desktop.hyprland.enable || cfg.desktop.sway.enable;
type = lib.types.bool;
};
hyprland = { hyprland = {
enable = lib.mkOption { enable = lib.mkOption {
description = "Hyprland with full desktop session components."; description = "Hyprland with full desktop session components.";
@ -196,6 +182,19 @@ in {
}; };
services = { services = {
easyeffects = {
enable = lib.mkEnableOption "EasyEffects user service.";
preset = lib.mkOption {
description = "Name of preset to start with.";
default = "";
type = lib.types.str;
};
};
gammastep.enable = lib.mkEnableOption "Gammastep redshift daemon.";
mako.enable = lib.mkEnableOption "Mako notification daemon.";
mpd = { mpd = {
enable = lib.mkEnableOption "MPD user service."; enable = lib.mkEnableOption "MPD user service.";
@ -206,15 +205,10 @@ in {
}; };
}; };
easyeffects = { pipewire-inhibit.enable = lib.mkEnableOption "Inhibit idle when audio is playing with Pipewire.";
enable = lib.mkEnableOption "EasyEffects user service."; randomWallpaper.enable = lib.mkEnableOption "Lightweight swaybg-based random wallpaper daemon.";
swayidle.enable = lib.mkEnableOption "Swayidle idle daemon.";
preset = lib.mkOption { waybar.enable = lib.mkEnableOption "Waybar wayland panel.";
description = "Name of preset to start with.";
default = "";
type = lib.types.str;
};
};
}; };
theme = { theme = {

View file

@ -1,6 +1,12 @@
{ {
imports = [ imports = [
./easyeffects ./easyeffects
./gammastep
./mako
./mpd ./mpd
./pipewire-inhibit
./randomWallpaper
./swayidle
./waybar
]; ];
} }

View file

@ -0,0 +1,15 @@
{
config,
lib,
...
}: let
cfg = config.ar.home;
in {
config = lib.mkIf cfg.services.gammastep.enable {
services.gammastep = {
enable = true;
latitude = lib.mkDefault "33.74";
longitude = lib.mkDefault "-84.38";
};
};
}

View file

@ -0,0 +1,49 @@
{
config,
lib,
pkgs,
...
}: {
config = lib.mkIf config.ar.home.services.mako.enable {
services.mako = {
enable = true;
anchor = "top-center";
backgroundColor = "${config.ar.home.theme.colors.background}CC";
borderColor = "${config.ar.home.theme.colors.primary}EE";
borderSize = 2;
borderRadius = 10;
defaultTimeout = 10000;
font = "${config.gtk.font.name} Regular ${toString config.gtk.font.size}";
height = 300;
layer = "top";
padding = "15";
textColor = "${config.ar.home.theme.colors.text}";
width = 400;
margin = "20,0";
extraConfig = ''
[mode=do-not-disturb]
invisible=1
'';
};
systemd.user.services.mako = {
Unit = {
After = "graphical-session.target";
Description = "Lightweight Wayland notification daemon";
Documentation = "man:mako(1)";
PartOf = "graphical-session.target";
};
Service = {
BusName = "org.freedesktop.Notifications";
ExecReload = ''${lib.getExe' pkgs.mako "makoctl"} reload'';
ExecStart = "${lib.getExe pkgs.mako}";
Restart = "on-failure";
RestartSec = 5;
Type = "dbus";
};
Install.WantedBy = ["hyprland-session.target" "sway-session.target"];
};
};
}

View file

@ -0,0 +1,26 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.ar.home;
in {
config = lib.mkIf cfg.services.pipewire-inhibit.enable {
systemd.user.services.pipewire-inhibit-idle = {
Unit = {
After = "graphical-session.target";
Description = "inhibit idle when audio is playing with Pipewire.";
PartOf = "graphical-session.target";
};
Service = {
ExecStart = lib.getExe pkgs.wayland-pipewire-idle-inhibit;
Restart = "on-failure";
RestartSec = 5;
};
Install.WantedBy = ["hyprland-session.target" "sway-session.target"];
};
};
}

View file

@ -0,0 +1,92 @@
{
config,
lib,
pkgs,
...
}: let
wallpaperD = pkgs.writers.writeRuby "randomWallpaperD" {} ''
require 'fileutils'
directory = "${config.xdg.dataHome}/backgrounds/"
current_pids = {}
known_monitors = {}
last_update_time = {}
update_interval = 900 # 15 minutes in seconds
def process_running?(process_name)
system("pidof #{process_name} > /dev/null 2>&1")
end
def get_outputs
if process_running?("sway")
outputs = IO.popen(["${lib.getExe' config.wayland.windowManager.sway.package "swaymsg"}", '-t', 'get_outputs', '-p']).readlines
outputs.select { |line| line.include?('Output') }.map { |line| line.split[1] }
elsif process_running?("Hyprland")
outputs = IO.popen(["${lib.getExe' config.wayland.windowManager.hyprland.package "hyprctl"}", 'monitors']).read
outputs.each_line.map { |line| line.split[1] if line.include?('Monitor') }.compact
end
end
sleep 1
if Dir.exist?(directory)
loop do
active_monitors = get_outputs
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 5 # Check for monitor changes and update intervals every 5 seconds
end
end
'';
in {
config = lib.mkIf config.ar.home.services.randomWallpaper.enable {
systemd.user.services.randomWallpaper = {
Unit = {
After = "graphical-session.target";
Description = "Lightweight swaybg-based random wallpaper daemon.";
PartOf = "graphical-session.target";
};
Service = {
ExecStart = "${wallpaperD}";
Restart = "on-failure";
RestartSec = 5;
};
Install.WantedBy = ["hyprland-session.target" "sway-session.target"];
};
};
}

View file

@ -0,0 +1,73 @@
{
config,
lib,
pkgs,
...
}: let
cfg = config.ar.home;
hyprctl = lib.getExe' config.wayland.windowManager.hyprland.package "hyprctl";
swaymsg = lib.getExe' config.wayland.windowManager.sway.package "swaymsg";
in {
config = lib.mkIf cfg.services.swayidle.enable {
services.swayidle = {
enable = true;
events = [
{
event = "before-sleep";
command = "${lib.getExe pkgs.playerctl} pause";
}
{
event = "before-sleep";
command = "${pkgs.swaylock}/bin/swaylock";
}
{
event = "lock";
command = "${pkgs.swaylock}/bin/swaylock";
}
];
timeouts =
[
{
timeout = 120;
command = "${lib.getExe pkgs.brightnessctl} -s set 10";
resumeCommand = "${lib.getExe pkgs.brightnessctl} -r";
}
{
timeout = 600;
command = "${pkgs.swaylock}/bin/swaylock";
}
]
++ lib.optional cfg.desktop.autoSuspend {
timeout = 600;
command = "${lib.getExe' pkgs.systemd "systemctl"} suspend";
}
++ lib.optional (!cfg.desktop.autoSuspend)
{
timeout = 600;
command = "${pkgs.swaylock}/bin/swaylock";
}
++ lib.optional (!cfg.desktop.autoSuspend && cfg.desktop.hyprland.enable)
{
timeout = 630;
command = "${hyprctl} dispatch dpms off";
resumeCommand = "${hyprctl} dispatch dpms on";
}
++ lib.optional (!cfg.desktop.autoSuspend && cfg.desktop.sway.enable)
{
timeout = 630;
command = "${swaymsg} \"output * dpms off\"";
resumeCommand = "${swaymsg} \"output * dpms on\"";
};
};
systemd.user.services.swayidle = {
Install.WantedBy = lib.mkForce ["hyprland-session.target" "sway-session.target"];
Service = {
Restart = lib.mkForce "on-failure";
RestartSec = 5;
};
};
};
}

View file

@ -4,9 +4,10 @@
pkgs, pkgs,
... ...
}: { }: {
config = lib.mkIf config.ar.home.apps.waybar.enable { config = lib.mkIf config.ar.home.services.waybar.enable {
programs.waybar = { programs.waybar = {
enable = true; enable = true;
settings = { settings = {
mainBar = { mainBar = {
height = 32; height = 32;
@ -225,6 +226,16 @@
}; };
}; };
}; };
systemd.enable = true;
};
systemd.user.services.waybar = {
Install.WantedBy = lib.mkForce ["hyprland-session.target" "sway-session.target"];
Service = {
Restart = lib.mkForce "on-failure";
RestartSec = 5;
};
}; };
xdg.configFile."waybar/style.css".text = '' xdg.configFile."waybar/style.css".text = ''

View file

@ -106,6 +106,11 @@ in {
editor = config.ar.home.apps.zed.package; editor = config.ar.home.apps.zed.package;
}; };
services = {
gammastep.enable = true;
randomWallpaper.enable = true;
};
theme = { theme = {
enable = true; enable = true;
wallpaper = "${config.xdg.dataHome}/backgrounds/wallhaven-5g6g33.jpg"; wallpaper = "${config.xdg.dataHome}/backgrounds/wallhaven-5g6g33.jpg";

View file

@ -50,7 +50,11 @@ self: {
"desc:HP Inc. HP 24mh 3CM037248S,preferred,-1920x0,auto" "desc:HP Inc. HP 24mh 3CM037248S,preferred,-1920x0,auto"
"desc:LG Electronics LG IPS QHD 109NTWG4Y865,preferred,-2560x0,auto" "desc:LG Electronics LG IPS QHD 109NTWG4Y865,preferred,-2560x0,auto"
]; ];
randomWallpaper = false; };
services = {
gammastep.enable = true;
randomWallpaper.enable = false;
}; };
theme = { theme = {