updated quickshell
This commit is contained in:
37
README.md
37
README.md
@@ -1,3 +1,9 @@
|
|||||||
|
# NixOS Configs
|
||||||
|
|
||||||
|
Reproducible multi-host NixOS + Hyprland ("Silicon Volt") configuration.
|
||||||
|
|
||||||
|
## Install (new machine)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Setup disks
|
# Setup disks
|
||||||
nix run --experimental-features "nix-common flakes" github:nix-community/disko -- --mode disko --flake .#hades
|
nix run --experimental-features "nix-common flakes" github:nix-community/disko -- --mode disko --flake .#hades
|
||||||
@@ -8,3 +14,34 @@ nixos-install --flake .#hades
|
|||||||
# set password
|
# set password
|
||||||
nixos-enter --root /mnt -- passwd anish
|
nixos-enter --root /mnt -- passwd anish
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Rebuild (existing machine)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rebuild switch # zsh helper: sudo nixos-rebuild switch --flake ~/NixOS-Configs#<host>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Adding a new host (e.g. a laptop)
|
||||||
|
|
||||||
|
1. Create `hosts/<name>/` with `default.nix`, `hardware-configuration.nix`, and
|
||||||
|
(optionally) `disko.nix`; import the shared modules (`modules/core`,
|
||||||
|
`modules/graphical`, `modules/apps`).
|
||||||
|
2. Register it in `flake.nix` under `nixosConfigurations`.
|
||||||
|
3. Declare host-specific displays in `hosts/<name>/default.nix`:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
home-manager.users.anish.volt.monitors = [
|
||||||
|
{
|
||||||
|
output = "eDP-1"; # or "desc:<panel description>"
|
||||||
|
mode = "2880x1800@120Hz"; # or "preferred"
|
||||||
|
position = "auto";
|
||||||
|
scale = 2;
|
||||||
|
vrr = null; # optional per-monitor VRR
|
||||||
|
}
|
||||||
|
{ output = ""; mode = "preferred"; position = "auto"; scale = "auto"; } # fallback
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
The `volt.monitors` default (any output @ preferred) keeps every machine working
|
||||||
|
out of the box; hosts override only what they need. Hosts without an NVIDIA GPU
|
||||||
|
simply don't import `modules/hardware/nvidia.nix` — all vendor env vars live there.
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
./brave.nix
|
./brave.nix
|
||||||
./zsh.nix
|
./zsh.nix
|
||||||
./nvim
|
./nvim
|
||||||
|
./rofi.nix
|
||||||
|
|
||||||
./pi.nix
|
./pi.nix
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ in
|
|||||||
style = "beam";
|
style = "beam";
|
||||||
blink = "yes";
|
blink = "yes";
|
||||||
beam-thickness = 1.5;
|
beam-thickness = 1.5;
|
||||||
|
color = "0e0e0e cffc00";
|
||||||
};
|
};
|
||||||
|
|
||||||
mouse = {
|
mouse = {
|
||||||
@@ -40,34 +41,34 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
colors = {
|
colors = {
|
||||||
alpha = 0.90;
|
alpha = 0.92;
|
||||||
background = "18181a";
|
background = "131313";
|
||||||
foreground = "f2f2f7";
|
foreground = "e5e2e1";
|
||||||
|
|
||||||
# macOS Catalina Apple System Dark Palette
|
# Silicon Volt palette (anish.govind.cc)
|
||||||
regular0 = "1c1c1e"; # Black / Slate
|
regular0 = "1c1b1b"; # Glass Black
|
||||||
regular1 = "ff453a"; # Apple Red
|
regular1 = "ff7a59"; # Coral Red
|
||||||
regular2 = "30d158"; # Apple Green
|
regular2 = "cffc00"; # Electric Lime (green)
|
||||||
regular3 = "ffd60a"; # Apple Yellow
|
regular3 = "e3ff66"; # Volt Light (yellow)
|
||||||
regular4 = "0a84ff"; # Apple Blue
|
regular4 = "00bfff"; # Sky Blue
|
||||||
regular5 = "bf5af2"; # Apple Purple
|
regular5 = "c6c6c7"; # Neutral Gray (magenta)
|
||||||
regular6 = "64d2ff"; # Apple Cyan
|
regular6 = "66d9ff"; # Light Cyan
|
||||||
regular7 = "f2f2f7"; # Apple Light Gray
|
regular7 = "e5e2e1"; # Light Gray
|
||||||
|
|
||||||
# Bright Colors
|
# Bright Colors
|
||||||
bright0 = "636366"; # Gray
|
bright0 = "5c5a59"; # Dim Gray
|
||||||
bright1 = "ff6961"; # Bright Red
|
bright1 = "ff9a82"; # Bright Coral
|
||||||
bright2 = "34c759"; # Bright Green
|
bright2 = "dfff66"; # Bright Lime
|
||||||
bright3 = "ffe066"; # Bright Yellow
|
bright3 = "f0ff8c"; # Bright Volt
|
||||||
bright4 = "409cff"; # Bright Blue
|
bright4 = "66d9ff"; # Bright Blue
|
||||||
bright5 = "c774f4"; # Bright Purple
|
bright5 = "e0e0e1"; # Bright Gray
|
||||||
bright6 = "70d7ff"; # Bright Cyan
|
bright6 = "99e6ff"; # Bright Cyan
|
||||||
bright7 = "ffffff"; # Pure White
|
bright7 = "ffffff"; # Pure White
|
||||||
|
|
||||||
# Selection & URLs
|
# Selection & URLs - volt lime selection like the site
|
||||||
selection-foreground = "ffffff";
|
selection-foreground = "0e0e0e";
|
||||||
selection-background = "0058d0"; # Apple selection blue
|
selection-background = "cffc00";
|
||||||
urls = "0a84ff";
|
urls = "00bfff";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
{ pkgs, ... }:
|
{ pkgs, lib, config, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
# Deterministic Silicon Volt wallpaper: rendered from SVG at build time,
|
||||||
|
# so the same source always produces a byte-identical image.
|
||||||
|
wallpaper = pkgs.runCommand "silicon-volt-wallpaper.png" { } ''
|
||||||
|
${pkgs.librsvg}/bin/rsvg-convert -w 3840 -h 2160 ${./wallpaper.svg} > $out
|
||||||
|
'';
|
||||||
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./hyprland.nix
|
./hyprland.nix
|
||||||
@@ -15,10 +22,51 @@
|
|||||||
wl-clipboard
|
wl-clipboard
|
||||||
cliphist
|
cliphist
|
||||||
brightnessctl
|
brightnessctl
|
||||||
|
jq
|
||||||
|
|
||||||
# Desktop Environment / Hyprland ecosystem
|
# Desktop Environment / Hyprland ecosystem
|
||||||
hyprpaper
|
hyprpaper
|
||||||
rofi
|
|
||||||
hyprpolkitagent
|
hyprpolkitagent
|
||||||
];
|
];
|
||||||
|
|
||||||
|
# Build-time rendered wallpaper
|
||||||
|
xdg.dataFile."backgrounds/silicon-volt.png".source = wallpaper;
|
||||||
|
|
||||||
|
# hyprpaper: load the Silicon Volt wallpaper on every output
|
||||||
|
xdg.configFile."hypr/hyprpaper.conf".text = ''
|
||||||
|
preload = ${config.home.homeDirectory}/.local/share/backgrounds/silicon-volt.png
|
||||||
|
wallpaper = ,${config.home.homeDirectory}/.local/share/backgrounds/silicon-volt.png
|
||||||
|
splash = false
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Notifications: flat brutalist-glass cards with volt accents
|
||||||
|
services.mako = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
background-color = "#1c1b1bee";
|
||||||
|
text-color = "#e5e2e1";
|
||||||
|
border-color = "#cffc00";
|
||||||
|
border-size = 1;
|
||||||
|
border-radius = 0;
|
||||||
|
width = 420;
|
||||||
|
margin = "12";
|
||||||
|
padding = "14";
|
||||||
|
default-timeout = 6000;
|
||||||
|
font = "JetBrainsMono Nerd Font 11";
|
||||||
|
format = "<b>%s</b>\\n%b";
|
||||||
|
"icon-location" = "left";
|
||||||
|
max-icon-size = 48;
|
||||||
|
|
||||||
|
"urgency=critical" = {
|
||||||
|
border-color = "#ff7a59";
|
||||||
|
text-color = "#ffffff";
|
||||||
|
default-timeout = 0;
|
||||||
|
};
|
||||||
|
"urgency=low" = {
|
||||||
|
border-color = "#2a2929";
|
||||||
|
text-color = "#adaaaa";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
general = {
|
general = {
|
||||||
lock_cmd = "pidof hyprlock || hyprlock";
|
lock_cmd = "pidof hyprlock || hyprlock";
|
||||||
before_sleep_cmd = "loginctl lock-session";
|
before_sleep_cmd = "loginctl lock-session";
|
||||||
after_sleep_cmd = "hyprctl dispatch dpms on";
|
after_sleep_cmd = "hyprctl dispatch \"hl.dsp.dpms({off = false})\"";
|
||||||
};
|
};
|
||||||
|
|
||||||
listener = [
|
listener = [
|
||||||
@@ -24,10 +24,12 @@
|
|||||||
on-timeout = "loginctl lock-session";
|
on-timeout = "loginctl lock-session";
|
||||||
}
|
}
|
||||||
# 3. Turn off displays (DPMS) after 10 minutes
|
# 3. Turn off displays (DPMS) after 10 minutes
|
||||||
|
# NOTE: Hyprland's Lua config bridge requires typed dispatcher calls;
|
||||||
|
# `hyprctl dispatch dpms off` is mangled into invalid Lua.
|
||||||
{
|
{
|
||||||
timeout = 600;
|
timeout = 600;
|
||||||
on-timeout = "hyprctl dispatch dpms off";
|
on-timeout = "hyprctl dispatch \"hl.dsp.dpms({off = true})\"";
|
||||||
on-resume = "hyprctl dispatch dpms on";
|
on-resume = "hyprctl dispatch \"hl.dsp.dpms({off = false})\"";
|
||||||
}
|
}
|
||||||
# 4. Suspend system after 30 minutes
|
# 4. Suspend system after 30 minutes
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,10 +1,58 @@
|
|||||||
{ pkgs, lib, ... }:
|
{ pkgs, lib, config, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
mkLua = lib.generators.mkLuaInline;
|
mkLua = lib.generators.mkLuaInline;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
wayland.windowManager.hyprland = {
|
# -------------------------------------------------------------------------
|
||||||
|
# Per-host monitor configuration.
|
||||||
|
#
|
||||||
|
# Hosts declare their displays once, in hosts/<host>/default.nix, via:
|
||||||
|
# home-manager.users.anish.volt.monitors = [ { ... } ];
|
||||||
|
# and the setting flows into Hyprland here. The default (empty output +
|
||||||
|
# preferred mode) works on any machine with any display.
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
options.volt.monitors = lib.mkOption {
|
||||||
|
description = "Hyprland monitor rules for this host";
|
||||||
|
type = lib.types.listOf (lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
output = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "";
|
||||||
|
description = "Output name or desc: match. Empty string matches every output.";
|
||||||
|
};
|
||||||
|
mode = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "preferred";
|
||||||
|
description = "Resolution@refresh, e.g. \"3840x2160@164.99Hz\" or \"preferred\".";
|
||||||
|
};
|
||||||
|
position = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "auto";
|
||||||
|
};
|
||||||
|
scale = lib.mkOption {
|
||||||
|
type = lib.types.either lib.types.number lib.types.str;
|
||||||
|
default = "auto";
|
||||||
|
};
|
||||||
|
vrr = lib.mkOption {
|
||||||
|
type = lib.types.nullOr (lib.types.either lib.types.number lib.types.str);
|
||||||
|
default = null;
|
||||||
|
description = "Optional per-monitor VRR setting (0/1/on-demand).";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
default = [
|
||||||
|
{ output = ""; mode = "preferred"; position = "auto"; scale = "auto"; }
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
wayland.windowManager.hyprland.settings.monitor = map (m:
|
||||||
|
{ inherit (m) output mode position scale; }
|
||||||
|
// (lib.optionalAttrs (m.vrr != null) { inherit (m) vrr; })
|
||||||
|
) config.volt.monitors;
|
||||||
|
|
||||||
|
wayland.windowManager.hyprland = {
|
||||||
enable = true;
|
enable = true;
|
||||||
configType = "lua";
|
configType = "lua";
|
||||||
package = null; # Hyprland package is managed system-wide via NixOS programs.hyprland
|
package = null; # Hyprland package is managed system-wide via NixOS programs.hyprland
|
||||||
@@ -18,45 +66,16 @@ in
|
|||||||
browser = { _var = "brave"; };
|
browser = { _var = "brave"; };
|
||||||
|
|
||||||
# -----------------------------------------------------------------------
|
# -----------------------------------------------------------------------
|
||||||
# 2. Monitors (hl.monitor)
|
# 2. Monitors (hl.monitor) - declared per-host via volt.monitors
|
||||||
|
# (see hosts/<host>/default.nix); defaults to any display @ preferred.
|
||||||
# -----------------------------------------------------------------------
|
# -----------------------------------------------------------------------
|
||||||
monitor = [
|
|
||||||
{
|
|
||||||
output = "eDP-2";
|
|
||||||
mode = "3840x2160@144";
|
|
||||||
position = "0x0";
|
|
||||||
scale = 2;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
output = "desc:Dell Inc. DELL U3419W 28DQ5T2";
|
|
||||||
mode = "3440x1440@60";
|
|
||||||
position = "0x-1440";
|
|
||||||
scale = 1;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
output = "desc:Samsung Electric Company Odyssey Ark H1AK500000";
|
|
||||||
mode = "3840x2160@144";
|
|
||||||
position = "3840x0";
|
|
||||||
scale = 1;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
output = "";
|
|
||||||
mode = "preferred";
|
|
||||||
position = "auto";
|
|
||||||
scale = "auto";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------
|
# -----------------------------------------------------------------------
|
||||||
# 3. Environment Variables (hl.env)
|
# 3. Environment Variables (hl.env)
|
||||||
# -----------------------------------------------------------------------
|
# -----------------------------------------------------------------------
|
||||||
env = [
|
env = [
|
||||||
{ _args = [ "XCURSOR_SIZE" "24" ]; }
|
{ _args = [ "XCURSOR_SIZE" "24" ]; }
|
||||||
{ _args = [ "LIBVA_DRIVE_NAME" "nvidia" ]; }
|
|
||||||
{ _args = [ "XDG_SESSION_TYPE" "wayland" ]; }
|
{ _args = [ "XDG_SESSION_TYPE" "wayland" ]; }
|
||||||
{ _args = [ "GBM_BACKEND" "nvidia-drm" ]; }
|
|
||||||
{ _args = [ "WLR_NO_HARDWARE_CURSORS" "1" ]; }
|
|
||||||
{ _args = [ "WLR_DRM_DEVICES" "/dev/dri/card1:/dev/dri/card0" ]; }
|
|
||||||
];
|
];
|
||||||
|
|
||||||
# -----------------------------------------------------------------------
|
# -----------------------------------------------------------------------
|
||||||
@@ -76,6 +95,9 @@ in
|
|||||||
|
|
||||||
cursor = {
|
cursor = {
|
||||||
inactive_timeout = 3;
|
inactive_timeout = 3;
|
||||||
|
# Hardware cursors ON (explicit). Note: this replaces the old
|
||||||
|
# WLR_NO_HARDWARE_CURSORS=1, which forced software rendering.
|
||||||
|
no_hardware_cursors = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
general = {
|
general = {
|
||||||
@@ -83,11 +105,12 @@ in
|
|||||||
gaps_out = 10;
|
gaps_out = 10;
|
||||||
border_size = 2;
|
border_size = 2;
|
||||||
col = {
|
col = {
|
||||||
|
# Silicon Volt: electric lime gradient on focus, glass gray at rest
|
||||||
active_border = {
|
active_border = {
|
||||||
colors = [ "rgba(33ccffee)" "rgba(00ff99ee)" ];
|
colors = [ "rgba(cffc00ee)" "rgba(e3ff66ee)" ];
|
||||||
angle = 45;
|
angle = 45;
|
||||||
};
|
};
|
||||||
inactive_border = "rgba(595959aa)";
|
inactive_border = "rgba(ffffff14)";
|
||||||
};
|
};
|
||||||
layout = "dwindle";
|
layout = "dwindle";
|
||||||
};
|
};
|
||||||
@@ -95,19 +118,19 @@ in
|
|||||||
group = {
|
group = {
|
||||||
groupbar = {
|
groupbar = {
|
||||||
font_size = 14;
|
font_size = 14;
|
||||||
font_family = "SF Pro Display";
|
font_family = "JetBrainsMono Nerd Font";
|
||||||
col = {
|
col = {
|
||||||
active = "rgba(33ccff00)";
|
active = "rgba(cffc0022)";
|
||||||
inactive = "rgba(59595900)";
|
inactive = "rgba(ffffff08)";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
col = {
|
col = {
|
||||||
border_active = {
|
border_active = {
|
||||||
colors = [ "rgba(33ccffee)" "rgba(00ff99ee)" ];
|
colors = [ "rgba(cffc00ee)" "rgba(e3ff66ee)" ];
|
||||||
angle = 45;
|
angle = 45;
|
||||||
};
|
};
|
||||||
border_inactive = "rgba(595959aa)";
|
border_inactive = "rgba(ffffff14)";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -117,19 +140,25 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
decoration = {
|
decoration = {
|
||||||
rounding = 10;
|
rounding = 4;
|
||||||
|
|
||||||
|
# Subtle glass blur to match the brutalist-glass aesthetic
|
||||||
blur = {
|
blur = {
|
||||||
enabled = false;
|
enabled = true;
|
||||||
size = 3;
|
size = 4;
|
||||||
passes = 1;
|
passes = 2;
|
||||||
|
new_optimizations = true;
|
||||||
|
ignore_opacity = true;
|
||||||
|
contrast = 1.1;
|
||||||
|
brightness = 0.9;
|
||||||
|
vibrancy = 0.1;
|
||||||
};
|
};
|
||||||
|
|
||||||
shadow = {
|
shadow = {
|
||||||
enabled = false;
|
enabled = true;
|
||||||
range = 4;
|
range = 12;
|
||||||
render_power = 3;
|
render_power = 3;
|
||||||
color = "rgba(1a1a1aee)";
|
color = "rgba(00000066)";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -180,6 +209,9 @@ in
|
|||||||
(mkLua ''function()
|
(mkLua ''function()
|
||||||
hl.exec_cmd("quickshell")
|
hl.exec_cmd("quickshell")
|
||||||
hl.exec_cmd("hyprpaper")
|
hl.exec_cmd("hyprpaper")
|
||||||
|
hl.exec_cmd("mako")
|
||||||
|
hl.exec_cmd("wl-paste --type text --watch cliphist store")
|
||||||
|
hl.exec_cmd("wl-paste --type image --watch cliphist store")
|
||||||
hl.exec_cmd("${pkgs.hyprpolkitagent}/libexec/hyprpolkitagent")
|
hl.exec_cmd("${pkgs.hyprpolkitagent}/libexec/hyprpolkitagent")
|
||||||
end'')
|
end'')
|
||||||
];
|
];
|
||||||
@@ -196,7 +228,7 @@ in
|
|||||||
{ _args = [ (mkLua "mainMod .. \" + SPACE\"") (mkLua "hl.dsp.exec_cmd(\"quickshell ipc call spotlight toggle || rofi -show combi -show-icons\")") ]; }
|
{ _args = [ (mkLua "mainMod .. \" + SPACE\"") (mkLua "hl.dsp.exec_cmd(\"quickshell ipc call spotlight toggle || rofi -show combi -show-icons\")") ]; }
|
||||||
{ _args = [ (mkLua "mainMod .. \" + N\"") (mkLua "hl.dsp.exec_cmd(\"quickshell ipc call controlCenter toggle || swaync-client -t -sw\")") ]; }
|
{ _args = [ (mkLua "mainMod .. \" + N\"") (mkLua "hl.dsp.exec_cmd(\"quickshell ipc call controlCenter toggle || swaync-client -t -sw\")") ]; }
|
||||||
{ _args = [ (mkLua "mainMod .. \" + V\"") (mkLua "hl.dsp.window.float({ action = \"toggle\" })") ]; }
|
{ _args = [ (mkLua "mainMod .. \" + V\"") (mkLua "hl.dsp.window.float({ action = \"toggle\" })") ]; }
|
||||||
{ _args = [ (mkLua "mainMod .. \" + R\"") (mkLua "hl.dsp.exec_cmd(\"quickshell ipc call spotlight toggle || rofi -show combi -show-icons\")") ]; }
|
{ _args = [ (mkLua "mainMod .. \" + R\"") (mkLua "hl.dsp.exec_cmd(\"rofi -show combi\")") ]; }
|
||||||
{ _args = [ (mkLua "mainMod .. \" + G\"") (mkLua "hl.dsp.group.toggle()") ]; }
|
{ _args = [ (mkLua "mainMod .. \" + G\"") (mkLua "hl.dsp.group.toggle()") ]; }
|
||||||
{ _args = [ (mkLua "mainMod .. \" + F\"") (mkLua "hl.dsp.window.fullscreen({ fullscreen = 0 })") ]; }
|
{ _args = [ (mkLua "mainMod .. \" + F\"") (mkLua "hl.dsp.window.fullscreen({ fullscreen = 0 })") ]; }
|
||||||
|
|
||||||
@@ -274,30 +306,30 @@ in
|
|||||||
{
|
{
|
||||||
_args = [
|
_args = [
|
||||||
"XF86MonBrightnessUp"
|
"XF86MonBrightnessUp"
|
||||||
(mkLua "hl.dsp.exec_cmd(\"brightnessctl -d acpi_video0 set 5%+\")")
|
(mkLua "hl.dsp.exec_cmd(\"brightnessctl set 5%+\")")
|
||||||
{ repeating = true; locked = true; }
|
{ repeating = true; locked = true; }
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
_args = [
|
_args = [
|
||||||
"XF86MonBrightnessDown"
|
"XF86MonBrightnessDown"
|
||||||
(mkLua "hl.dsp.exec_cmd(\"brightnessctl -d acpi_video0 set 5%-\")")
|
(mkLua "hl.dsp.exec_cmd(\"brightnessctl set 5%-\")")
|
||||||
{ repeating = true; locked = true; }
|
{ repeating = true; locked = true; }
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
# Lid switch
|
# Lid switch - generically detects the embedded (eDP*) panel on any laptop
|
||||||
{
|
{
|
||||||
_args = [
|
_args = [
|
||||||
"switch:off:Lid Switch"
|
"switch:off:Lid Switch"
|
||||||
(mkLua "hl.dsp.exec_cmd(\"hyprctl keyword monitor \\\"eDP-2,3840x2160@144,0x0,2\\\"\")")
|
(mkLua "hl.dsp.exec_cmd(\"m=$(hyprctl monitors | awk '$1==\\\"Monitor\\\"{print $2; exit}'); [ -n \\\"$m\\\" ] && hyprctl keyword monitor \\\"$m, preferred, auto, auto\\\"\")")
|
||||||
{ locked = true; }
|
{ locked = true; }
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
_args = [
|
_args = [
|
||||||
"switch:on:Lid Switch"
|
"switch:on:Lid Switch"
|
||||||
(mkLua "hl.dsp.exec_cmd(\"hyprctl keyword monitor \\\"eDP-2, disable\\\"\")")
|
(mkLua "hl.dsp.exec_cmd(\"m=$(hyprctl monitors | awk '$1==\\\"Monitor\\\"{print $2; exit}'); [ -n \\\"$m\\\" ] && hyprctl keyword monitor \\\"$m, disable\\\"\")")
|
||||||
{ locked = true; }
|
{ locked = true; }
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -364,5 +396,6 @@ in
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,41 +10,65 @@
|
|||||||
grace = 0;
|
grace = 0;
|
||||||
hide_cursor = true;
|
hide_cursor = true;
|
||||||
no_fade_in = false;
|
no_fade_in = false;
|
||||||
|
ignore_empty_input = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
# Background with screenshot blur effect
|
# Background: screenshot darkened into the site's #0e0e0e glass tone
|
||||||
background = [
|
background = [
|
||||||
{
|
{
|
||||||
path = "screenshot";
|
path = "screenshot";
|
||||||
blur_passes = 3;
|
blur_passes = 4;
|
||||||
blur_size = 8;
|
blur_size = 12;
|
||||||
noise = 0.0117;
|
noise = 0.0117;
|
||||||
contrast = 0.8916;
|
contrast = 0.9;
|
||||||
brightness = 0.8172;
|
brightness = 0.55;
|
||||||
vibrancy = 0.1696;
|
vibrancy = 0.1;
|
||||||
vibrancy_darkness = 0.0;
|
vibrancy_darkness = 0.4;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
# Clock display
|
|
||||||
label = [
|
label = [
|
||||||
|
# Big clock
|
||||||
{
|
{
|
||||||
monitor = "";
|
monitor = "";
|
||||||
text = "$TIME";
|
text = "$TIME";
|
||||||
color = "rgba(242, 243, 244, 0.75)";
|
color = "rgba(ffffffdd)";
|
||||||
font_size = 95;
|
font_size = 90;
|
||||||
font_family = "JetBrainsMono Nerd Font Bold";
|
font_family = "JetBrainsMono Nerd Font";
|
||||||
position = "0, 200";
|
position = "0, 220";
|
||||||
halign = "center";
|
halign = "center";
|
||||||
valign = "center";
|
valign = "center";
|
||||||
}
|
}
|
||||||
|
# Date
|
||||||
{
|
{
|
||||||
monitor = "";
|
monitor = "";
|
||||||
text = "cmd[update:1000] echo \"$(date +'%A, %B %d')\"";
|
text = "cmd[update:1000] echo \" $(date +'%A, %B %d') \"";
|
||||||
color = "rgba(242, 243, 244, 0.6)";
|
color = "rgba(adaaaaff)";
|
||||||
font_size = 22;
|
font_size = 20;
|
||||||
font_family = "JetBrainsMono Nerd Font";
|
font_family = "JetBrainsMono Nerd Font";
|
||||||
position = "0, 100";
|
position = "0, 120";
|
||||||
|
halign = "center";
|
||||||
|
valign = "center";
|
||||||
|
}
|
||||||
|
# Session banner
|
||||||
|
{
|
||||||
|
monitor = "";
|
||||||
|
text = "NIXOS // SILICON VOLT";
|
||||||
|
color = "rgba(cffc00ee)";
|
||||||
|
font_size = 14;
|
||||||
|
font_family = "JetBrainsMono Nerd Font";
|
||||||
|
position = "0, 60";
|
||||||
|
halign = "center";
|
||||||
|
valign = "center";
|
||||||
|
}
|
||||||
|
# User + hostname line
|
||||||
|
{
|
||||||
|
monitor = "";
|
||||||
|
text = "cmd[update:3600000] echo \" $USER @ $(hostname) \"";
|
||||||
|
color = "rgba(adaaaa99)";
|
||||||
|
font_size = 13;
|
||||||
|
font_family = "JetBrainsMono Nerd Font";
|
||||||
|
position = "0, -160";
|
||||||
halign = "center";
|
halign = "center";
|
||||||
valign = "center";
|
valign = "center";
|
||||||
}
|
}
|
||||||
@@ -54,18 +78,22 @@
|
|||||||
input-field = [
|
input-field = [
|
||||||
{
|
{
|
||||||
monitor = "";
|
monitor = "";
|
||||||
size = "250, 50";
|
size = "300, 50";
|
||||||
outline_thickness = 2;
|
outline_thickness = 2;
|
||||||
dots_size = 0.2;
|
dots_size = 0.2;
|
||||||
dots_spacing = 0.2;
|
dots_spacing = 0.2;
|
||||||
dots_center = true;
|
dots_center = true;
|
||||||
outer_color = "rgba(33ccffee)";
|
# Volt lime outline, dark glass interior
|
||||||
inner_color = "rgba(15, 23, 42, 0.85)";
|
outer_color = "rgba(cffc00ee)";
|
||||||
font_color = "rgb(242, 243, 244)";
|
inner_color = "rgba(1c1b1b, 0.9)";
|
||||||
|
check_color = "rgba(e3ff66ee)";
|
||||||
|
fail_color = "rgba(ff7a59ee)";
|
||||||
|
font_color = "rgba(e5e2e1ff)";
|
||||||
|
fail_text = "$FAIL (<b>attempts: $ATTEMPTS</b>)";
|
||||||
fade_on_empty = false;
|
fade_on_empty = false;
|
||||||
placeholder_text = "<i>Enter Password...</i>";
|
placeholder_text = "<i> Enter Password...</i>";
|
||||||
hide_input = false;
|
hide_input = false;
|
||||||
position = "0, -50";
|
position = "0, -80";
|
||||||
halign = "center";
|
halign = "center";
|
||||||
valign = "center";
|
valign = "center";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ QtObject {
|
|||||||
property int brightness: 100
|
property int brightness: 100
|
||||||
|
|
||||||
property bool wifiConnected: true
|
property bool wifiConnected: true
|
||||||
|
property string connectionType: "off" // "wifi" | "eth" | "off"
|
||||||
property string wifiSsid: "Wi-Fi"
|
property string wifiSsid: "Wi-Fi"
|
||||||
property string ipAddress: ""
|
property string ipAddress: ""
|
||||||
|
|
||||||
@@ -47,6 +48,11 @@ QtObject {
|
|||||||
property bool batteryCharging: false
|
property bool batteryCharging: false
|
||||||
property string batteryStatus: "Full"
|
property string batteryStatus: "Full"
|
||||||
|
|
||||||
|
// Disk Monitoring (root filesystem)
|
||||||
|
property int diskPercent: 0
|
||||||
|
property string diskUsedGb: "0"
|
||||||
|
property string diskTotalGb: "0"
|
||||||
|
|
||||||
// GPU VRAM Monitoring (NVIDIA)
|
// GPU VRAM Monitoring (NVIDIA)
|
||||||
property string gpuVramUsed: "0"
|
property string gpuVramUsed: "0"
|
||||||
property string gpuVramTotal: "0"
|
property string gpuVramTotal: "0"
|
||||||
@@ -98,31 +104,32 @@ QtObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function switchWorkspace(n) {
|
function switchWorkspace(n) {
|
||||||
Hyprland.dispatch("workspace " + n);
|
// NOTE: Hyprland's Lua config bridge requires typed dispatcher calls
|
||||||
|
// (plain `hyprctl dispatch workspace 2` is mangled into invalid Lua).
|
||||||
|
Hyprland.dispatch("hl.dsp.focus({workspace = " + n + "})");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hyprland raw event processing
|
// Hyprland raw event processing
|
||||||
readonly property Connections hyprConn: Connections {
|
readonly property Connections hyprConn: Connections {
|
||||||
target: Hyprland
|
target: Hyprland
|
||||||
function onRawEvent(event) { console.log(JSON.stringify(event), event.name, event.event, event.data);
|
function onRawEvent(event) {
|
||||||
if (!event) return;
|
if (!event || !event.name) return;
|
||||||
if (event.startsWith("workspace>>")) {
|
const name = event.name;
|
||||||
const data = event.substring(11);
|
const data = event.data !== undefined ? String(event.data) : "";
|
||||||
|
|
||||||
|
if (name === "workspace") {
|
||||||
const wsNum = parseInt(data);
|
const wsNum = parseInt(data);
|
||||||
if (!isNaN(wsNum)) root.activeWorkspace = wsNum;
|
if (!isNaN(wsNum)) root.activeWorkspace = wsNum;
|
||||||
} else if (event.startsWith("activewindow>>")) {
|
} else if (name === "activewindow") {
|
||||||
const data = event.substring(14);
|
|
||||||
const parts = data.split(",");
|
const parts = data.split(",");
|
||||||
const title = parts[1] ? parts[1].trim() : (parts[0] ? parts[0].trim() : "");
|
const cls = parts[0] ? parts[0].trim() : "";
|
||||||
const cls = parts[0] ? parts[0].trim() : "Finder";
|
const title = parts[1] ? parts[1].trim() : (cls || "");
|
||||||
|
|
||||||
root.activeWindowClass = cls && cls.length > 0 ? cls : "Finder";
|
root.activeWindowClass = cls && cls.length > 0 ? cls : "Desktop";
|
||||||
root.activeWindowTitle = title && title.length > 0 ? title : root.activeWindowClass;
|
root.activeWindowTitle = title && title.length > 0 ? title : root.activeWindowClass;
|
||||||
} else if (event.startsWith("activewindowv2>>")) {
|
} else if (name === "activewindowv2" || name === "openwindow" || name === "closewindow") {
|
||||||
// Update running clients
|
// Update running clients
|
||||||
clientsProc.running = true;
|
clientsProc.running = true;
|
||||||
} else if (event.startsWith("openwindow>>") || event.startsWith("closewindow>>")) {
|
|
||||||
clientsProc.running = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -156,6 +163,7 @@ QtObject {
|
|||||||
brightProc.running = true;
|
brightProc.running = true;
|
||||||
mprisProc.running = true;
|
mprisProc.running = true;
|
||||||
gpuProc.running = true;
|
gpuProc.running = true;
|
||||||
|
diskProc.running = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,15 +208,16 @@ QtObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
readonly property Process wifiProc: Process {
|
readonly property Process wifiProc: Process {
|
||||||
command: ["bash", "-c", "ssid=\"\"; if command -v nmcli &>/dev/null; then ssid=$(nmcli -t -f active,ssid dev wifi 2>/dev/null | grep '^yes:' | cut -d':' -f2); fi; [ -z \"$ssid\" ] && [ -f /proc/net/wireless ] && ssid=$(iwgetid -r 2>/dev/null); ip=$(ip -4 route get 1.1.1.1 2>/dev/null | awk '{print $7; exit}'); echo \"${ssid:-Ethernet} ${ip:-Offline}\""]
|
// Emits: connectionType|ssid|ip ("wifi" | "eth" | "off")
|
||||||
|
command: ["bash", "-c", "route=$(ip -4 route get 1.1.1.1 2>/dev/null); ip=$(echo \"$route\" | awk '{for(i=1;i<=NF;i++) if($i==\"src\") print $(i+1)}'); dev=$(echo \"$route\" | awk '{for(i=1;i<=NF;i++) if($i==\"dev\") print $(i+1)}'); type=\"off\"; ssid=\"\"; if [ -n \"$dev\" ]; then if [ -d \"/sys/class/net/$dev/wireless\" ]; then type=\"wifi\"; ssid=$(iwgetid -r 2>/dev/null); if [ -z \"$ssid\" ] && command -v nmcli &>/dev/null; then ssid=$(nmcli -t -f active,ssid dev wifi 2>/dev/null | grep '^yes:' | cut -d':' -f2); fi; else type=\"eth\"; fi; fi; echo \"$type|$ssid|$ip\""]
|
||||||
stdout: StdioCollector {
|
stdout: StdioCollector {
|
||||||
onDataChanged: {
|
onDataChanged: {
|
||||||
const str = String(data).trim();
|
const parts = String(data).trim().split("|");
|
||||||
const parts = str.split(" ");
|
if (parts.length >= 3) {
|
||||||
if (parts.length >= 2) {
|
root.connectionType = parts[0] !== "" ? parts[0] : "off";
|
||||||
root.wifiSsid = parts[0];
|
root.wifiSsid = parts[1];
|
||||||
root.ipAddress = parts[1];
|
root.ipAddress = parts[2];
|
||||||
root.wifiConnected = parts[1] !== "Offline";
|
root.wifiConnected = parts[2] !== "" && parts[2] !== "Offline";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,6 +246,21 @@ QtObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readonly property Process diskProc: Process {
|
||||||
|
// Emits: usedGB totalGB percent for the root filesystem
|
||||||
|
command: ["bash", "-c", "df -BG / 2>/dev/null | awk 'NR==2 {u=$3; t=$2; gsub(/G/,\"\",u); gsub(/G/,\"\",t); if (t+0 > 0) print u, t, int(u*100/t)}'"]
|
||||||
|
stdout: StdioCollector {
|
||||||
|
onDataChanged: {
|
||||||
|
const parts = String(data).trim().split(" ");
|
||||||
|
if (parts.length >= 3) {
|
||||||
|
root.diskUsedGb = parts[0];
|
||||||
|
root.diskTotalGb = parts[1];
|
||||||
|
root.diskPercent = parseInt(parts[2]) || 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
readonly property Process mprisProc: Process {
|
readonly property Process mprisProc: Process {
|
||||||
command: ["bash", "-c", "if command -v playerctl &>/dev/null; then t=$(playerctl metadata title 2>/dev/null); a=$(playerctl metadata artist 2>/dev/null); s=$(playerctl status 2>/dev/null); echo \"$s|$t|$a\"; fi"]
|
command: ["bash", "-c", "if command -v playerctl &>/dev/null; then t=$(playerctl metadata title 2>/dev/null); a=$(playerctl metadata artist 2>/dev/null); s=$(playerctl status 2>/dev/null); echo \"$s|$t|$a\"; fi"]
|
||||||
stdout: StdioCollector {
|
stdout: StdioCollector {
|
||||||
@@ -287,40 +311,40 @@ QtObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper functions to control system
|
// Helper functions to control system (execDetached: fire-and-forget)
|
||||||
function setVolume(val) {
|
function setVolume(val) {
|
||||||
root.volume = Math.max(0, Math.min(100, val));
|
root.volume = Math.max(0, Math.min(100, val));
|
||||||
Process.exec(["pactl", "set-sink-volume", "@DEFAULT_SINK@", `${root.volume}%`]);
|
Quickshell.execDetached(["pactl", "set-sink-volume", "@DEFAULT_SINK@", `${root.volume}%`]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleVolumeMute() {
|
function toggleVolumeMute() {
|
||||||
Process.exec(["pactl", "set-sink-mute", "@DEFAULT_SINK@", "toggle"]);
|
Quickshell.execDetached(["pactl", "set-sink-mute", "@DEFAULT_SINK@", "toggle"]);
|
||||||
root.volumeMuted = !root.volumeMuted;
|
root.volumeMuted = !root.volumeMuted;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setBrightness(val) {
|
function setBrightness(val) {
|
||||||
root.brightness = Math.max(1, Math.min(100, val));
|
root.brightness = Math.max(1, Math.min(100, val));
|
||||||
Process.exec(["brightnessctl", "set", `${root.brightness}%`]);
|
Quickshell.execDetached(["brightnessctl", "set", `${root.brightness}%`]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function mediaPlayPause() {
|
function mediaPlayPause() {
|
||||||
Process.exec(["playerctl", "play-pause"]);
|
Quickshell.execDetached(["playerctl", "play-pause"]);
|
||||||
mprisProc.running = true;
|
mprisProc.running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function mediaNext() {
|
function mediaNext() {
|
||||||
Process.exec(["playerctl", "next"]);
|
Quickshell.execDetached(["playerctl", "next"]);
|
||||||
mprisProc.running = true;
|
mprisProc.running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function mediaPrevious() {
|
function mediaPrevious() {
|
||||||
Process.exec(["playerctl", "previous"]);
|
Quickshell.execDetached(["playerctl", "previous"]);
|
||||||
mprisProc.running = true;
|
mprisProc.running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function launchApp(execCmd) {
|
function launchApp(execCmd) {
|
||||||
if (!execCmd) return;
|
if (!execCmd) return;
|
||||||
Process.exec(["bash", "-c", `${execCmd} &`]);
|
Quickshell.execDetached(["sh", "-c", execCmd]);
|
||||||
closeAllPopups();
|
closeAllPopups();
|
||||||
spotlightVisible = false;
|
spotlightVisible = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ Rectangle {
|
|||||||
model: root.menuName === "File" ? [
|
model: root.menuName === "File" ? [
|
||||||
{ text: "New Window", shortcut: "⌘N", cmd: "foot &" },
|
{ text: "New Window", shortcut: "⌘N", cmd: "foot &" },
|
||||||
{ text: "New Incognito Window", shortcut: "⇧⌘N", cmd: "brave --incognito &" },
|
{ text: "New Incognito Window", shortcut: "⇧⌘N", cmd: "brave --incognito &" },
|
||||||
{ text: "Close Window", shortcut: "⌘W", cmd: "hyprctl dispatch killactive" },
|
{ text: "Close Window", shortcut: "⌘W", cmd: "hyprctl dispatch \"hl.dsp.window.close()\"" },
|
||||||
{ text: "---", shortcut: "", cmd: "" },
|
{ text: "---", shortcut: "", cmd: "" },
|
||||||
{ text: "Take Screenshot", shortcut: "⇧⌘5", cmd: "grim -g \"$(slurp)\" ~/screenshot.png" }
|
{ text: "Take Screenshot", shortcut: "⇧⌘5", cmd: "grim -g \"$(slurp)\" ~/screenshot.png" }
|
||||||
] : []
|
] : []
|
||||||
@@ -49,9 +49,9 @@ Rectangle {
|
|||||||
// VIEW MENU
|
// VIEW MENU
|
||||||
Repeater {
|
Repeater {
|
||||||
model: root.menuName === "View" ? [
|
model: root.menuName === "View" ? [
|
||||||
{ text: "Toggle Fullscreen", shortcut: "⌃⌘F", cmd: "hyprctl dispatch fullscreen 0" },
|
{ text: "Toggle Fullscreen", shortcut: "⌃⌘F", cmd: "hyprctl dispatch \"hl.dsp.window.fullscreen({fullscreen = 0})\"" },
|
||||||
{ text: "Toggle Floating", shortcut: "⌘V", cmd: "hyprctl dispatch togglefloating" },
|
{ text: "Toggle Floating", shortcut: "⌘V", cmd: "hyprctl dispatch \"hl.dsp.window.float({action = \"toggle\"})\"" },
|
||||||
{ text: "Toggle Group", shortcut: "⌘G", cmd: "hyprctl dispatch togglegroup" },
|
{ text: "Toggle Group", shortcut: "⌘G", cmd: "hyprctl dispatch \"hl.dsp.group.toggle()\"" },
|
||||||
{ text: "---", shortcut: "", cmd: "" },
|
{ text: "---", shortcut: "", cmd: "" },
|
||||||
{ text: "Zoom In", shortcut: "⌘+", cmd: "" },
|
{ text: "Zoom In", shortcut: "⌘+", cmd: "" },
|
||||||
{ text: "Zoom Out", shortcut: "⌘-", cmd: "" }
|
{ text: "Zoom Out", shortcut: "⌘-", cmd: "" }
|
||||||
@@ -62,12 +62,12 @@ Rectangle {
|
|||||||
// WINDOW MENU
|
// WINDOW MENU
|
||||||
Repeater {
|
Repeater {
|
||||||
model: root.menuName === "Window" ? [
|
model: root.menuName === "Window" ? [
|
||||||
{ text: "Minimize Window", shortcut: "⌘M", cmd: "hyprctl dispatch movetoworkspacesilent special:scratch" },
|
{ text: "Minimize Window", shortcut: "⌘M", cmd: "hyprctl dispatch \"hl.dsp.window.move({workspace = \"special:scratch\"})\"" },
|
||||||
{ text: "Tile Left", shortcut: "⌃⌥←", cmd: "hyprctl dispatch movewindow l" },
|
{ text: "Tile Left", shortcut: "⌃⌥←", cmd: "hyprctl dispatch \"hl.dsp.window.move({direction = \"left\"})\"" },
|
||||||
{ text: "Tile Right", shortcut: "⌃⌥→", cmd: "hyprctl dispatch movewindow r" },
|
{ text: "Tile Right", shortcut: "⌃⌥→", cmd: "hyprctl dispatch \"hl.dsp.window.move({direction = \"right\"})\"" },
|
||||||
{ text: "---", shortcut: "", cmd: "" },
|
{ text: "---", shortcut: "", cmd: "" },
|
||||||
{ text: "Show Scratchpad", shortcut: "⌘↩", cmd: "hyprctl dispatch togglespecialworkspace scratch" },
|
{ text: "Show Scratchpad", shortcut: "⌘↩", cmd: "hyprctl dispatch \"hl.dsp.workspace.toggle_special(\"scratch\")\"" },
|
||||||
{ text: "Show Messaging", shortcut: "⌘M", cmd: "hyprctl dispatch togglespecialworkspace messaging" }
|
{ text: "Show Messaging", shortcut: "⌘M", cmd: "hyprctl dispatch \"hl.dsp.workspace.toggle_special(\"messaging\")\"" }
|
||||||
] : []
|
] : []
|
||||||
delegate: MenuEntryDelegate {}
|
delegate: MenuEntryDelegate {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ Rectangle {
|
|||||||
shortcut: "⇧⌘Q"
|
shortcut: "⇧⌘Q"
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
GlobalState.appleMenuVisible = false;
|
GlobalState.appleMenuVisible = false;
|
||||||
GlobalState.launchApp("hyprctl dispatch exit");
|
GlobalState.launchApp("loginctl terminate-session");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ PanelWindow {
|
|||||||
isPinned: false
|
isPinned: false
|
||||||
onCustomClicked: {
|
onCustomClicked: {
|
||||||
if (modelData.address) {
|
if (modelData.address) {
|
||||||
Hyprland.dispatch(`focuswindow address:${modelData.address}`);
|
Hyprland.dispatch(`hl.dsp.focus({window = "address:${modelData.address}"})`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -308,8 +308,9 @@ PanelWindow {
|
|||||||
var seen = {}
|
var seen = {}
|
||||||
if (GlobalState.runningApps) {
|
if (GlobalState.runningApps) {
|
||||||
for (var i = 0; i < GlobalState.runningApps.length; i++) {
|
for (var i = 0; i < GlobalState.runningApps.length; i++) {
|
||||||
var cls = GlobalState.runningApps[i]
|
// hyprctl clients entries are objects; extract the class string
|
||||||
if (cls && pinned.indexOf(cls) === -1 && !seen[cls]) {
|
var cls = GlobalState.runningApps[i] && GlobalState.runningApps[i].class
|
||||||
|
if (cls && cls.length > 0 && pinned.indexOf(cls) === -1 && !seen[cls]) {
|
||||||
seen[cls] = true
|
seen[cls] = true
|
||||||
running.push(cls)
|
running.push(cls)
|
||||||
}
|
}
|
||||||
@@ -331,7 +332,7 @@ PanelWindow {
|
|||||||
|
|
||||||
Text {
|
Text {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
text: modelData.charAt(0).toUpperCase()
|
text: modelData && modelData.length > 0 ? modelData.charAt(0).toUpperCase() : "?"
|
||||||
color: Theme.textPrimary
|
color: Theme.textPrimary
|
||||||
font.family: Theme.fontSans
|
font.family: Theme.fontSans
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
|
|||||||
@@ -31,7 +31,9 @@ PanelWindow {
|
|||||||
|
|
||||||
// App Database Loader Process
|
// App Database Loader Process
|
||||||
readonly property Process appScanProc: Process {
|
readonly property Process appScanProc: Process {
|
||||||
command: ["bash", "-c", "dirs=(\"/run/current-system/sw/share/applications\" \"$HOME/.nix-profile/share/applications\" \"$HOME/.local/share/applications\"); echo '['; first=1; for d in \"${dirs[@]}\"; do [ -d \"$d\" ] && for f in \"$d\"/*.desktop; do [ -e \"$f\" ] || continue; grep -q \"^NoDisplay=true\" \"$f\" 2>/dev/null && continue; n=$(grep -m 1 \"^Name=\" \"$f\" 2>/dev/null | cut -d= -f2-); e=$(grep -m 1 \"^Exec=\" \"$f\" 2>/dev/null | cut -d= -f2- | sed -E 's/%[fFuUdDnNickvm]//g'); if [ -n \"$n\" ] && [ -n \"$e\" ]; then [ $first -eq 0 ] && echo ','; first=0; echo \"{\\\"name\\\":\\\"$n\\\",\\\"exec\\\":\\\"$e\\\"}\"; fi; done; done; echo ']'"]
|
// Indexes .desktop applications AND executable user scripts so the
|
||||||
|
// launcher finds "everything" without depending on an external service.
|
||||||
|
command: ["bash", "-c", "dirs=(\"/run/current-system/sw/share/applications\" \"$HOME/.nix-profile/share/applications\" \"$HOME/.local/share/applications\"); bdirs=(\"$HOME/.local/bin\" \"$HOME/bin\" \"$HOME/.cargo/bin\"); echo '['; first=1; for d in \"${dirs[@]}\"; do [ -d \"$d\" ] && for f in \"$d\"/*.desktop; do [ -e \"$f\" ] || continue; grep -q \"^NoDisplay=true\" \"$f\" 2>/dev/null && continue; n=$(grep -m 1 \"^Name=\" \"$f\" 2>/dev/null | cut -d= -f2-); e=$(grep -m 1 \"^Exec=\" \"$f\" 2>/dev/null | cut -d= -f2- | sed -E 's/%[fFuUdDnNickvm]//g'); if [ -n \"$n\" ] && [ -n \"$e\" ]; then [ $first -eq 0 ] && echo ','; first=0; echo \"{\\\"name\\\":\\\"$n\\\",\\\"exec\\\":\\\"$e\\\"}\"; fi; done; done; for d in \"${bdirs[@]}\"; do [ -d \"$d\" ] || continue; for f in \"$d\"/*; do [ -f \"$f\" ] && [ -x \"$f\" ] || continue; n=$(basename \"$f\"); [ $first -eq 0 ] && echo ','; first=0; printf '{\\\"name\\\":\\\"%s\\\",\\\"exec\\\":\\\"%s\\\",\\\"comment\\\":\\\"script\\\"}\\n' \"$n\" \"$f\"; done; done; echo ']'"]
|
||||||
stdout: StdioCollector {
|
stdout: StdioCollector {
|
||||||
onDataChanged: {
|
onDataChanged: {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ PanelWindow {
|
|||||||
component ToggleCard: Rectangle {
|
component ToggleCard: Rectangle {
|
||||||
property string title: ""
|
property string title: ""
|
||||||
property string icon: ""
|
property string icon: ""
|
||||||
|
property string glyph: "" // Nerd Font glyph alternative to icon file
|
||||||
property bool active: false
|
property bool active: false
|
||||||
signal clicked()
|
signal clicked()
|
||||||
|
|
||||||
@@ -97,15 +98,22 @@ PanelWindow {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: 12
|
anchors.margins: 12
|
||||||
spacing: 12
|
spacing: 12
|
||||||
|
Text {
|
||||||
|
visible: parent.parent.glyph !== ""
|
||||||
|
text: parent.parent.glyph
|
||||||
|
font.family: "JetBrainsMono Nerd Font"
|
||||||
|
font.pixelSize: 20
|
||||||
|
color: parent.parent.active ? Theme.accentVolt : Theme.textMuted
|
||||||
|
}
|
||||||
Image {
|
Image {
|
||||||
source: icon ? Qt.resolvedUrl("../" + icon) : ""
|
source: parent.parent.icon && parent.parent.glyph === "" ? Qt.resolvedUrl("../" + parent.parent.icon) : ""
|
||||||
Layout.preferredWidth: 24
|
Layout.preferredWidth: 24
|
||||||
Layout.preferredHeight: 24
|
Layout.preferredHeight: 24
|
||||||
sourceSize: Qt.size(24, 24)
|
sourceSize: Qt.size(24, 24)
|
||||||
visible: parent.icon !== ""
|
visible: parent.parent.icon !== "" && parent.parent.glyph === ""
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
text: title
|
text: parent.parent.title
|
||||||
color: Theme.textPrimary
|
color: Theme.textPrimary
|
||||||
font.family: Theme.fontSans
|
font.family: Theme.fontSans
|
||||||
font.pixelSize: 13
|
font.pixelSize: 13
|
||||||
@@ -312,8 +320,7 @@ PanelWindow {
|
|||||||
icon: "assets/wifi.svg"
|
icon: "assets/wifi.svg"
|
||||||
active: GlobalState.wifiConnected
|
active: GlobalState.wifiConnected
|
||||||
onClicked: {
|
onClicked: {
|
||||||
let proc = Quickshell.createProcess("sh", ["-c", "nm-connection-editor || foot -e nmtui"])
|
Quickshell.execDetached(["sh", "-c", "nm-connection-editor || foot -e nmtui"])
|
||||||
proc.start()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,14 +337,14 @@ PanelWindow {
|
|||||||
ToggleCard {
|
ToggleCard {
|
||||||
property bool dndActive: false
|
property bool dndActive: false
|
||||||
title: "Do Not Disturb"
|
title: "Do Not Disturb"
|
||||||
icon: "" // Optional DND icon
|
glyph: "\uF186"
|
||||||
active: dndActive
|
active: dndActive
|
||||||
onClicked: dndActive = !dndActive
|
onClicked: dndActive = !dndActive
|
||||||
}
|
}
|
||||||
|
|
||||||
ToggleCard {
|
ToggleCard {
|
||||||
title: GlobalState.volumeMuted ? "Muted" : "Sound"
|
title: GlobalState.volumeMuted ? "Muted" : "Sound"
|
||||||
icon: "" // Optional sound icon
|
glyph: GlobalState.volumeMuted ? "\uF026" : "\uF028"
|
||||||
active: !GlobalState.volumeMuted
|
active: !GlobalState.volumeMuted
|
||||||
onClicked: GlobalState.toggleVolumeMute()
|
onClicked: GlobalState.toggleVolumeMute()
|
||||||
}
|
}
|
||||||
@@ -423,6 +430,13 @@ PanelWindow {
|
|||||||
valueText: GlobalState.memUsedGb + " / " + GlobalState.memTotalGb + " GB"
|
valueText: GlobalState.memUsedGb + " / " + GlobalState.memTotalGb + " GB"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProgressBarItem {
|
||||||
|
label: "DISK"
|
||||||
|
percent: GlobalState.diskPercent
|
||||||
|
valueText: GlobalState.diskUsedGb + " / " + GlobalState.diskTotalGb + " GB"
|
||||||
|
barColor: GlobalState.diskPercent > 90 ? Theme.accentCoral : Theme.accentVolt
|
||||||
|
}
|
||||||
|
|
||||||
ProgressBarItem {
|
ProgressBarItem {
|
||||||
label: "VRAM"
|
label: "VRAM"
|
||||||
percent: (GlobalState.gpuVramUsed / Math.max(1, GlobalState.gpuVramTotal)) * 100
|
percent: (GlobalState.gpuVramUsed / Math.max(1, GlobalState.gpuVramTotal)) * 100
|
||||||
@@ -446,7 +460,12 @@ PanelWindow {
|
|||||||
color: GlobalState.wifiConnected ? Theme.accentVolt : Theme.accentCoral
|
color: GlobalState.wifiConnected ? Theme.accentVolt : Theme.accentCoral
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
text: GlobalState.wifiConnected ? "Connected" : "Disconnected"
|
text: {
|
||||||
|
if (!GlobalState.wifiConnected) return "Disconnected";
|
||||||
|
if (GlobalState.connectionType === "wifi") return "Wi-Fi — " + (GlobalState.wifiSsid !== "" ? GlobalState.wifiSsid : "unknown");
|
||||||
|
if (GlobalState.connectionType === "eth") return "Ethernet";
|
||||||
|
return "Connected";
|
||||||
|
}
|
||||||
color: Theme.textPrimary
|
color: Theme.textPrimary
|
||||||
font.family: Theme.fontSans
|
font.family: Theme.fontSans
|
||||||
font.pixelSize: 14
|
font.pixelSize: 14
|
||||||
@@ -454,14 +473,8 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: "SSID: " + (GlobalState.wifiSsid !== "" ? GlobalState.wifiSsid : "None")
|
visible: GlobalState.wifiConnected
|
||||||
color: Theme.textSecondary
|
text: "IP: " + (GlobalState.ipAddress !== "" ? GlobalState.ipAddress : "—")
|
||||||
font.family: Theme.fontSans
|
|
||||||
font.pixelSize: 13
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "IP: " + GlobalState.ipAddress
|
|
||||||
color: Theme.textSecondary
|
color: Theme.textSecondary
|
||||||
font.family: Theme.fontMono
|
font.family: Theme.fontMono
|
||||||
font.pixelSize: 13
|
font.pixelSize: 13
|
||||||
@@ -478,8 +491,7 @@ PanelWindow {
|
|||||||
onEntered: parent.color = Theme.textPrimary
|
onEntered: parent.color = Theme.textPrimary
|
||||||
onExited: parent.color = Theme.textMuted
|
onExited: parent.color = Theme.textMuted
|
||||||
onClicked: {
|
onClicked: {
|
||||||
let proc = Quickshell.createProcess("sh", ["-c", "nm-connection-editor || foot -e nmtui"])
|
Quickshell.execDetached(["sh", "-c", "nm-connection-editor || foot -e nmtui"])
|
||||||
proc.start()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -558,7 +570,7 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
text: GlobalState.mediaStatus === "Playing" ? "⏸" : "▶"
|
text: GlobalState.mediaPlaying ? "⏸" : "▶"
|
||||||
font.pixelSize: 24
|
font.pixelSize: 24
|
||||||
color: Theme.textSecondary
|
color: Theme.textSecondary
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
|||||||
@@ -5,6 +5,11 @@ import Quickshell.Wayland
|
|||||||
import "../theme"
|
import "../theme"
|
||||||
import ".."
|
import ".."
|
||||||
|
|
||||||
|
// Nerd Font glyphs (JetBrainsMono Nerd Font, installed system-wide)
|
||||||
|
// \uF1EB wifi \uF796 ethernet \uF538 memory \uF1C0 disk
|
||||||
|
// \uF028 volume \uF185 brightness \uF240 battery \uF0E7 charging
|
||||||
|
// \uF017 clock \uF2DB cpu
|
||||||
|
|
||||||
PanelWindow {
|
PanelWindow {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
@@ -38,33 +43,87 @@ PanelWindow {
|
|||||||
color: Theme.glassBorder
|
color: Theme.glassBorder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
// Helpers to compose rich-text status segments
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
function pad(num) {
|
||||||
|
if (num === undefined || num === null) return "00";
|
||||||
|
return num < 10 ? "0" + num : num.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
function seg(icon, value, iconColor, valueColor) {
|
||||||
|
return "<font color=\"" + iconColor + "\">" + icon + "</font><font color=\"" + valueColor + "\"> " + value + "</font>";
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildStats() {
|
||||||
|
const c = "#e5e2e1";
|
||||||
|
const dim = "#adaaaa";
|
||||||
|
const volt = "#CFFC00";
|
||||||
|
const coral = "#FF7A59";
|
||||||
|
const sep = "<font color=\"#2a2929\"> // </font>";
|
||||||
|
const parts = [];
|
||||||
|
|
||||||
|
// Network: type icon + SSID (wifi) + IP
|
||||||
|
if (GlobalState.wifiConnected) {
|
||||||
|
const icon = GlobalState.connectionType === "wifi" ? "\uF1EB" : "\uF796";
|
||||||
|
const label = (GlobalState.connectionType === "wifi" && GlobalState.wifiSsid !== "") ? GlobalState.wifiSsid : "eth";
|
||||||
|
parts.push(seg(icon, label + " " + (GlobalState.ipAddress !== "" ? GlobalState.ipAddress : "\u2014"), volt, c));
|
||||||
|
} else {
|
||||||
|
parts.push(seg("\uF1EB", "offline", coral, dim));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Memory (used GB / total GB)
|
||||||
|
parts.push(seg("\uF538", GlobalState.memUsedGb + "G / " + GlobalState.memTotalGb + "G",
|
||||||
|
GlobalState.memPercent > 85 ? coral : dim, c));
|
||||||
|
|
||||||
|
// Disk (root filesystem percent)
|
||||||
|
parts.push(seg("\uF1C0", GlobalState.diskPercent + "%",
|
||||||
|
GlobalState.diskPercent > 90 ? coral : dim, c));
|
||||||
|
|
||||||
|
// Audio (mute state flips icon + color)
|
||||||
|
if (GlobalState.volumeMuted) {
|
||||||
|
parts.push(seg("\uF026", "mute", coral, dim));
|
||||||
|
} else {
|
||||||
|
parts.push(seg("\uF028", GlobalState.volume + "%", dim, c));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display brightness
|
||||||
|
parts.push(seg("\uF185", GlobalState.brightness + "%", dim, c));
|
||||||
|
|
||||||
|
// Battery (only when present, e.g. laptops)
|
||||||
|
if (GlobalState.batteryPresent) {
|
||||||
|
const icon = GlobalState.batteryCharging ? "\uF0E7" : "\uF240";
|
||||||
|
parts.push(seg(icon, GlobalState.batteryPercent + "%",
|
||||||
|
GlobalState.batteryPercent < 20 ? coral : dim, c));
|
||||||
|
}
|
||||||
|
|
||||||
|
return parts.join(sep);
|
||||||
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.leftMargin: 16
|
anchors.leftMargin: 16
|
||||||
anchors.rightMargin: 16
|
anchors.rightMargin: 16
|
||||||
spacing: 16
|
spacing: 16
|
||||||
|
|
||||||
// Left Section
|
// Left Section: workspace indicator
|
||||||
Text {
|
Text {
|
||||||
id: workspaceIndicator
|
id: workspaceIndicator
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
font.family: Theme.fontMono
|
textFormat: Text.RichText
|
||||||
|
font.family: "JetBrainsMono Nerd Font"
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
color: Theme.textMuted
|
|
||||||
|
|
||||||
function pad(num) {
|
|
||||||
if (num === undefined || num === null) return "00";
|
|
||||||
return num < 10 ? "0" + num : num.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
text: pad(GlobalState.activeWorkspace) + " // " + (GlobalState.workspaceNames[GlobalState.activeWorkspace] !== undefined ? GlobalState.workspaceNames[GlobalState.activeWorkspace] : "main")
|
text: {
|
||||||
|
const name = GlobalState.workspaceNames[GlobalState.activeWorkspace] !== undefined
|
||||||
Behavior on color {
|
? GlobalState.workspaceNames[GlobalState.activeWorkspace] : "main";
|
||||||
ColorAnimation { duration: 150 }
|
return "<font color=\"#CFFC00\">" + pad(GlobalState.activeWorkspace) + "</font>"
|
||||||
|
+ "<font color=\"#2a2929\"> // </font>"
|
||||||
|
+ "<font color=\"#adaaaa\">" + name + "</font>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Center Section
|
// Center Section: focused window title
|
||||||
Text {
|
Text {
|
||||||
id: windowTitle
|
id: windowTitle
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -84,18 +143,35 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Right Section
|
// Right Section: live system stats (click to open the System HUD)
|
||||||
|
Text {
|
||||||
|
id: stats
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
textFormat: Text.RichText
|
||||||
|
font.family: "JetBrainsMono Nerd Font"
|
||||||
|
font.pixelSize: 11
|
||||||
|
|
||||||
|
text: buildStats()
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: statsMouse
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: GlobalState.toggleSystemHud()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clock
|
||||||
Text {
|
Text {
|
||||||
id: clock
|
id: clock
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
font.family: Theme.fontMono
|
textFormat: Text.RichText
|
||||||
|
font.family: "JetBrainsMono Nerd Font"
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
color: Theme.textPrimary
|
|
||||||
text: GlobalState.timeString
|
|
||||||
|
|
||||||
Behavior on color {
|
text: "<font color=\"#adaaaa\">\uF017</font>"
|
||||||
ColorAnimation { duration: 150 }
|
+ "<font color=\"#ffffff\"> " + GlobalState.timeString + "</font>"
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
53
home/hypr/wallpaper.svg
Normal file
53
home/hypr/wallpaper.svg
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="3840" height="2160" viewBox="0 0 3840 2160">
|
||||||
|
<defs>
|
||||||
|
<radialGradient id="voltGlow" cx="72%" cy="88%" r="55%">
|
||||||
|
<stop offset="0%" stop-color="#CFFC00" stop-opacity="0.07"/>
|
||||||
|
<stop offset="60%" stop-color="#CFFC00" stop-opacity="0.015"/>
|
||||||
|
<stop offset="100%" stop-color="#CFFC00" stop-opacity="0"/>
|
||||||
|
</radialGradient>
|
||||||
|
<radialGradient id="coralGlow" cx="12%" cy="8%" r="45%">
|
||||||
|
<stop offset="0%" stop-color="#FF7A59" stop-opacity="0.05"/>
|
||||||
|
<stop offset="100%" stop-color="#FF7A59" stop-opacity="0"/>
|
||||||
|
</radialGradient>
|
||||||
|
<pattern id="grid" width="160" height="160" patternUnits="userSpaceOnUse">
|
||||||
|
<path d="M 160 0 L 0 0 0 160" fill="none" stroke="#FFFFFF" stroke-opacity="0.028" stroke-width="1"/>
|
||||||
|
</pattern>
|
||||||
|
<pattern id="gridFine" width="32" height="32" patternUnits="userSpaceOnUse">
|
||||||
|
<path d="M 32 0 L 0 0 0 32" fill="none" stroke="#FFFFFF" stroke-opacity="0.012" stroke-width="1"/>
|
||||||
|
</pattern>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<!-- Base: site bg-secondary -->
|
||||||
|
<rect width="3840" height="2160" fill="#0e0e0e"/>
|
||||||
|
<rect width="3840" height="2160" fill="url(#gridFine)"/>
|
||||||
|
<rect width="3840" height="2160" fill="url(#grid)"/>
|
||||||
|
|
||||||
|
<!-- Ambient glows -->
|
||||||
|
<rect width="3840" height="2160" fill="url(#voltGlow)"/>
|
||||||
|
<rect width="3840" height="2160" fill="url(#coralGlow)"/>
|
||||||
|
|
||||||
|
<!-- Horizon lines: subtle glass borders -->
|
||||||
|
<line x1="0" y1="1750" x2="3840" y2="1750" stroke="#FFFFFF" stroke-opacity="0.05" stroke-width="2"/>
|
||||||
|
<line x1="0" y1="1770" x2="3840" y2="1770" stroke="#CFFC00" stroke-opacity="0.10" stroke-width="1"/>
|
||||||
|
|
||||||
|
<!-- Top-left coral bracket (site accent) -->
|
||||||
|
<rect x="140" y="140" width="180" height="10" fill="#FF7A59" opacity="0.55"/>
|
||||||
|
<rect x="140" y="140" width="10" height="180" fill="#FF7A59" opacity="0.55"/>
|
||||||
|
|
||||||
|
<!-- Bottom-right volt corner assembly -->
|
||||||
|
<rect x="3420" y="2020" width="280" height="12" fill="#CFFC00" opacity="0.9"/>
|
||||||
|
<rect x="3688" y="1820" width="12" height="212" fill="#CFFC00" opacity="0.9"/>
|
||||||
|
<circle cx="3694" cy="2026" r="26" fill="#CFFC00"/>
|
||||||
|
<circle cx="3694" cy="2026" r="52" fill="none" stroke="#CFFC00" stroke-opacity="0.35" stroke-width="3"/>
|
||||||
|
|
||||||
|
<!-- Volt tick marks along the horizon -->
|
||||||
|
<rect x="300" y="1762" width="60" height="8" fill="#CFFC00" opacity="0.5"/>
|
||||||
|
<rect x="420" y="1762" width="24" height="8" fill="#CFFC00" opacity="0.3"/>
|
||||||
|
<rect x="3600" y="1762" width="120" height="8" fill="#CFFC00" opacity="0.5"/>
|
||||||
|
|
||||||
|
<!-- Faint "//" motif, mono-grid aligned -->
|
||||||
|
<g fill="#FFFFFF" fill-opacity="0.04">
|
||||||
|
<polygon points="1900,700 2000,700 1780,1460 1680,1460"/>
|
||||||
|
<polygon points="2080,700 2180,700 1960,1460 1860,1460"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.6 KiB |
28
home/rofi.nix
Normal file
28
home/rofi.nix
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
# Rofi script-mode indexer: exposes every executable user script
|
||||||
|
# (shell, python, whatever) so the launcher finds "everything".
|
||||||
|
rofiScripts = pkgs.writeShellScriptBin "rofi-scripts"
|
||||||
|
(builtins.readFile ./rofi/rofi-scripts.sh);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
programs.rofi = {
|
||||||
|
enable = true;
|
||||||
|
terminal = "${pkgs.foot}/bin/foot";
|
||||||
|
cycle = true;
|
||||||
|
theme = ./rofi/volt.rasi;
|
||||||
|
|
||||||
|
extraConfig = {
|
||||||
|
# Combi mode searches .desktop apps (drun), binaries (run),
|
||||||
|
# open windows (window) and user scripts (scripts).
|
||||||
|
modes = "combi";
|
||||||
|
combi-modes = "drun,run,window,scripts:${rofiScripts}/bin/rofi-scripts";
|
||||||
|
show-icons = false;
|
||||||
|
drun-display-format = "{name} <span alpha='60%'>{comment}</span>";
|
||||||
|
display-combi = "silicon volt >";
|
||||||
|
matching = "fuzzy";
|
||||||
|
sort = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
21
home/rofi/rofi-scripts.sh
Normal file
21
home/rofi/rofi-scripts.sh
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Rofi script-mode: indexes every executable user script so the launcher
|
||||||
|
# can find shell scripts and everything else, not just .desktop apps.
|
||||||
|
|
||||||
|
declare -A SCRIPTS
|
||||||
|
|
||||||
|
for dir in "$HOME/.local/bin" "$HOME/bin" "$HOME/.cargo/bin" "$HOME/Tools/bin" "$HOME/scripts"; do
|
||||||
|
[ -d "$dir" ] || continue
|
||||||
|
while IFS= read -r -d '' f; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
b=$(basename "$f")
|
||||||
|
SCRIPTS["$b"]="$f"
|
||||||
|
done < <(find "$dir" -maxdepth 1 -type f -executable -print0 2>/dev/null)
|
||||||
|
done
|
||||||
|
|
||||||
|
sel="${1:-}"
|
||||||
|
if [ -n "$sel" ] && [ -n "${SCRIPTS[$sel]:-}" ]; then
|
||||||
|
exec setsid "${SCRIPTS[$sel]}" >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '%s\n' "${!SCRIPTS[@]}" | sort
|
||||||
135
home/rofi/volt.rasi
Normal file
135
home/rofi/volt.rasi
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
// Silicon Volt - Rofi theme (anish.govind.cc palette)
|
||||||
|
// Flat brutalist-glass: dark glass surfaces, volt-lime selection, 0 radius.
|
||||||
|
|
||||||
|
* {
|
||||||
|
bg0: rgba( 14, 14, 14, 95 % );
|
||||||
|
bg1: rgba( 28, 27, 27, 95 % );
|
||||||
|
fg0: #e5e2e1;
|
||||||
|
fg1: #ffffff;
|
||||||
|
fg2: #adaaaa;
|
||||||
|
volt: #CFFC00;
|
||||||
|
volt-dim: rgba( 207, 252, 0, 10 % );
|
||||||
|
coral: #FF7A59;
|
||||||
|
border0: rgba( 255, 255, 255, 8 % );
|
||||||
|
|
||||||
|
background-color: transparent;
|
||||||
|
text-color: @fg0;
|
||||||
|
font: "JetBrainsMono Nerd Font 12";
|
||||||
|
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
window {
|
||||||
|
location: north;
|
||||||
|
width: 680;
|
||||||
|
y-offset: 140;
|
||||||
|
background-color: @bg0;
|
||||||
|
border: 1;
|
||||||
|
border-color: @border0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mainbox {
|
||||||
|
children: [ inputbar, message, listview ];
|
||||||
|
}
|
||||||
|
|
||||||
|
inputbar {
|
||||||
|
background-color: @bg1;
|
||||||
|
border: 0 0 1 0;
|
||||||
|
border-color: @border0;
|
||||||
|
padding: 14 18;
|
||||||
|
spacing: 12;
|
||||||
|
children: [ prompt, entry ];
|
||||||
|
}
|
||||||
|
|
||||||
|
prompt {
|
||||||
|
text-color: @volt;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry {
|
||||||
|
text-color: @fg1;
|
||||||
|
placeholder: "search apps, scripts, windows...";
|
||||||
|
placeholder-color: @fg2;
|
||||||
|
cursor: text;
|
||||||
|
cursor-color: @volt;
|
||||||
|
}
|
||||||
|
|
||||||
|
message {
|
||||||
|
background-color: @volt-dim;
|
||||||
|
padding: 10 18;
|
||||||
|
text-color: @fg2;
|
||||||
|
}
|
||||||
|
|
||||||
|
listview {
|
||||||
|
lines: 12;
|
||||||
|
fixed-height: false;
|
||||||
|
padding: 6 0;
|
||||||
|
scrollbar: true;
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollbar {
|
||||||
|
handle-width: 2;
|
||||||
|
handle-color: @volt;
|
||||||
|
padding: 6 2 6 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
element {
|
||||||
|
padding: 10 18;
|
||||||
|
text-color: @fg0;
|
||||||
|
border: 0 0 0 2;
|
||||||
|
border-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
element normal normal {
|
||||||
|
background-color: transparent;
|
||||||
|
text-color: @fg0;
|
||||||
|
}
|
||||||
|
|
||||||
|
element normal active {
|
||||||
|
text-color: @volt;
|
||||||
|
}
|
||||||
|
|
||||||
|
element selected normal {
|
||||||
|
background-color: @volt-dim;
|
||||||
|
border-color: @volt;
|
||||||
|
text-color: @fg1;
|
||||||
|
}
|
||||||
|
|
||||||
|
element selected active {
|
||||||
|
background-color: @volt-dim;
|
||||||
|
border-color: @volt;
|
||||||
|
text-color: @volt;
|
||||||
|
}
|
||||||
|
|
||||||
|
element alternate normal {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
element-text {
|
||||||
|
text-color: inherit;
|
||||||
|
vertical-align: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
element-icon {
|
||||||
|
size: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mode-switcher {
|
||||||
|
padding: 8 12;
|
||||||
|
border: 0 0 1 0;
|
||||||
|
border-color: @border0;
|
||||||
|
background-color: @bg1;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
text-color: @fg2;
|
||||||
|
padding: 6 14;
|
||||||
|
border: 0 0 2 0;
|
||||||
|
border-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
button selected {
|
||||||
|
text-color: @volt;
|
||||||
|
border-color: @volt;
|
||||||
|
}
|
||||||
@@ -41,13 +41,16 @@ done
|
|||||||
|
|
||||||
menu_items+=("🐚 [Skip - Plain Shell]")
|
menu_items+=("🐚 [Skip - Plain Shell]")
|
||||||
|
|
||||||
# Interactive session selector using fzf
|
# Interactive session selector using fzf (Silicon Volt palette)
|
||||||
if command -v fzf &>/dev/null; then
|
if command -v fzf &>/dev/null; then
|
||||||
selected=$(printf '%s\n' "${menu_items[@]}" | fzf \
|
selected=$(printf '%s\n' "${menu_items[@]}" | fzf \
|
||||||
--height=45% \
|
--height=45% \
|
||||||
--layout=reverse \
|
--layout=reverse \
|
||||||
--border=rounded \
|
--border=rounded \
|
||||||
--prompt=" Herdr Session > " \
|
--prompt=" Herdr Session > " \
|
||||||
|
--color=fg:#e5e2e1,bg:#131313,hl:#CFFC00,fg+:#ffffff,bg+:#1c1b1b,hl+:#e3ff66 \
|
||||||
|
--color=info:#ADAAAA,prompt:#CFFC00,pointer:#FF7A59,marker:#CFFC00,spinner:#00BFFF \
|
||||||
|
--color=border:#2a2929,gutter:#131313 \
|
||||||
--header="Select Herdr session to attach / create | Esc for plain shell" \
|
--header="Select Herdr session to attach / create | Esc for plain shell" \
|
||||||
--header-first)
|
--header-first)
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# macOS Catalina Dark Aesthetic Starship Theme (Single-Line)
|
# Silicon Volt Starship Theme (anish.govind.cc palette, single-line)
|
||||||
add_newline = false
|
add_newline = false
|
||||||
scan_timeout = 10
|
scan_timeout = 10
|
||||||
|
|
||||||
@@ -6,49 +6,49 @@ format = "$os$directory$git_branch$git_status$nix_shell$rust$c$python$cmd_durati
|
|||||||
|
|
||||||
[os]
|
[os]
|
||||||
disabled = false
|
disabled = false
|
||||||
style = "bold #f2f2f7"
|
style = "bold #e5e2e1"
|
||||||
symbols = { NixOS = " " }
|
symbols = { NixOS = " " }
|
||||||
|
|
||||||
[directory]
|
[directory]
|
||||||
truncation_length = 3
|
truncation_length = 3
|
||||||
truncate_to_repo = true
|
truncate_to_repo = true
|
||||||
style = "bold #0a84ff"
|
style = "bold #CFFC00"
|
||||||
format = "[$path]($style) "
|
format = "[$path]($style) "
|
||||||
|
|
||||||
[git_branch]
|
[git_branch]
|
||||||
symbol = " "
|
symbol = " "
|
||||||
style = "bold #bf5af2"
|
style = "bold #00BFFF"
|
||||||
format = "on [$symbol$branch]($style) "
|
format = "on [$symbol$branch]($style) "
|
||||||
|
|
||||||
[git_status]
|
[git_status]
|
||||||
style = "bold #ff453a"
|
style = "bold #FF7A59"
|
||||||
format = "([$all_status$ahead_behind]($style) )"
|
format = "([$all_status$ahead_behind]($style) )"
|
||||||
|
|
||||||
[nix_shell]
|
[nix_shell]
|
||||||
symbol = " "
|
symbol = " "
|
||||||
style = "bold #64d2ff"
|
style = "bold #e3ff66"
|
||||||
format = "via [$symbol$state]($style) "
|
format = "via [$symbol$state]($style) "
|
||||||
|
|
||||||
[rust]
|
[rust]
|
||||||
symbol = " "
|
symbol = " "
|
||||||
style = "bold #ff9f0a"
|
style = "bold #e3ff66"
|
||||||
format = "[$symbol($version )]($style)"
|
format = "[$symbol($version )]($style)"
|
||||||
|
|
||||||
[c]
|
[c]
|
||||||
symbol = " "
|
symbol = " "
|
||||||
style = "bold #5e5ce6"
|
style = "bold #00BFFF"
|
||||||
format = "[$symbol($version )]($style)"
|
format = "[$symbol($version )]($style)"
|
||||||
|
|
||||||
[python]
|
[python]
|
||||||
symbol = " "
|
symbol = " "
|
||||||
style = "bold #ffd60a"
|
style = "bold #CFFC00"
|
||||||
format = "[$symbol($version )]($style)"
|
format = "[$symbol($version )]($style)"
|
||||||
|
|
||||||
[cmd_duration]
|
[cmd_duration]
|
||||||
min_time = 2000
|
min_time = 2000
|
||||||
style = "bold #ffd60a"
|
style = "bold #FF7A59"
|
||||||
format = "took [$duration]($style) "
|
format = "took [$duration]($style) "
|
||||||
|
|
||||||
[character]
|
[character]
|
||||||
success_symbol = "[➜](bold #30d158) "
|
success_symbol = "[➜](bold #CFFC00) "
|
||||||
error_symbol = "[➜](bold #ff453a) "
|
error_symbol = "[➜](bold #FF7A59) "
|
||||||
|
|||||||
@@ -23,8 +23,9 @@
|
|||||||
enableZshIntegration = true;
|
enableZshIntegration = true;
|
||||||
defaultOptions = [
|
defaultOptions = [
|
||||||
"--color=dark"
|
"--color=dark"
|
||||||
"--color=fg:-1,bg:-1,hl:#c678dd,fg+:#ffffff,bg+:#4b5263,hl+:#d858fe"
|
"--color=fg:#e5e2e1,bg:-1,hl:#CFFC00,fg+:#ffffff,bg+:#1c1b1b,hl+:#e3ff66"
|
||||||
"--color=info:#98c379,prompt:#61afef,pointer:#be5046,marker:#e5c07b,spinner:#61afef,header:#61afef"
|
"--color=info:#ADAAAA,prompt:#CFFC00,pointer:#FF7A59,marker:#CFFC00,spinner:#00BFFF,header:#00BFFF"
|
||||||
|
"--color=border:#2a2929,bg+:-1,gutter:-1"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,26 @@
|
|||||||
|
|
||||||
networking.hostName = "hades";
|
networking.hostName = "hades";
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Host display configuration (absorbed by home/hypr/hyprland.nix)
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
home-manager.users.anish.volt.monitors = [
|
||||||
|
{
|
||||||
|
# Samsung Odyssey Ark - matched by description so it survives port changes
|
||||||
|
output = "desc:Samsung Electric Company Odyssey Ark H1AK500000";
|
||||||
|
mode = "3840x2160@164.99Hz";
|
||||||
|
position = "auto";
|
||||||
|
scale = 1.25;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
# Anything else plugged into hades: sensible automatic fallback
|
||||||
|
output = "";
|
||||||
|
mode = "preferred";
|
||||||
|
position = "auto";
|
||||||
|
scale = "auto";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
# Enable in-memory compressed swap
|
# Enable in-memory compressed swap
|
||||||
zramSwap.enable = true;
|
zramSwap.enable = true;
|
||||||
|
|
||||||
|
|||||||
@@ -1,32 +1,41 @@
|
|||||||
{ pkgs, ... }:
|
{ pkgs, lib, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
programs.hyprland = {
|
programs.hyprland = {
|
||||||
enable = true;
|
enable = true;
|
||||||
xwayland.enable = true;
|
xwayland.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
services.displayManager.sddm.enable = false;
|
|
||||||
services.getty.autologinUser = "anish";
|
services.getty.autologinUser = "anish";
|
||||||
|
|
||||||
|
# Boot straight into Hyprland from the first virtual console on any machine.
|
||||||
|
# No display manager required; tty2-6 remain available as plain shells.
|
||||||
|
environment.loginShellInit = ''
|
||||||
|
if [ "$(tty)" = "/dev/tty1" ]; then
|
||||||
|
exec ${pkgs.hyprland}/bin/Hyprland
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Machine-agnostic Wayland session variables.
|
||||||
|
# GPU/vendor specific variables live with their hardware module (e.g. modules/hardware/nvidia.nix).
|
||||||
environment.sessionVariables = {
|
environment.sessionVariables = {
|
||||||
NIXOS_OZONE_WL = "1";
|
NIXOS_OZONE_WL = "1";
|
||||||
WLR_NO_HARDWARE_CURSORS = "1";
|
|
||||||
LIBVA_DRIVER_NAME = "nvidia";
|
|
||||||
GBM_BACKEND = "nvidia-drm";
|
|
||||||
__GLX_VENDOR_LIBRARY_NAME = "nvidia";
|
|
||||||
HYPRCURSOR_ENABLED = "1";
|
HYPRCURSOR_ENABLED = "1";
|
||||||
MOZ_ENABLE_WAYLAND = "1";
|
MOZ_ENABLE_WAYLAND = "1";
|
||||||
QT_QPA_PLATFORM = "wayland;xcb";
|
QT_QPA_PLATFORM = "wayland;xcb";
|
||||||
QT_WAYLAND_DISABLE_WINDOWDECORATION = "1";
|
QT_WAYLAND_DISABLE_WINDOWDECORATION = "1";
|
||||||
CLUTTER_BACKEND = "wayland";
|
CLUTTER_BACKEND = "wayland";
|
||||||
GDK_BACKEND = "wayland,x11,*";
|
GDK_BACKEND = "wayland,x11,*";
|
||||||
WLR_DRM_DEVICES = "/dev/dri/card1:/dev/dri/card0";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Fonts used across the desktop shell (Silicon Volt theme):
|
||||||
|
# JetBrains Mono for terminal/UI mono, IBM Plex Sans for UI sans,
|
||||||
|
# Instrument Serif for display italics, Nanum Gothic Coding as mono fallback.
|
||||||
fonts.packages = with pkgs; [
|
fonts.packages = with pkgs; [
|
||||||
nerd-fonts.jetbrains-mono
|
nerd-fonts.jetbrains-mono
|
||||||
nerd-fonts.fira-code
|
nerd-fonts.fira-code
|
||||||
font-awesome
|
font-awesome
|
||||||
];
|
ibm-plex
|
||||||
|
nanum-gothic-coding
|
||||||
|
] ++ lib.optional (lib.hasAttr "instrument-serif" pkgs) pkgs.instrument-serif;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,4 +22,13 @@
|
|||||||
nvidiaSettings = true;
|
nvidiaSettings = true;
|
||||||
package = config.boot.kernelPackages.nvidiaPackages.stable;
|
package = config.boot.kernelPackages.nvidiaPackages.stable;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# NVIDIA-specific session variables live here so machines without
|
||||||
|
# NVIDIA GPUs (which do not import this module) stay vendor-clean.
|
||||||
|
environment.sessionVariables = {
|
||||||
|
LIBVA_DRIVER_NAME = "nvidia";
|
||||||
|
GBM_BACKEND = "nvidia-drm";
|
||||||
|
__GLX_VENDOR_LIBRARY_NAME = "nvidia";
|
||||||
|
NVD_BACKEND = "direct";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user