From e352d52d40fed964dab7743b22db38f77748b3f2 Mon Sep 17 00:00:00 2001 From: quirinecker Date: Wed, 23 Sep 2026 21:48:22 +0200 Subject: [PATCH] updated hyprland to allow for extra config. this way other services can register hyprland functionality. did extactly that for gpu screen recorder --- modules/desktop/hyprland.nix | 69 ++++++++++++------ modules/desktop/hyprland/hyprland.lua | 71 +++++++++---------- modules/gaming/gpu_screenrecorder.nix | 11 +++ .../gaming/gpu_screenrecorder/save-replay.sh | 3 + .../gaming/gpu_screenrecorder/start-replay.sh | 6 ++ modules/programs/programs.nix | 1 + 6 files changed, 101 insertions(+), 60 deletions(-) create mode 100755 modules/gaming/gpu_screenrecorder/save-replay.sh create mode 100755 modules/gaming/gpu_screenrecorder/start-replay.sh diff --git a/modules/desktop/hyprland.nix b/modules/desktop/hyprland.nix index 5f66eaa..a924ab9 100644 --- a/modules/desktop/hyprland.nix +++ b/modules/desktop/hyprland.nix @@ -11,33 +11,56 @@ in }; }; - flake.modules.homeManager.hyprland = { pkgs, config, ... }: { - home.packages = [ - pkgs.hyprpicker - pkgs.hypridle - pkgs.hyprshot - pkgs.hyprland-preview-share-picker - ]; + flake.modules.homeManager.hyprland = + { + pkgs, + config, + lib, + ... + }: + { + options = { + dotfiles-modules.hyprland.extraConfig = lib.mkOption { + type = lib.types.lines; + default = ""; + description = "Extra config to add to the hyprland config file."; + }; + }; + config = { + home.packages = [ + pkgs.hyprpicker + pkgs.hypridle + pkgs.hyprshot + pkgs.hyprland-preview-share-picker + ]; - xdg.configFile = { - "hypr/hyprland.lua".source = config.lib.file.mkOutOfStoreSymlink ./hyprland/hyprland.lua; + xdg.configFile = { + "hypr/hyprland.lua".text = '' + require("config") + require("extraConfig") + ''; - # The stups get linked to the config directory as well in order to use the autocomplete without copying it over in other places. - "hypr/hl.meta.lua".source = config.lib.file.mkOutOfStoreSymlink ./hyprland/hl.meta.lua; - "hypr/hypridle.conf".source = config.lib.file.mkOutOfStoreSymlink ./hyprland/hypridle.conf; - "backgrounds".source = config.lib.file.mkOutOfStoreSymlink ./backgrounds; + "hypr/config.lua".source = config.lib.file.mkOutOfStoreSymlink ./hyprland/hyprland.lua; - "hypr/nix.conf".text = '' - $defaultBrowser=${defaultBrowser} - ''; + "hypr/extraConfig.lua".text = config.dotfiles-modules.hyprland.extraConfig; - "hypr/xdph.conf".source = config.lib.file.mkOutOfStoreSymlink ./hyprland/xdph.conf; + # The stups get linked to the config directory as well in order to use the autocomplete without copying it over in other places. + "hypr/hl.meta.lua".source = config.lib.file.mkOutOfStoreSymlink ./hyprland/hl.meta.lua; - "hypr/scripts/gpu-screen-recorder/save-replay.sh".source = - config.lib.file.mkOutOfStoreSymlink ./hyprland/scripts/gpu-screen-recorder/save-replay.sh; - "hypr/scripts/gpu-screen-recorder/start-replay.sh".source = - config.lib.file.mkOutOfStoreSymlink ./hyprland/scripts/gpu-screen-recorder/start-replay.sh; + "hypr/hypridle.conf".source = config.lib.file.mkOutOfStoreSymlink ./hyprland/hypridle.conf; + "backgrounds".source = config.lib.file.mkOutOfStoreSymlink ./backgrounds; + + "hypr/nix.conf".text = '' + $defaultBrowser=${defaultBrowser} + ''; + + "hypr/xdph.conf".source = config.lib.file.mkOutOfStoreSymlink ./hyprland/xdph.conf; + + "hypr/scripts/gpu-screen-recorder/save-replay.sh".source = + config.lib.file.mkOutOfStoreSymlink ./hyprland/scripts/gpu-screen-recorder/save-replay.sh; + "hypr/scripts/gpu-screen-recorder/start-replay.sh".source = + config.lib.file.mkOutOfStoreSymlink ./hyprland/scripts/gpu-screen-recorder/start-replay.sh; + }; + }; }; - - }; } diff --git a/modules/desktop/hyprland/hyprland.lua b/modules/desktop/hyprland/hyprland.lua index 18311e1..24a3e56 100644 --- a/modules/desktop/hyprland/hyprland.lua +++ b/modules/desktop/hyprland/hyprland.lua @@ -1,4 +1,3 @@ -require('hyprland_hardware') ------------------ ---- MONITORS ---- ------------------ @@ -290,68 +289,66 @@ hl.gesture({ ---- KEYBINDINGS ---- --------------------- -local mainMod = "SUPER" -- Sets "Windows" key as main modifier +MainMod = "SUPER" -- Sets "Windows" key as main modifier. Is global so other scripts can also access it. -- Example binds, see https://wiki.hypr.land/Configuring/Basics/Binds/ for more -hl.bind(mainMod .. " + T", hl.dsp.exec_cmd(terminal)) -hl.bind(mainMod .. " + C", hl.dsp.window.close()) -hl.bind(mainMod .. " + SHIFT + Q", +hl.bind(MainMod .. " + T", hl.dsp.exec_cmd(terminal)) +hl.bind(MainMod .. " + C", hl.dsp.window.close()) +hl.bind(MainMod .. " + SHIFT + Q", hl.dsp.exec_cmd("command -v hyprshutdown >/dev/null 2>&1 && hyprshutdown || hyprctl dispatch 'hl.dsp.exit()'")) -hl.bind(mainMod .. " + Q", hl.dsp.exec_cmd("noctalia msg panel-open session")) -hl.bind(mainMod .. " + E", hl.dsp.exec_cmd(fileManager)) -hl.bind(mainMod .. " + B", hl.dsp.exec_cmd(browser)) -hl.bind(mainMod .. " + V", hl.dsp.window.float({ action = "toggle" })) -hl.bind(mainMod .. " + Space", hl.dsp.exec_cmd(menu)) -hl.bind(mainMod .. " + P", hl.dsp.window.pseudo()) -hl.bind(mainMod .. " + SHIFT + J", hl.dsp.layout("togglesplit")) -- dwindle only -hl.bind(mainMod .. " + F", hl.dsp.window.fullscreen({ action = "toggle", mode = "maximized" })) -hl.bind(mainMod .. " + SHIFT + F", hl.dsp.window.fullscreen({ action = "toggle", mode = "fullscreen" })) +hl.bind(MainMod .. " + Q", hl.dsp.exec_cmd("noctalia msg panel-open session")) +hl.bind(MainMod .. " + E", hl.dsp.exec_cmd(fileManager)) +hl.bind(MainMod .. " + B", hl.dsp.exec_cmd(browser)) +hl.bind(MainMod .. " + V", hl.dsp.window.float({ action = "toggle" })) +hl.bind(MainMod .. " + Space", hl.dsp.exec_cmd(menu)) +hl.bind(MainMod .. " + P", hl.dsp.window.pseudo()) +hl.bind(MainMod .. " + SHIFT + J", hl.dsp.layout("togglesplit")) -- dwindle only +hl.bind(MainMod .. " + F", hl.dsp.window.fullscreen({ action = "toggle", mode = "maximized" })) +hl.bind(MainMod .. " + SHIFT + F", hl.dsp.window.fullscreen({ action = "toggle", mode = "fullscreen" })) -- Layout stwitching -hl.bind(mainMod .. " + ALT + Space", hl.dsp.exec_cmd("hyprctl switchxkblayout current next")) +hl.bind(MainMod .. " + ALT + Space", hl.dsp.exec_cmd("hyprctl switchxkblayout current next")) -- Capturing something from the screen -hl.bind(mainMod .. " + SHIFT + S", hl.dsp.exec_cmd("hyprshot -m region -z")) -hl.bind(mainMod .. " + SHIFT + C", hl.dsp.exec_cmd("hyprpicker | wl-copy")) --- This requires gpu-screen-recorder to be installed. I installed it with this https://wiki.nixos.org/wiki/Gpu-screen-recorder. -hl.bind(mainMod .. " + SHIFT + V", hl.dsp.exec_cmd("~/.config/hypr/scripts/gpu-screen-recorder/save-replay.sh")) +hl.bind(MainMod .. " + SHIFT + S", hl.dsp.exec_cmd("hyprshot -m region -z")) +hl.bind(MainMod .. " + SHIFT + C", hl.dsp.exec_cmd("hyprpicker | wl-copy")) -- Noctalia Shell goodies -- hl.bind(mainMod .. " + SHIFT + L", hl.dsp.exec_cmd("noctalia-shell ipc call lockScreen lock")) hl.bind("F10", hl.dsp.exec_cmd("noctalia-shell ipc call lockScreen lock")) -hl.bind(mainMod .. " + I", hl.dsp.exec_cmd("noctalia-shell ipc call bar toggle")) +hl.bind(MainMod .. " + I", hl.dsp.exec_cmd("noctalia-shell ipc call bar toggle")) -- Move focus with mainMod + arrow keys -hl.bind(mainMod .. " + H", hl.dsp.focus({ direction = "left" })) -hl.bind(mainMod .. " + L", hl.dsp.focus({ direction = "right" })) -hl.bind(mainMod .. " + K", hl.dsp.focus({ direction = "up" })) -hl.bind(mainMod .. " + J", hl.dsp.focus({ direction = "down" })) +hl.bind(MainMod .. " + H", hl.dsp.focus({ direction = "left" })) +hl.bind(MainMod .. " + L", hl.dsp.focus({ direction = "right" })) +hl.bind(MainMod .. " + K", hl.dsp.focus({ direction = "up" })) +hl.bind(MainMod .. " + J", hl.dsp.focus({ direction = "down" })) -hl.bind(mainMod .. " + SHIFT + H", hl.dsp.window.move({ direction = "left" })) -hl.bind(mainMod .. " + SHIFT + L", hl.dsp.window.move({ direction = "right" })) -hl.bind(mainMod .. " + SHIFT + K", hl.dsp.window.move({ direction = "up" })) -hl.bind(mainMod .. " + SHIFT + J", hl.dsp.window.move({ direction = "down" })) +hl.bind(MainMod .. " + SHIFT + H", hl.dsp.window.move({ direction = "left" })) +hl.bind(MainMod .. " + SHIFT + L", hl.dsp.window.move({ direction = "right" })) +hl.bind(MainMod .. " + SHIFT + K", hl.dsp.window.move({ direction = "up" })) +hl.bind(MainMod .. " + SHIFT + J", hl.dsp.window.move({ direction = "down" })) for i = 1, 10 do local key = i % 10 -- 10 maps to key 0 - hl.bind(mainMod .. " + " .. key, hl.dsp.focus({ workspace = i })) - hl.bind(mainMod .. " + SHIFT + " .. key, hl.dsp.window.move({ workspace = i })) + hl.bind(MainMod .. " + " .. key, hl.dsp.focus({ workspace = i })) + hl.bind(MainMod .. " + SHIFT + " .. key, hl.dsp.window.move({ workspace = i })) end -- Example special workspace (scratchpad) -hl.bind(mainMod .. " + 0", hl.dsp.workspace.toggle_special("magic")) -hl.bind(mainMod .. " + SHIFT + 0", hl.dsp.window.move({ workspace = "special:magic" })) +hl.bind(MainMod .. " + 0", hl.dsp.workspace.toggle_special("magic")) +hl.bind(MainMod .. " + SHIFT + 0", hl.dsp.window.move({ workspace = "special:magic" })) -- Scroll through existing workspaces with mainMod + scroll -hl.bind(mainMod .. " + mouse_down", hl.dsp.focus({ workspace = "e+1" })) -hl.bind(mainMod .. " + mouse_up", hl.dsp.focus({ workspace = "e-1" })) +hl.bind(MainMod .. " + mouse_down", hl.dsp.focus({ workspace = "e+1" })) +hl.bind(MainMod .. " + mouse_up", hl.dsp.focus({ workspace = "e-1" })) -- Move/resize windows with mainMod + LMB/RMB and dragging -hl.bind(mainMod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true }) -hl.bind(mainMod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true }) +hl.bind(MainMod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true }) +hl.bind(MainMod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true }) -- Laptop multimedia keys for volume and LCD brightness hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+"), @@ -373,7 +370,7 @@ hl.bind("XF86AudioPrev", hl.dsp.exec_cmd("playerctl previous"), { locked = true -- Gaming Mode -hl.bind(mainMod .. "+ SHIFT + G", +hl.bind(MainMod .. "+ SHIFT + G", hl.dsp.exec_cmd( "nix run nixpkgs#gamescope -- -W 2560 -H 1440 -f -e -- steam -bigpicture", { workspace = "9" } diff --git a/modules/gaming/gpu_screenrecorder.nix b/modules/gaming/gpu_screenrecorder.nix index 5d5a07d..a150ceb 100644 --- a/modules/gaming/gpu_screenrecorder.nix +++ b/modules/gaming/gpu_screenrecorder.nix @@ -7,4 +7,15 @@ libnotify ]; }; + + # This modules requires the dotfiles-modules.homeManager.hyprland modules to be imported + # It adds the relevant scripts and shortcuts to be used in hyprland + flake.modules.homeManager.gpu-screenrecorder = { + dotfiles-modules.hyprland.extraConfig = '' + hl.bind(MainMod .. " + SHIFT + V", hl.dsp.exec_cmd("${./gpu_screenrecorder/save-replay.sh}")) + hl.on("hyprland.start", function() + hl.exec_cmd("${./gpu_screenrecorder/start-replay.sh}") + end) + ''; + }; } diff --git a/modules/gaming/gpu_screenrecorder/save-replay.sh b/modules/gaming/gpu_screenrecorder/save-replay.sh new file mode 100755 index 0000000..95e2e0d --- /dev/null +++ b/modules/gaming/gpu_screenrecorder/save-replay.sh @@ -0,0 +1,3 @@ +#!/bin/sh -e +killall -SIGUSR1 gpu-screen-recorder && sleep 0.5 && notify-send -t 1500 -u low -- "GPU Screen Recorder" "Replay saved" + diff --git a/modules/gaming/gpu_screenrecorder/start-replay.sh b/modules/gaming/gpu_screenrecorder/start-replay.sh new file mode 100755 index 0000000..c2efd32 --- /dev/null +++ b/modules/gaming/gpu_screenrecorder/start-replay.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +pidof -q gpu-screen-recorder && exit 0 +video_path="$HOME/Videos" +mkdir -p "$video_path" +gpu-screen-recorder -w screen -f 60 -a default_output -c mkv -bm cbr -q 40000 -r 60 -o "$video_path" diff --git a/modules/programs/programs.nix b/modules/programs/programs.nix index 5fedf3e..efe9fb5 100644 --- a/modules/programs/programs.nix +++ b/modules/programs/programs.nix @@ -14,6 +14,7 @@ let pkgs.discord pkgs.element-desktop pkgs.signal-desktop + pkgs.deltachat-desktop pkgs.spotify ];