use noctalia shell and niri flake

This commit is contained in:
Joakim Repomaa
2026-05-29 17:51:12 +03:00
parent 8d35120d66
commit 11031dba48
8 changed files with 776 additions and 800 deletions

View File

@@ -1,6 +1,5 @@
{
config,
osConfig,
lib,
pkgs,
pkgs-unstable,
@@ -8,6 +7,20 @@
self,
...
}:
let
noctalia-package = inputs.noctalia.packages.${pkgs.stdenv.hostPlatform.system}.default.override {
calendarSupport = true;
};
ns = lib.getExe noctalia-package;
ns-ipc =
args:
[
ns
"ipc"
"call"
]
++ args;
in
{
imports = [
../gnome
@@ -19,6 +32,8 @@
inputs.hastebin.nixosModules.hm
inputs.agenix.homeManagerModules.default
inputs.voxtype.homeManagerModules.default
inputs.noctalia.homeModules.default
inputs.niri-flake.homeModules.niri
];
# This value determines the Home Manager release that your configuration is
@@ -119,73 +134,123 @@
${lib.getExe grim} -t ppm -g "$(${lib.getExe slurp} -o -d -F monospace)" - | ${lib.getExe gradia}
'')
inputs.tree_hugger.packages.${stdenv.hostPlatform.system}.default
(writeShellScriptBin "ns" "${lib.join " " (ns-ipc [ ''"$@"'' ])}")
];
programs = {
ashell = {
noctalia-shell = {
enable = true;
package = pkgs-unstable.ashell;
systemd = {
enable = true;
target = "graphical-session.target";
};
settings = {
modules = {
left = [ "Workspaces" ];
center = [ "WindowTitle" ];
right = [
"CustomNotifications"
"SystemInfo"
[
"Clock"
"Privacy"
"Settings"
]
];
};
settings = {
lock_cmd = "hyprlock &";
logout_cmd = "niri msg action quit";
audio_sinks_more_cmd = "pavucontrol -t 3";
audio_sources_more_cmd = "pavucontrol -t 4";
bluetooth_more_cmd = "blueman-manager";
CustomButton =
let
isDark = lib.getExe (
pkgs.writeShellScriptBin "is-dark" ''
gsettings get org.gnome.desktop.interface color-scheme | grep -q dark
''
);
toggleDark = lib.getExe (
pkgs.writeShellScriptBin "toggle-dark" ''
if ${isDark}; then
gsettings set org.gnome.desktop.interface color-scheme 'prefer-light'
else
gsettings set org.gnome.desktop.interface color-scheme 'prefer-dark'
fi
''
);
in
[
bar = {
density = "compact";
position = "top";
showCapsule = false;
widgets = {
left = [
{
name = "Dark Mode";
icon = " ";
command = toggleDark;
status_command = isDark;
id = "Workspace";
hideUnoccupied = true;
labelMode = "none";
}
];
center = [
{
id = "Clock";
formatHorizontal = "HH:mm";
formatVertical = "HH mm";
usePrimaryColor = true;
}
];
right = [
{
id = "plugin:privacy-indicator";
}
{
id = "Battery";
warningThreshold = 20;
}
{
id = "NotificationHistory";
}
{
id = "Network";
}
{
id = "Bluetooth";
}
{
id = "VPN";
}
{
id = "ControlCenter";
useDistroLogo = true;
}
];
};
};
CustomModule = [
{
name = "CustomNotifications";
type = "Button";
icon = " ";
command = "swaync-client -t -sw";
listen_cmd = "swaync-client -swb";
icons."dnd.*" = " ";
alert = ".*notification";
}
];
audio.visualizerType = "linear";
wallpaper = {
overviewEnabled = true;
directory = "~/Pictures/Wallpapers";
automationEnabled = true;
};
controlCenter.shortcuts = {
right = [
{ id = "PowerProfile"; }
{ id = "KeepAwake"; }
{ id = "NightLight"; }
{ id = "DarkMode"; }
];
};
sessionMenu = {
countdownDuration = 5000;
powerOptions =
let
powerOption =
action: options:
{
inherit action;
enabled = true;
}
// options;
in
[
(powerOption "lock" {
keybind = "1";
countdownEnabled = false;
})
(powerOption "suspend" {
keybind = "2";
countdownEnabled = false;
})
(powerOption "hibernate" { keybind = "3"; })
(powerOption "reboot" { keybind = "4"; })
(powerOption "logout" { keybind = "5"; })
(powerOption "shutdown" { keybind = "6"; })
(powerOption "rebootToUefi" { keybind = "7"; })
];
};
colorSchemes.useWallpaperColors = true;
nightLight.enabled = true;
idle.enabled = true;
general = {
avatarImage = "~/.face";
radiusRatio = 0.2;
clockStyle = "analog";
};
location = {
monthBeforeDay = false;
analogClockInCalendar = true;
firstDayOfWeek = 0;
showWeekNumberInCalendar = true;
autoLocate = true;
};
package = noctalia-package;
};
};
@@ -518,37 +583,6 @@
enable = true;
defaultEditor = true;
};
hyprlock = {
enable = true;
package = pkgs-unstable.hyprlock;
settings = {
general = {
hide_cursor = true;
ignore_empty_input = true;
};
background = {
monitor = "";
path = "screenshot";
blur_passes = 3;
};
input-field = {
size = "20%, 5%";
monitor = "";
dots_center = true;
fade_on_empty = false;
rounding = 15;
shadow_passes = 2;
outline_thickness = 2;
placeholder_text = "Password...";
fail_text = "$PAMFAIL";
dots_spacing = "0.3";
position = "0, -20";
halign = "center";
valign = "center";
};
};
};
voxtype = {
enable = true;
package = inputs.voxtype.packages.${pkgs.stdenv.hostPlatform.system}.vulkan;
@@ -764,47 +798,6 @@
};
services = {
swaync = {
enable = true;
package = pkgs-unstable.swaynotificationcenter;
settings = {
scripts = {
focus-window =
let
jq = lib.getExe pkgs.jq;
niri = lib.getExe osConfig.programs.niri.package;
script = pkgs.writeShellScriptBin "swaync-focus-window" ''
set -e
APP_NAME="''${SWAYNC_APP_NAME:-}"
DESKTOP_ENTRY="''${SWAYNC_DESKTOP_ENTRY:-}"
APP_ID=""
if [[ -n "$DESKTOP_ENTRY" ]]; then
APP_ID="$DESKTOP_ENTRY"
elif [[ -n "$APP_NAME" ]]; then
APP_ID=$(echo "$APP_NAME" | tr '[:upper:]' '[:lower:]' | sed 's/ //g')
fi
[[ -z "$APP_ID" ]] && exit
# Find window ID for this app in niri and focus it
${jq} -r --arg app_id "$APP_ID" '.[] | select(.app_id | ascii_downcase | contains($app_id)) | .id' \
<(${niri} msg --json windows 2>/dev/null) | head -n1 | while read -r WINDOW_ID; do
if [[ -n "$WINDOW_ID" && "$WINDOW_ID" != "null" ]]; then
${niri} msg action focus-window --id "$WINDOW_ID"
fi
done
'';
in
{
exec = lib.getExe script;
run-on = "action";
};
};
};
};
gpg-agent = with pkgs; {
enable = true;
enableSshSupport = true;
@@ -949,7 +942,432 @@
};
};
xdg.configFile."niri/config.kdl".source = ./dotfiles/niri.kdl;
programs.niri =
let
bind =
{
modifiers,
key,
action,
args ? [ ],
}:
{
${lib.join "+" (modifiers ++ [ key ])}.action.${action} = args;
};
in
{
enable = true;
package = pkgs-unstable.niri;
settings = {
input = {
keyboard = {
xkb = {
layout = "us";
variant = "altgr-intl";
};
numlock = true;
};
touchpad = {
tap = true;
dwt = true;
dwtp = true;
natural-scroll = true;
};
focus-follows-mouse = {
enable = true;
max-scroll-amount = "10%";
};
};
outputs = {
"eDP-1" = {
scale = 1.5;
};
"DP-5" = {
scale = 1.0;
};
"DP-3" = {
scale = 1.2;
};
};
layout = {
gaps = 5;
center-focused-column = "never";
preset-column-widths = [
{ proportion = 1.0 / 3.0; }
{ proportion = 1.0 / 2.0; }
{ proportion = 2.0 / 3.0; }
];
default-column-width = {
proportion = 1.0 / 2.0;
};
focus-ring = {
enable = true;
width = 4;
active.color = "#7fc8ff";
inactive.color = "#505050";
};
border = {
enable = false;
width = 4;
active.color = "#ffc87f";
inactive.color = "#505050";
urgent.color = "#9b0000";
};
shadow = {
enable = true;
softness = 30;
spread = 5;
offset = {
x = 0;
y = 5;
};
color = "#0007";
};
};
spawn-at-startup = [
{ argv = [ ns ]; }
];
hotkey-overlay.skip-at-startup = true;
screenshot-path = "~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png";
debug.honor-xdg-activation-with-invalid-serial = true;
layer-rules = [
{
matches = [ { namespace = "^noctalia-overview*"; } ];
place-within-backdrop = true;
}
];
window-rules = [
{
matches = [
{
app-id = "firefox$";
title = "^Picture-in-Picture$";
}
];
open-floating = true;
}
{
geometry-corner-radius = {
top-left = 14.;
top-right = 14.;
bottom-left = 14.;
bottom-right = 14.;
};
clip-to-geometry = true;
}
#{
# background-effect = {
# blur = true;
# xray = false;
# };
#}
];
binds = lib.foldl' (acc: x: acc // x) { } (
[
{
"Mod+Shift+Slash" = {
action.show-hotkey-overlay = [ ];
};
"Mod+Return" = {
hotkey-overlay.title = "Open a Terminal: kitty";
action.spawn = "kitty";
};
"Mod+Z" = {
hotkey-overlay.title = "Open a launcher: walker";
action.spawn = "walker";
};
"Mod+Space" = {
action.spawn = "voxtoggle";
};
"Mod+Alt+L" = {
hotkey-overlay.title = "Lock the Screen: hyprlock";
action.spawn = ns-ipc [
"lockScreen"
"lock"
];
};
"XF86AudioRaiseVolume" = {
allow-when-locked = true;
action.spawn = ns-ipc [
"volume"
"increase"
];
};
"XF86AudioLowerVolume" = {
allow-when-locked = true;
action.spawn = ns-ipc [
"volume"
"decrease"
];
};
"XF86AudioMute" = {
allow-when-locked = true;
action.spawn = ns-ipc [
"volume"
"muteOutput"
];
};
"XF86AudioMicMute" = {
allow-when-locked = true;
action.spawn = ns-ipc [
"volume"
"muteInput"
];
};
"XF86AudioPlay" = {
allow-when-locked = true;
action.spawn = ns-ipc [
"media"
"playPause"
];
};
"XF86AudioPrev" = {
allow-when-locked = true;
action.spawn = ns-ipc [
"media"
"previous"
];
};
"XF86AudioNext" = {
allow-when-locked = true;
action.spawn = ns-ipc [
"media"
"next"
];
};
"XF86MonBrightnessUp" = {
allow-when-locked = true;
action.spawn = ns-ipc [
"brightness"
"increase"
];
};
"XF86MonBrightnessDown" = {
allow-when-locked = true;
action.spawn = ns-ipc [
"brightness"
"decrease"
];
};
"Mod+O" = {
repeat = false;
action.toggle-overview = [ ];
};
"Mod+Backspace" = {
repeat = false;
action.close-window = [ ];
};
"Mod+BracketLeft".action.consume-or-expel-window-left = [ ];
"Mod+BracketRight".action.consume-or-expel-window-right = [ ];
"Mod+Comma".action.consume-window-into-column = [ ];
"Mod+Period".action.expel-window-from-column = [ ];
"Mod+R".action.switch-preset-column-width = [ ];
"Mod+Ctrl+R".action.switch-preset-window-height = [ ];
"Mod+Shift+R".action.reset-window-height = [ ];
"Mod+F".action.maximize-column = [ ];
"Mod+Shift+F".action.fullscreen-window = [ ];
"Mod+M".action.maximize-window-to-edges = [ ];
"Mod+Ctrl+F".action.expand-column-to-available-width = [ ];
"Mod+C".action.center-column = [ ];
"Mod+Ctrl+C".action.center-visible-columns = [ ];
"Mod+Minus".action.set-column-width = "-10%";
"Mod+Equal".action.set-column-width = "+10%";
"Mod+Shift+Minus".action.set-window-height = "-10%";
"Mod+Shift+Equal".action.set-window-height = "+10%";
"Mod+V".action.toggle-window-floating = [ ];
"Mod+Shift+V".action.switch-focus-between-floating-and-tiling = [ ];
"Mod+W".action.toggle-column-tabbed-display = [ ];
"Print".action.spawn = "scrot";
"Mod+Escape" = {
allow-inhibiting = true;
action.toggle-keyboard-shortcuts-inhibit = [ ];
};
"Mod+Shift+E".action.quit = [ ];
"Ctrl+Alt+Delete".action.quit = [ ];
"Mod+Shift+P".action.power-off-monitors = [ ];
}
]
++ (map
(
{
dir,
keys,
}:
(lib.mergeAttrsList (
map
(
{ modifiers, action }: (lib.mergeAttrsList (map (key: bind { inherit modifiers key action; }) keys))
)
[
{
modifiers = [ "Mod" ];
action = "focus-column-${dir}";
}
{
modifiers = [
"Mod"
"Shift"
];
action = "move-column-${dir}";
}
{
modifiers = [
"Mod"
"Ctrl"
];
action = "focus-monitor-${dir}";
}
{
modifiers = [
"Mod"
"Shift"
"Ctrl"
];
action = "move-column-to-monitor-${dir}";
}
]
))
)
[
{
dir = "left";
keys = [
"Left"
"H"
];
}
{
dir = "right";
keys = [
"Right"
"L"
];
}
]
)
++ (map
(
{
dir,
keys,
}:
(lib.mergeAttrsList (
map
(
{ modifiers, action }: (lib.mergeAttrsList (map (key: bind { inherit modifiers key action; }) keys))
)
[
{
modifiers = [ "Mod" ];
action = "focus-window-or-workspace-${dir}";
}
{
modifiers = [
"Mod"
"Shift"
];
action = "move-window-${dir}-or-to-workspace-${dir}";
}
{
modifiers = [
"Mod"
"Ctrl"
];
action = "focus-monitor-${dir}";
}
{
modifiers = [
"Mod"
"Shift"
"Ctrl"
];
action = "move-column-to-monitor-${dir}";
}
]
))
)
[
{
dir = "up";
keys = [
"Up"
"K"
];
}
{
dir = "down";
keys = [
"Down"
"J"
];
}
]
)
++ [
{
"Mod+Home".action.focus-column-first = [ ];
"Mod+End".action.focus-column-last = [ ];
"Mod+Shift+Home".action.move-column-to-first = [ ];
"Mod+Shift+End".action.move-column-to-last = [ ];
"Mod+Page_Down".action.focus-workspace-down = [ ];
"Mod+Page_Up".action.focus-workspace-up = [ ];
"Mod+U".action.focus-workspace-down = [ ];
"Mod+I".action.focus-workspace-up = [ ];
"Mod+Ctrl+Page_Down".action.move-column-to-workspace-down = [ ];
"Mod+Ctrl+Page_Up".action.move-column-to-workspace-up = [ ];
"Mod+Ctrl+U".action.move-column-to-workspace-down = [ ];
"Mod+Ctrl+I".action.move-column-to-workspace-up = [ ];
"Mod+Shift+Page_Down".action.move-workspace-down = [ ];
"Mod+Shift+Page_Up".action.move-workspace-up = [ ];
"Mod+Shift+U".action.move-workspace-down = [ ];
"Mod+Shift+I".action.move-workspace-up = [ ];
"Mod+WheelScrollDown" = {
cooldown-ms = 150;
action.focus-workspace-down = [ ];
};
"Mod+WheelScrollUp" = {
cooldown-ms = 150;
action.focus-workspace-up = [ ];
};
"Mod+Ctrl+WheelScrollDown" = {
cooldown-ms = 150;
action.move-column-to-workspace-down = [ ];
};
"Mod+Ctrl+WheelScrollUp" = {
cooldown-ms = 150;
action.move-column-to-workspace-up = [ ];
};
"Mod+WheelScrollRight".action.focus-column-right = [ ];
"Mod+WheelScrollLeft".action.focus-column-left = [ ];
"Mod+Ctrl+WheelScrollRight".action.move-column-right = [ ];
"Mod+Ctrl+WheelScrollLeft".action.move-column-left = [ ];
"Mod+Shift+WheelScrollDown".action.focus-column-right = [ ];
"Mod+Shift+WheelScrollUp".action.focus-column-left = [ ];
"Mod+Ctrl+Shift+WheelScrollDown".action.move-column-right = [ ];
"Mod+Ctrl+Shift+WheelScrollUp".action.move-column-left = [ ];
}
]
++ (map (number: {
"Mod+${toString number}".action.focus-workspace = number;
"Mod+Shift+${toString number}".action.move-column-to-workspace = number;
}) (lib.range 1 9))
);
};
};
gnome.automaticTimeZone = true;
gtk.enable = true;