diff --git a/flake.nix b/flake.nix index f50742a..780a274 100644 --- a/flake.nix +++ b/flake.nix @@ -155,6 +155,7 @@ vars = { desktop = true; gaming = true; + nvidia = true; }; in { diff --git a/hosts/thalia/default.nix b/hosts/thalia/default.nix index 086c48e..8d435bf 100644 --- a/hosts/thalia/default.nix +++ b/hosts/thalia/default.nix @@ -7,6 +7,7 @@ imports = [ # System # ./disko.nix + ./mounts ./hardware-configuration.nix # ./impermanence.nix # Profiles @@ -21,14 +22,14 @@ # Custom modules unfree.enable = true; + nvidia.enable = true; desktop.enable = true; desktop.hostMonitorSettings = " - monitor=desc:Dell Inc. DELL P2419H 250TX53, 1920x1080, 0x0, 1, transform, 1 # Left + monitor=desc:Dell Inc. DELL P2419H 250TX53, 1920x1080, 0x0, 1, transform, 1 # Left monitor=desc:Dell Inc. DELL P2719H F3WNLS2, 1920x1080, 1080x840, 1 # Center monitor=desc:Dell Inc. DELL P2719H 93WNLS2, 1920x1080, 3000x840, 1 # Right "; - - # gaming.enable = true; + gaming.enable = true; # gsr.defaultAudioDevice = "alsa_output.usb-Schiit_Audio_Schiit_Modi_-00.analog-stereo.monitor"; # alsa_output.usb-Generic_USB_Audio-00.analog-stereo.monitor # low-latency.enable = false; # vhs-decode.enable = true; @@ -75,7 +76,7 @@ }; networking = { - hostName = "thalia-dev"; + hostName = "thalia"; wireless.enable = false; }; diff --git a/hosts/thalia/mounts/default.nix b/hosts/thalia/mounts/default.nix new file mode 100644 index 0000000..3953f0a --- /dev/null +++ b/hosts/thalia/mounts/default.nix @@ -0,0 +1,27 @@ +{ + username, + pkgs, + ... +}: +{ + environment.systemPackages = with pkgs; [ + cifs-utils + nfs-utils + ]; + + fileSystems = { + "/home/${username}/mnt" = { + device = "/dev/sda1"; + fsType = "auto"; + options = [ + "defaults" + "user" + "rw" + "utf8" + "noauto" + "umask=000" + ]; + }; + services.rpcbind.enable = true; + }; +} diff --git a/modules/apps/coolercontrol/default.nix b/modules/apps/coolercontrol/default.nix new file mode 100644 index 0000000..d9d8280 --- /dev/null +++ b/modules/apps/coolercontrol/default.nix @@ -0,0 +1,35 @@ +{ + lib, + config, + username, + vars, + ... +}: +let + cfg = config.coolercontrol; +in +{ + options = { + coolercontrol = { + enable = lib.mkEnableOption "Enable coolercontrol in NixOS"; + desktopEntry = lib.mkOption { + type = lib.types.bool; + default = true; + }; + }; + }; + config = lib.mkIf cfg.enable { + + # Allow for overclocking + boot.kernelParams = [ "amdgpu.ppfeaturemask=0xffffffff" ]; + + programs = { + coolercontrol = { + enable = true; + nvidiaSupport = vars.nvidia; + }; + }; + + home-manager.users.${username} = { }; + }; +} diff --git a/modules/apps/default.nix b/modules/apps/default.nix index 8c50b05..001e866 100644 --- a/modules/apps/default.nix +++ b/modules/apps/default.nix @@ -1,8 +1,16 @@ { imports = [ + ./coolercontrol ./direnv + ./gamemode + ./gamescope ./git ./hyprland + ./lact + ./mangohud + ./obs + ./steam + ./sunshine ./vscode ]; } diff --git a/modules/apps/gamemode/default.nix b/modules/apps/gamemode/default.nix new file mode 100644 index 0000000..d165874 --- /dev/null +++ b/modules/apps/gamemode/default.nix @@ -0,0 +1,73 @@ +{ + lib, + config, + username, + pkgs, + ... +}: +let + cfg = config.gamemode; + gamemode-start = ( + pkgs.writeShellApplication { + name = "gamemode-start"; + runtimeInputs = with pkgs; [ + libnotify + ]; + text = '' + notify-send -t 3000 -u low 'GameMode' 'GameMode started' -i applications-games -a 'GameMode' + #kscreen-doctor output.DP-1.wcg.enable output.DP-1.hdr.enable output.DP-1.brightness.100; + ''; + } + ); + gamemode-end = ( + pkgs.writeShellApplication { + name = "gamemode-end"; + runtimeInputs = with pkgs; [ + libnotify + ]; + text = '' + notify-send -t 3000 -u low 'GameMode' 'GameMode stopped' -i applications-games -a 'GameMode' + #kscreen-doctor output.DP-1.wcg.disable output.DP-1.hdr.disable output.DP-1.brightness.100; + ''; + } + ); +in +{ + options = { + gamemode = { + enable = lib.mkEnableOption "Enable gamemode in NixOS & home-manager"; + }; + }; + config = lib.mkIf cfg.enable { + programs.gamemode = { + enable = true; + settings = { + general = { + desiredgov = "performance"; + disable_splitlock = 1; + inhibit_screensaver = 1; + ioprio = 0; + renice = 10; + softrealtime = "auto"; + }; + cpu = { + park_cores = "yes"; + pin_cores = "yes"; + }; + gpu = { + apply_gpu_optimisations = "accept-responsibility"; + amd_performance_level = "high"; + }; + custom = { + # https://github.com/Electrostasy/dots/blob/master/hosts/terra/gaming.nix + start = "${lib.getBin gamemode-start}/bin/gamemode-start"; + end = "${lib.getBin gamemode-end}/bin/gamemode-end"; + }; + }; + }; + + users.users.${username}.extraGroups = [ "gamemode" ]; + + home-manager.users.${username} = { }; + }; +} diff --git a/modules/apps/gamescope/default.nix b/modules/apps/gamescope/default.nix new file mode 100644 index 0000000..bb45dee --- /dev/null +++ b/modules/apps/gamescope/default.nix @@ -0,0 +1,38 @@ +{ + lib, + config, + username, + pkgs, + ... +}: +let + cfg = config.gamescope; +in +{ + options = { + gamescope = { + enable = lib.mkEnableOption "Enable gamescope in NixOS & home-manager"; + }; + }; + config = lib.mkIf cfg.enable { + programs.gamescope = { + enable = true; + package = pkgs.gamescope; + capSysNice = false; # 'true' breaks gamescope for Steam https://github.com/NixOS/nixpkgs/issues/292620#issuecomment-2143529075 + }; + # Workaround for above https://github.com/NixOS/nixpkgs/issues/351516#issuecomment-2607156591 + services.ananicy = { + enable = true; + package = pkgs.ananicy-cpp; + rulesProvider = pkgs.ananicy-cpp; + extraRules = [ + { + "name" = "gamescope"; + "nice" = -20; + } + ]; + }; + + home-manager.users.${username} = { }; + }; +} diff --git a/modules/apps/hyprland/default.nix b/modules/apps/hyprland/default.nix index 8462525..6f6303d 100644 --- a/modules/apps/hyprland/default.nix +++ b/modules/apps/hyprland/default.nix @@ -14,6 +14,7 @@ with lib; imports = [ ./waybar.nix ./swaync.nix + ./rofi.nix ]; home-manager.users.${username}.wayland.windowManager.hyprland = { @@ -26,181 +27,190 @@ with lib; in concatStrings [ '' - env = NIXOS_OZONE_WL, 1 - env = NIXPKGS_ALLOW_UNFREE, 1 - env = XDG_CURRENT_DESKTOP, Hyprland - env = XDG_SESSION_TYPE, wayland - env = XDG_SESSION_DESKTOP, Hyprland - env = GDK_BACKEND, wayland, x11 - env = CLUTTER_BACKEND, wayland - env = QT_QPA_PLATFORM=wayland;xcb - env = QT_WAYLAND_DISABLE_WINDOWDECORATION, 1 - env = QT_AUTO_SCREEN_SCALE_FACTOR, 1 - env = SDL_VIDEODRIVER, x11 - env = MOZ_ENABLE_WAYLAND, 1 - exec-once = dbus-update-activation-environment --systemd --all - exec-once = systemctl --user import-environment QT_QPA_PLATFORMTHEME WAYLAND_DISPLAY XDG_CURRENT_DESKTOP - exec-once = killall -q swww;sleep .5 && swww init - exec-once = killall -q waybar;sleep .5 && waybar - exec-once = killall -q swaync;sleep .5 && swaync - exec-once = nm-applet --indicator - exec-once = blueman-applet - exec-once = lxqt-policykit-agent - exec-once = [workspace special silent] foot - exec-once = sleep 1.5 && swww img /home/${username}/Pictures/Wallpapers/pink-desert.jpeg - ${builtins.toString config.desktop.hostMonitorSettings} - exec-once = ${terminal} - general { - gaps_in = 6 - gaps_out = 8 - border_size = 2 - layout = dwindle - resize_on_border = true - } - input { - kb_layout = us - kb_options = grp:alt_shift_toggle - kb_options = caps:super - follow_mouse = 1 - touchpad { - natural_scroll = true - disable_while_typing = true - scroll_factor = 0.8 - tap_button_map = lmr - } - sensitivity = 0 # -1.0 - 1.0, 0 means no modification. - accel_profile = flat - } - windowrule = noborder,^(wofi)$ - windowrule = center,^(wofi)$ - windowrule = center,^(steam)$ - windowrule = float, nm-connection-editor|blueman-manager - windowrule = float, swayimg|vlc|Viewnior|pavucontrol - windowrule = float, nwg-look|qt5ct|mpv - windowrule = float, zoom - windowrulev2 = stayfocused, title:^()$,class:^(steam)$ - windowrulev2 = minsize 1 1, title:^()$,class:^(steam)$ - windowrulev2 = opacity 0.9 0.7, class:^(Brave)$ - windowrulev2 = opacity 0.9 0.7, class:^(thunar)$ - gestures { - workspace_swipe = true - workspace_swipe_fingers = 3 - } - misc { - initial_workspace_tracking = 0 - mouse_move_enables_dpms = true - key_press_enables_dpms = false - } - animations { - enabled = yes - bezier = wind, 0.05, 0.9, 0.1, 1.05 - bezier = winIn, 0.1, 1.1, 0.1, 1.1 - bezier = winOut, 0.3, -0.3, 0, 1 - bezier = liner, 1, 1, 1, 1 - animation = windows, 1, 6, wind, slide - animation = windowsIn, 1, 6, winIn, slide - animation = windowsOut, 1, 5, winOut, slide - animation = windowsMove, 1, 5, wind, slide - animation = border, 1, 1, liner - animation = fade, 1, 10, default - animation = workspaces, 1, 5, wind - animation = specialWorkspace, 1, 4, default, slidefadevert 20% - } - decoration { - rounding = 10 - blur { - enabled = true - size = 5 - passes = 3 - new_optimizations = on - ignore_opacity = off - } - } - plugin { - hyprtrails { - } - } - dwindle { - pseudotile = true - preserve_split = true - } - bind = ${modifier}SHIFT,Q,exit, - bind = ${modifier},ESCAPE,killactive, - bind = ${modifier},GRAVE,toggleSpecialWorkspace - bind = ${modifier},Return,exec,${terminal} - bind = ${modifier}SHIFT,Return,exec,rofi-launcher - bind = ${modifier}SHIFT,W,exec,web-search - bind = ${modifier}ALT,W,exec,wallsetter - bind = ${modifier}SHIFT,N,exec,swaync-client -rs - bind = ${modifier},W,exec,${browser} - bind = ${modifier},E,exec,emopicker9000 - bind = ${modifier},S,exec,screenshootin - bind = ${modifier},D,exec,discord - bind = ${modifier},O,exec,obs - bind = ${modifier},C,exec,hyprpicker -a - bind = ${modifier},G,exec,gimp - bind = ${modifier}SHIFT,G,exec,godot4 - bind = ${modifier},T,exec,thunar - bind = ${modifier},M,exec,spotify - bind = ${modifier},P,pseudo, - bind = ${modifier}SHIFT,I,togglesplit, - bind = ${modifier},F,fullscreen, - bind = ${modifier}SHIFT,F,togglefloating, - bind = ${modifier}SHIFT,left,movewindow,l - bind = ${modifier}SHIFT,right,movewindow,r - bind = ${modifier}SHIFT,up,movewindow,u - bind = ${modifier}SHIFT,down,movewindow,d - bind = ${modifier}SHIFT,h,movewindow,l - bind = ${modifier}SHIFT,l,movewindow,r - bind = ${modifier}SHIFT,k,movewindow,u - bind = ${modifier}SHIFT,j,movewindow,d - bind = ${modifier},left,movefocus,l - bind = ${modifier},right,movefocus,r - bind = ${modifier},up,movefocus,u - bind = ${modifier},down,movefocus,d - bind = ${modifier},h,movefocus,l - bind = ${modifier},l,movefocus,r - bind = ${modifier},k,movefocus,u - bind = ${modifier},j,movefocus,d - bind = ${modifier},1,workspace,1 - bind = ${modifier},2,workspace,2 - bind = ${modifier},3,workspace,3 - bind = ${modifier},4,workspace,4 - bind = ${modifier},5,workspace,5 - bind = ${modifier},6,workspace,6 - bind = ${modifier},7,workspace,7 - bind = ${modifier},8,workspace,8 - bind = ${modifier},9,workspace,9 - bind = ${modifier},0,workspace,10 - bind = ${modifier}SHIFT,SPACE,movetoworkspace,special - bind = ${modifier},SPACE,togglespecialworkspace - bind = ${modifier}SHIFT,1,movetoworkspace,1 - bind = ${modifier}SHIFT,2,movetoworkspace,2 - bind = ${modifier}SHIFT,3,movetoworkspace,3 - bind = ${modifier}SHIFT,4,movetoworkspace,4 - bind = ${modifier}SHIFT,5,movetoworkspace,5 - bind = ${modifier}SHIFT,6,movetoworkspace,6 - bind = ${modifier}SHIFT,7,movetoworkspace,7 - bind = ${modifier}SHIFT,8,movetoworkspace,8 - bind = ${modifier}SHIFT,9,movetoworkspace,9 - bind = ${modifier}SHIFT,0,movetoworkspace,10 - bind = ${modifier}CONTROL,right,workspace,e+1 - bind = ${modifier}CONTROL,left,workspace,e-1 - bind = ${modifier},mouse_down,workspace, e+1 - bind = ${modifier},mouse_up,workspace, e-1 - bindm = ${modifier},mouse:272,movewindow - bindm = ${modifier},mouse:273,resizewindow - bind = ALT,Tab,cyclenext - bind = ALT,Tab,bringactivetotop - bind = ,XF86AudioRaiseVolume,exec,wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+ - bind = ,XF86AudioLowerVolume,exec,wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%- - binde = ,XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle - bind = ,XF86AudioPlay, exec, playerctl play-pause - bind = ,XF86AudioPause, exec, playerctl play-pause - bind = ,XF86AudioNext, exec, playerctl next - bind = ,XF86AudioPrev, exec, playerctl previous - bind = ,XF86MonBrightnessDown,exec,brightnessctl set 5%- - bind = ,XF86MonBrightnessUp,exec,brightnessctl set +5% + env = GBM_BACKEND, nvidia-drm + env = __GLX_VENDOR_LIBRARY_NAME, nvidia + env = ENABLE_VKBASALT, 1 + env = LIBVA_DRIVER_NAME, nvidia + env = NIXOS_OZONE_WL, 1 + env = NIXPKGS_ALLOW_UNFREE, 1 + env = XDG_CURRENT_DESKTOP, Hyprland + env = XDG_SESSION_TYPE, wayland + env = XDG_SESSION_DESKTOP, Hyprland + env = GDK_BACKEND, wayland, x11 + env = CLUTTER_BACKEND, wayland + env = QT_QPA_PLATFORM=wayland;xcb + env = QT_WAYLAND_DISABLE_WINDOWDECORATION, 1 + env = QT_AUTO_SCREEN_SCALE_FACTOR, 1 + env = SDL_VIDEODRIVER, x11 + env = MOZ_ENABLE_WAYLAND, 1 + exec-once = dbus-update-activation-environment --systemd --all + exec-once = systemctl --user import-environment QT_QPA_PLATFORMTHEME WAYLAND_DISPLAY XDG_CURRENT_DESKTOP + exec-once = killall -q swww;sleep .5 && swww init + exec-once = killall -q waybar;sleep .5 && waybar + exec-once = killall -q swaync;sleep .5 && swaync + exec-once = nm-applet --indicator + exec-once = blueman-applet + exec-once = lxqt-policykit-agent + exec-once = [workspace special silent] foot + exec-once = sleep 1.5 && swww img /home/${username}/Pictures/Wallpapers/pink-desert.jpeg + ${builtins.toString config.desktop.hostMonitorSettings} + monitor = Unknown-1, disable + exec-once = ${terminal} + general { + gaps_in = 6 + gaps_out = 8 + border_size = 2 + layout = dwindle + resize_on_border = true + } + cursor { + no_hardware_cursors = true + } + input { + kb_layout = us, in + kb_variant = , hin-wx + kb_options = grp:shift_caps_toggle + kb_options = caps:super + follow_mouse = 1 + touchpad { + natural_scroll = true + disable_while_typing = true + scroll_factor = 0.8 + tap_button_map = lmr + } + sensitivity = 0 # -1.0 - 1.0, 0 means no modification. + accel_profile = flat + } + windowrule = noborder,^(wofi)$ + windowrule = center,^(wofi)$ + windowrule = center,^(steam)$ + windowrule = float, nm-connection-editor|blueman-manager + windowrule = float, swayimg|vlc|Viewnior|pavucontrol + windowrule = float, nwg-look|qt5ct|mpv + windowrule = float, zoom + windowrulev2 = stayfocused, title:^()$,class:^(steam)$ + windowrulev2 = minsize 1 1, title:^()$,class:^(steam)$ + windowrulev2 = opacity 0.9 0.7, class:^(Brave)$ + windowrulev2 = opacity 0.9 0.7, class:^(thunar)$ + gestures { + workspace_swipe = true + workspace_swipe_fingers = 3 + } + misc { + initial_workspace_tracking = 0 + mouse_move_enables_dpms = true + key_press_enables_dpms = false + } + animations { + enabled = yes + bezier = wind, 0.05, 0.9, 0.1, 1.05 + bezier = winIn, 0.1, 1.1, 0.1, 1.1 + bezier = winOut, 0.3, -0.3, 0, 1 + bezier = liner, 1, 1, 1, 1 + animation = windows, 1, 6, wind, slide + animation = windowsIn, 1, 6, winIn, slide + animation = windowsOut, 1, 5, winOut, slide + animation = windowsMove, 1, 5, wind, slide + animation = border, 1, 1, liner + animation = fade, 1, 10, default + animation = workspaces, 1, 5, wind + animation = specialWorkspace, 1, 4, default, slidefadevert 20% + } + decoration { + rounding = 10 + blur { + enabled = true + size = 5 + passes = 3 + new_optimizations = on + ignore_opacity = off + } + } + plugin { + hyprtrails { + } + } + dwindle { + pseudotile = true + preserve_split = true + } + bind = ${modifier}SHIFT,Q,exit, + bind = ${modifier},ESCAPE,killactive, + bind = ${modifier},GRAVE,toggleSpecialWorkspace + bind = ${modifier},Return,exec,${terminal} + bind = ${modifier}SHIFT,Return,exec,rofi-launcher + bind = ${modifier}SHIFT,W,exec,web-search + bind = ${modifier}ALT,W,exec,wallsetter + bind = ${modifier}SHIFT,N,exec,swaync-client -rs + bind = ${modifier},W,exec,${browser} + bind = ${modifier},E,exec,emopicker9000 + bind = ${modifier},S,exec,screenshootin + bind = ${modifier},D,exec,discord + bind = ${modifier},O,exec,obs + bind = ${modifier},C,exec,hyprpicker -a + bind = ${modifier},G,exec,gimp + bind = ${modifier}SHIFT,G,exec,godot4 + bind = ${modifier},T,exec,thunar + bind = ${modifier},M,exec,spotify + bind = ${modifier},P,pseudo, + bind = ${modifier}SHIFT,I,togglesplit, + bind = ${modifier},F,fullscreen, + bind = ${modifier}SHIFT,F,togglefloating, + bind = ${modifier}SHIFT,left,movewindow,l + bind = ${modifier}SHIFT,right,movewindow,r + bind = ${modifier}SHIFT,up,movewindow,u + bind = ${modifier}SHIFT,down,movewindow,d + bind = ${modifier}SHIFT,h,movewindow,l + bind = ${modifier}SHIFT,l,movewindow,r + bind = ${modifier}SHIFT,k,movewindow,u + bind = ${modifier}SHIFT,j,movewindow,d + bind = ${modifier},left,movefocus,l + bind = ${modifier},right,movefocus,r + bind = ${modifier},up,movefocus,u + bind = ${modifier},down,movefocus,d + bind = ${modifier},h,movefocus,l + bind = ${modifier},l,movefocus,r + bind = ${modifier},k,movefocus,u + bind = ${modifier},j,movefocus,d + bind = ${modifier},1,workspace,1 + bind = ${modifier},2,workspace,2 + bind = ${modifier},3,workspace,3 + bind = ${modifier},4,workspace,4 + bind = ${modifier},5,workspace,5 + bind = ${modifier},6,workspace,6 + bind = ${modifier},7,workspace,7 + bind = ${modifier},8,workspace,8 + bind = ${modifier},9,workspace,9 + bind = ${modifier},0,workspace,10 + bind = ${modifier}SHIFT,SPACE,movetoworkspace,special + bind = ${modifier},SPACE,togglespecialworkspace + bind = ${modifier}SHIFT,1,movetoworkspace,1 + bind = ${modifier}SHIFT,2,movetoworkspace,2 + bind = ${modifier}SHIFT,3,movetoworkspace,3 + bind = ${modifier}SHIFT,4,movetoworkspace,4 + bind = ${modifier}SHIFT,5,movetoworkspace,5 + bind = ${modifier}SHIFT,6,movetoworkspace,6 + bind = ${modifier}SHIFT,7,movetoworkspace,7 + bind = ${modifier}SHIFT,8,movetoworkspace,8 + bind = ${modifier}SHIFT,9,movetoworkspace,9 + bind = ${modifier}SHIFT,0,movetoworkspace,10 + bind = ${modifier}CONTROL,right,workspace,e+1 + bind = ${modifier}CONTROL,left,workspace,e-1 + bind = ${modifier},mouse_down,workspace, e+1 + bind = ${modifier},mouse_up,workspace, e-1 + bindm = ${modifier},mouse:272,movewindow + bindm = ${modifier},mouse:273,resizewindow + bind = ALT,Tab,cyclenext + bind = ALT,Tab,bringactivetotop + bind = ,XF86AudioRaiseVolume,exec,wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+ + bind = ,XF86AudioLowerVolume,exec,wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%- + binde = ,XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle + bind = ,XF86AudioPlay, exec, playerctl play-pause + bind = ,XF86AudioPause, exec, playerctl play-pause + bind = ,XF86AudioNext, exec, playerctl next + bind = ,XF86AudioPrev, exec, playerctl previous + bind = ,XF86MonBrightnessDown,exec,brightnessctl set 5%- + bind = ,XF86MonBrightnessUp,exec,brightnessctl set +5% '' ]; }; diff --git a/modules/apps/hyprland/rofi.nix b/modules/apps/hyprland/rofi.nix new file mode 100644 index 0000000..12b5e30 --- /dev/null +++ b/modules/apps/hyprland/rofi.nix @@ -0,0 +1,226 @@ +{ pkgs, username, ... }: + +{ + home-manager.users.${username} = { + home.packages = with pkgs; [ + (writeShellScriptBin "rofi-launcher" '' + if pgrep -x "rofi" > /dev/null; then + # Rofi is running, kill it + pkill -x rofi + exit 0 + fi + rofi -show drun + '') + ]; + programs = { + rofi = { + enable = true; + package = pkgs.rofi-wayland; + extraConfig = { + modi = "drun,filebrowser,run"; + show-icons = true; + icon-theme = "Papirus"; + location = 0; + font = "JetBrainsMono Nerd Font Mono 12"; + drun-display-format = "{icon} {name}"; + display-drun = " Apps"; + display-run = " Run"; + display-filebrowser = " File"; + }; + # theme = + # let + # inherit (config.lib.formats.rasi) mkLiteral; + # in + # { + # "*" = { + # bg = mkLiteral "#${config.stylix.base16Scheme.base00}"; + # bg-alt = mkLiteral "#${config.stylix.base16Scheme.base09}"; + # foreground = mkLiteral "#${config.stylix.base16Scheme.base01}"; + # selected = mkLiteral "#${config.stylix.base16Scheme.base08}"; + # active = mkLiteral "#${config.stylix.base16Scheme.base0B}"; + # text-selected = mkLiteral "#${config.stylix.base16Scheme.base00}"; + # text-color = mkLiteral "#${config.stylix.base16Scheme.base05}"; + # border-color = mkLiteral "#${config.stylix.base16Scheme.base0F}"; + # urgent = mkLiteral "#${config.stylix.base16Scheme.base0E}"; + # }; + # "window" = { + # width = mkLiteral "50%"; + # transparency = "real"; + # orientation = mkLiteral "vertical"; + # cursor = mkLiteral "default"; + # spacing = mkLiteral "0px"; + # border = mkLiteral "2px"; + # border-color = "@border-color"; + # border-radius = mkLiteral "20px"; + # background-color = mkLiteral "@bg"; + # }; + # "mainbox" = { + # padding = mkLiteral "15px"; + # enabled = true; + # orientation = mkLiteral "vertical"; + # children = map mkLiteral [ + # "inputbar" + # "listbox" + # ]; + # background-color = mkLiteral "transparent"; + # }; + # "inputbar" = { + # enabled = true; + # padding = mkLiteral "10px 10px 200px 10px"; + # margin = mkLiteral "10px"; + # background-color = mkLiteral "transparent"; + # border-radius = "25px"; + # orientation = mkLiteral "horizontal"; + # children = map mkLiteral [ + # "entry" + # "dummy" + # "mode-switcher" + # ]; + # background-image = mkLiteral ''url("~/Pictures/Wallpapers/beautifulmountainscape.jpg", width)''; + # }; + # "entry" = { + # enabled = true; + # expand = false; + # width = mkLiteral "20%"; + # padding = mkLiteral "10px"; + # border-radius = mkLiteral "12px"; + # background-color = mkLiteral "@selected"; + # text-color = mkLiteral "@text-selected"; + # cursor = mkLiteral "text"; + # placeholder = "🖥️ Search "; + # placeholder-color = mkLiteral "inherit"; + # }; + # "listbox" = { + # spacing = mkLiteral "10px"; + # padding = mkLiteral "10px"; + # background-color = mkLiteral "transparent"; + # orientation = mkLiteral "vertical"; + # children = map mkLiteral [ + # "message" + # "listview" + # ]; + # }; + # "listview" = { + # enabled = true; + # columns = 2; + # lines = 6; + # cycle = true; + # dynamic = true; + # scrollbar = false; + # layout = mkLiteral "vertical"; + # reverse = false; + # fixed-height = false; + # fixed-columns = true; + # spacing = mkLiteral "10px"; + # background-color = mkLiteral "transparent"; + # border = mkLiteral "0px"; + # }; + # "dummy" = { + # expand = true; + # background-color = mkLiteral "transparent"; + # }; + # "mode-switcher" = { + # enabled = true; + # spacing = mkLiteral "10px"; + # background-color = mkLiteral "transparent"; + # }; + # "button" = { + # width = mkLiteral "5%"; + # padding = mkLiteral "12px"; + # border-radius = mkLiteral "12px"; + # background-color = mkLiteral "@text-selected"; + # text-color = mkLiteral "@text-color"; + # cursor = mkLiteral "pointer"; + # }; + # "button selected" = { + # background-color = mkLiteral "@selected"; + # text-color = mkLiteral "@text-selected"; + # }; + # "scrollbar" = { + # width = mkLiteral "4px"; + # border = 0; + # handle-color = mkLiteral "@border-color"; + # handle-width = mkLiteral "8px"; + # padding = 0; + # }; + # "element" = { + # enabled = true; + # spacing = mkLiteral "10px"; + # padding = mkLiteral "10px"; + # border-radius = mkLiteral "12px"; + # background-color = mkLiteral "transparent"; + # cursor = mkLiteral "pointer"; + # }; + # "element normal.normal" = { + # background-color = mkLiteral "inherit"; + # text-color = mkLiteral "inherit"; + # }; + # "element normal.urgent" = { + # background-color = mkLiteral "@urgent"; + # text-color = mkLiteral "@foreground"; + # }; + # "element normal.active" = { + # background-color = mkLiteral "@active"; + # text-color = mkLiteral "@foreground"; + # }; + # "element selected.normal" = { + # background-color = mkLiteral "@selected"; + # text-color = mkLiteral "@text-selected"; + # }; + # "element selected.urgent" = { + # background-color = mkLiteral "@urgent"; + # text-color = mkLiteral "@text-selected"; + # }; + # "element selected.active" = { + # background-color = mkLiteral "@urgent"; + # text-color = mkLiteral "@text-selected"; + # }; + # "element alternate.normal" = { + # background-color = mkLiteral "transparent"; + # text-color = mkLiteral "inherit"; + # }; + # "element alternate.urgent" = { + # background-color = mkLiteral "transparent"; + # text-color = mkLiteral "inherit"; + # }; + # "element alternate.active" = { + # background-color = mkLiteral "transparent"; + # text-color = mkLiteral "inherit"; + # }; + # "element-icon" = { + # background-color = mkLiteral "transparent"; + # text-color = mkLiteral "inherit"; + # size = mkLiteral "36px"; + # cursor = mkLiteral "inherit"; + # }; + # "element-text" = { + # background-color = mkLiteral "transparent"; + # font = "JetBrainsMono Nerd Font Mono 12"; + # text-color = mkLiteral "inherit"; + # cursor = mkLiteral "inherit"; + # vertical-align = mkLiteral "0.5"; + # horizontal-align = mkLiteral "0.0"; + # }; + # "message" = { + # background-color = mkLiteral "transparent"; + # border = mkLiteral "0px"; + # }; + # "textbox" = { + # padding = mkLiteral "12px"; + # border-radius = mkLiteral "10px"; + # background-color = mkLiteral "@bg-alt"; + # text-color = mkLiteral "@bg"; + # vertical-align = mkLiteral "0.5"; + # horizontal-align = mkLiteral "0.0"; + # }; + # "error-message" = { + # padding = mkLiteral "12px"; + # border-radius = mkLiteral "20px"; + # background-color = mkLiteral "@bg-alt"; + # text-color = mkLiteral "@bg"; + # }; + # }; + }; + }; + }; +} diff --git a/modules/apps/lact/default.nix b/modules/apps/lact/default.nix new file mode 100644 index 0000000..0de4fd4 --- /dev/null +++ b/modules/apps/lact/default.nix @@ -0,0 +1,45 @@ +{ + pkgs, + lib, + config, + ... +}: + +let + cfg = config.lact; +in +{ + # https://reddit.com/r/NixOS/comments/1cwbsqv/how_to_undervolt_amd_grapics_card_and_control_fan/ + # https://github.com/JManch/nixos/blob/main/modules/nixos/upstream/lact.nix + # https://github.com/JManch/nixos/blob/main/modules/nixos/services/lact.nix + options = { + lact = { + enable = lib.mkEnableOption "Enable lact in NixOS"; + }; + }; + config = lib.mkIf cfg.enable { + + # Allow for overclocking + boot.kernelParams = [ "amdgpu.ppfeaturemask=0xffffffff" ]; + + environment.systemPackages = with pkgs; [ + nvtopPackages.amd + lact + ]; + + systemd.services.lact = { + description = "AMDGPU Control Daemon"; + after = [ "multi-user.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + ExecStart = "${pkgs.lact}/bin/lact daemon"; + Type = "simple"; + # Run as root since we need direct hardware access + User = "root"; + Group = "root"; + Restart = "on-failure"; + RestartSec = "5"; + }; + }; + }; +} diff --git a/modules/apps/mangohud/default.nix b/modules/apps/mangohud/default.nix new file mode 100644 index 0000000..f2ef918 --- /dev/null +++ b/modules/apps/mangohud/default.nix @@ -0,0 +1,126 @@ +{ + lib, + config, + username, + ... +}: +let + cfg = config.mangohud; + cpu = if config.networking.hostName == "thalia" then "7950X3D" else ""; + gpu = if config.networking.hostName == "thalia" then "7900XTX" else ""; +in +{ + options = { + mangohud = { + enable = lib.mkEnableOption "Enable mangohud in NixOS & home-manager"; + }; + }; + config = lib.mkIf cfg.enable { + home-manager.users.${username} = + { config, pkgs, ... }: + { + home.file = { + mangohud-config = { + enable = true; + text = '' + pci_dev=0000:03:00.0 + fps + fps_color_change + fps_limit=357,237,141,117,60,0 + fps_value=30,60 + frame_timing + gpu_stats + gpu_temp + gpu_core_clock + gpu_power + gpu_load_change + gpu_load_value=60,90 + gpu_fan + gpu_voltage + gpu_text=${gpu} + cpu_stats + cpu_temp + cpu_power + cpu_mhz + cpu_text=${cpu} + cpu_load_change + cpu_load_value=60,90 + core_load_change + core_load + core_bars + vram + ram + swap + procmem + engine_version + arch + vulkan_driver + wine + winesync + gamemode + vkbasalt + fsr + hdr + refresh_rate + show_fps_limit + resolution + present_mode + display_server # Doesn't work when legacy_layout=0 + gl_vsync=1 + vsync=2 # https://gitlab.freedesktop.org/drm/amd/-/issues/3166#note_2277578 + custom_text=P-State + exec=${pkgs.bat}/bin/bat --plain /sys/devices/system/cpu/amd_pstate/status + custom_text=P-State EPP + exec=${pkgs.bat}/bin/bat --plain /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_preference + custom_text=OS + exec=${pkgs.ripgrep}/bin/rg -w PRETTY_NAME /etc/os-release | ${pkgs.coreutils}/bin/cut -d '=' -f2 | ${pkgs.coreutils}/bin/tr -d '"' + custom_text=Distrobox + exec=${pkgs.bash}/bin/bash -c '[ -n "''${CONTAINER_ID}" ] && echo Yes || echo No' + custom_text=Kernel + exec=${pkgs.coreutils}/bin/uname -r + text_outline + text_outline_thickness=2.0 + position=bottom-right + background_alpha=0.2 + round_corners=10 + no_display + legacy_layout=0 # For scripts that rely on the new layout + font_file=${pkgs.lexend}/share/fonts/truetype/lexend/lexend/Lexend-Bold.ttf + toggle_fps_limit=Shift_R+F1 + toggle_hud=Alt_R+Shift_R + toggle_hud_position=Shift_R+F11 + toggle_preset=Shift_R+F10 + ${lib.optionalString config.catppuccin.enable '' + # Catppuccin theming + background_color=1e1e2e + battery_color=585b70 + cpu_color=89b4fa + cpu_load_color=a6e3a1,f9e2af,f38ba8 + engine_color=cba6f7 + fps_color=f38ba8,f9e2af,a6e3a1 + frametime_color=a6e3a1 + gpu_color=cba6f7 + gpu_load_color=a6e3a1,f9e2af,f38ba8 + io_color=f9e2af + media_player_color=cdd6f4 + ram_color=94e2d5 + text_color=cdd6f4 + text_outline_color=1e1e2e + vram_color=94e2d5 + wine_color=cba6f7 + ''}''; + target = "${config.xdg.configHome}/MangoHud/MangoHud.conf"; + }; + mangohud-presets = { + enable = true; + text = ''''; + target = "${config.xdg.configHome}/MangoHud/presets.conf"; + }; + }; + programs.mangohud = { + enable = true; + package = pkgs.mangohud; + }; + }; + }; +} diff --git a/modules/apps/obs/default.nix b/modules/apps/obs/default.nix new file mode 100644 index 0000000..e7db069 --- /dev/null +++ b/modules/apps/obs/default.nix @@ -0,0 +1,90 @@ +{ + lib, + config, + username, + pkgs, + ... +}: +let + cfg = config.obs; +in +{ + options = { + obs = { + enable = lib.mkEnableOption "Enable obs in home-manager"; + enableFlatpak = lib.mkOption { + type = lib.types.bool; + default = false; + }; + enableNative = lib.mkOption { + type = lib.types.bool; + default = true; + }; + silenceOutput = lib.mkOption { + type = lib.types.bool; + default = true; + }; + }; + }; + config = lib.mkIf cfg.enable { + home-manager.users.${username} = { + home = { + packages = lib.mkIf cfg.enableNative [ + pkgs.obs-cmd + ]; + sessionVariables = lib.mkIf cfg.silenceOutput { + OBS_VKCAPTURE_QUIET = "1"; + }; + }; + programs.obs-studio = { + enable = cfg.enableNative; + plugins = with pkgs.obs-studio-plugins; [ + input-overlay + looking-glass-obs + obs-gstreamer + obs-pipewire-audio-capture + obs-vaapi + obs-vkcapture + ]; + }; + services.flatpak = { + packages = lib.mkIf cfg.enableFlatpak [ + "com.obsproject.Studio" + "com.obsproject.Studio.Plugin.InputOverlay" + "com.obsproject.Studio.Plugin.OBSVkCapture" + "org.freedesktop.Platform.VulkanLayer.OBSVkCapture/x86_64/24.08" + ]; + }; + xdg = { + desktopEntries = { + "com.obsproject.Studio" = lib.mkIf cfg.enableFlatpak { + name = "OBS Studio"; + comment = "Flatpak - Free and Open Source Streaming/Recording Software"; + exec = "flatpak run --branch=stable --arch=x86_64 --command=obs com.obsproject.Studio --disable-shutdown-check"; + terminal = false; + icon = "com.obsproject.Studio"; + type = "Application"; + startupNotify = true; + categories = [ + "AudioVideo" + "Recorder" + ]; + }; + "obs" = lib.mkIf cfg.enableNative { + name = "OBS Studio"; + comment = "Free and Open Source Streaming/Recording Software"; + exec = "obs --disable-shutdown-check"; + terminal = false; + icon = "com.obsproject.Studio"; + type = "Application"; + startupNotify = true; + categories = [ + "AudioVideo" + "Recorder" + ]; + }; + }; + }; + }; + }; +} diff --git a/modules/apps/steam/default.nix b/modules/apps/steam/default.nix new file mode 100644 index 0000000..e623a4d --- /dev/null +++ b/modules/apps/steam/default.nix @@ -0,0 +1,108 @@ +{ + lib, + config, + username, + pkgs, + inputs, + ... +}: +let + cfg = config.steam; +in +{ + options.steam = { + enable = lib.mkEnableOption "Enable Steam in NixOS"; + enableNative = lib.mkOption { + type = lib.types.bool; + default = true; + }; + enableSteamBeta = lib.mkOption { + type = lib.types.bool; + default = true; + }; + # https://reddit.com/r/linux_gaming/comments/16e1l4h/slow_steam_downloads_try_this/ + fixDownloadSpeed = lib.mkOption { + type = lib.types.bool; + default = true; + }; + }; + config = lib.mkIf cfg.enable { + programs.java.enable = true; + programs.steam = { + enable = cfg.enableNative; + dedicatedServer.openFirewall = true; + # extraCompatPackages = with pkgs; [ + # # luxtorpeda + # # inputs.nix-proton-cachyos.packages.${system}.proton-cachyos + # ]; + gamescopeSession.enable = true; + localNetworkGameTransfers.openFirewall = true; + package = pkgs.steam.override { + extraBwrapArgs = [ "--unsetenv TZ" ]; # https://github.com/NixOS/nixpkgs/issues/338266#issuecomment-2419568331 + extraLibraries = + pkgs: with pkgs; [ + alsa-lib + libGL + SDL + SDL_image + SDL_mixer + SDL_ttf + SDL2 + SDL2_image + SDL2_mixer + SDL2_ttf + xorg.libX11 + xorg.libxcb + xorg.libXcursor + xorg.libXi + xorg.libXinerama + xorg.libXext + xorg.libXrandr + xorg.libXrender + xorg.libXScrnSaver + libpng + libpulseaudio + libvorbis + stdenv.cc.cc.lib + libkrb5 + keyutils + ]; + }; + protontricks.enable = true; + remotePlay.openFirewall = true; + }; + home-manager.users.${username} = + { pkgs, config, ... }: + { + home = { + file = { + steam-beta = { + enable = cfg.enableSteamBeta; + text = "publicbeta"; + target = "${config.xdg.dataHome}/Steam/package/beta"; + }; + steam-slow-fix = { + enable = cfg.fixDownloadSpeed; + text = '' + @nClientDownloadEnableHTTP2PlatformLinux 0 + @fDownloadRateImprovementToAddAnotherConnection 1.0 + ''; + target = "${config.xdg.dataHome}/Steam/steam_dev.cfg"; + }; + }; + packages = with pkgs; [ + # SteamTinkerLaunch tools + steamtinkerlaunch + gawk + procps + unixtools.xxd + xdotool + xorg.xprop + xorg.xrandr + xorg.xwininfo + yad + ]; + }; + }; + }; +} diff --git a/modules/apps/sunshine/default.nix b/modules/apps/sunshine/default.nix new file mode 100644 index 0000000..d3424d7 --- /dev/null +++ b/modules/apps/sunshine/default.nix @@ -0,0 +1,42 @@ +{ + lib, + config, + username, + pkgs, + ... +}: +{ + options = { + sunshine = { + enable = lib.mkEnableOption "Enable Sunshine in NixOS"; + }; + }; + config = lib.mkIf config.sunshine.enable { + services.sunshine = { + enable = true; + autoStart = true; + capSysAdmin = true; + openFirewall = true; + applications = { + env = { + PATH = "$(PATH):/run/current-system/sw/bin:/etc/profiles/per-user/${username}/bin:$(HOME)/.local/bin"; + }; + apps = [ + { + name = "Desktop"; + image-path = "desktop.png"; + } + { + name = "Steam Big Picture"; + image-path = "steam.png"; + detached = [ "steam steam://open/bigpicture" ]; + auto-detach = "true"; + wait-all = "true"; + exit-timeout = "5"; + } + ]; + }; + }; + home-manager.users.${username} = { }; + }; +} diff --git a/modules/components/default.nix b/modules/components/default.nix index efa38be..8fc3082 100644 --- a/modules/components/default.nix +++ b/modules/components/default.nix @@ -6,7 +6,7 @@ # ./mounts ./networking ./nix - # ./nvidia + ./nvidia # ./pipewire ./theming # ./users diff --git a/modules/components/nvidia/default.nix b/modules/components/nvidia/default.nix new file mode 100644 index 0000000..af7645a --- /dev/null +++ b/modules/components/nvidia/default.nix @@ -0,0 +1,53 @@ +{ + lib, + config, + username, + pkgs, + ... +}: +let + cfg = config.nvidia; +in +{ + options = { + nvidia = { + enable = lib.mkEnableOption "Enable nvidia in NixOS & home-manager"; + }; + }; + config = lib.mkIf cfg.enable { + boot.kernelPackages = lib.mkForce pkgs.linuxPackages_xanmod_latest; + boot.initrd.kernelModules = [ + "nvidia" + "nvidia_modeset" + "nvidia_uvm" + "nvidia_drm" + ]; + boot.blacklistedKernelModules = [ "nouveau" ]; + boot.kernelParams = [ "nvidia_drm.fbdev=1" "nvidia-drm.modeset=1" "module_blacklist=nouveau" ]; + environment.systemPackages = with pkgs; [ + (writeShellScriptBin "nvidia-offload" '' + export __NV_PRIME_RENDER_OFFLOAD=1 + export __NV_PRIME_RENDER_OFFLOAD_PROVIDER=NVIDIA-G0 + export __GLX_VENDOR_LIBRARY_NAME=nvidia + export __VK_LAYER_NV_optimus=NVIDIA_only + exec -a "$0" "$@" + '') + ]; + hardware = { + graphics.enable = true; + nvidia = { + modesetting.enable = true; + powerManagement.enable = false; + powerManagement.finegrained = false; + open = true; + nvidiaPersistenced = true; + nvidiaSettings = true; + package = config.boot.kernelPackages.nvidiaPackages.latest; + + }; + }; + services.xserver.videoDrivers = [ "nvidia" ]; + + home-manager.users.${username} = { }; + }; +} diff --git a/modules/components/theming/default.nix b/modules/components/theming/default.nix index 2e12517..e999223 100644 --- a/modules/components/theming/default.nix +++ b/modules/components/theming/default.nix @@ -22,7 +22,7 @@ in enable = true; autoEnable = true; image = ./wallpapers/biking-sunset.jpg; - base16Scheme = "${pkgs.base16-schemes}/share/themes/catppuccin-mocha.yaml"; + base16Scheme = "${pkgs.base16-schemes}/share/themes/catppuccin-frappe.yaml"; opacity.terminal = 0.8; cursor.package = pkgs.bibata-cursors; cursor.name = "Bibata-Modern-Ice"; @@ -33,8 +33,8 @@ in name = "JetBrainsMono Nerd Font Mono"; }; sansSerif = { - package = pkgs.montserrat; - name = "Montserrat"; + package = pkgs.inter; + name = "Inter"; }; serif = { package = pkgs.montserrat; @@ -56,13 +56,29 @@ in material-icons ]; }; - home-manager.users.${username}.stylix = { - targets = { - kitty.enable = true; - foot.enable = true; + home-manager.users.${username} = { + stylix = { + targets = { + kitty.enable = true; + foot.enable = true; + mangohud.enable = false; + }; + autoEnable = true; }; - autoEnable = true; - }; + services.xsettingsd = { + settings = { + # "Gtk/CursorThemeSize" = 24; + # "Gtk/CursorThemeName" = "${cursor-theme}"; + # "Gtk/FontName" = "${sans-font}, 12"; + "Net/IconThemeName" = "Papirus-Dark"; + # "Net/ThemeName" = "${GTK-THEME}"; + }; + }; + gtk.iconTheme = { + package = pkgs.catppuccin-papirus-folders; + name = "cat-mocha-lavender"; + }; + }; }; } diff --git a/modules/components/theming/verbose.nix b/modules/components/theming/verbose.nix index deb9fbc..fdc1149 100644 --- a/modules/components/theming/verbose.nix +++ b/modules/components/theming/verbose.nix @@ -413,17 +413,17 @@ in }; }; }; - # xsettingsd = { - # settings = { - # "Gtk/CursorThemeSize" = 24; - # "Gtk/CursorThemeName" = "${cursor-theme}"; - # "Gtk/FontName" = "${sans-font}, 12"; - # "Net/IconThemeName" = "Papirus-Dark"; - # "Net/ThemeName" = "${GTK-THEME}"; - # }; - # }; + xsettingsd = { + settings = { + # "Gtk/CursorThemeSize" = 24; + # "Gtk/CursorThemeName" = "${cursor-theme}"; + # "Gtk/FontName" = "${sans-font}, 12"; + "Net/IconThemeName" = "Papirus-Dark"; + "Net/ThemeName" = "${GTK-THEME}"; + }; + }; }; - + gtk.iconTheme.package = pkgs.catppuccin-papirus-folders; # xresources = { # properties = { # "Xcursor.size" = 24; diff --git a/modules/profiles/default.nix b/modules/profiles/default.nix index bbf259d..027f89e 100644 --- a/modules/profiles/default.nix +++ b/modules/profiles/default.nix @@ -2,11 +2,11 @@ imports = [ ./base.nix ./desktop.nix - # ./gaming.nix + ./gaming.nix # ./hardening.nix ./unfree.nix # ./office.nix ./packages.nix # ./server.nix ]; -} \ No newline at end of file +} diff --git a/modules/profiles/desktop.nix b/modules/profiles/desktop.nix index f51370c..50d6cd1 100644 --- a/modules/profiles/desktop.nix +++ b/modules/profiles/desktop.nix @@ -108,6 +108,7 @@ in home.packages = with pkgs; [ # GUI Apps firefox + ungoogled-chromium filezilla spotify diff --git a/modules/profiles/gaming.nix b/modules/profiles/gaming.nix new file mode 100644 index 0000000..41d13f1 --- /dev/null +++ b/modules/profiles/gaming.nix @@ -0,0 +1,381 @@ +{ + config, + lib, + pkgs, + username, + inputs, + ... +}: +let + cfg = config.gaming; + p = with pkgs; { + games = [ + openttd + prismlauncher # MineCraft + ]; + tools = [ + dolphin-emu + xboxdrv + ## Other + inputs.aaru.packages.${pkgs.system}.default + adwsteamgtk + chiaki-ng + inputs.nix-game-preservation.packages.${pkgs.system}.discimagecreator + ffmpeg + flips + gst_all_1.gstreamer + gst_all_1.gstreamermm + gst_all_1.gst-plugins-rs + gst_all_1.gst-plugins-bad + gst_all_1.gst-plugins-base + gst_all_1.gst-plugins-good + gst_all_1.gst-plugins-ugly + gst_all_1.gst-libav + gst_all_1.gst-vaapi + gswatcher + igir + innoextract + mpg123 + parsec-bin + python313Packages.lnkparse3 + x264 + x265 + xvidcore + ## Wine + inputs.nix-gaming.packages.${pkgs.system}.wine-discord-ipc-bridge + inputs.nix-gaming.packages.${pkgs.system}.wine-tkg + winetricks + # wineWowPackages.stagingFull + ## One-and-dones + glxinfo + /* + jpsxdec + mame.tools + mmv + nsz + ps3-disc-dumper + renderdoc + vgmplay-libvgm + vgmstream + vgmtools + vgmtrans + vulkan-tools + */ + ]; + }; +in +{ + options = { + gaming = { + enable = lib.mkEnableOption "Enable Gaming module in NixOS"; + }; + }; + config = lib.mkIf cfg.enable { + # Custom modules + coolercontrol.enable = true; + gamemode.enable = true; + gamescope.enable = true; + lact.enable = true; + mangohud.enable = true; + obs.enable = true; + steam.enable = true; + sunshine.enable = true; + + boot = { + extraModprobeConfig = '' + options v4l2loopback devices=1 video_nr=1 card_label="OBS Cam" exclusive_caps=1 + ''; + extraModulePackages = with config.boot.kernelPackages; [ + v4l2loopback + ]; + # initrd = { + # kernelModules = [ + # ]; + # }; + kernelParams = [ + # "usbhid.mousepoll=8" # Reduce mouse polling rate to 125hz + "gpu_sched.sched_policy=0" # https://gitlab.freedesktop.org/drm/amd/-/issues/2516#note_2119750 + "amdgpu.mcbp=0" + "tsc=reliable" + "clocksource=tsc" + "preempt=full" # https://reddit.com/r/linux_gaming/comments/1g0g7i0/god_of_war_ragnarok_crackling_audio/lr8j475/?context=3#lr8j475 + ]; + kernel = { + sysctl = { + # "kernel.sched_cfs_bandwidth_slice_us" = 3000; + # "net.ipv4.tcp_fin_timeout" = 5; + "vm.max_map_count" = 2147483642; + "vm.mmap_min_addr" = 0; # SheepShaver + # https://github.com/CachyOS/CachyOS-Settings/blob/master/usr/lib/sysctl.d/99-cachyos-settings.conf + "fs.file-max" = 2097152; + "fs.inotify.max_user_watches" = 524288; + "net.core.netdev_max_backlog" = 16384; + "net.core.somaxconn" = 8192; + "net.ipv4.tcp_slow_start_after_idle" = 0; + }; + }; + }; + + # environment = { + # sessionVariables = { + # # https://reddit.com/r/linux_gaming/comments/1c2ey6u/vrr_newbie_questions_plasma_6_wayland_amd/kzasm0j/?context=3#kzasm0j + # KWIN_DRM_DELAY_VRR_CURSOR_UPDATES = "1"; + # KWIN_FORCE_SW_CURSOR = "1"; + # }; + # }; + + hardware = { + new-lg4ff.enable = true; + uinput.enable = true; + xone.enable = true; + xpadneo.enable = true; + }; + + networking = { + firewall = { + allowedUDPPorts = [ + # Moonlight + 5353 + 47998 + 47999 + 48000 + 48002 + 48010 + ]; + allowedTCPPorts = [ + # Moonlight + 47984 + 47989 + 48010 + ]; + }; + }; + + nix.settings = { + extra-substituters = [ + "https://nix-gaming.cachix.org" + "https://nix-citizen.cachix.org" + ]; + extra-trusted-public-keys = [ + "nix-citizen.cachix.org-1:lPMkWc2X8XD4/7YPEEwXKKBg+SVbYTVrAaLA2wQTKCo=" + "nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4=" + ]; + }; + + nixpkgs.config.permittedInsecurePackages = [ + # "freeimage-unstable-2021-11-01" # Trenchbroom / SLADE + ]; + + services = { + hardware = { + openrgb = { + enable = true; + package = pkgs.openrgb-with-all-plugins; + }; + }; + # joycond.enable = true; + # ratbagd.enable = true; + scx = { + enable = true; + package = pkgs.scx.rustscheds; + scheduler = "scx_rusty"; + }; + # udev = { + # extraRules = '' + # # https://wiki.archlinux.org/title/Improving_performance#Changing_I/O_scheduler + # # HDD + # ACTION=="add|change", KERNEL=="sd[a-z]*", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="bfq" + + # # SSD + # ACTION=="add|change", KERNEL=="sd[a-z]*|mmcblk[0-9]*", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="bfq" + + # # NVMe SSD + # ACTION=="add|change", KERNEL=="nvme[0-9]*", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="none" + # ''; + # packages = with pkgs; [ + # game-devices-udev-rules + # # https://wiki.archlinux.org/title/Gamepad#Motion_controls_taking_over_joypad_controls_and/or_causing_unintended_input_with_joypad_controls + # (writeTextFile { + # name = "51-disable-DS3-and-DS4-motion-controls.rules"; + # text = '' + # SUBSYSTEM=="input", ATTRS{name}=="*Controller Motion Sensors", RUN+="${pkgs.coreutils}/bin/rm %E{DEVNAME}", ENV{ID_INPUT_JOYSTICK}="" + # ''; + # destination = "/etc/udev/rules.d/51-disable-DS3-and-DS4-motion-controls.rules"; + # }) + # # https://reddit.com/r/linux_gaming/comments/1fu4ggk/can_someone_explain_dualsense_to_me/lpwxv12/?context=3#lpwxv12 + # (writeTextFile { + # name = "51-disable-dualsense-sound-and-vibration.rules"; + # text = '' + # KERNEL=="hidraw*", ATTRS{idVendor}=="054c", ATTRS{idProduct}=="0ce6", MODE="0660", TAG+="uaccess" + # KERNEL=="hidraw*", KERNELS=="*054C:0CE6*", MODE="0660", TAG+="uaccess" + # ATTRS{idVendor}=="054c", ATTRS{idProduct}=="0ce6", ENV{PULSE_IGNORE}="1", ENV{ACP_IGNORE}="1" + # ''; + # destination = "/etc/udev/rules.d/51-disable-dualsense-sound-and-vibration.rules"; + # }) + # ]; + # }; + }; + + security = { + pam = { + loginLimits = [ + { + domain = "*"; + item = "memlock"; + type = "hard"; + value = "unlimited"; + } + { + domain = "*"; + item = "memlock"; + type = "soft"; + value = "unlimited"; + } + { + domain = "*"; + item = "nofile"; + type = "hard"; + value = "1048576"; + } + { + domain = "*"; + item = "nofile"; + type = "soft"; + value = "16777216"; + } + ]; + }; + }; + + services = { + input-remapper = { + enable = true; + # enableUdevRules = true; + }; + }; + + systemd = { + extraConfig = '' + DefaultLimitNOFILE=1048576 + ''; + tmpfiles = { + rules = [ + # https://wiki.archlinux.org/title/Gaming#Make_the_changes_permanent + "w /proc/sys/vm/compaction_proactiveness - - - - 0" + "w /proc/sys/vm/watermark_boost_factor - - - - 1" + "w /proc/sys/vm/min_free_kbytes - - - - 1048576" + "w /proc/sys/vm/watermark_scale_factor - - - - 500" + "w /sys/kernel/mm/lru_gen/enabled - - - - 5" + "w /proc/sys/vm/zone_reclaim_mode - - - - 0" + "w /proc/sys/vm/page_lock_unfairness - - - - 1" + "w /proc/sys/kernel/sched_child_runs_first - - - - 0" + "w /proc/sys/kernel/sched_autogroup_enabled - - - - 1" + "w /proc/sys/kernel/sched_cfs_bandwidth_slice_us - - - - 3000" + "w /sys/kernel/debug/sched/base_slice_ns - - - - 3000000" + "w /sys/kernel/debug/sched/migration_cost_ns - - - - 500000" + "w /sys/kernel/debug/sched/nr_migrate - - - - 8" + ]; + }; + }; + + home-manager.users.${username} = + { + inputs, + config, + ... + }: + { + # imports = [ + # ../apps/ludusavi + # ]; + home.file = { + desktop-entry-mangohud = + let + configFile = pkgs.fetchurl { + url = "https://raw.githubusercontent.com/flightlessmango/MangoHud/master/data/MangoHud.conf"; + hash = "sha256-hAZePm8o5/55IlSghWKhBJBi63JtKJQzGYDUn69u1oM="; + }; + in + { + enable = true; + text = '' + [Desktop Entry] + Comment=Create a new MangoHud config from template + Icon=text-x-makefile + Name=MangoHud Config... + Type=Link + URL[$e]=file:${configFile} + ''; + target = "${config.xdg.dataHome}/templates/mangohud.desktop"; + }; + }; + home.sessionVariables = { + # https://gitlab.com/OpenMW/openmw/-/issues/6185 + OSG_VERTEX_BUFFER_HINT = "VERTEX_BUFFER_OBJECT"; + }; + services = { + flatpak = { + overrides = { + "dev.opengoal.OpenGOAL" = { + Context = { + filesystems = [ "${config.home.homeDirectory}/Games/opengoal" ]; + }; + Environment = { + PULSE_SINK = "Game"; + }; + }; + "io.github.noxworld_dev.OpenNox" = { + Context = { + filesystems = [ + "!home" + "${config.home.homeDirectory}/Games/nox" + ]; + }; + Environment = { + PULSE_SINK = "Game"; + }; + }; + "io.openrct2.OpenRCT2" = { + Context = { + filesystems = [ "${config.home.homeDirectory}/Games/rollercoaster-tycoon" ]; + }; + Environment = { + PULSE_SINK = "Game"; + }; + }; + "net.shadps4.shadPS4" = { + Context = { + filesystems = [ + "${config.home.homeDirectory}/Games" + "xdg-data/games" + "!home" + ]; + }; + Environment = { + PULSE_SINK = "Game"; + }; + }; + "org.ryujinx.Ryujinx" = { + Context = { + filesystems = [ + "${config.home.homeDirectory}/Games" + "/mnt/crusader/Games/Rom/Other/Switch" + "xdg-data/games" + "!home" + ]; + }; + Environment = { + PULSE_SINK = "Game"; + }; + }; + }; + packages = [ + "com.github.optyfr.JRomManager" + "org.freedesktop.Platform.VulkanLayer.MangoHud/x86_64/24.08" + "org.freedesktop.Platform.VulkanLayer.gamescope/x86_64/24.08" + ]; + }; + }; + }; + }; +}