From 21b52a31e1eff5c8142f26e091fde083c21db55f Mon Sep 17 00:00:00 2001 From: Gregor Kleen <gkleen@yggdrasil.li> Date: Tue, 14 Jan 2025 11:30:32 +0100 Subject: niri --- accounts/gkleen@sif/niri/default.nix | 139 +++++++++++++++++ accounts/gkleen@sif/niri/waybar.nix | 288 +++++++++++++++++++++++++++++++++++ 2 files changed, 427 insertions(+) create mode 100644 accounts/gkleen@sif/niri/default.nix create mode 100644 accounts/gkleen@sif/niri/waybar.nix (limited to 'accounts/gkleen@sif/niri') diff --git a/accounts/gkleen@sif/niri/default.nix b/accounts/gkleen@sif/niri/default.nix new file mode 100644 index 00000000..6a8d10a0 --- /dev/null +++ b/accounts/gkleen@sif/niri/default.nix @@ -0,0 +1,139 @@ +{ config, pkgs, lib, ... }: +let + niri = config.programs.niri.package; + terminal = lib.getExe config.programs.kitty.package; + lightctl = lib.getExe' config.services.avizo.package "lightctl"; + volumectl = lib.getExe' config.services.avizo.package "volumectl"; + dunstctl = lib.getExe' config.services.dunst.package "dunstctl"; +in { + imports = [ + ./waybar.nix + ]; + + config = { + systemd.user.services.xwayland-satellite = { + Unit = { + BindsTo = [ "graphical-session.target" ]; + PartOf = [ "graphical-session.target" ]; + After = [ "graphical-session.target" ]; + Requisite = [ "graphical-session.target" ]; + }; + Service = { + Type = "notify"; + NotifyAccess = "all"; + ExecStart = lib.getExe pkgs.xwayland-satellite-unstable; + StandardOutput = "journal"; + }; + Install = { + WantedBy = [ "graphical-session.target" ]; + }; + }; + + programs.niri.settings = { + prefer-no-csd = true; + screenshot-path = "${config.home.homeDirectory}/screenshots"; + + input = { + keyboard.xkb = { + layout = "us,"; + variant = "dvp,"; + options = "compose:caps,grp:win_space_toggle"; + }; + }; + + environment = { + NIXOS_OZONE_WL = "1"; + QT_QPA_PLATFORM = "wayland"; + GDK_BACKEND = "wayland"; + SDL_VIDEODRIVER = "wayland"; + }; + + cursor.hide-when-typing = true; + + binds = with config.lib.niri.actions; { + "Mod+Return".action = spawn terminal; + "Mod+Q".action = close-window; + "Mod+D".action = spawn (lib.getExe config.programs.fuzzel.package); + "Mod+Shift+D".action = spawn (lib.getExe config.programs.fuzzel.package) "--list-executables-in-path"; + + "Mod+H".action = focus-column-left; + "Mod+T".action = focus-window-down; + "Mod+N".action = focus-window-up; + "Mod+S".action = focus-column-right; + + "Mod+Shift+H".action = move-column-left; + "Mod+Shift+T".action = move-window-down; + "Mod+Shift+N".action = move-window-up; + "Mod+Shift+S".action = move-column-right; + + "Mod+Control+H".action = focus-monitor-left; + "Mod+Control+T".action = focus-monitor-down; + "Mod+Control+N".action = focus-monitor-up; + "Mod+Control+S".action = focus-monitor-right; + + "Mod+Shift+Control+H".action = move-workspace-to-monitor-left; + "Mod+Shift+Control+T".action = move-workspace-to-monitor-down; + "Mod+Shift+Control+N".action = move-workspace-to-monitor-up; + "Mod+Shift+Control+S".action = move-workspace-to-monitor-right; + + "Mod+G".action = focus-workspace-down; + "Mod+C".action = focus-workspace-up; + + "Mod+Control+G".action = move-column-to-workspace-down; + "Mod+Control+C".action = move-column-to-workspace-up; + + "Mod+Shift+G".action = move-workspace-down; + "Mod+Shift+C".action = move-workspace-up; + + "Mod+M".action = consume-window-into-column; + "Mod+W".action = expel-window-from-column; + + "Mod+F".action = maximize-column; + "Mod+Shift+F".action = fullscreen-window; + + "Mod+Space".action = switch-focus-between-floating-and-tiling; + "Mod+Shift+Space".action = toggle-window-floating; + + "Mod+Left".action = set-column-width "-10%"; + "Mod+Down".action = set-window-height "-10%"; + "Mod+Up".action = set-window-height "+10%"; + "Mod+Right".action = set-column-width "+10%"; + + "Mod+Shift+Z" = { + action = spawn (lib.getExe niri) "msg" "action" "power-off-monitors"; + allow-when-locked = true; + }; + + "XF86MonBrightnessUp" = { + action = spawn lightctl "-d" "-e4" "-n1" "up"; + allow-when-locked = true; + }; + "XF86MonBrightnessDown" = { + action = spawn lightctl "-d" "-e4" "-n1" "down"; + allow-when-locked = true; + }; + "XF86AudioRaiseVolume" = { + action = spawn volumectl "-d" "-u" "up"; + allow-when-locked = true; + }; + "XF86AudioLowerVolume" = { + action = spawn volumectl "-d" "-u" "down"; + allow-when-locked = true; + }; + "XF86AudioMute" = { + action = spawn volumectl "-d" "toggle-mute"; + allow-when-locked = true; + }; + "XF86AudioMicMute" = { + action = spawn volumectl "-d" "-m" "toggle-mute"; + allow-when-locked = true; + }; + + "Mod+Semicolon".action = spawn dunstctl "close"; + "Mod+Shift+Semicolon".action = spawn dunstctl "close-all"; + "Mod+Period".action = spawn dunstctl "context"; + "Mod+Comma".action = spawn dunstctl "history-pop"; + }; + }; + }; +} diff --git a/accounts/gkleen@sif/niri/waybar.nix b/accounts/gkleen@sif/niri/waybar.nix new file mode 100644 index 00000000..1a25b581 --- /dev/null +++ b/accounts/gkleen@sif/niri/waybar.nix @@ -0,0 +1,288 @@ +{ lib, pkgs, ... }: +{ + config = { + programs.waybar = { + enable = true; + systemd = { + enable = true; + target = "graphical-session.target"; + }; + settings = let + windowRewrites = { + "(.*) — Mozilla Firefox" = "$1"; + "(.*) - Mozilla Thunderbird" = "$1"; + "(.*) - mpv" = "$1"; + }; + iconSize = 11; + in [ + { + layer = "top"; + position = "top"; + height = 14; + output = [ "eDP-1" "DP-2" "DP-3" ]; + modules-left = [ "niri/workspaces" ]; + modules-center = [ "niri/window" ]; + modules-right = [ # "custom/worktime" "custom/worktime-today" + "custom/weather" + # "custom/keymap" + "privacy" "tray" "wireplumber" "backlight" "battery" "idle_inhibitor" "clock" ]; + + "custom/weather" = { + format = "{}"; + tooltip = true; + interval = 3600; + exec = "${lib.getExe pkgs.wttrbar} --hide-conditions --nerd --custom-indicator \"<span font=\\\"Symbols Nerd Font Mono\\\" size=\\\"120%\\\">{ICON}</span> {FeelsLikeC}°\""; + return-type = "json"; + }; + "custom/keymap" = { + format = "{}"; + tooltip = true; + return-type = "json"; + exec = pkgs.writers.writePython3 "keymap" {} '' + import os + import socket + import re + import subprocess + import json + + + def output(keymap): + short = keymap + if keymap == "English (programmer Dvorak)": + short = "dvp" + elif keymap == "English (US)": + short = "<span color=\"#ffffff\">us</span>" + print(json.dumps({'text': short, 'tooltip': keymap}, separators=(',', ':')), flush=True) # noqa: E501 + + + r = subprocess.run(["hyprctl", "devices", "-j"], check=True, stdout=subprocess.PIPE, text=True) # noqa: E501 + for keyboard in json.loads(r.stdout)['keyboards']: + if keyboard['name'] != "at-translated-set-2-keyboard": + continue + output(keyboard['active_keymap']) + + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + sock.connect(os.environ["XDG_RUNTIME_DIR"] + "/hypr/" + os.environ["HYPRLAND_INSTANCE_SIGNATURE"] + "/.socket2.sock") # noqa: E501 + expected = re.compile(r'^activelayout>>at-translated-set-2-keyboard,(?P<keymap>.+)$') # noqa: E501 + for line in sock.makefile(buffering=1, encoding='utf-8'): + if match := expected.match(line): + output(match.group("keymap")) + ''; + on-click = "hyprctl switchxkblayout at-translated-set-2-keyboard next"; + }; + "custom/worktime" = { + interval = 60; + exec = lib.getExe pkgs.worktime; + tooltip = false; + }; + "custom/worktime-today" = { + interval = 60; + exec = "${lib.getExe pkgs.worktime} today"; + tooltip = false; + }; + "niri/workspaces" = { + all-outputs = true; + }; + "niri/window" = { + separate-outputs = true; + icon = true; + icon-size = 14; + rewrite = windowRewrites; + }; + clock = { + interval = 1; + # timezone = "Europe/Berlin"; + format = "W{:%V-%u %F %H:%M:%S%Ez}"; + tooltip-format = "<tt><small>{calendar}</small></tt>"; + calendar = { + mode = "year"; + mode-mon-col = 3; + weeks-pos = "left"; + on-scroll = 1; + format = { + months = "<span color='#ffead3'><b>{}</b></span>"; + days = "{}"; + weeks = "<span color='#99ffdd'><b>{}</b></span>"; + weekdays = "<span color='#ffcc66'><b>{}</b></span>"; + today = "<span color='#ff6699'><b>{}</b></span>"; + }; + }; + }; + battery = { + format = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">{icon}</span>"; + icon-size = iconSize - 2; + states = { warning = 30; critical = 15; }; + format-icons = ["󰂎" "󰁺" "󰁻" "󰁼" "󰁽" "󰁾" "󰁿" "󰂀" "󰂁" "󰂂" "󰁹" ]; + format-charging = "󰂄"; + format-plugged = "󰚥"; + tooltip-format = "{capacity}% {timeTo}"; + interval = 20; + }; + tray = { + icon-size = 16; + # show-passive-items = true; + spacing = 1; + }; + privacy = { + icon-spacing = 7; + icon-size = iconSize; + modules = [ + { type = "screenshare"; } + { type = "audio-in"; } + ]; + }; + idle_inhibitor = { + format = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">{icon}</span>"; + icon-size = iconSize; + format-icons = { activated = "󰈈"; deactivated = "󰈉"; }; + timeout = 120; + }; + backlight = { + format = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">{icon}</span>"; + icon-size = iconSize; + tooltip-format = "{percent}%"; + format-icons = ["󰃚" "󰃛" "󰃜" "󰃝" "󰃞" "󰃟" "󰃠"]; + on-scroll-up = "lightctl -d -e4 -n1 up"; + on-scroll-down = "lightctl -d -e4 -n1 down"; + }; + wireplumber = { + format = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">{icon}</span>"; + icon-size = iconSize; + tooltip-format = "{volume}% {node_name}"; + format-icons = ["󰕿" "󰖀" "󰕾"]; + format-muted = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">󰝟</span>"; + # ignored-sinks = ["Easy Effects Sink"]; + on-scroll-up = "volumectl -d -u up"; + on-scroll-down = "volumectl -d -u down"; + on-click = "volumectl -d toggle-mute"; + }; + } + { + layer = "top"; + position = "top"; + height = 14; + output = [ "!eDP-1" "!DP-2" "!DP-3" ]; + modules-left = [ "niri/workspaces" ]; + modules-center = [ "niri/window" ]; + modules-right = [ "clock" ]; + + "niri/workspaces" = { + all-outputs = false; + }; + "niri/window" = { + separate-outputs = true; + icon = true; + icon-size = 14; + rewrite = windowRewrites; + }; + clock = { + interval = 1; + # timezone = "Europe/Berlin"; + format = "{:%H:%M}"; + tooltip-format = "W{:%V-%u %F %H:%M:%S%Ez}"; + }; + } + ]; + style = '' + @define-color white #ffffff; + @define-color grey #555555; + @define-color blue #1a8fff; + @define-color green #23fd00; + @define-color orange #f28a21; + @define-color red #f2201f; + + * { + border: none; + font-family: "Fira Sans Nerd Font"; + font-size: 10pt; + min-height: 0; + } + + window#waybar { + background-color: rgba(0, 0, 0, 0.66); + color: @white; + } + + .modules-left { + margin-left: 9px; + } + .modules-right { + margin-right: 9px; + } + + .module { + margin: 0 5px; + } + + #workspaces button { + color: @grey; + } + #workspaces button.hosting-monitor { + color: @white; + } + #workspaces button.visible { + color: @blue; + } + #workspaces button.active { + color: @green; + } + #workspaces button.urgent { + color: @red; + } + + #custom-weather, #custom-keymap, #custom-worktime, #custom-worktime-today { + color: @grey; + margin: 0 5px; + } + #custom-weather, #custom-worktime-today { + margin-right: 3px; + } + #custom-keymap, #custom-weather { + margin-left: 3px; + } + + #tray { + margin: 0; + } + #battery, #idle_inhibitor, #backlight, #wireplumber { + color: @grey; + margin: 0 5px 0 2px; + } + #idle_inhibitor { + margin-right: 2px; + margin-left: 3px; + } + #battery { + margin-right: 3px; + } + #battery.discharging { + color: @white; + } + #battery.warning { + color: @orange; + } + #battery.critical { + color: @red; + } + #battery.charging { + color: @white; + } + #idle_inhibitor.activated { + color: @white; + } + + #idle_inhibitor { + padding-top: 1px; + } + + #privacy { + color: @red; + margin: -1px 2px 0px 5px; + } + #clock { + /* margin-right: 5px; */ + } + ''; + }; + }; +} -- cgit v1.2.3