diff --git a/eww/eww.scss b/eww/eww.scss new file mode 100644 index 0000000..65a2066 --- /dev/null +++ b/eww/eww.scss @@ -0,0 +1,48 @@ +* { all: unset; } + +.volume-overlay { + background: rgba(15, 15, 20, 0.92); + border: 1px solid rgba(255,255,255,0.08); + border-radius: 12px; + padding: 16px; + backdrop-filter: blur(20px); + color: #e0e0e0; + font-family: "JetBrains Mono", monospace; +} + +.header { + margin-bottom: 4px; + .header-icon { font-size: 18px; color: #33ccff; } + .header-title { font-size: 14px; font-weight: bold; color: #fff; } +} + +.divider { + background: rgba(255,255,255,0.07); + min-height: 1px; + margin: 4px 0; +} + +.sink-row { + padding: 4px 0; + .app-name { font-size: 12px; color: #aaa; min-width: 120px; } + .app-vol { font-size: 12px; color: #33ccff; margin-left: auto; } + .app-icon { font-size: 14px; color: #666; } +} + +.vol-slider { + min-height: 20px; + trough { background: rgba(255,255,255,0.1); border-radius: 4px; min-height: 4px; } + highlight { background: linear-gradient(90deg, #33ccff, #00ff99); border-radius: 4px; } + slider { background: #fff; border-radius: 50%; min-width: 12px; min-height: 12px; } +} + +.mute-btn { + margin-top: 8px; + background: rgba(255,255,255,0.06); + border-radius: 8px; + padding: 8px; + font-size: 13px; + color: #aaa; + &:hover { background: rgba(255,255,255,0.12); } + &.muted { color: #ff5555; background: rgba(255,85,85,0.1); } +} \ No newline at end of file diff --git a/eww/eww.yuck b/eww/eww.yuck new file mode 100644 index 0000000..7107fec --- /dev/null +++ b/eww/eww.yuck @@ -0,0 +1,49 @@ +(defpoll volume :interval "1s" + "wpctl get-volume @DEFAULT_AUDIO_SINK@ | awk '{printf \"%d\", $2*100}'") + +(defpoll muted :interval "1s" + "wpctl get-volume @DEFAULT_AUDIO_SINK@ | grep -c MUTED || echo 0") + +(defpoll sink-inputs :interval "2s" + "~/.config/eww/scripts/get-sinks.sh") + +(defwidget volume-overlay [] + (box :class "volume-overlay" :orientation "v" :spacing 12 :space-evenly false + (box :class "header" :orientation "h" :space-evenly false :spacing 8 + (label :class "header-icon" :text "󰕾") + (label :class "header-title" :text "Volume Mixer")) + + (box :class "sink-row" :orientation "v" :spacing 4 + (box :orientation "h" :space-evenly false :spacing 8 + (label :class "app-icon" :text "󰓃") + (label :class "app-name" :text "Master") + (label :class "app-vol" :text "${volume}%")) + (scale :class "vol-slider master-slider" + :min 0 :max 100 :value volume + :onchange "wpctl set-volume @DEFAULT_AUDIO_SINK@ {}%")) + + (box :class "divider") + + (for sink in sink-inputs + (box :class "sink-row" :orientation "v" :spacing 4 + (box :orientation "h" :space-evenly false :spacing 8 + (label :class "app-icon" :text "󰓃") + (label :class "app-name" :text {sink.name}) + (label :class "app-vol" :text "${sink.volume}%")) + (scale :class "vol-slider" + :min 0 :max 100 :value {sink.volume} + :onchange "wpctl set-volume ${sink.id} {}%"))) + + (button :class "mute-btn ${muted == "1" ? "muted" : ""}" + :onclick "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle" + (label :text "${muted == "1" ? "󰝟 Muted" : "󰕾 Mute"}")))) + +(defwindow volume-mixer + :monitor 0 + :geometry (geometry :x "0px" :y "40px" + :width "280px" + :anchor "top right") + :stacking "overlay" + :exclusive false + (volume-overlay)) + diff --git a/eww/scripts/get-sinks.sh b/eww/scripts/get-sinks.sh new file mode 100755 index 0000000..933bcbc --- /dev/null +++ b/eww/scripts/get-sinks.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# Get all sink inputs as JSON array for eww +pactl list sink-inputs | awk ' +/^Sink Input/ { id=substr($3,2,length($3)-1) } +/application.name/ { gsub(/"/,"",$3); name=$3 } +/Volume:.*%/ { + match($0, /[0-9]+%/) + vol=substr($0,RSTART,RLENGTH-1) + printf "{\"id\":\"%s\",\"name\":\"%s\",\"volume\":\"%s\"}\n", id, name, vol + name=""; vol="" +}' | jq -s '.' \ No newline at end of file diff --git a/eww/scripts/toggle-mixer.sh b/eww/scripts/toggle-mixer.sh new file mode 100755 index 0000000..814211a --- /dev/null +++ b/eww/scripts/toggle-mixer.sh @@ -0,0 +1,6 @@ +#!/bin/bash +if eww active-windows | grep -q "volume-mixer"; then + eww close volume-mixer +else + eww open volume-mixer +fi \ No newline at end of file diff --git a/hypr/2d-nav.sh b/hypr/2d-nav.sh new file mode 100644 index 0000000..93d3abe --- /dev/null +++ b/hypr/2d-nav.sh @@ -0,0 +1,131 @@ +#!/usr/bin/env bash +# ~/.config/hypr/2d-nav.sh +# 2D workspace navigation for Hyprland +# Workspaces are named "X" (base row) or "X-Y" (sub-row, Y >= 1) +# Usage: 2d-nav.sh [left|right|up|down|move-left|move-right|move-up|move-down] + +set -euo pipefail + +ACTION="${1:-}" + +# --- Parse current workspace --- +# Returns e.g. "3" or "3-2" +get_current_ws() { + hyprctl activeworkspace -j | jq -r '.name' +} + +# Split "X-Y" into X and Y parts +parse_ws() { + local name="$1" + if [[ "$name" =~ ^([0-9]+)-([0-9]+)$ ]]; then + echo "${BASH_REMATCH[1]} ${BASH_REMATCH[2]}" + elif [[ "$name" =~ ^([0-9]+)$ ]]; then + echo "${BASH_REMATCH[1]} 0" + else + # Named/special workspace we don't manage — bail + echo "0 0" + fi +} + +make_ws_name() { + local x="$1" y="$2" + if [[ "$y" -eq 0 ]]; then + echo "$x" + else + echo "${x}-${y}" + fi +} + +# Check if a named workspace currently exists (has at least one window OR is active) +ws_exists() { + local name="$1" + hyprctl workspaces -j | jq -e --arg n "$name" '.[] | select(.name == $n)' > /dev/null 2>&1 +} + +# Navigate to workspace (creates it on demand if going up; smart-back if going down) +go_to_ws() { + local name="$1" + hyprctl dispatch workspace "name:${name}" +} + +move_window_to_ws() { + local name="$1" + hyprctl dispatch movetoworkspace "name:${name}" +} + +# --- Main logic --- +current=$(get_current_ws) +read -r cx cy <<< "$(parse_ws "$current")" + +# Min/max for X axis (your config has 1-5 on DP-2, 6-10 on HDMI-A-1) +# But for 2D nav we treat X as free-range 1..10 +X_MIN=1 +X_MAX=10 +Y_MIN=0 +Y_MAX=9 # Reasonable cap for sub-workspaces + +case "$ACTION" in + right) + nx=$(( cx < X_MAX ? cx + 1 : cx )) + # When moving right, land on base row of target X (Y=0) + target=$(make_ws_name "$nx" 0) + go_to_ws "$target" + ;; + left) + nx=$(( cx > X_MIN ? cx - 1 : cx )) + target=$(make_ws_name "$nx" 0) + go_to_ws "$target" + ;; + up) + ny=$(( cy < Y_MAX ? cy + 1 : cy )) + target=$(make_ws_name "$cx" "$ny") + go_to_ws "$target" + ;; + down) + if [[ "$cy" -gt 0 ]]; then + ny=$(( cy - 1 )) + # If the workspace below doesn't exist, fall back to base (Y=0), not Y=(cy-1) + target=$(make_ws_name "$cx" "$ny") + if [[ "$ny" -gt 0 ]] && ! ws_exists "$target"; then + target=$(make_ws_name "$cx" 0) + fi + else + target=$(make_ws_name "$cx" 0) + fi + go_to_ws "$target" + ;; + + # --- Move window variants --- + move-right) + nx=$(( cx < X_MAX ? cx + 1 : cx )) + target=$(make_ws_name "$nx" 0) + move_window_to_ws "$target" + ;; + move-left) + nx=$(( cx > X_MIN ? cx - 1 : cx )) + target=$(make_ws_name "$nx" 0) + move_window_to_ws "$target" + ;; + move-up) + ny=$(( cy < Y_MAX ? cy + 1 : cy )) + target=$(make_ws_name "$cx" "$ny") + move_window_to_ws "$target" + ;; + move-down) + if [[ "$cy" -gt 0 ]]; then + ny=$(( cy - 1 )) + target=$(make_ws_name "$cx" "$ny") + if [[ "$ny" -gt 0 ]] && ! ws_exists "$target"; then + target=$(make_ws_name "$cx" 0) + fi + else + target=$(make_ws_name "$cx" 0) + fi + move_window_to_ws "$target" + ;; + + *) + echo "Usage: $0 [left|right|up|down|move-left|move-right|move-up|move-down]" >&2 + exit 1 + ;; +esac \ No newline at end of file diff --git a/hypr/2d-workspaces.sh b/hypr/2d-workspaces.sh new file mode 100644 index 0000000..33b79fd --- /dev/null +++ b/hypr/2d-workspaces.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +# ~/.config/hypr/2d-workspaces.sh +# Outputs current 2D position as Waybar JSON: "3" or "3.2" + +current=$(hyprctl activeworkspace -j | jq -r '.name') + +if [[ "$current" =~ ^([0-9]+)-([0-9]+)$ ]]; then + cx="${BASH_REMATCH[1]}" + cy="${BASH_REMATCH[2]}" + label="${cx}.${cy}" + class="sub" +elif [[ "$current" =~ ^([0-9]+)$ ]]; then + cx="${BASH_REMATCH[1]}" + label="${cx}" + class="base" +else + label="?" + class="unknown" +fi + +printf '{"text": "%s", "class": "%s"}\n' "$label" "$class" \ No newline at end of file diff --git a/hypr/autostart.sh b/hypr/autostart.sh deleted file mode 100755 index c404f30..0000000 --- a/hypr/autostart.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/bash -# ~/.config/hypr/autostart.sh -# Launches apps and moves them to the correct workspace once their window appears. -# Use in hyprland.conf: -# exec-once = ~/.config/hypr/autostart.sh - -# ── helpers ─────────────────────────────────────────────────────────────────── - -# Wait for a window matching a class/title regex, then move it to a workspace. -# Usage: launch_on -launch_on() { - local ws="$1" - local class="$2" - shift 2 - local cmd=("$@") - - # Launch the app in the background - "${cmd[@]}" & - - # Poll until the window appears, then move it - for _ in $(seq 1 30); do - sleep 1 - local addr - addr=$(hyprctl clients -j \ - | grep -i "\"class\": \"$class\"" \ - | head -1) - if [[ -n "$addr" ]]; then - hyprctl dispatch movetoworkspacesilent "$ws,class:^(${class})$" - break - fi - done -} - -# ── app definitions ─────────────────────────────────────────────────────────── -# launch_on - -launch_on 1 firefox firefox -launch_on 2 code code -launch_on 3 kitty kitty -launch_on 4 vesktop vesktop -launch_on 5 steam steam -launch_on 6 spotify spotify \ No newline at end of file diff --git a/hypr/depencies-check.sh b/hypr/depencies-check.sh new file mode 100644 index 0000000..dc34559 --- /dev/null +++ b/hypr/depencies-check.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +# ───────────────────────────────────────── +# Dependency Checker +# ───────────────────────────────────────── + +DEPS=( + eww + steam + code + firefox + vesktop + kitty + wofi + thunar + fastfetch + waybar + jq +) + +PASS=0 +FAIL=0 +MISSING=() + +# Colors +GREEN='\033[0;32m' +RED='\033[0;31m' +CYAN='\033[0;36m' +BOLD='\033[1m' +RESET='\033[0m' + +echo "" +echo -e "${BOLD}${CYAN} Checking dependencies...${RESET}" +echo -e " ──────────────────────────" + +for dep in "${DEPS[@]}"; do + if command -v "$dep" &>/dev/null; then + echo -e " ${GREEN}✓${RESET} $dep" + ((PASS++)) + else + echo -e " ${RED}✗${RESET} $dep ${RED}(not found)${RESET}" + MISSING+=("$dep") + ((FAIL++)) + fi +done + +echo -e " ──────────────────────────" +echo -e " ${GREEN}${PASS} found${RESET} | ${RED}${FAIL} missing${RESET}" +echo "" + +if [ ${#MISSING[@]} -gt 0 ]; then + echo -e "${BOLD} Missing:${RESET} ${MISSING[*]}" + echo "" + exit 1 +else + echo -e "${GREEN}${BOLD} All dependencies satisfied!${RESET}" + echo "" + exit 0 +fi \ No newline at end of file diff --git a/hypr/hyprland.conf b/hypr/hyprland.conf index 13b827a..2f74cc0 100644 --- a/hypr/hyprland.conf +++ b/hypr/hyprland.conf @@ -184,7 +184,7 @@ $mainMod = SUPER # Sets "Windows" key as main modifier bind = $mainMod, return, exec, $terminal bind = $mainMod, W, killactive, bind = $mainMod, M, exec, command -v hyprshutdown >/dev/null 2>&1 && hyprshutdown || hyprctl dispatch exit -bind = SUPER, R, exec, sh -c '~/.config/hypr/reload.sh' +bind = $mainMod, R, exec, sh -c '~/.config/hypr/reload.sh' bind = $mainMod, V, togglefloating, bind = $mainMod, space, exec, $menu bind = $mainMod, P, pseudo, # dwindle @@ -227,6 +227,18 @@ bind = SUPER SHIFT, left, movetoworkspacesilent, e-1 bind = SUPER ALT, right, movefocus, r bind = SUPER ALT, left, movefocus, l +# Navigate workspaces (2D) +#bind = SUPER, right, exec, ~/.config/hypr/2d-nav.sh right && pkill -SIGRTMIN+8 waybar +#bind = SUPER, left, exec, ~/.config/hypr/2d-nav.sh left && pkill -SIGRTMIN+8 waybar +#bind = SUPER, up, exec, ~/.config/hypr/2d-nav.sh up && pkill -SIGRTMIN+8 waybar +#bind = SUPER, down, exec, ~/.config/hypr/2d-nav.sh down && pkill -SIGRTMIN+8 waybar + +# Move window to workspace (2D) +#bind = SUPER SHIFT, right, exec, ~/.config/hypr/2d-nav.sh move-right && pkill -SIGRTMIN+8 waybar +#bind = SUPER SHIFT, left, exec, ~/.config/hypr/2d-nav.sh move-left && pkill -SIGRTMIN+8 waybar +#bind = SUPER SHIFT, up, exec, ~/.config/hypr/2d-nav.sh move-up && pkill -SIGRTMIN+8 waybar +#bind = SUPER SHIFT, down, exec, ~/.config/hypr/2d-nav.sh move-down && pkill -SIGRTMIN+8 waybar + # Example special workspace (scratchpad) @@ -300,10 +312,57 @@ windowrule { move = 20 monitor_h-120 float = yes + } # env stuff -exec-once = waybar +exec-once = waybar --style ~/.config/waybar/style.css exec-once = hyprpaper -exec-once = ~/.config/hypr/autostart.sh -exec-once = ~/.config/hypr/wallpaper-cycle.sh \ No newline at end of file +exec-once = ~/.config/hypr/theme-cycle.sh + +exec-once = [workspace 1 silent] firefox +exec-once = [workspace 10 silent] firefox --new-instance + + +windowrule { + name = firefox-to-ws2 + match:class = ^(firefox)$ + workspace = 1 silent +} + +windowrule { + name = code-to-ws2 + match:class = ^(code)$ + workspace = 2 silent +} + +windowrule { + name = vesktop-to-ws6 + match:class = ^(vesktop)$ + workspace = 4 silent +} + +windowrule { + name = vesktop-to-ws6 + match:class = ^(vesktop)$ + workspace = 4 silent +} + + +windowrule { + name = steam-to-ws7 + match:class = ^(steam)$ + workspace = 6 silent +} + +windowrule { + name = firefox-to-ws10 + match:class = ^(firefox)$ + workspace = 10 silent +} + +windowrule { + name = eww-volume-float + match:class = ^(eww)$ + float = yes +} \ No newline at end of file diff --git a/hypr/hyprpaper.conf b/hypr/hyprpaper.conf index 5d51857..45d5b5c 100644 --- a/hypr/hyprpaper.conf +++ b/hypr/hyprpaper.conf @@ -2,4 +2,5 @@ ipc = true splash = false preload = ~/.config/hypr/paper/day.jpg -preload = ~/.config/hypr/paper/night.jpg \ No newline at end of file +preload = ~/.config/hypr/paper/night.jpg +# check the ~/.config/hypr/theme-cycle.sh to change wallpaper \ No newline at end of file diff --git a/hypr/reload.sh b/hypr/reload.sh index c28bd05..ee76d4d 100755 --- a/hypr/reload.sh +++ b/hypr/reload.sh @@ -1,11 +1,19 @@ #!/usr/bin/env bash -killall -SIGUSR2 waybar 2>/dev/null +# Reload Waybar if running, otherwise start it +if pgrep -x waybar >/dev/null; then + killall -SIGUSR2 waybar +else + setsid waybar &>/dev/null & +fi +# Restart hyprpaper pkill hyprpaper 2>/dev/null setsid hyprpaper &>/dev/null & -pkill -f wallpaper-cycle.sh 2>/dev/null -setsid ~/.config/hypr/wallpaper-cycle.sh &>/dev/null & +# Restart wallpaper cycle script +pkill -f theme-cycle.sh 2>/dev/null +setsid ~/.config/hypr/theme-cycle.sh &>/dev/null & +# Reload Hyprland config hyprctl reload \ No newline at end of file diff --git a/hypr/theme-cycle.sh b/hypr/theme-cycle.sh new file mode 100755 index 0000000..bd413f7 --- /dev/null +++ b/hypr/theme-cycle.sh @@ -0,0 +1,117 @@ +#!/usr/bin/env bash + +DAY_HOUR=7 +NIGHT_HOUR=20 +DAY_WALL="$HOME/.config/hypr/paper/day.jpg" +NIGHT_WALL="$HOME/.config/hypr/paper/night.jpg" +STATE_FILE="/tmp/wallpaper-mode" # tracks: day / night / auto + +MONITORS=( $(hyprctl monitors -j | jq -r '.[].name') ) + +apply_day() { + for mon in "${MONITORS[@]}"; do + hyprctl hyprpaper wallpaper "$mon,$DAY_WALL" &>/dev/null + done +} + +apply_night() { + for mon in "${MONITORS[@]}"; do + hyprctl hyprpaper wallpaper "$mon,$NIGHT_WALL" &>/dev/null + done +} + +wait_for_hyprpaper() { + local retries=20 + local sock="$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.hyprpaper.sock" + [[ -S "$sock" ]] || sock="/tmp/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.hyprpaper.sock" + while ((retries-- > 0)); do + [[ -S "$sock" ]] && return 0 + sleep 0.3 + done + return 1 +} + +get_state() { + cat "$STATE_FILE" 2>/dev/null || echo "auto" +} + +set_state() { + echo "$1" > "$STATE_FILE" +} + +# --- ARGUMENT HANDLING --- +case "$1" in + day) + set_state "day" + wait_for_hyprpaper || { echo "hyprpaper not ready"; exit 1; } + apply_day + exit 0 + ;; + night) + set_state "night" + wait_for_hyprpaper || { echo "hyprpaper not ready"; exit 1; } + apply_night + exit 0 + ;; + auto) + set_state "auto" + exit 0 + ;; + # Waybar left-click: cycle day -> night -> auto -> day + next) + cur=$(get_state) + case "$cur" in + day) "$0" night; exit 0 ;; + night) "$0" auto; exit 0 ;; + auto) "$0" day; exit 0 ;; + esac + ;; + # Waybar polls this for the button label + status) + cur=$(get_state) + case "$cur" in + day) echo '{"text":"󰖙 day", "tooltip":"Wallpaper: day (click to → night)","class":"day"}' ;; + night) echo '{"text":"󰖔 night","tooltip":"Wallpaper: night (click to → auto)","class":"night"}' ;; + auto) echo '{"text":"󰃝 auto", "tooltip":"Wallpaper: auto (click to → day)","class":"auto"}' ;; + esac + exit 0 + ;; + "") + # No arg — fall through to cycle loop + ;; + *) + echo "Usage: $0 [day|night|auto|next|status]" + exit 1 + ;; +esac + +# --- CYCLE LOOP --- +current_mode="none" + +while true; do + hour=$(date +%H | sed 's/^0*//') + state=$(get_state) + + if [[ "$current_mode" == "none" ]]; then + if wait_for_hyprpaper; then + current_mode="waiting" + fi + sleep 1 + continue + fi + + # If pinned to day or night, just wait and recheck + if [[ "$state" == "day" && "$current_mode" != "day" ]]; then + apply_day; current_mode="day" + elif [[ "$state" == "night" && "$current_mode" != "night" ]]; then + apply_night; current_mode="night" + elif [[ "$state" == "auto" ]]; then + if (( hour >= DAY_HOUR && hour < NIGHT_HOUR )) && [[ "$current_mode" != "day" ]]; then + apply_day; current_mode="day" + elif (( hour < DAY_HOUR || hour >= NIGHT_HOUR )) && [[ "$current_mode" != "night" ]]; then + apply_night; current_mode="night" + fi + fi + + sleep $(( 60 - $(date +%S) )) +done \ No newline at end of file diff --git a/hypr/wallpaper-cycle.sh b/hypr/wallpaper-cycle.sh deleted file mode 100755 index 447fd9d..0000000 --- a/hypr/wallpaper-cycle.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env bash - -DAY_HOUR=7 -NIGHT_HOUR=20 - -DAY_WALL="$HOME/.config/hypr/paper/day.jpg" -NIGHT_WALL="$HOME/.config/hypr/paper/night.jpg" - -apply_day() { - hyprctl hyprpaper wallpaper "DP-2,$DAY_WALL" &>/dev/null - hyprctl hyprpaper wallpaper "HDMI-A-1,$DAY_WALL" &>/dev/null -} -apply_night() { - hyprctl hyprpaper wallpaper "DP-2,$NIGHT_WALL" &>/dev/null - hyprctl hyprpaper wallpaper "HDMI-A-1,$NIGHT_WALL" &>/dev/null -} - -apply_now() { - hour=$(date +%H) - if (( hour >= DAY_HOUR && hour < NIGHT_HOUR )); then - apply_night - echo "night" - else - apply_day - echo "day" - fi -} - -# --- FAST START --- -current_mode=$(apply_now) - -# If hyprpaper wasn't ready yet, retry once shortly after -sleep 0.5 -current_mode=$(apply_now) - -# --- MAIN LOOP --- -while true; do - hour=$(date +%H) - - if (( hour >= DAY_HOUR && hour < NIGHT_HOUR )); then - [[ "$current_mode" != "day" ]] && current_mode=$(apply_now) - else - [[ "$current_mode" != "night" ]] && current_mode=$(apply_now) - fi - - # sleep until next minute boundary (feels instant at change) - sleep $((60 - $(date +%S))) -done \ No newline at end of file diff --git a/kitty/kitty.conf b/kitty/kitty.conf index 71a019c..5115974 100644 --- a/kitty/kitty.conf +++ b/kitty/kitty.conf @@ -1,4 +1,6 @@ # BEGIN_KITTY_THEME # Dracula include current-theme.conf -# END_KITTY_THEME \ No newline at end of file +# END_KITTY_THEME + +background_opacity 0.75 diff --git a/nvim/init.lua b/nvim/init.lua index 5b63eaa..cb8ba1a 100644 --- a/nvim/init.lua +++ b/nvim/init.lua @@ -19,6 +19,11 @@ vim.opt.rtp:prepend(lazypath) -- ----------------------------------------------------------------------------- -- CORE OPTIONS -- ----------------------------------------------------------------------------- + +vim.api.nvim_set_hl(0, "Normal", { bg = "none" }) +vim.api.nvim_set_hl(0, "NormalFloat", { bg = "none" }) +vim.api.nvim_set_hl(0, "NormalNC", { bg = "none" }) + vim.g.mapleader = " " vim.g.maplocalleader = " " diff --git a/nvim/lazy-lock.json b/nvim/lazy-lock.json index b9520cd..d29ec84 100644 --- a/nvim/lazy-lock.json +++ b/nvim/lazy-lock.json @@ -32,6 +32,5 @@ "telescope-fzf-native.nvim": { "branch": "main", "commit": "6fea601bd2b694c6f2ae08a6c6fab14930c60e2c" }, "telescope.nvim": { "branch": "0.1.x", "commit": "a0bbec21143c7bc5f8bb02e0005fa0b982edc026" }, "toggleterm.nvim": { "branch": "main", "commit": "9a88eae817ef395952e08650b3283726786fb5fb" }, - "trouble.nvim": { "branch": "main", "commit": "bd67efe408d4816e25e8491cc5ad4088e708a69a" }, - "which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" } + "trouble.nvim": { "branch": "main", "commit": "bd67efe408d4816e25e8491cc5ad4088e708a69a" } } diff --git a/waybar/config.jsonc b/waybar/config.jsonc index 2ae0eea..27db693 100644 --- a/waybar/config.jsonc +++ b/waybar/config.jsonc @@ -10,7 +10,7 @@ "margin-right": 10, "modules-left": ["hyprland/workspaces", "hyprland/window"], "modules-center": ["clock"], - "modules-right": ["pulseaudio", "network", "cpu", "memory", "battery", "tray"], + "modules-right": ["custom/theme", "pulseaudio", "network", "cpu", "memory", "battery", "tray"], "hyprland/workspaces": { "format": "{icon}", "on-click": "activate", @@ -41,7 +41,7 @@ }, "network": { "format-wifi": "{signalStrength}%", - "format-ethernet": " {ipaddr}", + "format-ethernet": "{ipaddr}", "format-disconnected": "󰌙 Offline", "tooltip-format": "{essid} — {ipaddr}\n{bandwidthUpBits} up {bandwidthDownBits} down", "interval": 5 @@ -50,9 +50,30 @@ "format": "{icon} {volume}%", "format-muted": "󰝟 Muted", "format-icons": { "headphone": "󰋋", "default": ["󰕿", "󰖀", "󰕾"] }, - "on-click": "pavucontrol" + "on-click": "~/.config/eww/scripts/toggle-mixer.sh" }, - "tray": { "spacing": 8, "icon-size": 16 } + + "custom/theme": { + "exec": "$HOME/.config/hypr/theme-cycle.sh status", + "exec-on-event": true, + "return-type": "json", + "interval": 2, + "on-click": "$HOME/.config/hypr/theme-cycle.sh next", + "on-click-right": "$HOME/.config/hypr/theme-cycle.sh auto", + "on-scroll-up": "$HOME/.config/hypr/theme-cycle.sh day", + "on-scroll-down": "$HOME/.config/hypr/wallthemepaper-cycle.sh night" + }, + + + "tray": { "spacing": 8, "icon-size": 16 }, + + "custom/2d-workspaces": { + "exec": "~/.config/hypr/2d-workspaces.sh", + "return-type": "json", + "interval": "once", + "restart-interval": 1, + "signal": 8 + } }, { "layer": "top", @@ -65,7 +86,7 @@ "margin-right": 10, "modules-left": ["hyprland/workspaces", "hyprland/window"], "modules-center": ["clock"], - "modules-right": ["pulseaudio", "network", "cpu", "memory", "battery", "tray"], + "modules-right": ["custom/theme", "pulseaudio", "network", "cpu", "memory", "battery", "tray"], "hyprland/workspaces": { "format": "{icon}", "on-click": "activate", @@ -107,6 +128,30 @@ "format-icons": { "headphone": "󰋋", "default": ["󰕿", "󰖀", "󰕾"] }, "on-click": "pavucontrol" }, - "tray": { "spacing": 8, "icon-size": 16 } + + + "custom/theme": { + "exec": "$HOME/.config/hypr/theme-cycle.sh status", + "exec-on-event": true, + "return-type": "json", + "interval": 2, + "on-click": "$HOME/.config/hypr/theme-cycle.sh next", + "on-click-right": "$HOME/.config/hypr/theme-cycle.sh auto", + "on-scroll-up": "$HOME/.config/hypr/theme-cycle.sh day", + "on-scroll-down": "$HOME/.config/hypr/wallthemepaper-cycle.sh night" + }, + + + "tray": { "spacing": 8, "icon-size": 16 }, + + "custom/2d-workspaces": { + "exec": "~/.config/hypr/2d-workspaces.sh", + "return-type": "json", + "interval": "once", + "restart-interval": 1, + "signal": 8 + } } -] \ No newline at end of file + +] + diff --git a/waybar/night.css b/waybar/night.css new file mode 100644 index 0000000..14e0a5c --- /dev/null +++ b/waybar/night.css @@ -0,0 +1,130 @@ +* { + font-family: "JetBrainsMono Nerd Font", "Noto Sans", monospace; + font-size: 13px; + border: none; + border-radius: 0; + min-height: 0; +} + +window#waybar { + background: rgba(255, 255, 255, 0); + color: #f0f4f8; + border-radius: 10px; +} + +/* ── Workspaces ─────────────────────────────────────── */ +#workspaces { + background: rgba(0, 0, 0, 0.3); + border-radius: 8px; + padding: 2px 2px; +} + +#workspaces button { + padding: 2px 8px; + color: #ffffff; + background: transparent; + border-radius: 6px; + font-size: 15px; + transition: all 0.2s ease; +} + +#workspaces button:hover { + background: rgba(168, 206, 240, 0.18); + color: #f0f4f8; +} + +#workspaces button.active { + background: rgb(167, 124, 215); + color: #000000; + box-shadow: 0 0 6px rgba(62, 15, 65, 0.4); +} + +#workspaces button.urgent { + color: #c0392b; + background: rgba(192, 57, 43, 0.18); +} + +#workspaces button.empty { + color: #5b7a99; +} + +/* ── Window title ───────────────────────────────────── */ +#window { + background: rgba(0, 0, 0, 0.3); + color: #ffffff; + padding: 0 10px; + font-style: italic; + border-radius: 8px; +} + +/* ── Clock ──────────────────────────────────────────── */ +#clock { + color: #ffffff; + padding: 1px 14px; + font-weight: bold; + border-radius: 8px; + background: rgba(0, 0, 0, 0.3); +} + +#custom-wallpaper-mode{ + color: #ffffff; + padding: 1px 14px; + font-weight: bold; + border-radius: 8px; + background: rgba(0, 0, 0, 0.3); +} + +/* ── Right modules shared style ─────────────────────── */ +#cpu, +#memory, +#network, +#pulseaudio { + padding: 2px 10px; + border-radius: 8px; + background: rgba(0, 0, 0, 0.3); + color: #ffffff; +} + +/* ── CPU ────────────────────────────────────────────── */ +#cpu { color: #9ed649; } /* bright grass green */ +#cpu.warning { color: #e5b25b; } /* warm amber */ +#cpu.critical { color: #e04534; } /* red */ + +/* ── Memory ─────────────────────────────────────────── */ +#memory { color: #7db9ec; } /* sky mid-blue */ + + +/* ── Tray ───────────────────────────────────────────── */ +#tray { + padding: 2px 8px; + border-radius: 8px; + background: rgba(0, 0, 0, 0.3); + color: #ffffff; +} + +#tray > .passive { -gtk-icon-effect: dim; } +#tray > .needs-attention { + -gtk-icon-effect: highlight; + background-color: rgba(192, 57, 43, 0.2); +} + +/* ── Custom 2D Workspaces ───────────────────────────── */ +#custom-2d-workspaces { + font-size: 13px; + font-weight: bold; + padding: 0 12px; + border-radius: 6px; + transition: all 0.15s ease; +} + +/* Base row — sky blue */ +#custom-2d-workspaces.base { + color: #a8cef0; + background: transparent; +} + +/* Sub-workspace — grass green tint */ +#custom-2d-workspaces.sub { + color: #7dbe1e; + background: rgba(255, 255, 255, 0.5); +} \ No newline at end of file diff --git a/waybar/style.css b/waybar/style.css index 718acfd..7909aaf 100644 --- a/waybar/style.css +++ b/waybar/style.css @@ -1,4 +1,20 @@ /* ── Global ─────────────────────────────────────────── */ +/* + Theme: Arch Bliss + Inspired by the rolling green hills and blue sky of the wallpaper. + Palette: + Sky deep: #2a6db5 (upper sky blue) + Sky mid: #5b9fd6 (horizon blue) + Sky light: #a8cef0 (pale sky) + Grass dark: #3a6b0e (shadow grass) + Grass mid: #5a9416 (mid grass) + Grass light: #7dbe1e (bright grass highlight) + Hill muted: #4a7a12 (rolling hills mid) + White: #f0f4f8 (Arch logo white) + Muted: #8bafc8 (distant hill / muted text) + Urgent: #c0392b (red for warnings) +*/ + * { font-family: "JetBrainsMono Nerd Font", "Noto Sans", monospace; font-size: 13px; @@ -8,22 +24,21 @@ } window#waybar { - background: rgba(17, 17, 27, 0); - color: #cdd6f4; - /*border-bottom: 2px solid rgba(137, 180, 250, 0.25);*/ + background: rgba(255, 255, 255, 0); + color: #f0f4f8; border-radius: 10px; } /* ── Workspaces ─────────────────────────────────────── */ #workspaces { - background: rgba(30, 30, 46, 0.85); + background: rgba(0, 0, 0, 0.35); border-radius: 8px; - padding: 2px 6px; + padding: 2px 2px; } #workspaces button { padding: 2px 8px; - color: #6c7086; + color: #ffffff; background: transparent; border-radius: 6px; font-size: 15px; @@ -31,88 +46,113 @@ window#waybar { } #workspaces button:hover { - background: rgba(137, 180, 250, 0.15); - color: #ffffff; + background: rgba(168, 206, 240, 0.18); + color: #f0f4f8; } #workspaces button.active { - background: rgb(167, 124, 215); - color: #ffffff; + background: rgba(90, 148, 22, 0.85); + color: #f0f4f8; + box-shadow: 0 0 6px rgba(125, 190, 30, 0.4); } #workspaces button.urgent { - color: #f38ba8; - background: rgba(243, 139, 168, 0.15); + color: #c0392b; + background: rgba(192, 57, 43, 0.18); } #workspaces button.empty { - color: #6c7086; + color: #5b7a99; } /* ── Window title ───────────────────────────────────── */ #window { - color: #a6adc8; + background: rgba(0, 0, 0, 0.35); + color: #ffffff; padding: 0 10px; font-style: italic; - border-bottom: 2px solid rgba(45, 57, 76, 0.819); + border-radius: 8px; } /* ── Clock ──────────────────────────────────────────── */ #clock { - color: #cba6f7; + color: #ffffff; padding: 1px 14px; font-weight: bold; border-radius: 8px; - background: rgba(30, 30, 46, 0.85); + background: rgba(0, 0, 0, 0.35); } +#custom-theme { + color: #ffffff; + padding: 1px 14px; + font-weight: bold; + border-radius: 8px; + background: rgba(0, 0, 0, 0.35); +} + +#custom-theme.day { + color: #f9e2af; +} + +#custom-theme.night { + color: #89b4fa; +} + +#custom-theme.auto { + color: #a6e3a1; +} /* ── Right modules shared style ─────────────────────── */ #cpu, #memory, -#battery, #network, #pulseaudio { padding: 2px 10px; border-radius: 8px; - background: rgba(30, 30, 46, 0.85); + background: rgba(0, 0, 0, 0.35); + color: #ffffff; } /* ── CPU ────────────────────────────────────────────── */ -#cpu { color: #a6e3a1; } -#cpu.warning { color: #fab387; } -#cpu.critical { color: #f38ba8; } +#cpu { color: #bfff5e; } /* bright grass green */ +#cpu.warning { color: #ffe943; } /* warm amber */ +#cpu.critical { color: #ff6250; } /* red */ /* ── Memory ─────────────────────────────────────────── */ -#memory { color: #89dceb; } +#memory { color: #7dc2ff; } /* sky mid-blue */ -/* ── Battery ────────────────────────────────────────── */ -#battery { color: #a6e3a1; } -#battery.warning { color: #fab387; } -#battery.critical { color: #f38ba8; animation: blink 1s linear infinite; } -#battery.charging { color: #a6e3a1; } - -@keyframes blink { - to { color: transparent; } -} - -/* ── Network ────────────────────────────────────────── */ -#network { color: #89b4fa; } -#network.disconnected { color: #6c7086; } - -/* ── Audio ──────────────────────────────────────────── */ -#pulseaudio { color: #f5c2e7; } -#pulseaudio.muted { color: #6c7086; } /* ── Tray ───────────────────────────────────────────── */ #tray { padding: 2px 8px; border-radius: 8px; - background: rgba(30, 30, 46, 0.85); + background: rgba(0, 0, 0, 0.35); + color: #ffffff; } #tray > .passive { -gtk-icon-effect: dim; } #tray > .needs-attention { -gtk-icon-effect: highlight; - background-color: rgba(243, 139, 168, 0.2); + background-color: rgba(192, 57, 43, 0.2); } +/* ── Custom 2D Workspaces ───────────────────────────── */ +#custom-2d-workspaces { + font-size: 13px; + font-weight: bold; + padding: 0 12px; + border-radius: 6px; + transition: all 0.15s ease; +} + +/* Base row — sky blue */ +#custom-2d-workspaces.base { + color: #a8cef0; + background: transparent; +} + +/* Sub-workspace — grass green tint */ +#custom-2d-workspaces.sub { + color: #7dbe1e; + background: rgba(255, 255, 255, 0.5); +} \ No newline at end of file diff --git a/waybar/style.css.old b/waybar/style.css.old new file mode 100644 index 0000000..9c4fabf --- /dev/null +++ b/waybar/style.css.old @@ -0,0 +1,141 @@ +/* ── Global ─────────────────────────────────────────── */ +* { + font-family: "JetBrainsMono Nerd Font", "Noto Sans", monospace; + font-size: 13px; + border: none; + border-radius: 0; + min-height: 0; +} + +window#waybar { + background: rgba(17, 17, 27, 0); + color: #cdd6f4; + /*border-bottom: 2px solid rgba(137, 180, 250, 0.25);*/ + border-radius: 10px; +} + +/* ── Workspaces ─────────────────────────────────────── */ +#workspaces { + background: rgba(30, 30, 46, 0.85); + border-radius: 8px; + padding: 2px 6px; +} + +#workspaces button { + padding: 2px 8px; + color: #6c7086; + background: transparent; + border-radius: 6px; + font-size: 15px; + transition: all 0.2s ease; +} + +#workspaces button:hover { + background: rgba(137, 180, 250, 0.15); + color: #ffffff; +} + +#workspaces button.active { + background: rgb(167, 124, 215); + color: #ffffff; +} + +#workspaces button.urgent { + color: #f38ba8; + background: rgba(243, 139, 168, 0.15); +} + +#workspaces button.empty { + color: #6c7086; +} + +/* ── Window title ───────────────────────────────────── */ +#window { + color: #ffffff; + padding: 0 10px; + font-style: italic; + border: 2px solid rgba(30, 30, 46, 0.85); + border-radius: 8px; +} + +/* ── Clock ──────────────────────────────────────────── */ +#clock { + color: #cba6f7; + padding: 1px 14px; + font-weight: bold; + border-radius: 8px; + background: rgba(30, 30, 46, 0.85); +} + +/* ── Right modules shared style ─────────────────────── */ +#cpu, +#memory, +#battery, +#network, +#pulseaudio { + padding: 2px 10px; + border-radius: 8px; + background: rgba(30, 30, 46, 0.85); +} + +/* ── CPU ────────────────────────────────────────────── */ +#cpu { color: #a6e3a1; } +#cpu.warning { color: #fab387; } +#cpu.critical { color: #f38ba8; } + +/* ── Memory ─────────────────────────────────────────── */ +#memory { color: #89dceb; } + +/* ── Battery ────────────────────────────────────────── */ +#battery { color: #a6e3a1; } +#battery.warning { color: #fab387; } +#battery.critical { color: #f38ba8; animation: blink 1s linear infinite; } +#battery.charging { color: #a6e3a1; } + +@keyframes blink { + to { color: transparent; } +} + +/* ── Network ────────────────────────────────────────── */ +#network { color: #89b4fa; } +#network.disconnected { color: #6c7086; } + +/* ── Audio ──────────────────────────────────────────── */ +#pulseaudio { color: #f5c2e7; } +#pulseaudio.muted { color: #6c7086; } + +/* ── Tray ───────────────────────────────────────────── */ +#tray { + padding: 2px 8px; + border-radius: 8px; + background: rgba(30, 30, 46, 0.85); +} + +#tray > .passive { -gtk-icon-effect: dim; } +#tray > .needs-attention { + -gtk-icon-effect: highlight; + background-color: rgba(243, 139, 168, 0.2); +} + + +/* --- waybar style.css --- */ + +#custom-2d-workspaces { + font-size: 13px; + font-weight: bold; + padding: 0 12px; + border-radius: 6px; + transition: all 0.15s ease; +} + +/* Base row — normal blue */ +#custom-2d-workspaces.base { + color: #89b4fa; + background: transparent; +} + +/* Sub-workspace — green tint so you know you're "deeper" */ +#custom-2d-workspaces.sub { + color: #a6e3a1; + background: rgba(166, 227, 161, 0.12); +} \ No newline at end of file