From 771b662dd71a2bec39ba71226552b9e40b9ef745 Mon Sep 17 00:00:00 2001 From: Kate Adkins Date: Fri, 1 Aug 2025 21:13:51 +0200 Subject: [PATCH] add chrysalis --- XCompose | 63 ++ flake.nix | 12 +- nixos/configs/gui/default.nix | 1 - nixos/configs/gui/niri.nix | 4 +- nixos/configs/gui/waybar/default.nix | 865 ++++++++++---------- nixos/configs/power-saving-amd.nix | 22 + nixos/configs/power-saving.nix | 1 + nixos/dotfiles/hm.nix | 3 + nixos/hosts/chrysalis/audio.nix | 391 +++++++++ nixos/hosts/chrysalis/default.nix | 176 ++++ nixos/hosts/chrysalis/ec_kmod.nix | 56 ++ nixos/hosts/komashi/default.nix | 44 +- packages/default.nix | 3 + packages/framework-13-icm/color-profile.icm | Bin 0 -> 9932 bytes packages/framework-13-icm/default.nix | 13 + wezterm/wezterm.lua | 2 +- xonsh/chrysalis.xsh | 16 + 17 files changed, 1186 insertions(+), 486 deletions(-) create mode 100644 XCompose create mode 100644 nixos/configs/power-saving-amd.nix create mode 100644 nixos/hosts/chrysalis/audio.nix create mode 100644 nixos/hosts/chrysalis/default.nix create mode 100644 nixos/hosts/chrysalis/ec_kmod.nix create mode 100644 packages/framework-13-icm/color-profile.icm create mode 100644 packages/framework-13-icm/default.nix create mode 100644 xonsh/chrysalis.xsh diff --git a/XCompose b/XCompose new file mode 100644 index 0000000..55296ef --- /dev/null +++ b/XCompose @@ -0,0 +1,63 @@ +include "%L" + +# compose 5 = euro + <5> : "€" U20AC + +# general typography + : "…" U2026 # HORIZONTAL ELLIPSIS + : "⋮" U22EE # VERTICAL ELLIPSIS + : "⋯" U22EF # MIDLINE HORIZONTAL ELLIPSIS + +# these aren't the cookie + : "Ā" U0100 # LATIN CAPITAL LETTER A WITH MACRON + : "ā" U0101 # LATIN SMALL LETTER A WITH MACRON + : "Ē" U0112 # LATIN CAPITAL LETTER E WITH MACRON + : "ē" U0113 # LATIN SMALL LETTER E WITH MACRON + : "Ī" U012A # LATIN CAPITAL LETTER I WITH MACRON + : "ī" U012B # LATIN SMALL LETTER I WITH MACRON + : "Ō" U014C # LATIN CAPITAL LETTER O WITH MACRON + : "ō" U014D # LATIN SMALL LETTER O WITH MACRON + : "Ū" U016A # LATIN CAPITAL LETTER U WITH MACRON + : "ū" U016B # LATIN SMALL LETTER U WITH MACRON + +# puck keys +#- 2474;PARENTHESIZED DIGIT ONE;No;0;ON; 0028 0031 0029;;1;1;N;;;;; + <1> : "⑴" U2474 # PARENTHESIZED DIGIT ONE +#- 2475;PARENTHESIZED DIGIT TWO;No;0;ON; 0028 0032 0029;;2;2;N;;;;; + <2> : "⑵" U2475 # PARENTHESIZED DIGIT TWO +#- 2476;PARENTHESIZED DIGIT THREE;No;0;ON; 0028 0033 0029;;3;3;N;;;;; + <3> : "⑶" U2476 # PARENTHESIZED DIGIT THREE +#- 2477;PARENTHESIZED DIGIT FOUR;No;0;ON; 0028 0034 0029;;4;4;N;;;;; + <4> : "⑷" U2477 # PARENTHESIZED DIGIT FOUR +#- 2478;PARENTHESIZED DIGIT FIVE;No;0;ON; 0028 0035 0029;;5;5;N;;;;; + <5> : "⑸" U2478 # PARENTHESIZED DIGIT FIVE +#- 2479;PARENTHESIZED DIGIT SIX;No;0;ON; 0028 0036 0029;;6;6;N;;;;; + <6> : "⑹" U2479 # PARENTHESIZED DIGIT SIX +#- 247A;PARENTHESIZED DIGIT SEVEN;No;0;ON; 0028 0037 0029;;7;7;N;;;;; + <7> : "⑺" U247A # PARENTHESIZED DIGIT SEVEN +#- 247B;PARENTHESIZED DIGIT EIGHT;No;0;ON; 0028 0038 0029;;8;8;N;;;;; + <8> : "⑻" U247B # PARENTHESIZED DIGIT EIGHT +#- 247C;PARENTHESIZED DIGIT NINE;No;0;ON; 0028 0039 0029;;9;9;N;;;;; + <9> : "⑼" U247C # PARENTHESIZED DIGIT NINE +#- 247D;PARENTHESIZED NUMBER TEN;No;0;ON; 0028 0031 0030 0029;;;10;N;;;;; + <1> <0> : "⑽" U247D # PARENTHESIZED NUMBER TEN +#- 247E;PARENTHESIZED NUMBER ELEVEN;No;0;ON; 0028 0031 0031 0029;;;11;N;;;;; + <1> <1> : "⑾" U247E # PARENTHESIZED NUMBER ELEVEN +#- 247F;PARENTHESIZED NUMBER TWELVE;No;0;ON; 0028 0031 0032 0029;;;12;N;;;;; + <1> <2> : "⑿" U247F # PARENTHESIZED NUMBER TWELVE +#- 2480;PARENTHESIZED NUMBER THIRTEEN;No;0;ON; 0028 0031 0033 0029;;;13;N;;;;; + <1> <3> : "⒀" U2480 # PARENTHESIZED NUMBER THIRTEEN +#- 2481;PARENTHESIZED NUMBER FOURTEEN;No;0;ON; 0028 0031 0034 0029;;;14;N;;;;; + <1> <4> : "⒁" U2481 # PARENTHESIZED NUMBER FOURTEEN +#- 2482;PARENTHESIZED NUMBER FIFTEEN;No;0;ON; 0028 0031 0035 0029;;;15;N;;;;; + <1> <5> : "⒂" U2482 # PARENTHESIZED NUMBER FIFTEEN +#- 2483;PARENTHESIZED NUMBER SIXTEEN;No;0;ON; 0028 0031 0036 0029;;;16;N;;;;; + <1> <6> : "⒃" U2483 # PARENTHESIZED NUMBER SIXTEEN +#- 2484;PARENTHESIZED NUMBER SEVENTEEN;No;0;ON; 0028 0031 0037 0029;;;17;N;;;;; + <1> <7> : "⒄" U2484 # PARENTHESIZED NUMBER SEVENTEEN +#- 2485;PARENTHESIZED NUMBER EIGHTEEN;No;0;ON; 0028 0031 0038 0029;;;18;N;;;;; + <1> <8> : "⒅" U2485 # PARENTHESIZED NUMBER EIGHTEEN +#- 2486;PARENTHESIZED NUMBER NINETEEN;No;0;ON; 0028 0031 0039 0029;;;19;N;;;;; + <1> <9> : "⒆" U2486 # PARENTHESIZED NUMBER NINETEEN +#- 2487;PARENTHESIZED NUMBER TWENTY;No;0;ON; 0028 0032 0030 0029;;;20;N;;;;; + <2> <0> : "⒇" U2487 # PARENTHESIZED NUMBER TWENTY diff --git a/flake.nix b/flake.nix index e279b0c..4f9d578 100644 --- a/flake.nix +++ b/flake.nix @@ -277,17 +277,15 @@ ]; }; - # Valere (powerful laptop). - nixosConfigurations.valere = nixpkgs.lib.nixosSystem rec { + # Chrysalis (powerful Framework 13 laptop). + nixosConfigurations.chrysalis = nixpkgs.lib.nixosSystem rec { system = "x86_64-linux"; specialArgs = mkSpecialArgs system; modules = linuxOfflineGuiModules [ - ./nixos/hosts/valere - ./nixos/configs/steam.nix - ./nixos/configs/virt-host.nix - ./nixos/configs/power-saving.nix - ./nixos/configs/looking-glass.nix + ./nixos/hosts/chrysalis + ./nixos/configs/power-saving-amd.nix + #./nixos/configs/vmware.nix ]; }; diff --git a/nixos/configs/gui/default.nix b/nixos/configs/gui/default.nix index 94a63fa..8f4ef72 100644 --- a/nixos/configs/gui/default.nix +++ b/nixos/configs/gui/default.nix @@ -165,7 +165,6 @@ UseIn=niri'') # Also enable plasma, for when we need to use X11 for e.g. Talon. services.xserver.enable = true; services.desktopManager.plasma6.enable = true; - services.power-profiles-daemon.enable = lib.mkForce false; # Enable sound with pipewire. services.pulseaudio.enable = false; diff --git a/nixos/configs/gui/niri.nix b/nixos/configs/gui/niri.nix index 2bbf697..9183382 100644 --- a/nixos/configs/gui/niri.nix +++ b/nixos/configs/gui/niri.nix @@ -168,9 +168,9 @@ in accel-profile = "flat"; }; - keyboard = { + keyboard.xkb = { # Make caps lock a second escape, and ralt a compose. - xkb.options = "caps:escape,compose:ralt"; + options = "caps:escape,compose:ralt"; }; }; diff --git a/nixos/configs/gui/waybar/default.nix b/nixos/configs/gui/waybar/default.nix index 13fa11f..72e7ea5 100644 --- a/nixos/configs/gui/waybar/default.nix +++ b/nixos/configs/gui/waybar/default.nix @@ -10,465 +10,466 @@ }: let hostname = config.networking.hostName; + isAmd = config.hardware.cpu.amd.updateMicrocode; isSmallScreen = (hostname == "utol"); + cfg = config.deprekated.waybar; in { + options.deprekated.waybar = { - # Pull in some dependencies for our bar. - environment.systemPackages = with pkgs; [ networkmanagerapplet ]; - - # Enable the yubikey touch detector, for our icon. - programs.yubikey-touch-detector.enable = true; - - # - # Set up our waybar configuration in home-manager. - # - home-manager.users.deprekated = - { pkgs, config, ... }: - let - - icons = rec { - calendar = "󰃭 "; - clock = " "; - puclock = "󱑆"; - cpu = ""; - ram = ""; - battery.charging = "󱐋"; - battery.horizontal = [ - " " - " " - " " - " " - " " - ]; - battery.vertical = [ - "󰁺" - "󰁻" - "󰁼" - "󰁽" - "󰁾" - "󰁿" - "󰂀" - "󰂁" - "󰂂" - "󰁹" - ]; - battery.levels = battery.vertical; - network.disconnected = "󰤮 "; - network.ethernet = "󰈀 "; - network.strength = [ - "󰤟 " - "󰤢 " - "󰤥 " - "󰤨 " - ]; - bluetooth.on = "󰂯"; - bluetooth.off = "󰂲"; - bluetooth.battery = "󰥉"; - volume.source = "󱄠"; - volume.muted = "󰝟"; - volume.levels = [ - "󰕿" - "󰖀" - "󰕾" - ]; - idle = { - on = "󰅶"; - off = "󰾪"; - }; - vpn = "󰌆 "; - music = { - playing = ""; - paused = ""; - stopped = ""; - missing = "󰌙"; - }; - - speed = { - slow = "󰾆"; - medium = "󰾅"; - fast = "󰓅"; - }; - }; - colors = config.lib.stylix.colors; - - # From the Waybar wiki. - waybar-events = pkgs.writeScriptBin "waybar-events" '' - #!${pkgs.python3}/bin/python3 - - import calendar - import subprocess - import datetime - import json - import html - import sys - - data = {} - - today = datetime.date.today().strftime("%Y-%m-%d") - next_week = (datetime.date.today() + - datetime.timedelta(days=10)).strftime("%Y-%m-%d") - tomorrow = (datetime.date.today() + - datetime.timedelta(days=1)).strftime("%Y-%m-%d") - - human_events = subprocess.check_output('khal list now ' + next_week, shell=True).decode('utf-8') - machine_events = subprocess.check_output('khal list now ' + next_week + ' -d "Holidays in United States" --once -f "{title}|{start-date}|{start-time}" -df ""', shell=True).decode('utf-8') - - if not machine_events: - sys.exit(0) - - next_event = machine_events.split("\n")[0] - event, date, time = next_event.split('|') - - # Generate our hover-over text. - lines = human_events.split("\n") - new_lines = [] - for line in lines: - if line.startswith("To hide observances") or (line == ""): - continue - - clean_line = html.escape(line).split(" ::")[0] - if len(clean_line) and not clean_line[0] in ['0', '1', '2']: - clean_line = "\n"+clean_line+"" if (',' in clean_line) else clean_line - - new_lines.append(clean_line) - tooltip = "\n".join(new_lines).strip() - - if tomorrow in date: - date = "tomorrow" - else: - weekday = datetime.datetime.fromisoformat(date).weekday() - date = calendar.day_name[weekday].lower() - - - # Add time suffixes when appropriate. - time_suffix = "" - if time: - time_suffix = " @ " + time - - date_suffix = "" - if today not in date: - date_suffix = ", " + date - - - # In the typical case, display the next event. - data['text'] = html.escape(" " + event[0:30] + date_suffix + time_suffix) - - # Display our nice, human-readable event ouptut on hover. - data['tooltip'] = tooltip - - # Finally, send the data to Waybar. - print(json.dumps(data)) - ''; - - waybar-title = pkgs.writeScriptBin "waybar-title" '' - #!${pkgs.bash}/bin/bash - niri msg --json focused-window | jq -c '{text: (if ((.title | length) > 40) then (.title[:38] + "…") else .title end), tooltip: .app_id}' | sed 's/&[ $]/\& /g' - ''; - - waybar-puck-countdown = pkgs.writeScriptBin "waybar-puck-countdown" '' - #!${pkgs.python3}/bin/python3 - - import json - - from datetime import datetime, timezone - - now = datetime.now(timezone.utc) - puck_day = "2024-12-11 13:30:00-07:00" - puck_time = datetime.fromisoformat(puck_day) - until = puck_time - now - - response = { - "text": f" 󰧒 {until.days}d {until.seconds // 60 // 60}h", - "tooltip": f"days until {puck_day}" + hostSpecificCss = lib.mkOption { + type = lib.types.str; + default = ""; + example = '' + window#waybar { + padding-left: 8px; + padding-right: 8px; } - - print(json.dumps(response)) ''; + description = '' + CSS to add to our waybar config on this system. + ''; + }; + }; - in - { - # - # Core Waybar settings. - # - programs.waybar = { - enable = true; - #systemd.enable = true; - }; + config = { - programs.waybar.settings.mainBar = { - layer = "top"; - #mode = "overlay"; + # Pull in some dependencies for our bar. + environment.systemPackages = with pkgs; [ networkmanagerapplet ]; - modules-left = [ - "clock" - "clock#otherzone" - "mpris" - ]; - modules-center = [ - "custom/title" - "wlr/taskbar" - ]; - modules-right = [ - "tray" - "custom/events" - "privacy" - "custom/yubikey" - "wireplumber" - "battery" - ]; + # Enable the yubikey touch detector, for our icon. + programs.yubikey-touch-detector.enable = true; - battery = { - interval = 5; - format = "{icon} {capacity}%"; - format-charging = "{icon} {capacity}% ${icons.battery.charging}"; - format-icons = icons.battery.levels; - states.warning = 30; - states.critical = 15; - }; + # + # Set up our waybar configuration in home-manager. + # + home-manager.users.deprekated = + { pkgs, config, ... }: + let - cpu = { - format = "${icons.cpu} {usage}% @ {avg_frequency:0.1f}GHz"; - }; - - memory = { - format = "${icons.ram} {used:0.1f}G / {total:0.1f}G"; - }; - - clock = { - interval = 1; - format = "${icons.clock} {:%H:%M %A, %B %d %Z}"; - - tooltip-format = "${icons.calendar} {:%a, %Y-%m-%d}\n\n{calendar}"; - - calendar = { - mode = "month"; - format = { - weeks = "W{}"; - months = "{}"; - days = "{}"; - weekdays = "{}"; - today = "{}"; - }; - }; - }; - - "clock#otherzone" = { - interval = 1; - format = "${icons.puclock} {:%H:%M %Z}"; - timezone = "America/Denver"; - tooltip-format = '' - Homosexuality Statistics - - Homosexuality is online. - Homosexuality levels are CRITICAL. - ''; - }; - - network = { - on-click = "${pkgs.networkmanagerapplet}/bin/nm-connection-editor"; - tooltip = false; - format-disconnected = icons.network.disconnected; - format-ethernet = "${icons.network.ethernet}"; - format-wifi = "{icon} {essid}"; - format-icons = icons.network.strength; - }; - - bluetooth = { - format = "{icon}"; - format-disabled = "{icon}"; - format-icons = { - inherit (icons.bluetooth) on off; - connected = icons.bluetooth.on; - }; - format-connected = "{icon} {device_alias}"; - }; - "bluetooth#battery" = { - format = ""; - format-connected-battery = "${icons.bluetooth.battery} {device_battery_percentage}%"; - }; - - wireplumber = { - on-click = "${pkgs.pavucontrol}/bin/pavucontrol -t 1"; - format = "{icon} {volume}%"; - tooltip-format = "${icons.volume.source}"; - format-muted = "${icons.volume.muted}"; - format-icons = icons.volume.levels; - reverse-scrolling = 1; - }; - - # Displays an icon when our yubikey is waiting for touch. - "custom/yubikey" = { - exec = ./waybar-yubikey.sh; - return-type = "json"; - }; - - "custom/events" = { - exec = "${waybar-events}/bin/waybar-events"; - format = "{}"; - tooltip = true; - return-type = "json"; - interval = 60; - on-click = "${pkgs.wezterm}/bin/wezterm start ikhal"; - }; - - "custom/title" = { - exec = "${waybar-title}/bin/waybar-title"; - format = "{}"; - tooltip = true; - return-type = "json"; - interval = 1; - }; - - "custom/puckdown" = { - exec = "${waybar-puck-countdown}/bin/waybar-puck-countdown"; - format = "{}"; - tooltip = true; - return-type = "json"; - interval = 60 * 5; - }; - - "wlr/taskbar" = { - format = "{icon}"; - tooltip-format = "{app_id}"; - - on-click = "activate"; - }; - - tray = { - icon-size = 21; - spacing = 10; - }; - - # Display indicators when we're sharing video or audio. - privacy = { - icon-spacing = 4; - icon-size = 18; - transition-duration = 250; - modules = [ - { - type = "screenshare"; - tooltip = false; - tooltip-icon-size = 24; - } - { - type = "audio-out"; - tooltip = false; - tooltip-icon-size = 24; - } - { - type = "audio-in"; - tooltip = false; - tooltip-icon-size = 24; - } + icons = rec { + calendar = "󰃭 "; + clock = " "; + puclock = "󱑆"; + cpu = ""; + ram = ""; + battery.charging = "󱐋"; + battery.horizontal = [ + " " + " " + " " + " " + " " ]; - }; - - mpris = { - format = "${icons.music.playing} {artist} - {title}"; - format-paused = "${icons.music.paused} {artist} - {title}"; - format-stopped = ""; - format-disconnected = "${icons.music.missing}"; - tooltip-format = "${icons.music.playing} {artist} - {title}"; - max-length = 60; - }; - - idle_inhibitor = { - format = "{icon}"; - format-icons = { - activated = icons.idle.on; - deactivated = icons.idle.off; + battery.vertical = [ + "󰁺" + "󰁻" + "󰁼" + "󰁽" + "󰁾" + "󰁿" + "󰂀" + "󰂁" + "󰂂" + "󰁹" + ]; + battery.levels = battery.vertical; + network.disconnected = "󰤮 "; + network.ethernet = "󰈀 "; + network.strength = [ + "󰤟 " + "󰤢 " + "󰤥 " + "󰤨 " + ]; + bluetooth.on = "󰂯"; + bluetooth.off = "󰂲"; + bluetooth.battery = "󰥉"; + volume.source = "󱄠"; + volume.muted = "󰝟"; + volume.levels = [ + "󰕿" + "󰖀" + "󰕾" + ]; + idle = { + on = "󰅶"; + off = "󰾪"; + }; + vpn = "󰌆 "; + music = { + playing = ""; + paused = ""; + stopped = ""; + missing = "󰌙"; }; - tooltip-format-activated = "System blocked from going idle."; - tooltip-format-deactivated = "System allowed to go idle."; + speed = { + slow = "󰾆"; + medium = "󰾅"; + fast = "󰓅"; + }; }; - }; - stylix.targets.waybar.enable = false; - programs.waybar.style = - let - colors = config.lib.stylix.colors; - modules = s: "${s ".modules-left"}, ${s ".modules-center"}, ${s ".modules-right"}"; - module = s: modules (m: "${m} > ${s} > *"); - in - '' - * { - border: none; - font-family: ${config.stylix.fonts.monospace.name}; - font-weight: 400; - font-size: ${if isSmallScreen then "17" else toString config.stylix.fonts.sizes.desktop}px; - color: #${colors.base06}; - } + colors = config.lib.stylix.colors; - window#waybar { - background: #${colors.base00}; - } + # From the Waybar wiki. + waybar-events = pkgs.writeScriptBin "waybar-events" '' + #!${pkgs.python3}/bin/python3 - #taskbar button { - padding: 0 0.4em; - } + import calendar + import subprocess + import datetime + import json + import html + import sys - #taskbar button.active { - background: #${colors.base01}; - } + data = {} - #tray image, - #taskbar image { - -gtk-icon-transform: scale(0.75); - margin: -5px -4px; - padding: 0px 2px; - } + today = datetime.date.today().strftime("%Y-%m-%d") + next_week = (datetime.date.today() + + datetime.timedelta(days=10)).strftime("%Y-%m-%d") + tomorrow = (datetime.date.today() + + datetime.timedelta(days=1)).strftime("%Y-%m-%d") - ${modules lib.id} { - margin: 0; - } + human_events = subprocess.check_output('khal list now ' + next_week, shell=True).decode('utf-8') + machine_events = subprocess.check_output('khal list now ' + next_week + ' -d "Holidays in United States" --once -f "{title}|{start-date}|{start-time}" -df ""', shell=True).decode('utf-8') - ${module "*"} { - padding: 0 5px; - margin: 0; - font-size: 75%; - } + if not machine_events: + sys.exit(0) - ${module ":not(:first-child)"} { - border-left: 1px solid #${colors.base01}; - } + next_event = machine_events.split("\n")[0] + event, date, time = next_event.split('|') - ${module ":not(:last-child)"} { - border-right: 1px solid #${colors.base01}; - } + # Generate our hover-over text. + lines = human_events.split("\n") + new_lines = [] + for line in lines: + if line.startswith("To hide observances") or (line == ""): + continue - #battery.charging { - color: #${colors.green}; - } + clean_line = html.escape(line).split(" ::")[0] + if len(clean_line) and not clean_line[0] in ['0', '1', '2']: + clean_line = "\n"+clean_line+"" if (',' in clean_line) else clean_line - #battery.warning:not(.charging) { - color: #${colors.yellow}; - } + new_lines.append(clean_line) + tooltip = "\n".join(new_lines).strip() - #battery.critical:not(.charging) { - animation: critical-blink steps(8) 1s infinite alternate; - } + if tomorrow in date: + date = "tomorrow" + else: + weekday = datetime.datetime.fromisoformat(date).weekday() + date = calendar.day_name[weekday].lower() - @keyframes critical-blink { - to { - color: #${colors.red}; - } - } + + # Add time suffixes when appropriate. + time_suffix = "" + if time: + time_suffix = " @ " + time + + date_suffix = "" + if today not in date: + date_suffix = ", " + date + + + # In the typical case, display the next event. + data['text'] = html.escape(" " + event[0:30] + date_suffix + time_suffix) + + # Display our nice, human-readable event ouptut on hover. + data['tooltip'] = tooltip + + # Finally, send the data to Waybar. + print(json.dumps(data)) ''; - # - # Restart waybar when niri starts. - # - programs.niri.settings.spawn-at-startup = [ - { - command = [ - "systemctl" - "--user" - "restart" - "waybar" - ]; - } - { command = [ "nm-applet" ]; } - ]; - }; + waybar-title = pkgs.writeScriptBin "waybar-title" '' + #!${pkgs.bash}/bin/bash + niri msg --json focused-window | jq -c '{text: (if ((.title | length) > 40) then (.title[:38] + "…") else .title end), tooltip: .app_id}' | sed 's/&[ $]/\& /g' + ''; + in + { + # + # Core Waybar settings. + # + programs.waybar = { + enable = true; + #systemd.enable = true; + }; + + programs.waybar.settings.mainBar = + { + layer = "top"; + #mode = "overlay"; + + modules-left = [ + "clock" + "mpris" + ]; + modules-center = [ + "custom/title" + "wlr/taskbar" + ]; + modules-right = [ + "tray" + "custom/events" + "privacy" + "custom/yubikey" + "wireplumber" + "battery" + ] ++ (if isAmd then [ "power-profiles-daemon" ] else [ ]); + + battery = { + interval = 5; + format = "{icon} {capacity}%"; + format-charging = "{icon} {capacity}% ${icons.battery.charging}"; + format-icons = icons.battery.levels; + states.warning = 30; + states.critical = 15; + }; + + cpu = { + format = "${icons.cpu} {usage}% @ {avg_frequency:0.1f}GHz"; + }; + + memory = { + format = "${icons.ram} {used:0.1f}G / {total:0.1f}G"; + }; + + clock = { + interval = 1; + format = "${icons.clock} {:%H:%M %A, %B %d %Z}"; + + tooltip-format = "${icons.calendar} {:%a, %Y-%m-%d}\n\n{calendar}"; + + calendar = { + mode = "month"; + format = { + weeks = "W{}"; + months = "{}"; + days = "{}"; + weekdays = "{}"; + today = "{}"; + }; + }; + }; + + network = { + on-click = "${pkgs.networkmanagerapplet}/bin/nm-connection-editor"; + tooltip = false; + format-disconnected = icons.network.disconnected; + format-ethernet = "${icons.network.ethernet}"; + format-wifi = "{icon} {essid}"; + format-icons = icons.network.strength; + }; + + bluetooth = { + format = "{icon}"; + format-disabled = "{icon}"; + format-icons = { + inherit (icons.bluetooth) on off; + connected = icons.bluetooth.on; + }; + format-connected = "{icon} {device_alias}"; + }; + "bluetooth#battery" = { + format = ""; + format-connected-battery = "${icons.bluetooth.battery} {device_battery_percentage}%"; + }; + + wireplumber = { + on-click = "${pkgs.pavucontrol}/bin/pavucontrol -t 1"; + format = "{icon} {volume}%"; + tooltip-format = "${icons.volume.source}"; + format-muted = "${icons.volume.muted}"; + format-icons = icons.volume.levels; + reverse-scrolling = 1; + }; + + # Displays an icon when our yubikey is waiting for touch. + "custom/yubikey" = { + exec = ./waybar-yubikey.sh; + return-type = "json"; + }; + + "custom/events" = { + exec = "${waybar-events}/bin/waybar-events"; + format = "{}"; + tooltip = true; + return-type = "json"; + interval = 60; + on-click = "${pkgs.wezterm}/bin/wezterm start ikhal"; + }; + + "custom/title" = { + exec = "${waybar-title}/bin/waybar-title"; + format = "{}"; + tooltip = true; + return-type = "json"; + interval = 1; + }; + + "wlr/taskbar" = { + format = "{icon}"; + tooltip-format = "{app_id}"; + + on-click = "activate"; + }; + + tray = { + icon-size = 21; + spacing = 10; + }; + + # Display indicators when we're sharing video or audio. + privacy = { + icon-spacing = 4; + icon-size = 18; + transition-duration = 250; + modules = [ + { + type = "screenshare"; + tooltip = false; + tooltip-icon-size = 24; + } + { + type = "audio-out"; + tooltip = false; + tooltip-icon-size = 24; + } + { + type = "audio-in"; + tooltip = false; + tooltip-icon-size = 24; + } + ]; + }; + + mpris = { + format = "${icons.music.playing} {artist} - {title}"; + format-paused = "${icons.music.paused} {artist} - {title}"; + format-stopped = ""; + format-disconnected = "${icons.music.missing}"; + tooltip-format = "${icons.music.playing} {artist} - {title}"; + max-length = 60; + }; + + idle_inhibitor = { + format = "{icon}"; + format-icons = { + activated = icons.idle.on; + deactivated = icons.idle.off; + }; + + tooltip-format-activated = "System blocked from going idle."; + tooltip-format-deactivated = "System allowed to go idle."; + }; + } + // ( + # Support PPD on AMD. + if isAmd then + { + power-profiles-daemon = { + format = "{icon} "; + tooltip-format = "Power profile: {profile}nDriver: {driver}"; + tooltip = true; + format-icons = { + default = ""; + performance = ""; + balanced = ""; + power-saver = ""; + }; + }; + } + else + { } + ); + stylix.targets.waybar.enable = false; + programs.waybar.style = + let + colors = config.lib.stylix.colors; + modules = s: "${s ".modules-left"}, ${s ".modules-center"}, ${s ".modules-right"}"; + module = s: modules (m: "${m} > ${s} > *"); + in + '' + * { + border: none; + font-family: ${config.stylix.fonts.monospace.name}; + font-weight: 400; + font-size: ${if isSmallScreen then "17" else toString config.stylix.fonts.sizes.desktop}px; + color: #${colors.base06}; + } + + ${cfg.hostSpecificCss} + + window#waybar { + background: #${colors.base00}; + } + + #taskbar button { + padding: 0 0.4em; + } + + #taskbar button.active { + background: #${colors.base01}; + } + + #tray image, + #taskbar image { + -gtk-icon-transform: scale(0.75); + margin: -5px -4px; + padding: 0px 2px; + } + + ${modules lib.id} { + margin: 0; + } + + ${module "*"} { + padding: 0 5px; + margin: 0; + font-size: 75%; + } + + ${module ":not(:first-child)"} { + border-left: 1px solid #${colors.base01}; + } + + ${module ":not(:last-child)"} { + border-right: 1px solid #${colors.base01}; + } + + #battery.charging { + color: #${colors.green}; + } + + #battery.warning:not(.charging) { + color: #${colors.yellow}; + } + + #battery.critical:not(.charging) { + animation: critical-blink steps(8) 1s infinite alternate; + } + + @keyframes critical-blink { + to { + color: #${colors.red}; + } + } + ''; + + # + # Restart waybar when niri starts. + # + programs.niri.settings.spawn-at-startup = [ + { + command = [ + "systemctl" + "--user" + "restart" + "waybar" + ]; + } + { command = [ "nm-applet" ]; } + ]; + }; + }; } diff --git a/nixos/configs/power-saving-amd.nix b/nixos/configs/power-saving-amd.nix new file mode 100644 index 0000000..d3f1c50 --- /dev/null +++ b/nixos/configs/power-saving-amd.nix @@ -0,0 +1,22 @@ +# +# Laptop power-saving configuration. +# +# vim: et:ts=2:sw=2: +# +{ lib, pkgs, ... }: +let + powerprofilesctl = "${pkgs.power-profiles-daemon}/bin/powerprofilesctl"; +in +{ + # Set up a power saving policy manager. + services.power-profiles-daemon.enable = lib.mkForce true; + + # Profile its CLI. + environment.systemPackages = [ pkgs.power-profiles-daemon ]; + + # Automatically switch power profile on AC plug/unplug. + services.udev.extraRules = '' + SUBSYSTEM=="power_supply", ATTR{online}=="1", RUN+="${powerprofilesctl} set performance" + SUBSYSTEM=="power_supply", ATTR{online}=="0", RUN+="${powerprofilesctl} set power-saver" + ''; +} diff --git a/nixos/configs/power-saving.nix b/nixos/configs/power-saving.nix index fb1227b..7082408 100644 --- a/nixos/configs/power-saving.nix +++ b/nixos/configs/power-saving.nix @@ -9,6 +9,7 @@ services.thermald.enable = !pkgs.stdenv.isAarch64; # Set up a power saving policy manager. + # We use TLP on intel... services.tlp = { enable = true; settings = { diff --git a/nixos/dotfiles/hm.nix b/nixos/dotfiles/hm.nix index eacc406..538134f 100644 --- a/nixos/dotfiles/hm.nix +++ b/nixos/dotfiles/hm.nix @@ -17,6 +17,9 @@ # xonsh xdg.configFile.xonsh.source = ../../xonsh; + # XCompose + xdg.configFile."XCompose".source = ../../XCompose; + # zellij xdg.configFile.zellij.source = ../../zellij; diff --git a/nixos/hosts/chrysalis/audio.nix b/nixos/hosts/chrysalis/audio.nix new file mode 100644 index 0000000..07fac64 --- /dev/null +++ b/nixos/hosts/chrysalis/audio.nix @@ -0,0 +1,391 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.hardware.framework.laptop13.audioEnhancement; +in +{ + options = { + hardware.framework.laptop13.audioEnhancement = { + enable = lib.mkOption { + type = lib.types.bool; + default = false; + description = '' + Create a new audio device called "Framework Speakers", + which applies sound tuning before sending the audio out to the speakers. + This option requires PipeWire and WirePlumber. + + The filter chain includes the following: + - Psychoacoustic bass enhancement + - Loudness compensation + - Equalizer + - Slight compression + + This option has been optimised for the Framework Laptop 13 AMD 7040 series, but should work on all models. + + Before applying, ensure the speakers are set to 100%, + because the volumes compound and the raw speaker device will be hidden by default. + + You might also need to re-select the default output device. + + In some cases, the added bass will vibrate the keyboard cable leading to a rattling sound, + a piece of foam can be used to mitigate this. + ''; + }; + + hideRawDevice = lib.mkOption { + type = lib.types.bool; + default = true; + description = '' + Hide the raw speaker device. + This option is enabled by default, because keeping the raw speaker device can lead to volume conflicts. + ''; + }; + + rawDeviceName = lib.mkOption { + type = lib.types.str; + example = "alsa_output.pci-0000_c1_00.6.analog-stereo"; + description = '' + The name of the raw speaker device. This will vary by device. + You can get this by running `pw-dump | grep -C 20 pci-0000`. + ''; + }; + }; + }; + + config = lib.mkIf cfg.enable ( + let + outputName = cfg.rawDeviceName; + prettyName = "Framework Speakers"; + + # These are pre-made decibel to linear value conversions, since Nix doesn't have pow(). + # Use the formula `10 ** (db / 20)` to calculate. + db = { + "-18.1" = 0.1244514611771385; + "-5.48" = 0.5321082592667942; + "-4.76" = 0.5780960474057181; + "8.1" = 2.5409727055493048; + "-36" = 1.5848931924611134e-2; + }; + + json = pkgs.formats.json { }; + + # The filter chain, heavily inspired by the asahi-audio project: https://github.com/AsahiLinux/asahi-audio + filter-chain = json.generate "filter-chain.json" { + "node.description" = prettyName; + "media.name" = prettyName; + "filter.graph" = { + nodes = [ + # Psychoacoustic bass extension, + # it creates harmonics of the missing bass to fool our ears into hearing it. + { + type = "lv2"; + plugin = "https://chadmed.au/bankstown"; + name = "bassex"; + control = { + bypass = 0; + amt = 1.2; + sat_second = 1.3; + sat_third = 2.5; + blend = 1.0; + ceil = 200.0; + floor = 20.0; + }; + } + # Loudness compensation, + # it ensures that the sound profile stays consistent across different volumes. + { + type = "lv2"; + plugin = "http://lsp-plug.in/plugins/lv2/loud_comp_stereo"; + name = "el"; + control = { + enabled = 1; + input = 1.0; + fft = 4; + }; + } + # 8-band equalizer, + # it tries to lessen frequencies where the laptop might resonate, + # and tries to make the frequency curve more pleasing; + # this is the "Lappy McTopface" profile (https://github.com/ceiphr/ee-framework-presets) + # further tuned for the Framework Laptop 13 AMD 7040 series + # and might need some tuning on other models. + { + type = "lv2"; + plugin = "http://lsp-plug.in/plugins/lv2/para_equalizer_x8_lr"; + name = "fw13eq"; + control = { + mode = 0; + react = 0.2; + zoom = db."-36"; + + fl_0 = 101.0; + fml_0 = 0; + ftl_0 = 5; + gl_0 = db."-18.1"; + huel_0 = 0.0; + ql_0 = 4.36; + sl_0 = 0; + wl_0 = 4.0; + + fl_1 = 451.0; + fml_1 = 0; + ftl_1 = 1; + gl_1 = db."-5.48"; + huel_1 = 3.125e-2; + ql_1 = 2.46; + sl_1 = 0; + wl_1 = 4.0; + + fl_2 = 918.0; + fml_2 = 0; + ftl_2 = 1; + gl_2 = db."-4.76"; + huel_2 = 6.25e-2; + ql_2 = 2.44; + sl_2 = 0; + wl_2 = 4.0; + + fl_3 = 9700.0; + fml_3 = 0; + ftl_3 = 1; + gl_3 = db."8.1"; + huel_3 = 9.375e-2; + ql_3 = 2.0; + sl_3 = 0; + wl_3 = 4.0; + + fr_0 = 101.0; + fmr_0 = 0; + ftr_0 = 5; + gr_0 = db."-18.1"; + huer_0 = 0.0; + qr_0 = 4.36; + sr_0 = 0; + wr_0 = 4.0; + + fr_1 = 451.0; + fmr_1 = 0; + ftr_1 = 1; + gr_1 = db."-5.48"; + huer_1 = 3.125e-2; + qr_1 = 2.46; + sr_1 = 0; + wr_1 = 4.0; + + fr_2 = 918.0; + fmr_2 = 0; + ftr_2 = 1; + gr_2 = db."-4.76"; + huer_2 = 6.25e-2; + qr_2 = 2.44; + sr_2 = 0; + wr_2 = 4.0; + + fr_3 = 9700.0; + fmr_3 = 0; + ftr_3 = 1; + gr_3 = db."8.1"; + huer_3 = 9.375e-2; + qr_3 = 2.0; + sr_3 = 0; + wr_3 = 4.0; + }; + } + # Compressors. The settings were taken from the asahi-audio project. + { + type = "lv2"; + plugin = "http://lsp-plug.in/plugins/lv2/mb_compressor_stereo"; + name = "woofer_bp"; + control = { + mode = 0; + ce_0 = 1; + sla_0 = 5.0; + cr_0 = 1.75; + al_0 = 0.725; + at_0 = 1.0; + rt_0 = 100; + kn_0 = 0.125; + cbe_1 = 1; + sf_1 = 200.0; + ce_1 = 0; + cbe_2 = 0; + ce_2 = 0; + cbe_3 = 0; + ce_3 = 0; + cbe_4 = 0; + ce_4 = 0; + cbe_5 = 0; + ce_5 = 0; + cbe_6 = 0; + ce_6 = 0; + }; + } + { + type = "lv2"; + plugin = "http://lsp-plug.in/plugins/lv2/compressor_stereo"; + name = "woofer_lim"; + control = { + sla = 5.0; + al = 1.0; + at = 1.0; + rt = 100.0; + cr = 15.0; + kn = 0.5; + }; + } + ]; + + # Now, we're chaining together the modules instantiated above. + links = [ + { + output = "bassex:out_l"; + input = "el:in_l"; + } + { + output = "bassex:out_r"; + input = "el:in_r"; + } + + { + output = "el:out_l"; + input = "fw13eq:in_l"; + } + { + output = "el:out_r"; + input = "fw13eq:in_r"; + } + { + output = "fw13eq:out_l"; + input = "woofer_bp:in_l"; + } + { + output = "fw13eq:out_r"; + input = "woofer_bp:in_r"; + } + { + output = "woofer_bp:out_l"; + input = "woofer_lim:in_l"; + } + { + output = "woofer_bp:out_r"; + input = "woofer_lim:in_r"; + } + ]; + + inputs = [ + "bassex:in_l" + "bassex:in_r" + ]; + outputs = [ + "woofer_lim:out_l" + "woofer_lim:out_r" + ]; + + # This makes pipewire's volume control actually control the loudness comp module + "capture.volumes" = [ + { + control = "el:volume"; + min = -47.5; + max = 0.0; + scale = "cubic"; + } + ]; + }; + "capture.props" = { + "node.name" = "audio_effect.laptop-convolver"; + "media.class" = "Audio/Sink"; + "audio.channels" = "2"; + "audio.position" = [ + "FL" + "FR" + ]; + "audio.allowed-rates" = [ + 44100 + 48000 + 88200 + 96000 + 176400 + 192000 + ]; + "device.api" = "dsp"; + "node.virtual" = "false"; + + # Lower seems to mean "more preferred", + # bluetooth devices seem to be ~1000, speakers seem to be ~2000 + # since this is between the two, bluetooth devices take over when they connect, + # and hand over to this instead of the speakers when they disconnect. + "priority.session" = 1500; + "priority.driver" = 1500; + "state.default-volume" = 0.343; + "device.icon-name" = "audio-card-analog-pci"; + }; + "playback.props" = { + "node.name" = "audio_effect.laptop-convolver"; + "target.object" = outputName; + "node.passive" = "true"; + "audio.channels" = "2"; + "audio.allowed-rates" = [ + 44100 + 48000 + 88200 + 96000 + 176400 + 192000 + ]; + "audio.position" = [ + "FL" + "FR" + ]; + "device.icon-name" = "audio-card-analog-pci"; + }; + }; + + configPackage = + (pkgs.writeTextDir "share/wireplumber/wireplumber.conf.d/99-laptop.conf" '' + monitor.alsa.rules = [ + { + matches = [{ node.name = "${outputName}" }] + actions = { + update-props = { + audio.allowed-rates = [44100, 48000, 88200, 96000, 176400, 192000] + } + } + } + ] + + node.software-dsp.rules = [ + { + matches = [{ node.name = "${outputName}" }] + actions = { + create-filter = { + filter-path = "${filter-chain}" + hide-parent = ${lib.boolToString cfg.hideRawDevice} + } + } + } + ] + + wireplumber.profiles = { + main = { node.software-dsp = "required" } + } + '') + // { + passthru.requiredLv2Packages = with pkgs; [ + lsp-plugins + bankstown-lv2 + ]; + }; + in + { + services.pipewire.wireplumber.configPackages = [ configPackage ]; + + # Pipewire is needed for this. + services.pipewire.enable = lib.mkDefault true; + + } + ); +} diff --git a/nixos/hosts/chrysalis/default.nix b/nixos/hosts/chrysalis/default.nix new file mode 100644 index 0000000..0a7de4f --- /dev/null +++ b/nixos/hosts/chrysalis/default.nix @@ -0,0 +1,176 @@ +# +# Per-system configuration. +# +# vim: et:ts=2:sw=2: +# +{ + config, + lib, + pkgs, + deprekages, + modulesPath, + ... +}: +{ + imports = [ + (modulesPath + "/installer/scan/not-detected.nix") + ./audio.nix + ./ec_kmod.nix + ]; + + # Bootloader. + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + # Networking. + networking.hostName = "chrysalis"; + networking.networkmanager = { + enable = true; + wifi.backend = "iwd"; + }; + networking.firewall.enable = false; + + # This is a local machine, rather than our typical network-accesed ones. + # Run an ssh-agent locally. + programs.ssh.startAgent = true; + + # Support our fingerprint reader. + services.fprintd.enable = true; + + # Support framework updates. + services.fwupd.enable = true; + + # Tools for the framework EC. + environment.systemPackages = [ + pkgs.framework-tool + deprekages.framework-13-icm + ]; + + # + # Niri configuration for our monitors. + # + home-manager.users.deprekated.programs.niri.settings = { + outputs."eDP-1".scale = 1.5; + }; + + # Override stylix font sizes. + stylix.fonts.sizes.desktop = lib.mkForce 16; + + # Accomodate the curved screen top by moving things in just a little. + deprekated.waybar.hostSpecificCss = '' + .modules-left > :first-child > * { + padding-left: 3ex; + } + + .modules-right > :last-child > * { + padding-right: 3ex; + } + ''; + + # Provide memtest86, since that's nice. + boot.loader.systemd-boot.memtest86.enable = true; + + # + # Hardware config. + # + # Use the latest kernel, and our patches, until the Dell+Alienware stuff makes it into + # more mainline kernels. We'll include ccache so we can iterate sanely. + boot.kernelPackages = pkgs.linuxPackages_latest; + + boot.extraModprobeConfig = '' + # Ensure we have a regulatory domain set for our wifi. + options cfg80211 ieee80211_regdom=NL + + # Support microphones via the TRRS jack. + options snd-hda-intel model=dell-headset-multi + ''; + boot.initrd.availableKernelModules = [ + "xhci_pci" + "thunderbolt" + "vmd" + "nvme" + "usbhid" + "usb_storage" + "sd_mod" + ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ + "thunderbolt" + ]; + + boot.kernelParams = [ + # Bluetooth stability tweaks. + "mt7925e.disable_aspm=1" + + # N.b. if we start experiencing GPU stalls, disabling PSR can help. + #"amdgpu.dcdebugmask=0x10" + ]; + + # Allow use of our brightness sensor for screen auto-leveling. + hardware.sensor.iio.enable = lib.mkDefault true; + + # Fix suspend with the ethernet expansion card. + services.udev.extraRules = '' + # Ethernet expansion card support + ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="0bda", ATTR{idProduct}=="8156", ATTR{power/autosuspend}="20" + ''; + + # Support ICC color profiles. + services.colord.enable = true; + + # Support thunderbolt. + services.hardware.bolt.enable = true; + + # Enable audio DSP filtering. + hardware.framework.laptop13.audioEnhancement = { + enable = true; + rawDeviceName = "alsa_output.pci-0000_c1_00.6.analog-stereo"; + }; + + # Support the framework EC from sysfs. + hardware.framework.enableKmod = true; + + # Support bluetooth. + hardware.bluetooth = { + enable = true; + powerOnBoot = false; + + settings = { + General = { + + # Support A2DP. + Enable = "Source,Sink,Media,Socket"; + + # Enable experimental featurees, like reading device battery levels. + Experimental = true; + }; + + }; + }; + + fileSystems."/" = { + device = "/dev/disk/by-uuid/bb880b80-992f-4e56-bb80-c5c4df0ddd72"; + fsType = "ext4"; + }; + + fileSystems."/boot" = { + device = "/dev/disk/by-uuid/5B37-C691"; + fsType = "vfat"; + options = [ + "fmask=0022" + "dmask=0022" + ]; + }; + + swapDevices = [ { device = "/dev/disk/by-uuid/50f20263-9632-439d-b57d-b9ee8f13d62b"; } ]; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.wlp0s20f3.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.amd.updateMicrocode = true; +} diff --git a/nixos/hosts/chrysalis/ec_kmod.nix b/nixos/hosts/chrysalis/ec_kmod.nix new file mode 100644 index 0000000..7cb5374 --- /dev/null +++ b/nixos/hosts/chrysalis/ec_kmod.nix @@ -0,0 +1,56 @@ +{ + config, + lib, + pkgs, + ... +}: +let + kernel_version_compatible = lib.versionAtLeast config.boot.kernelPackages.kernel.version "6.10"; +in +{ + options.hardware.framework.enableKmod = + (lib.mkEnableOption "Enable the community created Framework kernel module that allows interacting with the embedded controller from sysfs.") + // { + # enable by default on NixOS >= 24.05 and kernel >= 6.10 + default = lib.and (lib.versionAtLeast (lib.versions.majorMinor lib.version) "24.05") kernel_version_compatible; + defaultText = "enabled by default on NixOS >= 24.05 and kernel >= 6.10"; + }; + + config.boot = lib.mkIf config.hardware.framework.enableKmod { + extraModulePackages = with config.boot.kernelPackages; [ + framework-laptop-kmod + ]; + + # https://github.com/DHowett/framework-laptop-kmod?tab=readme-ov-file#usage + kernelModules = [ + "cros_ec" + "cros_ec_lpcs" + ]; + + # add required patch if enabled on kernel <6.10 + kernelPatches = lib.mkIf (!kernel_version_compatible) [ + rec { + name = "platform/chrome: cros_ec_lpc: add support for AMD Framework Laptops"; + msgid = "20240403004713.130365-1-dustin@howett.net"; + version = "3"; + hash = "sha256-aQSyys8CMzlj9EdNhg8vtp76fg1qEwUVeJL0E+8w5HU="; + patch = + pkgs.runCommandLocal "patch-${msgid}" + { + nativeBuildInputs = with pkgs; [ + b4 + git + cacert + ]; + SSL_CERT_FILE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; + + outputHash = hash; + } + '' + export HOME="$TMP" + PYTHONHASHSEED=0 ${pkgs.b4}/bin/b4 -n am -C -T -v ${version} -o- "${msgid}" > "$out" + ''; + } + ]; + }; +} diff --git a/nixos/hosts/komashi/default.nix b/nixos/hosts/komashi/default.nix index d10a4dd..7bacf31 100644 --- a/nixos/hosts/komashi/default.nix +++ b/nixos/hosts/komashi/default.nix @@ -71,48 +71,6 @@ services.blueman.enable = true; - # Allow the NFC reader on the trackpoint to be used as a smartcard reader. - hardware.nfc-nci.enable = true; - - # - # Niri configuration for our monitors. - # - # - home-manager.users.deprekated = { - programs.niri.settings = { - - # Left monitor. - outputs."DP-3" = { - position = { - x = 0; - y = 0; - }; - scale = 1.0; - }; - - # Laptop screen. - outputs."eDP-1" = { - position = { - x = 1920; - y = 0; - }; - scale = 1.0; - }; - - # Right monitor. - outputs."DP-1" = { - position = { - x = 1920 * 2; - y = 0; - }; - scale = 1.0; - }; - }; - - # Also position waybar on only one monitor. - programs.waybar.settings.mainBar.output = "eDP-1"; - }; - # Override stylix font sizes. stylix.fonts.sizes.desktop = lib.mkForce 16; @@ -163,5 +121,5 @@ # networking.interfaces.wlp0s20f3.useDHCP = lib.mkDefault true; nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; - hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; + hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; } diff --git a/packages/default.nix b/packages/default.nix index 7b793d4..1c44d47 100644 --- a/packages/default.nix +++ b/packages/default.nix @@ -111,6 +111,9 @@ flake-utils.lib.eachDefaultSystem ( hantek-udev-rules = callPackage ./hantek-udev-rules { }; linux-nfc-lenovo-udev-rules = callPackage ./linux-nfc-lenovo/udev.nix { }; + # color profiles + framework-13-icm = callPackage ./framework-13-icm { }; + # weechat weechat-discord = callPackage ./weechat-discord { }; diff --git a/packages/framework-13-icm/color-profile.icm b/packages/framework-13-icm/color-profile.icm new file mode 100644 index 0000000000000000000000000000000000000000..e067230fb68346d9d9c9cdfc6575d97067e9e589 GIT binary patch literal 9932 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 literal 0 HcmV?d00001 diff --git a/packages/framework-13-icm/default.nix b/packages/framework-13-icm/default.nix new file mode 100644 index 0000000..20cd036 --- /dev/null +++ b/packages/framework-13-icm/default.nix @@ -0,0 +1,13 @@ +{ stdenv, ... }: +stdenv.mkDerivation (finalAttrs: { + pname = "framework-13-icm"; + version = "0.0.1"; + + src = ./color-profile.icm; + dontUnpack = true; + + installPhase = '' + mkdir -p $out/share/color/icc/colord/ + cp ${finalAttrs.src} $out/share/color/icc/colord/framework-13.icm + ''; +}) diff --git a/wezterm/wezterm.lua b/wezterm/wezterm.lua index bcc6d72..5cef280 100644 --- a/wezterm/wezterm.lua +++ b/wezterm/wezterm.lua @@ -89,7 +89,7 @@ config = { font_overrides = { miko = 10, hinata = 15, - valere = 12, + chrysalis = 12, utol = 13, trailblazer = 11, kanbaru = 12, diff --git a/xonsh/chrysalis.xsh b/xonsh/chrysalis.xsh new file mode 100644 index 0000000..dbb97e9 --- /dev/null +++ b/xonsh/chrysalis.xsh @@ -0,0 +1,16 @@ +# +# Dotfile specifics for this host. +# + +# Path +# Note: lower in the list = higher priority +PATH_ADDS = [ + "/run/current-system/sw/bin" + "/run/wrappers/bin" +] + +# SSH key management. +try_source("includes/add-ssh-keys") + +# NixOS compatibility. +try_source("includes/nixos")