From ff88fc3cd752c34f364526683222deb0a7e5bbbf Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Sun, 25 Jan 2026 21:54:04 -0600 Subject: feat(hyprland): add plugins and simplify layouts Plugins installed via hyprpm: - hy3: i3-style manual tiling with tab groups (monocle) - hyprscrolling: PaperWM-style horizontal scrolling - xtra-dispatchers: throwunfocused, bringallfrom, closeunfocused Layout system simplified to 4 modes: - Master (tile) - default DWM-style - Tab group (monocle) - via hy3 plugin - Scrolling - horizontal columns - Floating New scripts: - layout-navigate: layout-aware j/k navigation - Updated cycle-layout: cycles through 4 layouts - Updated waybar-layout: icons for new layouts Other changes: - Add hyprpm reload to startup - Add cpio and fc-cache to archsetup - Remove SSH fuzzel picker (conflicted with scrolling keybind) - Add slidevert animation for scratchpads - Update todo.org with plugin evaluation notes Co-Authored-By: Claude Opus 4.5 --- archsetup | 5 + dotfiles/hyprland/.config/hypr/hyprland.conf | 32 +- dotfiles/hyprland/.local/bin/cycle-layout | 49 ++- dotfiles/hyprland/.local/bin/layout-navigate | 58 ++++ dotfiles/hyprland/.local/bin/waybar-layout | 52 +--- todo.org | 447 ++++++++++++++++----------- 6 files changed, 386 insertions(+), 257 deletions(-) create mode 100755 dotfiles/hyprland/.local/bin/layout-navigate diff --git a/archsetup b/archsetup index c0f95ca..b07f369 100755 --- a/archsetup +++ b/archsetup @@ -835,6 +835,10 @@ user_customizations() { >> "$logfile" 2>&1 ) || error_warn "$action" "$?" fi + # Refresh font cache for any fonts in dotfiles + action="refreshing font cache" && display "task" "$action" + fc-cache -f >> "$logfile" 2>&1 || error_warn "$action" "$?" + # install desktop-file-utils before updating database (provides update-desktop-database) pacman_install desktop-file-utils @@ -1304,6 +1308,7 @@ hyprland() { pacman_install hyprpaper action="Hyprland Utilities" && display "subtitle" "$action" + pacman_install cpio # hyprpm (plugin manager) dependency pacman_install waybar # status bar pacman_install fuzzel # app launcher (native Wayland, pinentry support) pacman_install swww # wallpaper diff --git a/dotfiles/hyprland/.config/hypr/hyprland.conf b/dotfiles/hyprland/.config/hypr/hyprland.conf index e2afa07..bb099d8 100644 --- a/dotfiles/hyprland/.config/hypr/hyprland.conf +++ b/dotfiles/hyprland/.config/hypr/hyprland.conf @@ -10,6 +10,7 @@ monitor=,preferred,auto,auto # ============================================================================ # Startup Applications # ============================================================================ +exec-once = hyprpm reload exec-once = waybar exec-once = swww-daemon && sleep 1 && swww img ~/pictures/wallpaper/dark-lion.jpg exec-once = dunst @@ -64,6 +65,7 @@ animations { animation = windowsOut, 1, 3, default, popin 80% animation = fade, 1, 3, default animation = workspaces, 1, 3, default + animation = specialWorkspace, 1, 3, default, slidevert } # ============================================================================ @@ -130,7 +132,6 @@ bind = $mod, P, exec, fuzzel # From sxhkdrc bind = $mod, SPACE, exec, fuzzel -bind = $mod SHIFT, S, exec, fuzzel --dmenu < ~/.ssh/config | grep -oP '^Host\s+\K\S+' | fuzzel --dmenu --prompt "SSH: " | xargs -I{} foot ssh {} bind = $mod SHIFT, W, exec, $ALTBROWSER bind = CTRL ALT, W, exec, tor-browser bind = CTRL ALT, F, exec, thunar @@ -140,10 +141,11 @@ bind = $mod SHIFT, R, exec, shortwave bind = $mod SHIFT, P, exec, waypaper # Window management (from DWM) -bind = $mod, J, layoutmsg, cyclenext -bind = $mod, K, layoutmsg, cycleprev -bind = $mod SHIFT, J, layoutmsg, swapnext -bind = $mod SHIFT, K, layoutmsg, swapprev +# Layout-aware navigation (works across master, scrolling, hy3) +bind = $mod, J, exec, layout-navigate prev +bind = $mod, K, exec, layout-navigate next +bind = $mod SHIFT, J, exec, layout-navigate prev move +bind = $mod SHIFT, K, exec, layout-navigate next move bind = $mod, H, splitratio, -0.05 bind = $mod, L, splitratio, +0.05 bind = $mod, RETURN, layoutmsg, swapwithmaster master @@ -151,29 +153,19 @@ bind = $mod, G, centerwindow bind = $mod, TAB, workspace, previous bind = $mod SHIFT, C, killactive -# Layouts (from DWM) -# monocle [M] - maximize window -bind = $mod SHIFT, M, fullscreen, 1 -# tile []= - master on left (default master orientation) +# Layouts: master -> tab group (monocle) -> scrolling -> floating +# Click waybar layout icon to cycle, or use direct keybindings: bind = $mod SHIFT, T, exec, hyprctl keyword general:layout master && hyprctl keyword master:orientation left -# floating ><> - toggle floating for current window +bind = $mod SHIFT, M, exec, hyprctl keyword general:layout hy3 && hyprctl dispatch hy3:changegroup tab +bind = $mod SHIFT, S, exec, hyprctl keyword general:layout scrolling bind = $mod SHIFT, F, togglefloating bind = $mod SHIFT, SPACE, togglefloating -# bstack TTT - master on top -bind = $mod SHIFT, U, exec, hyprctl keyword general:layout master && hyprctl keyword master:orientation top -# bstackhoriz === - same as bstack in Hyprland -bind = $mod, U, exec, hyprctl keyword general:layout master && hyprctl keyword master:orientation top -# deck [D] - use dwindle layout as approximation -bind = $mod SHIFT, D, exec, hyprctl keyword general:layout dwindle -# centeredmaster |M| - master in center -bind = $mod SHIFT, I, exec, hyprctl keyword general:layout master && hyprctl keyword master:orientation center -# centeredfloatingmaster >M> - no direct equivalent, use centered master -bind = $mod SHIFT, O, exec, hyprctl keyword general:layout master && hyprctl keyword master:orientation center # Master layout adjustments bind = $mod, I, layoutmsg, addmaster bind = $mod, D, layoutmsg, removemaster + # Gaps (from DWM) bind = $mod, MINUS, exec, hyprctl keyword general:gaps_out $(( $(hyprctl getoption general:gaps_out -j | jq -r '.custom' | cut -d' ' -f1) - 5 )) && hyprctl keyword general:gaps_in $(( $(hyprctl getoption general:gaps_in -j | jq -r '.custom' | cut -d' ' -f1) - 5 )) bind = $mod, EQUAL, exec, hyprctl keyword general:gaps_out $(( $(hyprctl getoption general:gaps_out -j | jq -r '.custom' | cut -d' ' -f1) + 5 )) && hyprctl keyword general:gaps_in $(( $(hyprctl getoption general:gaps_in -j | jq -r '.custom' | cut -d' ' -f1) + 5 )) diff --git a/dotfiles/hyprland/.local/bin/cycle-layout b/dotfiles/hyprland/.local/bin/cycle-layout index a3b1b1a..ebfd2e0 100755 --- a/dotfiles/hyprland/.local/bin/cycle-layout +++ b/dotfiles/hyprland/.local/bin/cycle-layout @@ -1,30 +1,29 @@ #!/bin/sh # Cycle through Hyprland layouts +# Cycle: master -> hy3 (tab/monocle) -> scrolling -> floating -> master LAYOUT=$(hyprctl getoption general:layout -j | jq -r '.str') -ORIENTATION="" +FLOATING=$(hyprctl activewindow -j 2>/dev/null | jq -r '.floating // false') -if [ "$LAYOUT" = "master" ]; then - ORIENTATION=$(hyprctl getoption master:orientation -j | jq -r '.str') -fi - -# Cycle: master-left -> master-top -> master-center -> dwindle -> master-left -if [ "$LAYOUT" = "dwindle" ]; then - hyprctl keyword general:layout master - hyprctl keyword master:orientation left -elif [ "$LAYOUT" = "master" ]; then - case "$ORIENTATION" in - left) - hyprctl keyword master:orientation top - ;; - top) - hyprctl keyword master:orientation center - ;; - center) - hyprctl keyword general:layout dwindle - ;; - *) - hyprctl keyword master:orientation left - ;; - esac -fi +# Check if we're in "all floating" mode by checking layout +case "$LAYOUT" in + master) + hyprctl keyword general:layout hy3 + # Create tab group for monocle behavior + hyprctl dispatch hy3:changegroup tab + ;; + hy3) + hyprctl keyword general:layout scrolling + ;; + scrolling) + # Switch to master but float all windows + hyprctl keyword general:layout master + hyprctl dispatch workspaceopt allfloat + ;; + *) + # Return to master tiled + hyprctl dispatch workspaceopt allfloat + hyprctl keyword general:layout master + hyprctl keyword master:orientation left + ;; +esac diff --git a/dotfiles/hyprland/.local/bin/layout-navigate b/dotfiles/hyprland/.local/bin/layout-navigate new file mode 100755 index 0000000..ec2f659 --- /dev/null +++ b/dotfiles/hyprland/.local/bin/layout-navigate @@ -0,0 +1,58 @@ +#!/bin/sh +# Layout-aware navigation for Hyprland +# Usage: layout-navigate [move] +# direction: next|prev +# move: if present, move window instead of focus + +DIR="$1" +MOVE="$2" +LAYOUT=$(hyprctl getoption general:layout -j | jq -r '.str') + +case "$LAYOUT" in + scrolling) + if [ "$MOVE" = "move" ]; then + if [ "$DIR" = "next" ]; then + hyprctl dispatch layoutmsg movewindowto r + else + hyprctl dispatch layoutmsg movewindowto l + fi + else + if [ "$DIR" = "next" ]; then + hyprctl dispatch layoutmsg focus r + else + hyprctl dispatch layoutmsg focus l + fi + fi + ;; + hy3) + if [ "$MOVE" = "move" ]; then + if [ "$DIR" = "next" ]; then + hyprctl dispatch hy3:movewindow r + else + hyprctl dispatch hy3:movewindow l + fi + else + if [ "$DIR" = "next" ]; then + hyprctl dispatch hy3:movefocus r + else + hyprctl dispatch hy3:movefocus l + fi + fi + ;; + *) + # master, dwindle, etc. + if [ "$MOVE" = "move" ]; then + if [ "$DIR" = "next" ]; then + hyprctl dispatch layoutmsg swapnext + else + hyprctl dispatch layoutmsg swapprev + fi + else + if [ "$DIR" = "next" ]; then + hyprctl dispatch layoutmsg cyclenext + else + hyprctl dispatch layoutmsg cycleprev + fi + fi + ;; +esac diff --git a/dotfiles/hyprland/.local/bin/waybar-layout b/dotfiles/hyprland/.local/bin/waybar-layout index 7ffb8a8..6c45877 100755 --- a/dotfiles/hyprland/.local/bin/waybar-layout +++ b/dotfiles/hyprland/.local/bin/waybar-layout @@ -1,54 +1,36 @@ #!/bin/sh # Hyprland layout indicator for waybar # Shows current layout with nerd font icons +# Layouts: master -> tab group (monocle) -> scrolling -> floating # Get current layout LAYOUT=$(hyprctl getoption general:layout -j | jq -r '.str') -# Get master orientation if using master layout -ORIENTATION="" -if [ "$LAYOUT" = "master" ]; then - ORIENTATION=$(hyprctl getoption master:orientation -j | jq -r '.str') -fi - -# Check if active window is fullscreen (monocle) -FULLSCREEN=$(hyprctl activewindow -j | jq -r '.fullscreen') +# Check if workspace has allfloat enabled +ALLFLOAT=$(hyprctl activeworkspace -j | jq -r '.hasfullscreenwindow') # Check if active window is floating -FLOATING=$(hyprctl activewindow -j | jq -r '.floating') +FLOATING=$(hyprctl activewindow -j 2>/dev/null | jq -r '.floating // false') + +# Check workspace rules for allfloat +WSRULES=$(hyprctl activeworkspace -j | jq -r '.rules // []') # Determine icon and tooltip -if [ "$FULLSCREEN" = "2" ] || [ "$FULLSCREEN" = "1" ]; then - ICON="󰊓" - TOOLTIP="Monocle (fullscreen)" -elif [ "$FLOATING" = "true" ]; then +if [ "$LAYOUT" = "master" ] && echo "$WSRULES" | grep -q "allfloat"; then ICON="󰖲" TOOLTIP="Floating" -elif [ "$LAYOUT" = "dwindle" ]; then - ICON="󱒎" - TOOLTIP="Dwindle" +elif [ "$LAYOUT" = "scrolling" ]; then + ICON="󰯍" + TOOLTIP="Scrolling" +elif [ "$LAYOUT" = "hy3" ]; then + ICON="󰖯" + TOOLTIP="Tab Group (Monocle)" elif [ "$LAYOUT" = "master" ]; then - case "$ORIENTATION" in - left) - ICON="󰕰" - TOOLTIP="Master (left)" - ;; - top) - ICON="󱂩" - TOOLTIP="Master (top)" - ;; - center) - ICON="󰘸" - TOOLTIP="Master (center)" - ;; - *) - ICON="󰕰" - TOOLTIP="Master" - ;; - esac + ICON="󰕰" + TOOLTIP="Master" else ICON="󰕰" - TOOLTIP="Unknown" + TOOLTIP="$LAYOUT" fi echo "{\"text\": \"$ICON\", \"tooltip\": \"$TOOLTIP\"}" diff --git a/todo.org b/todo.org index c4055bd..49a549a 100644 --- a/todo.org +++ b/todo.org @@ -119,6 +119,223 @@ The script handles edge cases gracefully, provides detailed error messages with *Why this is Method 1:* Can't build testing infrastructure or maintain packages if the script doesn't work. This is the foundation—everything else depends on reliable execution. +*** TODO [#A] Make Hyprland Bulletproof and Comfy +**** TODO [#A] Fix Hyprland Configuration Issues +Issues discovered during live testing on ratio. Add sub-items as "hyprland config issue". + +***** TODO [#B] Consider Hyprland Plugins +Official plugins: https://github.com/hyprwm/hyprland-plugins +Install via hyprpm (added cpio dependency to archsetup). + +Interesting plugins: + +****** hyprscrolling (INTERESTED) +Arranges windows in vertical columns that scroll horizontally - like a paper tape. +Instead of tiling in a grid, windows line up side-by-side and you scroll through them. +Note: Still marked "work in progress" - may have rough edges. + +Options: +- column_width: default column width (0.5 = half monitor) +- explicit_column_widths: widths to cycle through ("0.333, 0.5, 0.667, 1.0") +- fullscreen_on_one_column: maximize when only one column +- focus_fit_method: 0=center focused column, 1=just fit on screen +- follow_focus: auto-scroll when focusing a window + +****** xtra-dispatchers (INTERESTED) +Adds 4 new dispatcher commands: + +| Dispatcher | What it does | +|-------------------------------------+-----------------------------------------------| +| plugin:xtd:moveorexec WINDOW,CMD | Move window here, or launch if not running | +| plugin:xtd:throwunfocused WORKSPACE | Send all unfocused windows away (focus mode!) | +| plugin:xtd:bringallfrom WORKSPACE | Bring all windows from another workspace | +| plugin:xtd:closeunfocused | Close all unfocused windows | + +throwunfocused is useful for focus mode - declutter workspace, then bringallfrom to restore. +closeunfocused is handy for cleaning up. + +****** Other official plugins +- hyprbars: window title bars +- hyprexpo: workspace overview (like macOS Mission Control) +- hyprfocus: flash effect when changing focus +- hyprtrails: window trail effects (eye candy) +- borders-plus-plus: extra border layers (cosmetic) +- hyprwinwrap: use any app as wallpaper + +***** TODO [#C] Evaluate Hyprland Layout Options +Current layouts: master (left/top/center), dwindle. No deck layout available natively. + +Options to consider: +1. Restrict to commonly used layouts only (remove unused from cycle) +2. Add hy3 plugin for i3-style manual tiling (horizontal/vertical/tab groups) + +hy3 plugin: +- URL: https://github.com/outfoxxed/hy3 +- Provides: horizontal splits, vertical splits, tab groups, autotiling +- Does NOT provide deck layout +- Requires different dispatchers (hy3:movefocus, hy3:makegroup, etc.) + +Other layout plugins (none have deck): +- hyprNStack: N-stack tiling +- hyprscroller: PaperWM-style scrolling +- hyprRiver: River-inspired layouts + +Decision: Keep current setup or adopt hy3 for more flexible manual tiling. + +***** TODO [#C] Consider Pywal for Dynamic Theming +Use pywal to generate color schemes from wallpaper. Reference: reference-repos/kastrbl4nik-dots/ +Tools: swww (wallpaper), wal (colors), pywalfox (Firefox), pywal-spicetify (Spotify) + +***** TODO [#C] Consider Customizing Hyprland Animations +Current: windows pop in, scratchpads slide from bottom. + +Customizable animations: +- windows / windowsOut / windowsMove - window open/close/move +- fade - opacity changes +- border / borderangle - border color and gradient angle +- workspaces - workspace switching +- specialWorkspace - scratchpads (currently slidevert) +- layers - waybar, notifications, etc. + +Styles: slide, slidevert, popin X%, fade +Parameters: animation = NAME, ON/OFF, SPEED, BEZIER, STYLE +Speed: lower = faster (1-10 typical) + +Example tweaks: +#+begin_src conf +animation = windows, 1, 2, myBezier, popin 80% +animation = workspaces, 1, 4, default, slide +animation = fade, 1, 2, default +animation = layers, 1, 2, default, fade +#+end_src + +***** CANCELLED [#D] Consider "show desktop" toggle via empty special workspace +CLOSED: [2026-01-25 Sun 21:13] +I think what I really want is the throw to other workspace dispatcher. + +Toggle to an empty special workspace to temporarily hide all windows (shows desktop). +Toggle again to return to windows. +Implementation: +#+begin_src conf +bind = $mod, Z, togglespecialworkspace, desktop +#+end_src + +***** DONE Scratchpads not spawning on keybind +mod+shift+return toggles special workspace (screen dims) but foot terminal doesn't spawn. +- Manual spawn works: =foot -T spterm tmux= +- Fixed pgrep self-match issue (bracket trick) +- Fixed windowrule syntax (match:class first, then rule) +- Still not working - need further investigation + +***** DONE Wofi launcher can't be dismissed +CLOSED: [2026-01-25 Sun 20:50] +mod+space launches wofi but mod+space and mod+shift+c don't dismiss it. +Need to configure proper dismiss keybinding. + +***** DONE No wallpaper displaying +Desktop has no wallpaper. Need to set up swww or similar. + +***** DONE Verify foot -T flag sets window title correctly +Need to confirm foot uses -T for title (vs -t or --title). + +***** DONE Pulsemixer scratchpad sizing different from others +mod+a pulsemixer scratchpad appears to be sized differently than other scratchpads. +All use same rules: size (monitor_w*0.6) (monitor_h*0.6). Investigate why it differs. + +***** DONE Waybar wireplumber volume control not working +CLOSED: [2026-01-25 Sun 20:50] +Click to mute and scroll to adjust not responding. Config uses wpctl commands. +May need to verify wpctl is working or try different approach. + +***** DONE Waybar clock not displaying +Clock module is configured correctly but not showing on bar. +- Config and style.css are stowed correctly +- Font (FiraCode Nerd Font Mono) is installed +- Removed battery module (desktop has no battery) +- Other modules (tray, disk, workspaces) appear to work +- Reference config in reference-repos/hyprland-dotfiles/waybar/ + +*** TODO [#A] Fix sleep/suspend on Framework Laptop (velox only) +Critical functionality for laptop use - current battery drain unacceptable +**NOTE:** This applies to Framework Laptop (velox), not Framework Desktop (ratio) +Add kernel parameter: ~rtc_cmos.use_acpi_alarm=1~ (will become systemd default) +Consider: ~acpi_mask_gpe=0x1A~ for battery drain, suspend-then-hibernate config +See Framework community notes on logind.conf and sleep.conf settings + +*** TODO [#B] Review slow and failed packages from 8GB RAM test +See [[file:docs/slow-failed-packages.org][Slow and Failed Packages Analysis]] + +Test run from 2025-11-09 with 8GB RAM, 50GB disk identified: +- 2 packages that hang indefinitely (anki, tageditor) +- 4 packages that fail to install (nitrogen, gtk-engine-murrine, adwaita-color-schemes, vagrant) +- Several slow but successful packages (multimarkdown, ptyxis, thunderbird, etc.) + +High priority actions: +- Remove or make optional: anki (hangs 98 min), tageditor (hangs on qt5-webengine) +- Investigate repository/build issues for failing packages + +*** TODO [#B] Improve error handling: UFW firewall, rmmod pcspkr, mkdir missing quotes +**** DONE [#B] Fix UFW firewall error handling (archsetup:395,410) +CLOSED: [2026-01-21 Wed] +Firewall failures use ~|| error "error"~ which logs but continues - system may be left exposed +Should use ~|| error "crash"~ or validate rules were applied successfully +RESOLVED: Added firewall verification after setup (checks "ufw status | grep Status: active"). +If verification fails, displays CRITICAL SECURITY WARNING in outro with manual fix commands. +**** DONE [#B] Fix rmmod pcspkr error (archsetup:588) +CLOSED: [2026-01-21 Wed] +~rmmod pcspkr~ doesn't check if module is loaded, produces error if already unloaded +Should use ~rmmod pcspkr 2>/dev/null || true~ or check with ~lsmod~ +RESOLVED: Changed to ~rmmod pcspkr 2>/dev/null || true~ +**** DONE [#B] Fix mkdir missing quotes (archsetup:247) +CLOSED: [2026-01-21 Wed] +Line 247: ~mkdir -p $source_dir~ should be ~mkdir -p "$source_dir"~ - fails if path contains spaces +RESOLVED: Current code at line 577 properly quotes: ~(mkdir -p "$source_dir")~ + +*** TODO [#B] Test complete end-to-end run on fresh VM +Validates the script actually works in a clean environment (blocks claiming Method 1 complete) + +*** TODO [#B] Make all error messages actionable with recovery steps +Currently just reports errors without guidance on how to fix them + +*** TODO [#B] Improve progress indicators throughout install +Enhance existing indicators to show what's happening in real-time + +*** TODO [#B] Check that full install logs have timestamps +Verify timestamps exist for debugging failures + +*** TODO [#B] Add retry logic to git_install function +pacman_install and aur_install have retry logic, but git_install doesn't + +*** TODO [#B] Add input validation for username and paths +Variables like ~$username~, ~$source_dir~, and paths are not validated +Special characters or malicious input could break the script or cause security issues +Should validate inputs match expected patterns (alphanumeric, valid paths, etc.) + +*** TODO [#B] Enable TLP power management for Framework Laptop +TLP manages power-saving modes for Wi-Fi, USB, PCIe, Bluetooth, CPU scheduler +Install tlp, enable service, add custom Framework 13 config to /etc/tlp.d/01-custom.conf +Improves battery life and prevents power-related issues during install/post-install + +*** TODO [#B] Improve logging consistency +Some operations log to ~$logfile~, others don't - standardize logging +All package installs should log, all system modifications should log, all errors should log with context +Makes debugging failed installations easier + +*** TODO [#C] Add backup before system file modifications +Safety net for /etc/X11/xorg.conf.d and other system file edits +Files like ~/etc/sudoers~, ~/etc/pacman.conf~, ~/etc/default/grub~ modified without backup +If modifications fail or are incorrect, difficult to recover - should backup files to ~.backup~ before modifying + +*** TODO [#C] Parse and improve AUR error reporting +Parse yay errors and provide specific, actionable fixes instead of generic error messages + +*** TODO [#D] Add cpupower installation and enabling to archsetup +cpupower service configures the default CPU scheduler (powersave or performance) +Install cpupower, configure /etc/default/cpupower, enable service: ~systemctl enable --now cpupower.service~ + +*** VERIFY [#C] FZF works everywhere +Especially the ** expander for all files - may already be fixed, needs verification + *** DONE [#A] Fix: no dotfiles were set up on last run CLOSED: [2025-11-13 Wed] RESOLVED - VM test confirms dotfiles are properly stowed as symlinks; all configs and scripts in place @@ -153,13 +370,6 @@ RESOLVED: Implemented file-based state tracking: - --fresh flag clears state for clean restart - 12 major steps tracked (intro through boot_ux) -*** TODO [#A] Fix sleep/suspend on Framework Laptop (velox only) -Critical functionality for laptop use - current battery drain unacceptable -**NOTE:** This applies to Framework Laptop (velox), not Framework Desktop (ratio) -Add kernel parameter: ~rtc_cmos.use_acpi_alarm=1~ (will become systemd default) -Consider: ~acpi_mask_gpe=0x1A~ for battery drain, suspend-then-hibernate config -See Framework community notes on logind.conf and sleep.conf settings - *** DONE [#A] Disable installing -debug packages CLOSED: [2025-12-01 Sun] Currently archsetup downloads a -debug package for every package installed, doubling install time @@ -182,18 +392,6 @@ CLOSED: [2026-01-20 Mon] AMD RDSEED warnings appearing at boot ("RDSEED32 is broken"). RESOLVED: Added random.trust_cpu=off to GRUB_CMDLINE_LINUX_DEFAULT. -*** TODO [#B] Review slow and failed packages from 8GB RAM test -See [[file:docs/slow-failed-packages.org][Slow and Failed Packages Analysis]] - -Test run from 2025-11-09 with 8GB RAM, 50GB disk identified: -- 2 packages that hang indefinitely (anki, tageditor) -- 4 packages that fail to install (nitrogen, gtk-engine-murrine, adwaita-color-schemes, vagrant) -- Several slow but successful packages (multimarkdown, ptyxis, thunderbird, etc.) - -High priority actions: -- Remove or make optional: anki (hangs 98 min), tageditor (hangs on qt5-webengine) -- Investigate repository/build issues for failing packages - *** DONE [#B] Resolve all 8 failed packages from last run CLOSED: [2025-11-13 Wed] All sub-items resolved - packages either fixed or removed from archsetup. @@ -219,48 +417,6 @@ REMOVED from archsetup - package removed due to build issues (hangs 98+ minutes, CLOSED: [2025-11-13 Wed] FTP download issue resolved - figlet-fonts 1.1-1 successfully installs in VM test -*** TODO [#B] Improve error handling: UFW firewall, rmmod pcspkr, mkdir missing quotes -**** DONE [#B] Fix UFW firewall error handling (archsetup:395,410) -CLOSED: [2026-01-21 Wed] -Firewall failures use ~|| error "error"~ which logs but continues - system may be left exposed -Should use ~|| error "crash"~ or validate rules were applied successfully -RESOLVED: Added firewall verification after setup (checks "ufw status | grep Status: active"). -If verification fails, displays CRITICAL SECURITY WARNING in outro with manual fix commands. -**** DONE [#B] Fix rmmod pcspkr error (archsetup:588) -CLOSED: [2026-01-21 Wed] -~rmmod pcspkr~ doesn't check if module is loaded, produces error if already unloaded -Should use ~rmmod pcspkr 2>/dev/null || true~ or check with ~lsmod~ -RESOLVED: Changed to ~rmmod pcspkr 2>/dev/null || true~ -**** DONE [#B] Fix mkdir missing quotes (archsetup:247) -CLOSED: [2026-01-21 Wed] -Line 247: ~mkdir -p $source_dir~ should be ~mkdir -p "$source_dir"~ - fails if path contains spaces -RESOLVED: Current code at line 577 properly quotes: ~(mkdir -p "$source_dir")~ - -*** TODO [#B] Test complete end-to-end run on fresh VM -Validates the script actually works in a clean environment (blocks claiming Method 1 complete) - -*** TODO [#B] Make all error messages actionable with recovery steps -Currently just reports errors without guidance on how to fix them - -*** TODO [#B] Improve progress indicators throughout install -Enhance existing indicators to show what's happening in real-time - -*** TODO [#B] Check that full install logs have timestamps -Verify timestamps exist for debugging failures - -*** TODO [#B] Add retry logic to git_install function -pacman_install and aur_install have retry logic, but git_install doesn't - -*** TODO [#B] Add input validation for username and paths -Variables like ~$username~, ~$source_dir~, and paths are not validated -Special characters or malicious input could break the script or cause security issues -Should validate inputs match expected patterns (alphanumeric, valid paths, etc.) - -*** TODO [#B] Enable TLP power management for Framework Laptop -TLP manages power-saving modes for Wi-Fi, USB, PCIe, Bluetooth, CPU scheduler -Install tlp, enable service, add custom Framework 13 config to /etc/tlp.d/01-custom.conf -Improves battery life and prevents power-related issues during install/post-install - *** DONE [#B] Fix "at" error during install CLOSED: [2026-01-21 Wed] Package fails with yay - appears to be in extra repository, may need to change to AUR install or verify correct source @@ -283,11 +439,6 @@ All music is in opus format - system needs opus codec to play music files Install opus package to prevent audio playback issues RESOLVED: Added pacman_install opus to archsetup (audio section) -*** TODO [#B] Improve logging consistency -Some operations log to ~$logfile~, others don't - standardize logging -All package installs should log, all system modifications should log, all errors should log with context -Makes debugging failed installations easier - *** DONE [#B] Complete Rofi integration CLOSED: [2025-12-01 Sun] Rofi installed but needs testing and polish to ensure no friction @@ -327,26 +478,11 @@ Wastes time and could mask package issues RESOLVED: obsidian already removed. Removed duplicate mediainfo from line 1510 (general apps); kept line 1407 (Emacs/dired section) where it's grouped with related preview tools. -*** TODO [#C] Add backup before system file modifications -Safety net for /etc/X11/xorg.conf.d and other system file edits -Files like ~/etc/sudoers~, ~/etc/pacman.conf~, ~/etc/default/grub~ modified without backup -If modifications fail or are incorrect, difficult to recover - should backup files to ~.backup~ before modifying - -*** TODO [#C] Parse and improve AUR error reporting -Parse yay errors and provide specific, actionable fixes instead of generic error messages - -*** VERIFY [#C] FZF works everywhere -Especially the ** expander for all files - may already be fixed, needs verification - *** DONE [#C] All mail secrets files added to dotfiles CLOSED: [2026-01-21 Wed] Verify mail configuration and secrets are properly tracked in dotfiles RESOLVED: Mail secrets present in dotfiles: .mbsyncrc and .authinfo.gpg -*** TODO [#D] Add cpupower installation and enabling to archsetup -cpupower service configures the default CPU scheduler (powersave or performance) -Install cpupower, configure /etc/default/cpupower, enable service: ~systemctl enable --now cpupower.service~ - ** Method 2: Establish Continuous Validation Every change to archsetup is automatically tested in a fresh environment. CI/CD runs the full install, captures logs, and reports what succeeded and what failed—with actionable recovery information. When packages fail to install (which will happen—that's outside my control), the test reports exactly which packages failed and provides a recovery script I can run post-install. Success isn't zero failures; success is clear, accurate reporting of failures. @@ -489,6 +625,18 @@ See [[file:docs/firmware-cleanup.org][docs/firmware-cleanup.org]] for full analy After removal, update archsetup script to install only needed firmware packages. +*** TODO [#B] Identify and replace packages no longer in repos +Systematic check for availability issues + +*** TODO [#B] Verify package origin for all packages +Ensure packages are installed from correct source (official repos vs AUR) - prevent installing from wrong place + +*** TODO [#B] Automate script usage tracking +Parse shell history files for ~/.local/bin script names to identify last usage date and unused scripts + +*** TODO [#B] Automate dotfile validation +Parse config files for binary/command references and verify those binaries exist - catch orphaned references + *** TODO [#C] Review and reorganize dotfiles for unused applications Review all dotfiles by application and remove unused application configurations. @@ -512,6 +660,12 @@ Current state: Reference: Identified on 2025-11-15 during package cleanup session +*** TODO [#C] Set up alerts for deprecated packages +Proactive monitoring integrated with Method 2 testing + +*** TODO [#C] Cleanup dotfiles repository +The .dotfiles repo has configuration for applications no longer used - remove stale configs + *** DONE [#B] Replace deprecated ntp with chrony CLOSED: [2026-01-21 Wed] ~ntp~ and ~ntpdate~ are deprecated - modern alternatives: @@ -520,24 +674,6 @@ CLOSED: [2026-01-21 Wed] Recommendation: Use ~chrony~ for better accuracy and laptop compatibility RESOLVED: Replaced ntp with chrony in package list; replaced ntpdate with chronyd -q one-shot sync -*** TODO [#B] Identify and replace packages no longer in repos -Systematic check for availability issues - -*** TODO [#B] Verify package origin for all packages -Ensure packages are installed from correct source (official repos vs AUR) - prevent installing from wrong place - -*** TODO [#B] Automate script usage tracking -Parse shell history files for ~/.local/bin script names to identify last usage date and unused scripts - -*** TODO [#B] Automate dotfile validation -Parse config files for binary/command references and verify those binaries exist - catch orphaned references - -*** TODO [#C] Set up alerts for deprecated packages -Proactive monitoring integrated with Method 2 testing - -*** TODO [#C] Cleanup dotfiles repository -The .dotfiles repo has configuration for applications no longer used - remove stale configs - ** Method 4: Ensure Secure AND Functional System I understand my laptop's security posture and trust it's properly protected. The firewall is enabled with correct rules—ports are open only for services I actually use, and everything I need works without fighting the security. When I enable Proton Mail Bridge, it works. When I connect to my remote server via SSH, it works. When I'm working in a cafe on public wifi, I'm confident I'm protected from casual attackers on the same network. @@ -589,12 +725,6 @@ Removed conflicting setxkbmap statements, gdm, and keyd configs - still didn't w *** TODO [#B] Document threat model and mitigations within 6 months Identify attack vectors, what's mitigated, what remains -*** DONE [#B] Add net-tools to archsetup for network connection monitoring -CLOSED: [2026-01-21 Wed] -Install net-tools package to enable ~netstat -nlp~ for checking open network connections -Useful for security auditing and verifying no unexpected services are listening -RESOLVED: Added pacman_install net-tools to archsetup - *** TODO [#B] Verify package signature verification not bypassed by --noconfirm Packages installed with ~--noconfirm~ may skip signature checks AUR had issues previously requiring --noconfirm workaround - verify this doesn't compromise security @@ -606,6 +736,12 @@ Practical guidelines for working in public spaces *** TODO [#C] Build security dashboard command Single command shows: encryption status, firewall status, open ports, running services +*** DONE [#B] Add net-tools to archsetup for network connection monitoring +CLOSED: [2026-01-21 Wed] +Install net-tools package to enable ~netstat -nlp~ for checking open network connections +Useful for security auditing and verifying no unexpected services are listening +RESOLVED: Added pacman_install net-tools to archsetup + ** Method 5: Modernize Software Stack My software stack evolves naturally as I discover better alternatives. When I see a tool being used elsewhere that solves a problem more elegantly, or when I identify a deficiency in what I'm currently using (like lack of ligature support in my terminal), I have a clear process to evaluate whether the new tool is worth adopting. @@ -622,6 +758,16 @@ Establish clear process for tool evaluation decisions *** TODO [#B] Test each modernization thoroughly before replacing Ensure new tools integrate with DWM environment and don't break workflow +*** TODO [#B] Add Rust installation via rustup instead of pacman package +The =rust= package has been removed from archsetup. Need to add Rust installation using =rustup= (the official Rust toolchain manager) instead of the Arch package. + +Steps: +- Install rustup: =pacman -S rustup= +- Initialize default toolchain: =rustup default stable= +- Consider adding to archsetup or post-install script + +Reference: Removed from archsetup on 2025-11-15 + *** TODO [#C] Evaluate modern CLI tool replacements bat, eza, zoxide, dust, ripgrep-all - only adopt if clear friction reduction @@ -645,16 +791,6 @@ RESOLVED: zoxide added to archsetup (line 1382: pacman_install zoxide) **** TODO [#C] Install Zoxide integration into Ranger https://github.com/jchook/ranger-zoxide - enables zoxide jumping within ranger file manager -*** TODO [#B] Add Rust installation via rustup instead of pacman package -The =rust= package has been removed from archsetup. Need to add Rust installation using =rustup= (the official Rust toolchain manager) instead of the Arch package. - -Steps: -- Install rustup: =pacman -S rustup= -- Initialize default toolchain: =rustup default stable= -- Consider adding to archsetup or post-install script - -Reference: Removed from archsetup on 2025-11-15 - *** TODO [#D] Bulk shellcheck cleanup Reviewed 2026-01-24: ~128 warnings, mostly acceptable patterns or low-priority style issues. - SC2024 (sudo redirects) - acceptable, script runs as root @@ -677,7 +813,18 @@ Currently archsetup installs only Xorg with DWM. This method adds a Wayland-base - Same keybindings = same muscle memory, no relearning - Choice allows gradual migration without losing fallback -*** TODO [#A] Create Wayland/Hyprland desktop environment option +*** TODO [#B] Add NVIDIA preflight check for Hyprland +Detect NVIDIA GPU and warn user about potential Wayland issues: +- Require driver version 535+ or abort +- Document required env vars (LIBVA_DRIVER_NAME, GBM_BACKEND, etc.) +- Prompt to continue or abort if NVIDIA detected + +*** TODO [#B] Validate DESKTOP_ENV default behavior +Confirm that defaulting DESKTOP_ENV to "dwm" when unassigned is the right choice. +Consider: should it prompt interactively instead? Or fail with a clear message? + +*** DONE [#A] Create Wayland/Hyprland desktop environment option +CLOSED: [2026-01-25 Sun 20:52] **** Requirements - Same keybindings as DWM/sxhkd (translate config) - Visual style matches current DWM setup initially @@ -709,7 +856,8 @@ Options to explore: 5. Implement user selection mechanism 6. Document differences and gotchas -*** TODO [#B] Write detailed Hyprland implementation plan +*** DONE [#B] Write detailed Hyprland implementation plan +CLOSED: [2026-01-25 Sun 20:52] Create docs/hyprland-implementation-plan.org with: - Full keybinding mapping from sxhkdrc - Package list comparison (Xorg vs Wayland) @@ -717,17 +865,8 @@ Create docs/hyprland-implementation-plan.org with: - Testing checklist - Rollback strategy -*** TODO [#B] Add NVIDIA preflight check for Hyprland -Detect NVIDIA GPU and warn user about potential Wayland issues: -- Require driver version 535+ or abort -- Document required env vars (LIBVA_DRIVER_NAME, GBM_BACKEND, etc.) -- Prompt to continue or abort if NVIDIA detected - -*** TODO [#B] Validate DESKTOP_ENV default behavior -Confirm that defaulting DESKTOP_ENV to "dwm" when unassigned is the right choice. -Consider: should it prompt interactively instead? Or fail with a clear message? - -*** TODO [#B] Review Hyprland dotfile repositories for visual inspiration +*** DONE [#B] Review Hyprland dotfile repositories for visual inspiration +CLOSED: [2026-01-25 Sun 20:52] See docs/PLAN-20260124-hyprland.org "Notes & References" section for URLs. Look for minimal, clean setups that avoid excessive transparency. Drop any additional URLs found into docs/inbox/ for later review. @@ -965,7 +1104,8 @@ Package: =yay -S lexend-fonts-git= Captured On: [2025-11-12 Tue 13:52] RESOLVED: Added aur_install lexend-fonts-git to archsetup (fonts section) -** TODO [#C] Patch Berkeley Mono to nerd font +** DONE [#C] Patch Berkeley Mono to nerd font +CLOSED: [2026-01-25 Sun 21:00] Use nerd-fonts patcher to add glyphs to Berkeley Mono for icon support in waybar/terminal. Options: - Full repo: https://github.com/ryanoasis/nerd-fonts (includes font-patcher script) @@ -988,54 +1128,7 @@ Options: - pywal: generate schemes from wallpaper (see pywal task below) - nwg-look + GTK theming for GUI apps -** DONE [#A] Fix Hyprland configuration issues -Issues discovered during live testing on ratio. Add sub-items as "hyprland config issue". - -*** DONE Scratchpads not spawning on keybind -mod+shift+return toggles special workspace (screen dims) but foot terminal doesn't spawn. -- Manual spawn works: =foot -T spterm tmux= -- Fixed pgrep self-match issue (bracket trick) -- Fixed windowrule syntax (match:class first, then rule) -- Still not working - need further investigation - -*** TODO Wofi launcher can't be dismissed -mod+space launches wofi but mod+space and mod+shift+c don't dismiss it. -Need to configure proper dismiss keybinding. - -*** DONE No wallpaper displaying -Desktop has no wallpaper. Need to set up swww or similar. - -*** DONE Verify foot -T flag sets window title correctly -Need to confirm foot uses -T for title (vs -t or --title). - -*** DONE [#D] Pulsemixer scratchpad sizing different from others -mod+a pulsemixer scratchpad appears to be sized differently than other scratchpads. -All use same rules: size (monitor_w*0.6) (monitor_h*0.6). Investigate why it differs. - -*** TODO [#C] Consider pywal for dynamic theming -Use pywal to generate color schemes from wallpaper. Reference: reference-repos/kastrbl4nik-dots/ -Tools: swww (wallpaper), wal (colors), pywalfox (Firefox), pywal-spicetify (Spotify) - -*** TODO Waybar wireplumber volume control not working -Click to mute and scroll to adjust not responding. Config uses wpctl commands. -May need to verify wpctl is working or try different approach. - -*** DONE Waybar clock not displaying -Clock module is configured correctly but not showing on bar. -- Config and style.css are stowed correctly -- Font (FiraCode Nerd Font Mono) is installed -- Removed battery module (desktop has no battery) -- Other modules (tray, disk, workspaces) appear to work -- Reference config in reference-repos/hyprland-dotfiles/waybar/ - -*** TODO [#D] Consider "show desktop" toggle via empty special workspace -Toggle to an empty special workspace to temporarily hide all windows (shows desktop). -Toggle again to return to windows. -Implementation: -#+begin_src conf -bind = $mod, Z, togglespecialworkspace, desktop -#+end_src - +* ArchSetup Notes ** Favorite Reference Repos (Hyprland/Waybar) These repos stood out for clean code, aesthetics, or useful features. Return to these for inspiration. -- cgit v1.2.3