Skip to content

nix: home-manager: add config wrapper (wip)#870

Closed
spikespaz wants to merge 36 commits intohyprwm:mainfrom
spikespaz-contrib:nix-hm-module
Closed

nix: home-manager: add config wrapper (wip)#870
spikespaz wants to merge 36 commits intohyprwm:mainfrom
spikespaz-contrib:nix-hm-module

Conversation

@spikespaz
Copy link
Copy Markdown
Contributor

@spikespaz spikespaz commented Oct 18, 2022

@fufexan @viperML

This is a work-in-progress PR. Its intent is to introduce a complete wrapper module for Nix Home Manager for all configurations presented on the Wiki.

You can see a current example utilizing all implemented features:

https://github.com/spikespaz/dotfiles/tree/master/users/jacob/desktops/hyprland

Help is appreciated, if you can spare the time. Let me now and we can get organized.

Comments, questions, concerns? I am eager to discuss.

Checklist

  • Ensure naming scheme is consistent, and renames are appropriate.
  • Update nix/README.md for an overview and guide.
  • Figure out how to generate nice Nix documentation, link it to the Wiki.
  • Ensure every configuration is implemented
    • General
    • Decoration
    • Layouts
      • Dwindle Layout
      • Master Layout
    • Animations
      • Bezier Curves
    • Input
      • Keyboard
      • Touchpad
      • Touchdevice
    • Gestures
    • Misc
    • Monitors
    • Binds
      • Dispatchers
    • Window Rules
      • Window Rule Groups
    • Debug
  • Ensure every configuration is documented
    • General
    • Decoration
    • Layouts
      • Dwindle Layout
      • Master Layout
    • Animations
      • Bezier Curves
    • Input
      • Keyboard
      • Touchpad
      • Touchdevice
    • Gestures
    • Misc
    • Monitors
    • Binds
      • Dispatchers
    • Window Rules
      • Window Rule Groups
    • Debug
  • Ensure options have correct types, new ones if needed
    • General
    • Decoration
    • Layouts
      • Dwindle Layout
      • Master Layout
    • Animations
      • Bezier Curves
    • Input
      • Keyboard
      • Touchpad
      • Touchdevice
    • Gestures
    • Misc
    • Monitors
    • Binds
      • Dispatchers
    • Window Rules
      • Window Rule Groups
    • Debug

Layout

nix
├── default.nix
├── hm-module
│   ├── config
│   │   ├── animations.nix
│   │   ├── binds.nix
│   │   ├── debug.nix
│   │   ├── decoration.nix
│   │   ├── dwindle.nix
│   │   ├── general.nix
│   │   ├── gestures.nix
│   │   ├── input.nix
│   │   ├── keyboard.nix
│   │   ├── misc.nix
│   │   ├── touchpad.nix
│   │   └── windowrules.nix
│   ├── config.nix
│   └── default.nix
├── meson-build.patch
├── module.nix
├── pr.md
├── update-inputs.sh
├── wlroots.nix
├── xwayland-hidpi.patch
└── xwayland-vsync.patch

Introduced hm-module/ and all children. config.nix is the template for the config file to write, while config/ houses the options avaiable to the user. Also observe default.nix.

Module is exposed as a flake output, hyprland.homeManagerModules.default.

@spikespaz spikespaz marked this pull request as draft October 18, 2022 09:52
@viperML
Copy link
Copy Markdown
Contributor

viperML commented Oct 18, 2022

I don't maintain this project anymore, and even less hunders of lines of nix by you.

@spikespaz spikespaz force-pushed the nix-hm-module branch 3 times, most recently from 2c15b6f to d41b677 Compare October 18, 2022 10:32
@fufexan
Copy link
Copy Markdown
Member

fufexan commented Oct 18, 2022

Oh my god that's huge. It's great, no doubt, but I think we can do better than this.

I'd rather spend the time implementing a TOML config in Hyprland itself, and then utilising Nix's formats.toToml over a freeform module to generate the config. I think it's way easier to maintain and also benefits non-Nix users.

@vaxerski
Copy link
Copy Markdown
Member

lmfao

@spikespaz
Copy link
Copy Markdown
Contributor Author

Oh my god that's huge. It's great, no doubt, but I think we can do better than this.

I'd rather spend the time implementing a TOML config in Hyprland itself, and then utilising Nix's formats.toToml over a freeform module to generate the config. I think it's way easier to maintain and also benefits non-Nix users.

It would be pretty peasy to switch it to toml

@spikespaz
Copy link
Copy Markdown
Contributor Author

I think vaxry likes his shit config parser

@algorithmiker
Copy link
Copy Markdown

I don't get it; why is this being worked on in upstream hyperland, instead of Home-Manager?

@fufexan
Copy link
Copy Markdown
Member

fufexan commented Oct 28, 2022

I don't get it; why is this being worked on in upstream hyperland, instead of Home-Manager?

  1. They move slow, and it wouldn't let us add/remove options as soon as they're added to the code.
  2. The (corresponding) Nixpkgs package has been outdated for a long time.

Basically we aim towards being autonomous, while following best practices from Nixpkgs and HM.

@quantenzitrone
Copy link
Copy Markdown

quantenzitrone commented Nov 18, 2022

Yo this might be too trivial for this purpose, but i just do it with these 4 functions:

{
mkValueString = value:(
    if builtins.isBool value then	(
        if value then "true" else "false"
    )
    else if (builtins.isFloat value || builtins.isInt value) then	(
        builtins.toString value
    )
    else if builtins.isString value then (
        value
    )
    else if (
        (builtins.isList value) &&
        ((builtins.length value) == 2) &&
        ((builtins.isFloat (builtins.elemAt value 0)) || (builtins.isFloat (builtins.elemAt value 0))) &&
        ((builtins.isFloat (builtins.elemAt value 1)) || (builtins.isFloat (builtins.elemAt value 1)))
    ) then (
        builtins.toString (builtins.elemAt value 0) + " " + builtins.toString (builtins.elemAt value 1)
    )
    else abort "Unhandled value type ${builtins.typeOf value}"
);

concatAttrs = arg: func: (
    assert builtins.isAttrs arg;
    builtins.concatStringsSep "\n" (lib.attrsets.mapAttrsToList func arg)
);

mkHyprlandVariables = arg: (
    concatAttrs arg (
        name: value: name + (
            if builtins.isAttrs value then (
                " {\n" + (mkHyprlandVariables value) + "\n}"
            )
            else " = " + mkValueString value
        )
    )
);

mkHyprlandBinds = arg: (
    concatAttrs arg (
        name: value: (
            if builtins.isList value then (
                builtins.concatStringsSep "\n" (builtins.map (x: name + " = " + x) value)
            )
            else concatAttrs value (
                name2: value2: name + " = " + name2 + "," + (assert builtins.isString value2; value2)
            )
        )
    )
);
}

and then i use these to write my config like this:

home.file.".config/hypr/hyprland.conf".text = mkHyprlandVariables {
    input = {
        kb_layout = "de";
        kb_variant = "bone";
        follow_mouse = true;
        touchpad = {
            natural_scroll = true;
        };
    };
    general = {
        border_size = var.BORDERPX;
        gaps_in = 5;
        gaps_out = 10;
        "col.active_border" = "rgb(${var.COLOR_ACCENT})";
        "col.inactive_border" = "rgb(${var.COLOR_BG})";
        cursor_inactive_timeout = 5;
        layout = "master";
    };
    decoration = {
        rounding = var.CORNERPX;
        multisample_edges = true;
        active_opacity = (lib.strings.toInt var.TRANSPARENCY * 0.01);
        inactive_opacity = (lib.strings.toInt var.TRANSPARENCY * 0.01);
        fullscreen_opacity = 1.0;
        blur = false;
        drop_shadow = false;
    };
    animations = {
        enabled = true;
    };
    master = {
        new_is_master = false;
        new_on_top = false;
        no_gaps_when_only = false;
    };
    gestures = {
        workspace_swipe = true;
    };
    misc = {
        disable_hyprland_logo = true;
        disable_splash_rendering = true;
        disable_autoreload = true;
        enable_swallow = true;
        swallow_regex = ".+${var.TERMINAL}.+";
    };
} + "\n" +
mkHyprlandBinds {
    bezier = {
        linear = "0,0,1,1";
    };
} + "\n" +
mkHyprlandBinds {
    monitor = {
            eDP-1 = "preferred,0x0,1";
            DP-1 = "preferred,0x1080,1";
    };
    workspace = {
        eDP-1 = "1";
        DP-1 = "11";
    };
    animation = {
        windows = "1,1,linear,slide";
        windowsIn = "1,1,linear,popin";
        windowsOut = "1,1,linear,popin";
        fade = "1,3,linear";
        workspaces = "1,1,linear,slide";
        specialWorkspace = "1,2,linear,slidevert";
    };
    wsbind = {
        # 1-10 ws to screen 1
        "1" = "eDP-1"; "2" = "eDP-1"; "3" = "eDP-1"; "4" = "eDP-1"; "5" = "eDP-1";
        "6" = "eDP-1"; "7" = "eDP-1"; "8" = "eDP-1"; "9" = "eDP-1"; "10" = "eDP-1";
        # 21-41 to second screen
        "11" = "DP-1"; "12" = "DP-1"; "13" = "DP-1"; "14" = "DP-1"; "15" = "DP-1";
        "16" = "DP-1"; "17" = "DP-1"; "18" = "DP-1"; "19" = "DP-1"; "20" = "DP-1";
    };
    bind = {
        ## audio control
        ",XF86AudioRaiseVolume" = "exec,pamixer -i 1";
        ",XF86AudioLowerVolume" = "exec,pamixer -d 1";
        ",XF86AudioMute" = "exec,pamixer -t";
        ",XF86AudioPlay" = "exec,playerctl play-pause";
        ",XF86AudioNext" = "exec,playerctl next";
        ",XF86AudioPrev" = "exec,playerctl previous";
        ## brightness control
        ",XF86MonBrightnessUp" = "exec,brightnessctl set +75";
        ",XF86MonBrightnessDown" = "exec,brightnessctl set 75-";
        ## display control
        #",XF86Display" = "exec,lock";
        ## killing application
        ",XF86RFKill" = "killactive,";
        # STARTERS
        "SUPER,T" = "exec,${var.TERMINAL}";
        "SUPER,B" = "exec,${var.WEBBROWSER}";
        "SUPER,d" = "exec,${var.FILEMANAGER}";
        "SUPER,space" = "exec,rofi -modi drun,run -show drun";
        "ALT,space" = "exec,rofi -modi drun,run -show drun";
        "SUPER,k" = "togglespecialworkspace,";
        "SUPER,o" = "toggleopaque,";
        # SHORTCUT KEYS
        "SUPER,C" = "killactive,";
        "SUPER,F" = "fullscreen,";
        "SUPER,V" = "togglefloating,e";
        # "SUPER,L" = "exec,lock";

        #############################
        # there are 3 hand positions this configuration should work:
        # - left hand on ctie (asdf)
        # - right hand on nrsg (jkl;)
        # or:
        # - left hand on ctie (asdf)
        # - right hand on mouse with all mouse button aviable
        # or:
        # - only touchscreen, and some buttons (doesn't work yet, maybe it will never fully work)
        ############################

        # window changing
        "ALT, ${right.right}" = "cyclenext,";
        "ALT, ${right.left}" = "cyclenext, prev";

        # move focused window
        "ALT SHIFT, ${right.right}" = "swapnext,";
        "ALT SHIFT, ${right.left}" = "swapnext, prev";

        # resizing focused
        "ALT CTRL, ${right.down}" = "resizeactive,0 100";
        "ALT CTRL, ${right.up}" = "resizeactive,0 -100 ";
        "ALT CTRL, ${right.right}" = "resizeactive,100 0";
        "ALT CTRL, ${right.left}" = "resizeactive,-100 0";

        # switch between workspaces by direction
        "ALT, ${left.left}" = "workspace, -1";
        "ALT, ${left.right}" = "workspace, +1";
        "ALT, ${left.up}" = "workspace, previous";
        # switch between workspaces directly
        "ALT, 1" = "workspace, 1";
        "ALT, 2" = "workspace, 2";
        "ALT, 3" = "workspace, 3";
        "ALT, 4" = "workspace, 4";
        "ALT, 5" = "workspace, 5";
        "ALT, 6" = "workspace, 6";
        "ALT, 7" = "workspace, 7";
        "ALT, 8" = "workspace, 8";
        "ALT, 9" = "workspace, 9";
        "ALT, 0" = "workspace, 10";
        "ALT CTRL, 1" = "workspace, 11";
        "ALT CTRL, 2" = "workspace, 12";
        "ALT CTRL, 3" = "workspace, 13";
        "ALT CTRL, 4" = "workspace, 14";
        "ALT CTRL, 5" = "workspace, 15";
        "ALT CTRL, 7" = "workspace, 17";
        "ALT CTRL, 8" = "workspace, 18";
        "ALT CTRL, 9" = "workspace, 19";
        "ALT CTRL, 0" = "workspace, 20";
        # move containers between workspaces by direction
        "ALT SHIFT, ${left.left}" = "movetoworkspace, -1";
        "ALT SHIFT, ${left.right}" = "movetoworkspace, +1";
        # move containers between workspaces directly
        "ALT SHIFT, 1" = "movetoworkspace, 1";
        "ALT SHIFT, 2" = "movetoworkspace, 2";
        "ALT SHIFT, 3" = "movetoworkspace, 3";
        "ALT SHIFT, 4" = "movetoworkspace, 4";
        "ALT SHIFT, 5" = "movetoworkspace, 5";
        "ALT SHIFT, 6" = "movetoworkspace, 6";
        "ALT SHIFT, 7" = "movetoworkspace, 7";
        "ALT SHIFT, 8" = "movetoworkspace, 8";
        "ALT SHIFT, 9" = "movetoworkspace, 9";
        "ALT SHIFT, 0" = "movetoworkspace, 10";
        "ALT CTRL SHIFT, 1" = "movetoworkspace, 11";
        "ALT CTRL SHIFT, 2" = "movetoworkspace, 12";
        "ALT CTRL SHIFT, 3" = "movetoworkspace, 13";
        "ALT CTRL SHIFT, 4" = "movetoworkspace, 14";
        "ALT CTRL SHIFT, 5" = "movetoworkspace, 15";
        "ALT CTRL SHIFT, 6" = "movetoworkspace, 16";
        "ALT CTRL SHIFT, 7" = "movetoworkspace, 17";
        "ALT CTRL SHIFT, 8" = "movetoworkspace, 18";
        "ALT CTRL SHIFT, 9" = "movetoworkspace, 19";
        "ALT CTRL SHIFT, 0" = "movetoworkspace, 20";
        "SUPER,mouse:274" = "killactive";
    };
    bindm = {
        "ALT,mouse:272" = "movewindow";
        "ALT,mouse:273" = "resizewindow";
    };
    bindl = {
        #",switch:Lid Switch" = "exec,lock";
    };
    windowrulev2 = [
        "float,class:Rofi"
        "tile,class:PPSSPPSDL"
        "noborder,class:Rofi"
        "center,class:Rofi"
        "monitor DP-1,class:xournalpp"
        "workspace special,class:KeePassXC"
        # no transparency for some windows
        "opaque,class:KeePassXC"
        "opaque,class:Rofi"
        "opaque,class:Alacritty"
        "opaque,class:PPSSPPSDL"
        "opaque,class:osu!"
        "opaque,class:xournalpp"
    ];
    exec-once = [
        "dunst"
        "blueman-applet"
        "${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1"
        "flameshot"
        "nm-applet --indicator"
        "xss-lock --transfer-sleep-lock -- swaylock -c 00000000"
        "keepassxc"
        "hyprpaper"
        "waybar"
    ];
};

and yes submaps are not supported by this, i dont use them

@algorithmiker
Copy link
Copy Markdown

If I wanted to test this, do I have to build your fork of Hyprland, @spikespaz ?

@spikespaz
Copy link
Copy Markdown
Contributor Author

If I wanted to test this, do I have to build your fork of Hyprland, @spikespaz ?

You need to add my fork as a flake input, and merge the nix-hm-module branch with this upstream's main branch. You should not need to rebuild the derivation as long as the package manifest in my fork matches the one you were previously using. I recommend adding the cachix instance as a substituter in your system config.

@spikespaz spikespaz force-pushed the nix-hm-module branch 3 times, most recently from 879fc25 to 7dbdccc Compare January 27, 2023 04:19
@vaxerski vaxerski force-pushed the main branch 2 times, most recently from e309ecf to 5eb98c0 Compare February 8, 2023 15:18
@Mic92
Copy link
Copy Markdown
Contributor

Mic92 commented Feb 19, 2023

I don't get it; why is this being worked on in upstream hyperland, instead of Home-Manager?

1. They move slow, and it wouldn't let us add/remove options as soon as they're added to the code.

2. The (corresponding) Nixpkgs package has been outdated for a long time.

Basically we aim towards being autonomous, while following best practices from Nixpkgs and HM.

If you have any features for hyprland you would like to be merged in nixpkgs you can ping me directly on matrix. Just now it seems like hyprland patches many things which makes keeping it up-to-date also harder.

@fufexan
Copy link
Copy Markdown
Member

fufexan commented Feb 19, 2023

@Mic92 thank you for wanting to support us.

I'll get in touch with the current Hyprland maintainer in Nixpkgs and try to update the package, as well as add the unpackaged hyprland-protocols, hyprpicker, hyprpaper and xdg-desktop-portal-hyprland.

As for the Home Manager part, I will try to add the module there (and in NixOS as well) as soon as the packages are in.

I will ping you for reviews. Thanks again.

@spikespaz spikespaz force-pushed the nix-hm-module branch 3 times, most recently from 5d89e84 to 24a2c83 Compare March 8, 2023 05:30
spikespaz added 24 commits April 7, 2023 19:25
decoration:blur_xray
decoration:shadow_scale
decoration:dim_special
decoration:dim_around
decoration:screen_shader
input:scroll_button
gestures:workspace_swipe_numbered
misc:focus_on_activate
misc:no_direct_scanout
misc:hide_cursor_on_touch
@spikespaz
Copy link
Copy Markdown
Contributor Author

Deprecating and closing this PR in favor of: https://github.com/spikespaz/dotfiles/tree/master/hm-modules/hyprland

Use the module from my flake, because it is still WIP.

You can find basic instructions in the readme of the repository. There are no instructions specifically for the module itself because I still consider it "for advanced Nix users only", however if you fit that description, please DO USE IT AND PROVIDE FEEDBACK!

Check out the config.nix, default.nix, keybinds.nix windowrules.nix, and monitors.nix files in the following subdirectory: https://github.com/spikespaz/dotfiles/tree/master/users/jacob/desktops/hyprland

@spikespaz spikespaz closed this Jun 9, 2023
@spikespaz
Copy link
Copy Markdown
Contributor Author

Cross-referencing: hyprwm/hyprland-wiki#273 (comment)

VirtCode pushed a commit to VirtCode/Hyprland that referenced this pull request Nov 16, 2025
* Refactor asset management to use shared_ptr

* Replace shared_ptr with ASP for SPreloadedAsset usage
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants