-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
hyprland: init #3837
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
hyprland: init #3837
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,216 @@ | ||||||||||||||||||||||||
| { config, lib, pkgs, ... }: | ||||||||||||||||||||||||
| let | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| cfg = config.wayland.windowManager.hyprland; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| in { | ||||||||||||||||||||||||
| meta.maintainers = [ lib.maintainers.fufexan ]; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| # A few option removals and renames to aid those migrating from the upstream | ||||||||||||||||||||||||
| # module. | ||||||||||||||||||||||||
| imports = [ | ||||||||||||||||||||||||
| (lib.mkRemovedOptionModule # \ | ||||||||||||||||||||||||
| [ "wayland" "windowManager" "hyprland" "disableAutoreload" ] | ||||||||||||||||||||||||
| "Autoreloading now always happen") | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| (lib.mkRemovedOptionModule # \ | ||||||||||||||||||||||||
| [ "wayland" "windowManager" "hyprland" "recommendedEnvironment" ] | ||||||||||||||||||||||||
| "Recommended environment variables are now always set") | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| (lib.mkRenamedOptionModule # \ | ||||||||||||||||||||||||
| [ "wayland" "windowManager" "hyprland" "nvidiaPatches" ] # \ | ||||||||||||||||||||||||
| [ "wayland" "windowManager" "hyprland" "enableNvidiaPatches" ]) | ||||||||||||||||||||||||
| ]; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| options.wayland.windowManager.hyprland = { | ||||||||||||||||||||||||
| enable = lib.mkEnableOption "Hyprland wayland compositor"; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| package = lib.mkPackageOption pkgs "hyprland" { }; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| finalPackage = lib.mkOption { | ||||||||||||||||||||||||
| type = lib.types.package; | ||||||||||||||||||||||||
| readOnly = true; | ||||||||||||||||||||||||
| default = cfg.package.override { | ||||||||||||||||||||||||
| enableXWayland = cfg.xwayland.enable; | ||||||||||||||||||||||||
| hidpiXWayland = cfg.xwayland.hidpi; | ||||||||||||||||||||||||
| nvidiaPatches = cfg.enableNvidiaPatches; | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
| defaultText = lib.literalMD | ||||||||||||||||||||||||
| "`wayland.windowManager.hyprland.package` with applied configuration"; | ||||||||||||||||||||||||
| description = '' | ||||||||||||||||||||||||
| The Hyprland package after applying configuration. | ||||||||||||||||||||||||
| ''; | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| plugins = lib.mkOption { | ||||||||||||||||||||||||
| type = with lib.types; listOf (either package path); | ||||||||||||||||||||||||
| default = [ ]; | ||||||||||||||||||||||||
| description = '' | ||||||||||||||||||||||||
| List of Hyprland plugins to use. Can either be packages or | ||||||||||||||||||||||||
| absolute plugin paths. | ||||||||||||||||||||||||
| ''; | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| systemdIntegration = lib.mkOption { | ||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When would you not want to use systemd integration? Btw, when enabling the systemd integration I don't see any attempt at shutting down the graphical session when Hyprland exits. Will that happen automatically?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps it makes sense for users that are on a distro without systemd. But they'd have a hard time using Nix by itself, let alone HM. No, there's no attempt to shut down the graphical session. I don't know how to do this, but I'm willing to include it if you have clues. Also, it does not automatically shut down.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Without something like home-manager/modules/xsession.nix Lines 209 to 219 in 6a19225
|
||||||||||||||||||||||||
| type = lib.types.bool; | ||||||||||||||||||||||||
| default = pkgs.stdenv.isLinux; | ||||||||||||||||||||||||
| description = '' | ||||||||||||||||||||||||
| Whether to enable {file}`hyprland-session.target` on | ||||||||||||||||||||||||
| hyprland startup. This links to `graphical-session.target`. | ||||||||||||||||||||||||
| Some important environment variables will be imported to systemd | ||||||||||||||||||||||||
| and dbus user environment before reaching the target, including | ||||||||||||||||||||||||
| - `DISPLAY` | ||||||||||||||||||||||||
| - `HYPRLAND_INSTANCE_SIGNATURE` | ||||||||||||||||||||||||
| - `WAYLAND_DISPLAY` | ||||||||||||||||||||||||
| - `XDG_CURRENT_DESKTOP` | ||||||||||||||||||||||||
| ''; | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| xwayland = { | ||||||||||||||||||||||||
| enable = lib.mkEnableOption "XWayland" // { default = true; }; | ||||||||||||||||||||||||
| hidpi = lib.mkEnableOption null // { | ||||||||||||||||||||||||
| description = '' | ||||||||||||||||||||||||
| Enable HiDPI XWayland, based on [XWayland MR 733](https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/733). | ||||||||||||||||||||||||
| See <https://wiki.hyprland.org/Nix/Options-Overrides/#xwayland-hidpi> for more info. | ||||||||||||||||||||||||
| ''; | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| enableNvidiaPatches = | ||||||||||||||||||||||||
| lib.mkEnableOption "patching wlroots for better Nvidia support"; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| settings = lib.mkOption { | ||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note, name changed to |
||||||||||||||||||||||||
| type = with lib.types; | ||||||||||||||||||||||||
| let | ||||||||||||||||||||||||
| valueType = nullOr (oneOf [ | ||||||||||||||||||||||||
| bool | ||||||||||||||||||||||||
| int | ||||||||||||||||||||||||
| float | ||||||||||||||||||||||||
| str | ||||||||||||||||||||||||
| path | ||||||||||||||||||||||||
| (attrsOf valueType) | ||||||||||||||||||||||||
| (listOf valueType) | ||||||||||||||||||||||||
| ]) // { | ||||||||||||||||||||||||
| description = "Hyprland configuration value"; | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
| in valueType; | ||||||||||||||||||||||||
| default = { }; | ||||||||||||||||||||||||
| description = '' | ||||||||||||||||||||||||
| Hyprland configuration written in Nix. Entries with the same key | ||||||||||||||||||||||||
| should be written as lists. Variables' and colors' names should be | ||||||||||||||||||||||||
| quoted. See <https://wiki.hyprland.org> for more examples. | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| ::: {.note} | ||||||||||||||||||||||||
| Use the [](#opt-wayland.windowManager.hyprland.plugins) option to | ||||||||||||||||||||||||
| declare plugins. | ||||||||||||||||||||||||
| ::: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| ''; | ||||||||||||||||||||||||
| example = lib.literalExpression '' | ||||||||||||||||||||||||
| { | ||||||||||||||||||||||||
| decoration = { | ||||||||||||||||||||||||
| shadow_offset = "0 5"; | ||||||||||||||||||||||||
| "col.shadow" = "rgba(00000099)"; | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| "$mod" = "SUPER"; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| bindm = [ | ||||||||||||||||||||||||
| # mouse movements | ||||||||||||||||||||||||
| "$mod, mouse:272, movewindow" | ||||||||||||||||||||||||
| "$mod, mouse:273, resizewindow" | ||||||||||||||||||||||||
| "$mod ALT, mouse:272, resizewindow" | ||||||||||||||||||||||||
| ]; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| ''; | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| extraConfig = lib.mkOption { | ||||||||||||||||||||||||
| type = lib.types.lines; | ||||||||||||||||||||||||
| default = ""; | ||||||||||||||||||||||||
| example = '' | ||||||||||||||||||||||||
| # window resize | ||||||||||||||||||||||||
| bind = $mod, S, submap, resize | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| submap = resize | ||||||||||||||||||||||||
| binde = , right, resizeactive, 10 0 | ||||||||||||||||||||||||
| binde = , left, resizeactive, -10 0 | ||||||||||||||||||||||||
| binde = , up, resizeactive, 0 -10 | ||||||||||||||||||||||||
| binde = , down, resizeactive, 0 10 | ||||||||||||||||||||||||
| bind = , escape, submap, reset | ||||||||||||||||||||||||
| submap = reset | ||||||||||||||||||||||||
| ''; | ||||||||||||||||||||||||
| description = '' | ||||||||||||||||||||||||
| Extra configuration lines to add to `~/.config/hypr/hyprland.conf`. | ||||||||||||||||||||||||
| ''; | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| config = lib.mkIf cfg.enable { | ||||||||||||||||||||||||
|
fufexan marked this conversation as resolved.
|
||||||||||||||||||||||||
| assertions = [ | ||||||||||||||||||||||||
| (lib.hm.assertions.assertPlatform "wayland.windowManager.hyprland" pkgs | ||||||||||||||||||||||||
| lib.platforms.linux) | ||||||||||||||||||||||||
| ]; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| warnings = let | ||||||||||||||||||||||||
| inconsistent = (cfg.systemdIntegration || cfg.plugins != [ ]) | ||||||||||||||||||||||||
| && cfg.extraConfig == "" && cfg.settings == { }; | ||||||||||||||||||||||||
| warning = | ||||||||||||||||||||||||
| "You have enabled hyprland.systemdIntegration or listed plugins in hyprland.plugins but do not have any configuration in hyprland.settings or hyprland.extraConfig. This is almost certainly a mistake."; | ||||||||||||||||||||||||
| in lib.optional inconsistent warning; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| home.packages = lib.optional (cfg.package != null) cfg.finalPackage; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| xdg.configFile."hypr/hyprland.conf" = let | ||||||||||||||||||||||||
| combinedSettings = cfg.settings // { | ||||||||||||||||||||||||
| plugin = let | ||||||||||||||||||||||||
| mkEntry = entry: | ||||||||||||||||||||||||
| if lib.types.package.check entry then | ||||||||||||||||||||||||
| "${entry}/lib/lib${entry.pname}.so" | ||||||||||||||||||||||||
| else | ||||||||||||||||||||||||
| entry; | ||||||||||||||||||||||||
| in map mkEntry cfg.plugins; | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| shouldGenerate = cfg.systemdIntegration || cfg.extraConfig != "" | ||||||||||||||||||||||||
| || combinedSettings != { }; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| toHyprconf = attrs: | ||||||||||||||||||||||||
| let | ||||||||||||||||||||||||
| mkSection = n: attrs: '' | ||||||||||||||||||||||||
| ${n} { | ||||||||||||||||||||||||
| ${toHyprconf attrs}} | ||||||||||||||||||||||||
| ''; | ||||||||||||||||||||||||
| mkFields = lib.generators.toKeyValue { listsAsDuplicateKeys = true; }; | ||||||||||||||||||||||||
| sections = lib.filterAttrs (n: v: lib.isAttrs v) attrs; | ||||||||||||||||||||||||
| fields = lib.filterAttrs (n: v: !(lib.isAttrs v)) attrs; | ||||||||||||||||||||||||
| in lib.concatStringsSep "\n" (lib.mapAttrsToList mkSection sections) | ||||||||||||||||||||||||
| + mkFields fields; | ||||||||||||||||||||||||
| in lib.mkIf shouldGenerate { | ||||||||||||||||||||||||
| text = lib.optionalString cfg.systemdIntegration '' | ||||||||||||||||||||||||
| exec-once = ${pkgs.dbus}/bin/dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY HYPRLAND_INSTANCE_SIGNATURE XDG_CURRENT_DESKTOP && systemctl --user start hyprland-session.target | ||||||||||||||||||||||||
| '' + lib.optionalString (combinedSettings != { }) | ||||||||||||||||||||||||
| (toHyprconf combinedSettings) | ||||||||||||||||||||||||
| + lib.optionalString (cfg.extraConfig != "") cfg.extraConfig; | ||||||||||||||||||||||||
| onChange = lib.mkIf (cfg.package != null) '' | ||||||||||||||||||||||||
| ( # execute in subshell so that `shopt` won't affect other scripts | ||||||||||||||||||||||||
| shopt -s nullglob # so that nothing is done if /tmp/hypr/ does not exist or is empty | ||||||||||||||||||||||||
| for instance in /tmp/hypr/*; do | ||||||||||||||||||||||||
| HYPRLAND_INSTANCE_SIGNATURE=''${instance##*/} ${cfg.finalPackage}/bin/hyprctl reload config-only \ | ||||||||||||||||||||||||
| || true # ignore dead instance(s) | ||||||||||||||||||||||||
| done | ||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||
| ''; | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| systemd.user.targets.hyprland-session = lib.mkIf cfg.systemdIntegration { | ||||||||||||||||||||||||
| Unit = { | ||||||||||||||||||||||||
| Description = "Hyprland compositor session"; | ||||||||||||||||||||||||
| Documentation = [ "man:systemd.special(7)" ]; | ||||||||||||||||||||||||
| BindsTo = [ "graphical-session.target" ]; | ||||||||||||||||||||||||
| Wants = [ "graphical-session-pre.target" ]; | ||||||||||||||||||||||||
| After = [ "graphical-session-pre.target" ]; | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| { | ||
| hyprland-simple-config = ./simple-config.nix; | ||
| hyprland-inconsistent-config = ./inconsistent-config.nix; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| { config, lib, ... }: | ||
|
|
||
| { | ||
| wayland.windowManager.hyprland = { | ||
| enable = true; | ||
| package = lib.makeOverridable | ||
| (attrs: config.lib.test.mkStubPackage { name = "hyprland"; }) { }; | ||
| plugins = | ||
| [ "/path/to/plugin1" (config.lib.test.mkStubPackage { name = "foo"; }) ]; | ||
| }; | ||
|
|
||
| test.asserts.warnings.expected = [ | ||
| "You have enabled hyprland.systemdIntegration or listed plugins in hyprland.plugins but do not have any configuration in hyprland.settings or hyprland.extraConfig. This is almost certainly a mistake." | ||
| ]; | ||
| test.asserts.warnings.enable = true; | ||
|
|
||
| nmt.script = '' | ||
| config=home-files/.config/hypr/hyprland.conf | ||
| assertFileExists "$config" | ||
| ''; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| exec-once = /nix/store/00000000000000000000000000000000-dbus/bin/dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY HYPRLAND_INSTANCE_SIGNATURE XDG_CURRENT_DESKTOP && systemctl --user start hyprland-session.target | ||
| decoration { | ||
| col.shadow=rgba(00000099) | ||
| shadow_offset=0 5 | ||
| } | ||
|
|
||
| input { | ||
| touchpad { | ||
| scroll_factor=0.300000 | ||
| } | ||
| accel_profile=flat | ||
| follow_mouse=1 | ||
| kb_layout=ro | ||
| } | ||
| $mod=SUPER | ||
| bindm=$mod, mouse:272, movewindow | ||
| bindm=$mod, mouse:273, resizewindow | ||
| bindm=$mod ALT, mouse:272, resizewindow | ||
| plugin=/path/to/plugin1 | ||
| plugin=/nix/store/00000000000000000000000000000000-foo/lib/libfoo.so | ||
| # window resize | ||
| bind = $mod, S, submap, resize | ||
|
|
||
| submap = resize | ||
| binde = , right, resizeactive, 10 0 | ||
| binde = , left, resizeactive, -10 0 | ||
| binde = , up, resizeactive, 0 -10 | ||
| binde = , down, resizeactive, 0 10 | ||
| bind = , escape, submap, reset | ||
| submap = reset |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| { config, lib, ... }: | ||
|
|
||
| { | ||
| wayland.windowManager.hyprland = { | ||
| enable = true; | ||
| package = lib.makeOverridable | ||
| (attrs: config.lib.test.mkStubPackage { name = "hyprland"; }) { }; | ||
| plugins = | ||
| [ "/path/to/plugin1" (config.lib.test.mkStubPackage { name = "foo"; }) ]; | ||
| settings = { | ||
| decoration = { | ||
| shadow_offset = "0 5"; | ||
| "col.shadow" = "rgba(00000099)"; | ||
| }; | ||
|
|
||
| "$mod" = "SUPER"; | ||
|
|
||
| input = { | ||
| kb_layout = "ro"; | ||
| follow_mouse = 1; | ||
| accel_profile = "flat"; | ||
| touchpad = { scroll_factor = 0.3; }; | ||
| }; | ||
|
|
||
| bindm = [ | ||
| # mouse movements | ||
| "$mod, mouse:272, movewindow" | ||
| "$mod, mouse:273, resizewindow" | ||
| "$mod ALT, mouse:272, resizewindow" | ||
| ]; | ||
| }; | ||
| extraConfig = '' | ||
| # window resize | ||
| bind = $mod, S, submap, resize | ||
|
|
||
| submap = resize | ||
| binde = , right, resizeactive, 10 0 | ||
| binde = , left, resizeactive, -10 0 | ||
| binde = , up, resizeactive, 0 -10 | ||
| binde = , down, resizeactive, 0 10 | ||
| bind = , escape, submap, reset | ||
| submap = reset | ||
| ''; | ||
| }; | ||
|
|
||
| nmt.script = '' | ||
| config=home-files/.config/hypr/hyprland.conf | ||
| assertFileExists "$config" | ||
|
|
||
| normalizedConfig=$(normalizeStorePaths "$config") | ||
| assertFileContent "$normalizedConfig" ${./simple-config.conf} | ||
| ''; | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.