diff --git a/Makefile b/Makefile index 1dd43d3..6100759 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,11 @@ HOSTS = nixbook nixpad tuxcomp +# build this host's system and make a boot entry boot: nixos-rebuild boot --flake . --sudo --ask-sudo-password +# build this host's system and switch in place switch: nixos-rebuild switch --flake . --sudo --ask-sudo-password @@ -15,10 +17,10 @@ build: nixos-rebuild build --flake . # evaluate every host. -check: +test: @for host in $(HOSTS); do \ echo "$$host"; \ - nix eval --raw .#nixosConfigurations.$$host.config.system.build.toplevel.drvPath > /dev/null || exit 1; \ + nix eval --show-trace --raw .#nixosConfigurations.$$host.config.system.build.toplevel.drvPath > /dev/null || exit 1; \ done update: diff --git a/hosts/nixbook/default.nix b/hosts/nixbook/default.nix index e0c0b3c..9e19297 100644 --- a/hosts/nixbook/default.nix +++ b/hosts/nixbook/default.nix @@ -1,5 +1,8 @@ { lib, config, pkgs, ... }: +let + hyprLib = import ../../lib/hypr.nix { inherit lib; }; +in { imports = [ ./hardware-configuration.nix @@ -13,6 +16,10 @@ boot.initrd.luks.devices."luks-082cc474-c00a-46c5-b140-4b7ccc2e6958".device = "/dev/disk/by-uuid/082cc474-c00a-46c5-b140-4b7ccc2e6958"; + home-manager.users."djai".wayland.windowManager.hyprland.settings.bind = [ + (hyprLib.bind "XF86TouchpadToggle" (hyprLib.exec "~/.config/hypr/scripts/toggle_touchpad.sh") "Toggle touchpad using XF86 keys") + ]; + services.power-profiles-daemon.enable = true; hardware.bluetooth.powerOnBoot = false; diff --git a/hosts/tuxcomp/default.nix b/hosts/tuxcomp/default.nix index 7f451f4..1eb47f8 100644 --- a/hosts/tuxcomp/default.nix +++ b/hosts/tuxcomp/default.nix @@ -1,5 +1,8 @@ { lib, config, pkgs, ... }: +let + hyprLib = import ../../lib/hypr.nix { inherit lib; }; +in { imports = [ ./hardware-configuration.nix @@ -19,6 +22,12 @@ }; hardware.tuxedo-drivers.enable = true; + # tuxcomp specific binds + home-manager.users."djai".wayland.windowManager.hyprland.settings.bind = [ + (hyprLib.bind "SUPER + SHIFT + G" (hyprLib.exec "~/.config/hypr/scripts/gamemode_power.sh") "Toggle gaming power profile mode") + (hyprLib.bind "META + ALT + F6" (hyprLib.exec "~/.config/hypr/scripts/gamemode_power.sh") "Toggle gaming power profile mode") + ]; + # FIXME: this patch does not work # adds a `stretch_aspect` scaler (Valve/gamescope#927) and lets `--rt` use the # rtprio limit from modules/gaming.nix instead of CAP_SYS_NICE. diff --git a/hosts/tuxcomp/nvidia.nix b/hosts/tuxcomp/nvidia.nix index 205467d..200f565 100644 --- a/hosts/tuxcomp/nvidia.nix +++ b/hosts/tuxcomp/nvidia.nix @@ -6,19 +6,19 @@ "nvidia" ]; - hardware.nvidia.prime = { - offload = { - enable = true; - enableOffloadCmd = true; + hardware.nvidia = { + prime = { + offload = { + enable = true; + enableOffloadCmd = true; + }; + amdgpuBusId = "PCI:0@6:0:0"; + nvidiaBusId = "PCI:0@1:0:1"; }; - amdgpuBusId = "PCI:6@0:0:0"; - nvidiaBusId = "PCI:1@0:0:0"; - }; - - hardware.nvidia = { open = true; modesetting.enable = true; nvidiaSettings = true; + powerManagement.enable = true; }; } diff --git a/lib/hypr.nix b/lib/hypr.nix new file mode 100644 index 0000000..cfb088b --- /dev/null +++ b/lib/hypr.nix @@ -0,0 +1,55 @@ +# Helpers for writing Hyprland's Lua config through home-manager, which +# renders each `settings.` entry as an hl.(...) call. Calls with +# several arguments take an `_args` list, and Lua expressions (dispatchers) +# must be wrapped with mkLuaInline or they'd be emitted as strings. +{ lib }: + +rec { + lua = lib.generators.mkLuaInline; + + # A Lua string literal (JSON's escaping is valid Lua for printable text). + str = builtins.toJSON; + + _bind = keys: dispatcher: { + _args = [ + keys + (lua dispatcher) + ]; + }; + bindWith = opts: keys: dispatcher: { + _args = [ + keys + (lua dispatcher) + opts + ]; + }; + bind = keys: dispatcher: desc: bindWith {description = desc;} keys dispatcher; + bindm = keys: dispatcher: desc: bindWith {description = desc; mouse = true;} keys dispatcher; + + exec = cmd: "hl.dsp.exec_cmd(${str cmd})"; + mulexec = cmds: "function() ${lib.concatMapStringsSep " " (cmd: "hl.dsp.exec_cmd(${str cmd})") cmds} end"; + + pass = window: "hl.dsp.pass({ window = ${str window}})"; + submap = name: "hl.dsp.submap(${str name})"; + sendShortcut = shortcut: window: "hl.dsp.send_shortcut({ mods = '', key = ${str shortcut}, window = ${str window}})"; + + moveWorkspace = ws: follow: "hl.dsp.window.move({ workspace = ${if builtins.isInt ws then toString ws else str ws}; follow = ${str follow} })"; + moveDirection = dir: "hl.dsp.window.move({ direction = ${str dir} })"; + + focusWorkspace = ws: "hl.dsp.focus({ workspace = ${if builtins.isInt ws then toString ws else str ws} })"; + focusDirection = dir: "hl.dsp.focus({ direction = ${str dir} })"; + + makeSubmap = name: binds: + let + bindContent = builtins.concatStringsSep "\n " (map (bind: + ''hl.bind("${builtins.elemAt bind 0}", ${builtins.elemAt bind 1}, { description = "${if builtins.length bind >= 3 then builtins.elemAt bind 2 else ""}" })'' + ) binds); + in + { + _args = [ + name + (lua "function()\n ${bindContent}\nend") + ]; + }; +} + diff --git a/modules/desktop/default.nix b/modules/desktop/default.nix index ce70101..556b37e 100644 --- a/modules/desktop/default.nix +++ b/modules/desktop/default.nix @@ -44,7 +44,6 @@ yudit ]; - services.gvfs.enable = true; # CHECK: that this gives us gio back services.udisks2.enable = true; services.printing.enable = true; diff --git a/modules/desktop/hypr-bindings.nix b/modules/desktop/hypr-bindings.nix new file mode 100644 index 0000000..e27d404 --- /dev/null +++ b/modules/desktop/hypr-bindings.nix @@ -0,0 +1,69 @@ +{ hyprLib, mainMod, ... }: +let + inherit (hyprLib) + bind + bindm + exec + focusDirection + focusWorkspace + moveDirection + moveWorkspace + ; +in +{ + home-manager.users."djai".wayland.windowManager.hyprland.settings.bind = [ + # default binds + (bind "${mainMod} + T" (exec "~/.config/WMScripts/kitty_window.sh") "Kitty") + (bind "${mainMod} + SHIFT + T" (exec "~/.config/WMScripts/kitty_window.sh") "Kitty (with sh)") + (bind "${mainMod} + SHIFT + R" (exec "~/.config/WMScripts/record.sh") "Record screen with ffmpg") + (bind "CTRL + SHIFT + SPACE" (exec "~/.config/WMScripts/microphone.sh") "Global mute toggle") + (bind "PRINT" (exec "grimblast copy area --freeze") "Printscreen (frozen)") + (bind "SHIFT + PRINT" (exec "grimblast copy area") "Printscreen") + (bind "${mainMod} + SHIFT + S" (exec "grimblast copy area") "Printscreen") + (bind "CTRL + PRINT" (exec "~/.config/WMScripts/screenshot_float.sh") "Screenshot to feh (flameshot)") + (bind "CTRL + SHIFT + PRINT" (exec "~/.config/hypr/scripts/screenshot_float.sh") "Screenshot to feh (grim)") + (bind "${mainMod} + O" (exec "~/.config/WMScripts/tess.sh") "Screenshot to OCR") + (bind "${mainMod} + P" (exec "hyprpicker -ra") "Colour picker") + (bind "${mainMod} + CTRL + P" (exec "~/.config/WMScripts/changewall.fish") "Manually switch wallpaper") + (bind "${mainMod} + D" (exec "rofi -show drun") "Program runner") + (bind "${mainMod} + SHIFT + D" (exec "~/.config/hypr/scripts/keybinds.sh") "Show keybinds") + (bind "${mainMod} + N" (exec "dunstctl close-all") "Clear dunst notifications") + (bind "${mainMod} + SHIFT + N" (exec "~/.config/WMScripts/dunst.sh") "Toggle dunst notifications") + (bind "CTRL + SHIFT + ESCAPE" (exec "~/.config/WMScripts/murder.sh") "Terminate a program") + (bind "${mainMod} + CTRL + M" (exec "~/.config/WMScripts/mute_active.sh") "Toggle mute active window") + (bind "${mainMod} + CTRL + SHIFT + M" (exec "~/.config/WMScripts/mute_active.sh muted") "Toggle mute active window and apply the 'muted' shader") + (bind "${mainMod} + M" (exec "~/.config/WMScripts/toggle_audiocables.sh combine") "Toggle hyperx audio output") + (bind "${mainMod} + SHIFT + M" (exec "~/.config/WMScripts/toggle_audiocables.sh clementine") "Toggle clementine audio output") + (bind "${mainMod} + Q" (exec "killall deadcells") "Murder Dead cells specifically") + (bind "CTRL + ALT + M" (exec "pactl set-sink-mute 'alsa_output.pci-0000_06_00.6.analog-stereo' toggle") "Toggle internal speaker output") + (bind "${mainMod} + SHIFT + V" (exec "~/.config/hypr/scripts/shader_picker.sh") "Pick a shader") + (bind "${mainMod} + G" (exec "~/.config/hypr/scripts/gamemode_hypr.sh") "Toggle power-saving mode") + ] ++ [ + # window navigation + (bind "${mainMod} + V" "hl.dsp.window.pin()" "Pin window") + (bind "${mainMod} + SHIFT + C" "hl.dsp.window.center()" "Center floating window") + (bind "${mainMod} + SHIFT + MINUS" (moveWorkspace "special:magic" false) "Move window to special workspace") + (bind "${mainMod} + MINUS" "hl.dsp.workspace.toggle_special('magic')" "Toggle special workspace") + (bind "${mainMod} + SHIFT + Q" "hl.dsp.window.close()" "Kill focused window") + (bind "${mainMod} + SHIFT + SPACE" "hl.dsp.window.float()" "Toggle floating") + (bind "${mainMod} + SPACE" (exec "~/.config/hypr/scripts/toggle_focus_floating.sh") "Toggle floating focus") + (bind "${mainMod} + F" "hl.dsp.window.fullscreen()" "Toggle fullscreen") + (bind "${mainMod} + H" (focusDirection "left") "Focus left") + (bind "${mainMod} + J" (focusDirection "down") "Focus down") + (bind "${mainMod} + K" (focusDirection "up") "Focus up") + (bind "${mainMod} + L" (focusDirection "right") "Focus right") + + (bind "${mainMod} + SHIFT + H" (moveDirection "left") "Move window left") + (bind "${mainMod} + SHIFT + J" (moveDirection "down") "Move window down") + (bind "${mainMod} + SHIFT + K" (moveDirection "up") "Move window up") + (bind "${mainMod} + SHIFT + L" (moveDirection "right") "Move window right") + (bind "${mainMod} + CTRL + F" "hl.dsp.window.pseudo()" "Toggle pesudo-floating") + (bind "${mainMod} + E" "hl.dsp.layout('togglesplit')" "Toggle split layout") + (bindm "${mainMod} + mouse:272" "hl.dsp.window.drag()" "Move using mouse") + (bindm "${mainMod} + mouse:273" "hl.dsp.window.resize()" "Resize using mouse") + (bind "${mainMod} + COMMA " (focusWorkspace 999) "") + (bind "${mainMod} + SHIFT + COMMA" (moveWorkspace 999 false) "") + (bind "${mainMod} + SHIFT + code:60" "hl.dsp.workspace.move({ monitor = '+1' })" "Move workspace between monitors") + ]; +} + diff --git a/modules/desktop/hypr-input.nix b/modules/desktop/hypr-input.nix new file mode 100644 index 0000000..9a070c9 --- /dev/null +++ b/modules/desktop/hypr-input.nix @@ -0,0 +1,42 @@ +{ ... }: + +{ + home-manager.users."djai".wayland.windowManager.hyprland.settings.config = { + input = { + kb_layout = "us"; + kb_variant = "euro"; + kb_options = "caps:escape"; + + follow_mouse = 1; + mouse_refocus = false; + accel_profile = "flat"; + sensitivity = -0.3; + + touchpad = { + disable_while_typing = true; + natural_scroll = true; + clickfinger_behavior = false; + tap_to_click = true; + }; + + tablet = { + output = "HDMI-A-1"; + left_handed = true; + region_size = [ 1920 1080 ]; + }; + }; + + device = [ + { + name = "4152:6180:SteelSeries_SteelSeries_Rival_3"; + disable_while_typing = false; + accel_profile = "flat"; + sensitivity = -0.3; + } + { + name = "uniw0001:00-093a:0255-touchpad"; + enabled = false; + }]; + }; +} + diff --git a/modules/desktop/hypr-look-and-feel.nix b/modules/desktop/hypr-look-and-feel.nix new file mode 100644 index 0000000..05e7635 --- /dev/null +++ b/modules/desktop/hypr-look-and-feel.nix @@ -0,0 +1,60 @@ +{ ... }: + +{ + + home-manager.users."djai".wayland.windowManager.hyprland.settings = { + curve = [ + { _args = [ "specialWorkSwitch" { type = "bezier"; points = [ [ 0.05 0.7 ] [ 0.1 1 ] ]; }];} + { _args = [ "emphasizedAccel" { type = "bezier"; points = [ [ 0.3 0 ] [ 0.8 0.15 ] ]; }];} + { _args = [ "emphasizedDecel" { type = "bezier"; points = [ [ 0.05 0.7 ] [ 0.1 1 ] ]; }];} + { _args = [ "standard" { type = "bezier"; points = [ [ 0.2 0 ] [ 0 1 ] ]; } ];} + { _args = [ "myBezier" { type = "bezier"; points = [ [ 0.05 0.9 ] [ 0.1 1.05 ] ]; }];} + ]; + + animation = [ + { leaf = "layersIn"; enabled = true; speed = 5; bezier = "emphasizedDecel"; style = "slide";} + { leaf = "layersOut"; enabled = true; speed = 4; bezier = "emphasizedAccel"; style = "slide";} + { leaf = "fadeLayers"; enabled = true; speed = 5; bezier = "standard";} + { leaf = "windowsIn"; enabled = true; speed = 5; bezier = "emphasizedDecel";} + { leaf = "windowsOut"; enabled = true; speed = 3; bezier = "emphasizedAccel";} + { leaf = "windowsMove"; enabled = true; speed = 6; bezier = "myBezier";} + { leaf = "workspaces"; enabled = true; speed = 6; bezier = "standard";} + { leaf = "specialWorkspace"; enabled = true; speed = 4; bezier = "specialWorkSwitch"; style = "slidefadevert 15%";} + { leaf = "fade"; enabled = true; speed = 6; bezier = "standard";} + { leaf = "fadeDim"; enabled = true; speed = 6; bezier = "standard";} + { leaf = "border"; enabled = true; speed = 6; bezier = "standard";} + ]; + + config = { + animations = { + enabled = true; + }; + + decoration = { + rounding = 10; + + active_opacity = 1; + inactive_opacity = 1; + fullscreen_opacity = 1; + + dim_inactive = true; + dim_strength = 0.2; + + shadow = { + range = 4; + render_power = 3; + color = "rgba(1a1a1aee)"; + }; + + blur = { + enabled = true; + size = 12; + passes = 4; + new_optimizations = true; + + xray = true; + }; + }; + }; + }; +} diff --git a/modules/desktop/hypr-passthrough.nix b/modules/desktop/hypr-passthrough.nix new file mode 100644 index 0000000..2b3a0f8 --- /dev/null +++ b/modules/desktop/hypr-passthrough.nix @@ -0,0 +1,71 @@ +{ hyprLib, mainMod, ... }: + +let + inherit (hyprLib) + bind + pass + sendShortcut + submap + makeSubmap + ; + + makePassthrough = window: binds: + let + customBinds = map (mapping: + let + k = builtins.elemAt mapping 0; + v = builtins.elemAt mapping 1; + d = if builtins.length mapping >= 3 then builtins.elemAt mapping 2 else ""; + in + [k (sendShortcut v window) d] + ) binds; + in + customBinds ++ [["ESCAPE" (submap "reset")]]; + fehBinds = [ + [ "RETURN" "0"] + [ "1" "1"] + [ "2" "2"] + [ "3" "3"] + [ "4" "4"] + [ "W" "5"] + [ "A" "6"] + [ "D" "7"] + [ "F" "8"] + [ "Z" "9"] + [ "Q" "LEFT"] + [ "E" "RIGHT"] + [ "S" "h"] + [ "H" "h"] + ]; + feishinBinds = [ + [ "0" "0" "Send '0' to feishin"] + [ "1" "1" "Send '1' to feishin"] + [ "2" "2" "Send '2' to feishin"] + [ "3" "3" "Send '3' to feishin"] + [ "4" "4" "Send '4' to feishin"] + [ "W" "5" "Send '5' to feishin"] + [ "S" "h" "Send 'h' to feishin"] + [ "H" "h" "Send 'h' to feishin"] + [ "Q" "q" "Send 'q' to feishin"] + [ "E" "e" "Send 'e' to feishin"] + [ "SPACE" "space" "Send 'space' to feishin"] + [ "A" "a" "Send 'a' to feishin"] + [ "D" "d" "Send 'd' to feishin"] + ]; +in +{ + home-manager.users."djai".wayland.windowManager.hyprland.settings = { + bind = [ + (bind "${mainMod} + SHIFT + A" (submap "feh") "") + (bind "${mainMod} + SHIFT + F" (submap "feishin") "Enter feishin passthrough mode") + (bind "F7" (pass "class:^(com.obsproject.Studio)$") "Send F7 to obs studio") + (bind "F8" (pass "class:^(com.obsproject.Studio)$") "Send F8 to obs studio") + (bind "F9" (pass "class:^(com.obsproject.Studio)$") "Send F9 to obs studio") + ]; + + define_submap = [ + (makeSubmap "feh" (makePassthrough "class:^*hideme)$" fehBinds)) + (makeSubmap "feishin" (makePassthrough "class:^(feishin)$" feishinBinds)) + ]; + }; +} diff --git a/modules/desktop/hypr-plugins.nix b/modules/desktop/hypr-plugins.nix new file mode 100644 index 0000000..dec56a8 --- /dev/null +++ b/modules/desktop/hypr-plugins.nix @@ -0,0 +1,44 @@ +{ hyprLib, mainMod, lib, pkgs, ... }: + +let + inherit (hyprLib) + bind + exec + ; + + # automatically discover shaders in the relative hypr shaders directory + shaders = lib.mapAttrsToList (name: _: lib.strings.removeSuffix ".glsl" "${name}") + (lib.attrsets.filterAttrs + (name: type: type == "regular") + (builtins.readDir ./windowShaders) + ); + loadShader = name: "hl.plugin.darkwindow.load_shader('${name}', { path = './windowShaders/${name}.glsl'})"; +in +{ + users.users.djai.packages = with pkgs.hyprlandPlugins; [ + hypr-darkwindow + ]; + + # supposed to map to hl.plugin.darkwindow.load_shader("${shader}" { path = "./windowShaders/${shader}.glsl"}) + home-manager.users."djai".wayland.windowManager.hyprland.extraConfig = '' + if hl.plugin.darkwindow ~= nil then + ${lib.strings.join "\n " (map loadShader shaders)} + end + ''; + + home-manager.users."djai".wayland.windowManager.hyprland.settings = { + bind = [ + (bind "${mainMod} + SHIFT + B" (exec "~/.config/hypr/scripts/shader_picker_window.sh") "Pick a shader for active window") + ]; + + window_rule = [ + { match.tag = "shader/muted"; "darkwindow:shade" = "grey";} + { match.tag = "muted"; "darkwindow:shade" = "grey";} + ] ++ map (name: { match.tag = "shader/${name}"; "darkwindow:shade" = "${name}";}) shaders; + }; + + + + # TODO: symlink ./windowShaders into ~/.config/hypr/ + # TODO: symlink ./shaders into ~/.config/hypr/ <- should happen in desktop/hypr.nix prolly +} diff --git a/modules/desktop/hypr-rules.nix b/modules/desktop/hypr-rules.nix new file mode 100644 index 0000000..c33cbea --- /dev/null +++ b/modules/desktop/hypr-rules.nix @@ -0,0 +1,83 @@ +{ lib, ... }: + +{ + home-manager.users."djai".wayland.windowManager.hyprland.settings = { + layer_rule = [ + { match.namespace = "wallpaper"; animation = "fade"; } + { match.namespace = "notifs"; blur = false; xray = true; } + { match.namespace = "waybar"; no_anim = true; ignore_alpha = 0; } + { match.namespace = "selection"; no_anim = true; ignore_alpha = 1; xray = false; } + { match.namespace = "hyprpicker"; no_anim = true; } + { match.namespace = "rofi"; blur = false; animation = "popin"; } + + ]; + + window_rule = [ + { match.title = "^slop$"; no_blur = true;} + + # scratchyness + { match.workspace = "special"; float = true;} + { match.class = "^scratchme$"; workspace = "special:magic";} + + # floatyness + { match.class = "^steam$"; float = true; center = true;} + { match.class = "^steam$"; match.title = "^Steam$"; float = false;} + { match.class = "^floatme$"; float = true;} + { match.title = "^floatme$"; float = true;} + { match.title = "^Save as.*$"; float = true;} + { match.title = "^Save image.*$"; center = true;} + { match.class = "^file-png$"; float = true;} + { match.class = "^yad$"; float = true;} + + # flameshot + { match.class = "^flameshot$"; float = true;} + { match.class = "^flameshot$"; move = "exact 1920 1080";} + { match.class = "^flameshot$"; size = "1920 1080";} + + # move bitwarden login window to center + { match.title = ".*Bitwarden.*"; float = true;} + { match.title = ".*Bitwarden.*"; size = "monitor_w*0.25 monitor_h*0.15";} + { match.title = ".*Bitwarden.*"; center = true;} + + # gimp floating windows + { match.class = "^gimp$"; match.title = ".*Colour Exchange.*"; move = "100 (monitor_h/2)-(window_h/2)";} + { match.class = "^script-fu$"; float = true;} + { match.class = "^script-fu$"; move = "100 (monitor_h/2)-(window_h/2)";} + + # default workspaces + { match.class = "Librewolf"; workspace = "1 silent";} + { match.class = "VsCodium"; workspace = "2 silent";} + { match.class = "feishin"; workspace = "3 silent";} + { match.class = "signal"; workspace = "4 silent";} + { match.class = "Element"; workspace = "4 silent";} + { match.class = "vesktop"; workspace = "4 silent";} + { match.class = "stoat-desktop"; workspace = "4 silent";} + { match.class = "freetube"; workspace = "5 silent";} + { match.class = "com.obsproject.Studio"; workspace = "6 silent";} + { match.class = "steam"; workspace = "6 silent";} + { match.class = "org.prismlauncher.PrismLauncher"; workspace = "6 silent";} + { match.class = "Enigmatica.*"; workspace = "6 silent";} + { match.class = "gimp"; workspace = "7 silent";} + { match.class = "krita"; workspace = "7 silent";} + { match.class = "tuxedo-control-center"; workspace = "10 silent";} + { match.class = "opencloud"; workspace = "10 silent";} + + # shadowdim + { match.title = ".*shadowDim.*"; workspace = "999 silent";} + + # ignore max requests + { match.class = ".*"; suppress_event = "maximize";} + + # muted tag + { match.tag = "muted"; border_color = { colors = [ + (lib.generators.mkLuaInline "colors.subtext0") # FIXME: stupid hack to use catppuccin-nix colors + (lib.generators.mkLuaInline "colors.subtext1") + ]; angle = 45;};} + + # steam window fixes + { match.class = "^(steam)$"; suppress_event = "activatefocus";} + ]; + }; +} + + diff --git a/modules/desktop/hypr-shutdown.nix b/modules/desktop/hypr-shutdown.nix new file mode 100644 index 0000000..44b81da --- /dev/null +++ b/modules/desktop/hypr-shutdown.nix @@ -0,0 +1,32 @@ +{ hyprLib, mainMod, ... }: + +let + inherit (hyprLib) + bind + exec + submap + makeSubmap + ; + + systemModeName = " l e s h r ^s"; + exitScript = "~/.config/WMScripts/exit.sh"; +in +{ + home-manager.users."djai".wayland.windowManager.hyprland.settings = { + bind = [ + (bind "${mainMod} + SHIFT + E" (submap systemModeName) "Enter Shutdown mode") + ]; + + define_submap = [ + (makeSubmap systemModeName [ + ["L" (exec "${exitScript} lock") "Lock the machine"] + ["E" (exec "${exitScript} logout") "Log out"] + ["S" (exec "${exitScript} suspend") "Suspend the machine"] + ["H" (exec "${exitScript} hibernate") "Hibernate the machine"] + ["R" (exec "${exitScript} reboot") "Reboot the machine"] + ["SHIFT + S" (exec "${exitScript} shutdown") "Power the machine off"] + ["ESCAPE" (submap "reset") "Return to default mode"] + ]) + ]; + }; +} diff --git a/modules/desktop/hypr-workspaces.nix b/modules/desktop/hypr-workspaces.nix new file mode 100644 index 0000000..63511e7 --- /dev/null +++ b/modules/desktop/hypr-workspaces.nix @@ -0,0 +1,43 @@ +{ hyprLib, mainMod, ... }: + +let + inherit (hyprLib) + bind + focusWorkspace + moveWorkspace + submap + makeSubmap + ; + + mod = a: b: a - (b * (builtins.div a b)); +in +{ + home-manager.users."djai".wayland.windowManager.hyprland.settings = { + bind = [ + (bind "${mainMod} + SHIFT + W" (submap "H") "") # hidden workspaces + ] ++ builtins.concatLists (builtins.genList (i: + let ws = builtins.toJSON (mod i 11); + in [ + (bind "${mainMod} + ${toString i}" (focusWorkspace ws) "Switch to workspace ${toString i}") + (bind "${mainMod} + SHIFT + ${toString i} " (moveWorkspace ws false) "Move window to workspace ${toString i}") + ] + ) 9); + + define_submap = [ + (makeSubmap "H" ([ + ["ESCAPE" (submap "reset")] + ] ++ builtins.concatLists (builtins.genList (i: + let ws = i+10; + in [ + [(toString i) (focusWorkspace ws) ""] + ["SHIFT + ${toString i}" (moveWorkspace ws false)] + ]) 9)))]; + + window_rule = [ + { match.class = ".*hideme.*"; workspace = "11 silent";} + { match.title = ".*hideme.*"; workspace = "11 silent";} + { match.class = ".*hideme.*"; no_screen_share = true;} + { match.title = ".*hideme.*"; no_screen_share = true;} + ]; + }; +} diff --git a/modules/desktop/hypr-xf86.nix b/modules/desktop/hypr-xf86.nix new file mode 100644 index 0000000..a627d47 --- /dev/null +++ b/modules/desktop/hypr-xf86.nix @@ -0,0 +1,21 @@ +{ hyprLib, ... }: + +let + inherit (hyprLib) + bind + exec + mulexec + ; +in +{ + home-manager.users."djai".wayland.windowManager.hyprland.settings.bind = [ + (bind "XF86AudioRaiseVolume" (exec "pactl set-sink-volume @DEFAULT_SINK@ +10% ") "Increase volume using XF86 keys") + (bind "XF86AudioLowerVolume" (exec "pactl set-sink-volume @DEFAULT_SINK@ -10% ") "Decrease volume using XF86 keys") + (bind "XF86AudioMute" (exec "pactl set-sink-mute @DEFAULT_SINK@ toggle") "Toggle mute using XF86 keys") + (bind "XF86AudioMicMute" (exec "pactl set-source-mute @DEFAULT_SOURCE@ toggle ") "Toggle microphone mute using XF86 keys") + + (bind "XF86MonBrightnessUp" (mulexec ["brightnessctl set +10%" "~/.config/WMScripts/backlight-notif.sh"]) "Increase screen brightness using XF86 keys") + (bind "XF86MonBrightnessDown" (mulexec ["brightnessctl set 10%-" "~/.config/WMScripts/backlight-notif.sh"]) "Decrease screen brightness using XF86 keys") + ]; +} + diff --git a/modules/desktop/hypr.nix b/modules/desktop/hypr.nix index eb27349..cb39122 100644 --- a/modules/desktop/hypr.nix +++ b/modules/desktop/hypr.nix @@ -1,6 +1,54 @@ -{ ... }: +{ lib, pkgs, ... }: +#----------------------------------------Autostart---------------------------------------- +# hl.on("hyprland.start", function() +# -- plugins +# hl.exec_cmd("hyprpm reload") +# +# -- run kanshi for output placement (also starts up bg and waybar) +# hl.exec_cmd("kanshi") +# +# -- notification manager +# hl.exec_cmd("dunst") +# +# -- start a terminal in the scratchpad +# hl.exec_cmd("kitty --class scratchme -d ~/Documents/diary") +# +# -- run flameshot daemon +# hl.exec_cmd("nohup flameshot") +# +# -- cursor theme +# hl.exec_cmd("hyprctl setcursor Catppuccin-Macchiato-Dark-Cursors 24") +# +# -- opencloud +# hl.exec_cmd("opencloud") +# +# -- openrgb +# hl.exec_cmd("type openrgb &> /dev/null && openrgb --noautoconnect -p aroace.orp > /dev/null") +# end) +# + + +let + hyprLib = import ../../lib/hypr.nix { inherit lib; }; + + mainMod = "SUPER"; +in { + imports = [ + (import ./hypr-bindings.nix { inherit hyprLib mainMod; }) + ./hypr-input.nix + ./hypr-look-and-feel.nix + (import ./hypr-passthrough.nix { inherit hyprLib mainMod; }) + (import ./hypr-plugins.nix { inherit hyprLib mainMod lib pkgs; }) + ./hypr-rules.nix + (import ./hypr-shutdown.nix { inherit hyprLib mainMod; }) + (import ./hypr-workspaces.nix { inherit hyprLib mainMod; }) + ./hypr-xf86.nix + ./hyprapps.nix + ]; + _module.args.hyprLib = hyprLib; + programs.hyprland = { enable = true; withUWSM = true; @@ -17,92 +65,56 @@ }; }; + # TODO: symlink entire shellscript directory here. - home-manager.users."djai".programs.hyprlock = { + home-manager.users."djai".wayland.windowManager.hyprland = { enable = true; + configType = "lua"; + + plugins = with pkgs; [ + hyprlandPlugins.hypr-darkwindow + ]; + portalPackage = null; + settings = { - general = { - hide_cursor = true; - ignore_empty_input = true; - }; + config = { + general = { + gaps_in = 5; + gaps_out = 1; + border_size = 2; - animations = { - enabled = true; - fade_in = { - duration = 300; - bezier = "easeOutQuint"; - }; - fade_out = { - duration = 300; - bezier = "easeOutQuint"; + col = { + active_border = { colors = [ + (lib.generators.mkLuaInline "colors.blue") + (lib.generators.mkLuaInline "colors.mauve") + ]; angle = 45; }; + inactive_border = (lib.generators.mkLuaInline "colors.mantle"); + }; + + layout = "dwindle"; }; - input_field_dots = { - duration = 100; - bezier = "linear"; + dwindle = { + preserve_split = true; + special_scale_factor = 0.7; + }; + + misc = { + enable_anr_dialog = false; + enable_swallow = false; + disable_hyprland_logo = true; + animate_manual_resizes = true; + animate_mouse_windowdragging = false; + + mouse_move_focuses_monitor = true; + focus_on_activate = false; + }; + + ecosystem = { + no_update_news = true; + no_donation_nag = true; }; }; - - background = { - path = "screenshot"; - blur_passes = 3; - }; - - input-field = { - size = "20%, 5%"; - outline_thickness = 3; - inner_color = "rgba(0, 0, 0, 0.0)"; # no fill - outer_color = "rgba($blueAlphaee) rgba($mauveAlphaee) 340deg"; - check_color = "rgba($greenAlphaee) rgba($tealAlphaee) 120deg"; - fail_color = "rgba($redAlphaee) rgba($peachAlphaee) 20deg"; - - font_color = "$text"; - fade_on_empty = false; - rounding = 15; - - font_family = "Monospace"; - placeholder_text = "Input password.."; - fail_text = "$PAMFAIL"; - - dots_spacing = 0.3; - - position = "0, -20"; - halign = "center"; - valign = "center"; - }; - - label = { - text = "$ATTEMPTS"; - font_size = 24; - - position = "0, 40"; - halign = "center"; - valign = "center"; - }; - }; - }; - - home-manager.users."djai".services.hyprsunset = { - enable = true; - settings = { - max-gamma = 150; - - profile = [ - { - time = "7:30"; - identity = true; - } - { - time = "20:00"; - temperature = 3500; - gamma = 0.9; - } - { - time = "21:00"; - temperature = 2500; - gamma = 0.9; - } - ]; }; }; } diff --git a/modules/desktop/hyprapps.nix b/modules/desktop/hyprapps.nix new file mode 100644 index 0000000..7e5cf65 --- /dev/null +++ b/modules/desktop/hyprapps.nix @@ -0,0 +1,91 @@ +{ ... }: + +{ + home-manager.users."djai".programs.hyprlock = { + enable = true; + settings = { + general = { + hide_cursor = true; + ignore_empty_input = true; + }; + + animations = { + enabled = true; + fade_in = { + duration = 300; + bezier = "easeOutQuint"; + }; + fade_out = { + duration = 300; + bezier = "easeOutQuint"; + }; + + input_field_dots = { + duration = 100; + bezier = "linear"; + }; + }; + + background = { + path = "screenshot"; + blur_passes = 3; + }; + + input-field = { + size = "20%, 5%"; + outline_thickness = 3; + inner_color = "rgba(0, 0, 0, 0.0)"; # no fill + outer_color = "rgba($blueAlphaee) rgba($mauveAlphaee) 340deg"; + check_color = "rgba($greenAlphaee) rgba($tealAlphaee) 120deg"; + fail_color = "rgba($redAlphaee) rgba($peachAlphaee) 20deg"; + + font_color = "$text"; + fade_on_empty = false; + rounding = 15; + + font_family = "Monospace"; + placeholder_text = "Input password.."; + fail_text = "$PAMFAIL"; + + dots_spacing = 0.3; + + position = "0, -20"; + halign = "center"; + valign = "center"; + }; + + label = { + text = "$ATTEMPTS"; + font_size = 24; + + position = "0, 40"; + halign = "center"; + valign = "center"; + }; + }; + }; + + home-manager.users."djai".services.hyprsunset = { + enable = true; + settings = { + max-gamma = 150; + + profile = [ + { + time = "7:30"; + identity = true; + } + { + time = "20:00"; + temperature = 3500; + gamma = 0.9; + } + { + time = "21:00"; + temperature = 2500; + gamma = 0.9; + } + ]; + }; + }; +} diff --git a/modules/desktop/windowShaders/crt.glsl b/modules/desktop/windowShaders/crt.glsl new file mode 100644 index 0000000..7ef5ac0 --- /dev/null +++ b/modules/desktop/windowShaders/crt.glsl @@ -0,0 +1,48 @@ +//modified version of [this shader](https://github.com/wessles/GLSL-CRT/blob/master/shader.frag) +const vec3 VIB_RGB_BALANCE = vec3(1.0, 1.0, 1.0); +const float VIB_VIBRANCE = 0.40; +const vec3 VIB_coeffVibrance = VIB_RGB_BALANCE * -VIB_VIBRANCE; + +void windowShader(inout vec4 color) { + vec2 texCoord = x_TexCoord; + + // Distance from the center + float dx = abs(0.5-texCoord.x); + float dy = abs(0.5-texCoord.y); + + // Square it to smooth the edges + dx *= dx; + dy *= dy; + + texCoord.x -= 0.5; + texCoord.x *= 1.0 + (dy * 0.05); + texCoord.x += 0.5; + + texCoord.y -= 0.5; + texCoord.y *= 1.0 + (dx * 0.18); + texCoord.y += 0.5; + + // Get texel, and add in scanline if need be + color = x_Texture(texCoord); + color.rgb += sin(texCoord.y * 1250.0) * 0.02; + + // Cutoff + if(texCoord.y > 1.0 || texCoord.x < 0.0 || texCoord.x > 1.0 || texCoord.y < 0.0) + color = vec4(0.0); + + // vec3 VIB_coefLuma = vec3(0.333333, 0.333334, 0.333333); // was for `if VIB_LUMA == 1` + vec3 VIB_coefLuma = vec3(0.212656, 0.715158, 0.072186); // try both and see which one looks nicer. + + float luma = dot(VIB_coefLuma, color.rgb); + + float max_color = max(color.r, max(color.g, color.b)); + float min_color = min(color.r, min(color.g, color.b)); + + float color_saturation = max_color - min_color; + + vec3 p_col = vec3(vec3(vec3(vec3(sign(VIB_coeffVibrance) * color_saturation) - 1.0) * VIB_coeffVibrance) + 1.0); + + color.r = mix(luma, color.r, p_col.r); + color.g = mix(luma, color.g, p_col.g); + color.b = mix(luma, color.b, p_col.b); +} diff --git a/modules/desktop/windowShaders/dim.glsl b/modules/desktop/windowShaders/dim.glsl new file mode 100644 index 0000000..e5498cd --- /dev/null +++ b/modules/desktop/windowShaders/dim.glsl @@ -0,0 +1,7 @@ +// blue light filter shader + +void windowShader(inout vec4 color) { + color.r *= 0.7; + color.g *= 0.6; + color.b *= 0.5; +} diff --git a/modules/desktop/windowShaders/grey.glsl b/modules/desktop/windowShaders/grey.glsl new file mode 100644 index 0000000..3d3901b --- /dev/null +++ b/modules/desktop/windowShaders/grey.glsl @@ -0,0 +1,9 @@ +// Values obtained from: http://en.wikipedia.org/wiki/Grayscale#Luma_coding_in_video_systems +vec3 LumaFactors = vec3(0.299, 0.587, 0.114); + +void windowShader(inout vec4 color) { + // Desaturate to luma only + float luma = dot(vec3(color.r, color.g, color.b), LumaFactors); + + color.rgb = vec3(luma, luma, luma); +} diff --git a/modules/desktop/windowShaders/horror.glsl b/modules/desktop/windowShaders/horror.glsl new file mode 100644 index 0000000..3a52a7a --- /dev/null +++ b/modules/desktop/windowShaders/horror.glsl @@ -0,0 +1,17 @@ +const float display_framerate = 60.0; +const vec2 display_resolution = vec2(2520.0, 1680.0); +const float gamma = 1.0; + +float rand(vec2 uv, float t) { + return fract(sin(dot(uv, vec2(1225.6548, 321.8942))) * 4251.4865 + t); +} + +float Sigmoid(float x) { return 1.0 / (1.0 + (exp(-(x - 0.5) * 14.0))); } + +void windowShader(inout vec4 color) { + color = vec4(Sigmoid(color.r), Sigmoid(color.g), Sigmoid(color.b), 1.0); + + color = pow(color, vec4(gamma)); + + color.a = 1.0; +} diff --git a/modules/desktop/windowShaders/muted.glsl b/modules/desktop/windowShaders/muted.glsl new file mode 100644 index 0000000..3d3901b --- /dev/null +++ b/modules/desktop/windowShaders/muted.glsl @@ -0,0 +1,9 @@ +// Values obtained from: http://en.wikipedia.org/wiki/Grayscale#Luma_coding_in_video_systems +vec3 LumaFactors = vec3(0.299, 0.587, 0.114); + +void windowShader(inout vec4 color) { + // Desaturate to luma only + float luma = dot(vec3(color.r, color.g, color.b), LumaFactors); + + color.rgb = vec3(luma, luma, luma); +} diff --git a/modules/desktop/windowShaders/noblue.glsl b/modules/desktop/windowShaders/noblue.glsl new file mode 100644 index 0000000..2a24480 --- /dev/null +++ b/modules/desktop/windowShaders/noblue.glsl @@ -0,0 +1,14 @@ +// Values obtained from: http://en.wikipedia.org/wiki/Grayscale#Luma_coding_in_video_systems +vec3 LumaFactors = vec3(0.299, 0.587, 0.114); + +void windowShader(inout vec4 color) { + // average brightness + float luma = dot(vec3(color.r, color.g, color.b), LumaFactors); + + if (color.r < color.g) { + color = vec4(luma, c.g, luma, color.a); + } else { + color = vec4(color.r, luma, luma, color.a); + } + // color = vec4(color.r, color.g, luma, color.a); +} diff --git a/modules/desktop/windowShaders/nogreen.glsl b/modules/desktop/windowShaders/nogreen.glsl new file mode 100644 index 0000000..2d60a0b --- /dev/null +++ b/modules/desktop/windowShaders/nogreen.glsl @@ -0,0 +1,14 @@ +// Values obtained from: http://en.wikipedia.org/wiki/Grayscale#Luma_coding_in_video_systems +vec3 LumaFactors = vec3(0.299, 0.587, 0.114); + +void windowShader(inout vec4 color) { + // average brightness + float luma = dot(vec3(color.r, color.g, color.b), LumaFactors); + + if (color.r < color.b) { + color = vec4(luma, luma, color.b, color.a); + } else { + color = vec4(color.r, luma, luma, color.a); + } + // color = vec4(color.r, luma, color.b, color.a); +} diff --git a/modules/desktop/windowShaders/nored.glsl b/modules/desktop/windowShaders/nored.glsl new file mode 100644 index 0000000..69bfaf6 --- /dev/null +++ b/modules/desktop/windowShaders/nored.glsl @@ -0,0 +1,14 @@ +// Values obtained from: http://en.wikipedia.org/wiki/Grayscale#Luma_coding_in_video_systems +vec3 LumaFactors = vec3(0.299, 0.587, 0.114); + +void windowShader(inout vec4 color) { + // average brightness + float luma = dot(vec3(color.r, color.g, color.b), LumaFactors); + + if (color.g < color.b) { + color = vec4(luma, luma, color.b, color.a); + } else { + color = vec4(luma, color.g, luma, color.a); + } + // color = vec4(luma, color.g, color.b, color.a); +} diff --git a/modules/desktop/windowShaders/rainbow.glsl b/modules/desktop/windowShaders/rainbow.glsl new file mode 100644 index 0000000..172297f --- /dev/null +++ b/modules/desktop/windowShaders/rainbow.glsl @@ -0,0 +1,15 @@ +//modified version of [this shader](https://github.com/wessles/GLSL-CRT/blob/master/shader.frag) +const float scaleFactor = 0.7; + +float clamp(float x, float min, float max) { + if (x > max) return max; + if (x < min) return min; + return x; +} + +void windowShader(inout vec4 color) { + // color += vec4(cos(x_TexCoord.x)/4., sin(x_TexCoord.y)/4., 0., 1.); + color += vec4(cos(v_texcoord.x)/4., cos(v_texcoord.y)/8., sin(v_texcoord.y)/4., 1.); + + color = vec4(clamp(color.x, 0., 1.), clamp(color.y, 0., 1.), clamp(color.z, 0., 1.), color.w); +} diff --git a/modules/desktop/windowShaders/rbinvert.glsl b/modules/desktop/windowShaders/rbinvert.glsl new file mode 100644 index 0000000..da8a355 --- /dev/null +++ b/modules/desktop/windowShaders/rbinvert.glsl @@ -0,0 +1,5 @@ +//modified version of [this shader](https://github.com/wessles/GLSL-CRT/blob/master/shader.frag) + +void windowShader(inout vec4 color) { + color = vec4(color.z, color.y, color.x, color.a); +} diff --git a/modules/terminal/kitty.nix b/modules/terminal/kitty.nix index 133c537..41885ea 100644 --- a/modules/terminal/kitty.nix +++ b/modules/terminal/kitty.nix @@ -15,7 +15,7 @@ "ctrl+shift+n" = "new_os_window_with_cwd"; }; - themeFile = "Catppuccin-Macchiato"; # FIXME: borked in home manager? + themeFile = "Catppuccin-Macchiato"; # NOTE: catppuccin-nix is borked for kitty so we do it like this settings = { shell = "${pkgs.fish}/bin/fish"; diff --git a/secrets/default.nix b/secrets/default.nix index a5ebf5c..4fd9474 100644 --- a/secrets/default.nix +++ b/secrets/default.nix @@ -20,7 +20,7 @@ in sops.secrets = { # ssh config (exposes hostnames/ips/ports) "ssh-config" = djaiOnly // { - sopsFile = ./ssh-config.bin; # TODO: actually use this + sopsFile = ./ssh-config.bin; }; # wireguard tunnels