350 lines
9.9 KiB
Nix
Executable File
350 lines
9.9 KiB
Nix
Executable File
{
|
|
lib,
|
|
pkgs,
|
|
window_manager,
|
|
systemName,
|
|
...
|
|
}:
|
|
|
|
let
|
|
isLaptop = systemName == "laptop";
|
|
isPc = systemName == "pc";
|
|
|
|
# Match hyprland definitions
|
|
mod = "Alt";
|
|
terminal = "footclient";
|
|
fileManager = "thunar";
|
|
runner = "dms ipc call spotlight toggle";
|
|
browser = "firefox";
|
|
editor = "emacsclient -c";
|
|
in
|
|
{
|
|
programs.niri = {
|
|
enable = window_manager == "niri" || window_manager == "all";
|
|
|
|
settings = {
|
|
# Input configuration (aligned with hyprland)
|
|
input = {
|
|
keyboard = {
|
|
xkb.layout = lib.mkMerge [
|
|
(lib.mkIf isLaptop "ie")
|
|
(lib.mkIf isPc "us")
|
|
];
|
|
repeat-rate = 40;
|
|
repeat-delay = 500;
|
|
};
|
|
|
|
touchpad = {
|
|
tap = true;
|
|
natural-scroll = false; # Match hyprland
|
|
dwt = true;
|
|
};
|
|
|
|
mouse = {
|
|
accel-profile = "flat";
|
|
};
|
|
|
|
focus-follows-mouse = {
|
|
enable = true;
|
|
max-scroll-amount = "0%"; # Don't scroll/center on hover, only on click
|
|
};
|
|
};
|
|
|
|
# Layout settings (aligned with hyprland gaps)
|
|
layout = {
|
|
gaps = 10; # hyprland: gaps_out = 10
|
|
center-focused-column = "always";
|
|
|
|
preset-column-widths = [
|
|
{ proportion = 1.0 / 3.0; }
|
|
{ proportion = 1.0 / 2.0; }
|
|
{ proportion = 2.0 / 3.0; }
|
|
{ proportion = 0.9; }
|
|
];
|
|
|
|
default-column-width = {
|
|
proportion = 0.95;
|
|
};
|
|
|
|
focus-ring = {
|
|
enable = true; # Hyprland doesn't have separate focus ring
|
|
};
|
|
|
|
border = {
|
|
enable = true;
|
|
};
|
|
|
|
shadow = {
|
|
enable = true;
|
|
softness = 30;
|
|
spread = 5;
|
|
offset = {
|
|
x = 0;
|
|
y = 5;
|
|
};
|
|
color = "#00000070";
|
|
};
|
|
};
|
|
|
|
# Startup programs (aligned with hyprland exec-once)
|
|
spawn-at-startup = [
|
|
{ command = [ "xwayland-satellite" ]; }
|
|
{
|
|
command = [
|
|
"fcitx5"
|
|
"-d"
|
|
];
|
|
}
|
|
{
|
|
command = [
|
|
"foot"
|
|
"-s"
|
|
];
|
|
}
|
|
{
|
|
command = [
|
|
"sh"
|
|
"-c"
|
|
"systemctl --user import-environment DBUS_SESSION_BUS_ADDRESS WAYLAND_DISPLAY XDG_SESSION_TYPE XDG_CURRENT_DESKTOP XDG_SESSION_DESKTOP QT_QPA_PLATFORMTHEME GTK_THEME"
|
|
];
|
|
}
|
|
{
|
|
command = [
|
|
"dbus-update-activation-environment"
|
|
"--systemd"
|
|
"--all"
|
|
];
|
|
}
|
|
];
|
|
|
|
# Prefer server-side decorations
|
|
prefer-no-csd = true;
|
|
|
|
# Screenshot path
|
|
screenshot-path = "~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png";
|
|
|
|
# Environment variables
|
|
environment = {
|
|
DISPLAY = ":0";
|
|
};
|
|
|
|
# Hotkey overlay settings
|
|
hotkey-overlay.skip-at-startup = true;
|
|
|
|
# Keybinds (aligned with hyprland)
|
|
binds = {
|
|
# App launchers (matching hyprland)
|
|
"${mod}+Return".action.spawn = [ terminal ];
|
|
"${mod}+B".action.spawn = [ browser ];
|
|
"${mod}+F".action.spawn = [ fileManager ];
|
|
"${mod}+D".action.spawn = [
|
|
"sh"
|
|
"-c"
|
|
runner
|
|
];
|
|
"${mod}+E".action.spawn = [
|
|
"sh"
|
|
"-c"
|
|
editor
|
|
];
|
|
|
|
# Audio control (using pamixer like hyprland)
|
|
"XF86AudioRaiseVolume".action.spawn = [
|
|
"pamixer"
|
|
"-i"
|
|
"5"
|
|
];
|
|
"XF86AudioLowerVolume".action.spawn = [
|
|
"pamixer"
|
|
"-d"
|
|
"5"
|
|
];
|
|
"XF86AudioMute".action.spawn = [
|
|
"pamixer"
|
|
"--toggle-mute"
|
|
];
|
|
"XF86AudioMicMute".action.spawn = [
|
|
"wpctl"
|
|
"set-mute"
|
|
"@DEFAULT_AUDIO_SOURCE@"
|
|
"toggle"
|
|
];
|
|
|
|
# Media controls (matching hyprland)
|
|
"XF86AudioNext".action.spawn = [
|
|
"playerctl"
|
|
"next"
|
|
];
|
|
"XF86AudioPrev".action.spawn = [
|
|
"playerctl"
|
|
"previous"
|
|
];
|
|
"XF86AudioPlay".action.spawn = [
|
|
"playerctl"
|
|
"play-pause"
|
|
];
|
|
"XF86AudioPause".action.spawn = [
|
|
"playerctl"
|
|
"play-pause"
|
|
];
|
|
|
|
# Brightness control
|
|
"XF86MonBrightnessUp".action.spawn = [
|
|
"sh"
|
|
"-c"
|
|
"dms ipc call brightness increment 5"
|
|
];
|
|
"XF86MonBrightnessDown".action.spawn = [
|
|
"sh"
|
|
"-c"
|
|
"dms ipc call brightness decrement 5"
|
|
];
|
|
|
|
# Window management (matching hyprland)
|
|
"${mod}+Q".action.close-window = { };
|
|
"${mod}+M".action.quit = { }; # Match hyprland exit
|
|
"${mod}+V".action.toggle-window-floating = { };
|
|
"${mod}+T".action.fullscreen-window = { }; # Match hyprland fullscreen
|
|
|
|
# Screenshots (using dms like hyprland)
|
|
"Print".action.spawn = [
|
|
"dms"
|
|
"screenshot"
|
|
];
|
|
"${mod}+F1".action.spawn = [
|
|
"sh"
|
|
"-c"
|
|
"dms ipc call keybinds toggle niri"
|
|
];
|
|
"${mod}+Backslash".action.spawn = [
|
|
"sh"
|
|
"-c"
|
|
"dms ipc call notepad toggle"
|
|
];
|
|
|
|
# Focus navigation (vim-style, with workspace wraparound for j/k)
|
|
"${mod}+H".action.focus-column-or-monitor-left = { };
|
|
"${mod}+J".action.focus-window-or-workspace-down = { };
|
|
"${mod}+K".action.focus-window-or-workspace-up = { };
|
|
"${mod}+L".action.focus-column-or-monitor-right = { };
|
|
|
|
# Move windows (matching hyprland)
|
|
"${mod}+Shift+H".action.move-column-left = { };
|
|
"${mod}+Shift+J".action.move-window-down = { };
|
|
"${mod}+Shift+K".action.move-window-up = { };
|
|
"${mod}+Shift+L".action.move-column-right = { };
|
|
|
|
# Monitor focus
|
|
"${mod}+Ctrl+H".action.focus-monitor-left = { };
|
|
"${mod}+Ctrl+J".action.focus-monitor-down = { };
|
|
"${mod}+Ctrl+K".action.focus-monitor-up = { };
|
|
"${mod}+Ctrl+L".action.focus-monitor-right = { };
|
|
|
|
# Move to monitor
|
|
"${mod}+Ctrl+Shift+H".action.move-column-to-monitor-left = { };
|
|
"${mod}+Ctrl+Shift+J".action.move-column-to-monitor-down = { };
|
|
"${mod}+Ctrl+Shift+K".action.move-column-to-monitor-up = { };
|
|
"${mod}+Ctrl+Shift+L".action.move-column-to-monitor-right = { };
|
|
|
|
# Workspace numbers (matching hyprland)
|
|
"${mod}+1".action.focus-workspace = 1;
|
|
"${mod}+2".action.focus-workspace = 2;
|
|
"${mod}+3".action.focus-workspace = 3;
|
|
"${mod}+4".action.focus-workspace = 4;
|
|
"${mod}+5".action.focus-workspace = 5;
|
|
"${mod}+6".action.focus-workspace = 6;
|
|
"${mod}+7".action.focus-workspace = 7;
|
|
"${mod}+8".action.focus-workspace = 8;
|
|
"${mod}+9".action.focus-workspace = 9;
|
|
"${mod}+0".action.focus-workspace = 10;
|
|
|
|
"${mod}+Shift+1".action.move-column-to-workspace = 1;
|
|
"${mod}+Shift+2".action.move-column-to-workspace = 2;
|
|
"${mod}+Shift+3".action.move-column-to-workspace = 3;
|
|
"${mod}+Shift+4".action.move-column-to-workspace = 4;
|
|
"${mod}+Shift+5".action.move-column-to-workspace = 5;
|
|
"${mod}+Shift+6".action.move-column-to-workspace = 6;
|
|
"${mod}+Shift+7".action.move-column-to-workspace = 7;
|
|
"${mod}+Shift+8".action.move-column-to-workspace = 8;
|
|
"${mod}+Shift+9".action.move-column-to-workspace = 9;
|
|
"${mod}+Shift+0".action.move-column-to-workspace = 10;
|
|
|
|
# Scroll through workspaces (matching hyprland mouse scroll)
|
|
"${mod}+WheelScrollDown".action.focus-workspace-down = { };
|
|
"${mod}+WheelScrollUp".action.focus-workspace-up = { };
|
|
|
|
# Column management (niri-specific, kept similar)
|
|
"${mod}+Comma".action.consume-window-into-column = { };
|
|
"${mod}+Period".action.expel-window-from-column = { };
|
|
"${mod}+BracketLeft".action.consume-or-expel-window-left = { };
|
|
"${mod}+BracketRight".action.consume-or-expel-window-right = { };
|
|
"${mod}+Semicolon".action.focus-column-first = { }; # Similar to promote in master layout
|
|
|
|
# Window sizing
|
|
"${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}+R".action.switch-preset-column-width = { };
|
|
"${mod}+Shift+R".action.switch-preset-window-height = { };
|
|
"${mod}+C".action.center-column = { };
|
|
|
|
# Floating
|
|
"${mod}+Shift+V".action.switch-focus-between-floating-and-tiling = { };
|
|
|
|
# Tabs
|
|
"${mod}+W".action.toggle-column-tabbed-display = { };
|
|
|
|
# Window overview (alt-tab replacement)
|
|
"${mod}+Tab".action.toggle-overview = { };
|
|
|
|
# Misc
|
|
"${mod}+Escape".action.toggle-keyboard-shortcuts-inhibit = { };
|
|
"${mod}+Shift+P".action.power-off-monitors = { };
|
|
};
|
|
|
|
# Window rules
|
|
window-rules = [
|
|
#{
|
|
# matches = [
|
|
# { app-id = "firefox"; }
|
|
# { app-id = "thunar"; }
|
|
# { app-id = "vesktop"; }
|
|
# ];
|
|
# default-column-width = {
|
|
# proportion = 0.95;
|
|
# };
|
|
#}
|
|
# Float file dialogs
|
|
{
|
|
matches = [
|
|
{ title = "^Open File$"; }
|
|
{ title = "^Save File$"; }
|
|
];
|
|
open-floating = true;
|
|
}
|
|
|
|
{
|
|
matches = [ { app-id = "vesktop"; } ];
|
|
block-out-from = "screencast";
|
|
}
|
|
];
|
|
};
|
|
};
|
|
|
|
# Redirect the generated config to a different file
|
|
xdg.configFile.niri-config.target = lib.mkForce "niri/generated.kdl";
|
|
|
|
# Create the main config that includes everything
|
|
xdg.configFile."niri/config.kdl".text = ''
|
|
include "generated.kdl"
|
|
include "dms/outputs.kdl"
|
|
include "dms/colors.kdl"
|
|
include "dms/layout.kdl"
|
|
include "dms/alttab.kdl"
|
|
include "dms/binds.kdl"
|
|
include "dms/cursor.kdl"
|
|
'';
|
|
}
|