diff --git a/home/toph/common/optional/hyprland/binds.nix b/home/toph/common/optional/hyprland/binds.nix index 26e5ee9..7302132 100644 --- a/home/toph/common/optional/hyprland/binds.nix +++ b/home/toph/common/optional/hyprland/binds.nix @@ -106,13 +106,16 @@ # "SUPER_SHIFT, P, exec, ${notify} 'Toggled Pin'" "SUPER_SHIFT, S, swapnext" # "SUPER_SHIFT, O, toggleopaque" + "SUPER, G, togglegroup" + # "SUPER, G, exec, ${notify} 'Toggled Group'" + "SUPER, Tab, changegroupactive, f" # -- Workspaces -- ", Home, overview:toggle" # "SUPER, A, " # TODO: use hycov for alt tab, https://github.com/bighu630/hycov - "ALT, Tab, cyclenext," - "ALT, Tab, bringactivetotop," + "ALT, Tab, cyclenext," + "ALT, Tab, bringactivetotop," ]; }; diff --git a/home/toph/common/optional/hyprland/default.nix b/home/toph/common/optional/hyprland/default.nix index bb8b998..c5323f6 100644 --- a/home/toph/common/optional/hyprland/default.nix +++ b/home/toph/common/optional/hyprland/default.nix @@ -31,9 +31,8 @@ ]; settings = { - # - # ========== Environment Vars ========== - # + + ## Environment Vars ## env = [ "NIXOS_OZONE_WL, 1" # for ozone-based and electron apps to run on wayland "MOZ_ENABLE_WAYLAND, 1" # for firefox to run on wayland @@ -46,120 +45,159 @@ ]; ## Monitor ## - # parse the monitor spec defined in home///default.nix + monitor = ( + # INFO: parse the monitors defined in home///default.nix map ( m: "${m.name},${ if m.enabled then - "${toString m.width}x${toString m.height}@${toString m.refreshRate},${toString m.x}x${toString m.y},1,transform,${toString m.transform},vrr,${toString m.vrr}" + "${toString m.width}x${toString m.height}@${toString m.refreshRate},${toString m.x}x${toString m.y},${toString m.scale},transform,${toString m.transform},vrr,${toString m.vrr}" else "disable" }" ) (config.monitors) ); - #FIXME(hyprland): adapt this to work with new monitor module - #FIXME(hyprland): ws1 still appears on both DP-1 and DP-3 on reboot - # workspace = [ - # "1, monitor:DP-1, default:true, persistent:true" - # "2, monitor:DP-1, default:true" - # "3, monitor:DP-1, default:true" - # "4, monitor:DP-1, default:true" - # "5, monitor:DP-1, default:true" - # "6, monitor:DP-1, default:true" - # "7, monitor:DP-1, default:true" - # "8, monitor:DP-2, default:true, persistent:true" - # "9, monitor:HDMI-A-1, default:true, persistent:true" - # "0, monitor:DP-3, default:true, persistent:true" - # ]; + # I love this :) + # Creates 5 workspaces for all monitors + workspace = + let + json = pkgs.writeTextFile { + name = "monitors.json"; + text = builtins.toJSON config.monitors; + }; + parse = pkgs.runCommand "parse-workspaces" { } '' + mkdir "$out"; ${pkgs.jq}/bin/jq -r ' + [ to_entries[] | + (.key as $i | .value.name as $name | + [ range(0;5) | ($i * 5 + .) as $wsnum | + if . == 0 then "\($wsnum), monitor:\($name), default:true, persistent:true" + else "\($wsnum), monitor:\($name)" end + ] + ) + ] | flatten + ' ${json} > "$out/out.json" + ''; + output = builtins.fromJSON (builtins.readFile "${parse}/out.json"); + in + output; + + ## Behavior ## - # - # ========== Behavior ========== - # binds = { - workspace_center_on = 1; # Whether switching workspaces should center the cursor on the workspace (0) or on the last active window for that workspace (1) - movefocus_cycles_fullscreen = false; # If enabled, when on a fullscreen window, movefocus will cycle fullscreen, if not, it will move the focus in a direction. + workspace_center_on = 1; + movefocus_cycles_fullscreen = false; }; + input = { follow_mouse = 2; - # follow_mouse options: - # 0 - Cursor movement will not change focus. - # 1 - Cursor movement will always change focus to the window under the cursor. - # 2 - Cursor focus will be detached from keyboard focus. Clicking on a window will move keyboard focus to that window. - # 3 - Cursor focus will be completely separate from keyboard focus. Clicking on a window will not change keyboard focus. mouse_refocus = false; kb_options = "fkeys:basic_13-24"; + sensitivity = 0.5; }; - cursor.inactive_timeout = 10; + + cursor = { + inactive_timeout = 10; + }; + misc = { disable_hyprland_logo = true; animate_manual_resizes = true; animate_mouse_windowdragging = true; #disable_autoreload = true; - new_window_takes_over_fullscreen = 2; # 0 - behind, 1 - takes over, 2 - unfullscreen/unmaxize + new_window_takes_over_fullscreen = 2; middle_click_paste = false; }; - # - # ========== Appearance ========== - # - #FIXME-rice colors conflict with stylix + group = { + drag_into_group = 2; + merge_groups_on_drag = true; + # col.border_active = ""; + # col.border_inactive = ""; + groupbar = { + enabled = true; + height = 12; + }; + }; + + dwindle = { + pseudotile = false; + force_split = 0; + smart_split = true; + split_bias = 1; + }; + + ## Appearance ## + general = { + border_size = 2; gaps_in = 6; gaps_out = 6; - border_size = 0; - #col.inactive-border = "0x00000000"; - #col.active-border = "0x0000000"; - resize_on_border = true; - hover_icon_on_border = true; + "col.inactive_border" = "0x44e3625e"; + "col.active_border" = "0x20e3625e"; allow_tearing = true; # used to reduce latency and/or jitter in games + snap = { + enabled = true; + window_gap = 6; + }; }; + decoration = { - active_opacity = 1.0; - inactive_opacity = 0.85; - fullscreen_opacity = 1.0; rounding = 10; + rounding_power = 4.0; + active_opacity = 0.90; + inactive_opacity = 0.80; + fullscreen_opacity = 1.0; blur = { enabled = true; - size = 4; + size = 15; passes = 2; new_optimizations = true; + ignore_opacity = true; + xray = true; + # noise = 0.15; popups = true; }; shadow = { enabled = true; - range = 12; - offset = "3 3"; - #color = "0x88ff9400"; - #color_inactive = "0x8818141d"; + range = 30; + render_power = 3; + scale = 1.0; + color = "0x66000000"; + color_inactive = "0x66000000"; }; }; - # group = { - #groupbar = { - # }; - #}; - # - # ========== Auto Launch ========== - # - # exec-once = ''${startupScript}/path''; - # To determine path, run `which foo` + animation = [ + "windowsIn, 1, 5 ,default, popin 0%" + "windowsOut, 1, 5 ,default, popin" + "windowsMove, 1, 5 ,default, slide" + "fadeIn, 1, 8 ,default" + "fadeOut, 1, 8 ,default" + "fadeSwitch, 1, 8 ,default" + "fadeShadow, 1, 8 ,default" + "fadeDim, 1, 8 ,default" + "border, 1, 10 ,default" + "workspaces, 1, 5 ,default, slide" + ]; + + ## Auto Launch ## + exec-once = [ ''${pkgs.waypaper}/bin/waypaper --restore'' ]; - # - # ========== Layer Rules ========== - # + + ## Layers Rules ## + layer = [ #"blur, rofi" #"ignorezero, rofi" #"ignorezero, logout_dialog" - ]; - # - # ========== Window Rules ========== - # + + ## Window Rules ## + windowrule = [ # Dialogs "float, title:^(Open File)(.*)$" @@ -170,7 +208,11 @@ "float, title:^(Library)(.*)$" "float, title:^(Accounts)(.*)$" ]; + windowrulev2 = [ + #Zen Extensions + "suppressevent maximize, class:^(zen)$" + "float, class:^(galculator)$" "float, class:^(waypaper)$" "float, class:^(keymapp)$" @@ -220,14 +262,14 @@ # # ========== Workspace Assignments ========== # - "workspace 8, class:^(virt-manager)$" - "workspace 8, class:^(obsidian)$" - "workspace 9, class:^(brave-browser)$" - "workspace 9, class:^(signal)$" - "workspace 9, class:^(org.telegram.desktop)$" - "workspace 9, class:^(discord)$" - "workspace 0, title:^([Ss]potify*)$" - "workspace special, class:^(yubioath-flutter)$" + # "workspace 8, class:^(virt-manager)$" + # "workspace 8, class:^(obsidian)$" + # "workspace 9, class:^(brave-browser)$" + # "workspace 9, class:^(signal)$" + # "workspace 9, class:^(org.telegram.desktop)$" + # "workspace 9, class:^(discord)$" + # "workspace 0, title:^([Ss]potify*)$" + # "workspace special, class:^(yubioath-flutter)$" ]; # load at the end of the hyperland set diff --git a/home/toph/common/optional/hyprland/gtk.nix b/home/toph/common/optional/hyprland/gtk.nix index ab274f0..d1a1c0f 100644 --- a/home/toph/common/optional/hyprland/gtk.nix +++ b/home/toph/common/optional/hyprland/gtk.nix @@ -27,7 +27,7 @@ font = { name = "Sans"; - size = 14; + size = 12; }; }; } diff --git a/home/toph/common/optional/hyprland/scripts/default.nix b/home/toph/common/optional/hyprland/scripts/default.nix index ffcd441..b23287b 100644 --- a/home/toph/common/optional/hyprland/scripts/default.nix +++ b/home/toph/common/optional/hyprland/scripts/default.nix @@ -1 +1,4 @@ -{ } +{ lib, ... }: +{ + imports = lib.custom.scanPaths ./.; +} diff --git a/home/toph/common/optional/hyprland/scripts/zen-float.nix b/home/toph/common/optional/hyprland/scripts/zen-float.nix new file mode 100644 index 0000000..921e6b0 --- /dev/null +++ b/home/toph/common/optional/hyprland/scripts/zen-float.nix @@ -0,0 +1,78 @@ +{ pkgs, lib, ... }: +let + zen-extensions = { + bitwarden = { + regex = "'*(Bitwarden Password Manager) - Bitwarden*'"; + x = 500; + y = 900; + }; + authenticator = { + regex = "'*(Authenticator) - Authenticator*'"; + x = 335; + y = 525; + }; + }; + + zen-json = pkgs.writeText "zen-extensions.json" (builtins.toJSON zen-extensions); + zen-script = pkgs.writeScript "zen-script" '' + #!/usr/bin/env fish + + function handle + set -l line $argv[1] + switch $line + case "windowtitlev2*" + # Expected format: windowtitlev2>>, + set -l payload (string replace -r '^windowtitlev2>>' "" $line) + set -l parts (string split "," $payload) + set -l window_id (string trim $parts[1]) + set -l title (string join "," $parts[2..-1]) + + # Debug output + echo "Extracted window_id: [$window_id]" + echo "Extracted title: [$title]" + + # Loop over the extensions defined in the JSON file. + for ext in ( ${pkgs.jq}/bin/jq -r 'keys[]' ${zen-json} ) + echo "Processing extension: [$ext]" + # Get regex, x and y for the current extension. + set -l reg ( ${pkgs.jq}/bin/jq -r --arg k $ext '.[$k].regex' ${zen-json} ) + set -l ext_x ( ${pkgs.jq}/bin/jq -r --arg k $ext '.[$k].x' ${zen-json} ) + set -l ext_y ( ${pkgs.jq}/bin/jq -r --arg k $ext '.[$k].y' ${zen-json} ) + + # Remove any extra surrounding single quotes. + set -l reg (string trim -c "'" $reg) + + # Debug: show the extension and regex being used. + echo "Checking extension [$ext] with regex [$reg] against title [$title]" + + # If the title matches the regex, dispatch floating commands. + if string match -q -- "*$reg*" "$title" + echo "$ext window id: $window_id -- setting float mode with size $ext_x x $ext_y" + hyprctl --batch "dispatch togglefloating address:0x$window_id; dispatch resizewindowpixel exact $ext_x $ext_y,address:0x$window_id; dispatch movewindowpixel exact 64% 3%,address:0x$window_id" + return + end + end + ;; + case "*" + # Do nothing for other events. + ;; + end + end + + ${pkgs.socat}/bin/socat -U - UNIX-CONNECT:/run/user/1000/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock | while read -l line + handle "$line" + end + ''; +in +{ + wayland.windowManager.hyprland.settings = { + exec-once = [ + "${pkgs.fish}/bin/fish ${zen-script}" + ]; + + windowrulev2 = [ + # Zen Extensions + "suppressevent maximize, class:^(zen)$" + ]; + }; +} diff --git a/home/toph/rune/default.nix b/home/toph/rune/default.nix index 1dd6a7e..6acc0fc 100644 --- a/home/toph/rune/default.nix +++ b/home/toph/rune/default.nix @@ -11,7 +11,8 @@ ## Host-specific Optional Configs ## ../common/optional/browsers - ../common/optional/gnome + # ../common/optional/gnome + ../common/optional/hyprland ../common/optional/development ../common/optional/gaming ../common/optional/xdg.nix # file associations @@ -36,7 +37,6 @@ bitwarden-desktop inspector remmina - wezterm vial # KB setup ## Productivity ## @@ -45,6 +45,31 @@ ; }; + monitors = [ + { + name = "DP-3"; + x = 900; + y = 0; + width = 3840; + height = 2160; + refreshRate = 120; + primary = true; + scale = 1.20; + vrr = 2; + } + { + name = "HDMI-A-2"; + x = 0; + y = 0; + width = 1920; + height = 1080; + refreshRate = 60; + primary = false; + transform = 3; + scale = 1.20; + } + ]; + # home.file = { # "run-mac.sh".source = config.lib.file.mkOutOfStoreSymlink "${pkgs.macos-ventura-image.runScript}"; # }; diff --git a/hosts/common/core/default.nix b/hosts/common/core/default.nix index 6762d99..0807c90 100644 --- a/hosts/common/core/default.nix +++ b/hosts/common/core/default.nix @@ -35,10 +35,11 @@ in # System-wide packages, in case we log in as root environment.systemPackages = with pkgs; [ micro - plocate openssh + plocate ranger sshfs + wget ]; # Enable CUPS to print documents. @@ -108,7 +109,7 @@ in ]; ## NIX NIX NIX ## - documentation.nixos.enable = false; + documentation.nixos.enable = lib.mkForce false; nix = { # This will add each flake input as a registry # To make nix3 commands consistent with your flake diff --git a/hosts/common/optional/hyprland/foot.nix b/hosts/common/optional/hyprland/foot.nix new file mode 100644 index 0000000..4add592 --- /dev/null +++ b/hosts/common/optional/hyprland/foot.nix @@ -0,0 +1,16 @@ +{ + programs.foot = { + enable = true; + settings = { + main = { + term = "xterm-256color"; + font = "monospace:size=10"; + dpi-aware = "yes"; + }; + + mouse = { + hide-when-typing = "yes"; + }; + }; + }; +} diff --git a/hosts/common/optional/hyprland/gnome-services.nix b/hosts/common/optional/hyprland/gnome-services.nix new file mode 100644 index 0000000..d624503 --- /dev/null +++ b/hosts/common/optional/hyprland/gnome-services.nix @@ -0,0 +1,22 @@ +{ pkgs, ... }: +{ + + environment.systemPackages = with pkgs; [ + file-roller + nautilus + ]; + + services = { + # needed for GNOME services outside of GNOME Desktop + dbus.packages = with pkgs; [ + gcr + gnome-keyring + gnome-settings-daemon + gvfs + ]; + + gnome.gnome-keyring.enable = true; + + gvfs.enable = true; + }; +} diff --git a/hosts/nixos/rune/default.nix b/hosts/nixos/rune/default.nix index da11089..035cad8 100644 --- a/hosts/nixos/rune/default.nix +++ b/hosts/nixos/rune/default.nix @@ -33,7 +33,8 @@ in "hosts/common/optional/bluetooth.nix" "hosts/common/optional/ddcutil.nix" # ddcutil for monitor controls "hosts/common/optional/gaming.nix" # steam, gamescope, gamemode, and related hardware - "hosts/common/optional/gnome.nix" # desktop + # "hosts/common/optional/gnome.nix" # desktop + "hosts/common/optional/hyprland" # desktop "hosts/common/optional/libvirt.nix" # vm tools "hosts/common/optional/nvtop.nix" # GPU monitor (not available in home-manager) "hosts/common/optional/plymouth.nix" # fancy boot screen @@ -67,10 +68,6 @@ in programs.nix-ld.enable = true; environment.systemPackages = with pkgs; [ asdf-vm - openssh - ranger - sshfs - wget ]; # https://wiki.nixos.org/wiki/FAQ/When_do_I_update_stateVersion diff --git a/hosts/nixos/rune/hardware.nix b/hosts/nixos/rune/hardware.nix index af6d516..859f92f 100644 --- a/hosts/nixos/rune/hardware.nix +++ b/hosts/nixos/rune/hardware.nix @@ -3,6 +3,7 @@ # to /etc/nixos/configuration.nix instead. { + pkgs, config, lib, modulesPath, @@ -24,6 +25,9 @@ timeout = 3; }; + # use latest kernel + kernelPackages = pkgs.linuxPackages_latest; + initrd = { systemd.enable = true; verbose = false; @@ -61,8 +65,7 @@ }; "/pool" = { - # FIXME: admin does not work here anymore - device = "${config.hostSpec.username}@104.40.4.24:/pool"; + device = "${config.hostSpec.username}@cloud:/pool"; fsType = "sshfs"; options = [ "defaults"