Added conf file for hyprscrolling

This commit is contained in:
2026-02-25 14:12:18 +01:00
parent d8500cde2e
commit 2b4e0a321e
3 changed files with 59 additions and 125 deletions
+6 -75
View File
@@ -1765,60 +1765,20 @@ in
** hyprscrolling ** hyprscrolling
This Nix module integrates the hyprscrolling plugin into a Home-Manager managed Hyprland setup in a declarative and reproducible way. It ensures the plugin is installed, optionally switches Hyprland to the scrolling layout, and renders user-defined plugin settings directly into the Hyprland configuration. The goal is to manage the scrolling workspace behavior entirely from Nix instead of maintaining manual edits inside hyprland.conf. This Nix module integrates the hyprscrolling plugin into a Home-Manager managed Hyprland setup in a declarative and reproducible way. It ensures the plugin is installed, optionally switches Hyprland to the scrolling layout, and renders user-defined plugin settings directly into the Hyprland configuration. The goal is to manage the scrolling workspace behavior entirely from Nix instead of maintaining manual edits inside hyprland.conf.
#+begin_src nix :tangle home/desktop/hyprscrolling.nix :noweb tangle :mkdirp yes #+begin_src nix :tangle home/desktop/hyprscrolling.nix :noweb tangle :mkdirp yes
{ config, lib, pkgs, ... }: { config, lib, pkgs, flakeRoot, ... }:
let let
cfg = config.programs.hyprscrolling; cfg = config.programs.hyprscrolling;
# Render plugin settings into:
# plugin:hyprscrolling {
# key = value
# }
renderValue = v:
if lib.isString v then "\"${v}\""
else if lib.isBool v then (if v then "true" else "false")
else if lib.isInt v || lib.isFloat v then toString v
else if lib.isList v then
"[ " + (lib.concatStringsSep " " (map renderValue v)) + " ]"
else
throw "programs.hyprscrolling.settings: unsupported value type: ${builtins.typeOf v}";
renderSettings = settings:
let
lines = lib.mapAttrsToList (k: v: " ${k} = ${renderValue v}") settings;
in
if settings == { } then ""
else ''
plugin:hyprscrolling {
${lib.concatStringsSep "\n" lines}
}
'';
defaultPluginPkg = (pkgs.hyprlandPlugins.hyprscrolling or null); defaultPluginPkg = (pkgs.hyprlandPlugins.hyprscrolling or null);
# Stable paths (avoid pinning /nix/store/... in your hyprland.conf) # Stable paths (avoid pinning /nix/store/... in your hyprland.conf)
stableSoPath = "/etc/hypr/plugins/libhyprscrolling.so"; stableSoPath = "/etc/hypr/plugins/libhyprscrolling.so";
dropInConfPath = "/etc/hypr/conf.d/90-hyprscrolling.conf"; dropInConfPath = "/etc/hypr/conf.d/90-hyprscrolling.conf";
# Read drop-in config from your repo (flake root)
dropInConf = '' dropInConfSourcePath = flakeRoot + "/assets/conf/desktop/hypr/hyprscrolling.conf";
# Managed by Nix: programs.hyprscrolling dropInConf = builtins.readFile dropInConfSourcePath;
# Load plugin shared object (.so)
plugin = ${stableSoPath}
${lib.optionalString cfg.setAsDefaultLayout ''
general {
layout = scrolling
}
''}
${renderSettings cfg.settings}
${cfg.extraConfig}
'';
in in
{ {
options.programs.hyprscrolling = { options.programs.hyprscrolling = {
enable = lib.mkEnableOption "Hyprland hyprscrolling (scrolling layout) plugin (NixOS-friendly)"; enable = lib.mkEnableOption "Hyprland hyprscrolling (scrolling layout) plugin (NixOS-friendly)";
pluginPackage = lib.mkOption { pluginPackage = lib.mkOption {
type = lib.types.nullOr lib.types.package; type = lib.types.nullOr lib.types.package;
default = defaultPluginPkg; default = defaultPluginPkg;
@@ -1827,35 +1787,12 @@ in
Defaults to pkgs.hyprlandPlugins.hyprscrolling when available. Defaults to pkgs.hyprlandPlugins.hyprscrolling when available.
''; '';
}; };
setAsDefaultLayout = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Whether to set `general { layout = scrolling }` in the generated drop-in config.";
};
settings = lib.mkOption {
type = lib.types.attrs;
default = { };
description = ''
Attribute set rendered into a `plugin:hyprscrolling { ... }` block
in the generated drop-in config.
'';
};
extraConfig = lib.mkOption {
type = lib.types.lines;
default = "";
description = "Extra Hyprland config appended to the generated drop-in config.";
};
# Where we install the generated config snippet (so you can `source = ...` it) # Where we install the generated config snippet (so you can `source = ...` it)
dropInPath = lib.mkOption { dropInPath = lib.mkOption {
type = lib.types.str; type = lib.types.str;
default = dropInConfPath; default = dropInConfPath;
description = "Path to the generated Hyprland drop-in config file (needs to be sourced by your hyprland.conf)."; description = "Path to the Hyprland drop-in config file (needs to be sourced by your hyprland.conf).";
}; };
# Where we install a stable symlink to the plugin .so # Where we install a stable symlink to the plugin .so
stablePluginSoPath = lib.mkOption { stablePluginSoPath = lib.mkOption {
type = lib.types.str; type = lib.types.str;
@@ -1863,7 +1800,6 @@ in
description = "Stable path for the plugin shared object (symlinked to the Nix store)."; description = "Stable path for the plugin shared object (symlinked to the Nix store).";
}; };
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
assertions = [ assertions = [
{ {
@@ -1874,15 +1810,10 @@ in
''; '';
} }
]; ];
# Ensure the plugin is built and available.
environment.systemPackages = [ cfg.pluginPackage ]; environment.systemPackages = [ cfg.pluginPackage ];
# Provide a stable .so path under /etc (no /nix/store hardcoding in hyprland.conf)
environment.etc."hypr/plugins/libhyprscrolling.so".source = environment.etc."hypr/plugins/libhyprscrolling.so".source =
"${cfg.pluginPackage}/lib/libhyprscrolling.so"; "${cfg.pluginPackage}/lib/libhyprscrolling.so";
# Now /etc/hypr/conf.d/90-hyprscrolling.conf is exactly your files contents
# Provide a drop-in config file under /etc.
environment.etc."hypr/conf.d/90-hyprscrolling.conf".text = dropInConf; environment.etc."hypr/conf.d/90-hyprscrolling.conf".text = dropInConf;
}; };
} }
@@ -109,8 +109,10 @@ bind = $mainMod SHIFT, 0, movetoworkspace, 10
bind = $mainMod, mouse_down, workspace, e+1 bind = $mainMod, mouse_down, workspace, e+1
bind = $mainMod, mouse_up, workspace, e-1 bind = $mainMod, mouse_up, workspace, e-1
# bind = $mainMod, period, layoutmsg, move +col bind = $mainMod, period, layoutmsg, move +col
# bind = $mainMod, comma, layoutmsg, swapcol l bind = $mainMod, comma, layoutmsg, swapcol l
bind = $mainMod, S, layoutmsg, togglesplitbind = $mainMod, S, layoutmsg, togglesplit
# Mouse drag # Mouse drag
bindm = $mainMod, mouse:272, movewindow bindm = $mainMod, mouse:272, movewindow
@@ -1,61 +1,62 @@
# hyprscrolling.conf # --------------------------------------------------
# Loaded from: ./assets/conf/desktop/hypr/hyprscrolling.conf # Hyprscrolling scrolling layout with indicators
# # Managed in repo: assets/conf/desktop/hypr/hyprscrolling.conf
# Notes: # --------------------------------------------------
# - These are the documented scrolling-layout knobs and defaults.
# - Keep them here; Home-Manager will source this file from ~/.config/hypr/conf.d/.
######################## # Load plugin (.so is symlinked by Nix module)
# Layout selection plugin = /etc/hypr/plugins/libhyprscrolling.so
########################
# Make scrolling the default layout
general { general {
layout = scrolling layout = scrolling
} }
######################## # --------------------------------------------------
# Scrolling layout config # Plugin configuration
######################## # --------------------------------------------------
scrolling {
# when enabled, a single column on a workspace will always span the entire screen.
fullscreen_on_one_column = true
# the default width of a column, [0.1 - 1.0] plugin:hyprscrolling {
column_width = 0.5
# When a column is focused, what method should be used to bring it into view. # --- Core behaviour ---
# 0 = center, 1 = fit enable = true
focus_fit_method = 0 focus_follows_mouse = true
smooth_scrolling = true
# when a window is focused, should the layout move to bring it into view automatically # --- Gaps & spacing ---
follow_focus = true gaps_in = 6
gaps_out = 16
# when a window is focused, require that at least a given fraction of it is visible # --- Indicators ---
# for focus to follow. Hard input (e.g. binds, clicks) will always follow. [0.0 - 1.0] # Show visual indicators for stacked windows
follow_min_visible = 0.4 indicators = true
# A comma-separated list of preconfigured widths for colresize +conf/-conf # Style of indicators (examples: line, dots, bar)
explicit_column_widths = 0.333, 0.5, 0.667, 1.0 indicator_style = bar
# Direction in which new windows appear and the layout scrolls. left/right/down/up # Thickness / size
direction = right indicator_thickness = 4
# Spacing between indicators
indicator_spacing = 6
# Offset from window edge
indicator_offset = 8
# Colors (RGBA)
indicator_color_active = rgba(137, 180, 250, 0.9) # blue-ish (Catppuccin style)
indicator_color_inactive = rgba(88, 91, 112, 0.6)
# Position (top, bottom, left, right)
indicator_position = bottom
} }
######################## # --------------------------------------------------
# Workspace rules (optional examples) # Optional keybinds
######################## # --------------------------------------------------
# workspace = 2, layoutopt:direction:right
######################## # Scroll through stack
# Layout messages (optional examples) bind = SUPER, mouse_down, layoutmsg, scroll +1
######################## bind = SUPER, mouse_up, layoutmsg, scroll -1
# bind = $mainMod, period, layoutmsg, move +col
# bind = $mainMod, comma, layoutmsg, swapcol l # Toggle layout manually
# bind = SUPER, S, layoutmsg, togglesplit
# Available layoutmsg params:
# - move (-200 / +200) or (+col / -col)
# - colresize (0.5 / +0.2 / -0.2 / +conf / -conf / all (number))
# - fit (active / visible / all / toend / tobeg)
# - focus (l/r/u/d) (wraps instead of moving to neighboring monitors)
# - promote (moves a window to its own new column)
# - swapcol (l or r) (wraps around)
# - togglefit (toggles focus_fit_method)