user services + wm in hjr, some qs workaround

This commit is contained in:
atagen 2025-10-29 12:27:35 +11:00
parent 9e3aa574eb
commit cb44e16d76
19 changed files with 393 additions and 361 deletions

View file

@ -1,122 +1,137 @@
_: { }
# TODO rewrite this with hjem-rum
# {
# pkgs,
# lib,
# config,
# inputs,
# scope,
# ...
# }:
# let
# inherit (lib)
# range
# nameValuePair
# mapAttrs'
# mergeAttrsList
# ;
# inherit (builtins) listToAttrs replaceStrings;
# inherit (config.hm.lib.niri) actions;
# hBinds = {
# H = "left";
# L = "right";
# };
# vBinds = {
# J = "down";
# K = "up";
# };
# makeDirBind =
# mods: cmd: keys:
# mapAttrs' (
# key: dir:
# nameValuePair "${mods}+${key}" {
# action = actions."${replaceStrings [ "$DIR" ] [ "${dir}" ] "${cmd}"}";
# }
# ) keys;
# makeWsBind =
# mods: cmd:
# listToAttrs (
# map (num: {
# name = "${mods}+${builtins.toString num}";
# value = {
# action."${cmd}" = num;
# };
# }) (range 1 6)
# );
# tagctl = lib.getExe' inputs.niri-tag.packages.${pkgs.system}.unstable "tagctl";
# makeTagBind =
# mods: cmd:
# listToAttrs (
# map (num: {
# name = "${mods}+${builtins.toString num}";
# value = {
# action.spawn = [
# tagctl
# cmd
# (builtins.toString num)
# ];
# };
# }) (range 1 6)
# );
# in
# scope "hm.programs.niri.settings" {
# binds = mergeAttrsList [
# {
# "Mod+D".action.spawn = [
# "qs"
# "ipc"
# "call"
# "launch"
# "toggle"
# ];
# "Mod+F".action.spawn = "firefox";
# "Mod+E".action.spawn = "nautilus";
# "Mod+Return".action.spawn = "foot";
# "Mod+Shift+E".action.spawn = "wlogout";
# "Mod+Equal".action.spawn = "bitwarden";
# "Mod+Shift+Q".action = actions.close-window;
# "Mod+Shift+S".action = actions.screenshot;
# "Mod+R".action = actions.switch-preset-column-width;
# "Mod+Shift+R".action = actions.maximize-column;
# "XF86AudioRaiseVolume".action.spawn = [
# "volumectl"
# "-u"
# "up"
# ];
# "XF86AudioLowerVolume".action.spawn = [
# "volumectl"
# "-u"
# "down"
# ];
# "XF86AudioMute".action.spawn = [
# "volumectl"
# "toggle-mute"
# ];
# "XF86AudioStop".action.spawn = [
# "playerctl"
# "stop"
# ];
# "XF86AudioPlay".action.spawn = [
# "playerctl"
# "play-pause"
# ];
# "XF86AudioNext".action.spawn = [
# "playerctl"
# "next"
# ];
# "XF86AudioPrev".action.spawn = [
# "playerctl"
# "previous"
# ];
# "Mod+Space".action = actions.toggle-window-floating;
# }
# (makeDirBind "Mod" "focus-window-$DIR" vBinds)
# (makeDirBind "Mod" "focus-column-or-monitor-$DIR" hBinds)
# (makeDirBind "Mod+Shift" "move-column-$DIR-or-to-monitor-$DIR" hBinds)
# (makeDirBind "Mod+Ctrl" "consume-or-expel-window-$DIR" hBinds)
# (makeDirBind "Mod+Ctrl" "move-window-$DIR" vBinds)
# (makeTagBind "Mod" "toggle-tag")
# (makeTagBind "Mod+Shift" "toggle")
# (makeTagBind "Mod+Ctrl" "exclusive-tag")
# ];
# }
{
lib,
config,
scope,
...
}:
let
inherit (lib)
range
nameValuePair
mapAttrs'
mergeAttrsList
;
inherit (builtins) listToAttrs replaceStrings;
hBinds = {
H = "left";
L = "right";
};
vBinds = {
J = "down";
K = "up";
};
makeDirBind =
mods: cmd: keys:
mapAttrs' (
key: dir:
nameValuePair "${mods}+${key}" {
action = "${replaceStrings [ "$DIR" ] [ "${dir}" ] "${cmd}"}";
}
) keys;
makeTagBind =
mods: cmd:
listToAttrs (
map (num: {
name = "${mods}+${builtins.toString (lib.mod num 10)}";
value = {
spawn = [
"tagctl"
cmd
(builtins.toString num)
];
};
}) (range 1 10)
);
getApp = app: lib.singleton (lib.getExe config.apps.${app});
in
scope "user.desktops.niri.binds"
<| mergeAttrsList [
{
"Mod+Grave".action = "focus-monitor-next";
"Mod+Shift+Grave".action = "move-column-to-monitor-next";
"Mod+Minus".spawn = [
"tagctl"
"toggle-tag"
"99"
];
"Mod+Equal".spawn = [
"tagctl"
"toggle-tag"
"101"
];
"Mod+D".spawn = [
"qs"
"ipc"
"call"
"launch"
"toggle"
];
"Mod+F".spawn = (getApp "browser");
"Mod+E".spawn = (getApp "fm");
"Mod+Return".spawn = (getApp "terminal");
"Mod+Shift+E".spawn = [
"qs"
"ipc"
"call"
"logout"
"toggle"
];
# "Mod+Equal".spawn = (getAppName "passwordManager"); # niri-tag needs proper scratchpads smh
"Mod+Shift+Q".action = "close-window";
"Mod+Shift+S".action = "screenshot";
"Mod+R".action = "switch-preset-column-width";
"Mod+Shift+R".action = "maximize-column";
"XF86AudioLowerVolume".spawn = [
"volumectl"
"-u"
"down"
];
"XF86AudioMute".spawn = [
"volumectl"
"toggle-mute"
];
"XF86AudioNext".spawn = [
"playerctl"
"next"
];
"XF86AudioPlay".spawn = [
"playerctl"
"play-pause"
];
"XF86AudioPrev".spawn = [
"playerctl"
"previous"
];
"XF86AudioRaiseVolume".spawn = [
"volumectl"
"-u"
"up"
];
"XF86AudioStop".spawn = [
"playerctl"
"stop"
];
"XF86MonBrightnessUp".spawn = [
"brightnessctl"
"s"
"5%+"
];
"XF86MonBrightnessDown".spawn = [
"brightnessctl"
"s"
"5%-"
];
"Mod+Space".action = "switch-focus-between-floating-and-tiling";
"Mod+Shift+Space".action = "toggle-window-floating";
"Mod+Ctrl+Space".action = "fullscreen-window";
"Mod+C".action = "center-window";
}
(makeDirBind "Mod" "focus-window-$DIR" vBinds)
(makeDirBind "Mod" "focus-column-or-monitor-$DIR" hBinds)
(makeDirBind "Mod+Shift" "consume-or-expel-window-$DIR" hBinds)
(makeDirBind "Mod+Ctrl" "move-column-$DIR-or-to-monitor-$DIR" hBinds)
(makeDirBind "Mod+Ctrl" "move-window-$DIR" vBinds)
(makeTagBind "Mod" "toggle-tag")
(makeTagBind "Mod+Shift" "toggle")
(makeTagBind "Mod+Ctrl" "exclusive-tag")
]

View file

@ -22,7 +22,8 @@ let
Status = "locked";
};
in
scope "programs.firefox" {
(scope "apps.browser" <| pkgs.firefox)
// scope "programs.firefox" {
enable = true;
policies = {

View file

@ -0,0 +1,55 @@
input {
keyboard {
xkb {
layout ""
model ""
rules ""
variant ""
}
repeat-delay 600
repeat-rate 25
track-layout "global"
}
mouse {
accel-profile "flat"
}
warp-mouse-to-focus
focus-follows-mouse
}
screenshot-path "~/screenshots/%Y-%m-%d_%H-%M-%S.png"
prefer-no-csd
layout {
gaps %GAPS%
struts {
left 0
right 0
top 0
bottom 0
}
focus-ring {
width %BORDER%
active-color "%ACTIVE%"
inactive-color "%INACTIVE%"
}
border { off; }
default-column-width { proportion 0.500000; }
preset-column-widths {
proportion 0.666667
proportion 0.500000
proportion 0.333333
}
center-focused-column "never"
always-center-single-column
}
cursor {
xcursor-theme "%CURSOR%"
xcursor-size 16
hide-when-typing
hide-after-inactive-ms 5000
}
hotkey-overlay { skip-at-startup; }
window-rule {
geometry-corner-radius 0.000000 %ROUNDING%.000000 0.000000 %ROUNDING%.000000
clip-to-geometry true
}
xwayland-satellite { path "%SATELLITE%"; }

View file

@ -6,7 +6,7 @@ import Quickshell.Io
Singleton {
id: data
property var tags: {}
property var tags: ({})
property var keys: []
Timer {
id: reconnectTimer

View file

@ -9,17 +9,20 @@
}:
let
inherit (lib) getExe getExe';
stable = inputs.nixpkgs-stable;
inherit (stable.legacyPackages.x86_64-linux) quickshell;
in
{
# quickshell stuff
user.packages = getPkgs {
# quickshell stuff
inherit (pkgs.kdePackages) qtbase qtdeclarative;
inherit (pkgs) wl-clipboard quickshell;
inherit (pkgs) wl-clipboard;
inherit quickshell;
};
quick.services = {
swaync = "${getExe pkgs.swaynotificationcenter}";
quickshell = "${getExe pkgs.quickshell}";
quickshell = "${getExe quickshell}";
swayidle =
let
niri = getFlakePkg' inputs.niri "niri-unstable";

74
graphical/desktop/wm.nix Normal file
View file

@ -0,0 +1,74 @@
{
mainUser,
inputs,
getFlakePkg',
lib,
config,
...
}:
let
niri = (getFlakePkg' inputs.niri "niri-unstable");
xwayland-satellite = (getFlakePkg' inputs.niri "xwayland-satellite-unstable");
inherit (config) rice;
in
{
imports = [
inputs.niri.nixosModules.niri
inputs.niri-tag.nixosModules.niri-tag
];
user.desktops.niri = {
enable = true;
config =
let
template = builtins.readFile ./niri.kdl;
baseConfig =
with rice;
lib.replaceStrings
[
"%CURSOR%"
"%ROUNDING%"
"%GAPS%"
"%BORDER%"
"%ACTIVE%"
"%INACTIVE%"
"%SATELLITE%"
]
[
cursor.name
(toString borders.rounding)
(toString borders.gaps)
(toString borders.thickness)
palette.shortHex.bright.yellow
palette.shortHex.normal.yellow
(lib.getExe xwayland-satellite)
]
template;
in
baseConfig;
};
user.packages = [
niri
xwayland-satellite
];
services.greetd = {
enable = true;
restart = false;
settings =
let
session = {
command = "niri-session";
user = "${mainUser}";
};
in
{
default_session = session;
initial_session = session;
};
};
programs.niri = {
enable = true;
package = niri;
};
services.niri-tag.enable = true;
}

View file

@ -8,7 +8,7 @@
scope "user" {
programs = {
direnv = {
enable = false;
enable = true;
integrations.fish.enable = true;
};
@ -19,15 +19,12 @@ scope "user" {
name = "atagen";
email = "boss@atagen.co";
};
# merge = {
# conflictstyle = "diff3";
# };
init = {
defaultBranch = "main";
};
url = {
"https://github.com/".insteadOf = "github:";
"https://git.atagen.co/".insteadOf = "atagen:";
"https://git.atagen.co/atagen".insteadOf = "atagen:";
"https://codeberg.org/".insteadOf = "codeberg:";
};
credential.helper = "rbw";

View file

@ -7,7 +7,7 @@
qt = {
enable = true;
style = "adwaita-dark";
# platformTheme = "gnome";
# platformTheme = "gnome"; # broken in unstable ?
};
user.misc.gtk =

View file

@ -2,60 +2,57 @@
config,
lib,
mainUser,
scope,
...
}:
{
options = {
quick = {
services =
with lib;
mkOption {
type = with types; attrsOf str;
default = { };
};
oneShots =
with lib;
mkOption {
type = with types; attrsOf str;
default = { };
};
scope "options.quick" {
services =
with lib;
mkOption {
type = with types; attrsOf str;
default = { };
};
oneShots =
with lib;
mkOption {
type = with types; attrsOf str;
default = { };
};
};
config = {
systemd.user.services =
builtins.mapAttrs (name: cmd: {
environment.PATH = lib.mkForce "/run/current-system/sw/bin:/run/current-system/sw/sbin:/etc/profiles/per-user/${mainUser}/bin:/etc/profiles/per-user/${mainUser}/sbin";
unitConfig = {
Description = "${name}";
Requires = [
"graphical-session.target"
];
After = [
"graphical-session.target"
"niri.target"
];
PartOf = [ "graphical-session.target" ];
};
serviceConfig = {
ExecStart = cmd;
};
wantedBy = [ "graphical-session.target" ];
}) config.quick.services
// builtins.mapAttrs (name: cmd: {
unitConfig = {
Description = "${name}";
Requires = [ "graphical-session.target" ];
After = [
"graphical-session.target"
"niri.target"
];
};
serviceConfig = {
ExecStart = cmd;
Type = "oneshot";
};
wantedBy = [ "graphical-session.target" ];
}) config.quick.oneShots;
};
}
// scope "config.user.systemd" {
enable = true;
services =
builtins.mapAttrs (name: cmd: {
environment.PATH = lib.mkForce "/run/current-system/sw/bin:/run/current-system/sw/sbin:/etc/profiles/per-user/${mainUser}/bin:/etc/profiles/per-user/${mainUser}/sbin";
unitConfig = {
Description = "${name}";
Requires = [
"graphical-session.target"
];
After = [
"graphical-session.target"
"niri.target"
];
PartOf = [ "graphical-session.target" ];
};
serviceConfig = {
ExecStart = cmd;
};
wantedBy = [ "graphical-session.target" ];
}) config.quick.services
// builtins.mapAttrs (name: cmd: {
unitConfig = {
Description = "${name}";
Requires = [ "graphical-session.target" ];
After = [
"graphical-session.target"
"niri.target"
];
};
serviceConfig = {
ExecStart = cmd;
Type = "oneshot";
};
wantedBy = [ "graphical-session.target" ];
}) config.quick.oneShots;
}

View file

@ -36,9 +36,9 @@
};
borders = {
thickness = 6;
rounding = 0;
gaps = 48;
thickness = 4;
rounding = 10;
gaps = 64;
};
bg = {
@ -59,7 +59,7 @@
plymouth = {
theme = "starship";
font = "${config.rice.fonts.sans.package}/share/fonts/truetype/InriaSans-Regular.ttf";
font = "${config.rice.fonts.sans.package}/share/fonts/truetype/MSW98UI-Regular.ttf";
themePackages = [
inputs.hudcore.packages.${pkgs.system}.default
];

View file

@ -1,112 +0,0 @@
{
mainUser,
inputs,
getFlakePkg',
# config,
...
}:
let
# inherit (config) rice;
niri = (getFlakePkg' inputs.niri "niri-unstable");
xwayland-satellite = (getFlakePkg' inputs.niri "xwayland-satellite-unstable");
in
{
imports = [
inputs.niri.nixosModules.niri
inputs.niri-tag.nixosModules.niri-tag
];
# user.desktops.niri = {
# enable = true;
# configFile = ./desktop/niri-config.kdl;
# };
environment.files."/home/${mainUser}/.config/niri/config.kdl" = {
uid = 1000;
gid = 100;
source = "/home/${mainUser}/.nix/graphical/desktop/niri-config.kdl";
};
# user.xdg.config.files."niri/config.kdl".source = ./desktop/niri-config.kdl;
user.packages = [
niri
xwayland-satellite
];
services.greetd = {
enable = true;
restart = false;
settings =
let
session = {
command = "niri-session";
user = "${mainUser}";
};
in
{
default_session = session;
initial_session = session;
};
};
programs.niri = {
enable = true;
package = niri;
};
services.niri-tag.enable = true;
}
# old hm config, TODO template from this
# {
# values = {
# input = {
# warp-mouse-to-focus.enable = true;
# };
# cursor = {
# hide-after-inactive-ms = 5000;
# hide-when-typing = true;
# size = 16;
# theme = rice.cursor.name;
# };
# layout = {
# always-center-single-column = true;
# gaps = config.rice.borders.gaps;
# default-column-width.proportion = 0.5;
# preset-column-widths = map (p: { proportion = p; }) [
# (2.0 / 3.0)
# 0.5
# (1.0 / 3.0)
# ];
# focus-ring =
# let
# pal = rice.palette.hex;
# in
# {
# active = {
# color = pal.bright.yellow;
# };
# inactive = {
# color = pal.normal.black;
# };
# };
# };
# prefer-no-csd = true;
# hotkey-overlay.skip-at-startup = true;
# window-rules =
# let
# v = 10.0;
# in
# [
# {
# geometry-corner-radius = {
# bottom-left = v;
# bottom-right = 0.0;
# top-left = 0.0;
# top-right = v;
# };
# clip-to-geometry = true;
# }
# ];
# xwayland-satellite = {
# enable = true;
# path = lib.getExe inputs.niri.packages.${pkgs.system}.xwayland-satellite-unstable;
# };
# };
# }
#