diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000..75fb614 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,39 @@ +{ + "permissions": { + "allow": [ + "Bash(nixos-version:*)", + "Bash(glxinfo)", + "Bash(bambu-studio --version)", + "Bash(lspci)", + "Bash(lsmod)", + "Bash(echo $XDG_SESSION_TYPE)", + "Bash(echo $DISPLAY $WAYLAND_DISPLAY)", + "Bash(coredumpctl list:*)", + "Bash(journalctl --user -b -g bambu --no-pager)", + "Bash(coredumpctl info:*)", + "Bash(nix search:*)", + "Bash(find /nix/store/ji5hxn8c4n5dvivqr9ilm91962p8c5ld-bambu-studio-02.05.00.67/ -name *.so)", + "Bash(find /nix/store/ji5hxn8c4n5dvivqr9ilm91962p8c5ld-bambu-studio-02.05.00.67/ -name *.so*)", + "Bash(dconf read:*)", + "Bash(gsettings get:*)", + "Read(//usr/share/**)", + "Read(//home/jgarr/.local/share/applications/**)", + "Bash(sudo nixos-rebuild:*)", + "Read(//home/jgarr/.config/niri/**)", + "Bash(find /etc/nixos -name *.nix)", + "Bash(niri --version)", + "Bash(niri msg:*)", + "Bash(niri --help)", + "Bash(/nix/store/8a08pxn2hpj1619b3cp48lzajdqpnrqq-niri-26.04/bin/niri msg:*)", + "Bash(nix shell:*)", + "Bash(/nix/store/8a08pxn2hpj1619b3cp48lzajdqpnrqq-niri-26.04/bin/niri validate:*)", + "WebFetch(domain:github.com)", + "Read(//nix/store/**)", + "Bash(systemctl --user restart swayosd)", + "Bash(swayosd-client --output-volume raise)", + "Bash(journalctl --user -u swayosd -n 10 --no-pager)", + "Bash(TERM=xterm vim -E -s -u ~/.dotfiles/ln/.vimrc +PluginInstall +qall)", + "Bash(echo \"exit: $?\")" + ] + } +} diff --git a/controld.nix b/controld.nix index 2eb4666..63a2fba 100644 --- a/controld.nix +++ b/controld.nix @@ -32,21 +32,10 @@ in ''; }; - # Create writable config directory systemd.tmpfiles.rules = [ - "d /etc/ctrld 0755 jgarr jgarr - -" + "d /etc/ctrld 0755 root root - -" ]; - # Write ctrld config to /etc/ctrld/config.toml - environment.etc."ctrld/config.toml".text = '' - [server] - listen = "0.0.0.0:53" - tcp_enable = true - - [upstream.dns] - primary = "76.76.2.22#242b3nujblf.dns.controld.com" - ''; - # Ensure ctrld starts before resolved systemd.services.ctrld = { description = "ControlD DNS Proxy"; diff --git a/home.nix b/home.nix index fd78ee7..228b6ae 100644 --- a/home.nix +++ b/home.nix @@ -63,6 +63,14 @@ videos = "$HOME/videos"; }; + gtk = { + enable = true; + theme = { + name = "Adwaita"; + package = pkgs.gnome-themes-extra; + }; + }; + dconf.settings = { "org/gnome/desktop/input-sources" = { sources = [ (lib.hm.gvariant.mkTuple [ "xkb" "us+dvorak" ]) ]; @@ -276,6 +284,13 @@ "application/json" = "org.gnome.TextEditor.desktop"; "audio/flac" = "io.mpv.Mpv.desktop"; "image/vnd.adobe.photoshop" = "org.kde.krita.desktop"; + "image/jpeg" = "imv.desktop"; + "image/png" = "imv.desktop"; + "image/gif" = "imv.desktop"; + "image/webp" = "imv.desktop"; + "image/bmp" = "imv.desktop"; + "image/tiff" = "imv.desktop"; + "image/svg+xml" = "imv.desktop"; }; defaultApplications = { "x-scheme-handler/http" = "xdg-open-wrapper.desktop"; @@ -293,6 +308,13 @@ "video/mp4" = "io.mpv.Mpv.desktop"; "video/quicktime" = "io.mpv.Mpv.desktop"; "video/x-matroska" = "io.mpv.Mpv.desktop"; + "image/jpeg" = "imv.desktop"; + "image/png" = "imv.desktop"; + "image/gif" = "imv.desktop"; + "image/webp" = "imv.desktop"; + "image/bmp" = "imv.desktop"; + "image/tiff" = "imv.desktop"; + "image/svg+xml" = "imv.desktop"; "x-scheme-handler/beeper" = "beepertexts.desktop"; "application/json" = "org.gnome.TextEditor.desktop"; "audio/flac" = "io.mpv.Mpv.desktop"; diff --git a/hosts/x-home.nix b/hosts/x-home.nix index c0221a6..30745cf 100644 --- a/hosts/x-home.nix +++ b/hosts/x-home.nix @@ -1,16 +1,61 @@ -{ pkgs, ... }: +{ pkgs, unstable, ... }: { + services.swayosd = { + enable = true; + package = unstable.swayosd; + stylePath = "${pkgs.writeText "swayosd-style.css" '' + window#osd { + border-radius: 12px; + border: none; + background: rgba(30, 30, 30, 0.9); + } + window#osd #container { + margin: 16px; + } + window#osd image, + window#osd label { + color: white; + } + window#osd progressbar { + min-height: 8px; + min-width: 200px; + border-radius: 999px; + background: transparent; + border: none; + } + window#osd trough { + min-height: inherit; + min-width: inherit; + border-radius: inherit; + border: none; + background: rgba(255, 255, 255, 0.25); + } + window#osd progress { + min-height: inherit; + min-width: 0; + border-radius: inherit; + border: none; + background: white; + } + ''}"; + }; + home.packages = [ pkgs.xwayland-satellite pkgs.libinput-gestures pkgs.brightnessctl pkgs.playerctl pkgs.iio-sensor-proxy # provides monitor-sensor - pkgs.swayosd pkgs.wlogout + pkgs.swaybg ]; + xdg.configFile."ghostty/config".text = '' + background-opacity = 0.9 + working-directory = home + ''; + xdg.configFile."libinput-gestures.conf".text = '' gesture swipe right 3 niri msg action focus-column-right gesture swipe left 3 niri msg action focus-column-left @@ -130,8 +175,11 @@ } touchpad { tap + dwt natural-scroll } + + focus-follows-mouse } // Outputs - run `niri msg outputs` to find output names @@ -139,6 +187,7 @@ // scale 1.5 // } output "DSI-1" { + scale 1.5 transform "270" // landscape-right (90° CW physical rotation) } @@ -155,30 +204,131 @@ } // Spawn at startup + spawn-at-startup "swaybg" "-i" "/home/jgarr/pictures/27021343-mosaic-abstract-wallpapers.jpg" "-m" "fill" spawn-at-startup "bash" "-c" "sleep 1 && waybar" + spawn-at-startup "ghostty" + spawn-at-startup "firefox" spawn-at-startup "libinput-gestures" - spawn-at-startup "swayosd-server" // Key bindings binds { - Mod+T { spawn "ghostty"; } - Mod+D { spawn "fuzzel"; } - Alt+Tab { spawn "niri-alt-tab"; } - Mod+Q { close-window; } + Mod+Shift+Slash { show-hotkey-overlay; } + Mod+Slash { show-hotkey-overlay; } + + Mod+T hotkey-overlay-title="Open a Terminal: ghostty" { spawn "ghostty"; } + Mod+D hotkey-overlay-title="Run an Application: fuzzel" { spawn "fuzzel"; } + Super+Alt+L hotkey-overlay-title="Lock the Screen: swaylock" { spawn "swaylock"; } + + Super+Alt+S allow-when-locked=true hotkey-overlay-title=null { spawn-sh "pkill orca || exec orca"; } + + XF86AudioRaiseVolume allow-when-locked=true { spawn "swayosd-client" "--output-volume" "raise"; } + XF86AudioLowerVolume allow-when-locked=true { spawn "swayosd-client" "--output-volume" "lower"; } + XF86AudioMute allow-when-locked=true { spawn "swayosd-client" "--output-volume" "mute-toggle"; } + XF86AudioMicMute allow-when-locked=true { spawn-sh "wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"; } + + XF86AudioPlay allow-when-locked=true { spawn "playerctl" "play-pause"; } + XF86AudioPause allow-when-locked=true { spawn "playerctl" "play-pause"; } + XF86AudioStop allow-when-locked=true { spawn-sh "playerctl stop"; } + XF86AudioPrev allow-when-locked=true { spawn "playerctl" "previous"; } + XF86AudioNext allow-when-locked=true { spawn "playerctl" "next"; } + + XF86MonBrightnessUp allow-when-locked=true { spawn "swayosd-client" "--brightness" "raise"; } + XF86MonBrightnessDown allow-when-locked=true { spawn "swayosd-client" "--brightness" "lower"; } + + Mod+O repeat=false { toggle-overview; } + + Mod+Q repeat=false { close-window; } Mod+Left { focus-column-left; } - Mod+Right { focus-column-right; } - Mod+Up { focus-window-up; } Mod+Down { focus-window-down; } + Mod+Up { focus-window-up; } + Mod+Right { focus-column-right; } + Mod+H { focus-column-left; } + Mod+J { focus-window-down; } + Mod+K { focus-window-up; } + Mod+L { focus-column-right; } + + Mod+Ctrl+Left { move-column-left; } + Mod+Ctrl+Down { move-window-down; } + Mod+Ctrl+Up { move-window-up; } + Mod+Ctrl+Right { move-column-right; } + Mod+Ctrl+H { move-column-left; } + Mod+Ctrl+J { move-window-down; } + Mod+Ctrl+K { move-window-up; } + Mod+Ctrl+L { move-column-right; } + + Mod+Home { focus-column-first; } + Mod+End { focus-column-last; } + Mod+Ctrl+Home { move-column-to-first; } + Mod+Ctrl+End { move-column-to-last; } - Mod+Shift+Left { move-column-left; } - Mod+Shift+Right { move-column-right; } + Mod+Shift+Left { focus-monitor-left; } + Mod+Shift+Down { focus-monitor-down; } + Mod+Shift+Up { focus-monitor-up; } + Mod+Shift+Right { focus-monitor-right; } + Mod+Shift+H { focus-monitor-left; } + Mod+Shift+J { focus-monitor-down; } + Mod+Shift+K { focus-monitor-up; } + Mod+Shift+L { focus-monitor-right; } + + Mod+Shift+Ctrl+Left { move-column-to-monitor-left; } + Mod+Shift+Ctrl+Down { move-column-to-monitor-down; } + Mod+Shift+Ctrl+Up { move-column-to-monitor-up; } + Mod+Shift+Ctrl+Right { move-column-to-monitor-right; } + Mod+Shift+Ctrl+H { move-column-to-monitor-left; } + Mod+Shift+Ctrl+J { move-column-to-monitor-down; } + Mod+Shift+Ctrl+K { move-column-to-monitor-up; } + Mod+Shift+Ctrl+L { move-column-to-monitor-right; } + + Mod+Page_Down { focus-workspace-down; } + Mod+Page_Up { focus-workspace-up; } + Ctrl+Alt+Down { focus-workspace-down; } + Ctrl+Alt+Up { focus-workspace-up; } + Ctrl+Alt+Shift+Down { move-window-to-workspace-down; } + Ctrl+Alt+Shift+Up { move-window-to-workspace-up; } + Mod+U { focus-workspace-down; } + Mod+I { focus-workspace-up; } + Mod+Ctrl+Page_Down { move-column-to-workspace-down; } + Mod+Ctrl+Page_Up { move-column-to-workspace-up; } + Mod+Ctrl+U { move-column-to-workspace-down; } + Mod+Ctrl+I { move-column-to-workspace-up; } + + Mod+Shift+Page_Down { move-workspace-down; } + Mod+Shift+Page_Up { move-workspace-up; } + + Mod+WheelScrollDown cooldown-ms=150 { focus-workspace-down; } + Mod+WheelScrollUp cooldown-ms=150 { focus-workspace-up; } + Mod+Ctrl+WheelScrollDown cooldown-ms=150 { move-column-to-workspace-down; } + Mod+Ctrl+WheelScrollUp cooldown-ms=150 { move-column-to-workspace-up; } + + Mod+WheelScrollRight { focus-column-right; } + Mod+WheelScrollLeft { focus-column-left; } + Mod+Ctrl+WheelScrollRight { move-column-right; } + Mod+Ctrl+WheelScrollLeft { move-column-left; } + + Mod+Shift+WheelScrollDown { focus-column-right; } + Mod+Shift+WheelScrollUp { focus-column-left; } + Mod+Ctrl+Shift+WheelScrollDown { move-column-right; } + Mod+Ctrl+Shift+WheelScrollUp { move-column-left; } Mod+1 { focus-workspace 1; } Mod+2 { focus-workspace 2; } Mod+3 { focus-workspace 3; } Mod+4 { focus-workspace 4; } Mod+5 { focus-workspace 5; } + Mod+6 { focus-workspace 6; } + Mod+7 { focus-workspace 7; } + Mod+8 { focus-workspace 8; } + Mod+9 { focus-workspace 9; } + Mod+Ctrl+1 { move-column-to-workspace 1; } + Mod+Ctrl+2 { move-column-to-workspace 2; } + Mod+Ctrl+3 { move-column-to-workspace 3; } + Mod+Ctrl+4 { move-column-to-workspace 4; } + Mod+Ctrl+5 { move-column-to-workspace 5; } + Mod+Ctrl+6 { move-column-to-workspace 6; } + Mod+Ctrl+7 { move-column-to-workspace 7; } + Mod+Ctrl+8 { move-column-to-workspace 8; } + Mod+Ctrl+9 { move-column-to-workspace 9; } Mod+Shift+1 { move-window-to-workspace 1; } Mod+Shift+2 { move-window-to-workspace 2; } @@ -186,52 +336,73 @@ Mod+Shift+4 { move-window-to-workspace 4; } Mod+Shift+5 { move-window-to-workspace 5; } - Mod+F { maximize-column; } + Mod+BracketLeft { consume-or-expel-window-left; } + Mod+BracketRight { consume-or-expel-window-right; } + + Mod+Comma { consume-window-into-column; } + Mod+Period { expel-window-from-column; } + + Mod+R { switch-preset-column-width; } + Mod+Shift+R { spawn "sh" "-c" "niri msg action reload-config"; } + Mod+Ctrl+Shift+R { switch-preset-window-height; } + Mod+Ctrl+R { reset-window-height; } + + Mod+F { maximize-column; } Mod+Shift+F { fullscreen-window; } + Mod+M { maximize-window-to-edges; } + Mod+Ctrl+F { expand-column-to-available-width; } - Mod+Shift+E { spawn "wlogout"; } + Mod+C { center-column; } + Mod+Ctrl+C { center-visible-columns; } - Mod+Shift+R { spawn "sh" "-c" "niri msg action reload-config"; } + Mod+Minus { set-column-width "-10%"; } + Mod+Equal { set-column-width "+10%"; } + Mod+Shift+Minus { set-window-height "-10%"; } + Mod+Shift+Equal { set-window-height "+10%"; } - Mod+Slash { show-hotkey-overlay; } + Mod+V { toggle-window-floating; } + Mod+Shift+V { switch-focus-between-floating-and-tiling; } - Print { screenshot; } - Ctrl+Print { screenshot-screen; } - Alt+Print { screenshot-window; } + Mod+W { toggle-column-tabbed-display; } - XF86AudioRaiseVolume allow-when-locked=true { spawn "swayosd-client" "--output-volume" "raise"; } - XF86AudioLowerVolume allow-when-locked=true { spawn "swayosd-client" "--output-volume" "lower"; } - XF86AudioMute allow-when-locked=true { spawn "swayosd-client" "--output-volume" "mute-toggle"; } - XF86MonBrightnessUp allow-when-locked=true { spawn "swayosd-client" "--brightness" "raise"; } - XF86MonBrightnessDown allow-when-locked=true { spawn "swayosd-client" "--brightness" "lower"; } - XF86AudioPlay allow-when-locked=true { spawn "playerctl" "play-pause"; } - XF86AudioPause allow-when-locked=true { spawn "playerctl" "play-pause"; } - XF86AudioNext allow-when-locked=true { spawn "playerctl" "next"; } - XF86AudioPrev allow-when-locked=true { spawn "playerctl" "previous"; } + Print { screenshot; } + Ctrl+Print { screenshot-screen; } + Alt+Print { screenshot-window; } + + Mod+Escape allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; } + + Mod+Shift+E { spawn "wlogout"; } + Ctrl+Alt+Delete { quit; } + + Mod+Shift+P { power-off-monitors; } } // Screenshots screenshot-path "~/pictures/screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png" - ''; - - home.file.".local/bin/niri-alt-tab" = { - enable = true; - executable = true; - text = '' - #!/usr/bin/env bash - current_ws=$(niri msg --json workspaces | jq -r '.[] | select(.is_focused == true) | .id') - data=$(niri msg --json windows | jq -r --argjson ws "$current_ws" \ - '.[] | select(.workspace_id == $ws) | "\(.app_id): \(.title // "(no title)")\t\(.id)"') - [ -z "$data" ] && exit + // Window rules + window-rule { + match app-id="^firefox$" + open-maximized true + } - selected=$(echo "$data" | cut -f1 | fuzzel --dmenu) - [ -z "$selected" ] && exit + // Gestures + gestures { + hot-corners { + top-left + bottom-left + bottom-right + } + } - id=$(echo "$data" | awk -F'\t' -v sel="$selected" '$1 == sel {print $2; exit}') - [ -n "$id" ] && niri msg action focus-window --id "$id" - ''; - }; + // Window effects + window-rule { + match app-id="^com\\.mitchellh\\.ghostty$" + background-effect { + blur true + } + } + ''; # Auto-rotation: listen to iio-sensor-proxy and update niri output transform systemd.user.services.auto-rotate = { diff --git a/packages.txt b/packages.txt index efbf7da..96c2819 100644 --- a/packages.txt +++ b/packages.txt @@ -156,3 +156,4 @@ gnomeExtensions.just-perfection gnomeExtensions.vitals gnomeExtensions.launch-new-instance gnomeExtensions.user-themes +imv