524 lines
19 KiB
Nix
524 lines
19 KiB
Nix
{
|
||
perSystem,
|
||
osConfig,
|
||
config,
|
||
pkgs,
|
||
lib,
|
||
...
|
||
}: let
|
||
inherit (lib.strings) removeSuffix;
|
||
inherit (lib) mkIf mkEnableOption mkDefault mkForce getExe;
|
||
inherit (config.lib.stylix) colors;
|
||
inherit (config.stylix) cursor;
|
||
inherit (osConfig.module.stylix) theme;
|
||
inherit (osConfig.networking) hostName;
|
||
cfg = config.desktop.niri;
|
||
keyboard =
|
||
if hostName == "eldrid"
|
||
then "chromeos"
|
||
else "platform";
|
||
xdgPics =
|
||
config.xdg.userDirs.pictures;
|
||
ifLaptop = mkIf (hostName != "dunamis");
|
||
launcher = getExe pkgs.fuzzel;
|
||
lockscreen = getExe pkgs.gtklock;
|
||
in {
|
||
options = {
|
||
desktop.niri.enable =
|
||
mkEnableOption "enable niri desktop";
|
||
};
|
||
config = mkIf cfg.enable {
|
||
stylix.targets = {
|
||
waybar.enable = false;
|
||
wpaperd.enable = true;
|
||
qt.enable = false;
|
||
};
|
||
xdg.configFile = {
|
||
niri = {
|
||
target = "niri/config.kdl";
|
||
text = let
|
||
arrows = {
|
||
left = "Left";
|
||
down = "Down";
|
||
up = "Up";
|
||
right = "Right";
|
||
};
|
||
homerow-arrows = {
|
||
left = "n";
|
||
down = "e";
|
||
up = "i";
|
||
right = "o";
|
||
};
|
||
letters = {
|
||
first = "Q";
|
||
second = "W";
|
||
third = "F";
|
||
fourth = "P";
|
||
fifth = "B";
|
||
sixth = "J";
|
||
seventh = "L";
|
||
eighth = "U";
|
||
ninth = "Y";
|
||
};
|
||
numbers = {
|
||
first = "1";
|
||
second = "2";
|
||
third = "3";
|
||
fourth = "4";
|
||
fifth = "5";
|
||
sixth = "6";
|
||
seventh = "7";
|
||
eighth = "8";
|
||
ninth = "9";
|
||
};
|
||
genArrowNavigation = keys: ''
|
||
Mod+${keys.left} { focus-column-left; }
|
||
Mod+${keys.down} { focus-window-or-workspace-down; }
|
||
Mod+${keys.up} { focus-window-or-workspace-up; }
|
||
Mod+${keys.right} { focus-column-right; }
|
||
Mod+Ctrl+${keys.left} { move-column-left; }
|
||
Mod+Ctrl+${keys.down} { move-window-down-or-to-workspace-down; }
|
||
Mod+Ctrl+${keys.up} { move-window-up-or-to-workspace-up; }
|
||
Mod+Ctrl+${keys.right} { move-column-right; }
|
||
Mod+Shift+${keys.left} { focus-monitor-left; }
|
||
Mod+Shift+${keys.down} { focus-monitor-down; }
|
||
Mod+Shift+${keys.up} { focus-monitor-up; }
|
||
Mod+Shift+${keys.right} { focus-monitor-right; }
|
||
Mod+Shift+Ctrl+${keys.left} { move-column-to-monitor-left; }
|
||
Mod+Shift+Ctrl+${keys.down} { move-column-to-monitor-down; }
|
||
Mod+Shift+Ctrl+${keys.up} { move-column-to-monitor-up; }
|
||
Mod+Shift+Ctrl+${keys.right} { move-column-to-monitor-right; }
|
||
'';
|
||
genWorkspacesNavigation = keys: ''
|
||
Mod+${keys.first} { focus-workspace 1; }
|
||
Mod+${keys.second} { focus-workspace 2; }
|
||
Mod+${keys.third} { focus-workspace 3; }
|
||
Mod+${keys.fourth} { focus-workspace 4; }
|
||
Mod+${keys.fifth} { focus-workspace 5; }
|
||
Mod+${keys.sixth} { focus-workspace 6; }
|
||
Mod+${keys.seventh} { focus-workspace 7; }
|
||
Mod+${keys.eighth} { focus-workspace 8; }
|
||
Mod+${keys.ninth} { focus-workspace 9; }
|
||
Mod+Ctrl+Shift+${keys.first} { move-column-to-workspace 1; }
|
||
Mod+Ctrl+Shift+${keys.second} { move-column-to-workspace 2; }
|
||
Mod+Ctrl+Shift+${keys.third} { move-column-to-workspace 3; }
|
||
Mod+Ctrl+Shift+${keys.fourth} { move-column-to-workspace 4; }
|
||
Mod+Ctrl+Shift+${keys.fifth} { move-column-to-workspace 5; }
|
||
Mod+Ctrl+Shift+${keys.sixth} { move-column-to-workspace 6; }
|
||
Mod+Ctrl+Shift+${keys.seventh} { move-column-to-workspace 7; }
|
||
Mod+Ctrl+Shift+${keys.eighth} { move-column-to-workspace 8; }
|
||
Mod+Ctrl+Shift+${keys.ninth} { move-column-to-workspace 9; }
|
||
'';
|
||
in ''
|
||
environment {
|
||
DISPLAY ":123"
|
||
QT_QPA_PLATFORM "wayland"
|
||
QT_QPA_PLATFORMTHEME "gtk3"
|
||
GDK_BACKEND "wayland"
|
||
MOZ_ENABLE_WAYLAND "1"
|
||
MOZ_WEBRENDER "1"
|
||
XDG_SESSION_TYPE "wayland"
|
||
CLUTTER_BACKEND "wayland"
|
||
SDL_VIDEODRIVER "wayland"
|
||
}
|
||
input {
|
||
keyboard {
|
||
xkb {
|
||
layout "us,ua"
|
||
${
|
||
if (hostName == "dunamis" || hostName == "legion")
|
||
then "// variant \"colemak_dh_ortho,\""
|
||
else "variant \"colemak_dh_ortho,\""
|
||
}
|
||
}
|
||
repeat-delay 200
|
||
repeat-rate 50
|
||
track-layout "global"
|
||
}
|
||
touchpad {
|
||
// off
|
||
tap
|
||
// dwt
|
||
// dwtp
|
||
natural-scroll
|
||
accel-speed 0.2
|
||
accel-profile "flat"
|
||
// scroll-method "two-finger"
|
||
// disabled-on-external-mouse
|
||
}
|
||
mouse {
|
||
// off
|
||
// natural-scroll
|
||
accel-speed 0.0
|
||
accel-profile "flat"
|
||
// scroll-method "no-scroll"
|
||
}
|
||
warp-mouse-to-focus
|
||
// focus-follows-mouse
|
||
}
|
||
output "eDP-1" {
|
||
// off
|
||
scale 1.2
|
||
transform "normal"
|
||
// position x=1920 y=0
|
||
}
|
||
output "Samsung Electric Company S24R65x H4TMA03291" {
|
||
position x=0 y=0
|
||
variable-refresh-rate
|
||
}
|
||
output "Philips Consumer Electronics Company 27M2N5500 UK02418033254" {
|
||
mode "2560x1440@${
|
||
if hostName == "legion"
|
||
then "144.001"
|
||
else "180.000"
|
||
}"
|
||
variable-refresh-rate
|
||
position x=0 y=0
|
||
scale 1.33
|
||
}
|
||
output "PNP(AOC) 27V2G5 0x0000026C" {
|
||
position x=1920 y=0
|
||
mode "1920x1080@74.973"
|
||
variable-refresh-rate
|
||
}
|
||
|
||
cursor {
|
||
xcursor-theme "${cursor.name}"
|
||
xcursor-size ${toString cursor.size}
|
||
}
|
||
|
||
layout {
|
||
gaps 6
|
||
center-focused-column "never" // "on-overflow"
|
||
preset-column-widths {
|
||
proportion 0.33333
|
||
proportion 0.66667
|
||
}
|
||
|
||
// default-column-width { proportion 0.9; }
|
||
default-column-width { proportion 0.5; }
|
||
tab-indicator {
|
||
active-color "#${colors.base04}"
|
||
inactive-color "#${colors.base03}"
|
||
corner-radius 4
|
||
gap 6
|
||
gaps-between-tabs 3
|
||
length total-proportion=0.3
|
||
place-within-column
|
||
position "left"
|
||
width 6
|
||
}
|
||
focus-ring {
|
||
// off
|
||
width 3
|
||
active-gradient from="#${colors.base0D}" to="#${colors.base0F}" angle=40 relative-to="workspace-view"
|
||
inactive-color "#${colors.base03}"
|
||
}
|
||
struts {
|
||
left 24
|
||
right 24
|
||
}
|
||
}
|
||
|
||
prefer-no-csd
|
||
|
||
hotkey-overlay {
|
||
skip-at-startup
|
||
}
|
||
window-rule {
|
||
geometry-corner-radius 12
|
||
clip-to-geometry true
|
||
}
|
||
window-rule {
|
||
match is-window-cast-target=true
|
||
focus-ring {
|
||
width 3
|
||
active-color "#${colors.base0F}"
|
||
inactive-color "#${colors.base03}"
|
||
}
|
||
border {
|
||
width 3
|
||
active-color "#${colors.base0F}"
|
||
inactive-color "#${colors.base03}"
|
||
}
|
||
shadow {
|
||
on
|
||
color "#${colors.base0F}"
|
||
inactive-color "#${colors.base03}"
|
||
}
|
||
}
|
||
|
||
screenshot-path "${xdgPics}/screenshots/screenshot-%Y-%m-%d-%H-%M-%S.png"
|
||
|
||
animations {
|
||
slowdown 0.8
|
||
}
|
||
|
||
window-rule {
|
||
match title="Картинка в картинці"
|
||
match title="Picture-in-Picture"
|
||
open-floating true
|
||
}
|
||
window-rule {
|
||
match app-id="org.wezfurlong.wezterm"
|
||
match app-id="com.mitchellh.ghostty"
|
||
default-column-width { proportion 1.0; }
|
||
}
|
||
window-rule {
|
||
match app-id="re.sonny.Junction"
|
||
open-floating true
|
||
open-focused true
|
||
}
|
||
|
||
window-rule {
|
||
match app-id="com.mitchellh.ghostty"
|
||
draw-border-with-background false
|
||
}
|
||
|
||
window-rule {
|
||
match app-id=r#"^org\.keepassxc\.KeePassXC$"#
|
||
match app-id=r#"^org\.gnome\.World\.Secrets$"#
|
||
match app-id=r#"^Bitwarden$"#
|
||
match app-id="org.telegram.desktop"
|
||
match app-id="org.signal.Signal"
|
||
match app-id="WebCord"
|
||
// block-out-from "screen-capture"
|
||
block-out-from "screencast"
|
||
}
|
||
|
||
binds {
|
||
Mod+Shift+Slash { show-hotkey-overlay; }
|
||
|
||
Mod+Tab { focus-workspace-previous; }
|
||
Mod+C { center-column; }
|
||
Mod+M { maximize-column; }
|
||
Mod+H { set-column-width "50%"; }
|
||
Mod+T { set-column-width "33%"; }
|
||
Mod+Shift+T { set-column-width "67%"; }
|
||
Mod+V { toggle-column-tabbed-display; }
|
||
Mod+G { switch-focus-between-floating-and-tiling; }
|
||
|
||
Mod+Ctrl+Comma { consume-or-expel-window-left; }
|
||
Mod+Ctrl+Period { consume-or-expel-window-right; }
|
||
|
||
Mod+Ctrl+Q { close-window; }
|
||
Mod+Ctrl+M { fullscreen-window; }
|
||
Mod+Ctrl+G { toggle-window-floating; }
|
||
|
||
Mod+Minus { set-column-width "-10%"; }
|
||
Mod+Equal { set-column-width "+10%"; }
|
||
Mod+Comma { set-column-width "-10%"; }
|
||
Mod+Period { set-column-width "+10%"; }
|
||
Mod+Shift+Comma { set-window-height "-10%"; }
|
||
Mod+Shift+Period { set-window-height "+10%"; }
|
||
|
||
Mod+Escape { switch-layout "next"; }
|
||
|
||
Mod+Return repeat=false { spawn "sh" "-c" "$TERMINAL"; }
|
||
Mod+Space repeat=false { spawn "${launcher}"; }
|
||
Mod+Ctrl+L repeat=false { spawn "${lockscreen}"; }
|
||
Mod+Ctrl+V repeat=false { spawn "copyq" "toggle"; }
|
||
|
||
Mod+Ctrl+Shift+BracketLeft { quit; }
|
||
Mod+Ctrl+Shift+BracketRight { power-off-monitors; }
|
||
|
||
Print { screenshot; }
|
||
Ctrl+Print { screenshot-screen; }
|
||
Shift+Print { screenshot-window; }
|
||
|
||
// Caps_Lock { spawn "swayosd-client" "--caps-lock"; }
|
||
// XF86AudioRaiseVolume allow-when-locked=true { spawn "wpctl" "set-volume" "-l" "1.0" "@DEFAULT_AUDIO_SINK@" "5%+"; }
|
||
// XF86AudioLowerVolume allow-when-locked=true { spawn "wpctl" "set-volume" "-l" "1.0" "@DEFAULT_AUDIO_SINK@" "5%-"; }
|
||
// XF86AudioMute allow-when-locked=true { spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SINK@" "toggle"; }
|
||
// XF86AudioMicMute allow-when-locked=true { spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SOURCE@" "toggle"; }
|
||
XF86AudioRaiseVolume allow-when-locked=true { spawn "swayosd-client" "--output-volume" "raise"; }
|
||
XF86AudioLowerVolume allow-when-locked=true { spawn "swayosd-client" "--output-volume" "lower"; }
|
||
XF86AudioMute allow-when-locked=true { spawn "swayosd-client" "--output-volume" "mute-toggle"; }
|
||
XF86AudioMicMute allow-when-locked=true { spawn "swayosd-client" "--input-volume" "mute-toggle"; }
|
||
XF86AudioPlay allow-when-locked=true { spawn "playerctl" "play-pause"; }
|
||
XF86AudioPause allow-when-locked=true { spawn "playerctl" "pause"; }
|
||
XF86AudioPrev allow-when-locked=true { spawn "playerctl" "previous"; }
|
||
XF86AudioNext allow-when-locked=true { spawn "playerctl" "next"; }
|
||
|
||
XF86ScreenSaver allow-when-locked=true { spawn "${lockscreen}"; }
|
||
XF86MonBrightnessUp allow-when-locked=true { spawn "brightnessctl" "s" "5%+"; }
|
||
XF86MonBrightnessDown allow-when-locked=true { spawn "brightnessctl" "s" "5%-"; }
|
||
Alt+XF86MonBrightnessUp allow-when-locked=true { spawn "brightnessctl" "s" "5%+" "-d" "${keyboard}::kbd_backlight"; }
|
||
Alt+XF86MonBrightnessDown allow-when-locked=true { spawn "brightnessctl" "s" "5%-" "-d" "${keyboard}::kbd_backlight"; }
|
||
XF86KbdBrightnessUp allow-when-locked=true { spawn "brightnessctl" "s" "5%+" "-d" "${keyboard}::kbd_backlight"; }
|
||
XF86KbdBrightnessDown allow-when-locked=true { spawn "brightnessctl" "s" "5%-" "-d" "${keyboard}::kbd_backlight"; }
|
||
|
||
|
||
Mod+Home { focus-column-first; }
|
||
Mod+End { focus-column-last; }
|
||
Mod+Ctrl+Home { move-column-to-first; }
|
||
Mod+Ctrl+End { move-column-to-last; }
|
||
|
||
Mod+Next { focus-workspace-down; }
|
||
Mod+Prior { focus-workspace-up; }
|
||
Mod+Ctrl+Next { move-column-to-workspace-down; }
|
||
Mod+Ctrl+Prior { move-column-to-workspace-up; }
|
||
Mod+Shift+Next { move-workspace-down; }
|
||
Mod+Shift+Prior { move-workspace-up; }
|
||
|
||
Mod+WheelScrollDown cooldown-ms=150 { focus-workspace-down; }
|
||
Mod+WheelScrollUp cooldown-ms=150 { focus-workspace-up; }
|
||
Mod+Ctrl+WheelScrollDown cooldown-ms=150 { move-column-to-workspace-down; }
|
||
Mod+Ctrl+WheelScrollUp cooldown-ms=150 { move-column-to-workspace-up; }
|
||
|
||
Mod+WheelScrollRight { focus-column-right; }
|
||
Mod+WheelScrollLeft { focus-column-left; }
|
||
Mod+Ctrl+WheelScrollRight { move-column-right; }
|
||
Mod+Ctrl+WheelScrollLeft { move-column-left; }
|
||
Mod+Shift+WheelScrollDown { focus-column-right; }
|
||
Mod+Shift+WheelScrollUp { focus-column-left; }
|
||
Mod+Ctrl+Shift+WheelScrollDown { move-column-right; }
|
||
Mod+Ctrl+Shift+WheelScrollUp { move-column-left; }
|
||
|
||
Mod+TouchpadScrollDown { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.02+"; }
|
||
Mod+TouchpadScrollUp { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.02-"; }
|
||
|
||
${genArrowNavigation arrows}
|
||
${genArrowNavigation homerow-arrows}
|
||
${genWorkspacesNavigation letters}
|
||
${genWorkspacesNavigation numbers}
|
||
}
|
||
'';
|
||
};
|
||
};
|
||
services = import ./services {inherit pkgs lockscreen getExe perSystem;};
|
||
programs.fuzzel = import ./programs/fuzzel {inherit config mkDefault;};
|
||
programs.waybar = import ./programs/waybar {inherit colors config getExe ifLaptop pkgs;};
|
||
home.packages = with pkgs;
|
||
[
|
||
# gui libadwaita apps
|
||
celluloid # mpv gui in libadwaita
|
||
helvum # pipewire patchbay in rust
|
||
junction # app chooser
|
||
loupe # image viewer and editor in rust
|
||
mission-center # task manager in rust (partly)
|
||
nautilus # file manager
|
||
overskride # bluetooth gui in rust
|
||
papers # pdf reader in rust
|
||
pika-backup # borg gui in rust
|
||
pwvucontrol # pipewire gui in rust
|
||
wdisplays # wlroots display configurator
|
||
]
|
||
++ [
|
||
# misc utils
|
||
(ifLaptop brightnessctl)
|
||
dconf
|
||
libnotify
|
||
playerctl
|
||
wl-clipboard-rs # wl-clipboard in rust
|
||
];
|
||
|
||
gtk = {
|
||
enable = true;
|
||
iconTheme = {
|
||
name =
|
||
if config.stylix.polarity == "dark"
|
||
then "Papirus-Dark"
|
||
else "Papirus-Light";
|
||
package =
|
||
if (removeSuffix "-light" theme) == "nord"
|
||
then pkgs.papirus-nord
|
||
else pkgs.papirus-icon-theme;
|
||
};
|
||
};
|
||
qt = {
|
||
enable = true;
|
||
platformTheme.name = "gtk3";
|
||
};
|
||
dconf.settings = {
|
||
"org/gnome/desktop/wm/preferences" = {
|
||
button-layout = "icon:close";
|
||
};
|
||
"org/gnome/desktop/interface" = {
|
||
icon-theme = config.gtk.iconTheme.name;
|
||
};
|
||
};
|
||
xdg = {
|
||
mime.enable = true;
|
||
mimeApps = {
|
||
enable = true;
|
||
defaultApplications = let
|
||
file_manager = ["org.gnome.Nautilus.desktop"];
|
||
image_viewer = ["org.gnome.Loupe.desktop"];
|
||
pdf_reader = ["org.gnome.Papers.desktop"];
|
||
video_player = ["io.github.celluloid_player.Celluloid.desktop"];
|
||
web_browser = ["re.sonny.Junction.desktop"];
|
||
in {
|
||
"application/pdf" = pdf_reader;
|
||
"image/jpeg" = image_viewer;
|
||
"image/png" = image_viewer;
|
||
"inode/directory" = file_manager;
|
||
"text/html" = web_browser;
|
||
"video/mp4" = video_player;
|
||
"video/mpeg" = video_player;
|
||
"video/x-matroska" = video_player;
|
||
"video/x-mpeg" = video_player;
|
||
"x-scheme-handler/about" = web_browser;
|
||
"x-scheme-handler/http" = web_browser;
|
||
"x-scheme-handler/https" = web_browser;
|
||
"x-scheme-handler/unknown" = web_browser;
|
||
};
|
||
};
|
||
};
|
||
systemd.user = {
|
||
settings.Manager.DefaultEnvironment = {
|
||
QT_QPA_PLATFORM = "wayland";
|
||
DISPLAY = ":123";
|
||
};
|
||
targets.tray.Unit.Description = "Home Manager System Tray"; # workaround for udiskie
|
||
services = let
|
||
mkGraphicalService = config: graphicalService // config;
|
||
graphicalService = {
|
||
Install.WantedBy = ["niri.service"];
|
||
Unit = {
|
||
Requisite = ["graphical-session.target"];
|
||
PartOf = ["graphical-session.target"];
|
||
After = ["graphical-session.target"];
|
||
};
|
||
Service = {
|
||
Restart = "on-failure";
|
||
TimeoutStopSec = 10;
|
||
RestartSec = 1;
|
||
};
|
||
};
|
||
in {
|
||
udiskie = mkGraphicalService {};
|
||
waybar = mkGraphicalService {};
|
||
network-manager-applet = mkGraphicalService {};
|
||
copyq = mkGraphicalService {
|
||
Service =
|
||
graphicalService.Service
|
||
// {
|
||
Environment = mkForce "QT_QPA_PLATFORM=wayland";
|
||
};
|
||
};
|
||
xwayland-satellite = mkGraphicalService {
|
||
Service =
|
||
graphicalService.Service
|
||
// {
|
||
Type = "simple";
|
||
ExecStart = getExe pkgs.xwayland-satellite + " :123";
|
||
};
|
||
};
|
||
wpaperd = mkGraphicalService {
|
||
Service =
|
||
mkDefault graphicalService.Service;
|
||
};
|
||
gnome-polkit-agent = mkGraphicalService {
|
||
Service =
|
||
graphicalService.Service
|
||
// {
|
||
Type = "simple";
|
||
ExecStart = pkgs.polkit_gnome + "/libexec/polkit-gnome-authentication-agent-1";
|
||
};
|
||
};
|
||
};
|
||
};
|
||
};
|
||
}
|