Compare commits

12 Commits

15 changed files with 339 additions and 301 deletions

View File

@@ -21,3 +21,11 @@ hl.window_rule({
class = ".*[Ss]team*." class = ".*[Ss]team*."
} }
}) })
hl.window_rule({
name = "shrink-file-picker",
match = { class = "^(xdg-desktop-portal-gtk)$" },
float = true,
size = {900, 900},
move = {"(monitor_w - window_w) / 2", "(monitor_h - window_h) / 2"},
})

View File

@@ -14,12 +14,11 @@ hl.config({
respect_gaps = true, respect_gaps = true,
}, },
col = { col = {
active_border = "rgba(0DB7D4FF)", active_border = "rgba(E29A6EFF)",
inactive_border = "rgba(31313633)", inactive_border = "rgba(2C252033)",
}, },
}, },
}) })
hl.config({ hl.config({
dwindle = { dwindle = {
preserve_split = true, preserve_split = true,
@@ -27,7 +26,6 @@ hl.config({
smart_resizing = false, smart_resizing = false,
}, },
}) })
hl.config({ hl.config({
decoration = { decoration = {
rounding = 10, rounding = 10,
@@ -35,7 +33,7 @@ hl.config({
enabled = true, enabled = true,
range = 16, range = 16,
render_power = 2, render_power = 2,
color = "rgba(00000040)", color = "rgba(1A161340)",
}, },
blur = { blur = {
enabled = true, enabled = true,
@@ -45,9 +43,14 @@ hl.config({
}, },
}, },
}) })
hl.config({ hl.config({
animations = { animations = {
enabled = true, enabled = true,
}, },
}) })
hl.curve("myBezier", { type = "bezier", points = { {0.16, 1}, {0.3, 1} } })
hl.animation({ leaf = "windows", enabled = true, speed = 1.8, bezier = "myBezier" })
hl.animation({ leaf = "windowsOut", enabled = true, speed = 1.6, bezier = "myBezier", style = "popin 90%" })
hl.animation({ leaf = "border", enabled = true, speed = 2.5, bezier = "myBezier" })
hl.animation({ leaf = "fade", enabled = true, speed = 1.8, bezier = "myBezier" })
hl.animation({ leaf = "workspaces", enabled = true, speed = 1.8, bezier = "myBezier" })

View File

@@ -16,7 +16,9 @@ hl.config({
-- Envs -- Envs
hl.env("XCURSOR_SIZE", 24) hl.env("XCURSOR_SIZE", 24)
hl.env("XCUROSR_THEME", "breeze-dark")
hl.env("HYPRCURSOR_SIZE", 24) hl.env("HYPRCURSOR_SIZE", 24)
hl.env("HYPRCURSOR_THEME", "breeze-dark")
hl.env("LIBVA_DRIVER_NAME", "nvidia") hl.env("LIBVA_DRIVER_NAME", "nvidia")
hl.env("__GLX_VENDOR_LIBRARY_NAME", "nvidia") hl.env("__GLX_VENDOR_LIBRARY_NAME", "nvidia")
hl.env("NVD_BACKEND", "direct") hl.env("NVD_BACKEND", "direct")
@@ -33,10 +35,10 @@ hl.on("hyprland.start", function()
hl.exec_cmd("/usr/lib/xdg-desktop-portal-hyprland &") hl.exec_cmd("/usr/lib/xdg-desktop-portal-hyprland &")
hl.exec_cmd("/usr/lib/xdg-desktop-portal &") hl.exec_cmd("/usr/lib/xdg-desktop-portal &")
hl.exec_cmd("hyprpaper") hl.exec_cmd("hyprpaper")
hl.exec_cmd("hypridle")
hl.exec_cmd("nextcloud") hl.exec_cmd("nextcloud")
hl.exec_cmd("waybar") hl.exec_cmd("waybar")
hl.exec_cmd("hyprctl setcursor breeze 24") hl.exec_cmd("hyprctl setcursor breeze 24")
hl.exec_cmd("xsettingsd")
end) end)
-- Exec (run every reload) -- Exec (run every reload)

View File

@@ -0,0 +1,4 @@
ipc = on
preload = /home/dylan/.wallpapers/monochrome.png
wallpaper = ,/home/dylan/.wallpapers/monochrome.png
splash = false

View File

@@ -3,76 +3,72 @@
local mainMod = "SUPER" local mainMod = "SUPER"
-- Sets "Windows" key as main modifier -- Sets "Windows" key as main modifier
hl.bind(mainMod .. " + " .. "RETURN", hl.dsp.exec_cmd(terminal)) hl.bind(mainMod .. " + " .. "RETURN", hl.dsp.exec_cmd(terminal), { description = "Terminal" })
-- Move focus with mainMod + arrow keys -- Move focus with mainMod + arrow keys
hl.bind(mainMod .. " + " .. "left", hl.dsp.focus({ direction = "left" })) hl.bind(mainMod .. " + " .. "up", hl.dsp.focus({ direction = "up" }), { description = "Focus up" })
hl.bind(mainMod .. " + " .. "right", hl.dsp.focus({ direction = "right" })) hl.bind(mainMod .. " + " .. "down", hl.dsp.focus({ direction = "down" }), { description = "Focus down" })
hl.bind(mainMod .. " + " .. "up", hl.dsp.focus({ direction = "up" }))
hl.bind(mainMod .. " + " .. "down", hl.dsp.focus({ direction = "down" }))
-- Switch workspaces with mainMod + [0-9] -- Switch workspaces with mainMod + [0-9]
hl.bind(mainMod .. " + " .. 1, hl.dsp.focus({ workspace = 1 })) hl.bind(mainMod .. " + " .. 1, hl.dsp.focus({ workspace = 1 }), { description = "Workspace 1" })
hl.bind(mainMod .. " + " .. 2, hl.dsp.focus({ workspace = 2 })) hl.bind(mainMod .. " + " .. 2, hl.dsp.focus({ workspace = 2 }), { description = "Workspace 2" })
hl.bind(mainMod .. " + " .. 3, hl.dsp.focus({ workspace = 3 })) hl.bind(mainMod .. " + " .. 3, hl.dsp.focus({ workspace = 3 }), { description = "Workspace 3" })
hl.bind(mainMod .. " + " .. 4, hl.dsp.focus({ workspace = 4 })) hl.bind(mainMod .. " + " .. 4, hl.dsp.focus({ workspace = 4 }), { description = "Workspace 4" })
hl.bind(mainMod .. " + " .. 5, hl.dsp.focus({ workspace = 5 })) hl.bind(mainMod .. " + " .. 5, hl.dsp.focus({ workspace = 5 }), { description = "Workspace 5" })
hl.bind(mainMod .. " + " .. 6, hl.dsp.focus({ workspace = 6 })) hl.bind(mainMod .. " + " .. 6, hl.dsp.focus({ workspace = 6 }), { description = "Workspace 6" })
hl.bind(mainMod .. " + " .. 7, hl.dsp.focus({ workspace = 7 })) hl.bind(mainMod .. " + " .. 7, hl.dsp.focus({ workspace = 7 }), { description = "Workspace 7" })
hl.bind(mainMod .. " + " .. 8, hl.dsp.focus({ workspace = 8 })) hl.bind(mainMod .. " + " .. 8, hl.dsp.focus({ workspace = 8 }), { description = "Workspace 8" })
hl.bind(mainMod .. " + " .. 9, hl.dsp.focus({ workspace = 9 })) hl.bind(mainMod .. " + " .. 9, hl.dsp.focus({ workspace = 9 }), { description = "Workspace 9" })
hl.bind(mainMod .. " + " .. 0, hl.dsp.focus({ workspace = 10 })) hl.bind(mainMod .. " + " .. 0, hl.dsp.focus({ workspace = 10 }), { description = "Workspace 10" })
-- Move active window to a workspace with mainMod + SHIFT + [0-9] -- Move active window to a workspace with mainMod + SHIFT + [0-9]
hl.bind(mainMod .. " + " .. "SHIFT" .. " + " .. 1, hl.dsp.window.move({ workspace = 1 })) hl.bind(mainMod .. " + " .. "SHIFT" .. " + " .. 1, hl.dsp.window.move({ workspace = 1 }), { description = "Move window to workspace 1" })
hl.bind(mainMod .. " + " .. "SHIFT" .. " + " .. 2, hl.dsp.window.move({ workspace = 2 })) hl.bind(mainMod .. " + " .. "SHIFT" .. " + " .. 2, hl.dsp.window.move({ workspace = 2 }), { description = "Move window to workspace 2" })
hl.bind(mainMod .. " + " .. "SHIFT" .. " + " .. 3, hl.dsp.window.move({ workspace = 3 })) hl.bind(mainMod .. " + " .. "SHIFT" .. " + " .. 3, hl.dsp.window.move({ workspace = 3 }), { description = "Move window to workspace 3" })
hl.bind(mainMod .. " + " .. "SHIFT" .. " + " .. 4, hl.dsp.window.move({ workspace = 4 })) hl.bind(mainMod .. " + " .. "SHIFT" .. " + " .. 4, hl.dsp.window.move({ workspace = 4 }), { description = "Move window to workspace 4" })
hl.bind(mainMod .. " + " .. "SHIFT" .. " + " .. 5, hl.dsp.window.move({ workspace = 5 })) hl.bind(mainMod .. " + " .. "SHIFT" .. " + " .. 5, hl.dsp.window.move({ workspace = 5 }), { description = "Move window to workspace 5" })
hl.bind(mainMod .. " + " .. "SHIFT" .. " + " .. 6, hl.dsp.window.move({ workspace = 6 })) hl.bind(mainMod .. " + " .. "SHIFT" .. " + " .. 6, hl.dsp.window.move({ workspace = 6 }), { description = "Move window to workspace 6" })
hl.bind(mainMod .. " + " .. "SHIFT" .. " + " .. 7, hl.dsp.window.move({ workspace = 7 })) hl.bind(mainMod .. " + " .. "SHIFT" .. " + " .. 7, hl.dsp.window.move({ workspace = 7 }), { description = "Move window to workspace 7" })
hl.bind(mainMod .. " + " .. "SHIFT" .. " + " .. 8, hl.dsp.window.move({ workspace = 8 })) hl.bind(mainMod .. " + " .. "SHIFT" .. " + " .. 8, hl.dsp.window.move({ workspace = 8 }), { description = "Move window to workspace 8" })
hl.bind(mainMod .. " + " .. "SHIFT" .. " + " .. 9, hl.dsp.window.move({ workspace = 9 })) hl.bind(mainMod .. " + " .. "SHIFT" .. " + " .. 9, hl.dsp.window.move({ workspace = 9 }), { description = "Move window to workspace 9" })
hl.bind(mainMod .. " + " .. "SHIFT" .. " + " .. 0, hl.dsp.window.move({ workspace = 10 })) hl.bind(mainMod .. " + " .. "SHIFT" .. " + " .. 0, hl.dsp.window.move({ workspace = 10 }), { description = "Move window to workspace 10" })
-- Scroll through existing workspaces with mainMod + scroll -- Scroll through existing workspaces with mainMod + scroll
hl.bind(mainMod .. " + " .. "mouse_down", hl.dsp.focus({ workspace = "e+1" })) hl.bind(mainMod .. " + " .. "right", hl.dsp.focus({ workspace = "+1" }), { description = "Next workspace" })
hl.bind(mainMod .. " + " .. "mouse_up", hl.dsp.focus({ workspace = "e-1" })) hl.bind(mainMod .. " + " .. "left", hl.dsp.focus({ workspace = "-1" }), { description = "Previous workspace" })
-- Move/resize windows with mainMod + LMB/RMB and dragging -- Move/resize windows with mainMod + LMB/RMB and dragging
hl.bind(mainMod .. " + " .. "mouse:272", hl.dsp.window.drag(), { mouse = true }) hl.bind(mainMod .. " + " .. "mouse:272", hl.dsp.window.drag(), { mouse = true, description = "Move window" })
hl.bind(mainMod .. " + " .. "mouse:273", hl.dsp.window.resize(), { mouse = true }) hl.bind(mainMod .. " + " .. "mouse:273", hl.dsp.window.resize(), { mouse = true, description = "Resize window" })
-- Change wallpaper -- Change wallpaper
hl.bind(mainMod .. " + " .. "W", hl.dsp.exec_cmd("~/.config/wofi/scripts/wallpaper.sh")) hl.bind(mainMod .. " + " .. "W", hl.dsp.exec_cmd("~/.config/wofi/scripts/wallpaper.sh"), { description = "Change wallpaper" })
hl.bind(mainMod .. " + " .. "L", hl.dsp.exec_cmd("brightnessctl -e4 -n2 set 5%+"), { locked = true }) hl.bind(mainMod .. " + " .. "L", hl.dsp.exec_cmd("brightnessctl -e4 -n2 set 5%+"), { locked = true, description = "Brightness up" })
hl.bind(mainMod .. " + " .. "K", hl.dsp.exec_cmd("brightnessctl -e4 -n2 set 5%-"), { locked = true }) hl.bind(mainMod .. " + " .. "K", hl.dsp.exec_cmd("brightnessctl -e4 -n2 set 5%-"), { locked = true, description = "Brightness down" })
-- Volume -- Volume
hl.bind("F7", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"), { locked = true }) hl.bind("F7", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"), { locked = true, description = "Volume down" })
hl.bind("F8", hl.dsp.exec_cmd("wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+"), { locked = true }) hl.bind("F8", hl.dsp.exec_cmd("wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+"), { locked = true, description = "Volume up" })
hl.bind("F9", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"), { locked = true }) hl.bind("F9", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"), { locked = true, description = "Mute output" })
hl.bind("F10", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"), { locked = true }) hl.bind("F10", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"), { locked = true, description = "Mute microphone" })
-- Playback (requires playerctl) -- Playback (requires playerctl)
hl.bind("F4", hl.dsp.exec_cmd("playerctl previous"), { locked = true }) hl.bind("F4", hl.dsp.exec_cmd("playerctl previous"), { locked = true, description = "Previous track" })
hl.bind("F5", hl.dsp.exec_cmd("playerctl play-pause"), { locked = true }) hl.bind("F5", hl.dsp.exec_cmd("playerctl play-pause"), { locked = true, description = "Play/pause" })
hl.bind("F6", hl.dsp.exec_cmd("playerctl next"), { locked = true }) hl.bind("F6", hl.dsp.exec_cmd("playerctl next"), { locked = true, description = "Next track" })
hl.bind("switch:on:Lid Switch", hl.dsp.exec_cmd("hyprctl dispatch dpms off"), { locked = true }) hl.bind("switch:on:Lid Switch", hl.dsp.exec_cmd("hyprctl dispatch dpms off"), { locked = true, description = "Displays off on lid close" })
hl.bind("switch:off:Lid Switch", hl.dsp.exec_cmd("hyprctl dispatch dpms on"), { locked = true }) hl.bind("switch:off:Lid Switch", hl.dsp.exec_cmd("hyprctl dispatch dpms on"), { locked = true, description = "Displays on on lid open" })
-- My binds -- My binds
hl.bind("SUPER + CTRL" .. " + " .. "left", hl.dsp.window.swap({ direction = "left" })) hl.bind("SUPER + CTRL" .. " + " .. "left", hl.dsp.window.swap({ direction = "left" }), { description = "Swap window left" })
hl.bind("SUPER + CTRL" .. " + " .. "right", hl.dsp.window.swap({ direction = "right" })) hl.bind("SUPER + CTRL" .. " + " .. "right", hl.dsp.window.swap({ direction = "right" }), { description = "Swap window right" })
hl.bind("SUPER + SHIFT" .. " + " .. "F", hl.dsp.window.fullscreen()) hl.bind("SUPER + SHIFT" .. " + " .. "F", hl.dsp.window.fullscreen(), { description = "Fullscreen" })
hl.bind("SUPER + CTRL" .. " + " .. "F", hl.dsp.window.fullscreen({mode = "maximized"})) hl.bind("SUPER + CTRL" .. " + " .. "F", hl.dsp.window.fullscreen({mode = "maximized"}), { description = "Maximize" })
hl.bind("SUPER" .. " + " .. "Q", hl.dsp.window.close()) hl.bind("SUPER" .. " + " .. "Q", hl.dsp.window.close(), { description = "Close window" })
hl.bind("ALT" .. " + " .. "TAB", hl.dsp.window.cycle_next()) hl.bind("ALT" .. " + " .. "TAB", hl.dsp.window.cycle_next(), { description = "Cycle windows" })
hl.bind("SUPER" .. " + " .. "F", hl.dsp.exec_cmd(fileManager)) hl.bind("SUPER" .. " + " .. "F", hl.dsp.exec_cmd(fileManager), { description = "File manager" })
hl.bind("SUPER" .. " + " .. "D", hl.dsp.exec_cmd(menu)) hl.bind("SUPER" .. " + " .. "D", hl.dsp.exec_cmd(menu), { description = "App launcher" })
hl.bind("SUPER" .. " + " .. "B", hl.dsp.exec_cmd(browser)) hl.bind("SUPER" .. " + " .. "B", hl.dsp.exec_cmd(browser), { description = "Browser" })
hl.bind( hl.bind("SUPER + SHIFT + S", hl.dsp.exec_cmd('grim -g "$(slurp -d)" - | wl-copy'), { description = "Screenshot region to clipboard" })
"SUPER + SHIFT + S", hl.bind(mainMod .. " + slash", hl.dsp.exec_cmd(os.getenv("HOME") .. "/.config/hypr/scripts/show-binds.sh"), { description = "Show keybind cheat sheet" })
hl.dsp.exec_cmd('grim -g "$(slurp -d)" - | wl-copy')
)

View File

@@ -0,0 +1,26 @@
#!/usr/bin/env bash
DATA=$(hyprctl -j binds | jq -r '
def mods(m):
[ if m >= 64 then "SUPER" else empty end,
if (m % 16) >= 8 then "ALT" else empty end,
if (m % 8) >= 4 then "CTRL" else empty end,
if (m % 2) >= 1 then "SHIFT" else empty end ] | join("+");
[ .[] | select(.has_description)
| { k: "\(if .modmask > 0 then mods(.modmask) + "+" else "" end)\(.key)",
d: .description } ]
| sort_by(.k)
| (map(.k | length) | max) as $w
| .[] | "\(.k + (" " * ($w - (.k | length)))) \(.d)"
')
COLS=$(awk '{ if (length > m) m = length } END { print m }' <<< "$DATA")
ROWS=$(wc -l <<< "$DATA")
PRW=$(( COLS * 2 + 4 ))
PX=$(( PRW * 7 + 60 ))
PY=$(( (ROWS / 2 + 2) * 18 + 60 ))
pr -2 -t -w "$PRW" <<< "$DATA" \
| yad --text-info --title="Hyprland Keybinds" \
--width="$PX" --height="$PY" --center \
--fontname="monospace 10" --no-buttons --wrap=false

View File

@@ -0,0 +1,43 @@
#!/usr/bin/env bash
#
# waybar custom module: shows currently playing media, mac-menu-bar style.
# Outputs a single JSON line: {"text":..., "tooltip":..., "class":..., "alt":...}
# waybar re-runs this on an interval (set in config.jsonc) and re-renders.
# --status-format lets us build one compact string per call instead of
# separate playerctl invocations for title/artist/status (fewer subprocess
# spawns = faster polling, matters since waybar calls this every ~1s).
STATUS=$(playerctl -a metadata --format '{{status}}|{{artist}}|{{title}}|{{playerName}}' 2>/dev/null | head -n1)
if [ -z "$STATUS" ]; then
# No MPRIS players running at all -> render nothing (empty text hides
# the module if `"class": "hidden"` is styled to display:none, but
# simplest is just an empty text with no tooltip).
echo '{"text": "", "tooltip": "No media playing", "class": "hidden"}'
exit 0
fi
# IFS='|' read splits our pipe-delimited format string into vars.
IFS='|' read -r PSTATUS ARTIST TITLE PLAYER <<< "$STATUS"
# Playing vs Paused get different CSS classes so you can dim the paused state.
case "$PSTATUS" in
Playing) ICON="" ;; # nerd-font play glyph
Paused) ICON="" ;; # nerd-font pause glyph
*) ICON="" ;;
esac
# Truncate long titles so the bar doesn't blow out — cut at 30 chars,
# append an ellipsis. This is bash parameter expansion, not a subprocess.
LABEL="${ARTIST} - ${TITLE}"
if [ "${#LABEL}" -gt 32 ]; then
LABEL="${LABEL:0:29}..."
fi
# Escape double quotes so we don't break the JSON if a title contains one.
LABEL_ESC=$(printf '%s' "$LABEL" | sed 's/"/\\"/g')
TOOLTIP_ESC=$(printf '%s — %s\n(%s)' "$ARTIST" "$TITLE" "$PLAYER" | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/\\n/g')
CLASS="media-${PSTATUS,,}" # bash ${var,,} lowercases -> "media-playing" / "media-paused"
echo "{\"text\": \"${ICON} ${LABEL_ESC}\", \"tooltip\": \"${TOOLTIP_ESC}\", \"class\": \"${CLASS}\", \"alt\": \"${PSTATUS}\"}"

View File

@@ -1,32 +1,33 @@
/* ============================================================ /* ============================================================
WAYBAR STYLE — Dark Industrial / Refined Utility WAYBAR STYLE — Cream Claude / Warm Minimal
Palette: deep charcoal base, amber accents, cool greys Palette: warm cream base, clay/terracotta accent, soft browns
============================================================ */ ============================================================ */
/* ── Root Variables ───────────────────────────────────────── */ /* ── Root Variables ───────────────────────────────────────── */
* { * {
font-family: "JetBrainsMono Nerd Font Propo"; font-family: "Inter", "SF Pro Display", "Segoe UI", sans-serif;
font-size: 13px; font-size: 13px;
font-weight: 400;
border: none; border: none;
border-radius: 0; border-radius: 0;
} }
/* ── Bar ──────────────────────────────────────────────────── */ /* ── Bar ──────────────────────────────────────────────────── */
window#waybar { window#waybar {
background: rgba(10, 10, 14, 0); background: rgba(26, 22, 19, 0.55);
color: #dcdce8; color: #e8ddd0;
} }
/* ── Tooltip ──────────────────────────────────────────────── */ /* ── Tooltip ──────────────────────────────────────────────── */
tooltip { tooltip {
background: #0e0e12; background: rgba(30, 25, 21, 0.92);
border: 1px solid rgba(255, 180, 60, 0.35); border: 1px solid rgba(196, 108, 74, 0.4);
color: #dcdce8; color: #e8ddd0;
padding: 6px 10px; padding: 6px 10px;
} }
tooltip label { tooltip label {
color: #dcdce8; color: #e8ddd0;
} }
/* ── Shared Module Base ───────────────────────────────────── */ /* ── Shared Module Base ───────────────────────────────────── */
@@ -41,53 +42,42 @@ tooltip label {
#custom-power { #custom-power {
padding: 6px 12px; padding: 6px 12px;
margin: 5px 0; margin: 5px 0;
color: #dcdce8; color: #e8ddd0;
background: rgba(10, 10, 14, 0.3); background: rgba(44, 37, 32, 0.5);
transition: color 0.2s ease, background 0.2s ease; transition: color 0.2s ease, background 0.2s ease;
} }
/* ── Separator dots between modules ──────────────────────── */
#cpu,
#memory,
#pulseaudio,
#bluetooth,
#custom-micmute,
#battery {
border-left: 1px solid rgba(255, 255, 255, 0);
}
/* ═══════════════════════════════════════════════════════════ /* ═══════════════════════════════════════════════════════════
LEFT — System Info: Clock · CPU · Memory LEFT — System Info: Clock · CPU · Memory
═══════════════════════════════════════════════════════════ */ ═══════════════════════════════════════════════════════════ */
#clock { #clock {
font-family: "JetBrainsMono Nerd Font Propo"; font-weight: 500;
font-weight: 400;
font-size: 12.5px; font-size: 12.5px;
color: #f0de9c; color: #e29a6e;
letter-spacing: 0.04em; letter-spacing: 0.03em;
padding-left: 0.4em; padding-left: 0.4em;
border-left: 3px solid rgba(255, 180, 60, 0.3); border-left: 3px solid rgba(226, 154, 110, 0.5);
margin-left: 8px; margin-left: 8px;
} }
#cpu { #cpu {
color: #b8d8ee; color: #c9baa8;
} }
#cpu:hover { #cpu:hover {
color: #d8f0ff; color: #f0e6d8;
background: rgba(160, 196, 216, 0.14); background: rgba(226, 154, 110, 0.16);
} }
#memory { #memory {
color: #b0d4be; color: #c9baa8;
} }
#memory:hover { #memory:hover {
color: #ceeede; color: #f0e6d8;
background: rgba(157, 191, 173, 0.14); background: rgba(180, 156, 120, 0.2);
} }
@@ -102,12 +92,11 @@ tooltip label {
} }
#workspaces button { #workspaces button {
font-family: 'JetBrains Nerd Font Propo';
font-size: 12px; font-size: 12px;
padding: 2px 10px; padding: 2px 10px;
margin: 4px 2px; margin: 4px 2px;
color: #6e6e88; color: #8a7a68;
background: rgba(255, 255, 255, 0.05); background: rgba(232, 221, 208, 0.08);
border: 1px solid transparent; border: 1px solid transparent;
border-radius: 3px; border-radius: 3px;
transition: all 0.15s ease; transition: all 0.15s ease;
@@ -115,22 +104,22 @@ tooltip label {
} }
#workspaces button:hover { #workspaces button:hover {
color: #c0c0d8; color: #e8ddd0;
background: rgba(255, 255, 255, 0.1); background: rgba(232, 221, 208, 0.14);
border-color: rgba(255, 255, 255, 0.15); border-color: rgba(232, 221, 208, 0.2);
} }
#workspaces button.active { #workspaces button.active {
color: #f0c060; color: #e29a6e;
background: rgba(255, 180, 60, 0.14); background: rgba(226, 154, 110, 0.18);
border-color: rgba(255, 180, 60, 0.5); border-color: rgba(226, 154, 110, 0.55);
font-weight: 600; font-weight: 600;
} }
#workspaces button.urgent { #workspaces button.urgent {
color: #f08080; color: #d9695a;
background: rgba(240, 80, 80, 0.15); background: rgba(217, 105, 90, 0.18);
border-color: rgba(240, 80, 80, 0.45); border-color: rgba(217, 105, 90, 0.5);
} }
@@ -149,61 +138,61 @@ tooltip label {
#tray > .needs-attention { #tray > .needs-attention {
-gtk-icon-effect: highlight; -gtk-icon-effect: highlight;
background-color: rgba(240, 120, 60, 0.25); background-color: rgba(196, 108, 74, 0.25);
} }
/* ── Audio ────────────────────────────────────────────────── */ /* ── Audio ────────────────────────────────────────────────── */
#pulseaudio { #pulseaudio {
color: #c4bce8; color: #c9a68c;
} }
#pulseaudio:hover { #pulseaudio:hover {
color: #e0d8ff; color: #f0e6d8;
background: rgba(176, 168, 216, 0.14); background: rgba(201, 166, 140, 0.16);
} }
/* ── Bluetooth ────────────────────────────────────────────── */ /* ── Bluetooth ────────────────────────────────────────────── */
#bluetooth { #bluetooth {
color: #90c8f0; color: #9ab4c4;
} }
#bluetooth.connected { #bluetooth.connected {
color: #70d8ff; color: #a8c8dc;
} }
#bluetooth:hover { #bluetooth:hover {
background: rgba(128, 184, 224, 0.14); background: rgba(154, 180, 196, 0.16);
} }
/* ── Microphone Mute ──────────────────────────────────────── */ /* ── Microphone Mute ──────────────────────────────────────── */
#custom-micmute { #custom-micmute {
color: #b0d4be; color: #c9baa8;
} }
#custom-micmute.muted { #custom-micmute.muted {
color: #585870; color: #6e6055;
} }
#custom-micmute:hover { #custom-micmute:hover {
background: rgba(157, 191, 173, 0.14); background: rgba(201, 186, 168, 0.16);
} }
/* ── Battery ──────────────────────────────────────────────── */ /* ── Battery ──────────────────────────────────────────────── */
#battery { #battery {
color: #b8dc98; color: #a8bc90;
} }
#battery.charging, #battery.charging,
#battery.plugged { #battery.plugged {
color: #d4f098; color: #c0d4a0;
} }
#battery.warning:not(.charging) { #battery.warning:not(.charging) {
color: #eecb68; color: #dcb06a;
} }
#battery.critical:not(.charging) { #battery.critical:not(.charging) {
color: #f07060; color: #e0796a;
animation: battery-pulse 1.5s ease-in-out infinite; animation: battery-pulse 1.5s ease-in-out infinite;
} }
@@ -220,19 +209,19 @@ tooltip label {
} }
#battery:hover { #battery:hover {
background: rgba(168, 204, 136, 0.14); background: rgba(168, 188, 144, 0.16);
} }
/* ── Power Button ─────────────────────────────────────────── */ /* ── Power Button ─────────────────────────────────────────── */
#custom-power { #custom-power {
color: #d07070; color: #e29a6e;
font-size: 14px; font-size: 14px;
padding: 2px 14px 2px 12px; padding: 2px 14px 2px 12px;
margin-right: 8px; margin-right: 8px;
border-right: 3px solid rgba(255, 0, 0, 0.3); border-right: 3px solid rgba(196, 108, 74, 0.4);
} }
#custom-power:hover { #custom-power:hover {
color: #f09090; color: #c0392b;
background: rgba(200, 60, 60, 0.2); background: rgba(196, 108, 74, 0.2);
} }

View File

@@ -1,8 +1,11 @@
mode=drun show=drun
allow_images=true width=600
image_size=32 height=420
term=kitty
insensitive=true
location=center location=center
no_actions=true
prompt=Search prompt=Search
allow_images=true
image_size=28
insensitive=true
hide_scroll=true
no_actions=true
gtk_dark=true

View File

@@ -1,91 +1,44 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Configuration # wallpaper.sh — pick a wallpaper from ~/.wallpapers via wofi, apply with hyprpaper
WALLPAPER_DIR="$HOME/.wallpapers" # Change this to your wallpaper directory set -euo pipefail
CACHE_DIR="$HOME/.cache/wallpaper-selector" DIR="${HOME}/.wallpapers"
THUMBNAIL_WIDTH="250" # Size of thumbnails in pixels (16:9) CACHE="${XDG_CACHE_HOME:-$HOME/.cache}/wallpaper-thumbs"
THUMBNAIL_HEIGHT="141" [[ -d "$DIR" ]] || { notify-send "wallpaper.sh" "No $DIR"; exit 1; }
# Create cache directory if it doesn't exist mkdir -p "$CACHE"
mkdir -p "$CACHE_DIR"
# Function to generate thumbnail mapfile -t files < <(find -L "$DIR" -maxdepth 1 -type f \
generate_thumbnail() { \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' -o -iname '*.webp' \) \
local input="$1" -printf '%f\n' | LC_ALL=C sort)
local output="$2" [[ ${#files[@]} -gt 0 ]] || { notify-send "wallpaper.sh" "No images found"; exit 1; }
magick "$input" -thumbnail "${THUMBNAIL_WIDTH}x${THUMBNAIL_HEIGHT}^" -gravity center -extent "${THUMBNAIL_WIDTH}x${THUMBNAIL_HEIGHT}" "$output"
}
# Create shuffle icon thumbnail on the fly # Build any missing/stale thumbnails, in parallel.
SHUFFLE_ICON="$CACHE_DIR/shuffle_thumbnail.png" for f in "${files[@]}"; do
# Create a properly sized shuffle icon thumbnail src="${DIR}/${f}"
# magick -size "${THUMBNAIL_WIDTH}x${THUMBNAIL_HEIGHT}" xc:#1e1e2e \ thumb="${CACHE}/${f%.*}.png"
# "$HOME/Repos/wallpaper-selector/assets/shuffle.png" -resize "120x120" -gravity center -composite \ [[ -f "$thumb" && "$thumb" -nt "$src" ]] && continue
# "$SHUFFLE_ICON" magick "$src" -thumbnail 360x360^ -strip "$thumb" &
magick -size "${THUMBNAIL_WIDTH}x${THUMBNAIL_HEIGHT}" xc:#1e1e2e \ done
\( "$HOME/Repos/wallpaper-selector/assets/shuffle.png" -resize "80x80" \) \ wait
-gravity center -composite "$SHUFFLE_ICON"
# Generate thumbnails and create menu items RANDOM_LABEL="🎲 Random"
generate_menu() { menu="img::text:${RANDOM_LABEL}\n"
# Add random/shuffle option with a name that sorts first (using ! prefix) for f in "${files[@]}"; do
echo -en "img:$SHUFFLE_ICON\x00info:!Random Wallpaper\x1fRANDOM\n" menu+="img:${CACHE}/${f%.*}.png:text:${f}\n"
done
# Then add all wallpapers line=$(echo -en "$menu" | wofi \
for img in "$WALLPAPER_DIR"/*.{jpg,jpeg,png}; do --dmenu --show dmenu --allow-images --insensitive \
# Skip if no matches found --define image_size=180 --columns 4 --prompt "Wallpaper" \
[[ -f "$img" ]] || continue --define sort_order=default --cache-file /dev/null \
--style "${HOME}/.config/wofi/wallpaper.css" \
--width 900 --height 620 --define halign=fill --define content_halign=fill)
[[ -n "$line" ]] || exit 0
# Generate thumbnail filename if [[ "$line" == *"$RANDOM_LABEL"* ]]; then
thumbnail="$CACHE_DIR/$(basename "${img%.*}").png" WALL="${DIR}/${files[RANDOM % ${#files[@]}]}"
else
# Generate thumbnail if it doesn't exist or is older than source choice="${line##*:text:}"
if [[ ! -f "$thumbnail" ]] || [[ "$img" -nt "$thumbnail" ]]; then WALL="${DIR}/${choice}"
generate_thumbnail "$img" "$thumbnail"
fi
# Output menu item (filename and path)
echo -en "img:$thumbnail\x00info:$(basename "$img")\x1f$img\n"
done
}
# Use wofi to display grid of wallpapers - IMPORTANT: added --sort-order=default
selected=$(generate_menu | wofi --show dmenu \
--cache-file /dev/null \
--define "image-size=${THUMBNAIL_WIDTH}x${THUMBNAIL_HEIGHT}" \
--columns 3 \
--allow-images \
--insensitive \
--sort-order=default \
--prompt "Select Wallpaper" \
--conf ~/.config/wofi/wallpaper.conf \
)
# Set wallpaper if one was selected
if [ -n "$selected" ]; then
# Remove the img: prefix to get the cached thumbnail path
thumbnail_path="${selected#img:}"
# Check if random wallpaper was selected
if [[ "$thumbnail_path" == "$SHUFFLE_ICON" ]]; then
# Select a random wallpaper from the directory
original_path=$(find "$WALLPAPER_DIR" -type f \( -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" \) | shuf -n 1)
else
# Get the original filename from the thumbnail path
original_filename=$(basename "${thumbnail_path%.*}")
# Find the corresponding original file in the wallpaper directory
original_path=$(find "$WALLPAPER_DIR" -type f -name "${original_filename}.*" | head -n1)
fi
# Ensure a valid wallpaper was found before proceeding
if [ -n "$original_path" ]; then
hyprctl hyprpaper wallpaper ",$original_path"
# Save the selection for persistence
echo "$original_path" > "$HOME/.cache/current_wallpaper"
# Optional: Notify user
notify-send "Wallpaper" "Wallpaper has been updated" -i "$original_path"
else
notify-send "Wallpaper Error" "Could not find the original wallpaper file."
fi
fi fi
hyprctl hyprpaper wallpaper ",${WALL}"

View File

@@ -1,66 +1,70 @@
/* ======================== /* ~/.config/wofi/style.css */
Wofi Lovely Theme @define-color base rgba(26, 22, 19, 0.75);
======================== */ @define-color mantle rgba(20, 17, 14, 0.7);
@define-color surface rgba(232, 221, 208, 0.1);
@define-color overlay #8a7a68;
@define-color text #e8ddd0;
@define-color subtext #c9baa8;
@define-color accent #e29a6e;
@define-color accent2 #c46c4a;
/* Window styling */
window { window {
background-color: #1e1e2e; /* Dark blue-ish background */ background-color: transparent;
border-radius: 12px; font-family: "Inter", "SF Pro Display", "Segoe UI", sans-serif;
padding: 10px; font-size: 14px;
border: 1px solid #44475a;
} }
#outer-box {
/* Entry box styling */ background-color: @base;
entry { border: 1px solid rgba(226, 154, 110, 0.35);
font-family: "JetBrains Mono", monospace; border-radius: 14px;
font-size: 16px; padding: 12px;
color: #f8f8f2; /* light text */ }
#input {
background-color: @mantle;
color: @text;
border: 1px solid rgba(232, 221, 208, 0.12);
border-radius: 10px;
padding: 10px 14px;
margin-bottom: 10px;
caret-color: @accent;
}
#input:focus {
border-color: @accent;
}
#scroll {
margin: 0;
border: none;
}
#inner-box {
background-color: transparent;
}
#entry {
padding: 8px 10px; padding: 8px 10px;
border-radius: 8px; border-radius: 8px;
background-color: #2e2e3e; /* darker input box */
border: 1px solid #6272a4;
}
/* Selected suggestion */
row:selected {
background-color: #6272a4;
color: #f8f8f2;
}
/* Suggestions list */
row {
padding: 6px 10px;
border-radius: 6px;
margin: 2px 0; margin: 2px 0;
transition: background 0.2s ease; color: @subtext;
transition: background-color 120ms ease, color 120ms ease;
} }
#entry:selected,
/* Icon styling */ #entry:hover {
image { background-color: @surface;
width: 32px; /* smaller icons */ color: @text;
height: 32px; outline: none;
margin-right: 10px;
} }
#entry:selected {
/* Scrollbar styling */ box-shadow: inset 3px 0 0 0 @accent;
scrollbar {
background-color: #1e1e2e;
width: 6px;
border-radius: 3px;
} }
/* node type `image`, not `img` — this is the one that actually moves the icon */
scrollbar slider { #entry image {
background-color: #6272a4; margin-right: 18px;
border-radius: 3px; -gtk-icon-transform: scale(0.9);
} }
#entry #text {
/* Hint text */ color: inherit;
entry placeholder {
color: #bfbfbf;
} }
#entry:selected #text {
/* For accessibility: highlight keyboard navigation */ font-weight: 600;
row:focus { }
outline: 2px solid #ff79c6; #unselected {
color: @subtext;
} }

View File

@@ -1,47 +1,50 @@
/* wallpaper.sh picker — dark glass, terracotta accent */
window { window {
background-color: #1e1e2e; background-color: rgba(26, 22, 19, 0.85);
border-radius: 8px; border: 1px solid rgba(226, 154, 110, 0.35);
border: 2px solid #313244; border-radius: 16px;
font-family: "Inter", "SF Pro Display", "Segoe UI", sans-serif;
} }
#input { #input {
margin: 2px; margin: 12px;
padding: 4px; padding: 10px 14px;
border-radius: 4px; border: 1px solid rgba(226, 154, 110, 0.25);
border: none; border-radius: 10px;
background-color: #313244; background-color: rgba(20, 17, 14, 0.85);
color: #cdd6f4; color: #e8ddd0;
font-size: 15px;
}
#input:focus {
border-color: rgba(226, 154, 110, 0.8);
} }
#inner-box { #inner-box {
margin: 0px; margin: 6px 12px 12px 12px;
background-color: transparent;
} }
#outer-box { #outer-box {
margin: 0px; background-color: transparent;
} }
#scroll { #scroll {
margin: 0px; margin: 0px;
} }
#text {
margin: 2px;
color: #cdd6f4;
}
#entry { #entry {
padding: 2px; margin: 6px;
margin: 0px; padding: 6px;
border-radius: 4px; border: 2px solid transparent;
border-radius: 12px;
background-color: rgba(44, 37, 32, 0.5);
} }
#entry:selected { #entry:selected {
background-color: #313244; border-color: #e29a6e;
background-color: rgba(226, 154, 110, 0.15);
} }
#entry image {
#img { border-radius: 8px;
margin: 2px; }
padding-left: 4px; #text {
border-radius: 4px; color: #c9baa8;
margin: 0px 4px;
}
#entry:selected #text {
color: #ffffff;
} }

2
.zshrc
View File

@@ -13,6 +13,8 @@ export QT_QPA_PLATFORMTHEME=qt6ct # Qt6 apps
# ALIASES # ALIASES
alias dotfiles="git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME" alias dotfiles="git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME"
alias pac="sudo pacman -S"
alias update="sudo pacman -Syu"
# COMPLETION (before plugins that hook into it) # COMPLETION (before plugins that hook into it)
autoload -Uz compinit && compinit autoload -Uz compinit && compinit

View File

@@ -20,3 +20,4 @@ unzip
zip zip
zsh zsh
zsh-syntax-highlighting zsh-syntax-highlighting
zsh-autosuggestions

View File

@@ -41,3 +41,4 @@ imagemagick
webkit2gtk webkit2gtk
xorg-xrandr xorg-xrandr
earlyoom earlyoom
yad