refactor noctalia module

This commit is contained in:
Nate Anderson 2026-02-12 16:20:21 -07:00
parent d6eece6c13
commit 127ebd10c5
8 changed files with 863 additions and 534 deletions

6
flake.lock generated
View File

@ -200,11 +200,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1770617025, "lastModified": 1770770419,
"narHash": "sha256-1jZvgZoAagZZB6NwGRv2T2ezPy+X6EFDsJm+YSlsvEs=", "narHash": "sha256-iKZMkr6Cm9JzWlRYW/VPoL0A9jVKtZYiU4zSrVeetIs=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "2db38e08fdadcc0ce3232f7279bab59a15b94482", "rev": "6c5e707c6b5339359a9a9e215c5e66d6d802fd7a",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@ -12,6 +12,7 @@
../../../shared/modules/apps/helix.nix ../../../shared/modules/apps/helix.nix
../../../shared/modules/home-manager/git-autosync.nix ../../../shared/modules/home-manager/git-autosync.nix
../../../shared/modules/home-manager/noctalia.nix ../../../shared/modules/home-manager/noctalia.nix
../../../shared/modules/home-manager/json2nix.nix
../../../shared/modules/home-manager/style-preview.nix ../../../shared/modules/home-manager/style-preview.nix
../niri/niri_home.nix ../niri/niri_home.nix
./programs.nix ./programs.nix
@ -26,6 +27,7 @@
ghosttyApp.enable = true; ghosttyApp.enable = true;
helixApp.enable = true; helixApp.enable = true;
stylePreview.enable = true; stylePreview.enable = true;
json2nix.enable = true;
fonts.fontconfig.enable = true; fonts.fontconfig.enable = true;
# OpenCode with Stylix theming (using unstable package) # OpenCode with Stylix theming (using unstable package)
@ -46,11 +48,15 @@
# Enable Noctalia shell (replaces Waybar, SwayNC, SwayOSD, wlsunset) # Enable Noctalia shell (replaces Waybar, SwayNC, SwayOSD, wlsunset)
noctaliaShell = { noctaliaShell = {
enable = true; enable = true;
barPosition = "top"; settings = {
bar.position = "top";
colorSchemes = {
darkMode = true; darkMode = true;
colorScheme = "Noctalia (default)"; # Or try "Monochrome" to complement woodland theme predefinedScheme = "Noctalia (default)";
locationName = "Denver"; };
avatarImage = "/home/${userName}/.face"; location.name = "Denver";
general.avatarImage = "/home/${userName}/.face";
};
}; };
# Additional user packages # Additional user packages

View File

@ -11,6 +11,7 @@
../../../shared/modules/apps/helix.nix ../../../shared/modules/apps/helix.nix
../../../shared/modules/home-manager/git-autosync.nix ../../../shared/modules/home-manager/git-autosync.nix
../../../shared/modules/home-manager/noctalia.nix ../../../shared/modules/home-manager/noctalia.nix
../../../shared/modules/home-manager/json2nix.nix
../../../shared/modules/home-manager/style-preview.nix ../../../shared/modules/home-manager/style-preview.nix
../niri/niri_home.nix ../niri/niri_home.nix
./programs.nix ./programs.nix
@ -25,6 +26,7 @@
ghosttyApp.enable = true; ghosttyApp.enable = true;
helixApp.enable = true; helixApp.enable = true;
stylePreview.enable = true; stylePreview.enable = true;
json2nix.enable = true;
fonts.fontconfig.enable = true; fonts.fontconfig.enable = true;
# Stylix auto-theming - applies to all programs.<name>.enable apps # Stylix auto-theming - applies to all programs.<name>.enable apps
@ -39,11 +41,15 @@
# Enable Noctalia shell (replaces Waybar, SwayNC, SwayOSD, wlsunset) # Enable Noctalia shell (replaces Waybar, SwayNC, SwayOSD, wlsunset)
noctaliaShell = { noctaliaShell = {
enable = true; enable = true;
barPosition = "top"; settings = {
bar.position = "top";
colorSchemes = {
darkMode = false; # Jaci uses light mode darkMode = false; # Jaci uses light mode
useWallpaperColors = true; # Generate colors from wallpaper useWallpaperColors = true;
locationName = "Salt Lake"; };
avatarImage = "/home/${userName}/.face"; location.name = "Salt Lake";
general.avatarImage = "/home/${userName}/.face";
};
}; };
# Additional user packages # Additional user packages

View File

@ -1,9 +1,18 @@
{ inputs, config, pkgs, lib, ... }: {
inputs,
config,
pkgs,
lib,
...
}:
let let
userName = "nate"; userName = "nate";
fullName = "Nate Anderson"; fullName = "Nate Anderson";
email = "nate.anderson@vasion.com"; email = "nate.anderson@vasion.com";
unstable = import inputs.nixpkgs-unstable { system = "x86_64-linux"; config.allowUnfree = true; }; unstable = import inputs.nixpkgs-unstable {
system = "x86_64-linux";
config.allowUnfree = true;
};
in in
{ {
imports = [ imports = [
@ -13,6 +22,7 @@
../../../shared/modules/home-manager/programs.nix ../../../shared/modules/home-manager/programs.nix
../../../shared/modules/home-manager/git-autosync.nix ../../../shared/modules/home-manager/git-autosync.nix
../../../shared/modules/home-manager/noctalia.nix ../../../shared/modules/home-manager/noctalia.nix
../../../shared/modules/home-manager/json2nix.nix
../../../shared/modules/home-manager/style-preview.nix ../../../shared/modules/home-manager/style-preview.nix
../niri/niri_home.nix ../niri/niri_home.nix
../vpn-proxy/vpn-proxy.nix ../vpn-proxy/vpn-proxy.nix
@ -33,6 +43,7 @@
helixApp.enable = true; helixApp.enable = true;
sharedPrograms.enable = true; sharedPrograms.enable = true;
stylePreview.enable = true; stylePreview.enable = true;
json2nix.enable = true;
fonts.fontconfig.enable = true; fonts.fontconfig.enable = true;
# OpenCode with Stylix theming (using unstable package) # OpenCode with Stylix theming (using unstable package)
@ -59,54 +70,6 @@
homePackages = [ ]; homePackages = [ ];
}; };
# Enable Noctalia shell (replaces Waybar, SwayNC, SwayOSD, wlsunset)
noctaliaShell = {
enable = true;
# Bar
barPosition = "top";
barDensity = "spacious";
barBackgroundOpacity = 1.0;
clockFormat = "HH:mm ddd, MMM dd";
launcherIcon = "rocket";
# Color scheme
darkMode = true;
useWallpaperColors = true;
# Location & weather
locationName = "Saratoga Springs, UT";
use12hourFormat = true;
firstDayOfWeek = 1;
hideWeatherTimezone = true;
# General
avatarImage = "/home/${userName}/.face";
dimmerOpacity = 0.0;
lockScreenAnimations = true;
lockScreenCountdownDuration = 3000;
telemetryEnabled = true;
# UI fonts
fontDefault = "Lato";
fontFixed = "Maple Mono NF";
fontDefaultScale = 1.2;
panelBackgroundOpacity = 0.9;
# Wallpaper
wallpaperDirectory = "/home/${userName}/Pictures/Wallpapers";
# Dock
dockBackgroundOpacity = 0.8;
dockSize = 1.5;
# Notifications & OSD
notificationLocation = "top";
enableMediaToast = true;
osdLocation = "bottom";
# Night light
enableNightLight = true;
nightLightTemp = "4011";
# System monitor custom colors
systemMonitorUseCustomColors = true;
systemMonitorWarningColor = "#5a5a5a";
systemMonitorCriticalColor = "#c88c8c";
# Plugins
pluginsAutoUpdate = true;
};
# Additional user packages # Additional user packages
# Note: Programs with Stylix theming are in shared modules # Note: Programs with Stylix theming are in shared modules
home.packages = with pkgs; [ home.packages = with pkgs; [
@ -213,7 +176,10 @@
# enable saving ssh secrets (needed for go mod installing private packages) # enable saving ssh secrets (needed for go mod installing private packages)
services.gnome-keyring.enable = true; services.gnome-keyring.enable = true;
services.gnome-keyring.components = [ "ssh" "secrets" ]; services.gnome-keyring.components = [
"ssh"
"secrets"
];
# Enable bluetooth headphone controls # Enable bluetooth headphone controls
services.mpris-proxy.enable = true; services.mpris-proxy.enable = true;
@ -229,10 +195,18 @@
settings = { settings = {
user.name = fullName; user.name = fullName;
user.email = email; user.email = email;
init = { defaultBranch = "main"; }; init = {
merge = { conflictStyle="zdiff3"; }; defaultBranch = "main";
pull = { ff = "only"; }; };
push = { autoSetupRemote="true"; }; merge = {
conflictStyle = "zdiff3";
};
pull = {
ff = "only";
};
push = {
autoSetupRemote = "true";
};
# Vasion rewrite rule # Vasion rewrite rule
url = { url = {
"git@github.com:" = { "git@github.com:" = {
@ -328,31 +302,621 @@
home.file = lib.mkMerge [ home.file = lib.mkMerge [
# Shared dotfiles # Shared dotfiles
(let (
let
sharedDotfilesPath = ../../../shared/dotfiles; sharedDotfilesPath = ../../../shared/dotfiles;
in in
if builtins.pathExists sharedDotfilesPath then if builtins.pathExists sharedDotfilesPath then
builtins.listToAttrs (map (name: { builtins.listToAttrs (
map (name: {
name = ".config/${name}"; name = ".config/${name}";
value = { source = lib.mkDefault (sharedDotfilesPath + "/${name}"); }; value = {
}) (builtins.attrNames (builtins.readDir sharedDotfilesPath))) source = lib.mkDefault (sharedDotfilesPath + "/${name}");
else {}) };
}) (builtins.attrNames (builtins.readDir sharedDotfilesPath))
)
else
{ }
)
# Add local dotfiles, overriding from local over shared # Add local dotfiles, overriding from local over shared
(let (
let
localDotfilesPath = ../../dotfiles; localDotfilesPath = ../../dotfiles;
in in
if builtins.pathExists localDotfilesPath && builtins.readDir localDotfilesPath != { } then if builtins.pathExists localDotfilesPath && builtins.readDir localDotfilesPath != { } then
builtins.listToAttrs (map (name: { builtins.listToAttrs (
map (name: {
name = ".config/${name}"; name = ".config/${name}";
value = { source = localDotfilesPath + "/${name}"; }; value = {
}) (builtins.attrNames (builtins.readDir localDotfilesPath))) source = localDotfilesPath + "/${name}";
else {}) };
}) (builtins.attrNames (builtins.readDir localDotfilesPath))
)
else
{ }
)
]; ];
xdg.configFile = { xdg.configFile = {
# Active linked dotfiles # Active linked dotfiles
"hypr".source = config.lib.file.mkOutOfStoreSymlink "/home/nate/nixos/nate-work/linked-dotfiles/hypr"; "hypr".source =
"niri".source = config.lib.file.mkOutOfStoreSymlink "/home/nate/nixos/nate-work/linked-dotfiles/niri"; config.lib.file.mkOutOfStoreSymlink "/home/nate/nixos/nate-work/linked-dotfiles/hypr";
"niri".source =
config.lib.file.mkOutOfStoreSymlink "/home/nate/nixos/nate-work/linked-dotfiles/niri";
# waybar is now managed by shared/modules/home-manager/waybar.nix via waybarConfig.enable # waybar is now managed by shared/modules/home-manager/waybar.nix via waybarConfig.enable
}; };
# Enable Noctalia shell (replaces Waybar, SwayNC, SwayOSD, wlsunset)
noctaliaShell = {
enable = true;
settings = {
settingsVersion = 51;
bar = {
barType = "simple";
position = "top";
monitors = [ ];
density = "spacious";
showOutline = false;
showCapsule = true;
capsuleOpacity = 1.0;
capsuleColorKey = "none";
backgroundOpacity = 1.0;
useSeparateOpacity = false;
floating = false;
marginVertical = 4;
marginHorizontal = 4;
frameThickness = 8;
frameRadius = 12;
outerCorners = true;
hideOnOverview = false;
displayMode = "always_visible";
autoHideDelay = 500;
autoShowDelay = 150;
widgets = {
left = [
{
icon = "rocket";
iconColor = "none";
id = "Launcher";
}
{
clockColor = "none";
customFont = "";
formatHorizontal = "HH:mm ddd, MMM dd";
formatVertical = "HH mm - dd MM";
id = "Clock";
tooltipFormat = "HH:mm ddd, MMM dd";
useCustomFont = false;
}
{ id = "plugin:weekly-calendar"; }
{
compactMode = true;
diskPath = "/";
iconColor = "none";
id = "SystemMonitor";
showCpuFreq = false;
showCpuTemp = true;
showCpuUsage = true;
showDiskAvailable = false;
showDiskUsage = false;
showDiskUsageAsPercent = false;
showGpuTemp = false;
showLoadAverage = false;
showMemoryAsPercent = false;
showMemoryUsage = true;
showNetworkStats = false;
showSwapUsage = false;
textColor = "none";
useMonospaceFont = true;
}
{
colorizeIcons = false;
hideMode = "hidden";
id = "ActiveWindow";
maxWidth = 145;
scrollingMode = "hover";
showIcon = true;
textColor = "none";
useFixedWidth = false;
}
{
compactMode = false;
compactShowAlbumArt = true;
compactShowVisualizer = false;
hideMode = "hidden";
hideWhenIdle = false;
id = "MediaMini";
maxWidth = 145;
panelShowAlbumArt = true;
panelShowVisualizer = true;
scrollingMode = "hover";
showAlbumArt = true;
showArtistFirst = true;
showProgressRing = true;
showVisualizer = false;
textColor = "none";
useFixedWidth = false;
visualizerType = "linear";
}
{
defaultSettings = {
refreshInterval = 5000;
};
id = "plugin:mini-docker";
}
];
center = [
{
characterCount = 2;
colorizeIcons = false;
emptyColor = "secondary";
enableScrollWheel = true;
focusedColor = "primary";
followFocusedScreen = false;
groupedBorderOpacity = 1.0;
hideUnoccupied = false;
iconScale = 0.8;
id = "Workspace";
labelMode = "index";
occupiedColor = "secondary";
pillSize = 0.6;
reverseScroll = false;
showApplications = false;
showBadge = true;
showLabelsOnlyWhenOccupied = true;
unfocusedIconsOpacity = 1.0;
}
];
right = [
{
blacklist = [ ];
chevronColor = "none";
colorizeIcons = false;
drawerEnabled = true;
hidePassive = false;
id = "Tray";
pinned = [ ];
}
{
hideWhenZero = false;
hideWhenZeroUnread = false;
iconColor = "none";
id = "NotificationHistory";
showUnreadBadge = true;
unreadBadgeColor = "primary";
}
{
deviceNativePath = "__default__";
displayMode = "graphic-clean";
hideIfIdle = false;
hideIfNotDetected = true;
id = "Battery";
showNoctaliaPerformance = false;
showPowerProfiles = false;
}
{
displayMode = "onhover";
iconColor = "none";
id = "Volume";
middleClickCommand = "pwvucontrol || pavucontrol";
textColor = "none";
}
{
displayMode = "onhover";
iconColor = "none";
id = "Brightness";
textColor = "none";
}
{
colorizeDistroLogo = false;
colorizeSystemIcon = "none";
customIconPath = "";
enableColorization = false;
icon = "noctalia";
id = "ControlCenter";
useDistroLogo = false;
}
];
};
screenOverrides = [ ];
};
general = {
avatarImage = "/home/${userName}/.face";
dimmerOpacity = 0.1;
showScreenCorners = false;
forceBlackScreenCorners = false;
scaleRatio = 1.1;
radiusRatio = 1;
iRadiusRatio = 1;
boxRadiusRatio = 1;
screenRadiusRatio = 1;
animationSpeed = 1;
animationDisabled = false;
compactLockScreen = false;
lockScreenAnimations = false;
lockOnSuspend = true;
showSessionButtonsOnLockScreen = true;
showHibernateOnLockScreen = false;
enableShadows = true;
shadowDirection = "bottom_right";
shadowOffsetX = 2;
shadowOffsetY = 3;
language = "";
allowPanelsOnScreenWithoutBar = true;
showChangelogOnStartup = true;
telemetryEnabled = false;
enableLockScreenCountdown = true;
lockScreenCountdownDuration = 10000;
autoStartAuth = false;
allowPasswordWithFprintd = false;
clockStyle = "custom";
clockFormat = "hh\\nmm";
lockScreenMonitors = [ ];
lockScreenBlur = 0;
lockScreenTint = 0;
keybinds = {
keyUp = [ "Up" ];
keyDown = [ "Down" ];
keyLeft = [ "Left" ];
keyRight = [ "Right" ];
keyEnter = [ "Return" ];
keyEscape = [ "Esc" ];
};
};
ui = {
fontDefault = "Lato";
fontFixed = "Maple Mono NF";
fontDefaultScale = 1.25;
fontFixedScale = 1;
tooltipsEnabled = true;
panelBackgroundOpacity = 1.0;
panelsAttachedToBar = true;
settingsPanelMode = "attached";
wifiDetailsViewMode = "grid";
bluetoothDetailsViewMode = "grid";
networkPanelView = "wifi";
bluetoothHideUnnamedDevices = false;
boxBorderEnabled = false;
};
location = {
name = "Saratoga Springs, UT";
weatherEnabled = true;
weatherShowEffects = true;
useFahrenheit = true;
use12hourFormat = true;
showWeekNumberInCalendar = false;
showCalendarEvents = true;
showCalendarWeather = true;
analogClockInCalendar = false;
firstDayOfWeek = -1;
hideWeatherTimezone = false;
hideWeatherCityName = false;
};
calendar = {
cards = [
{
enabled = true;
id = "calendar-header-card";
}
{
enabled = true;
id = "calendar-month-card";
}
{
enabled = true;
id = "weather-card";
}
];
};
wallpaper = {
enabled = true;
overviewEnabled = false;
directory = "/home/${userName}/Pictures/Wallpapers";
monitorDirectories = [ ];
enableMultiMonitorDirectories = false;
showHiddenFiles = false;
viewMode = "single";
setWallpaperOnAllMonitors = true;
fillMode = "crop";
fillColor = "#000000";
useSolidColor = false;
solidColor = "#1a1a2e";
automationEnabled = false;
wallpaperChangeMode = "random";
randomIntervalSec = 300;
transitionDuration = 1500;
transitionType = "random";
transitionEdgeSmoothness = 0.05;
panelPosition = "follow_bar";
hideWallpaperFilenames = false;
overviewBlur = 0.4;
overviewTint = 0.6;
useWallhaven = false;
wallhavenQuery = "";
wallhavenSorting = "relevance";
wallhavenOrder = "desc";
wallhavenCategories = "111";
wallhavenPurity = "100";
wallhavenRatios = "";
wallhavenApiKey = "";
wallhavenResolutionMode = "atleast";
wallhavenResolutionWidth = "";
wallhavenResolutionHeight = "";
sortOrder = "name";
};
appLauncher = {
enableClipboardHistory = false;
autoPasteClipboard = false;
enableClipPreview = true;
clipboardWrapText = true;
clipboardWatchTextCommand = "wl-paste --type text --watch cliphist store";
clipboardWatchImageCommand = "wl-paste --type image --watch cliphist store";
position = "center";
pinnedApps = [ ];
useApp2Unit = false;
sortByMostUsed = true;
terminalCommand = "ghostty -e";
customLaunchPrefixEnabled = false;
customLaunchPrefix = "";
viewMode = "list";
showCategories = true;
iconMode = "tabler";
showIconBackground = false;
enableSettingsSearch = true;
enableWindowsSearch = true;
ignoreMouseInput = false;
screenshotAnnotationTool = "";
overviewLayer = false;
density = "default";
};
controlCenter = {
position = "close_to_bar_button";
diskPath = "/";
shortcuts = {
left = [
{ id = "Network"; }
{ id = "Bluetooth"; }
{ id = "WallpaperSelector"; }
{ id = "NoctaliaPerformance"; }
];
right = [
{ id = "Notifications"; }
{ id = "PowerProfile"; }
{ id = "KeepAwake"; }
{ id = "NightLight"; }
];
};
cards = [
{
enabled = true;
id = "profile-card";
}
{
enabled = true;
id = "shortcuts-card";
}
{
enabled = true;
id = "audio-card";
}
{
enabled = false;
id = "brightness-card";
}
{
enabled = true;
id = "weather-card";
}
{
enabled = true;
id = "media-sysmon-card";
}
];
};
systemMonitor = {
cpuWarningThreshold = 80;
cpuCriticalThreshold = 90;
tempWarningThreshold = 80;
tempCriticalThreshold = 90;
gpuWarningThreshold = 80;
gpuCriticalThreshold = 90;
memWarningThreshold = 80;
memCriticalThreshold = 90;
swapWarningThreshold = 80;
swapCriticalThreshold = 90;
diskWarningThreshold = 80;
diskCriticalThreshold = 90;
diskAvailWarningThreshold = 20;
diskAvailCriticalThreshold = 10;
batteryWarningThreshold = 20;
batteryCriticalThreshold = 5;
cpuPollingInterval = 1000;
gpuPollingInterval = 3000;
enableDgpuMonitoring = false;
memPollingInterval = 1000;
diskPollingInterval = 30000;
networkPollingInterval = 1000;
loadAvgPollingInterval = 3000;
useCustomColors = false;
warningColor = "";
criticalColor = "";
externalMonitor = "resources || missioncenter || jdsystemmonitor || corestats || system-monitoring-center || gnome-system-monitor || plasma-systemmonitor || mate-system-monitor || ukui-system-monitor || deepin-system-monitor || pantheon-system-monitor";
};
dock = {
enabled = true;
position = "bottom";
displayMode = "auto_hide";
backgroundOpacity = 1.0;
floatingRatio = 1;
size = 1;
onlySameOutput = true;
monitors = [ ];
pinnedApps = [ ];
colorizeIcons = false;
pinnedStatic = false;
inactiveIndicators = false;
deadOpacity = 0.6;
animationSpeed = 1;
};
network = {
wifiEnabled = true;
bluetoothRssiPollingEnabled = false;
bluetoothRssiPollIntervalMs = 10000;
wifiDetailsViewMode = "grid";
bluetoothDetailsViewMode = "grid";
bluetoothHideUnnamedDevices = false;
};
sessionMenu = {
enableCountdown = true;
countdownDuration = 10000;
position = "center";
showHeader = true;
largeButtonsStyle = true;
largeButtonsLayout = "single-row";
showNumberLabels = true;
powerOptions = [
{
action = "lock";
command = "";
countdownEnabled = true;
enabled = true;
keybind = "";
}
{
action = "suspend";
command = "";
countdownEnabled = true;
enabled = true;
keybind = "";
}
{
action = "hibernate";
command = "";
countdownEnabled = true;
enabled = true;
keybind = "";
}
{
action = "reboot";
command = "";
countdownEnabled = true;
enabled = true;
keybind = "";
}
{
action = "logout";
command = "";
countdownEnabled = true;
enabled = true;
keybind = "";
}
{
action = "shutdown";
command = "";
countdownEnabled = true;
enabled = true;
keybind = "";
}
];
};
notifications = {
enabled = true;
monitors = [ ];
location = "top";
overlayLayer = true;
backgroundOpacity = 1.0;
respectExpireTimeout = false;
lowUrgencyDuration = 3;
normalUrgencyDuration = 8;
criticalUrgencyDuration = 15;
saveToHistory = {
low = true;
normal = true;
critical = true;
};
sounds = {
enabled = false;
volume = 0.5;
separateSounds = false;
criticalSoundFile = "";
normalSoundFile = "";
lowSoundFile = "";
excludedApps = "discord,firefox,chrome,chromium,edge";
};
enableMediaToast = false;
enableKeyboardLayoutToast = true;
enableBatteryToast = true;
};
osd = {
enabled = true;
location = "bottom";
autoHideMs = 2000;
overlayLayer = true;
backgroundOpacity = 1.0;
enabledTypes = [
0
1
2
3
];
monitors = [ ];
};
audio = {
volumeStep = 5;
volumeOverdrive = false;
cavaFrameRate = 30;
visualizerType = "linear";
mprisBlacklist = [ ];
preferredPlayer = "";
volumeFeedback = false;
};
brightness = {
brightnessStep = 5;
enforceMinimum = true;
enableDdcSupport = false;
};
colorSchemes = {
useWallpaperColors = false;
predefinedScheme = "Noctalia (default)";
darkMode = true;
schedulingMode = "off";
manualSunrise = "06:30";
manualSunset = "18:30";
generationMethod = "tonal-spot";
monitorForColors = "";
};
templates = {
activeTemplates = [ ];
enableUserTheming = false;
};
nightLight = {
enabled = false;
forced = false;
autoSchedule = true;
nightTemp = "4000";
dayTemp = "6500";
manualSunrise = "06:30";
manualSunset = "18:30";
};
hooks = {
enabled = false;
wallpaperChange = "";
darkModeChange = "";
screenLock = "";
screenUnlock = "";
performanceModeEnabled = "";
performanceModeDisabled = "";
startup = "";
session = "";
};
plugins = {
autoUpdate = false;
};
desktopWidgets = {
enabled = false;
gridSnap = false;
monitorWidgets = [ ];
};
};
};
} }

View File

@ -13,6 +13,7 @@
../../../shared/modules/home-manager/programs.nix ../../../shared/modules/home-manager/programs.nix
../../../shared/modules/home-manager/git-autosync.nix ../../../shared/modules/home-manager/git-autosync.nix
../../../shared/modules/home-manager/noctalia.nix ../../../shared/modules/home-manager/noctalia.nix
../../../shared/modules/home-manager/json2nix.nix
../../../shared/modules/home-manager/style-preview.nix ../../../shared/modules/home-manager/style-preview.nix
../niri/niri_home.nix ../niri/niri_home.nix
]; ];
@ -32,6 +33,7 @@
helixApp.enable = true; helixApp.enable = true;
sharedPrograms.enable = true; sharedPrograms.enable = true;
stylePreview.enable = true; stylePreview.enable = true;
json2nix.enable = true;
fonts.fontconfig.enable = true; fonts.fontconfig.enable = true;
# OpenCode with Stylix theming (using unstable package) # OpenCode with Stylix theming (using unstable package)
@ -58,11 +60,15 @@
# Enable Noctalia shell (replaces Waybar, SwayNC, SwayOSD, wlsunset) # Enable Noctalia shell (replaces Waybar, SwayNC, SwayOSD, wlsunset)
noctaliaShell = { noctaliaShell = {
enable = true; enable = true;
barPosition = "top"; settings = {
bar.position = "top";
colorSchemes = {
darkMode = true; darkMode = true;
useWallpaperColors = true; # Generate colors from wallpaper useWallpaperColors = true;
locationName = "Denver"; };
avatarImage = "/home/${userName}/.face"; location.name = "Denver";
general.avatarImage = "/home/${userName}/.face";
};
}; };
# Additional user packages # Additional user packages

View File

@ -0,0 +1,83 @@
# Provides json2nix command for converting JSON to Nix attribute set syntax
# Usage: wl-paste | json2nix | wl-copy
# json2nix < settings.json
{ config, lib, pkgs, ... }:
let
cfg = config.json2nix;
json2nixScript = pkgs.writeScriptBin "json2nix" ''
#!${pkgs.python3}/bin/python3
"""Convert JSON to Nix attribute set syntax.
Usage: wl-paste | json2nix | wl-copy
json2nix < settings.json
"""
import json
import sys
def to_nix(obj, indent=0):
"""Convert a Python object (from JSON) to Nix syntax."""
spaces = " " * indent
if obj is None:
return "null"
elif isinstance(obj, bool):
return "true" if obj else "false"
elif isinstance(obj, int):
return str(obj)
elif isinstance(obj, float):
# Ensure floats stay as floats (e.g., 1.0 not 1)
s = str(obj)
if '.' not in s and 'e' not in s.lower():
s += ".0"
return s
elif isinstance(obj, str):
# Escape special characters for Nix strings
escaped = obj.replace("\\", "\\\\")
escaped = escaped.replace('"', '\\"')
escaped = escaped.replace("\n", "\\n")
escaped = escaped.replace("\r", "\\r")
escaped = escaped.replace("\t", "\\t")
return f'"{escaped}"'
elif isinstance(obj, list):
if not obj:
return "[ ]"
items = []
for item in obj:
items.append(f"{spaces} {to_nix(item, indent + 1)}")
return "[\n" + "\n".join(items) + f"\n{spaces}]"
elif isinstance(obj, dict):
if not obj:
return "{ }"
items = []
for key, value in obj.items():
# Quote keys that aren't valid Nix identifiers
if not key.isidentifier() or key in ['if', 'then', 'else', 'let', 'in', 'with', 'rec', 'inherit', 'or', 'and']:
nix_key = f'"{key}"'
else:
nix_key = key
nix_value = to_nix(value, indent + 1)
items.append(f"{spaces} {nix_key} = {nix_value};")
return "{\n" + "\n".join(items) + f"\n{spaces}}}"
try:
data = json.load(sys.stdin)
print(to_nix(data))
except json.JSONDecodeError as e:
print(f"Error: Invalid JSON - {e}", file=sys.stderr)
sys.exit(1)
except Exception as e:
print(f"Error: {e}", file=sys.stderr)
sys.exit(1)
'';
in
{
options.json2nix = {
enable = lib.mkEnableOption "json2nix command for converting JSON to Nix syntax";
};
config = lib.mkIf cfg.enable {
home.packages = [ json2nixScript ];
};
}

View File

@ -4,8 +4,6 @@
# nix shell nixpkgs#jq nixpkgs#colordiff -c bash -c "colordiff -u --nobanner <(jq -S . ~/.config/noctalia/settings.json) <(noctalia-shell ipc call state all | jq -S .settings)" # nix shell nixpkgs#jq nixpkgs#colordiff -c bash -c "colordiff -u --nobanner <(jq -S . ~/.config/noctalia/settings.json) <(noctalia-shell ipc call state all | jq -S .settings)"
{ config, lib, pkgs, inputs, ... }: { config, lib, pkgs, inputs, ... }:
with lib;
let let
cfg = config.noctaliaShell; cfg = config.noctaliaShell;
in in
@ -15,378 +13,34 @@ in
]; ];
options.noctaliaShell = { options.noctaliaShell = {
enable = mkEnableOption "Noctalia shell"; enable = lib.mkEnableOption "Noctalia shell";
colorScheme = mkOption { settings = lib.mkOption {
type = types.str; type = lib.types.attrs;
default = "Noctalia (default)"; default = { };
description = '' description = "Noctalia shell settings. See https://docs.noctalia.dev/getting-started/nixos/#config-ref";
Predefined color scheme to use. Options include:
"Noctalia (default)", "Monochrome", "Catppuccin Mocha", etc.
See Noctalia docs for full list.
'';
};
useWallpaperColors = mkOption {
type = types.bool;
default = false;
description = "Generate colors from wallpaper instead of using predefined scheme";
};
darkMode = mkOption {
type = types.bool;
default = true;
description = "Use dark mode for Noctalia shell";
};
barPosition = mkOption {
type = types.enum [ "top" "bottom" "left" "right" ];
default = "top";
description = "Position of the Noctalia bar";
};
barDensity = mkOption {
type = types.enum [ "spacious" "comfortable" "default" "compact" "mini" ];
default = "default";
description = "Bar density (compact for vertical bars)";
};
enableDock = mkOption {
type = types.bool;
default = true;
description = "Enable the Noctalia dock";
};
dockPosition = mkOption {
type = types.enum [ "top" "bottom" "left" "right" ];
default = "bottom";
description = "Position of the dock";
};
pinnedApps = mkOption {
type = types.listOf types.str;
default = [ ];
description = "List of .desktop file names for pinned dock apps";
};
avatarImage = mkOption {
type = types.str;
default = "";
description = "Path to avatar image for user profile";
};
locationName = mkOption {
type = types.str;
default = "Denver";
description = "Location name for weather widget";
};
use12hourFormat = mkOption {
type = types.bool;
default = false;
description = "Use 12-hour time format";
};
useFahrenheit = mkOption {
type = types.bool;
default = false;
description = "Use Fahrenheit for temperature";
};
# UI settings
fontDefault = mkOption {
type = types.str;
default = "";
description = "Default font for Noctalia shell";
};
fontFixed = mkOption {
type = types.str;
default = "";
description = "Monospace font for Noctalia shell";
};
fontDefaultScale = mkOption {
type = types.float;
default = 1.0;
description = "Scale factor for default font";
};
panelBackgroundOpacity = mkOption {
type = types.float;
default = 0.93;
description = "Background opacity for panels";
};
# General settings
dimmerOpacity = mkOption {
type = types.float;
default = 0.2;
description = "Opacity for screen dimmer";
};
lockScreenAnimations = mkOption {
type = types.bool;
default = false;
description = "Enable lock screen animations";
};
lockScreenCountdownDuration = mkOption {
type = types.int;
default = 10000;
description = "Lock screen countdown duration in milliseconds";
};
telemetryEnabled = mkOption {
type = types.bool;
default = false;
description = "Enable telemetry for Noctalia";
};
# Bar settings
barBackgroundOpacity = mkOption {
type = types.float;
default = 0.93;
description = "Bar background opacity";
};
clockFormat = mkOption {
type = types.str;
default = "HH:mm ddd, MMM dd";
description = "Clock format for horizontal display";
};
launcherIcon = mkOption {
type = types.str;
default = "activities";
description = "Icon for the launcher widget";
};
# Wallpaper settings
wallpaperDirectory = mkOption {
type = types.str;
default = "";
description = "Directory containing wallpapers";
};
# Dock settings
dockBackgroundOpacity = mkOption {
type = types.float;
default = 1.0;
description = "Dock background opacity";
};
dockSize = mkOption {
type = types.float;
default = 1.0;
description = "Dock size multiplier";
};
# Notification settings
notificationLocation = mkOption {
type = types.enum [ "top" "top_right" "top_left" "bottom" "bottom_right" "bottom_left" ];
default = "top_right";
description = "Location for notifications";
};
enableMediaToast = mkOption {
type = types.bool;
default = false;
description = "Enable media change toast notifications";
};
# OSD settings
osdLocation = mkOption {
type = types.enum [ "top" "top_right" "top_left" "bottom" "bottom_right" "bottom_left" "center" ];
default = "top_right";
description = "Location for OSD popups";
};
# Night light settings
enableNightLight = mkOption {
type = types.bool;
default = false;
description = "Enable night light feature";
};
nightLightTemp = mkOption {
type = types.str;
default = "4000";
description = "Night time color temperature";
};
# System monitor settings
systemMonitorUseCustomColors = mkOption {
type = types.bool;
default = false;
description = "Use custom colors for system monitor thresholds";
};
systemMonitorWarningColor = mkOption {
type = types.str;
default = "";
description = "Warning color for system monitor";
};
systemMonitorCriticalColor = mkOption {
type = types.str;
default = "";
description = "Critical color for system monitor";
};
# Plugin settings
pluginsAutoUpdate = mkOption {
type = types.bool;
default = false;
description = "Auto-update Noctalia plugins";
};
# Calendar settings
firstDayOfWeek = mkOption {
type = types.int;
default = (-1);
description = "First day of week (-1 for system default, 0=Sunday, 1=Monday)";
};
hideWeatherTimezone = mkOption {
type = types.bool;
default = false;
description = "Hide timezone in weather display";
}; };
}; };
config = mkIf cfg.enable { config = lib.mkIf cfg.enable {
# Configure Noctalia shell via home-manager module
programs.noctalia-shell = { programs.noctalia-shell = {
enable = true; enable = true;
# Override with calendarSupport for evolution-data-server integration
# Don't install the package separately since systemd service handles it package = inputs.noctalia.packages.${pkgs.stdenv.hostPlatform.system}.default.override {
# But we need it for IPC commands in keybinds calendarSupport = true;
package = inputs.noctalia.packages.${pkgs.stdenv.hostPlatform.system}.default;
settings = mkMerge [
# Use mkDefault for all settings to allow per-host overrides
(mkDefault {
colorSchemes = {
useWallpaperColors = cfg.useWallpaperColors;
predefinedScheme = cfg.colorScheme;
darkMode = cfg.darkMode;
}; };
settings = cfg.settings;
bar = {
position = cfg.barPosition;
density = cfg.barDensity;
backgroundOpacity = cfg.barBackgroundOpacity;
showCapsule = true;
floating = false;
widgets = {
left = [
{ id = "Launcher"; icon = cfg.launcherIcon; }
{ id = "Clock"; formatHorizontal = cfg.clockFormat; }
{ id = "SystemMonitor"; }
{ id = "ActiveWindow"; }
{ id = "MediaMini"; }
];
center = [
{ id = "Workspace"; }
];
right = [
{ id = "Tray"; }
{ id = "NotificationHistory"; }
{ id = "Battery"; }
{ id = "Volume"; }
{ id = "Brightness"; }
{ id = "ControlCenter"; }
];
};
};
dock = {
enabled = cfg.enableDock;
position = cfg.dockPosition;
displayMode = "auto_hide";
backgroundOpacity = cfg.dockBackgroundOpacity;
size = cfg.dockSize;
pinnedApps = cfg.pinnedApps;
};
general = {
avatarImage = cfg.avatarImage;
dimmerOpacity = cfg.dimmerOpacity;
radiusRatio = 1;
animationSpeed = 1;
enableShadows = true;
lockScreenAnimations = cfg.lockScreenAnimations;
lockScreenCountdownDuration = cfg.lockScreenCountdownDuration;
telemetryEnabled = cfg.telemetryEnabled;
};
ui = {
fontDefault = cfg.fontDefault;
fontFixed = cfg.fontFixed;
fontDefaultScale = cfg.fontDefaultScale;
panelBackgroundOpacity = cfg.panelBackgroundOpacity;
};
location = {
name = cfg.locationName;
weatherEnabled = true;
use12hourFormat = cfg.use12hourFormat;
useFahrenheit = cfg.useFahrenheit;
firstDayOfWeek = cfg.firstDayOfWeek;
hideWeatherTimezone = cfg.hideWeatherTimezone;
};
wallpaper = {
enabled = true;
directory = cfg.wallpaperDirectory;
};
notifications = {
enabled = true;
location = cfg.notificationLocation;
enableMediaToast = cfg.enableMediaToast;
};
osd = {
enabled = true;
location = cfg.osdLocation;
};
nightLight = {
enabled = cfg.enableNightLight;
autoSchedule = true;
nightTemp = cfg.nightLightTemp;
};
systemMonitor = {
useCustomColors = cfg.systemMonitorUseCustomColors;
warningColor = cfg.systemMonitorWarningColor;
criticalColor = cfg.systemMonitorCriticalColor;
};
plugins = {
autoUpdate = cfg.pluginsAutoUpdate;
};
appLauncher = {
position = "center";
sortByMostUsed = true;
viewMode = "list";
};
})
];
}; };
# Disable conflicting services that Noctalia replaces # Disable conflicting services that Noctalia replaces
services.swayosd.enable = mkForce false; services.swayosd.enable = lib.mkForce false;
services.swaync.enable = mkForce false; services.swaync.enable = lib.mkForce false;
# Disable wlsunset - Noctalia has built-in night light # Disable wlsunset - Noctalia has built-in night light
services.wlsunset.enable = mkForce false; services.wlsunset.enable = lib.mkForce false;
# Disable waybar - Noctalia has its own bar # Disable waybar - Noctalia has its own bar
waybarConfig.enable = mkForce false; waybarConfig.enable = lib.mkForce false;
programs.waybar.enable = mkForce false; programs.waybar.enable = lib.mkForce false;
}; };
} }

View File

@ -23,9 +23,19 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
# Enable the systemd service if requested # Enable the systemd service if requested
services.noctalia-shell.enable = cfg.enableSystemdService; # Override package with calendar support for evolution-data-server integration
services.noctalia-shell = {
enable = cfg.enableSystemdService;
package = inputs.noctalia.packages.${pkgs.stdenv.hostPlatform.system}.default.override {
calendarSupport = true;
};
};
# Required system services for Noctalia features # Required system services for Noctalia features
# Evolution data server and Evolution - for calendar events support in Noctalia
services.gnome.evolution-data-server.enable = mkDefault true;
environment.systemPackages = [ pkgs.evolution ];
# NetworkManager - for wifi widget # NetworkManager - for wifi widget
networking.networkmanager.enable = mkDefault true; networking.networkmanager.enable = mkDefault true;