From cc05a1d7900481acd7b56049cb5bb09e46d3f69c Mon Sep 17 00:00:00 2001 From: Ivan Malison Date: Tue, 20 Jan 2026 13:34:45 -0500 Subject: [PATCH] Add Hyprland with hy3 plugin for XMonad-like tiling Configure Hyprland to use the hy3 plugin for dynamic tiling similar to XMonad. Uses official Hyprland and hy3 flakes pinned to v0.53.0 for proper plugin compatibility (nixpkgs packaging had header issues). Key changes: - Add hyprland and hy3 flake inputs with version pinning - Rewrite hyprland.conf with hy3 layout and XMonad-like keybindings - Add helper scripts for window management (bring, replace, gather, etc.) - WASD directional navigation using hy3:movefocus/movewindow - Tab groups, horizontal/vertical splits via hy3:makegroup - Scratchpads via Hyprland special workspaces Also removes org-agenda-api flake integration (moved elsewhere). Co-Authored-By: Claude Opus 4.5 --- dotfiles/config/hypr/hyprland.conf | 497 +++++++--- dotfiles/config/hypr/scripts/bring-window.sh | 30 + dotfiles/config/hypr/scripts/cycle-layout.sh | 15 + .../config/hypr/scripts/focus-next-class.sh | 48 + dotfiles/config/hypr/scripts/gather-class.sh | 30 + dotfiles/config/hypr/scripts/raise-or-run.sh | 19 + .../config/hypr/scripts/replace-window.sh | 33 + .../hypr/scripts/shift-to-empty-on-screen.sh | 30 + nixos/desktop.nix | 3 +- nixos/extra.nix | 2 - nixos/flake.lock | 872 ++++++++++++------ nixos/flake.nix | 31 +- nixos/hyprland.nix | 16 +- 13 files changed, 1198 insertions(+), 428 deletions(-) create mode 100755 dotfiles/config/hypr/scripts/bring-window.sh create mode 100755 dotfiles/config/hypr/scripts/cycle-layout.sh create mode 100755 dotfiles/config/hypr/scripts/focus-next-class.sh create mode 100755 dotfiles/config/hypr/scripts/gather-class.sh create mode 100755 dotfiles/config/hypr/scripts/raise-or-run.sh create mode 100755 dotfiles/config/hypr/scripts/replace-window.sh create mode 100755 dotfiles/config/hypr/scripts/shift-to-empty-on-screen.sh diff --git a/dotfiles/config/hypr/hyprland.conf b/dotfiles/config/hypr/hyprland.conf index bd375e48..b97b4e80 100644 --- a/dotfiles/config/hypr/hyprland.conf +++ b/dotfiles/config/hypr/hyprland.conf @@ -1,25 +1,38 @@ # Hyprland Configuration +# XMonad-like dynamic tiling using hy3 plugin # Based on XMonad configuration from xmonad.hs -# See https://wiki.hyprland.org/Configuring/Monitors/ +# ============================================================================= +# PLUGINS (Hyprland pinned to 0.53.0 to match hy3) +# ============================================================================= +exec-once = hyprctl plugin load /run/current-system/sw/lib/libhy3.so +# hyprexpo disabled - header compatibility issue +# exec-once = hyprctl plugin load /run/current-system/sw/lib/libhyprexpo.so + +# ============================================================================= +# MONITORS +# ============================================================================= monitor=,preferred,auto,auto -# Source a file (multi-file configs) -# source = ~/.config/hypr/myColors.conf - -# Set programs that you use +# ============================================================================= +# PROGRAMS +# ============================================================================= $terminal = alacritty $fileManager = dolphin $menu = rofi -show drun -show-icons $runMenu = rofi -show run -# Environment variables +# ============================================================================= +# ENVIRONMENT VARIABLES +# ============================================================================= env = XCURSOR_SIZE,24 env = QT_QPA_PLATFORMTHEME,qt5ct env = GDK_DPI_SCALE,1.25 env = QT_FONT_DPI,120 -# Input configuration +# ============================================================================= +# INPUT CONFIGURATION +# ============================================================================= input { kb_layout = us kb_variant = @@ -33,100 +46,213 @@ input { natural_scroll = no } - sensitivity = 0 # -1.0 - 1.0, 0 means no modification. + sensitivity = 0 } -# General settings +# ============================================================================= +# GENERAL SETTINGS +# ============================================================================= general { gaps_in = 5 - gaps_out = 20 + gaps_out = 10 border_size = 2 col.active_border = rgba(edb443ee) rgba(33ccffee) 45deg col.inactive_border = rgba(595959aa) - layout = master + # Use hy3 layout for XMonad-like dynamic tiling + layout = hy3 allow_tearing = false } -# Decoration +# ============================================================================= +# DECORATION +# ============================================================================= decoration { - rounding = 10 - + rounding = 5 + blur { enabled = true size = 3 passes = 1 } + + # Fade inactive windows (like XMonad's fadeInactive) + active_opacity = 1.0 + inactive_opacity = 0.9 } -# Animations +# ============================================================================= +# ANIMATIONS +# ============================================================================= animations { enabled = yes bezier = myBezier, 0.05, 0.9, 0.1, 1.05 + bezier = linear, 0, 0, 1, 1 - animation = windows, 1, 7, myBezier - animation = windowsOut, 1, 7, default, popin 80% + animation = windows, 1, 4, myBezier + animation = windowsOut, 1, 4, default, popin 80% animation = border, 1, 10, default animation = borderangle, 1, 8, default - animation = fade, 1, 7, default - animation = workspaces, 1, 6, default -} - -# Layout configuration -dwindle { - pseudotile = yes # master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below - preserve_split = yes # you probably want this + animation = fade, 1, 4, default + animation = workspaces, 1, 4, default } +# ============================================================================= +# MASTER LAYOUT CONFIGURATION +# ============================================================================= master { - mfact = 0.25 + new_status = slave + mfact = 0.5 orientation = left + # Smart gaps - no gaps when only one window + no_gaps_when_only = 1 } -# Misc +# Dwindle layout (alternative - binary tree like i3) +dwindle { + pseudotile = yes + preserve_split = yes + no_gaps_when_only = 1 +} + +# Group/tabbed window configuration (built-in alternative to hy3 tabs) +group { + col.border_active = rgba(edb443ff) + col.border_inactive = rgba(091f2eff) + + groupbar { + enabled = true + font_size = 12 + height = 22 + col.active = rgba(edb443ff) + col.inactive = rgba(091f2eff) + text_color = rgba(091f2eff) + } +} + +# ============================================================================= +# HY3/HYPREXPO PLUGIN CONFIG +# ============================================================================= +plugin { + hy3 { + # Disable autotile to get XMonad-like manual control + autotile { + enable = false + } + + # Tab configuration + tabs { + height = 22 + padding = 6 + render_text = true + text_font = "Sans" + text_height = 10 + text_padding = 3 + col.active = rgba(edb443ff) + col.inactive = rgba(091f2eff) + col.urgent = rgba(ff0000ff) + col.text.active = rgba(091f2eff) + col.text.inactive = rgba(ffffffff) + col.text.urgent = rgba(ffffffff) + } + } + + # hyprexpo disabled - header compatibility issue + # hyprexpo { + # columns = 3 + # gap_size = 5 + # bg_col = rgba(000000ff) + # workspace_method = first 1 + # enable_gesture = true + # gesture_fingers = 3 + # gesture_distance = 300 + # gesture_positive = false + # } +} + +# ============================================================================= +# MISC +# ============================================================================= misc { force_default_wallpaper = 0 disable_hyprland_logo = true } -# Scratchpad-like windows -windowrule = float, title:^(htop)$ -windowrule = size 80% 80%, title:^(htop)$ +# ============================================================================= +# WINDOW RULES +# ============================================================================= +# Float dialogs +windowrulev2 = float, class:^()$,title:^()$ +windowrulev2 = float, title:^(Picture-in-Picture)$ +windowrulev2 = float, title:^(Open File)$ +windowrulev2 = float, title:^(Save File)$ +windowrulev2 = float, title:^(Confirm)$ -# Chrome specific rules -windowrule = float, class:^(chrome)$,title:^(.*@gmail.com.*Gmail.*)$ -windowrule = float, class:^(chrome)$,title:^(Messages)$ -windowrule = size 90% 90%, class:^(chrome)$,title:^(.*@gmail.com.*Gmail.*)$ -windowrule = size 90% 90%, class:^(chrome)$,title:^(Messages)$ +# Scratchpad windows - float and size +windowrulev2 = float, class:^(htop-scratch)$ +windowrulev2 = size 90% 90%, class:^(htop-scratch)$ +windowrulev2 = center, class:^(htop-scratch)$ -# ===== KEY BINDINGS ===== -# Based on XMonad configuration +windowrulev2 = float, class:^(pavucontrol)$ +windowrulev2 = size 90% 90%, class:^(pavucontrol)$ +windowrulev2 = center, class:^(pavucontrol)$ -# Main modifier key (Super/Windows key equivalent to mod4Mask) +windowrulev2 = float, class:^(Spotify)$ +windowrulev2 = size 90% 90%, class:^(Spotify)$ +windowrulev2 = center, class:^(Spotify)$ + +windowrulev2 = float, class:^(Element)$ +windowrulev2 = size 90% 90%, class:^(Element)$ +windowrulev2 = center, class:^(Element)$ + +windowrulev2 = float, class:^(Slack)$ +windowrulev2 = size 90% 90%, class:^(Slack)$ +windowrulev2 = center, class:^(Slack)$ + +windowrulev2 = float, class:^(transmission-gtk)$ +windowrulev2 = size 90% 90%, class:^(transmission-gtk)$ +windowrulev2 = center, class:^(transmission-gtk)$ + +# Gmail and Messages (Chrome windows) +windowrulev2 = float, class:^(google-chrome)$,title:^(.*@gmail.com.*Gmail.*)$ +windowrulev2 = size 90% 90%, class:^(google-chrome)$,title:^(.*@gmail.com.*Gmail.*)$ +windowrulev2 = center, class:^(google-chrome)$,title:^(.*@gmail.com.*Gmail.*)$ + +windowrulev2 = float, class:^(google-chrome)$,title:^(Messages.*)$ +windowrulev2 = size 90% 90%, class:^(google-chrome)$,title:^(Messages.*)$ +windowrulev2 = center, class:^(google-chrome)$,title:^(Messages.*)$ + +# ============================================================================= +# KEY BINDINGS +# ============================================================================= + +# Modifier keys $mainMod = SUPER +$modAlt = SUPER ALT +$hyper = SUPER CTRL ALT -# Mod+Alt combination (equivalent to modalt in XMonad) -$modAlt = SUPER_ALT - -# Hyper key (equivalent to mod3Mask in XMonad) -$hyper = ALT_R - -# Program launching +# ----------------------------------------------------------------------------- +# Program Launching +# ----------------------------------------------------------------------------- bind = $mainMod, P, exec, $menu bind = $mainMod SHIFT, P, exec, $runMenu bind = $mainMod SHIFT, Return, exec, $terminal bind = $mainMod, Q, killactive, bind = $mainMod SHIFT, C, killactive, bind = $mainMod SHIFT, Q, exit, -bind = $mainMod, E, exec, emacsclient -c -bind = $mainMod, V, exec, xclip -o | xdotool type --file - +# Emacs-everywhere (like XMonad's emacs-everywhere) +bind = $mainMod, E, exec, emacsclient --eval '(emacs-everywhere)' +bind = $mainMod, V, exec, wl-paste | xdotool type --file - -# Chrome/Browser launching (equivalent to bindBringAndRaise) -bind = $modAlt, C, exec, google-chrome-stable +# Chrome/Browser (raise or spawn like XMonad's bindBringAndRaise) +bind = $modAlt, C, exec, ~/.config/hypr/scripts/raise-or-run.sh google-chrome google-chrome-stable -# Scratchpad equivalents (toggle special workspaces) +# ----------------------------------------------------------------------------- +# SCRATCHPADS (Special Workspaces) +# ----------------------------------------------------------------------------- +# Toggle scratchpads bind = $modAlt, E, togglespecialworkspace, element bind = $modAlt, G, togglespecialworkspace, gmail bind = $modAlt, H, togglespecialworkspace, htop @@ -136,7 +262,7 @@ bind = $modAlt, S, togglespecialworkspace, spotify bind = $modAlt, T, togglespecialworkspace, transmission bind = $modAlt, V, togglespecialworkspace, volume -# Move windows to special workspaces +# Move windows to scratchpads bind = $modAlt SHIFT, E, movetoworkspace, special:element bind = $modAlt SHIFT, G, movetoworkspace, special:gmail bind = $modAlt SHIFT, H, movetoworkspace, special:htop @@ -146,56 +272,109 @@ bind = $modAlt SHIFT, S, movetoworkspace, special:spotify bind = $modAlt SHIFT, T, movetoworkspace, special:transmission bind = $modAlt SHIFT, V, movetoworkspace, special:volume -# Directional navigation (WASD keys as in XMonad) -bind = $mainMod, W, movefocus, u -bind = $mainMod, S, movefocus, d -bind = $mainMod, A, movefocus, l -bind = $mainMod, D, movefocus, r +# Hidden workspace (like XMonad's NSP) +bind = $mainMod, X, movetoworkspace, special:NSP +bind = $mainMod SHIFT, X, togglespecialworkspace, NSP -# Move windows directionally -bind = $mainMod SHIFT, W, movewindow, u -bind = $mainMod SHIFT, S, movewindow, d -bind = $mainMod SHIFT, A, movewindow, l -bind = $mainMod SHIFT, D, movewindow, r +# ----------------------------------------------------------------------------- +# DIRECTIONAL NAVIGATION (WASD - like XMonad Navigation2D) +# Using hy3 dispatchers for proper tree-based navigation +# ----------------------------------------------------------------------------- -# Resize windows -bind = $mainMod CTRL, W, resizeactive, 0 -50 -bind = $mainMod CTRL, S, resizeactive, 0 50 -bind = $mainMod CTRL, A, resizeactive, -50 0 -bind = $mainMod CTRL, D, resizeactive, 50 0 +# Focus movement (Mod + WASD) - hy3:movefocus navigates the tree +bind = $mainMod, W, hy3:movefocus, u +bind = $mainMod, S, hy3:movefocus, d +bind = $mainMod, A, hy3:movefocus, l +bind = $mainMod, D, hy3:movefocus, r -# Layout control -bind = $mainMod, Space, exec, hyprctl dispatch layoutmsg cyclenext -bind = $mainMod CTRL, Space, fullscreen, 0 -bind = $mainMod, slash, exec, hyprctl dispatch layoutmsg orientationcycle left top +# Move windows (Mod + Shift + WASD) - hy3:movewindow with once=true for swapping +bind = $mainMod SHIFT, W, hy3:movewindow, u, once +bind = $mainMod SHIFT, S, hy3:movewindow, d, once +bind = $mainMod SHIFT, A, hy3:movewindow, l, once +bind = $mainMod SHIFT, D, hy3:movewindow, r, once + +# Resize windows (Mod + Ctrl + WASD) +binde = $mainMod CTRL, W, resizeactive, 0 -50 +binde = $mainMod CTRL, S, resizeactive, 0 50 +binde = $mainMod CTRL, A, resizeactive, -50 0 +binde = $mainMod CTRL, D, resizeactive, 50 0 + +# Screen/Monitor focus (Hyper + WASD) +bind = $hyper, W, focusmonitor, u +bind = $hyper, S, focusmonitor, d +bind = $hyper, A, focusmonitor, l +bind = $hyper, D, focusmonitor, r + +# Move window to monitor and follow (Hyper + Shift + WASD) +bind = $hyper SHIFT, W, movewindow, mon:u +bind = $hyper SHIFT, S, movewindow, mon:d +bind = $hyper SHIFT, A, movewindow, mon:l +bind = $hyper SHIFT, D, movewindow, mon:r + +# Shift to empty workspace on screen direction (Hyper + Ctrl + WASD) +# Like XMonad's shiftToEmptyOnScreen +bind = $hyper CTRL, W, exec, ~/.config/hypr/scripts/shift-to-empty-on-screen.sh u +bind = $hyper CTRL, S, exec, ~/.config/hypr/scripts/shift-to-empty-on-screen.sh d +bind = $hyper CTRL, A, exec, ~/.config/hypr/scripts/shift-to-empty-on-screen.sh l +bind = $hyper CTRL, D, exec, ~/.config/hypr/scripts/shift-to-empty-on-screen.sh r + +# ----------------------------------------------------------------------------- +# LAYOUT CONTROL (XMonad-like with hy3) +# ----------------------------------------------------------------------------- + +# Create groups with different orientations (like XMonad layouts) +# hy3:makegroup creates a split/tab group from focused window +bind = $mainMod, Space, hy3:changegroup, toggletab +bind = $mainMod SHIFT, Space, hy3:changegroup, opposite + +# Create specific group types +bind = $mainMod, H, hy3:makegroup, h +bind = $mainMod SHIFT, V, hy3:makegroup, v +bind = $mainMod CTRL, Space, hy3:makegroup, tab + +# Change group type (cycle h -> v -> tab) +bind = $mainMod, slash, hy3:changegroup, h +bind = $mainMod SHIFT, slash, hy3:changegroup, v + +# Tab navigation (like XMonad's focus next/prev in tabbed) +bind = $mainMod, bracketright, hy3:focustab, r, wrap +bind = $mainMod, bracketleft, hy3:focustab, l, wrap + +# Move window within tab group +bind = $mainMod SHIFT, bracketright, hy3:movetab, r +bind = $mainMod SHIFT, bracketleft, hy3:movetab, l + +# Expand focus to parent group (like XMonad's focus parent) +bind = $mainMod, grave, hy3:expand, expand +bind = $mainMod SHIFT, grave, hy3:expand, base + +# Fullscreen (like XMonad's NBFULL toggle) bind = $mainMod, F, fullscreen, 0 bind = $mainMod SHIFT, F, fullscreen, 1 + +# Toggle floating bind = $mainMod, T, togglefloating, -bind = $mainMod SHIFT, Y, pseudo, # dwindle pseudotile -bind = $mainMod, J, togglesplit, # dwindle split direction -bind = $mainMod, comma, exec, hyprctl dispatch splitratio -0.05 -bind = $mainMod, period, exec, hyprctl dispatch splitratio +0.05 -bind = $mainMod, N, exec, hyprctl dispatch layoutmsg addmaster -bind = $mainMod SHIFT, N, exec, hyprctl dispatch layoutmsg removemaster -# Focus manipulation -bind = $mainMod, Tab, exec, hyprctl dispatch focuswindow "class:$(hyprctl activewindow -j | jq -r '.class')" -bind = $mainMod, M, exec, hyprctl dispatch focuswindow "class:master" +# Resize split ratio (hy3 uses resizeactive for splits) +binde = $mainMod, comma, resizeactive, -50 0 +binde = $mainMod, period, resizeactive, 50 0 -# Monitor/Screen control -bind = $mainMod, Z, focusmonitor, +1 -bind = $mainMod SHIFT, Z, movewindow, mon:+1 +# Kill group - removes the focused window from its group +bind = $mainMod, N, hy3:killactive -# Window management -bind = $mainMod, G, exec, hyprctl clients -j | jq -r '.[] | select(.workspace.id >= 0) | "\(.title) - \(.class)"' | rofi -dmenu -i -p "Go to window" | head -1 | xargs -I {} hyprctl dispatch focuswindow "title:{}" -bind = $mainMod, B, exec, SELECTION=$(hyprctl clients -j | jq -r '.[] | select(.workspace.id >= 0) | "\(.title) - \(.class) [\(.address)]"' | rofi -dmenu -i -p "Bring window"); if [ -n "$SELECTION" ]; then ADDRESS=$(echo "$SELECTION" | sed 's/.*\[\(.*\)\]/\1/'); hyprctl dispatch movetoworkspace "$(hyprctl activeworkspace -j | jq -r '.id')",address:"$ADDRESS"; fi -bind = $mainMod SHIFT, B, exec, hyprctl clients -j | jq -r '.[] | select(.workspace.id >= 0) | "\(.title) - \(.class)"' | rofi -dmenu -i -p "Replace window" | head -1 | xargs -I {} hyprctl dispatch swapwindow "title:{}" -bind = $mainMod, M, exec, hyprctl dispatch togglespecialworkspace minimized -bind = $mainMod SHIFT, M, exec, hyprctl dispatch movetoworkspace special:minimized -bind = $mainMod SHIFT, H, exec, EMPTY_WS=$(hyprctl workspaces -j | jq -r 'map(select(.windows == 0)) | .[0].id // empty'); if [ -z "$EMPTY_WS" ]; then EMPTY_WS=$(hyprctl workspaces -j | jq -r 'max_by(.id).id + 1'); fi; hyprctl dispatch movetoworkspace $EMPTY_WS && hyprctl dispatch workspace $EMPTY_WS -bind = $mainMod, X, exec, hyprctl dispatch movetoworkspace special:NSP +# hy3:setswallow - set a window to swallow newly spawned windows +bind = $mainMod, M, hy3:setswallow, toggle -# Workspace switching +# Minimize to special workspace (like XMonad's minimizeWindow) +bind = $mainMod SHIFT, M, movetoworkspace, special:minimized +# Restore last minimized +bind = $modAlt, Return, togglespecialworkspace, minimized + +# ----------------------------------------------------------------------------- +# WORKSPACE CONTROL +# ----------------------------------------------------------------------------- + +# Switch workspaces (1-9, 0=10) bind = $mainMod, 1, workspace, 1 bind = $mainMod, 2, workspace, 2 bind = $mainMod, 3, workspace, 3 @@ -207,7 +386,7 @@ bind = $mainMod, 8, workspace, 8 bind = $mainMod, 9, workspace, 9 bind = $mainMod, 0, workspace, 10 -# Move windows to workspaces +# Move window to workspace bind = $mainMod SHIFT, 1, movetoworkspace, 1 bind = $mainMod SHIFT, 2, movetoworkspace, 2 bind = $mainMod SHIFT, 3, movetoworkspace, 3 @@ -219,27 +398,73 @@ bind = $mainMod SHIFT, 8, movetoworkspace, 8 bind = $mainMod SHIFT, 9, movetoworkspace, 9 bind = $mainMod SHIFT, 0, movetoworkspace, 10 -# Move and follow to workspace -bind = $mainMod CTRL, 1, movetoworkspace, 1 -bind = $mainMod CTRL, 2, movetoworkspace, 2 -bind = $mainMod CTRL, 3, movetoworkspace, 3 -bind = $mainMod CTRL, 4, movetoworkspace, 4 -bind = $mainMod CTRL, 5, movetoworkspace, 5 -bind = $mainMod CTRL, 6, movetoworkspace, 6 -bind = $mainMod CTRL, 7, movetoworkspace, 7 -bind = $mainMod CTRL, 8, movetoworkspace, 8 -bind = $mainMod CTRL, 9, movetoworkspace, 9 -bind = $mainMod CTRL, 0, movetoworkspace, 10 +# Move and follow to workspace (like XMonad's shiftThenView) +bind = $mainMod CTRL, 1, movetoworkspacesilent, 1 +bind = $mainMod CTRL, 1, workspace, 1 +bind = $mainMod CTRL, 2, movetoworkspacesilent, 2 +bind = $mainMod CTRL, 2, workspace, 2 +bind = $mainMod CTRL, 3, movetoworkspacesilent, 3 +bind = $mainMod CTRL, 3, workspace, 3 +bind = $mainMod CTRL, 4, movetoworkspacesilent, 4 +bind = $mainMod CTRL, 4, workspace, 4 +bind = $mainMod CTRL, 5, movetoworkspacesilent, 5 +bind = $mainMod CTRL, 5, workspace, 5 +bind = $mainMod CTRL, 6, movetoworkspacesilent, 6 +bind = $mainMod CTRL, 6, workspace, 6 +bind = $mainMod CTRL, 7, movetoworkspacesilent, 7 +bind = $mainMod CTRL, 7, workspace, 7 +bind = $mainMod CTRL, 8, movetoworkspacesilent, 8 +bind = $mainMod CTRL, 8, workspace, 8 +bind = $mainMod CTRL, 9, movetoworkspacesilent, 9 +bind = $mainMod CTRL, 9, workspace, 9 +bind = $mainMod CTRL, 0, movetoworkspacesilent, 10 +bind = $mainMod CTRL, 0, workspace, 10 -# Media keys and volume control -bind = , XF86AudioRaiseVolume, exec, set_volume --unmute --change-volume +5 -bind = , XF86AudioLowerVolume, exec, set_volume --unmute --change-volume -5 +# Workspace cycling (like XMonad's cycleWorkspaceOnCurrentScreen) +bind = $mainMod, backslash, workspace, previous + +# Go to next empty workspace (like XMonad's moveTo Next emptyWS) +bind = $hyper, E, workspace, empty + +# Move to next screen (like XMonad's shiftToNextScreenX) +bind = $mainMod, Z, focusmonitor, +1 +bind = $mainMod SHIFT, Z, movewindow, mon:+1 + +# Shift to empty workspace and view (like XMonad's shiftToEmptyAndView) +bind = $mainMod SHIFT, H, movetoworkspace, empty + +# ----------------------------------------------------------------------------- +# WINDOW MANAGEMENT +# ----------------------------------------------------------------------------- + +# Go to window (rofi window switcher) +bind = $mainMod, G, exec, rofi -show window -show-icons + +# Bring window (move to current workspace) +bind = $mainMod, B, exec, ~/.config/hypr/scripts/bring-window.sh + +# Replace window (swap focused with selected - like XMonad's myReplaceWindow) +bind = $mainMod SHIFT, B, exec, ~/.config/hypr/scripts/replace-window.sh + +# Gather windows of same class (like XMonad's gatherThisClass) +bind = $hyper, G, exec, ~/.config/hypr/scripts/gather-class.sh + +# Focus next window of different class (like XMonad's focusNextClass) +bind = $mainMod, Tab, exec, ~/.config/hypr/scripts/focus-next-class.sh + +# ----------------------------------------------------------------------------- +# MEDIA KEYS +# ----------------------------------------------------------------------------- + +# Volume control (matching XMonad: Mod+I=up, Mod+K=down, Mod+U=mute) +binde = , XF86AudioRaiseVolume, exec, set_volume --unmute --change-volume +5 +binde = , XF86AudioLowerVolume, exec, set_volume --unmute --change-volume -5 bind = , XF86AudioMute, exec, set_volume --toggle-mute -bind = $mainMod, I, exec, set_volume --unmute --change-volume +5 -bind = $mainMod, K, exec, set_volume --unmute --change-volume -5 +binde = $mainMod, I, exec, set_volume --unmute --change-volume +5 +binde = $mainMod, K, exec, set_volume --unmute --change-volume -5 bind = $mainMod, U, exec, set_volume --toggle-mute -# Media player controls +# Media player controls (matching XMonad: Mod+;=play, Mod+L=next, Mod+J=prev) bind = $mainMod, semicolon, exec, playerctl play-pause bind = , XF86AudioPlay, exec, playerctl play-pause bind = , XF86AudioPause, exec, playerctl play-pause @@ -248,47 +473,67 @@ bind = , XF86AudioNext, exec, playerctl next bind = $mainMod, J, exec, playerctl previous bind = , XF86AudioPrev, exec, playerctl previous -# Brightness control -bind = , XF86MonBrightnessUp, exec, brightness.sh 5 -bind = , XF86MonBrightnessDown, exec, brightness.sh -5 +# Mute current window (like XMonad's toggle_mute_current_window) +bind = $hyper SHIFT, Q, exec, toggle_mute_current_window.sh +bind = $hyper CTRL, Q, exec, toggle_mute_current_window.sh only -# Utility bindings -bind = $hyper, V, exec, rofi_clipit.sh -bind = $hyper, Y, exec, rofi-pass -bind = $hyper, H, exec, rofi_shutter +# Brightness control +binde = , XF86MonBrightnessUp, exec, brightness.sh up +binde = , XF86MonBrightnessDown, exec, brightness.sh down + +# ----------------------------------------------------------------------------- +# UTILITY BINDINGS +# ----------------------------------------------------------------------------- + +bind = $hyper, V, exec, cliphist list | rofi -dmenu -p "Clipboard" | cliphist decode | wl-copy +bind = $hyper, P, exec, rofi-pass +bind = $hyper, H, exec, grim -g "$(slurp)" - | swappy -f - bind = $hyper, C, exec, shell_command.sh bind = $hyper, X, exec, rofi_command.sh -bind = $hyper SHIFT, L, exec, dm-tool lock +bind = $hyper SHIFT, L, exec, hyprlock bind = $hyper, K, exec, rofi_kill_process.sh bind = $hyper SHIFT, K, exec, rofi_kill_all.sh bind = $hyper, R, exec, rofi-systemd bind = $hyper, 9, exec, start_synergy.sh -bind = $hyper, slash, exec, toggle_taffybar -bind = $hyper, Space, exec, skippy-xd +# Overview - show all windows (Hyper+Space) +# hyprexpo disabled - using rofi window switcher as fallback +bind = $hyper, Space, exec, rofi -show window -show-icons bind = $hyper, I, exec, rofi_select_input.hs bind = $hyper, O, exec, rofi_paswitch bind = $mainMod, apostrophe, exec, load_default_map bind = $modAlt, apostrophe, exec, load_xkb_map + +# Reload config bind = $mainMod, R, exec, hyprctl reload -# Workspace cycling -bind = $mainMod, backslash, workspace, previous -bind = $mainMod, Tab, workspace, previous +# ----------------------------------------------------------------------------- +# MOUSE BINDINGS +# ----------------------------------------------------------------------------- -# Mouse bindings bindm = $mainMod, mouse:272, movewindow bindm = $mainMod, mouse:273, resizewindow -# Scroll through existing workspaces with mainMod + scroll +# Scroll through workspaces bind = $mainMod, mouse_down, workspace, e+1 bind = $mainMod, mouse_up, workspace, e-1 -# Special workspaces for "scratchpad" applications +# ============================================================================= +# AUTOSTART +# ============================================================================= + +# Scratchpad applications (start in special workspaces) exec-once = [workspace special:element silent] element-desktop exec-once = [workspace special:gmail silent] google-chrome-stable --new-window https://mail.google.com/mail/u/0/#inbox -exec-once = [workspace special:htop silent] alacritty --title htop -e htop +exec-once = [workspace special:htop silent] alacritty --class htop-scratch --title htop -e htop exec-once = [workspace special:messages silent] google-chrome-stable --new-window https://messages.google.com/web/conversations exec-once = [workspace special:slack silent] slack exec-once = [workspace special:spotify silent] spotify exec-once = [workspace special:transmission silent] transmission-gtk exec-once = [workspace special:volume silent] pavucontrol + +# Clipboard history daemon +exec-once = wl-paste --type text --watch cliphist store +exec-once = wl-paste --type image --watch cliphist store + +# Night light (optional - comment out if not needed) +# exec-once = wlsunset -l 37.7 -L -122.4 diff --git a/dotfiles/config/hypr/scripts/bring-window.sh b/dotfiles/config/hypr/scripts/bring-window.sh new file mode 100755 index 00000000..94a3131a --- /dev/null +++ b/dotfiles/config/hypr/scripts/bring-window.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# Bring window to current workspace (like XMonad's bringWindow) +# Uses rofi to select a window and moves it to the current workspace + +set -euo pipefail + +# Get current workspace +CURRENT_WS=$(hyprctl activeworkspace -j | jq -r '.id') + +# Get all windows and format for rofi +WINDOWS=$(hyprctl clients -j | jq -r '.[] | select(.workspace.id >= 0 and .workspace.id != '"$CURRENT_WS"') | "\(.title) [\(.class)] - WS:\(.workspace.id) |\(.address)"') + +if [ -z "$WINDOWS" ]; then + notify-send "Bring Window" "No windows on other workspaces" + exit 0 +fi + +# Show rofi menu +SELECTION=$(echo "$WINDOWS" | rofi -dmenu -i -p "Bring window" -format 's') + +if [ -n "$SELECTION" ]; then + # Extract the window address (after the last |) + ADDRESS=$(echo "$SELECTION" | sed 's/.*|//') + + # Move window to current workspace + hyprctl dispatch movetoworkspace "$CURRENT_WS,address:$ADDRESS" + + # Focus the window + hyprctl dispatch focuswindow "address:$ADDRESS" +fi diff --git a/dotfiles/config/hypr/scripts/cycle-layout.sh b/dotfiles/config/hypr/scripts/cycle-layout.sh new file mode 100755 index 00000000..b223fffe --- /dev/null +++ b/dotfiles/config/hypr/scripts/cycle-layout.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +# Cycle between master and dwindle layouts +# Like XMonad's NextLayout + +set -euo pipefail + +CURRENT=$(hyprctl getoption general:layout -j | jq -r '.str') + +if [ "$CURRENT" = "master" ]; then + hyprctl keyword general:layout dwindle + notify-send "Layout" "Switched to Dwindle (binary tree)" +else + hyprctl keyword general:layout master + notify-send "Layout" "Switched to Master (XMonad-like)" +fi diff --git a/dotfiles/config/hypr/scripts/focus-next-class.sh b/dotfiles/config/hypr/scripts/focus-next-class.sh new file mode 100755 index 00000000..8d4a9534 --- /dev/null +++ b/dotfiles/config/hypr/scripts/focus-next-class.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +# Focus next window of a different class (like XMonad's focusNextClass) + +set -euo pipefail + +# Get focused window class +FOCUSED_CLASS=$(hyprctl activewindow -j | jq -r '.class') +FOCUSED_ADDR=$(hyprctl activewindow -j | jq -r '.address') + +if [ "$FOCUSED_CLASS" = "null" ] || [ -z "$FOCUSED_CLASS" ]; then + # No focused window, just focus any window + hyprctl dispatch cyclenext + exit 0 +fi + +# Get all unique classes +ALL_CLASSES=$(hyprctl clients -j | jq -r '[.[] | select(.workspace.id >= 0) | .class] | unique | .[]') + +# Get sorted list of classes +CLASSES_ARRAY=() +while IFS= read -r class; do + CLASSES_ARRAY+=("$class") +done <<< "$ALL_CLASSES" + +# Find current class index and get next class +CURRENT_INDEX=-1 +for i in "${!CLASSES_ARRAY[@]}"; do + if [ "${CLASSES_ARRAY[$i]}" = "$FOCUSED_CLASS" ]; then + CURRENT_INDEX=$i + break + fi +done + +if [ $CURRENT_INDEX -eq -1 ] || [ ${#CLASSES_ARRAY[@]} -le 1 ]; then + # Only one class or class not found + exit 0 +fi + +# Get next class (wrapping around) +NEXT_INDEX=$(( (CURRENT_INDEX + 1) % ${#CLASSES_ARRAY[@]} )) +NEXT_CLASS="${CLASSES_ARRAY[$NEXT_INDEX]}" + +# Find first window of next class +NEXT_WINDOW=$(hyprctl clients -j | jq -r ".[] | select(.class == \"$NEXT_CLASS\" and .workspace.id >= 0) | .address" | head -1) + +if [ -n "$NEXT_WINDOW" ]; then + hyprctl dispatch focuswindow "address:$NEXT_WINDOW" +fi diff --git a/dotfiles/config/hypr/scripts/gather-class.sh b/dotfiles/config/hypr/scripts/gather-class.sh new file mode 100755 index 00000000..92dca803 --- /dev/null +++ b/dotfiles/config/hypr/scripts/gather-class.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# Gather all windows of the same class as focused window (like XMonad's gatherThisClass) + +set -euo pipefail + +# Get focused window class +FOCUSED_CLASS=$(hyprctl activewindow -j | jq -r '.class') +CURRENT_WS=$(hyprctl activeworkspace -j | jq -r '.id') + +if [ "$FOCUSED_CLASS" = "null" ] || [ -z "$FOCUSED_CLASS" ]; then + notify-send "Gather Class" "No focused window" + exit 0 +fi + +# Find all windows with same class on other workspaces +WINDOWS=$(hyprctl clients -j | jq -r ".[] | select(.class == \"$FOCUSED_CLASS\" and .workspace.id != $CURRENT_WS and .workspace.id >= 0) | .address") + +if [ -z "$WINDOWS" ]; then + notify-send "Gather Class" "No other windows of class '$FOCUSED_CLASS'" + exit 0 +fi + +# Move each window to current workspace +COUNT=0 +for ADDR in $WINDOWS; do + hyprctl dispatch movetoworkspace "$CURRENT_WS,address:$ADDR" + ((COUNT++)) +done + +notify-send "Gather Class" "Gathered $COUNT windows of class '$FOCUSED_CLASS'" diff --git a/dotfiles/config/hypr/scripts/raise-or-run.sh b/dotfiles/config/hypr/scripts/raise-or-run.sh new file mode 100755 index 00000000..8e20c7c3 --- /dev/null +++ b/dotfiles/config/hypr/scripts/raise-or-run.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +# Raise existing window or run command (like XMonad's raiseNextMaybe) +# Usage: raise-or-run.sh + +set -euo pipefail + +CLASS_PATTERN="$1" +COMMAND="$2" + +# Find windows matching the class pattern +MATCHING=$(hyprctl clients -j | jq -r ".[] | select(.class | test(\"$CLASS_PATTERN\"; \"i\")) | .address" | head -1) + +if [ -n "$MATCHING" ]; then + # Window exists, focus it + hyprctl dispatch focuswindow "address:$MATCHING" +else + # No matching window, run the command + exec $COMMAND +fi diff --git a/dotfiles/config/hypr/scripts/replace-window.sh b/dotfiles/config/hypr/scripts/replace-window.sh new file mode 100755 index 00000000..5f16c916 --- /dev/null +++ b/dotfiles/config/hypr/scripts/replace-window.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# Replace focused window with selected window (like XMonad's myReplaceWindow) +# Swaps the positions of focused window and selected window + +set -euo pipefail + +# Get current workspace and focused window +CURRENT_WS=$(hyprctl activeworkspace -j | jq -r '.id') +FOCUSED=$(hyprctl activewindow -j | jq -r '.address') + +if [ "$FOCUSED" = "null" ] || [ -z "$FOCUSED" ]; then + notify-send "Replace Window" "No focused window" + exit 0 +fi + +# Get all windows except focused +WINDOWS=$(hyprctl clients -j | jq -r ".[] | select(.workspace.id >= 0 and .address != \"$FOCUSED\") | \"\(.title) [\(.class)] - WS:\(.workspace.id) |\(.address)\"") + +if [ -z "$WINDOWS" ]; then + notify-send "Replace Window" "No other windows available" + exit 0 +fi + +# Show rofi menu +SELECTION=$(echo "$WINDOWS" | rofi -dmenu -i -p "Replace with" -format 's') + +if [ -n "$SELECTION" ]; then + # Extract the window address + ADDRESS=$(echo "$SELECTION" | sed 's/.*|//') + + # Swap windows using hy3 + hyprctl dispatch hy3:movewindow "address:$ADDRESS" +fi diff --git a/dotfiles/config/hypr/scripts/shift-to-empty-on-screen.sh b/dotfiles/config/hypr/scripts/shift-to-empty-on-screen.sh new file mode 100755 index 00000000..fcc76dca --- /dev/null +++ b/dotfiles/config/hypr/scripts/shift-to-empty-on-screen.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# Shift window to empty workspace on screen in given direction +# Like XMonad's shiftToEmptyOnScreen +# Usage: shift-to-empty-on-screen.sh + +set -euo pipefail + +DIRECTION="$1" + +# First, move focus to the screen in that direction +hyprctl dispatch focusmonitor "$DIRECTION" + +# Get the monitor we're now on +MONITOR=$(hyprctl activeworkspace -j | jq -r '.monitor') + +# Find an empty workspace or create one +# First check if there's an empty workspace on this monitor +EMPTY_WS=$(hyprctl workspaces -j | jq -r ".[] | select(.windows == 0 and .monitor == \"$MONITOR\") | .id" | head -1) + +if [ -z "$EMPTY_WS" ]; then + # No empty workspace, find next available workspace number + MAX_WS=$(hyprctl workspaces -j | jq -r 'map(.id) | max') + EMPTY_WS=$((MAX_WS + 1)) +fi + +# Go back to original monitor and move the window +hyprctl dispatch focusmonitor "$DIRECTION" # This actually toggles back + +# Move window to the empty workspace and follow +hyprctl dispatch movetoworkspace "$EMPTY_WS" diff --git a/nixos/desktop.nix b/nixos/desktop.nix index ad35a76c..7e586c66 100644 --- a/nixos/desktop.nix +++ b/nixos/desktop.nix @@ -2,6 +2,7 @@ makeEnable config "myModules.desktop" true { imports = [ ./fonts.nix + ./hyprland.nix ]; services.xserver = { @@ -21,8 +22,6 @@ makeEnable config "myModules.desktop" true { }; }; - programs.hyprland.enable = true; - services.autorandr = { enable = true; }; diff --git a/nixos/extra.nix b/nixos/extra.nix index 559e3142..ae2ff1de 100644 --- a/nixos/extra.nix +++ b/nixos/extra.nix @@ -1,7 +1,5 @@ { config, pkgs, makeEnable, ... }: makeEnable config "myModules.extra" false { - programs.hyprland.enable = true; - environment.systemPackages = with pkgs; [ android-studio gradle diff --git a/nixos/flake.lock b/nixos/flake.lock index e37fd2cf..66621a76 100644 --- a/nixos/flake.lock +++ b/nixos/flake.lock @@ -29,7 +29,7 @@ "railbird-secrets", "nixpkgs" ], - "systems": "systems_8" + "systems": "systems_7" }, "locked": { "lastModified": 1707830867, @@ -45,6 +45,39 @@ "type": "github" } }, + "aquamarine": { + "inputs": { + "hyprutils": [ + "hyprland", + "hyprutils" + ], + "hyprwayland-scanner": [ + "hyprland", + "hyprwayland-scanner" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1765900596, + "narHash": "sha256-+hn8v9jkkLP9m+o0Nm5SiEq10W0iWDSotH2XfjU45fA=", + "owner": "hyprwm", + "repo": "aquamarine", + "rev": "d83c97f8f5c0aae553c1489c7d9eff3eadcadace", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "aquamarine", + "type": "github" + } + }, "darwin": { "inputs": { "nixpkgs": [ @@ -90,29 +123,23 @@ "type": "github" } }, - "emacs-overlay": { - "inputs": { - "nixpkgs": [ - "org-agenda-api", - "nixpkgs" - ], - "nixpkgs-stable": "nixpkgs-stable" - }, + "flake-compat": { + "flake": false, "locked": { - "lastModified": 1768379502, - "narHash": "sha256-P1iX+CKgqR1vAeolUl7i6UlLX8SWFcF4mRK7Epe5v6U=", - "owner": "nix-community", - "repo": "emacs-overlay", - "rev": "c0b6ffb9edfb7ca5ccc36c3723690768ed8b8471", + "lastModified": 1761588595, + "narHash": "sha256-XKUZz9zewJNUj46b4AJdiRZJAvSZ0Dqj2BNfXvFlJC4=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "f387cd2afec9419c8ee37694406ca490c3f34ee5", "type": "github" }, "original": { - "owner": "nix-community", - "repo": "emacs-overlay", + "owner": "edolstra", + "repo": "flake-compat", "type": "github" } }, - "flake-compat": { + "flake-compat_2": { "flake": false, "locked": { "lastModified": 1696426674, @@ -128,7 +155,7 @@ "type": "github" } }, - "flake-compat_2": { + "flake-compat_3": { "flake": false, "locked": { "lastModified": 1767039857, @@ -144,14 +171,14 @@ "type": "github" } }, - "flake-compat_3": { + "flake-compat_4": { "flake": false, "locked": { - "lastModified": 1765121682, - "narHash": "sha256-4VBOP18BFeiPkyhy9o4ssBNQEvfvv1kXkasAYd0+rrA=", + "lastModified": 1767039857, + "narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=", "owner": "edolstra", "repo": "flake-compat", - "rev": "65f23138d8d09a92e30f1e5c87611b23ef451bf3", + "rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab", "type": "github" }, "original": { @@ -160,7 +187,7 @@ "type": "github" } }, - "flake-compat_4": { + "flake-compat_5": { "flake": false, "locked": { "lastModified": 1673956053, @@ -176,7 +203,7 @@ "type": "github" } }, - "flake-compat_5": { + "flake-compat_6": { "flake": false, "locked": { "lastModified": 1673956053, @@ -314,61 +341,7 @@ "type": "github" } }, - "flake-utils_10": { - "inputs": { - "systems": "systems_12" - }, - "locked": { - "lastModified": 1685518550, - "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "flake-utils_11": { - "inputs": { - "systems": "systems_13" - }, - "locked": { - "lastModified": 1681202837, - "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "cfacdce06f30d2b68473a46042957675eebb3401", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, "flake-utils_2": { - "inputs": { - "systems": "systems_2" - }, - "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "flake-utils_3": { "inputs": { "systems": "systems_3" }, @@ -386,7 +359,7 @@ "type": "github" } }, - "flake-utils_4": { + "flake-utils_3": { "inputs": { "systems": "systems_4" }, @@ -404,10 +377,28 @@ "type": "github" } }, - "flake-utils_5": { + "flake-utils_4": { "inputs": { "systems": "systems_5" }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_5": { + "inputs": { + "systems": "systems_6" + }, "locked": { "lastModified": 1685518550, "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", @@ -424,43 +415,7 @@ }, "flake-utils_6": { "inputs": { - "systems": "systems_6" - }, - "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "flake-utils_7": { - "inputs": { - "systems": "systems_7" - }, - "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "flake-utils_8": { - "inputs": { - "systems": "systems_9" + "systems": "systems_8" }, "locked": { "lastModified": 1709126324, @@ -476,9 +431,9 @@ "type": "github" } }, - "flake-utils_9": { + "flake-utils_7": { "inputs": { - "systems": "systems_11" + "systems": "systems_10" }, "locked": { "lastModified": 1710146030, @@ -494,6 +449,42 @@ "type": "github" } }, + "flake-utils_8": { + "inputs": { + "systems": "systems_11" + }, + "locked": { + "lastModified": 1685518550, + "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_9": { + "inputs": { + "systems": "systems_12" + }, + "locked": { + "lastModified": 1681202837, + "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "cfacdce06f30d2b68473a46042957675eebb3401", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, "fourmolu-011": { "flake": false, "locked": { @@ -595,7 +586,7 @@ }, "git-ignore-nix_2": { "inputs": { - "nixpkgs": "nixpkgs_4" + "nixpkgs": "nixpkgs_5" }, "locked": { "lastModified": 1762808025, @@ -634,30 +625,29 @@ "type": "github" } }, - "git-sync-rs": { + "gitignore": { "inputs": { - "flake-utils": "flake-utils_7", "nixpkgs": [ - "org-agenda-api", + "hyprland", + "pre-commit-hooks", "nixpkgs" - ], - "rust-overlay": "rust-overlay" + ] }, "locked": { - "lastModified": 1757482858, - "narHash": "sha256-iImcGGDTa28YzTq5eFDuszCWaRfU0kaIvq3oNHb23Z0=", - "owner": "colonelpanic8", - "repo": "git-sync-rs", - "rev": "46bad19b218ccfc07a3982cfb25b694a980fc3d5", + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", "type": "github" }, "original": { - "owner": "colonelpanic8", - "repo": "git-sync-rs", + "owner": "hercules-ci", + "repo": "gitignore.nix", "type": "github" } }, - "gitignore": { + "gitignore_2": { "inputs": { "nixpkgs": [ "imalison-taffybar", @@ -681,7 +671,7 @@ "type": "github" } }, - "gitignore_2": { + "gitignore_3": { "flake": false, "locked": { "lastModified": 1660459072, @@ -697,7 +687,7 @@ "type": "github" } }, - "gitignore_3": { + "gitignore_4": { "flake": false, "locked": { "lastModified": 1660459072, @@ -964,11 +954,11 @@ }, "haskell-language-server": { "inputs": { - "flake-compat": "flake-compat_4", + "flake-compat": "flake-compat_5", "flake-utils": "flake-utils_5", "fourmolu-011": "fourmolu-011", "fourmolu-012": "fourmolu-012", - "gitignore": "gitignore_2", + "gitignore": "gitignore_3", "haskell-hie-bios": "haskell-hie-bios", "haskell-implicit-hie-cradle": "haskell-implicit-hie-cradle", "hiedb": "hiedb", @@ -977,7 +967,7 @@ "lsp": "lsp", "lsp-test": "lsp-test", "lsp-types": "lsp-types", - "nixpkgs": "nixpkgs_12", + "nixpkgs": "nixpkgs_13", "ormolu-052": "ormolu-052", "ormolu-07": "ormolu-07", "stylish-haskell-0145": "stylish-haskell-0145" @@ -999,11 +989,11 @@ }, "haskell-language-server_2": { "inputs": { - "flake-compat": "flake-compat_5", - "flake-utils": "flake-utils_10", + "flake-compat": "flake-compat_6", + "flake-utils": "flake-utils_8", "fourmolu-011": "fourmolu-011_2", "fourmolu-012": "fourmolu-012_2", - "gitignore": "gitignore_3", + "gitignore": "gitignore_4", "haskell-hie-bios": "haskell-hie-bios_2", "haskell-implicit-hie-cradle": "haskell-implicit-hie-cradle_2", "hiedb": "hiedb_2", @@ -1057,7 +1047,7 @@ "hercules-ci-effects_2": { "inputs": { "flake-parts": "flake-parts_5", - "nixpkgs": "nixpkgs_10" + "nixpkgs": "nixpkgs_11" }, "locked": { "lastModified": 1701009247, @@ -1183,11 +1173,11 @@ ] }, "locked": { - "lastModified": 1768598210, - "narHash": "sha256-kkgA32s/f4jaa4UG+2f8C225Qvclxnqs76mf8zvTVPg=", + "lastModified": 1768912518, + "narHash": "sha256-FJlof1jnbLIT5RbKxef/NV6RzcOj1GoMzXE4FcBFg5Y=", "owner": "nix-community", "repo": "home-manager", - "rev": "c47b2cc64a629f8e075de52e4742de688f930dc6", + "rev": "9c5f8aceb6ef620e881f50fe65cb4a2c6b1e8527", "type": "github" }, "original": { @@ -1219,10 +1209,353 @@ "type": "github" } }, + "hy3": { + "inputs": { + "hyprland": [ + "hyprland" + ] + }, + "locked": { + "lastModified": 1767957561, + "narHash": "sha256-N0kFdc6tSE0yFeQ/Iit3KNrz4nf2K5xvP3juL7SUyhc=", + "owner": "outfoxxed", + "repo": "hy3", + "rev": "3287049e79e9e51431de8c09f9192a18afa1bf35", + "type": "github" + }, + "original": { + "owner": "outfoxxed", + "ref": "hl0.53.0", + "repo": "hy3", + "type": "github" + } + }, + "hyprcursor": { + "inputs": { + "hyprlang": [ + "hyprland", + "hyprlang" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1753964049, + "narHash": "sha256-lIqabfBY7z/OANxHoPeIrDJrFyYy9jAM4GQLzZ2feCM=", + "owner": "hyprwm", + "repo": "hyprcursor", + "rev": "44e91d467bdad8dcf8bbd2ac7cf49972540980a5", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprcursor", + "type": "github" + } + }, + "hyprgraphics": { + "inputs": { + "hyprutils": [ + "hyprland", + "hyprutils" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1763733840, + "narHash": "sha256-JnET78yl5RvpGuDQy3rCycOCkiKoLr5DN1fPhRNNMco=", + "owner": "hyprwm", + "repo": "hyprgraphics", + "rev": "8f1bec691b2d198c60cccabca7a94add2df4ed1a", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprgraphics", + "type": "github" + } + }, + "hyprland": { + "inputs": { + "aquamarine": "aquamarine", + "hyprcursor": "hyprcursor", + "hyprgraphics": "hyprgraphics", + "hyprland-guiutils": "hyprland-guiutils", + "hyprland-protocols": "hyprland-protocols", + "hyprlang": "hyprlang", + "hyprutils": "hyprutils", + "hyprwayland-scanner": "hyprwayland-scanner", + "hyprwire": "hyprwire", + "nixpkgs": "nixpkgs_2", + "pre-commit-hooks": "pre-commit-hooks", + "systems": "systems_2", + "xdph": "xdph" + }, + "locked": { + "lastModified": 1767021696, + "narHash": "sha256-1jZK7hqNhQRqhj+2eb/JvnBoARxUgoVXKLSwp2RPmNQ=", + "ref": "refs/tags/v0.53.0", + "rev": "ea444c35bb23b6e34505ab6753e069de7801cc25", + "revCount": 6756, + "submodules": true, + "type": "git", + "url": "https://github.com/hyprwm/Hyprland" + }, + "original": { + "ref": "refs/tags/v0.53.0", + "submodules": true, + "type": "git", + "url": "https://github.com/hyprwm/Hyprland" + } + }, + "hyprland-guiutils": { + "inputs": { + "aquamarine": [ + "hyprland", + "aquamarine" + ], + "hyprgraphics": [ + "hyprland", + "hyprgraphics" + ], + "hyprlang": [ + "hyprland", + "hyprlang" + ], + "hyprtoolkit": "hyprtoolkit", + "hyprutils": [ + "hyprland", + "hyprutils" + ], + "hyprwayland-scanner": [ + "hyprland", + "hyprwayland-scanner" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1765643131, + "narHash": "sha256-CCGohW5EBIRy4B7vTyBMqPgsNcaNenVad/wszfddET0=", + "owner": "hyprwm", + "repo": "hyprland-guiutils", + "rev": "e50ae912813bdfa8372d62daf454f48d6df02297", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprland-guiutils", + "type": "github" + } + }, + "hyprland-protocols": { + "inputs": { + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1765214753, + "narHash": "sha256-P9zdGXOzToJJgu5sVjv7oeOGPIIwrd9hAUAP3PsmBBs=", + "owner": "hyprwm", + "repo": "hyprland-protocols", + "rev": "3f3860b869014c00e8b9e0528c7b4ddc335c21ab", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprland-protocols", + "type": "github" + } + }, + "hyprlang": { + "inputs": { + "hyprutils": [ + "hyprland", + "hyprutils" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1764612430, + "narHash": "sha256-54ltTSbI6W+qYGMchAgCR6QnC1kOdKXN6X6pJhOWxFg=", + "owner": "hyprwm", + "repo": "hyprlang", + "rev": "0d00dc118981531aa731150b6ea551ef037acddd", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprlang", + "type": "github" + } + }, + "hyprtoolkit": { + "inputs": { + "aquamarine": [ + "hyprland", + "hyprland-guiutils", + "aquamarine" + ], + "hyprgraphics": [ + "hyprland", + "hyprland-guiutils", + "hyprgraphics" + ], + "hyprlang": [ + "hyprland", + "hyprland-guiutils", + "hyprlang" + ], + "hyprutils": [ + "hyprland", + "hyprland-guiutils", + "hyprutils" + ], + "hyprwayland-scanner": [ + "hyprland", + "hyprland-guiutils", + "hyprwayland-scanner" + ], + "nixpkgs": [ + "hyprland", + "hyprland-guiutils", + "nixpkgs" + ], + "systems": [ + "hyprland", + "hyprland-guiutils", + "systems" + ] + }, + "locked": { + "lastModified": 1764592794, + "narHash": "sha256-7CcO+wbTJ1L1NBQHierHzheQGPWwkIQug/w+fhTAVuU=", + "owner": "hyprwm", + "repo": "hyprtoolkit", + "rev": "5cfe0743f0e608e1462972303778d8a0859ee63e", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprtoolkit", + "type": "github" + } + }, + "hyprutils": { + "inputs": { + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1766160771, + "narHash": "sha256-roINUGikWRqqgKrD4iotKbGj3ZKJl3hjMz5l/SyKrHw=", + "owner": "hyprwm", + "repo": "hyprutils", + "rev": "5ac060bfcf2f12b3a6381156ebbc13826a05b09f", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprutils", + "type": "github" + } + }, + "hyprwayland-scanner": { + "inputs": { + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1763640274, + "narHash": "sha256-Uan1Nl9i4TF/kyFoHnTq1bd/rsWh4GAK/9/jDqLbY5A=", + "owner": "hyprwm", + "repo": "hyprwayland-scanner", + "rev": "f6cf414ca0e16a4d30198fd670ec86df3c89f671", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprwayland-scanner", + "type": "github" + } + }, + "hyprwire": { + "inputs": { + "hyprutils": [ + "hyprland", + "hyprutils" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1766253200, + "narHash": "sha256-26qPwrd3od+xoYVywSB7hC2cz9ivN46VPLlrsXyGxvE=", + "owner": "hyprwm", + "repo": "hyprwire", + "rev": "1079777525b30a947c8d657fac158e00ae85de9d", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprwire", + "type": "github" + } + }, "imalison-taffybar": { "inputs": { "flake-utils": "flake-utils_2", - "nixpkgs": "nixpkgs_2", + "nixpkgs": "nixpkgs_3", "taffybar": "taffybar", "xmonad": "xmonad" }, @@ -1310,19 +1643,19 @@ }, "nix": { "inputs": { - "flake-compat": "flake-compat_2", + "flake-compat": "flake-compat_3", "flake-parts": "flake-parts", "git-hooks-nix": "git-hooks-nix", - "nixpkgs": "nixpkgs_6", + "nixpkgs": "nixpkgs_7", "nixpkgs-23-11": "nixpkgs-23-11", "nixpkgs-regression": "nixpkgs-regression" }, "locked": { - "lastModified": 1768607897, - "narHash": "sha256-bJV5vMMpXp1HZp9Y9MH5F4i7L9V/lh1tqGNYFA+gytk=", + "lastModified": 1768884656, + "narHash": "sha256-yfPH0kRErMLFgpfedlr28Hak8m0zgbDq8RnMJsDdtEU=", "owner": "NixOS", "repo": "nix", - "rev": "af7c7b672355c697617d1b83aafc11f5c4555d6e", + "rev": "67a99db5be960031040fa8dd0c412c7408137a75", "type": "github" }, "original": { @@ -1334,7 +1667,7 @@ "inputs": { "flake-parts": "flake-parts_2", "hercules-ci-effects": "hercules-ci-effects", - "nixpkgs": "nixpkgs_7" + "nixpkgs": "nixpkgs_8" }, "locked": { "lastModified": 1768647869, @@ -1368,15 +1701,15 @@ }, "nixos-wsl": { "inputs": { - "flake-compat": "flake-compat_3", - "nixpkgs": "nixpkgs_8" + "flake-compat": "flake-compat_4", + "nixpkgs": "nixpkgs_9" }, "locked": { - "lastModified": 1768404695, - "narHash": "sha256-eT3dNE2CQYcPDHaeRZAEFrZ0BmMq2wLxMp7hCmzOZBA=", + "lastModified": 1768840529, + "narHash": "sha256-e22ou8nikeThx9x9/y29VdMEW4Fm7DBzlhp9ndDJUGE=", "owner": "nix-community", "repo": "NixOS-WSL", - "rev": "d0d3636b9d174c4558e3bbb18e194d970505fed8", + "rev": "b8e9a758fa2e08d8ac5c3be5d4b1fcc92fd3ce84", "type": "github" }, "original": { @@ -1451,23 +1784,23 @@ "type": "github" } }, - "nixpkgs-stable": { + "nixpkgs_10": { "locked": { - "lastModified": 1767313136, - "narHash": "sha256-16KkgfdYqjaeRGBaYsNrhPRRENs0qzkQVUooNHtoy2w=", + "lastModified": 1768564909, + "narHash": "sha256-Kell/SpJYVkHWMvnhqJz/8DqQg2b6PguxVWOuadbHCc=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "ac62194c3917d5f474c1a844b6fd6da2db95077d", + "rev": "e4bae1bd10c9c57b2cf517953ab70060a828ee6f", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixos-25.05", + "ref": "nixos-unstable", "repo": "nixpkgs", "type": "github" } }, - "nixpkgs_10": { + "nixpkgs_11": { "locked": { "lastModified": 1697723726, "narHash": "sha256-SaTWPkI8a5xSHX/rrKzUe+/uVNy6zCGMXgoeMb7T9rg=", @@ -1483,7 +1816,7 @@ "type": "github" } }, - "nixpkgs_11": { + "nixpkgs_12": { "locked": { "lastModified": 1703255338, "narHash": "sha256-Z6wfYJQKmDN9xciTwU3cOiOk+NElxdZwy/FiHctCzjU=", @@ -1499,7 +1832,7 @@ "type": "github" } }, - "nixpkgs_12": { + "nixpkgs_13": { "locked": { "lastModified": 1686874404, "narHash": "sha256-u2Ss8z+sGaVlKtq7sCovQ8WvXY+OoXJmY1zmyxITiaY=", @@ -1515,22 +1848,6 @@ "type": "github" } }, - "nixpkgs_13": { - "locked": { - "lastModified": 1744536153, - "narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, "nixpkgs_14": { "locked": { "lastModified": 1709703039, @@ -1578,6 +1895,22 @@ } }, "nixpkgs_2": { + "locked": { + "lastModified": 1766070988, + "narHash": "sha256-G/WVghka6c4bAzMhTwT2vjLccg/awmHkdKSd2JrycLc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "c6245e83d836d0433170a16eb185cefe0572f8b8", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { "locked": { "lastModified": 1764252443, "narHash": "sha256-U4G4dUSYWZYKtrF7/ozebD1B96at08SIhY4R9OaK1nw=", @@ -1593,7 +1926,7 @@ "type": "github" } }, - "nixpkgs_3": { + "nixpkgs_4": { "locked": { "lastModified": 1730768919, "narHash": "sha256-8AKquNnnSaJRXZxc5YmF/WfmxiHX6MMZZasRP6RRQkE=", @@ -1609,7 +1942,7 @@ "type": "github" } }, - "nixpkgs_4": { + "nixpkgs_5": { "locked": { "lastModified": 1666603677, "narHash": "sha256-apAEIj+z1iwMaMJ4tB21r/VTetfGDLDzuhXRHJknIAU=", @@ -1623,7 +1956,7 @@ "type": "indirect" } }, - "nixpkgs_5": { + "nixpkgs_6": { "locked": { "lastModified": 1764230294, "narHash": "sha256-Z63xl5Scj3Y/zRBPAWq1eT68n2wBWGCIEF4waZ0bQBE=", @@ -1637,7 +1970,7 @@ "type": "indirect" } }, - "nixpkgs_6": { + "nixpkgs_7": { "locked": { "lastModified": 1763948260, "narHash": "sha256-zZk7fn2ARAqmLwaYTpxBJmj81KIdz11NiWt7ydHHD/M=", @@ -1650,7 +1983,7 @@ "url": "https://channels.nixos.org/nixos-25.05/nixexprs.tar.xz" } }, - "nixpkgs_7": { + "nixpkgs_8": { "locked": { "lastModified": 1768380750, "narHash": "sha256-V5drPOmaGA7bszxKxyViYEZyT2h6RYa/Ll+3aJL4Grs=", @@ -1666,22 +1999,6 @@ "type": "github" } }, - "nixpkgs_8": { - "locked": { - "lastModified": 1765472234, - "narHash": "sha256-9VvC20PJPsleGMewwcWYKGzDIyjckEz8uWmT0vCDYK0=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "2fbfb1d73d239d2402a8fe03963e37aab15abe8b", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, "nixpkgs_9": { "locked": { "lastModified": 1768564909, @@ -1702,7 +2019,7 @@ "inputs": { "flake-parts": "flake-parts_4", "hercules-ci-effects": "hercules-ci-effects_2", - "nixpkgs": "nixpkgs_11", + "nixpkgs": "nixpkgs_12", "osx-kvm": "osx-kvm" }, "locked": { @@ -1746,29 +2063,6 @@ "type": "github" } }, - "org-agenda-api": { - "inputs": { - "emacs-overlay": "emacs-overlay", - "flake-utils": "flake-utils_6", - "git-sync-rs": "git-sync-rs", - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1768558276, - "narHash": "sha256-pfJEORUHXc4nU8bqP/3TJM+VbBkHN1DZKE2fmnJ3e+E=", - "owner": "colonelpanic8", - "repo": "org-agenda-api", - "rev": "97a0654004a346946b77427014c26dc55ed9a5a1", - "type": "github" - }, - "original": { - "owner": "colonelpanic8", - "repo": "org-agenda-api", - "type": "github" - } - }, "ormolu-052": { "flake": false, "locked": { @@ -1837,7 +2131,30 @@ "inputs": { "flake-compat": "flake-compat", "gitignore": "gitignore", - "nixpkgs": "nixpkgs_3" + "nixpkgs": [ + "hyprland", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1765911976, + "narHash": "sha256-t3T/xm8zstHRLx+pIHxVpQTiySbKqcQbK+r+01XVKc0=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "b68b780b69702a090c8bb1b973bab13756cc7a27", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, + "pre-commit-hooks_2": { + "inputs": { + "flake-compat": "flake-compat_2", + "gitignore": "gitignore_2", + "nixpkgs": "nixpkgs_4" }, "locked": { "lastModified": 1747372754, @@ -1856,7 +2173,7 @@ "railbird-secrets": { "inputs": { "agenix": "agenix_2", - "flake-utils": "flake-utils_8", + "flake-utils": "flake-utils_6", "nixpkgs": "nixpkgs_14" }, "locked": { @@ -1881,42 +2198,25 @@ "gtk-sni-tray": "gtk-sni-tray", "gtk-strut": "gtk-strut_2", "home-manager": "home-manager_2", + "hy3": "hy3", + "hyprland": "hyprland", "imalison-taffybar": "imalison-taffybar", "nix": "nix", "nixified-ai": "nixified-ai", "nixos-hardware": "nixos-hardware", "nixos-wsl": "nixos-wsl", - "nixpkgs": "nixpkgs_9", + "nixpkgs": "nixpkgs_10", "nixtheplanet": "nixtheplanet", "notifications-tray-icon": "notifications-tray-icon", - "org-agenda-api": "org-agenda-api", "railbird-secrets": "railbird-secrets", "status-notifier-item": "status-notifier-item_2", - "systems": "systems_10", + "systems": "systems_9", "taffybar": "taffybar_2", "vscode-server": "vscode-server", "xmonad": "xmonad_3", "xmonad-contrib": "xmonad-contrib" } }, - "rust-overlay": { - "inputs": { - "nixpkgs": "nixpkgs_13" - }, - "locked": { - "lastModified": 1755311859, - "narHash": "sha256-NspGtm0ZpihxlFD628pvh5ZEhL/Q6/Z9XBpe3n6ZtEw=", - "owner": "oxalica", - "repo": "rust-overlay", - "rev": "07619500e5937cc4669f24fec355d18a8fec0165", - "type": "github" - }, - "original": { - "owner": "oxalica", - "repo": "rust-overlay", - "type": "github" - } - }, "status-notifier-item": { "flake": false, "locked": { @@ -2072,33 +2372,18 @@ "type": "github" } }, - "systems_13": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - }, "systems_2": { "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "lastModified": 1689347949, + "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "repo": "default-linux", + "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", "type": "github" }, "original": { "owner": "nix-systems", - "repo": "default", + "repo": "default-linux", "type": "github" } }, @@ -2240,7 +2525,7 @@ }, "taffybar_2": { "inputs": { - "flake-utils": "flake-utils_9", + "flake-utils": "flake-utils_7", "git-ignore-nix": "git-ignore-nix_3", "gtk-sni-tray": "gtk-sni-tray_3", "gtk-strut": "gtk-strut_4", @@ -2316,7 +2601,7 @@ }, "vscode-server": { "inputs": { - "flake-utils": "flake-utils_11", + "flake-utils": "flake-utils_9", "nixpkgs": "nixpkgs_16" }, "locked": { @@ -2340,7 +2625,7 @@ "taffybar", "nixpkgs" ], - "pre-commit-hooks": "pre-commit-hooks" + "pre-commit-hooks": "pre-commit-hooks_2" }, "locked": { "lastModified": 1748252779, @@ -2356,11 +2641,52 @@ "type": "github" } }, + "xdph": { + "inputs": { + "hyprland-protocols": [ + "hyprland", + "hyprland-protocols" + ], + "hyprlang": [ + "hyprland", + "hyprlang" + ], + "hyprutils": [ + "hyprland", + "hyprutils" + ], + "hyprwayland-scanner": [ + "hyprland", + "hyprwayland-scanner" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1761431178, + "narHash": "sha256-xzjC1CV3+wpUQKNF+GnadnkeGUCJX+vgaWIZsnz9tzI=", + "owner": "hyprwm", + "repo": "xdg-desktop-portal-hyprland", + "rev": "4b8801228ff958d028f588f0c2b911dbf32297f9", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "xdg-desktop-portal-hyprland", + "type": "github" + } + }, "xmonad": { "inputs": { "flake-utils": "flake-utils_4", "git-ignore-nix": "git-ignore-nix_2", - "nixpkgs": "nixpkgs_5", + "nixpkgs": "nixpkgs_6", "unstable": "unstable" }, "locked": { diff --git a/nixos/flake.nix b/nixos/flake.nix index 66079281..941398df 100644 --- a/nixos/flake.nix +++ b/nixos/flake.nix @@ -27,6 +27,16 @@ agenix = {url = "github:ryantm/agenix";}; + # Hyprland and plugins from official flakes for proper plugin compatibility + hyprland = { + url = "git+https://github.com/hyprwm/Hyprland?submodules=1&ref=refs/tags/v0.53.0"; + }; + + hy3 = { + url = "github:outfoxxed/hy3?ref=hl0.53.0"; + inputs.hyprland.follows = "hyprland"; + }; + railbird-secrets = { url = "git+ssh://gitea@dev.railbird.ai:1123/railbird/secrets-flake.git"; }; @@ -111,10 +121,6 @@ nixtheplanet.url = "github:matthewcroughan/nixtheplanet"; - org-agenda-api = { - url = "github:colonelpanic8/org-agenda-api"; - inputs.nixpkgs.follows = "nixpkgs"; - }; }; outputs = inputs @ { @@ -130,6 +136,8 @@ nix, agenix, imalison-taffybar, + hyprland, + hy3, ... }: let # Nixpkgs PR patches - just specify PR number and hash @@ -199,11 +207,10 @@ mkConfigurationParams = filename: { name = machineNameFromFilename filename; value = { - modules = [ + baseModules = [ (machinesFilepath + ("/" + filename)) agenix.nixosModules.default nixtheplanet.nixosModules.macos-ventura - inputs.org-agenda-api.nixosModules.default ]; }; }; @@ -325,15 +332,5 @@ mkConfig (params // machineParams) ) defaultConfigurationParams; - } - // - # Per-system packages (using flake-utils) - inputs.flake-utils.lib.eachDefaultSystem (system: - let - pkgs = import nixpkgs { inherit system; }; - orgAgendaPackages = import ./org-agenda-api.nix { inherit pkgs inputs system; }; - in { - packages = orgAgendaPackages; - } - ); + }; } diff --git a/nixos/hyprland.nix b/nixos/hyprland.nix index 2ab3a5b6..49f7d616 100644 --- a/nixos/hyprland.nix +++ b/nixos/hyprland.nix @@ -1,12 +1,9 @@ -{ config, pkgs, lib, makeEnable, ... }: +{ config, pkgs, lib, makeEnable, inputs, ... }: makeEnable config "myModules.hyprland" true { programs.hyprland = { enable = true; - # Plugins for XMonad-like experience - plugins = [ - pkgs.hyprlandPlugins.hy3 # Dynamic tiling like XMonad - pkgs.hyprlandPlugins.hyprexpo # Expose/overview (like skippy-xd) - ]; + # Use Hyprland from the flake for proper plugin compatibility + package = inputs.hyprland.packages.${pkgs.system}.hyprland; }; # Hyprland-specific packages @@ -23,7 +20,10 @@ makeEnable config "myModules.hyprland" true { swappy # Screenshot annotation wlsunset # Night light / blue light filter - # For hy3 directional focus - jq # JSON processing (used in scripts) + # hy3 plugin from flake (properly built against matching Hyprland) + inputs.hy3.packages.${pkgs.system}.hy3 + + # For scripts + jq ]; }