{ config, hostConfig, pkgs, lib, ... }: let niri = config.programs.niri.package; terminal = lib.getExe config.programs.kitty.package; lightctl = lib.getExe' config.services.avizo.package "lightctl"; volumectl = lib.getExe' config.services.avizo.package "volumectl"; dunstctl = lib.getExe' config.services.dunst.package "dunstctl"; loginctl = lib.getExe' hostConfig.systemd.package "loginctl"; systemctl = lib.getExe' hostConfig.systemd.package "systemctl"; focus-or-spawn = pkgs.writeShellApplication { name = "focus-or-spawn"; runtimeInputs = [ niri pkgs.gojq pkgs.gnugrep pkgs.socat ]; text = '' app_id="$1" shift workspace_name="$1" shift workspaces_json="$(niri msg -j workspaces)" workspace_output="$(jq -r --arg workspace_name "$workspace_name" '.[] | select(.name == $workspace_name) | .output' <<<"$workspaces_json")" active_workspace="$(jq -r --arg workspace_output "$workspace_output" '.[] | select(.output == $workspace_output and .is_active) | .id' <<<"$workspaces_json")" niri msg action move-workspace-to-monitor --output "$(jq -r '.[] | select(.is_focused) | .output' <<<"$workspaces_json")" "$workspace_name" socat STDIO "$NIRI_SOCKET" <<<'{"Action":{"FocusWorkspace":{"reference":{"Id":'"''${active_workspace}"'}}}}' niri msg action move-workspace-to-index --index 1 "$workspace_name" while IFS=$'\n' read -r window_json; do if jq -r '.app_id' <<<"$window_json" | grep -q "$app_id"; then niri msg action focus-window --id "$(jq -r '.id' <<<"$window_json")" exit 0 fi done < <(niri msg -j windows | jq -c '.[]') exec "$@" ''; }; focus-or-spawn-action = app_id: workspace_name: config.lib.niri.actions.spawn (lib.getExe focus-or-spawn) (lib.escapeShellArg app_id) (lib.escapeShellArg workspace_name); in { imports = [ ./waybar.nix ]; config = { systemd.user.services.xwayland-satellite = { Unit = { BindsTo = [ "graphical-session.target" ]; PartOf = [ "graphical-session.target" ]; After = [ "graphical-session.target" ]; Requisite = [ "graphical-session.target" ]; }; Service = { Type = "notify"; NotifyAccess = "all"; Environment = [ "DISPLAY=:0" ]; ExecStart = ''${lib.getExe pkgs.xwayland-satellite-unstable} ''${DISPLAY}''; ExecStartPre = "${systemctl} --user import-environment DISPLAY"; StandardOutput = "journal"; }; Install = { WantedBy = [ "graphical-session.target" ]; }; }; services.swayidle = { events = [ { event = "after-resume"; command = "${lib.getExe niri} msg action power-on-monitors"; } ]; timeouts = [ { timeout = 300; command = "${lib.getExe niri} msg action power-off-monitors"; } ]; }; programs.niri.settings = { prefer-no-csd = true; screenshot-path = "${config.home.homeDirectory}/screenshots"; hotkey-overlay.skip-at-startup = true; input = { keyboard.xkb = { layout = "us,us"; variant = "dvp,"; options = "compose:caps,grp:win_space_toggle"; }; workspace-auto-back-and-forth = true; # focus-follows-mouse.enable = true; warp-mouse-to-focus = true; }; outputs = { "Samsung Display Corp. 0x4141 Unknown" = { scale = 1.5; position = { x = 0; y = 0; }; }; "Ancor Communications Inc ASUS PB287Q 0x0000DD9B" = { scale = 1.5; position = { x = 2560; y = 0; }; }; }; environment = { NIXOS_OZONE_WL = "1"; QT_QPA_PLATFORM = "wayland"; GDK_BACKEND = "wayland"; SDL_VIDEODRIVER = "wayland"; }; layout = { gaps = 8; struts = { left = 8; right = 8; top = 0; bottom = 0; }; focus-ring = { width = 2; }; }; cursor.hide-when-typing = true; workspaces = { "001".name = "pwctl"; "002".name = "kpxc"; "003".name = "bmgr"; "101".name = "comm"; "102".name = "web"; "104".name = "read"; "105".name = "mon"; "110".name = "vid"; }; window-rules = [ { geometry-corner-radius = let allCorners = r: { bottom-left = r; bottom-right = r; top-left = r; top-right = r; }; in allCorners 8.; clip-to-geometry = true; } { matches = [ { app-id = "^com\.saivert\.pwvucontrol$"; } ]; open-on-workspace = "pwctl"; } { matches = [ { app-id = "^\.blueman-manager-wrapped$"; } ]; open-on-workspace = "bmgr"; } { matches = [ { app-id = "^org\.keepassxc\.KeePassXC$"; } ]; excludes = [ { title = "^Unlock Database"; } { title = "^Access Request"; } { title = "^Passkey credentials"; } ]; open-on-workspace = "kpxc"; open-focused = false; } { matches = [ { app-id = "^thunderbird$"; } { app-id = "^Element$"; } ]; open-on-workspace = "comm"; } { matches = [ { app-id = "^firefox$"; } ]; open-on-workspace = "web"; } { matches = [ { app-id = "^evince$"; } { app-id = "^imv$"; } { app-id = "^org\.pwmt\.zathura$"; } ]; open-on-workspace = "read"; } { matches = [ { app-id = "^mpv$"; } ]; open-on-workspace = "vid"; } { matches = [ { app-id = "^qemu$"; } { app-id = "^virt-manager$"; } ]; open-on-workspace = "mon"; } ]; binds = with config.lib.niri.actions; { "Mod+Slash".action = show-hotkey-overlay; "Mod+Return".action = spawn terminal; "Mod+Q".action = close-window; "Mod+D".action = spawn (lib.getExe config.programs.fuzzel.package); "Mod+Shift+D".action = spawn (lib.getExe config.programs.fuzzel.package) "--list-executables-in-path"; "Mod+H".action = focus-column-left; "Mod+T".action = focus-window-down; "Mod+N".action = focus-window-up; "Mod+S".action = focus-column-right; "Mod+Shift+H".action = move-column-left; "Mod+Shift+T".action = move-window-down; "Mod+Shift+N".action = move-window-up; "Mod+Shift+S".action = move-column-right; "Mod+Control+H".action = focus-monitor-left; "Mod+Control+T".action = focus-monitor-down; "Mod+Control+N".action = focus-monitor-up; "Mod+Control+S".action = focus-monitor-right; "Mod+Shift+Control+H".action = move-workspace-to-monitor-left; "Mod+Shift+Control+T".action = move-workspace-to-monitor-down; "Mod+Shift+Control+N".action = move-workspace-to-monitor-up; "Mod+Shift+Control+S".action = move-workspace-to-monitor-right; "Mod+G".action = focus-workspace-down; "Mod+C".action = focus-workspace-up; "Mod+Shift+G".action = move-column-to-workspace-down; "Mod+Shift+C".action = move-column-to-workspace-up; "Mod+Shift+Control+G".action = move-workspace-down; "Mod+Shift+Control+C".action = move-workspace-up; "Mod+M".action = consume-or-expel-window-left; "Mod+W".action = consume-or-expel-window-right; "Mod+R".action = switch-preset-column-width; "Mod+Shift+R".action = switch-preset-window-height; "Mod+F".action = center-column; "Mod+Shift+F".action = maximize-column; "Mod+Shift+Ctrl+F".action = fullscreen-window; "Mod+B".action = switch-focus-between-floating-and-tiling; "Mod+Shift+B".action = toggle-window-floating; "Mod+Left".action = set-column-width "-10%"; "Mod+Down".action = set-window-height "-10%"; "Mod+Up".action = set-window-height "+10%"; "Mod+Right".action = set-column-width "+10%"; "Mod+Shift+Z" = { action = spawn (lib.getExe niri) "msg" "action" "power-off-monitors"; allow-when-locked = true; }; "Mod+Shift+L" = { action = spawn loginctl "lock-session"; }; "Mod+Shift+E".action = quit; "XF86MonBrightnessUp" = { action = spawn lightctl "-d" "-e4" "-n1" "up"; allow-when-locked = true; }; "XF86MonBrightnessDown" = { action = spawn lightctl "-d" "-e4" "-n1" "down"; allow-when-locked = true; }; "XF86AudioRaiseVolume" = { action = spawn volumectl "-d" "-u" "up"; allow-when-locked = true; }; "XF86AudioLowerVolume" = { action = spawn volumectl "-d" "-u" "down"; allow-when-locked = true; }; "XF86AudioMute" = { action = spawn volumectl "-d" "toggle-mute"; allow-when-locked = true; }; "XF86AudioMicMute" = { action = spawn volumectl "-d" "-m" "toggle-mute"; allow-when-locked = true; }; "Mod+Semicolon".action = spawn dunstctl "close"; "Mod+Shift+Semicolon".action = spawn dunstctl "close-all"; "Mod+Period".action = spawn dunstctl "context"; "Mod+Comma".action = spawn dunstctl "history-pop"; "Mod+Alt+A".action = focus-or-spawn-action "^com\.saivert\.pwvucontrol$" "pwctl" "pwvucontrol"; "Mod+Alt+P".action = focus-or-spawn-action "^org\.keepassxc\.KeePassXC$" "kpxc" "keepassxc"; "Mod+Alt+B".action = focus-or-spawn-action "^\.blueman-manager-wrapped$" "bmgr" "blueman-manager"; }; }; }; }