diff --git a/cachix/cachix/niri.nix b/cachix/cachix/niri.nix new file mode 100644 index 0000000..08bca63 --- /dev/null +++ b/cachix/cachix/niri.nix @@ -0,0 +1,13 @@ + +{ + nix = { + settings = { + substituters = [ + "https://niri.cachix.org" + ]; + trusted-public-keys = [ + "niri.cachix.org-1:Wv0OmO7PsuocRKzfDoJ3mulSl7Z6oezYhGhR+3W2964=" + ]; + }; + }; +} diff --git a/home/home.nix b/home/home.nix index b0c4408..ca45aaa 100644 --- a/home/home.nix +++ b/home/home.nix @@ -1,4 +1,4 @@ -{ config, lib, pkgs, inputs, ... }: +{ config, lib, pkgs, inputs, niri, ... }: let laptop = builtins.readFile "/etc/hostname" == '' @@ -1492,7 +1492,7 @@ in { padding.y = 10; dynamic_padding = true; }; - terminal.shell.program = "fish"; + terminal.shell.program = "nu"; font = { normal = { family = "VictorMono Nerd Font"; diff --git a/home/modules/niri.nix b/home/modules/niri.nix index 5ae5d7b..2c904df 100644 --- a/home/modules/niri.nix +++ b/home/modules/niri.nix @@ -1,25 +1,89 @@ -{ config, lib, pkgs, ... }: +{ config, lib, pkgs, niri, ... }: let laptop = builtins.readFile "/etc/hostname" == "syl\n"; + cosmic-extra-niri = pkgs.writeShellScriptBin "cosmic-extra-niri" '' +set -e + +# From: https://people.debian.org/~mpitt/systemd.conf-2016-graphical-session.pdf + +if command -v systemctl >/dev/null; then + # robustness: if the previous graphical session left some failed units, + # reset them so that they don't break this startup + for unit in $(systemctl --user --no-legend --state=failed --plain list-units | cut -f1 -d' '); do + partof="$(systemctl --user show -p PartOf --value "$unit")" + for target in cosmic-session.target graphical-session.target; do + if [ "$partof" = "$target" ]; then + systemctl --user reset-failed "$unit" + break + fi + done + done +fi + +# use the user's preferred shell to acquire environment variables +# see: https://github.com/pop-os/cosmic-session/issues/23 +if [ -n "''${SHELL}" ]; then + # --in-login-shell: our flag to indicate that we don't need to recurse any further + if [ "''${1}" != "--in-login-shell" ]; then + # `exec -l`: like `login`, prefixes $SHELL with a hyphen to start a login shell + exec bash -c "''${0} --in-login-shell" + fi +fi + +export XDG_CURRENT_DESKTOP="''${XDG_CURRENT_DESKTOP:=niri}" +export XDG_SESSION_TYPE="''${XDG_SESSION_TYPE:=wayland}" +export XCURSOR_THEME="''${XCURSOR_THEME:=Cosmic}" +export _JAVA_AWT_WM_NONREPARENTING=1 +export GDK_BACKEND=wayland,x11 +export MOZ_ENABLE_WAYLAND=1 +export QT_QPA_PLATFORM="wayland;xcb" +export QT_AUTO_SCREEN_SCALE_FACTOR=1 +export QT_ENABLE_HIGHDPI_SCALING=1 + +if command -v systemctl >/dev/null; then + # set environment variables for new units started by user service manager + systemctl --user import-environment XDG_SESSION_TYPE XDG_CURRENT_DESKTOP +fi +# Run cosmic-session +if [[ -z "''${DBUS_SESSION_BUS_ADDRESS}" ]]; then + exec dbus-run-session -- ${pkgs.cosmic-session}/bin/cosmic-session niri +else + exec ${pkgs.cosmic-session}/bin/cosmic-session niri +fi + ''; in { + home.packages = with pkgs; [ + cosmic-extra-niri + ]; programs.niri = { - enable = true; + # enable = true; settings = { - binds = { + prefer-no-csd = true; + binds = with config.lib.niri.actions; { "XF86AudioRaiseVolume".action.spawn = ["volup"]; "XF86AudioLowerVolume".action.spawn = ["voldown"]; - "Mod+E".action.spawn = "emacslof"; - "Mod+B".action.spawn = "qblof"; - "Mod+Shift+Q".action = quit; - "Mod+O".action = toggle-overview; - "Mod+F".action = fullscreen-window; - "Mod+M".action = toggle-windowed-fullscreen; - "Mod+C".action = close-window; - "Mod+Left".action = focus-column-left; - "Mod+Right".action = focus-column-right; + "Super+E".action.spawn = "nu nirilof emacs 'emacslient -c'"; + "Super+Return".action.spawn = "alacritty"; + "Super+B".action.spawn = "nu nirilof org.qutebrowser.qutebrowser qutebrowser"; + "Super+Space".action.spawn = "cosmic-launcher"; + "Super+Shift+Q".action = quit; + "Super+O".action = toggle-overview; + "Super+F".action = fullscreen-window; + "Super+Shift+F".action = toggle-windowed-fullscreen; + "Super+C".action = close-window; + "Super+P".action.spawn = "/home/chris/bin/rbw.sh"; + "Super+Left".action = focus-column-left; + "Super+H".action = focus-column-left; + "Super+Shift+H".action = move-column-left; + "Super+Right".action = focus-column-right; + "Super+L".action = focus-column-right; + "Super+Shift+L".action = move-column-right; + "Super+Ctrl+L".action = set-column-width "+10%"; + "Super+Ctrl+H".action = set-column-width "-10%"; + "Super+M".action = set-column-width "95%"; }; spawn-at-startup = [ { argv = ["waybar"]; } @@ -38,27 +102,29 @@ in }; }; window-rules = [ - all = { + { geometry-corner-radius = { - top-left = 18; - top-right = 18; - bottom-left = 18; - bottom-right = 18; + top-left = 16.0; + top-right = 16.0; + bottom-left = 16.0; + bottom-right = 16.0; }; - }; - emacs = { - matches.app-id = "emacs"; + clip-to-geometry = true; + draw-border-with-background = false; + } + { + matches = [ {app-id = "emacs";} ]; open-on-workspace = "main"; - }; - browser = { - matches.app-id = "org.qutebrowser.qutebrowser"; + } + { + matches = [{app-id = "org.qutebrowser.qutebrowser";}]; open-on-workspace = "main"; - }; - cosmic-files = { - matches.app-id = "com.system76.CosmicFiles"; + } + { + matches = [{app-id = "com.system76.CosmicFiles";}]; open-on-workspace = "main"; open-floating = true; - }; + } ]; layout = { gaps = 15; @@ -71,11 +137,20 @@ in shadow = { enable = true; draw-behind-window = false; + inactive-color = "#00000000"; + softness = 10; + spread = 15; }; border = { + enable = false; + width = 4; + active = { color = "#57c7ff"; }; + inactive = { color = "#5af78e"; }; + }; + focus-ring = { enable = true; width = 4; - + active = { color = "#5af78e"; }; }; }; screenshot-path = "~/pics/screenshot_%Y-%m-%d_%H-%M-%S.png"; @@ -87,11 +162,11 @@ in outputs = { "eDP-1" = { enable = true; + name = "A"; mode = { height = 1504; width = 2256; - refresh = 60; - name = "A"; + refresh = 60.0; }; }; }; diff --git a/modules/desktop.nix b/modules/desktop.nix index 1f124fc..0538dbd 100644 --- a/modules/desktop.nix +++ b/modules/desktop.nix @@ -77,30 +77,98 @@ in }; services.displayManager.cosmic-greeter = { - enable = false; + enable = true; }; - services.greetd = { - enable = true; - settings = rec { - initial_session = { - command = "uwsm start hyprland-uwsm.desktop"; - user = "chris"; - }; - default_session = { - command = "${pkgs.greetd.tuigreet}/bin/tuigreet --time -r --window-padding 2 --cmd 'uwsm start hyprland-uwsm.desktop' -s /etc/greetd/environments"; - user = "greeter"; - }; - cosmic_session = { - command = "start-cosmic"; - user = "chris"; - }; - hyprland_session = { - command = "uwsm start hyprland-uwsm.desktop"; - user = "chris"; - }; - }; - }; + # services.greetd = { + # enable = true; + # settings = rec { + # initial_session = { + # command = "uwsm start hyprland-uwsm.desktop"; + # user = "chris"; + # }; + # default_session = { + # command = "${pkgs.greetd.tuigreet}/bin/tuigreet --time -r --window-padding 2 --cmd 'uwsm start hyprland-uwsm.desktop' -s /etc/greetd/environments"; + # user = "greeter"; + # }; + # cosmic_session = { + # command = "start-cosmic"; + # user = "chris"; + # }; + # hyprland_session = { + # command = "uwsm start hyprland-uwsm.desktop"; + # user = "chris"; + # }; + # }; + # }; + + services.displayManager.sessionPackages = [ + ((pkgs.writeTextFile { + name = "cosmic-on-niri"; + destination = "/share/wayland-sessions/COSMIC-on-niri.desktop"; + text = '' + [Desktop Entry] + Name=COSMIC-on-niri + Comment=This session logs you into the COSMIC desktop on niri + Type=Application + DesktopNames=niri + Exec=${pkgs.writeShellApplication { + name = "start-cosmic-ext-niri"; + runtimeInputs = [ pkgs.systemd pkgs.dbus pkgs.cosmic-session pkgs.bash pkgs.coreutils ]; + text = '' + set -e + # From: https://people.debian.org/~mpitt/systemd.conf-2016-graphical-session.pdf + if command -v systemctl >/dev/null; then + # robustness: if the previous graphical session left some failed units, + # reset them so that they don't break this startup + for unit in $(systemctl --user --no-legend --state=failed --plain list-units | cut -f1 -d' '); do + partof="$(systemctl --user show -p PartOf --value "$unit")" + for target in cosmic-session.target graphical-session.target; do + if [ "$partof" = "$target" ]; then + systemctl --user reset-failed "$unit" + break + fi + done + done + fi + # use the user's preferred shell to acquire environment variables + # see: https://github.com/pop-os/cosmic-session/issues/23 + if [ -n "''${SHELL:-}" ]; then + # --in-login-shell: our flag to indicate that we don't need to recurse any further + if [ "''${1:-}" != "--in-login-shell" ]; then + # `exec -l`: like `login`, prefixes $SHELL with a hyphen to start a login shell + exec bash -c "exec -l ${"'"}''${SHELL}' -c ${"'"}''${0} --in-login-shell'" + fi + fi + export XDG_CURRENT_DESKTOP="''${XDG_CURRENT_DESKTOP:=niri}" + export XDG_SESSION_TYPE="''${XDG_SESSION_TYPE:=wayland}" + export XCURSOR_THEME="''${XCURSOR_THEME:=Cosmic}" + export _JAVA_AWT_WM_NONREPARENTING=1 + export GDK_BACKEND=wayland,x11 + export MOZ_ENABLE_WAYLAND=1 + export QT_QPA_PLATFORM="wayland;xcb" + export QT_AUTO_SCREEN_SCALE_FACTOR=1 + export QT_ENABLE_HIGHDPI_SCALING=1 + if command -v systemctl >/dev/null; then + # set environment variables for new units started by user service manager + systemctl --user import-environment XDG_SESSION_TYPE XDG_CURRENT_DESKTOP + fi + # Run cosmic-session + if [[ -z "''${DBUS_SESSION_BUS_ADDRESS}" ]]; then + exec dbus-run-session -- cosmic-session niri + else + exec cosmic-session niri + fi + ''; + }}/bin/start-cosmic-ext-niri + ''; + } + + ).overrideAttrs + (old: { + passthru.providedSessions = [ "COSMIC-on-niri" ]; + })) + ]; programs.regreet = { enable = true; }; diff --git a/pkgs/desktop-packages.nix b/pkgs/desktop-packages.nix index 7d0ae73..4a4b6d4 100644 --- a/pkgs/desktop-packages.nix +++ b/pkgs/desktop-packages.nix @@ -173,6 +173,7 @@ esptool wireguard-tools # cosmic-ext-examine + cosmic-settings aider-chat wgsl-analyzer ]; diff --git a/scripts/nirilof b/scripts/nirilof new file mode 100755 index 0000000..7ee49ce --- /dev/null +++ b/scripts/nirilof @@ -0,0 +1,15 @@ +#/usr/bin/env nu + +def main [app: string, command: string] { + let open = try { + niri msg --json windows | from json | where app_id == $app | get id | first + } catch { + 0 + } + + if $open > 0 { + niri msg action focus-window --id $open + } else { + bash -c $"($command) &" + } +}