feat(system): comprehensive branding, styling, and system feature update

- Relocate themes to assets/themes/ and update all references.
- Implement custom SDDM theme and Plymouth theme enhancements.
- Add themed templates for Alacritty, Hyprland, Waybar, and other apps.
- Introduce Makima key remapper module and configuration.
- Add Voxtype and Walker configurations.
- Implement systemd power management and timeout optimizations.
- Add Nautilus-python extensions for LocalSend.
- Update branding assets and ASCII art integration.
This commit is contained in:
Bernardo Magri
2026-04-05 10:52:41 +01:00
parent 9d5049aed5
commit 514b305713
465 changed files with 3770 additions and 578 deletions

View File

@@ -0,0 +1,18 @@
#!/bin/bash
# Check if hibernation is supported
if [[ ! -f /sys/power/image_size ]]; then
exit 1
fi
# Sum all swap sizes (excluding zram)
SWAPSIZE_KB=$(awk '!/Filename|zram/ {sum += $3} END {print sum+0}' /proc/swaps)
SWAPSIZE=$(( 1024 * ${SWAPSIZE_KB:-0} ))
HIBERNATION_IMAGE_SIZE=$(cat /sys/power/image_size)
if (( SWAPSIZE > HIBERNATION_IMAGE_SIZE )) && [[ -f /etc/mkinitcpio.conf.d/nnomarchy_resume.conf ]]; then
exit 0
else
exit 1
fi

View File

@@ -0,0 +1,59 @@
#!/bin/bash
# Removes hibernation setup: disables swap, removes swapfile, removes fstab entry,
# removes resume hook, and removes suspend-then-hibernate configuration.
MKINITCPIO_CONF="/etc/mkinitcpio.conf.d/nnomarchy_resume.conf"
# Check if hibernation is configured
if [[ ! -f $MKINITCPIO_CONF ]] || ! grep -q "^HOOKS+=(resume)$" "$MKINITCPIO_CONF"; then
echo "Hibernation is not set up"
exit 0
fi
if ! gum confirm "Remove hibernation setup?"; then
exit 0
fi
SWAP_SUBVOLUME="/swap"
SWAP_FILE="$SWAP_SUBVOLUME/swapfile"
# Disable swap if active
if swapon --show | grep -q "$SWAP_FILE"; then
echo "Disabling swap on $SWAP_FILE"
sudo swapoff "$SWAP_FILE"
fi
# Remove swapfile
if [[ -f $SWAP_FILE ]]; then
echo "Removing swapfile"
sudo rm "$SWAP_FILE"
fi
# Remove swap subvolume
if sudo btrfs subvolume show "$SWAP_SUBVOLUME" &>/dev/null; then
echo "Removing Btrfs subvolume $SWAP_SUBVOLUME"
sudo btrfs subvolume delete "$SWAP_SUBVOLUME"
fi
# Remove fstab entry
if grep -Fq "$SWAP_FILE" /etc/fstab; then
echo "Removing swapfile from /etc/fstab"
sudo cp -a /etc/fstab "/etc/fstab.$(date +%Y%m%d%H%M%S).back"
sudo sed -i "\|$SWAP_FILE|d" /etc/fstab
sudo sed -i '/^# Btrfs swapfile for system hibernation$/d' /etc/fstab
fi
# Remove suspend-then-hibernate configuration
echo "Removing suspend-then-hibernate configuration"
sudo rm -f /etc/systemd/logind.conf.d/lid.conf
sudo rm -f /etc/systemd/sleep.conf.d/hibernate.conf
# Remove mkinitcpio resume hook
echo "Removing resume hook"
sudo rm "$MKINITCPIO_CONF"
echo "Regenerating initramfs..."
sudo limine-mkinitcpio
echo "Hibernation removed"

View File

@@ -0,0 +1,99 @@
#!/bin/bash
# Creates a swap file in the btrfs subvolume, adds the swap file to /etc/fstab,
# adds a resume hook to mkinitcpio, and configures suspend-then-hibernate.
if [[ ! -f /sys/power/image_size ]]; then
echo -e "Hibernation is not supported on your system" >&2
exit 0
fi
if ! command -v limine-mkinitcpio &>/dev/null; then
echo "Skipping hibernation setup (requires Limine bootloader)"
exit 0
fi
MKINITCPIO_CONF="/etc/mkinitcpio.conf.d/nnomarchy_resume.conf"
# Check if hibernation is already configured
if [[ -f $MKINITCPIO_CONF ]] && grep -q "^HOOKS+=(resume)$" "$MKINITCPIO_CONF"; then
echo "Hibernation is already set up"
exit 0
fi
if [[ $1 != "--force" ]]; then
MEM_TOTAL_HUMAN=$(free --human | awk '/Mem/ {print $2}')
if ! gum confirm "Use $MEM_TOTAL_HUMAN on boot drive to make hibernation available?"; then
exit 0
fi
fi
SWAP_SUBVOLUME="/swap"
SWAP_FILE="$SWAP_SUBVOLUME/swapfile"
# Create btrfs subvolume for swap
if ! sudo btrfs subvolume show "$SWAP_SUBVOLUME" &>/dev/null; then
echo "Creating Btrfs subvolume"
sudo btrfs subvolume create "$SWAP_SUBVOLUME"
sudo chattr +C "$SWAP_SUBVOLUME"
fi
# Create swapfile
if ! sudo swaplabel "$SWAP_FILE" &>/dev/null; then
echo "Creating swapfile in Btrfs subvolume"
MEM_TOTAL_KB="$(awk '/MemTotal/ {print $2}' /proc/meminfo)k"
sudo btrfs filesystem mkswapfile -s "$MEM_TOTAL_KB" "$SWAP_FILE"
fi
# Add swapfile to fstab
if ! grep -Fq "$SWAP_FILE" /etc/fstab; then
echo "Adding swapfile to /etc/fstab"
sudo cp -a /etc/fstab "/etc/fstab.$(date +%Y%m%d%H%M%S).back"
printf "\n# Btrfs swapfile for system hibernation\n%s none swap defaults,pri=0 0 0\n" "$SWAP_FILE" | sudo tee -a /etc/fstab >/dev/null
fi
# Enable swap
if ! swapon --show | grep -q "$SWAP_FILE"; then
echo "Enabling swap on $SWAP_FILE"
sudo swapon -p 0 "$SWAP_FILE"
fi
# Add resume hook to mkinitcpio
sudo mkdir -p /etc/mkinitcpio.conf.d
echo "Adding resume hook to $MKINITCPIO_CONF"
echo "HOOKS+=(resume)" | sudo tee "$MKINITCPIO_CONF" >/dev/null
# Add resume= kernel parameters so the initramfs resume hook knows where to find the
# hibernation image. Without these, resume happens late (after GPU drivers load) and fails.
RESUME_DROP_IN="/etc/limine-entry-tool.d/resume.conf"
if [[ ! -f $RESUME_DROP_IN ]]; then
echo "Adding resume kernel parameters"
sudo swapon -p 0 "$SWAP_FILE" 2>/dev/null
RESUME_DEVICE=$(findmnt -no SOURCE -T "$SWAP_FILE" | sed 's/\[.*\]//')
RESUME_OFFSET=$(sudo btrfs inspect-internal map-swapfile -r "$SWAP_FILE")
sudo mkdir -p /etc/limine-entry-tool.d
echo "KERNEL_CMDLINE[default]+=\" resume=$RESUME_DEVICE resume_offset=$RESUME_OFFSET\"" | sudo tee "$RESUME_DROP_IN" >/dev/null
sudo tee -a /etc/default/limine < "$RESUME_DROP_IN" >/dev/null
fi
# Use ACPI alarm for RTC wakeup on s2idle systems (needed for suspend-then-hibernate)
if grep -q "\[s2idle\]" /sys/power/mem_sleep 2>/dev/null; then
LIMINE_DROP_IN="/etc/limine-entry-tool.d/rtc-alarm.conf"
if [[ ! -f $LIMINE_DROP_IN ]]; then
echo "Enabling ACPI RTC alarm for s2idle suspend"
sudo mkdir -p /etc/limine-entry-tool.d
echo 'KERNEL_CMDLINE[default]+=" rtc_cmos.use_acpi_alarm=1"' | sudo tee "$LIMINE_DROP_IN" >/dev/null
sudo tee -a /etc/default/limine < "$LIMINE_DROP_IN" >/dev/null
fi
fi
# Regenerate initramfs and boot entry
echo "Regenerating initramfs..."
sudo limine-mkinitcpio
sudo limine-update
echo
if [[ $1 != "--force" ]] && gum confirm "Reboot to enable hibernation?"; then
nnomarchy-system-reboot
fi

27
bin/system/nomarchy-pkg-add Executable file
View File

@@ -0,0 +1,27 @@
#!/usr/bin/env bash
PKG_NAME="$1"
if [ -z "$PKG_NAME" ]; then
echo "Usage: nnomarchy-pkg-add <package-name>"
exit 1
fi
STATE_FILE="$HOME/.config/home-manager/user-packages.json"
mkdir -p "$(dirname "$STATE_FILE")"
if [ ! -f "$STATE_FILE" ]; then
echo "[]" > "$STATE_FILE"
fi
if jq -e ". | index(\"$PKG_NAME\")" "$STATE_FILE" >/dev/null; then
echo "Package $PKG_NAME is already in your user-packages.json"
exit 0
fi
# Append package to the JSON array
jq ". + [\"$PKG_NAME\"]" "$STATE_FILE" > "${STATE_FILE}.tmp" && mv "${STATE_FILE}.tmp" "$STATE_FILE"
echo "Package $PKG_NAME added declaratively to $STATE_FILE."
echo "Applying changes with env-update..."
env-update

27
bin/system/nomarchy-pkg-remove Executable file
View File

@@ -0,0 +1,27 @@
#!/usr/bin/env bash
PKG_NAME="$1"
if [ -z "$PKG_NAME" ]; then
echo "Usage: nnomarchy-pkg-remove <package-name>"
exit 1
fi
STATE_FILE="$HOME/.config/home-manager/user-packages.json"
if [ ! -f "$STATE_FILE" ]; then
echo "No packages managed by nnomarchy-pkg yet."
exit 0
fi
if ! jq -e ". | index(\"$PKG_NAME\")" "$STATE_FILE" >/dev/null; then
echo "Package $PKG_NAME is not in your user-packages.json"
exit 0
fi
# Remove package from the JSON array
jq ". - [\"$PKG_NAME\"]" "$STATE_FILE" > "${STATE_FILE}.tmp" && mv "${STATE_FILE}.tmp" "$STATE_FILE"
echo "Package $PKG_NAME removed declaratively from $STATE_FILE."
echo "Applying changes with env-update..."
env-update

View File

@@ -0,0 +1,7 @@
#!/bin/bash
# Unblock and restart the bluetooth service.
echo -e "Unblocking bluetooth...\n"
rfkill unblock bluetooth
rfkill list bluetooth

View File

@@ -0,0 +1,6 @@
#!/bin/bash
# Restart the PipeWire audio service to fix audio issues or apply new configuration.
echo -e "Restarting pipewire audio service...\n"
systemctl --user restart pipewire.service

View File

@@ -0,0 +1,7 @@
#!/bin/bash
# Unblock and restart the Wi-Fi service.
echo -e "Unblocking wifi...\n"
rfkill unblock wifi
rfkill list wifi

View File

@@ -0,0 +1,5 @@
#!/bin/bash
# Restart the XCompose input method service (fcitx5) to apply new compose key settings.
nnomarchy-restart-app fcitx5 --disable notificationitem

35
bin/system/nomarchy-setup-dns Executable file
View File

@@ -0,0 +1,35 @@
#!/usr/bin/env bash
# Configure DNS declaratively for Nnomarchy NixOS.
# Hybrid: updates /etc/nixos/state.json and runs sys-update.
STATE_FILE="/etc/nixos/state.json"
if [[ -z $1 ]]; then
dns=$(gum choose --height 6 --header "Select DNS provider" Cloudflare Google DHCP Custom)
else
dns=$1
fi
case "$dns" in
Cloudflare|Google|DHCP)
sudo jq ".dns = \"$dns\"" "$STATE_FILE" > /tmp/state.json && sudo mv /tmp/state.json "$STATE_FILE"
;;
Custom)
echo "Enter your DNS servers (space-separated, e.g. '192.168.1.1 1.1.1.1'):"
read -r dns_servers
if [[ -z $dns_servers ]]; then
echo "Error: No DNS servers provided."
exit 1
fi
# Convert to JSON array
dns_array=$(echo "$dns_servers" | jq -R 'split(" ")')
sudo jq ".dns = \"Custom\" | .customDns = $dns_array" "$STATE_FILE" > /tmp/state.json && sudo mv /tmp/state.json "$STATE_FILE"
;;
esac
echo "DNS configured to $dns. Applying changes..."
sudo sys-update

26
bin/system/nomarchy-setup-fido2 Executable file
View File

@@ -0,0 +1,26 @@
#!/usr/bin/env bash
# Configure FIDO2 support declaratively for Nnomarchy NixOS.
STATE_FILE="/etc/nixos/state.json"
if [[ "--remove" == $1 ]]; then
sudo jq ".features.fido2 = false" "$STATE_FILE" > /tmp/state.json && sudo mv /tmp/state.json "$STATE_FILE"
echo "FIDO2 support disabled. Applying changes..."
sudo sys-update
exit 0
fi
sudo jq ".features.fido2 = true" "$STATE_FILE" > /tmp/state.json && sudo mv /tmp/state.json "$STATE_FILE"
echo "FIDO2 support enabled. Applying changes..."
sudo sys-update
# Enrollment is still an imperative action
if command -v pamu2fcfg &> /dev/null; then
echo "Let's register your FIDO2 key now."
mkdir -p ~/.config/Yubico
pamu2fcfg > ~/.config/Yubico/u2f_keys
echo "FIDO2 key registered."
else
echo "pamu2fcfg not found. It will be available after the next reboot or sys-update."
fi

View File

@@ -0,0 +1,25 @@
#!/usr/bin/env bash
# Configure fingerprint support declaratively for Nnomarchy NixOS.
STATE_FILE="/etc/nixos/state.json"
if [[ "--remove" == $1 ]]; then
sudo jq ".features.fingerprint = false" "$STATE_FILE" > /tmp/state.json && sudo mv /tmp/state.json "$STATE_FILE"
echo "Fingerprint support disabled. Applying changes..."
sudo sys-update
exit 0
fi
sudo jq ".features.fingerprint = true" "$STATE_FILE" > /tmp/state.json && sudo mv /tmp/state.json "$STATE_FILE"
echo "Fingerprint support enabled. Applying changes..."
sudo sys-update
# Enrollment is still an imperative action
if command -v fprintd-enroll &> /dev/null; then
echo "Let's enroll your fingerprint now."
fprintd-enroll
echo "Fingerprint enrolled."
else
echo "fprintd not found. It will be available after the next reboot or sys-update."
fi

View File

@@ -0,0 +1,10 @@
#!/bin/bash
# Prompt for sudo once and keep the credential alive in the background.
# Source this script so the trap applies to the calling shell:
# source nnomarchy-sudo-keepalive
sudo -v
while true; do sudo -n true; sleep 60; done 2>/dev/null &
SUDO_KEEPALIVE_PID=$!
trap "kill $SUDO_KEEPALIVE_PID 2>/dev/null" EXIT

View File

@@ -0,0 +1,43 @@
#!/bin/bash
# Toggle passwordless sudo for the current user.
# First run: enables passwordless sudo for 15 minutes (after confirmation).
# Second run: disables it early.
NOPASSWD_FILE="/etc/sudoers.d/99-nnomarchy-nopasswd-${USER}"
TIMER_NAME="nnomarchy-nopasswd-expire-${USER}"
# Safety: if the file exists but the timer doesn't (e.g. after reboot), clean up
if sudo test -f "$NOPASSWD_FILE" && ! systemctl is-active "${TIMER_NAME}.timer" &>/dev/null; then
sudo rm "$NOPASSWD_FILE"
fi
# Check for the file directly — sudo -n can stay cached or be granted by other rules
if sudo test -f "$NOPASSWD_FILE"; then
sudo rm "$NOPASSWD_FILE"
sudo systemctl stop "${TIMER_NAME}.timer" 2>/dev/null
echo "Passwordless sudo has been DISABLED. Sudo will require a password again."
else
echo ""
echo "⚠️ WARNING: This will allow ANY process running as your user to"
echo "execute ANY command as root WITHOUT a password for 15 minutes."
echo ""
echo "This is useful for AI agents that need to run sudo commands,"
echo "but it significantly weakens the security of your system."
echo "Anyone or anything with access to your user account gets full root."
echo ""
echo "Passwordless sudo will automatically disable after 15 minutes."
echo "Run this command again to disable it early."
echo ""
if gum confirm "Enable passwordless sudo for 15 minutes? This is a significant security risk!"; then
echo "${USER} ALL=(ALL) NOPASSWD: ALL" | sudo tee "$NOPASSWD_FILE" > /dev/null
sudo chmod 440 "$NOPASSWD_FILE"
sudo systemd-run --on-active=15m --timer-property=AccuracySec=1s --unit="$TIMER_NAME" \
rm "$NOPASSWD_FILE"
echo "Passwordless sudo has been ENABLED. It will automatically disable in 15 minutes."
echo "Note: if you restart before then, run nnomarchy-sudo-passwordless-toggle again to disable it."
else
echo "Aborted. No changes made."
fi
fi

7
bin/system/nomarchy-sudo-reset Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
# Reset the sudo lockout/faillock for the current user.
# This clears any failed authentication attempts that may have locked the user out.
# Resetting sudo lockout for user
su -c "faillock --reset --user $USER"

View File

@@ -0,0 +1,11 @@
#!/bin/bash
# Logout command that first closes all application windows (thus giving them a chance to save state),
# then stops the session, returning to the SDDM login screen.
# Schedule the session stop after closing windows (detached from terminal)
nohup bash -c "sleep 2 && uwsm stop" >/dev/null 2>&1 &
# Now close all windows
nnomarchy-hyprland-window-close-all
sleep 1 # Allow apps like Chrome to shutdown correctly

View File

@@ -0,0 +1,13 @@
#!/bin/bash
# Reboot command that first closes all application windows (thus giving them a chance to save state).
# This is particularly helpful for applications like Chromium that otherwise won't shutdown cleanly.
nnomarchy-state clear re*-required
# Schedule the reboot to happen after closing windows (detached from terminal)
nohup bash -c "sleep 2 && systemctl reboot --no-wall" >/dev/null 2>&1 &
# Now close all windows
nnomarchy-hyprland-window-close-all
sleep 1 # Allow apps like Chrome to shutdown correctly

View File

@@ -0,0 +1,13 @@
#!/bin/bash
# Shutdown command that first closes all application windows (thus giving them a chance to save state).
# This is particularly helpful for applications like Chromium that otherwise won't shutdown cleanly.
nnomarchy-state clear re*-required
# Schedule the shutdown to happen after closing windows (detached from terminal)
nohup bash -c "sleep 2 && systemctl poweroff --no-wall" >/dev/null 2>&1 &
# Now close all windows
nnomarchy-hyprland-window-close-all
sleep 1 # Allow apps like Chrome to shutdown correctly

27
bin/system/nomarchy-toggle-idle Executable file
View File

@@ -0,0 +1,27 @@
#!/usr/bin/env bash
# Toggles the idle daemon (hypridle) between enabled and disabled.
# Hybrid: updates state.json and provides instant feedback.
STATE_FILE="$HOME/.config/home-manager/state.json"
mkdir -p "$(dirname "$STATE_FILE")"
# Initialize if doesn't exist
[[ ! -f $STATE_FILE ]] && echo "{}" > "$STATE_FILE"
if [[ $NNOMARCHY_TOGGLE_IDLE == "false" ]]; then
NEW_VALUE="true"
setsid hypridle >/dev/null 2>&1 &
notify-send -u low "󱫖 Now locking computer when idle"
else
NEW_VALUE="false"
pkill -x hypridle
notify-send -u low "󱫖 Stop locking computer when idle"
fi
TMP_JSON=$(mktemp)
jq ".idle = $NEW_VALUE" "$STATE_FILE" > "$TMP_JSON" && mv "$TMP_JSON" "$STATE_FILE"
echo "Idle state set to $NEW_VALUE. Environment will be fully updated on next rebuild."
pkill -RTMIN+9 waybar # Signal waybar if needed

View File

@@ -0,0 +1,29 @@
#!/usr/bin/env bash
# Toggles the suspend menu option availability.
# Hybrid: updates state.json and runs env-update for persistence.
STATE_FILE="$HOME/.config/home-manager/state.json"
mkdir -p "$(dirname "$STATE_FILE")"
# Initialize if doesn't exist
[[ ! -f $STATE_FILE ]] && echo "{}" > "$STATE_FILE"
# Get current state from env or state file
if [[ $NNOMARCHY_TOGGLE_SUSPEND == "false" ]]; then
NEW_VALUE="true"
notify-send -u low "󰒲 Suspend now available in system menu"
else
NEW_VALUE="false"
notify-send -u low "󰒲 Suspend removed from system menu"
fi
# Update JSON using jq
# We use a temporary file to avoid corruption if the shell is interrupted
TMP_JSON=$(mktemp)
jq ".suspend = $NEW_VALUE" "$STATE_FILE" > "$TMP_JSON" && mv "$TMP_JSON" "$STATE_FILE"
echo "Suspend availability set to $NEW_VALUE. Updating environment..."
# Run env-update to apply changes to the menu
env-update

12
bin/system/nomarchy-tz-select Executable file
View File

@@ -0,0 +1,12 @@
#!/usr/bin/env bash
# Select system timezone declaratively for Nnomarchy NixOS.
STATE_FILE="/etc/nixos/state.json"
timezone=$(timedatectl list-timezones | gum filter --height 20 --header "Set timezone") || exit 1
sudo jq ".timezone = \"$timezone\"" "$STATE_FILE" > /tmp/state.json && sudo mv /tmp/state.json "$STATE_FILE"
echo "Timezone is now set to $timezone. Applying changes..."
sudo sys-update

38
bin/system/nomarchy-update Executable file
View File

@@ -0,0 +1,38 @@
#!/usr/bin/env bash
# Nnomarchy Update Script
# 1. Updates the flake inputs in /etc/nixos
# 2. Applies system-wide NixOS changes
# 3. Applies user-level Home Manager changes
set -e
REPO_DIR="/etc/nixos"
if [ ! -d "$REPO_DIR" ]; then
echo "Error: $REPO_DIR not found. Are you running on a Nnomarchy system?"
exit 1
fi
echo "--- Starting Nnomarchy Update ---"
# 1. Update Flake Lock
echo "Updating flake inputs..."
sudo nix --extra-experimental-features "nix-command flakes" flake update --flake "$REPO_DIR"
# 2. Rebuild System
echo "Applying system-level updates..."
sudo nixos-rebuild switch --flake "$REPO_DIR#default" --impure
# 3. Rebuild Home Environment
echo "Applying user-level updates..."
home-manager switch --flake "$REPO_DIR#default" --impure
# 4. Commit changes if it's a git repo
if [ -d "$REPO_DIR/.git" ]; then
echo "Committing update to local history..."
sudo git -C "$REPO_DIR" add flake.lock
sudo git -C "$REPO_DIR" commit -m "chore: update system (flake.lock)" || echo "No lockfile changes to commit."
fi
echo "--- Nnomarchy Update Complete ---"

View File

@@ -0,0 +1,4 @@
#!/bin/bash
echo "Updating time..."
sudo systemctl restart systemd-timesyncd