add obs, etc
This commit is contained in:
parent
746b703d70
commit
f367c42651
16 changed files with 844 additions and 31 deletions
|
|
@ -81,6 +81,7 @@
|
||||||
./home/sscoble.nix
|
./home/sscoble.nix
|
||||||
./home/pi.nix
|
./home/pi.nix
|
||||||
./home/wgu.nix
|
./home/wgu.nix
|
||||||
|
./home/macos.nix
|
||||||
{
|
{
|
||||||
home.homeDirectory = "/Users/sscoble";
|
home.homeDirectory = "/Users/sscoble";
|
||||||
nixpkgs.config.allowUnfree = true;
|
nixpkgs.config.allowUnfree = true;
|
||||||
|
|
|
||||||
56
home/bin/lid-handler.sh
Executable file
56
home/bin/lid-handler.sh
Executable file
|
|
@ -0,0 +1,56 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# ~/.config/hypr/scripts/lid-handler.sh
|
||||||
|
# Handles laptop lid close/open events for Hyprland.
|
||||||
|
# Called by Hyprland bindl (runs in user session context).
|
||||||
|
# Usage: lid-handler.sh close|open
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
EVENT="${1:-}" # "close" or "open"
|
||||||
|
|
||||||
|
# Determine lid state if not provided
|
||||||
|
if [ -z "$EVENT" ]; then
|
||||||
|
LID_STATE=$(cat /proc/acpi/button/lid/LID0/state 2>/dev/null || cat /proc/acpi/button/lid/LID/state 2>/dev/null || echo "open")
|
||||||
|
if echo "$LID_STATE" | grep -qi "closed"; then
|
||||||
|
EVENT="close"
|
||||||
|
else
|
||||||
|
EVENT="open"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Detect monitors via hyprctl
|
||||||
|
INTERNAL=$(hyprctl monitors -j 2>/dev/null | jq -r '.[] | select(.name | startswith("eDP")) | .name' | head -1 || echo "")
|
||||||
|
EXTERNAL=$(hyprctl monitors -j 2>/dev/null | jq -r '.[] | select(.name | startswith("eDP") | not) | .name' | head -1 || echo "")
|
||||||
|
|
||||||
|
# Fallback: try known names from hyprland.conf
|
||||||
|
[ -z "$INTERNAL" ] && INTERNAL="eDP-1"
|
||||||
|
[ -z "$EXTERNAL" ] && EXTERNAL="DP-3"
|
||||||
|
|
||||||
|
case "$EVENT" in
|
||||||
|
close)
|
||||||
|
if [ -n "$EXTERNAL" ]; then
|
||||||
|
# Move all workspaces to the external display first
|
||||||
|
WORKSPACES=$(hyprctl workspaces -j 2>/dev/null | jq -r '.[].id' || echo "")
|
||||||
|
for ws in $WORKSPACES; do
|
||||||
|
hyprctl dispatch moveworkspacetomonitor "$ws" "$EXTERNAL" 2>/dev/null || true
|
||||||
|
done
|
||||||
|
# Set external as primary (scale factor 1)
|
||||||
|
hyprctl keyword monitor "$EXTERNAL",preferred,auto,1 2>/dev/null || true
|
||||||
|
# Disable internal display
|
||||||
|
if [ -n "$INTERNAL" ]; then
|
||||||
|
hyprctl keyword monitor "$INTERNAL,disable" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
notify-send -t 3000 "Lid Closed" "Switched to $EXTERNAL as primary display"
|
||||||
|
else
|
||||||
|
notify-send -t 3000 "Lid Closed" "No external display detected — locking"
|
||||||
|
hyprlock 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
open)
|
||||||
|
# Re-enable internal display alongside external
|
||||||
|
if [ -n "$INTERNAL" ]; then
|
||||||
|
hyprctl keyword monitor "$INTERNAL,preferred,auto,1" 2>/dev/null || true
|
||||||
|
notify-send -t 3000 "Lid Opened" "Internal display $INTERNAL re-enabled"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
169
home/desktop.nix
169
home/desktop.nix
|
|
@ -5,6 +5,8 @@
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
# pi + qmd (from overlay)
|
# pi + qmd (from overlay)
|
||||||
qmd
|
qmd
|
||||||
|
# Browser
|
||||||
|
chromium
|
||||||
# Terminal
|
# Terminal
|
||||||
ghostty
|
ghostty
|
||||||
zellij
|
zellij
|
||||||
|
|
@ -19,6 +21,8 @@
|
||||||
awww
|
awww
|
||||||
btop
|
btop
|
||||||
fuzzel
|
fuzzel
|
||||||
|
# Screen recording / streaming
|
||||||
|
obs-studio
|
||||||
# Lock + idle
|
# Lock + idle
|
||||||
hyprlock
|
hyprlock
|
||||||
hypridle
|
hypridle
|
||||||
|
|
@ -40,9 +44,13 @@
|
||||||
bibata-cursors
|
bibata-cursors
|
||||||
papirus-icon-theme
|
papirus-icon-theme
|
||||||
adw-gtk3
|
adw-gtk3
|
||||||
|
beos-r5-icons
|
||||||
|
haiku-cursor
|
||||||
# Network / containers / system
|
# Network / containers / system
|
||||||
networkmanagerapplet
|
networkmanagerapplet
|
||||||
firefox
|
gh
|
||||||
|
winetricks
|
||||||
|
cabextract # required by winetricks for .cab extraction
|
||||||
tailscale
|
tailscale
|
||||||
docker
|
docker
|
||||||
dive
|
dive
|
||||||
|
|
@ -53,24 +61,58 @@
|
||||||
nmap
|
nmap
|
||||||
tcpdump
|
tcpdump
|
||||||
speedtest-cli
|
speedtest-cli
|
||||||
|
protonmail-bridge-gui
|
||||||
];
|
];
|
||||||
|
|
||||||
|
# === Proton Mail Bridge user service (starts at login) ===
|
||||||
|
systemd.user.services.protonmail-bridge = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Proton Mail Bridge";
|
||||||
|
After = [ "network-online.target" "graphical-session.target" ];
|
||||||
|
Wants = [ "network-online.target" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
Service = {
|
||||||
|
Type = "simple";
|
||||||
|
ExecStart = "${pkgs.protonmail-bridge}/bin/protonmail-bridge --non-interactive";
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = "5";
|
||||||
|
};
|
||||||
|
|
||||||
|
Install = {
|
||||||
|
WantedBy = [ "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
# === GTK / QT theming ===
|
# === GTK / QT theming ===
|
||||||
gtk = {
|
gtk = {
|
||||||
enable = true;
|
enable = true;
|
||||||
theme.name = "adw-gtk3-dark";
|
theme.name = "adw-gtk3-dark";
|
||||||
iconTheme.name = "Papirus-Dark";
|
iconTheme.name = "BeOS-r5";
|
||||||
cursorTheme = {
|
cursorTheme = {
|
||||||
name = "Bibata-Modern-Classic";
|
name = "Haiku_Cursor";
|
||||||
size = 24;
|
size = 24;
|
||||||
};
|
};
|
||||||
|
gtk3.extraConfig = {
|
||||||
|
gtk-application-prefer-dark-theme = 1;
|
||||||
|
};
|
||||||
|
gtk4.extraConfig = {
|
||||||
|
gtk-application-prefer-dark-theme = 1;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
qt = {
|
qt = {
|
||||||
enable = true;
|
enable = true;
|
||||||
platformTheme.name = "gtk";
|
platformTheme.name = "gtk3";
|
||||||
style.name = "adwaita-dark";
|
style.name = "adwaita-dark";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# === libadwaita dark mode ===
|
||||||
|
dconf.settings = {
|
||||||
|
"org/gnome/desktop/interface" = {
|
||||||
|
color-scheme = "prefer-dark";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
# === Hyprland WM config ===
|
# === Hyprland WM config ===
|
||||||
home.file.".config/hypr/hyprland.conf" = {
|
home.file.".config/hypr/hyprland.conf" = {
|
||||||
force = true;
|
force = true;
|
||||||
|
|
@ -165,7 +207,7 @@
|
||||||
layer = "top"; position = "top"; height = 32; spacing = 4; margin = "6 8 0 8";
|
layer = "top"; position = "top"; height = 32; spacing = 4; margin = "6 8 0 8";
|
||||||
modules-left = [ "hyprland/workspaces" ];
|
modules-left = [ "hyprland/workspaces" ];
|
||||||
modules-center = [ "clock" ];
|
modules-center = [ "clock" ];
|
||||||
modules-right = [ "tray" "pulseaudio" "backlight" "battery" "network" "cpu" "temperature" "memory" ];
|
modules-right = [ "tray" "bluetooth" "pulseaudio" "backlight" "battery" "network" "cpu" "temperature" "memory" ];
|
||||||
|
|
||||||
"hyprland/workspaces" = {
|
"hyprland/workspaces" = {
|
||||||
format = "{icon}";
|
format = "{icon}";
|
||||||
|
|
@ -175,7 +217,7 @@
|
||||||
};
|
};
|
||||||
persistent_workspaces = { "1" = []; "2" = []; "3" = []; "4" = []; "5" = []; };
|
persistent_workspaces = { "1" = []; "2" = []; "3" = []; "4" = []; "5" = []; };
|
||||||
};
|
};
|
||||||
clock = { format = "{:%a %b %d %H:%M}"; tooltip-format = "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>"; };
|
clock = { format = "{:%a %b %d %I:%M %p}"; tooltip-format = "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>"; };
|
||||||
cpu = { format = " {usage}%"; };
|
cpu = { format = " {usage}%"; };
|
||||||
temperature = { format = " {temperatureC}°C"; interval = 10; thermal-zone = 5; };
|
temperature = { format = " {temperatureC}°C"; interval = 10; thermal-zone = 5; };
|
||||||
memory = { format = " {}%"; };
|
memory = { format = " {}%"; };
|
||||||
|
|
@ -193,6 +235,15 @@
|
||||||
format = "{icon} {volume}%"; format-bluetooth = "{icon} {volume}%"; format-muted = "";
|
format = "{icon} {volume}%"; format-bluetooth = "{icon} {volume}%"; format-muted = "";
|
||||||
format-icons.default = [ "" "" "" ]; on-click = "pavucontrol";
|
format-icons.default = [ "" "" "" ]; on-click = "pavucontrol";
|
||||||
};
|
};
|
||||||
|
bluetooth = {
|
||||||
|
format = "";
|
||||||
|
format-connected = " {device_alias}";
|
||||||
|
format-disabled = "";
|
||||||
|
format-no-controller = "";
|
||||||
|
format-off = "";
|
||||||
|
tooltip-format = "{device_alias} — {device_address}";
|
||||||
|
on-click = "blueman-manager";
|
||||||
|
};
|
||||||
tray.spacing = 10;
|
tray.spacing = 10;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -204,7 +255,7 @@
|
||||||
#workspaces button { padding: 0 6px; color: #6c7086; background: transparent; border-radius: 4px; }
|
#workspaces button { padding: 0 6px; color: #6c7086; background: transparent; border-radius: 4px; }
|
||||||
#workspaces button.active { color: #cdd6f4; background: #45475a; }
|
#workspaces button.active { color: #cdd6f4; background: #45475a; }
|
||||||
#workspaces button:hover { color: #cdd6f4; background: #313244; }
|
#workspaces button:hover { color: #cdd6f4; background: #313244; }
|
||||||
#clock, #cpu, #memory, #backlight, #battery, #network, #pulseaudio, #tray { padding: 0 10px; color: #cdd6f4; }
|
#clock, #cpu, #memory, #backlight, #battery, #network, #pulseaudio, #bluetooth, #tray { padding: 0 10px; color: #cdd6f4; }
|
||||||
#cpu.warning, #memory.warning, #battery.warning { color: #f9e2af; }
|
#cpu.warning, #memory.warning, #battery.warning { color: #f9e2af; }
|
||||||
#cpu.critical, #memory.critical, #battery.critical { color: #f38ba8; }
|
#cpu.critical, #memory.critical, #battery.critical { color: #f38ba8; }
|
||||||
tooltip { background: rgba(30,30,46,0.95); border: 1px solid #45475a; border-radius: 6px; }
|
tooltip { background: rgba(30,30,46,0.95); border: 1px solid #45475a; border-radius: 6px; }
|
||||||
|
|
@ -213,7 +264,7 @@
|
||||||
# === Rofi launcher ===
|
# === Rofi launcher ===
|
||||||
home.file.".config/rofi/config.rasi" = {
|
home.file.".config/rofi/config.rasi" = {
|
||||||
force = true;
|
force = true;
|
||||||
source = ./rofi-config.rasi;
|
source = ./spotlight-dark.rasi;
|
||||||
};
|
};
|
||||||
# === Dunst notifications ===
|
# === Dunst notifications ===
|
||||||
home.file.".config/dunst/dunstrc".text = ''
|
home.file.".config/dunst/dunstrc".text = ''
|
||||||
|
|
@ -230,8 +281,110 @@
|
||||||
[urgency_normal] background = "#1e1e2e"; foreground = "#cdd6f4"; timeout = 5
|
[urgency_normal] background = "#1e1e2e"; foreground = "#cdd6f4"; timeout = 5
|
||||||
[urgency_critical] background = "#f38ba8"; foreground = "#1e1e2e"; timeout = 0
|
[urgency_critical] background = "#f38ba8"; foreground = "#1e1e2e"; timeout = 0
|
||||||
'';
|
'';
|
||||||
|
# === Lid handler ===
|
||||||
|
home.file.".config/hypr/scripts/lid-handler.sh" = {
|
||||||
|
force = true;
|
||||||
|
executable = true;
|
||||||
|
source = ./bin/lid-handler.sh;
|
||||||
|
};
|
||||||
|
|
||||||
# === Wallpaper rotation ===
|
# === Wallpaper rotation ===
|
||||||
home.file.".local/bin/wallpaper-rotate" = {
|
home.file.".local/bin/wallpaper-rotate" = {
|
||||||
|
force = true;
|
||||||
source = ./wallpaper-rotate.sh;
|
source = ./wallpaper-rotate.sh;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# === BeOS cursor theme installer ===
|
||||||
|
home.file.".local/bin/install-beos-cursor" = {
|
||||||
|
force = true;
|
||||||
|
executable = true;
|
||||||
|
text = ''
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
CURSOR_NAME="BeOS"
|
||||||
|
ICONS_DIR="$HOME/.local/share/icons"
|
||||||
|
CURSOR_DIR="$ICONS_DIR/$CURSOR_NAME"
|
||||||
|
|
||||||
|
echo "==> BeOS Cursor Installer"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [ -d "$CURSOR_DIR" ] && [ -f "$CURSOR_DIR/index.theme" ]; then
|
||||||
|
echo " ✅ BeOS cursor already installed at $CURSOR_DIR"
|
||||||
|
echo ""
|
||||||
|
echo "To switch to it:"
|
||||||
|
echo " gsettings set org.gnome.desktop.interface cursor-theme BeOS"
|
||||||
|
echo " # Or update ~/.config/gtk-3.0/settings.ini:"
|
||||||
|
echo " # gtk-cursor-theme-name=BeOS"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "To install BeOS cursors:"
|
||||||
|
echo " 1. Open https://www.gnome-look.org/p/999293/ in your browser"
|
||||||
|
echo " 2. Download the BeOS-Cursors.tar.gz"
|
||||||
|
echo " 3. Run: install-beos-cursor /path/to/BeOS-Cursors.tar.gz"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [ $# -eq 0 ]; then
|
||||||
|
echo "No file provided. See instructions above."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ARCHIVE="$1"
|
||||||
|
if [ ! -f "$ARCHIVE" ]; then
|
||||||
|
echo " ❌ File not found: $ARCHIVE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "==> Installing BeOS cursor from $ARCHIVE..."
|
||||||
|
mkdir -p "$ICONS_DIR"
|
||||||
|
tar xzf "$ARCHIVE" -C "$ICONS_DIR" 2>/dev/null || tar xzf "$ARCHIVE" -C "$ICONS_DIR" --strip-components=1 2>/dev/null || true
|
||||||
|
|
||||||
|
if [ -f "$CURSOR_DIR/index.theme" ]; then
|
||||||
|
echo " ✅ Installed to $CURSOR_DIR"
|
||||||
|
echo ""
|
||||||
|
echo "Now switch to BeOS cursor:"
|
||||||
|
echo " gsettings set org.gnome.desktop.interface cursor-theme BeOS"
|
||||||
|
else
|
||||||
|
# Try to find what was extracted
|
||||||
|
echo " Checking extracted directories..."
|
||||||
|
find "$ICONS_DIR" -name "index.theme" -exec dirname {} \\; 2>/dev/null | head -5
|
||||||
|
echo ""
|
||||||
|
echo "The extracted cursor directories are listed above."
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# === Logos Bible Software (Wine) ===
|
||||||
|
|
||||||
|
# Helper script: first run installs Logos, subsequent runs launch it
|
||||||
|
home.file.".local/bin/logos" = {
|
||||||
|
force = true;
|
||||||
|
executable = true;
|
||||||
|
text = ''
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Launch Logos Bible Software as a Chromium web app
|
||||||
|
exec chromium --app="https://app.logos.com" --name="Logos" "$@"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# Logos web app icon
|
||||||
|
home.file.".local/share/icons/hicolor/scalable/apps/logos.svg".source = ./logos-icon.svg;
|
||||||
|
|
||||||
|
# Desktop entry for Logos web app
|
||||||
|
home.file.".local/share/applications/logos.desktop" = {
|
||||||
|
force = true;
|
||||||
|
text = ''
|
||||||
|
[Desktop Entry]
|
||||||
|
Type=Application
|
||||||
|
Name=Logos Bible Software
|
||||||
|
Comment=Logos Bible Software (Web App)
|
||||||
|
Exec=logos
|
||||||
|
Icon=logos
|
||||||
|
Terminal=false
|
||||||
|
Categories=Office;Education;Network;
|
||||||
|
StartupWMClass=logos
|
||||||
|
MimeType=x-scheme-handler/logos;
|
||||||
|
'';
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ monitor=,preferred,auto,1
|
||||||
monitor=DP-3,preferred,auto,1.5
|
monitor=DP-3,preferred,auto,1.5
|
||||||
|
|
||||||
env = XCURSOR_SIZE,24
|
env = XCURSOR_SIZE,24
|
||||||
env = XCURSOR_THEME,Bibata-Modern-Classic
|
env = XCURSOR_THEME,Haiku_Cursor
|
||||||
env = GTK_THEME,adw-gtk3-dark
|
env = GTK_THEME,adw-gtk3-dark
|
||||||
env = QT_QPA_PLATFORMTHEME,gtk2
|
env = QT_QPA_PLATFORMTHEME,gtk2
|
||||||
|
|
||||||
|
|
@ -14,11 +14,12 @@ exec-once = wl-paste --type text --watch cliphist store
|
||||||
exec-once = wl-paste --type image --watch cliphist store
|
exec-once = wl-paste --type image --watch cliphist store
|
||||||
exec-once = hypridle
|
exec-once = hypridle
|
||||||
exec-once = ~/.local/bin/wallpaper-rotate
|
exec-once = ~/.local/bin/wallpaper-rotate
|
||||||
|
exec-once = blueman-applet
|
||||||
|
|
||||||
# Auto-launch apps into their workspaces
|
# Auto-launch apps (window rules place them in correct workspaces)
|
||||||
exec-once = [workspace 1 silent] ghostty -e zellij
|
exec-once = ghostty -e zellij
|
||||||
exec-once = [workspace 3 silent] firefox
|
exec-once = firefox
|
||||||
exec-once = [workspace 4 silent] discord
|
exec-once = discord
|
||||||
|
|
||||||
input {
|
input {
|
||||||
kb_layout = us
|
kb_layout = us
|
||||||
|
|
@ -85,9 +86,11 @@ bind = $mainMod SHIFT, Return, exec, ghostty
|
||||||
bind = $mainMod, B, exec, firefox
|
bind = $mainMod, B, exec, firefox
|
||||||
bind = $mainMod, D, exec, fuzzel
|
bind = $mainMod, D, exec, fuzzel
|
||||||
bind = $mainMod, Space, exec, fuzzel
|
bind = $mainMod, Space, exec, fuzzel
|
||||||
|
bind = $mainMod SHIFT, Space, exec, rofi -show drun
|
||||||
bind = $mainMod, V, exec, cliphist list | rofi -dmenu | cliphist decode | wl-copy
|
bind = $mainMod, V, exec, cliphist list | rofi -dmenu | cliphist decode | wl-copy
|
||||||
bind = $mainMod, N, exec, thunar
|
bind = $mainMod, N, exec, thunar
|
||||||
bind = $mainMod, L, exec, hyprlock
|
bind = $mainMod, L, exec, hyprlock
|
||||||
|
bind = $mainMod, X, exec, blueman-manager
|
||||||
bind = $mainMod, Q, killactive
|
bind = $mainMod, Q, killactive
|
||||||
bind = $mainMod, F, fullscreen
|
bind = $mainMod, F, fullscreen
|
||||||
bind = $mainMod, G, togglefloating
|
bind = $mainMod, G, togglefloating
|
||||||
|
|
@ -137,6 +140,10 @@ bindel = , XF86MonBrightnessDown, exec, brightnessctl set 5%-
|
||||||
bind = $mainMod SHIFT, Q, exec, hyprctl dispatch exit
|
bind = $mainMod SHIFT, Q, exec, hyprctl dispatch exit
|
||||||
bind = $mainMod SHIFT, R, exec, hyprctl reload
|
bind = $mainMod SHIFT, R, exec, hyprctl reload
|
||||||
|
|
||||||
|
# Lid switch: close → external display only, open → restore internal
|
||||||
|
bindl = , switch:on:Lid Switch, exec, ~/.config/hypr/scripts/lid-handler.sh close
|
||||||
|
bindl = , switch:off:Lid Switch, exec, ~/.config/hypr/scripts/lid-handler.sh open
|
||||||
|
|
||||||
|
|
||||||
windowrule = match:class ^(pavucontrol)$, float on
|
windowrule = match:class ^(pavucontrol)$, float on
|
||||||
windowrule = match:class ^(firefox)$, match:title PIP, float on
|
windowrule = match:class ^(firefox)$, match:title PIP, float on
|
||||||
|
|
|
||||||
4
home/logos-icon.svg
Normal file
4
home/logos-icon.svg
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="48" height="48">
|
||||||
|
<rect width="48" height="48" rx="8" fill="#2c2c2c"/>
|
||||||
|
<text font-family="Georgia, serif" font-size="28" font-weight="bold" fill="#f0c040" x="50%" y="55%" text-anchor="middle" dominant-baseline="central">L</text>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 306 B |
270
home/macos.nix
Normal file
270
home/macos.nix
Normal file
|
|
@ -0,0 +1,270 @@
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# === macOS-specific configuration ===
|
||||||
|
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
# macOS window manager
|
||||||
|
aerospace
|
||||||
|
|
||||||
|
# Keyboard remapping (GUI app — download separately or install via brew)
|
||||||
|
# brew install --cask karabiner-elements
|
||||||
|
];
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# KEYBOARD GOAL: Consistent finger positions across keyboards
|
||||||
|
#
|
||||||
|
# ThinkPad T490 (Linux): Ctrl | Super(Win) | Alt | Space
|
||||||
|
# Keychron V10M (macOS): Ctrl | Alt(⌥) | Cmd | Space ← remapped
|
||||||
|
# After remap (macOS): Ctrl | Super(Cmd) | Alt | Space
|
||||||
|
#
|
||||||
|
# Muscle memory:
|
||||||
|
# Middle key → Super/Cmd = WM actions (workspaces, focus, move)
|
||||||
|
# Next to space → Alt/Option = app shortcuts
|
||||||
|
#
|
||||||
|
# Remap: Physical Alt(⌥) → Cmd(⌘), Physical Cmd(⌘) → Alt(⌥)
|
||||||
|
# Applied via Karabiner-Elements, targeted to Keychron only.
|
||||||
|
#
|
||||||
|
# To find your Keychron's vendor/product IDs:
|
||||||
|
# 1. Open Karabiner-Elements → EventViewer tab
|
||||||
|
# 2. Press a key on the Keychron
|
||||||
|
# 3. Note the "VendorID" and "ProductID" values
|
||||||
|
# 4. Update them in the JSON below
|
||||||
|
#
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
home.file.".config/karabiner/karabiner.json" = {
|
||||||
|
force = true;
|
||||||
|
text = builtins.toJSON {
|
||||||
|
global = {
|
||||||
|
check_for_updates_on_startup = false;
|
||||||
|
show_in_menu_bar = false;
|
||||||
|
show_profile_name_in_menu_bar = false;
|
||||||
|
};
|
||||||
|
profiles = [
|
||||||
|
{
|
||||||
|
name = "Default";
|
||||||
|
selected = true;
|
||||||
|
simple_modifications = [];
|
||||||
|
fn_function_keys = [];
|
||||||
|
virtual_hid_keyboard = {
|
||||||
|
keyboard_type = "ansi";
|
||||||
|
caps_lock_delay_microseconds = 0;
|
||||||
|
};
|
||||||
|
devices = [];
|
||||||
|
complex_modifications = {
|
||||||
|
parameters = {
|
||||||
|
"basic.simultaneous_threshold_milliseconds" = 50;
|
||||||
|
"basic.to_if_held_down_threshold_milliseconds" = 500;
|
||||||
|
"basic.to_delayed_action_delay_milliseconds" = 500;
|
||||||
|
"basic.to_if_alone_timeout_milliseconds" = 1000;
|
||||||
|
};
|
||||||
|
rules = [
|
||||||
|
{
|
||||||
|
description = "Keychron V10M: swap Option ↔ Command (match ThinkPad bottom row)";
|
||||||
|
manipulators = [
|
||||||
|
{
|
||||||
|
# Physical Alt(⌥) → sends Cmd(⌘) = Super/WM key
|
||||||
|
type = "basic";
|
||||||
|
from = {
|
||||||
|
key_code = "left_alt";
|
||||||
|
modifiers = { optional = [ "any" ]; };
|
||||||
|
};
|
||||||
|
to = [ { key_code = "left_gui"; } ];
|
||||||
|
conditions = [
|
||||||
|
{
|
||||||
|
type = "device_if";
|
||||||
|
identifiers = [
|
||||||
|
{
|
||||||
|
# ⚠ UPDATE THESE with your Keychron's IDs
|
||||||
|
vendor_id = 0;
|
||||||
|
product_id = 0;
|
||||||
|
description = "Keychron V10M (Alice 75)";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
# Physical Cmd(⌘) → sends Alt(⌥) = Alt key
|
||||||
|
type = "basic";
|
||||||
|
from = {
|
||||||
|
key_code = "left_gui";
|
||||||
|
modifiers = { optional = [ "any" ]; };
|
||||||
|
};
|
||||||
|
to = [ { key_code = "left_alt"; } ];
|
||||||
|
conditions = [
|
||||||
|
{
|
||||||
|
type = "device_if";
|
||||||
|
identifiers = [
|
||||||
|
{
|
||||||
|
vendor_id = 0;
|
||||||
|
product_id = 0;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# AEROSPACE — macOS Tiling Window Manager
|
||||||
|
#
|
||||||
|
# Keybindings use `cmd` (Super after remap) to match Hyprland's SUPER:
|
||||||
|
# Middle key + number → switch workspace
|
||||||
|
# Middle key + h/j/k/l → focus direction
|
||||||
|
# Middle key + tab → focus next window (cycle through all workspaces)
|
||||||
|
# Middle key + shift → move window
|
||||||
|
#
|
||||||
|
# macOS-native Cmd+Tab (now Alt+Tab after remap) still cycles apps.
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
home.file.".config/aerospace/aerospace.toml" = {
|
||||||
|
force = true;
|
||||||
|
text = ''
|
||||||
|
# =============================================================================
|
||||||
|
# Aerospace — macOS Tiling Window Manager
|
||||||
|
#
|
||||||
|
# Keybinding conventions (after Keychron remap matches ThinkPad):
|
||||||
|
# cmd (middle key) = SUPER — WM actions
|
||||||
|
# alt (next to space) = ALT — app shortcuts
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# --- General ---
|
||||||
|
[general]
|
||||||
|
border = true
|
||||||
|
gaps = {
|
||||||
|
inner = { px = 6, vertical = 8, horizontal = 8 },
|
||||||
|
outer = { px = 4, px-monitor-workspace = 4, bottom = 6 },
|
||||||
|
}
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# WORKSPACE SWITCHING — cmd = middle key
|
||||||
|
# =============================================================================
|
||||||
|
[mode.main.binding]
|
||||||
|
# Switch to workspace
|
||||||
|
cmd-1 = "workspace 1"
|
||||||
|
cmd-2 = "workspace 2"
|
||||||
|
cmd-3 = "workspace 3"
|
||||||
|
cmd-4 = "workspace 4"
|
||||||
|
cmd-5 = "workspace 5"
|
||||||
|
cmd-6 = "workspace 6"
|
||||||
|
cmd-7 = "workspace 7"
|
||||||
|
cmd-8 = "workspace 8"
|
||||||
|
cmd-9 = "workspace 9"
|
||||||
|
|
||||||
|
# Move window to workspace
|
||||||
|
cmd-shift-1 = "move-node-to-workspace 1"
|
||||||
|
cmd-shift-2 = "move-node-to-workspace 2"
|
||||||
|
cmd-shift-3 = "move-node-to-workspace 3"
|
||||||
|
cmd-shift-4 = "move-node-to-workspace 4"
|
||||||
|
cmd-shift-5 = "move-node-to-workspace 5"
|
||||||
|
cmd-shift-6 = "move-node-to-workspace 6"
|
||||||
|
cmd-shift-7 = "move-node-to-workspace 7"
|
||||||
|
cmd-shift-8 = "move-node-to-workspace 8"
|
||||||
|
cmd-shift-9 = "move-node-to-workspace 9"
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# FOCUS NAVIGATION — Vim-style with cmd (middle key)
|
||||||
|
# =============================================================================
|
||||||
|
cmd-h = "focus left"
|
||||||
|
cmd-j = "focus down"
|
||||||
|
cmd-k = "focus up"
|
||||||
|
cmd-l = "focus right"
|
||||||
|
|
||||||
|
# Tab through windows across all workspaces
|
||||||
|
cmd-tab = "focus next"
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# WINDOW MANAGEMENT
|
||||||
|
# =============================================================================
|
||||||
|
cmd-f = "fullscreen"
|
||||||
|
cmd-w = "close"
|
||||||
|
cmd-t = "floating toggle"
|
||||||
|
cmd-d = "layout tiles horizontal vertical"
|
||||||
|
cmd-shift-d = "layout tiles vertical horizontal"
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# LAYOUT MANAGEMENT
|
||||||
|
# =============================================================================
|
||||||
|
cmd-r = "mode resize"
|
||||||
|
|
||||||
|
cmd-shift-h = "move left"
|
||||||
|
cmd-shift-j = "move down"
|
||||||
|
cmd-shift-k = "move up"
|
||||||
|
cmd-shift-l = "move right"
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# RESIZE MODE
|
||||||
|
# =============================================================================
|
||||||
|
[mode.resize.binding]
|
||||||
|
cmd-h = "resize -50 0"
|
||||||
|
cmd-j = "resize 0 50"
|
||||||
|
cmd-k = "resize 0 -50"
|
||||||
|
cmd-l = "resize 50 0"
|
||||||
|
escape = "mode main"
|
||||||
|
enter = "mode main"
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# MISC
|
||||||
|
# =============================================================================
|
||||||
|
cmd-shift-period = "reload-config"
|
||||||
|
cmd-backslash = "layout v_accordion"
|
||||||
|
cmd-shift-slash = "layout h_accordion"
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# APP CYCLING
|
||||||
|
#
|
||||||
|
# macOS natively handles app cycling via Cmd+Tab.
|
||||||
|
# After Karabiner remap, the physical key next to spacebar now sends Alt,
|
||||||
|
# so what was Cmd+Tab is now available as a distinct chord.
|
||||||
|
# We use cmd+tab (middle key + tab) for Aerospace's "focus next" above,
|
||||||
|
# and the macOS native cycle is still accessible via alt+tab (next-to-space + tab).
|
||||||
|
# =============================================================================
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# HELPER: Find Keychron keyboard IDs for Karabiner
|
||||||
|
# =============================================================================
|
||||||
|
home.file.".local/bin/find-keychron-id" = {
|
||||||
|
force = true;
|
||||||
|
executable = true;
|
||||||
|
text = ''
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Find your Keychron's vendor/product IDs for Karabiner-Elements config.
|
||||||
|
#
|
||||||
|
# Usage: ./find-keychron-id
|
||||||
|
#
|
||||||
|
# If Karabiner EventViewer is running, check its log for recent key events.
|
||||||
|
LOG="$HOME/.local/share/karabiner/eventviewer.log"
|
||||||
|
if [ -f "$LOG" ]; then
|
||||||
|
echo "Checking Karabiner EventViewer log..."
|
||||||
|
grep -i "keychron\|vendor_id\|product_id" "$LOG" 2>/dev/null | tail -10
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Alternative: use ioreg to list HID devices
|
||||||
|
echo ""
|
||||||
|
echo "All HID keyboard devices (look for Keychron):"
|
||||||
|
ioreg -p IOUSB -l -w 0 | grep -A 10 -i "keyboard\|keychron" 2>/dev/null || \\
|
||||||
|
ioreg -r -c IOUSBDevice -l -w 0 | grep -A 15 -i "keychron\|keyboard" | grep -E "vendor|product|idProduct|idVendor|USB Product Name" | head -20
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Or press a key on your Keychron and run:"
|
||||||
|
echo " hidutil list 2>/dev/null | grep -i keychron"
|
||||||
|
echo ""
|
||||||
|
echo "Then update vendor_id and product_id (as DECIMAL numbers) in:"
|
||||||
|
echo " ~/.config/karabiner/karabiner.json"
|
||||||
|
echo ""
|
||||||
|
echo " e.g. if vendor_id=0x3434, product_id=0x0408"
|
||||||
|
echo " then in JSON: vendor_id=13364, product_id=1032"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
150
home/spotlight-dark.rasi
Normal file
150
home/spotlight-dark.rasi
Normal file
|
|
@ -0,0 +1,150 @@
|
||||||
|
/* Spotlight-Dark — macOS-inspired Rofi theme */
|
||||||
|
|
||||||
|
configuration {
|
||||||
|
modi: "drun,run,window";
|
||||||
|
show-icons: true;
|
||||||
|
icon-theme: "Papirus-Dark";
|
||||||
|
drun-display-format: "{name}";
|
||||||
|
font: "JetBrainsMono Nerd Font 14";
|
||||||
|
matching: "fuzzy";
|
||||||
|
terminal: "ghostty";
|
||||||
|
fuzzy-match: true;
|
||||||
|
scrollbar: false;
|
||||||
|
sidebar-mode: false;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
bg-col: rgba(30, 30, 46, 0.93);
|
||||||
|
bg-alt: rgba(49, 50, 68, 0.95);
|
||||||
|
fg-col: rgba(205, 214, 244, 1.0);
|
||||||
|
fg-dim: rgba(205, 214, 244, 0.5);
|
||||||
|
sel-bg: rgba(137, 180, 250, 0.18);
|
||||||
|
urgent-col: rgba(243, 139, 168, 1.0);
|
||||||
|
border-col: rgba(137, 180, 250, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
window {
|
||||||
|
width: 520px;
|
||||||
|
location: center;
|
||||||
|
anchor: center;
|
||||||
|
fullscreen: false;
|
||||||
|
y-offset: -120px;
|
||||||
|
|
||||||
|
border: 0px;
|
||||||
|
border-radius: 14px;
|
||||||
|
background-color: @bg-col;
|
||||||
|
text-color: @fg-col;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mainbox {
|
||||||
|
padding: 0;
|
||||||
|
children: [ inputbar, listview ];
|
||||||
|
spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inputbar {
|
||||||
|
padding: 14px 18px;
|
||||||
|
background-color: @bg-alt;
|
||||||
|
border-radius: 14px 14px 0 0;
|
||||||
|
margin: 0;
|
||||||
|
children: [ entry, case-indicator ];
|
||||||
|
spacing: 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry {
|
||||||
|
background: transparent;
|
||||||
|
text-color: @fg-col;
|
||||||
|
caret-color: @fg-col;
|
||||||
|
placeholder-color: @fg-dim;
|
||||||
|
placeholder: "Search apps, commands...";
|
||||||
|
expand: true;
|
||||||
|
horizontal-align: 0;
|
||||||
|
vertical-align: 0.5;
|
||||||
|
font: "JetBrainsMono Nerd Font 14";
|
||||||
|
}
|
||||||
|
|
||||||
|
case-indicator {
|
||||||
|
background: transparent;
|
||||||
|
text-color: @fg-dim;
|
||||||
|
font: "JetBrainsMono Nerd Font 10";
|
||||||
|
spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
listview {
|
||||||
|
background: transparent;
|
||||||
|
padding: 6px 0;
|
||||||
|
lines: 8;
|
||||||
|
columns: 1;
|
||||||
|
spacing: 0;
|
||||||
|
cycle: true;
|
||||||
|
dynamic: true;
|
||||||
|
scrollbar: false;
|
||||||
|
layout: vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
element {
|
||||||
|
padding: 10px 18px;
|
||||||
|
border-radius: 0;
|
||||||
|
text-color: @fg-col;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
element normal.normal {
|
||||||
|
background-color: transparent;
|
||||||
|
text-color: @fg-col;
|
||||||
|
}
|
||||||
|
|
||||||
|
element selected.normal {
|
||||||
|
background-color: @sel-bg;
|
||||||
|
text-color: @fg-col;
|
||||||
|
}
|
||||||
|
|
||||||
|
element urgent.normal {
|
||||||
|
text-color: @urgent-col;
|
||||||
|
}
|
||||||
|
|
||||||
|
element-icon {
|
||||||
|
size: 22px;
|
||||||
|
padding: 0 12px 0 0;
|
||||||
|
horizontal-align: 0;
|
||||||
|
vertical-align: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
element-text {
|
||||||
|
padding: 0;
|
||||||
|
vertical-align: 0.5;
|
||||||
|
horizontal-align: 0;
|
||||||
|
text-color: inherit;
|
||||||
|
font: "JetBrainsMono Nerd Font 12";
|
||||||
|
}
|
||||||
|
|
||||||
|
element-text selected {
|
||||||
|
text-color: @fg-col;
|
||||||
|
}
|
||||||
|
|
||||||
|
message {
|
||||||
|
margin: 0;
|
||||||
|
padding: 10px 18px;
|
||||||
|
border-radius: 0 0 14px 14px;
|
||||||
|
background-color: @bg-alt;
|
||||||
|
text-color: @fg-dim;
|
||||||
|
}
|
||||||
|
|
||||||
|
textbox {
|
||||||
|
padding: 4px 8px;
|
||||||
|
text-color: @fg-dim;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
text-color: @fg-col;
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollbar {
|
||||||
|
width: 4px;
|
||||||
|
border: 0;
|
||||||
|
handle-width: 4px;
|
||||||
|
handle-color: @border-col;
|
||||||
|
}
|
||||||
|
|
@ -45,20 +45,22 @@
|
||||||
# === Git Config ===
|
# === Git Config ===
|
||||||
programs.git = {
|
programs.git = {
|
||||||
enable = true;
|
enable = true;
|
||||||
userName = "Scott Scoble";
|
settings = {
|
||||||
userEmail = "sscoble@scobleclaw.dev";
|
user = {
|
||||||
extraConfig = {
|
name = "Scott Scoble";
|
||||||
|
email = "sscoble@scobleclaw.dev";
|
||||||
|
};
|
||||||
init.defaultBranch = "main";
|
init.defaultBranch = "main";
|
||||||
pull.rebase = true;
|
pull.rebase = true;
|
||||||
push.autoSetupRemote = true;
|
push.autoSetupRemote = true;
|
||||||
core.editor = "nvim";
|
core.editor = "nvim";
|
||||||
};
|
alias = {
|
||||||
aliases = {
|
lol = "log --graph --oneline --decorate --all";
|
||||||
lol = "log --graph --oneline --decorate --all";
|
co = "checkout";
|
||||||
co = "checkout";
|
br = "branch";
|
||||||
br = "branch";
|
st = "status";
|
||||||
st = "status";
|
ci = "commit";
|
||||||
ci = "commit";
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -156,7 +158,7 @@
|
||||||
l = "ls -CF";
|
l = "ls -CF";
|
||||||
nix-clean = "sudo nix-collect-garbage -d && nix-collect-garbage -d";
|
nix-clean = "sudo nix-collect-garbage -d && nix-collect-garbage -d";
|
||||||
};
|
};
|
||||||
initExtra = ''
|
initContent = ''
|
||||||
# Nix flake shortcuts (adapts to platform)
|
# Nix flake shortcuts (adapts to platform)
|
||||||
if command -v nixos-rebuild &>/dev/null; then
|
if command -v nixos-rebuild &>/dev/null; then
|
||||||
alias nr="sudo nixos-rebuild switch --flake git+https://os.scoble.me/forgejo/sscoble/laptop-config.git#laptop"
|
alias nr="sudo nixos-rebuild switch --flake git+https://os.scoble.me/forgejo/sscoble/laptop-config.git#laptop"
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@
|
||||||
|
|
||||||
# Browsers
|
# Browsers
|
||||||
brave
|
brave
|
||||||
firefox
|
|
||||||
|
|
||||||
# Note-taking
|
# Note-taking
|
||||||
obsidian
|
obsidian
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,49 @@
|
||||||
# Session variables
|
# Session variables
|
||||||
environment.sessionVariables.NIXOS_OZONE_WL = "1";
|
environment.sessionVariables.NIXOS_OZONE_WL = "1";
|
||||||
|
|
||||||
|
# === Lid close behavior ===
|
||||||
|
# Don't suspend when lid closes — external display stays active
|
||||||
|
services.logind = {
|
||||||
|
lidSwitch = "ignore";
|
||||||
|
lidSwitchExternalPower = "ignore";
|
||||||
|
lidSwitchDocked = "ignore";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Fallback ACPI handler for lid events outside Hyprland session
|
||||||
|
# Primary handling is done via Hyprland bindl in hyprland.conf
|
||||||
|
services.acpid = {
|
||||||
|
enable = true;
|
||||||
|
handlers.lid = {
|
||||||
|
event = "button/lid.*";
|
||||||
|
action = ''
|
||||||
|
${pkgs.bash}/bin/bash -c '
|
||||||
|
LID_STATE=$(cat /proc/acpi/button/lid/LID0/state 2>/dev/null || cat /proc/acpi/button/lid/LID/state 2>/dev/null || echo "open")
|
||||||
|
if echo "$LID_STATE" | grep -qi "closed"; then
|
||||||
|
EVENT="close"
|
||||||
|
else
|
||||||
|
EVENT="open"
|
||||||
|
fi
|
||||||
|
for user_dir in /run/user/*/hypr/; do
|
||||||
|
[ -d "$user_dir" ] || continue
|
||||||
|
SIG=$(ls "$user_dir" 2>/dev/null | head -1)
|
||||||
|
[ -z "$SIG" ] && continue
|
||||||
|
UID=$(basename $(dirname "$user_dir"))
|
||||||
|
USER=$(id -nu $UID 2>/dev/null || echo "sscoble")
|
||||||
|
HOME_DIR=$(getent passwd "$USER" | cut -d: -f6)
|
||||||
|
USER_SCRIPT="$HOME_DIR/.config/hypr/scripts/lid-handler.sh"
|
||||||
|
if [ -x "$USER_SCRIPT" ]; then
|
||||||
|
sudo -u "$USER" \
|
||||||
|
XDG_RUNTIME_DIR="/run/user/$UID" \
|
||||||
|
HYPRLAND_INSTANCE_SIGNATURE="$SIG" \
|
||||||
|
"$USER_SCRIPT" "$EVENT"
|
||||||
|
fi
|
||||||
|
break
|
||||||
|
done
|
||||||
|
'
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
# Security — required for hyprlock
|
# Security — required for hyprlock
|
||||||
security.pam.services.hyprlock = {};
|
security.pam.services.hyprlock = {};
|
||||||
|
|
||||||
|
|
@ -82,6 +125,15 @@
|
||||||
hardware.bluetooth.enable = true;
|
hardware.bluetooth.enable = true;
|
||||||
hardware.bluetooth.powerOnBoot = true;
|
hardware.bluetooth.powerOnBoot = true;
|
||||||
|
|
||||||
|
# Bluetooth manager (GUI pairing, tray applet)
|
||||||
|
# Note: using manual setup instead of services.blueman.enable to avoid
|
||||||
|
# a systemd unit bug (duplicate ExecStart in blueman-applet.service).
|
||||||
|
# The applet is launched via exec-once in hyprland.conf instead.
|
||||||
|
environment.systemPackages = with pkgs; [ blueman ];
|
||||||
|
services.dbus.packages = with pkgs; [ blueman ];
|
||||||
|
systemd.user.services.blueman-applet = { enable = false; };
|
||||||
|
systemd.user.services.blueman-manager = { enable = false; };
|
||||||
|
|
||||||
# NetworkManager applet
|
# NetworkManager applet
|
||||||
programs.nm-applet.enable = true;
|
programs.nm-applet.enable = true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,8 +43,15 @@
|
||||||
wineWow64Packages.stable
|
wineWow64Packages.stable
|
||||||
];
|
];
|
||||||
|
|
||||||
# DNS fallback (Tailscale MagicDNS sometimes blocks public resolvers)
|
# === WiFi / NetworkManager (imperative — not idempotent) ===
|
||||||
networking.nameservers = [ "1.1.1.1" "8.8.8.8" ];
|
# We move between SSIDs regularly, so NO declarative wifi networks here.
|
||||||
|
# Use nm-applet (tray) or nmcli (CLI) to connect to any SSID at runtime.
|
||||||
|
# Connections persist across reboots via /etc/NetworkManager/system-connections/
|
||||||
|
networking.networkmanager.enable = true;
|
||||||
|
|
||||||
|
# DNS handed out by NM to each connection; Tailscale MagicDNS can interfere
|
||||||
|
# with public resolvers, so we inject Cloudflare + Google as fallbacks.
|
||||||
|
networking.networkmanager.insertNameservers = [ "1.1.1.1" "8.8.8.8" ];
|
||||||
|
|
||||||
# Passwordless sudo for sscoble
|
# Passwordless sudo for sscoble
|
||||||
security.sudo.extraRules = [
|
security.sudo.extraRules = [
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
# Enable network printer discovery via mDNS/Bonjour
|
# Enable network printer discovery via mDNS/Bonjour
|
||||||
services.avahi = {
|
services.avahi = {
|
||||||
enable = true;
|
enable = true;
|
||||||
nssmdns = true;
|
nssmdns4 = true;
|
||||||
publish = {
|
publish = {
|
||||||
enable = true;
|
enable = true;
|
||||||
addresses = true;
|
addresses = true;
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,51 @@
|
||||||
# === powertop ===
|
# === powertop ===
|
||||||
powerManagement.powertop.enable = true;
|
powerManagement.powertop.enable = true;
|
||||||
|
|
||||||
# Skip thermald — conflicts with throttled (enabled by nixos-hardware)
|
# === throttled — undervolt + raise trip temp for better sustained perf ===
|
||||||
|
services.throttled = {
|
||||||
|
extraConfig = ''
|
||||||
|
[GENERAL]
|
||||||
|
Enabled: True
|
||||||
|
Sysfs_Power_Path: /sys/class/power_supply/AC*/online
|
||||||
|
Autoreload: True
|
||||||
|
|
||||||
|
[BATTERY]
|
||||||
|
Update_Rate_s: 30
|
||||||
|
PL1_Tdp_W: 29
|
||||||
|
PL1_Duration_s: 28
|
||||||
|
PL2_Tdp_W: 29
|
||||||
|
PL2_Duration_S: 0.002
|
||||||
|
Trip_Temp_C: 85
|
||||||
|
cTDP: 0
|
||||||
|
Disable_BDPROCHOT: False
|
||||||
|
|
||||||
|
[AC]
|
||||||
|
Update_Rate_s: 5
|
||||||
|
PL1_Tdp_W: 44
|
||||||
|
PL1_Duration_s: 28
|
||||||
|
PL2_Tdp_W: 44
|
||||||
|
PL2_Duration_S: 0.002
|
||||||
|
Trip_Temp_C: 97
|
||||||
|
cTDP: 0
|
||||||
|
Disable_BDPROCHOT: False
|
||||||
|
|
||||||
|
[UNDERVOLT.BATTERY]
|
||||||
|
CORE: -70
|
||||||
|
GPU: -50
|
||||||
|
CACHE: -70
|
||||||
|
UNCORE: -40
|
||||||
|
ANALOGIO: -40
|
||||||
|
|
||||||
|
[UNDERVOLT.AC]
|
||||||
|
CORE: -80
|
||||||
|
GPU: -50
|
||||||
|
CACHE: -80
|
||||||
|
UNCORE: -50
|
||||||
|
ANALOGIO: -50
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# Skip thermald — conflicts with throttled
|
||||||
services.thermald.enable = false;
|
services.thermald.enable = false;
|
||||||
|
|
||||||
# === zram swap (faster + saves NVMe writes) ===
|
# === zram swap (faster + saves NVMe writes) ===
|
||||||
|
|
@ -135,11 +179,14 @@
|
||||||
# === Tailscale (consistent cluster access from any network) ===
|
# === Tailscale (consistent cluster access from any network) ===
|
||||||
services.tailscale.enable = true;
|
services.tailscale.enable = true;
|
||||||
|
|
||||||
|
# === Proton Mail Bridge (local IMAP/SMTP for Proton Mail) ===
|
||||||
|
# The systemd user service is defined in home/desktop.nix
|
||||||
|
|
||||||
# === NVMe tools ===
|
# === NVMe tools ===
|
||||||
environment.systemPackages = with pkgs; [ nvme-cli ];
|
environment.systemPackages = with pkgs; [ nvme-cli protonmail-bridge ];
|
||||||
|
|
||||||
# === Touchpad & TrackPoint ===
|
# === Touchpad & TrackPoint ===
|
||||||
services.xserver.libinput = {
|
services.libinput = {
|
||||||
enable = true;
|
enable = true;
|
||||||
touchpad = {
|
touchpad = {
|
||||||
tapping = true;
|
tapping = true;
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,7 @@ final: prev: {
|
||||||
qmd = final.writeShellScriptBin "qmd" ''
|
qmd = final.writeShellScriptBin "qmd" ''
|
||||||
exec ${final.bun}/bin/bunx --bun @tobilu/qmd "$@"
|
exec ${final.bun}/bin/bunx --bun @tobilu/qmd "$@"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
beos-r5-icons = final.callPackage ./pkgs/beos-r5-icons { };
|
||||||
|
haiku-cursor = final.callPackage ./pkgs/haiku-cursor { };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
34
pkgs/beos-r5-icons/default.nix
Normal file
34
pkgs/beos-r5-icons/default.nix
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
{ lib, stdenvNoCC, fetchFromGitHub }:
|
||||||
|
|
||||||
|
stdenvNoCC.mkDerivation {
|
||||||
|
pname = "beos-r5-icons";
|
||||||
|
version = "2021-03-24";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "jcherven";
|
||||||
|
repo = "BeOS-r5-Icons";
|
||||||
|
rev = "1c1067eabaeb0196c12606ac19b2aed4496bc15e";
|
||||||
|
hash = "sha256-6qnOWMdwgK9tKifHXSF6s1KjHkdIG/jnM9Te43cVOjo=";
|
||||||
|
};
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/share/icons/BeOS-r5
|
||||||
|
cp -pr * $out/share/icons/BeOS-r5/
|
||||||
|
# Remove broken symlinks (icon theme has some dangling links)
|
||||||
|
find $out/share/icons/BeOS-r5 -type l -not -exec test -e {} \; -delete
|
||||||
|
rm -f $out/share/icons/BeOS-r5/screenshot.png
|
||||||
|
rm -f $out/share/icons/BeOS-r5/.icon-theme.cache
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Classic BeOS r5 icons for Linux desktops";
|
||||||
|
longDescription = ''
|
||||||
|
A large collection of BeOS & period-correct icons.
|
||||||
|
Includes icons from BeOS-r5, Zeta OS, Haiku OS, KDEclassic, and more.
|
||||||
|
'';
|
||||||
|
homepage = "https://github.com/jcherven/BeOS-r5-Icons";
|
||||||
|
license = licenses.gpl2Plus;
|
||||||
|
platforms = platforms.linux;
|
||||||
|
maintainers = [ ];
|
||||||
|
};
|
||||||
|
}
|
||||||
28
pkgs/haiku-cursor/default.nix
Normal file
28
pkgs/haiku-cursor/default.nix
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
{ lib, stdenvNoCC, fetchurl }:
|
||||||
|
|
||||||
|
stdenvNoCC.mkDerivation {
|
||||||
|
pname = "haiku-cursor";
|
||||||
|
version = "linux-02";
|
||||||
|
|
||||||
|
src = fetchurl {
|
||||||
|
url = "https://github.com/leath-dub/Haiku_Cursor/releases/download/linux-02/Haiku_Cursor.tgz";
|
||||||
|
hash = "sha256-AXgo+jqrCjEyDpWL6GnpUAbvx3Oje+7zQvnIC8j1uz0=";
|
||||||
|
};
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/share/icons/Haiku_Cursor
|
||||||
|
cp -pr * $out/share/icons/Haiku_Cursor/
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Haiku/BeOS-style XCursor theme";
|
||||||
|
longDescription = ''
|
||||||
|
A port of the Haiku cursor set as an XCursor theme.
|
||||||
|
These cursors are faithful to the BeOS/Haiku look.
|
||||||
|
'';
|
||||||
|
homepage = "https://github.com/leath-dub/Haiku_Cursor";
|
||||||
|
license = licenses.mit;
|
||||||
|
platforms = platforms.linux;
|
||||||
|
maintainers = [ ];
|
||||||
|
};
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue