new wm, hyprland gone
This commit is contained in:
parent
003f37bfbd
commit
cb4b22b4e5
41 changed files with 1145 additions and 1364 deletions
421
modules/desktop/niri.nix
Normal file
421
modules/desktop/niri.nix
Normal file
|
@ -0,0 +1,421 @@
|
|||
{ inputs, lib, config, system, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.modules.desktop.niri;
|
||||
in {
|
||||
options.modules.desktop.niri = {
|
||||
enable = mkEnableOption "Enable niri, a scrolling wayland compositor";
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.niri-unstable;
|
||||
example = "pkgs.niri";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.displayManager.sessionPackages = [ cfg.package ];
|
||||
|
||||
programs.niri = {
|
||||
enable = true;
|
||||
package = cfg.package;
|
||||
};
|
||||
|
||||
systemd.user.services.niri-flake-polkit.enable = false; # niri-flake has its own polkit agent, disable it
|
||||
|
||||
hm.programs.niri = {
|
||||
package = cfg.package;
|
||||
settings = let
|
||||
allCorners = r: { bottom-left = r; bottom-right = r; top-left = r; top-right = r; };
|
||||
in {
|
||||
input = {
|
||||
power-key-handling.enable = false;
|
||||
focus-follows-mouse.enable = true;
|
||||
focus-follows-mouse.max-scroll-amount = "0%";
|
||||
|
||||
# TODO: uhm?? why do i have to do this here. should be automatic from libinput
|
||||
# whatever. ill just hardcode for now
|
||||
touchpad = {
|
||||
click-method = "button-areas";
|
||||
tap = true;
|
||||
natural-scroll = true;
|
||||
};
|
||||
|
||||
mouse = {
|
||||
accel-profile = "flat";
|
||||
};
|
||||
};
|
||||
|
||||
clipboard = {
|
||||
disable-primary = true;
|
||||
};
|
||||
|
||||
cursor = {
|
||||
theme = config.modules.desktop.themes.cursorTheme.name;
|
||||
size = config.modules.desktop.themes.cursorTheme.size;
|
||||
};
|
||||
|
||||
environment = {
|
||||
DISPLAY = ":0";
|
||||
};
|
||||
|
||||
prefer-no-csd = true;
|
||||
|
||||
layout = {
|
||||
gaps = 6;
|
||||
|
||||
center-focused-column = "on-overflow";
|
||||
|
||||
focus-ring = {
|
||||
enable = false;
|
||||
width = 1;
|
||||
active.color = config.modules.desktop.themes.niri.accent;
|
||||
inactive.color = config.modules.desktop.themes.niri.inactive;
|
||||
};
|
||||
|
||||
border = {
|
||||
enable = true;
|
||||
width = 1;
|
||||
active.color = config.modules.desktop.themes.niri.accent;
|
||||
inactive.color = config.modules.desktop.themes.niri.inactive;
|
||||
};
|
||||
|
||||
shadow = {
|
||||
enable = true;
|
||||
# TODO: remove this?
|
||||
# this is a way to make the shadow appear on rounded corners
|
||||
# see: https://github.com/YaLTeR/niri/blob/e251ca7340bc71870c3a81a7ffc3d9bde58e685a/resources/default-config.kdl#L201
|
||||
draw-behind-window = true;
|
||||
offset.x = 0;
|
||||
offset.y = 0;
|
||||
softness = 30;
|
||||
spread = 2;
|
||||
color = config.modules.desktop.themes.niri.shadow;
|
||||
};
|
||||
};
|
||||
|
||||
hotkey-overlay.skip-at-startup = true;
|
||||
|
||||
screenshot-path = null;
|
||||
|
||||
animations = {
|
||||
shaders.window-resize = ''
|
||||
vec4 resize_color(vec3 coords_curr_geo, vec3 size_curr_geo) {
|
||||
vec3 coords_next_geo = niri_curr_geo_to_next_geo * coords_curr_geo;
|
||||
|
||||
vec3 coords_stretch = niri_geo_to_tex_next * coords_curr_geo;
|
||||
vec3 coords_crop = niri_geo_to_tex_next * coords_next_geo;
|
||||
|
||||
// We can crop if the current window size is smaller than the next window
|
||||
// size. One way to tell is by comparing to 1.0 the X and Y scaling
|
||||
// coefficients in the current-to-next transformation matrix.
|
||||
bool can_crop_by_x = niri_curr_geo_to_next_geo[0][0] <= 1.0;
|
||||
bool can_crop_by_y = niri_curr_geo_to_next_geo[1][1] <= 1.0;
|
||||
|
||||
vec3 coords = coords_stretch;
|
||||
if (can_crop_by_x)
|
||||
coords.x = coords_crop.x;
|
||||
if (can_crop_by_y)
|
||||
coords.y = coords_crop.y;
|
||||
|
||||
vec4 color = texture2D(niri_tex_next, coords.st);
|
||||
|
||||
// However, when we crop, we also want to crop out anything outside the
|
||||
// current geometry. This is because the area of the shader is unspecified
|
||||
// and usually bigger than the current geometry, so if we don't fill pixels
|
||||
// outside with transparency, the texture will leak out.
|
||||
//
|
||||
// When stretching, this is not an issue because the area outside will
|
||||
// correspond to client-side decoration shadows, which are already supposed
|
||||
// to be outside.
|
||||
if (can_crop_by_x && (coords_curr_geo.x < 0.0 || 1.0 < coords_curr_geo.x))
|
||||
color = vec4(0.0);
|
||||
if (can_crop_by_y && (coords_curr_geo.y < 0.0 || 1.0 < coords_curr_geo.y))
|
||||
color = vec4(0.0);
|
||||
|
||||
return color;
|
||||
}
|
||||
'';
|
||||
|
||||
window-close = {
|
||||
easing = {
|
||||
curve = "linear";
|
||||
duration-ms = 600;
|
||||
};
|
||||
};
|
||||
shaders.window-close = ''
|
||||
vec4 fall_and_rotate(vec3 coords_geo, vec3 size_geo) {
|
||||
float progress = niri_clamped_progress * niri_clamped_progress;
|
||||
vec2 coords = (coords_geo.xy - vec2(0.5, 1.0)) * size_geo.xy;
|
||||
coords.y -= progress * 1440.0;
|
||||
float random = (niri_random_seed - 0.5) / 2.0;
|
||||
random = sign(random) - random;
|
||||
float max_angle = 0.5 * random;
|
||||
float angle = progress * max_angle;
|
||||
mat2 rotate = mat2(cos(angle), -sin(angle), sin(angle), cos(angle));
|
||||
coords = rotate * coords;
|
||||
coords_geo = vec3(coords / size_geo.xy + vec2(0.5, 1.0), 1.0);
|
||||
vec3 coords_tex = niri_geo_to_tex * coords_geo;
|
||||
vec4 color = texture2D(niri_tex, coords_tex.st);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
vec4 close_color(vec3 coords_geo, vec3 size_geo) {
|
||||
return fall_and_rotate(coords_geo, size_geo);
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
window-rules = [
|
||||
{
|
||||
geometry-corner-radius = allCorners 10.0;
|
||||
clip-to-geometry = true;
|
||||
}
|
||||
{
|
||||
matches = [
|
||||
{ app-id = "^org\.wezfurlong\.wezterm$"; }
|
||||
];
|
||||
# see earlier shadow config; this is here because it's a transparent window, special case
|
||||
shadow.draw-behind-window = false;
|
||||
}
|
||||
{
|
||||
matches = [
|
||||
{ app-id = "^gcr-prompter$"; }
|
||||
{ app-id = "^.*pinentry-.*$"; }
|
||||
{ app-id = "^polkit-.*$"; }
|
||||
{ app-id = "^org.gnome.seahorse.Application$"; }
|
||||
];
|
||||
block-out-from = "screen-capture";
|
||||
}
|
||||
{
|
||||
matches = [
|
||||
{ app-id = "^gcr-prompter$"; }
|
||||
{ app-id = "^.*pinentry-.*$"; }
|
||||
{ app-id = "^polkit-.*$"; }
|
||||
{ app-id = "^org\.gnome\.Loupe$"; }
|
||||
{ title = "^Open Folder$"; }
|
||||
{ title = "^Open Files$"; }
|
||||
{ title = "^Open File$"; }
|
||||
{ title = "^Open$"; }
|
||||
{ title = "^Save$"; }
|
||||
{ title = "^Save As$"; }
|
||||
];
|
||||
open-floating = true;
|
||||
focus-ring = {
|
||||
enable = true;
|
||||
width = 4000;
|
||||
active.color = "${config.modules.desktop.themes.niri.shadow}65";
|
||||
inactive.color = "${config.modules.desktop.themes.niri.shadow}65";
|
||||
};
|
||||
}
|
||||
{
|
||||
matches = [
|
||||
{ app-id = "firefox$"; title = "^Picture-in-Picture$"; }
|
||||
{ title = "^Picture in picture$"; }
|
||||
{ title = "^Discord Popout$"; }
|
||||
];
|
||||
open-floating = true;
|
||||
default-floating-position = {
|
||||
x = 15;
|
||||
y = 15;
|
||||
relative-to = "top-right";
|
||||
};
|
||||
}
|
||||
{
|
||||
matches = [
|
||||
{ app-id = "^gcr-prompter$"; }
|
||||
{ app-id = "^.*pinentry-.*$"; }
|
||||
{ app-id = "^polkit-.*$"; }
|
||||
{ app-id = "^file-roller$"; }
|
||||
{ app-id = "^org\.gnome\.FileRoller$"; }
|
||||
{ app-id = "^org\.gnome\.Loupe$"; }
|
||||
{ title = "^Open Folder$"; }
|
||||
{ title = "^Open Files$"; }
|
||||
{ title = "^Open File$"; }
|
||||
{ title = "^Open$"; }
|
||||
{ title = "^Save$"; }
|
||||
{ title = "^Save As$"; }
|
||||
];
|
||||
open-floating = true;
|
||||
default-column-width.proportion = 0.6;
|
||||
default-window-height.proportion = 0.8;
|
||||
}
|
||||
];
|
||||
|
||||
layer-rules = [
|
||||
{
|
||||
matches = [
|
||||
{ namespace = "^notifications$"; }
|
||||
{ namespace = "^rofi$"; } # a bit silly, but we use rofi for clipboard history
|
||||
];
|
||||
block-out-from = "screencast";
|
||||
}
|
||||
{
|
||||
matches = [
|
||||
{ namespace = "^launcher$"; }
|
||||
{ namespace = "^notifications$"; }
|
||||
{ namespace = "^rofi$"; }
|
||||
{ namespace = "^waybar$"; }
|
||||
{ namespace = "^wob$"; }
|
||||
];
|
||||
shadow = {
|
||||
enable = true;
|
||||
};
|
||||
}
|
||||
{
|
||||
matches = [
|
||||
{ namespace = "^launcher$"; }
|
||||
{ namespace = "^wob$"; }
|
||||
];
|
||||
# see earlier shadow config; this is here because it's a transparent window, special case
|
||||
shadow.draw-behind-window = false;
|
||||
}
|
||||
];
|
||||
|
||||
binds = with config.hm.lib.niri.actions; let
|
||||
sh = spawn "sh" "-c";
|
||||
in {
|
||||
"Mod+Shift+Slash".action = show-hotkey-overlay;
|
||||
|
||||
"Mod+D".action = spawn "fuzzel";
|
||||
|
||||
"Mod+Q".action = close-window;
|
||||
|
||||
"Mod+H".action = toggle-window-floating;
|
||||
"Mod+Shift+H".action = switch-focus-between-floating-and-tiling;
|
||||
|
||||
"Mod+Left".action = focus-column-left;
|
||||
"Mod+Down".action = focus-window-down;
|
||||
"Mod+Up".action = focus-window-up;
|
||||
"Mod+Right".action = focus-column-right;
|
||||
|
||||
"Mod+Shift+Left".action = move-column-left;
|
||||
"Mod+Shift+Down".action = move-window-down;
|
||||
"Mod+Shift+Up".action = move-window-up;
|
||||
"Mod+Shift+Right".action = move-column-right;
|
||||
|
||||
"Mod+Ctrl+Left".action = focus-monitor-left;
|
||||
"Mod+Ctrl+Down".action = focus-monitor-down;
|
||||
"Mod+Ctrl+Up".action = focus-monitor-up;
|
||||
"Mod+Ctrl+Right".action = focus-monitor-right;
|
||||
|
||||
"Mod+Home".action = focus-column-first;
|
||||
"Mod+End".action = focus-column-last;
|
||||
"Mod+Shift+Home".action = move-column-to-first;
|
||||
"Mod+Shift+End".action = move-column-to-last;
|
||||
|
||||
"Mod+Page_Down".action = focus-workspace-down;
|
||||
"Mod+Page_Up".action = focus-workspace-up;
|
||||
|
||||
"Mod+Shift+Page_Down".action = move-column-to-workspace-down;
|
||||
"Mod+Shift+Page_Up".action = move-column-to-workspace-up;
|
||||
|
||||
"Mod+Ctrl+Page_Down".action = move-workspace-down;
|
||||
"Mod+Ctrl+Page_Up".action = move-workspace-up;
|
||||
|
||||
"Mod+1".action = focus-workspace 1;
|
||||
"Mod+2".action = focus-workspace 2;
|
||||
"Mod+3".action = focus-workspace 3;
|
||||
"Mod+4".action = focus-workspace 4;
|
||||
"Mod+5".action = focus-workspace 5;
|
||||
"Mod+6".action = focus-workspace 6;
|
||||
"Mod+7".action = focus-workspace 7;
|
||||
"Mod+8".action = focus-workspace 8;
|
||||
"Mod+9".action = focus-workspace 9;
|
||||
"Mod+0".action = focus-workspace 10;
|
||||
"Mod+Shift+1".action = move-column-to-workspace 1;
|
||||
"Mod+Shift+2".action = move-column-to-workspace 2;
|
||||
"Mod+Shift+3".action = move-column-to-workspace 3;
|
||||
"Mod+Shift+4".action = move-column-to-workspace 4;
|
||||
"Mod+Shift+5".action = move-column-to-workspace 5;
|
||||
"Mod+Shift+6".action = move-column-to-workspace 6;
|
||||
"Mod+Shift+7".action = move-column-to-workspace 7;
|
||||
"Mod+Shift+8".action = move-column-to-workspace 8;
|
||||
"Mod+Shift+9".action = move-column-to-workspace 9;
|
||||
"Mod+Shift+0".action = move-column-to-workspace 10;
|
||||
|
||||
"Mod+Comma".action = consume-window-into-column;
|
||||
"Mod+Period".action = expel-window-from-column;
|
||||
|
||||
"Mod+BracketLeft".action = consume-or-expel-window-left;
|
||||
"Mod+BracketRight".action = consume-or-expel-window-right;
|
||||
|
||||
"Mod+R".action = switch-preset-column-width;
|
||||
"Mod+Shift+R".action = switch-preset-window-height;
|
||||
"Mod+Ctrl+R".action = reset-window-height;
|
||||
"Mod+F".action = maximize-column;
|
||||
"Mod+Shift+F".action = fullscreen-window;
|
||||
"Mod+C".action = center-column;
|
||||
|
||||
"Mod+Minus".action = set-column-width "-10%";
|
||||
"Mod+Equal".action = set-column-width "+10%";
|
||||
|
||||
"Mod+Shift+Minus".action = set-window-height "-10%";
|
||||
"Mod+Shift+Equal".action = set-window-height "+10%";
|
||||
|
||||
"Print".action = screenshot;
|
||||
|
||||
"Mod+Shift+E".action = quit;
|
||||
|
||||
"XF86AudioMicMute".action = spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SOURCE@" "toggle";
|
||||
"XF86AudioMicMute".allow-when-locked = true;
|
||||
|
||||
"XF86LaunchA".action = screenshot;
|
||||
"XF86LaunchB".action = sh "${lib.getExe pkgs.rofi-rbw-wayland} -a copy -t password --clear-after 20";
|
||||
"XF86ScreenSaver".action = sh "${pkgs.systemd}/bin/loginctl lock-session";
|
||||
|
||||
# substitutions for when not on laptop
|
||||
"Mod+Shift+S".action = screenshot;
|
||||
"Mod+Shift+P".action = sh "${lib.getExe pkgs.rofi-rbw-wayland} -a copy -t password --clear-after 20";
|
||||
"Mod+L".action = sh "${pkgs.systemd}/bin/loginctl lock-session";
|
||||
|
||||
"Mod+T".action = spawn "wezterm";
|
||||
"Mod+E".action = spawn "nautilus";
|
||||
|
||||
"XF86AudioPrev".action = sh "${lib.getExe pkgs.playerctl} previous";
|
||||
"XF86AudioPlay".action = sh "${lib.getExe pkgs.playerctl} play-pause";
|
||||
"XF86AudioNext".action = sh "${lib.getExe pkgs.playerctl} next";
|
||||
|
||||
"Mod+V".action = sh "${config.modules.desktop.cliphist.summonScript}";
|
||||
|
||||
"Mod+Shift+Control+T".action = toggle-debug-tint;
|
||||
"Mod+Shift+Control+O".action = debug-toggle-opaque-regions;
|
||||
"Mod+Shift+Control+D".action = debug-toggle-damage;
|
||||
} // (if config.modules.desktop.wob.enable then let
|
||||
wobSock = config.modules.desktop.wob.sockPath;
|
||||
in {
|
||||
"XF86AudioRaiseVolume".action = sh "wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+ && wpctl get-volume @DEFAULT_AUDIO_SINK@ | sed 's/[^0-9]//g' > ${wobSock}";
|
||||
"XF86AudioRaiseVolume".allow-when-locked = true;
|
||||
"XF86AudioLowerVolume".action = sh "wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%- && wpctl get-volume @DEFAULT_AUDIO_SINK@ | sed 's/[^0-9]//g' > ${wobSock}";
|
||||
"XF86AudioLowerVolume".allow-when-locked = true;
|
||||
"XF86AudioMute".action = sh "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle && (wpctl get-volume @DEFAULT_AUDIO_SINK@ | grep -q MUTED && echo 0 > ${wobSock}) || wpctl get-volume @DEFAULT_AUDIO_SINK@ | sed 's/[^0-9]//g' > ${wobSock}";
|
||||
"XF86AudioMute".allow-when-locked = true;
|
||||
"XF86MonBrightnessUp".action = sh "${lib.getExe pkgs.brightnessctl} -c backlight s +5% | sed -n 's/.*(\\([0-9]*\\)%).*/\\1/p' > ${wobSock}";
|
||||
"XF86MonBrightnessUp".allow-when-locked = true;
|
||||
"XF86MonBrightnessDown".action = sh "${lib.getExe pkgs.brightnessctl} -c backlight s 5%- | sed -n 's/.*(\\([0-9]*\\)%).*/\\1/p' > ${wobSock}";
|
||||
"XF86MonBrightnessDown".allow-when-locked = true;
|
||||
"XF86KbdBrightnessUp".action = sh "${lib.getExe pkgs.brightnessctl} -d '*:kbd_backlight' s +5% | sed -n 's/.*(\\([0-9]*\\)%).*/\\1/p' > ${wobSock}";
|
||||
"XF86KbdBrightnessUp".allow-when-locked = true;
|
||||
"XF86KbdBrightnessDown".action = sh "${lib.getExe pkgs.brightnessctl} -d '*:kbd_backlight' s 5%- | sed -n 's/.*(\\([0-9]*\\)%).*/\\1/p' > ${wobSock}";
|
||||
"XF86KbdBrightnessDown".allow-when-locked = true;
|
||||
} else {
|
||||
"XF86AudioRaiseVolume".action = sh "wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+";
|
||||
"XF86AudioRaiseVolume".allow-when-locked = true;
|
||||
"XF86AudioLowerVolume".action = sh "wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-";
|
||||
"XF86AudioLowerVolume".allow-when-locked = true;
|
||||
"XF86AudioMute".action = sh "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle";
|
||||
"XF86AudioMute".allow-when-locked = true;
|
||||
"XF86MonBrightnessUp".action = sh "${lib.getExe pkgs.brightnessctl} -c backlight s +5%";
|
||||
"XF86MonBrightnessUp".allow-when-locked = true;
|
||||
"XF86MonBrightnessDown".action = sh "${lib.getExe pkgs.brightnessctl} -c backlight s 5%-";
|
||||
"XF86MonBrightnessDown".allow-when-locked = true;
|
||||
"XF86KbdBrightnessUp".action = sh "${lib.getExe pkgs.brightnessctl} -d '*:kbd_backlight' s +5%";
|
||||
"XF86KbdBrightnessUp".allow-when-locked = true;
|
||||
"XF86KbdBrightnessDown".action = sh "${lib.getExe pkgs.brightnessctl} -d '*:kbd_backlight' s 5%-";
|
||||
"XF86KbdBrightnessDown".allow-when-locked = true;
|
||||
});
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue