Initial ThinkPad Hyprland dotfiles
This commit is contained in:
7
config/gtk-3.0/bookmarks
Normal file
7
config/gtk-3.0/bookmarks
Normal file
@@ -0,0 +1,7 @@
|
||||
file:///home/pascal/Schreibtisch Schreibtisch
|
||||
file:///home/pascal/Dokumente Dokumente
|
||||
file:///home/pascal/Downloads Downloads
|
||||
file:///home/pascal/Videos Videos
|
||||
file:///home/pascal/Musik Musik
|
||||
file:///home/pascal/Bilder Bilder
|
||||
file:///home/pascal/Projekte Projekte
|
||||
18
config/gtk-3.0/gtk.css
Normal file
18
config/gtk-3.0/gtk.css
Normal file
@@ -0,0 +1,18 @@
|
||||
@define-color accent_color #00ff9c;
|
||||
@define-color accent_bg_color #00ff9c;
|
||||
@define-color accent_fg_color #000000;
|
||||
@define-color window_bg_color #14141e;
|
||||
@define-color window_fg_color #cdd6f4;
|
||||
@define-color view_bg_color #14141e;
|
||||
@define-color view_fg_color #cdd6f4;
|
||||
@define-color card_bg_color #282837;
|
||||
@define-color card_fg_color #cdd6f4;
|
||||
@define-color popover_bg_color #282837;
|
||||
@define-color popover_fg_color #cdd6f4;
|
||||
@define-color headerbar_bg_color #282837;
|
||||
@define-color headerbar_fg_color #cdd6f4;
|
||||
@define-color sidebar_bg_color #14141e;
|
||||
@define-color sidebar_fg_color #cdd6f4;
|
||||
@define-color destructive_color #f38ba8;
|
||||
@define-color warning_color #f9e2af;
|
||||
@define-color success_color #a6e3a1;
|
||||
4
config/gtk-3.0/settings.ini
Normal file
4
config/gtk-3.0/settings.ini
Normal file
@@ -0,0 +1,4 @@
|
||||
[Settings]
|
||||
gtk-theme-name=Adwaita
|
||||
gtk-icon-theme-name=Papirus-ForestNeon
|
||||
gtk-application-prefer-dark-theme=1
|
||||
18
config/gtk-4.0/gtk.css
Normal file
18
config/gtk-4.0/gtk.css
Normal file
@@ -0,0 +1,18 @@
|
||||
@define-color accent_color #00ff9c;
|
||||
@define-color accent_bg_color #00ff9c;
|
||||
@define-color accent_fg_color #000000;
|
||||
@define-color window_bg_color #14141e;
|
||||
@define-color window_fg_color #cdd6f4;
|
||||
@define-color view_bg_color #14141e;
|
||||
@define-color view_fg_color #cdd6f4;
|
||||
@define-color card_bg_color #282837;
|
||||
@define-color card_fg_color #cdd6f4;
|
||||
@define-color popover_bg_color #282837;
|
||||
@define-color popover_fg_color #cdd6f4;
|
||||
@define-color headerbar_bg_color #282837;
|
||||
@define-color headerbar_fg_color #cdd6f4;
|
||||
@define-color sidebar_bg_color #14141e;
|
||||
@define-color sidebar_fg_color #cdd6f4;
|
||||
@define-color destructive_color #f38ba8;
|
||||
@define-color warning_color #f9e2af;
|
||||
@define-color success_color #a6e3a1;
|
||||
4
config/gtk-4.0/settings.ini
Normal file
4
config/gtk-4.0/settings.ini
Normal file
@@ -0,0 +1,4 @@
|
||||
[Settings]
|
||||
gtk-theme-name=Adwaita
|
||||
gtk-icon-theme-name=Papirus-ForestNeon
|
||||
gtk-application-prefer-dark-theme=1
|
||||
22
config/hypr/Scripts/ags-switcher.sh
Executable file
22
config/hypr/Scripts/ags-switcher.sh
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
HYPR_DIR="$(cd -- "$SCRIPT_DIR/.." && pwd)"
|
||||
MODE="${1:-wallpaper}"
|
||||
export HYPR_DIR
|
||||
export HYPR_SWITCHER_THEME_DIR="$HYPR_DIR/Themes"
|
||||
export HYPR_SWITCHER_WALLPAPER_DIR="${WALLPAPER_DIR:-$HOME/Bilder/Wallpaper}"
|
||||
|
||||
notify() {
|
||||
notify-send "AGS Switcher" "$1" >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
if ! command -v ags >/dev/null 2>&1; then
|
||||
notify "ags ist nicht installiert."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "$HYPR_DIR"
|
||||
ags quit --instance hypr-switcher >/dev/null 2>&1 || true
|
||||
exec ags run "$HYPR_DIR/ags/switcher.tsx" "$MODE"
|
||||
20
config/hypr/Scripts/appearance-menu.sh
Executable file
20
config/hypr/Scripts/appearance-menu.sh
Executable file
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
choice="$(
|
||||
printf '%s\n' \
|
||||
" Theme wechseln" \
|
||||
" Wallpaper wechseln" |
|
||||
wofi --dmenu --prompt " Aussehen" --insensitive
|
||||
)"
|
||||
|
||||
case "$choice" in
|
||||
*"Theme wechseln"*)
|
||||
"$SCRIPT_DIR/ags-switcher.sh" theme
|
||||
;;
|
||||
*"Wallpaper wechseln"*)
|
||||
"$SCRIPT_DIR/ags-switcher.sh" wallpaper
|
||||
;;
|
||||
esac
|
||||
74
config/hypr/Scripts/audio-menu.sh
Executable file
74
config/hypr/Scripts/audio-menu.sh
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
notify() {
|
||||
notify-send " Audio" "$1"
|
||||
}
|
||||
|
||||
require_wpctl() {
|
||||
if ! command -v wpctl >/dev/null 2>&1; then
|
||||
notify "wpctl ist nicht installiert."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
choose_sink() {
|
||||
wpctl status |
|
||||
awk '
|
||||
/Sinks:/ {in_sinks=1; next}
|
||||
/Sources:/ {in_sinks=0}
|
||||
in_sinks && /\*/ {gsub(/^[[:space:]]*[│├└─* ]*/, ""); print " " $0}
|
||||
in_sinks && /^[[:space:]]*[│├└─ ]*[0-9]+\./ {gsub(/^[[:space:]]*[│├└─ ]*/, ""); print " " $0}
|
||||
' |
|
||||
wofi --dmenu --prompt " Audioausgabe" --insensitive
|
||||
}
|
||||
|
||||
require_wpctl
|
||||
|
||||
choice="$(
|
||||
printf '%s\n' \
|
||||
" Lauter" \
|
||||
" Leiser" \
|
||||
" Stumm schalten" \
|
||||
" Ausgabe wechseln" \
|
||||
" Mikrofon stumm" \
|
||||
" Play/Pause" \
|
||||
" Naechster Titel" \
|
||||
" Vorheriger Titel" \
|
||||
" Status" |
|
||||
wofi --dmenu --prompt " Audio" --insensitive
|
||||
)"
|
||||
|
||||
case "$choice" in
|
||||
*"Lauter"*)
|
||||
wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+
|
||||
;;
|
||||
*"Leiser"*)
|
||||
wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-
|
||||
;;
|
||||
*"Stumm schalten"*)
|
||||
wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
|
||||
;;
|
||||
*"Ausgabe wechseln"*)
|
||||
selection="$(choose_sink)"
|
||||
[ -n "$selection" ] || exit 0
|
||||
sink_id="$(printf '%s\n' "$selection" | sed -n 's/.* \([0-9][0-9]*\)\..*/\1/p')"
|
||||
[ -n "$sink_id" ] || exit 0
|
||||
wpctl set-default "$sink_id" && notify "Audioausgabe gewechselt."
|
||||
;;
|
||||
*"Mikrofon stumm"*)
|
||||
wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle
|
||||
;;
|
||||
*"Play/Pause"*)
|
||||
playerctl play-pause
|
||||
;;
|
||||
*"Naechster Titel"*)
|
||||
playerctl next
|
||||
;;
|
||||
*"Vorheriger Titel"*)
|
||||
playerctl previous
|
||||
;;
|
||||
*"Status"*)
|
||||
wpctl status | wofi --dmenu --prompt " Audiostatus"
|
||||
;;
|
||||
esac
|
||||
133
config/hypr/Scripts/bluetooth-menu.sh
Executable file
133
config/hypr/Scripts/bluetooth-menu.sh
Executable file
@@ -0,0 +1,133 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
notify() {
|
||||
notify-send " Bluetooth" "$1"
|
||||
}
|
||||
|
||||
require_bluetoothctl() {
|
||||
if ! command -v bluetoothctl >/dev/null 2>&1; then
|
||||
notify "bluetoothctl ist nicht installiert."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
wofi_pick() {
|
||||
wofi --dmenu --prompt "$1" --insensitive
|
||||
}
|
||||
|
||||
adapter_powered() {
|
||||
{ bluetoothctl show 2>/dev/null || true; } | awk -F': ' '/Powered/ {print $2; exit}'
|
||||
}
|
||||
|
||||
device_name() {
|
||||
local mac="$1"
|
||||
bluetoothctl info "$mac" 2>/dev/null | awk -F': ' '/Name/ {print $2; exit}'
|
||||
}
|
||||
|
||||
pick_device() {
|
||||
local prompt="$1"
|
||||
bluetoothctl devices |
|
||||
awk '{mac=$2; $1=""; $2=""; sub(/^ */, ""); printf " %s [%s]\n", $0, mac}' |
|
||||
wofi_pick "$prompt"
|
||||
}
|
||||
|
||||
selected_mac() {
|
||||
sed -n 's/.*\[\([0-9A-Fa-f:]\{17\}\)\].*/\1/p'
|
||||
}
|
||||
|
||||
scan_devices() {
|
||||
notify "Scan laeuft fuer 8 Sekunden."
|
||||
timeout 8 bluetoothctl scan on >/dev/null 2>&1 || true
|
||||
bluetoothctl scan off >/dev/null 2>&1 || true
|
||||
|
||||
local selection mac name
|
||||
selection="$(pick_device " Geraet verbinden")"
|
||||
[ -n "$selection" ] || exit 0
|
||||
mac="$(printf '%s\n' "$selection" | selected_mac)"
|
||||
name="$(device_name "$mac")"
|
||||
[ -n "$name" ] || name="$mac"
|
||||
|
||||
bluetoothctl pair "$mac" >/dev/null 2>&1 || true
|
||||
bluetoothctl trust "$mac" >/dev/null 2>&1 || true
|
||||
bluetoothctl connect "$mac" && notify "Verbunden mit $name."
|
||||
}
|
||||
|
||||
connect_saved_device() {
|
||||
local selection mac name
|
||||
selection="$(pick_device " Gekoppeltes Geraet verbinden")"
|
||||
[ -n "$selection" ] || exit 0
|
||||
mac="$(printf '%s\n' "$selection" | selected_mac)"
|
||||
name="$(device_name "$mac")"
|
||||
[ -n "$name" ] || name="$mac"
|
||||
bluetoothctl connect "$mac" && notify "Verbunden mit $name."
|
||||
}
|
||||
|
||||
disconnect_device() {
|
||||
local selection mac name
|
||||
selection="$(
|
||||
bluetoothctl devices Connected |
|
||||
awk '{mac=$2; $1=""; $2=""; sub(/^ */, ""); printf " %s [%s]\n", $0, mac}' |
|
||||
wofi_pick " Bluetooth trennen"
|
||||
)"
|
||||
|
||||
[ -n "$selection" ] || exit 0
|
||||
mac="$(printf '%s\n' "$selection" | selected_mac)"
|
||||
name="$(device_name "$mac")"
|
||||
[ -n "$name" ] || name="$mac"
|
||||
bluetoothctl disconnect "$mac" && notify "$name getrennt."
|
||||
}
|
||||
|
||||
remove_device() {
|
||||
local selection mac name
|
||||
selection="$(pick_device " Geraet entfernen")"
|
||||
[ -n "$selection" ] || exit 0
|
||||
mac="$(printf '%s\n' "$selection" | selected_mac)"
|
||||
name="$(device_name "$mac")"
|
||||
[ -n "$name" ] || name="$mac"
|
||||
bluetoothctl remove "$mac" && notify "$name entfernt."
|
||||
}
|
||||
|
||||
require_bluetoothctl
|
||||
|
||||
power="$(adapter_powered)"
|
||||
[ -n "$power" ] || power="unknown"
|
||||
|
||||
choice="$(
|
||||
printf '%s\n' \
|
||||
" Geraet suchen und verbinden" \
|
||||
" Bluetooth ein/aus" \
|
||||
" Gekoppelte Geraete" \
|
||||
" Verbundenes Geraet trennen" \
|
||||
" Geraet entfernen" \
|
||||
" Status: $power" |
|
||||
wofi_pick " Bluetooth"
|
||||
)"
|
||||
|
||||
case "$choice" in
|
||||
*"Geraet suchen"*)
|
||||
bluetoothctl power on >/dev/null
|
||||
bluetoothctl agent on >/dev/null 2>&1 || true
|
||||
bluetoothctl default-agent >/dev/null 2>&1 || true
|
||||
scan_devices
|
||||
;;
|
||||
*"Bluetooth ein/aus"*)
|
||||
if [ "$power" = "yes" ]; then
|
||||
bluetoothctl power off && notify "Bluetooth ausgeschaltet."
|
||||
else
|
||||
bluetoothctl power on && notify "Bluetooth eingeschaltet."
|
||||
fi
|
||||
;;
|
||||
*"Gekoppelte Geraete"*)
|
||||
connect_saved_device
|
||||
;;
|
||||
*"Verbundenes Geraet trennen"*)
|
||||
disconnect_device
|
||||
;;
|
||||
*"Geraet entfernen"*)
|
||||
remove_device
|
||||
;;
|
||||
*"Status:"*)
|
||||
bluetoothctl show | wofi --dmenu --prompt " Bluetoothstatus"
|
||||
;;
|
||||
esac
|
||||
369
config/hypr/Scripts/dev-menu.sh
Executable file
369
config/hypr/Scripts/dev-menu.sh
Executable file
@@ -0,0 +1,369 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
PROJECT_ROOTS=(
|
||||
"$HOME/Projekte"
|
||||
"$HOME/Projects"
|
||||
"$HOME/Code"
|
||||
"$HOME/Developer"
|
||||
"$HOME/dev"
|
||||
"$HOME/test"
|
||||
)
|
||||
|
||||
notify() {
|
||||
notify-send " Dev Menue" "$1" >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
pick() {
|
||||
wofi --dmenu --prompt "$1" --insensitive
|
||||
}
|
||||
|
||||
terminal_hold() {
|
||||
local title="$1"
|
||||
shift
|
||||
|
||||
if command -v kitty >/dev/null 2>&1; then
|
||||
kitty --title "$title" sh -lc "$*; printf '\n'; read -r -p 'Enter zum Schliessen... ' _"
|
||||
else
|
||||
notify "kitty ist nicht installiert."
|
||||
fi
|
||||
}
|
||||
|
||||
shell_quote() {
|
||||
printf '%q' "$1"
|
||||
}
|
||||
|
||||
code_cmd() {
|
||||
if command -v code >/dev/null 2>&1; then
|
||||
printf '%s\n' code
|
||||
elif command -v codium >/dev/null 2>&1; then
|
||||
printf '%s\n' codium
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
docker_available() {
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
notify "Docker ist nicht installiert."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! docker info >/dev/null 2>&1; then
|
||||
notify "Docker laeuft nicht oder ist nicht erreichbar."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
has_compose() {
|
||||
local project="$1"
|
||||
|
||||
[[ -f "$project/compose.yml" ||
|
||||
-f "$project/compose.yaml" ||
|
||||
-f "$project/docker-compose.yml" ||
|
||||
-f "$project/docker-compose.yaml" ]]
|
||||
}
|
||||
|
||||
project_label() {
|
||||
local project="$1"
|
||||
local marker=""
|
||||
|
||||
if [[ -d "$project/.git" ]]; then
|
||||
marker+=" "
|
||||
fi
|
||||
|
||||
if has_compose "$project"; then
|
||||
marker+=" "
|
||||
fi
|
||||
|
||||
printf '%s%s' "$marker" "${project#$HOME/}"
|
||||
}
|
||||
|
||||
pick_project() {
|
||||
local roots=()
|
||||
local projects=()
|
||||
local labels=()
|
||||
local root project choice
|
||||
|
||||
for root in "${PROJECT_ROOTS[@]}"; do
|
||||
[[ -d "$root" ]] && roots+=("$root")
|
||||
done
|
||||
|
||||
if ((${#roots[@]} == 0)); then
|
||||
notify "Keine Projektordner gefunden."
|
||||
return 1
|
||||
fi
|
||||
|
||||
mapfile -t projects < <(
|
||||
{
|
||||
find "${roots[@]}" -maxdepth 4 -type d -name .git -printf '%h\n' 2>/dev/null
|
||||
find "${roots[@]}" -maxdepth 3 -type d \( -name node_modules -o -name vendor \) -prune -o \
|
||||
-type f \( -name compose.yml -o -name compose.yaml -o -name docker-compose.yml -o -name docker-compose.yaml -o -name package.json -o -name Cargo.toml -o -name pyproject.toml -o -name go.mod \) \
|
||||
-printf '%h\n' 2>/dev/null
|
||||
} |
|
||||
sort -u
|
||||
)
|
||||
|
||||
if ((${#projects[@]} == 0)); then
|
||||
notify "Keine Projekte gefunden."
|
||||
return 1
|
||||
fi
|
||||
|
||||
for project in "${projects[@]}"; do
|
||||
labels+=("$(project_label "$project")")
|
||||
done
|
||||
|
||||
choice="$(printf '%s\n' "${labels[@]}" | pick "📁 Projekt")"
|
||||
[[ -z "${choice:-}" ]] && return 1
|
||||
|
||||
for i in "${!labels[@]}"; do
|
||||
if [[ "$choice" == "${labels[$i]}" ]]; then
|
||||
printf '%s\n' "${projects[$i]}"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
open_project_browser() {
|
||||
local project="$1"
|
||||
local choice url
|
||||
|
||||
choice="$(
|
||||
printf '%s\n' \
|
||||
"🌐 http://localhost:3000" \
|
||||
"🌐 http://localhost:5173" \
|
||||
"🌐 http://localhost:8000" \
|
||||
"🌐 http://localhost:8080" \
|
||||
"🌐 http://localhost:5000" \
|
||||
"🌐 http://localhost:4200" \
|
||||
"📂 Projektordner im Browser" |
|
||||
pick "🌐 Projekt im Browser"
|
||||
)"
|
||||
|
||||
case "$choice" in
|
||||
*"Projektordner"*)
|
||||
xdg-open "$project" >/dev/null 2>&1 &
|
||||
;;
|
||||
*"http"*)
|
||||
url="${choice#* }"
|
||||
xdg-open "$url" >/dev/null 2>&1 &
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
project_menu() {
|
||||
local project project_q choice editor
|
||||
|
||||
project="$(pick_project)" || return 0
|
||||
project_q="$(shell_quote "$project")"
|
||||
|
||||
choice="$(
|
||||
printf '%s\n' \
|
||||
"📂 Projekt oeffnen (Code)" \
|
||||
"🌐 Projekt im Browser oeffnen" \
|
||||
"🐳 Docker Compose starten" \
|
||||
"🛑 Docker stoppen" \
|
||||
"🔄 Container neu starten" \
|
||||
"📜 Logs anzeigen" \
|
||||
"📦 Git Repo Status anzeigen" |
|
||||
pick "📁 $(basename "$project")"
|
||||
)"
|
||||
|
||||
case "$choice" in
|
||||
*"Projekt oeffnen"*)
|
||||
if editor="$(code_cmd)"; then
|
||||
"$editor" "$project" >/dev/null 2>&1 &
|
||||
else
|
||||
notify "VS Code/Codium ist nicht installiert."
|
||||
fi
|
||||
;;
|
||||
*"Browser"*)
|
||||
open_project_browser "$project"
|
||||
;;
|
||||
*"Docker Compose starten"*)
|
||||
docker_available || return 0
|
||||
if has_compose "$project"; then
|
||||
terminal_hold "Docker Compose: $(basename "$project")" "cd $project_q && docker compose up -d && docker compose ps"
|
||||
else
|
||||
notify "Kein Docker-Compose File im Projekt."
|
||||
fi
|
||||
;;
|
||||
*"Docker stoppen"*)
|
||||
docker_available || return 0
|
||||
if has_compose "$project"; then
|
||||
terminal_hold "Docker Stop: $(basename "$project")" "cd $project_q && docker compose stop && docker compose ps"
|
||||
else
|
||||
notify "Kein Docker-Compose File im Projekt."
|
||||
fi
|
||||
;;
|
||||
*"Container neu starten"*)
|
||||
docker_available || return 0
|
||||
if has_compose "$project"; then
|
||||
terminal_hold "Docker Restart: $(basename "$project")" "cd $project_q && docker compose restart && docker compose ps"
|
||||
else
|
||||
notify "Kein Docker-Compose File im Projekt."
|
||||
fi
|
||||
;;
|
||||
*"Logs anzeigen"*)
|
||||
docker_available || return 0
|
||||
if has_compose "$project"; then
|
||||
if command -v kitty >/dev/null 2>&1; then
|
||||
kitty --title "Logs: $(basename "$project")" sh -lc "cd $project_q && docker compose logs -f --tail=200"
|
||||
else
|
||||
notify "kitty ist nicht installiert."
|
||||
fi
|
||||
else
|
||||
notify "Kein Docker-Compose File im Projekt."
|
||||
fi
|
||||
;;
|
||||
*"Git Repo Status"*)
|
||||
if [[ -d "$project/.git" ]]; then
|
||||
terminal_hold "Git Status: $(basename "$project")" "cd $project_q && git status --short --branch"
|
||||
else
|
||||
notify "Kein Git Repository."
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
pick_container() {
|
||||
local containers=()
|
||||
local labels=()
|
||||
local line name status choice
|
||||
|
||||
docker_available || return 1
|
||||
|
||||
mapfile -t containers < <(docker ps -a --format '{{.Names}}|{{.Status}}' | sort)
|
||||
if ((${#containers[@]} == 0)); then
|
||||
notify "Keine Docker Container gefunden."
|
||||
return 1
|
||||
fi
|
||||
|
||||
for line in "${containers[@]}"; do
|
||||
name="${line%%|*}"
|
||||
status="${line#*|}"
|
||||
labels+=("🐳 $name · $status")
|
||||
done
|
||||
|
||||
choice="$(printf '%s\n' "${labels[@]}" | pick "🐳 Container")"
|
||||
[[ -z "${choice:-}" ]] && return 1
|
||||
|
||||
for i in "${!labels[@]}"; do
|
||||
if [[ "$choice" == "${labels[$i]}" ]]; then
|
||||
printf '%s\n' "${containers[$i]%%|*}"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
docker_menu() {
|
||||
local choice container running_ids all_ids
|
||||
|
||||
choice="$(
|
||||
printf '%s\n' \
|
||||
"▶️ Alle Container starten" \
|
||||
"⏹️ Alle stoppen" \
|
||||
"🔄 Einzelnen Container neu starten" \
|
||||
"📊 docker stats" \
|
||||
"📜 Logs anzeigen" \
|
||||
"🧹 Cleanup dangling images" |
|
||||
pick "🐳 Docker Control"
|
||||
)"
|
||||
|
||||
case "$choice" in
|
||||
*"Alle Container starten"*)
|
||||
docker_available || return 0
|
||||
all_ids="$(docker ps -aq)"
|
||||
if [[ -n "$all_ids" ]]; then
|
||||
terminal_hold "Docker Start" "docker start $all_ids && docker ps"
|
||||
else
|
||||
notify "Keine Container gefunden."
|
||||
fi
|
||||
;;
|
||||
*"Alle stoppen"*)
|
||||
docker_available || return 0
|
||||
running_ids="$(docker ps -q)"
|
||||
if [[ -n "$running_ids" ]]; then
|
||||
terminal_hold "Docker Stop" "docker stop $running_ids && docker ps -a"
|
||||
else
|
||||
notify "Keine laufenden Container."
|
||||
fi
|
||||
;;
|
||||
*"Einzelnen Container neu starten"*)
|
||||
container="$(pick_container)" || return 0
|
||||
terminal_hold "Docker Restart: $container" "docker restart '$container' && docker ps -a --filter name='^/$container$'"
|
||||
;;
|
||||
*"docker stats"*)
|
||||
docker_available || return 0
|
||||
if command -v kitty >/dev/null 2>&1; then
|
||||
kitty --title "docker stats" sh -lc "docker stats"
|
||||
else
|
||||
notify "kitty ist nicht installiert."
|
||||
fi
|
||||
;;
|
||||
*"Logs anzeigen"*)
|
||||
container="$(pick_container)" || return 0
|
||||
if command -v kitty >/dev/null 2>&1; then
|
||||
kitty --title "Logs: $container" sh -lc "docker logs -f --tail=200 '$container'"
|
||||
else
|
||||
notify "kitty ist nicht installiert."
|
||||
fi
|
||||
;;
|
||||
*"Cleanup dangling images"*)
|
||||
docker_available || return 0
|
||||
terminal_hold "Docker Cleanup" "docker image prune -f"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
choice="$(
|
||||
printf '%s\n' \
|
||||
"📁 Projekt Management" \
|
||||
" Homelab Controlcenter" \
|
||||
"🐳 Docker Control" \
|
||||
" Terminal" \
|
||||
" Projektordner" \
|
||||
" VS Code / Codium" \
|
||||
" Git GUI" |
|
||||
pick " Dev Menue"
|
||||
)"
|
||||
|
||||
case "$choice" in
|
||||
*"Projekt Management"*)
|
||||
project_menu
|
||||
;;
|
||||
*"Homelab Controlcenter"*)
|
||||
"$SCRIPT_DIR/homelab-control.sh"
|
||||
;;
|
||||
*"Docker Control"*)
|
||||
docker_menu
|
||||
;;
|
||||
*"Terminal"*)
|
||||
kitty
|
||||
;;
|
||||
*"Projektordner"*)
|
||||
nautilus
|
||||
;;
|
||||
*"VS Code"*|*"Codium"*)
|
||||
if editor="$(code_cmd)"; then
|
||||
"$editor" >/dev/null 2>&1 &
|
||||
else
|
||||
notify "VS Code/Codium ist nicht installiert."
|
||||
fi
|
||||
;;
|
||||
*"Git GUI"*)
|
||||
if command -v gitg >/dev/null 2>&1; then
|
||||
gitg
|
||||
elif command -v git-cola >/dev/null 2>&1; then
|
||||
git-cola
|
||||
else
|
||||
notify "gitg oder git-cola ist nicht installiert."
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
145
config/hypr/Scripts/display-menu.sh
Executable file
145
config/hypr/Scripts/display-menu.sh
Executable file
@@ -0,0 +1,145 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
notify() {
|
||||
notify-send " Display" "$1"
|
||||
}
|
||||
|
||||
wofi_pick() {
|
||||
wofi --dmenu --prompt "$1" --insensitive
|
||||
}
|
||||
|
||||
connected_monitors() {
|
||||
hyprctl monitors all 2>/dev/null | awk '
|
||||
/^Monitor / {
|
||||
name=$2
|
||||
disabled=0
|
||||
}
|
||||
/disabled: true/ {
|
||||
disabled=1
|
||||
}
|
||||
/^$/ && name != "" {
|
||||
if (!disabled) print name
|
||||
name=""
|
||||
}
|
||||
END {
|
||||
if (name != "" && !disabled) print name
|
||||
}
|
||||
'
|
||||
}
|
||||
|
||||
all_monitors() {
|
||||
hyprctl monitors all 2>/dev/null | awk '/^Monitor / {print $2}'
|
||||
}
|
||||
|
||||
first_monitor() {
|
||||
connected_monitors | head -n 1
|
||||
}
|
||||
|
||||
second_monitor() {
|
||||
connected_monitors | sed -n '2p'
|
||||
}
|
||||
|
||||
show_status() {
|
||||
hyprctl monitors all | wofi --dmenu --prompt " Displaystatus"
|
||||
}
|
||||
|
||||
choose_monitor() {
|
||||
local monitors
|
||||
monitors="$(all_monitors)"
|
||||
|
||||
if [ -z "$monitors" ]; then
|
||||
notify "Keine Monitore ueber hyprctl gefunden."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
printf '%s\n' "$monitors" | awk '{print " " $0}' | wofi_pick "$1"
|
||||
}
|
||||
|
||||
disable_monitor() {
|
||||
local selection monitor
|
||||
selection="$(choose_monitor " Monitor deaktivieren")"
|
||||
[ -n "$selection" ] || exit 0
|
||||
monitor="${selection#* }"
|
||||
hyprctl keyword monitor "$monitor,disable" && notify "$monitor deaktiviert."
|
||||
}
|
||||
|
||||
enable_preferred() {
|
||||
local selection monitor
|
||||
selection="$(choose_monitor " Monitor aktivieren")"
|
||||
[ -n "$selection" ] || exit 0
|
||||
monitor="${selection#* }"
|
||||
hyprctl keyword monitor "$monitor,preferred,auto,1" && notify "$monitor aktiviert."
|
||||
}
|
||||
|
||||
extend_right() {
|
||||
local primary secondary
|
||||
primary="$(first_monitor)"
|
||||
secondary="$(second_monitor)"
|
||||
|
||||
if [ -z "$primary" ] || [ -z "$secondary" ]; then
|
||||
notify "Dafuer muessen mindestens zwei aktive Monitore vorhanden sein."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
hyprctl keyword monitor "$primary,preferred,0x0,1"
|
||||
hyprctl keyword monitor "$secondary,preferred,auto-right,1"
|
||||
notify "Displays erweitert."
|
||||
}
|
||||
|
||||
mirror_displays() {
|
||||
local primary secondary
|
||||
primary="$(first_monitor)"
|
||||
secondary="$(second_monitor)"
|
||||
|
||||
if [ -z "$primary" ] || [ -z "$secondary" ]; then
|
||||
notify "Dafuer muessen mindestens zwei aktive Monitore vorhanden sein."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
hyprctl keyword monitor "$primary,preferred,0x0,1"
|
||||
hyprctl keyword monitor "$secondary,preferred,0x0,1,mirror,$primary"
|
||||
notify "Displays gespiegelt."
|
||||
}
|
||||
|
||||
choice="$(
|
||||
printf '%s\n' \
|
||||
" Status anzeigen" \
|
||||
" Display-Konfig neu laden" \
|
||||
" Monitor aktivieren" \
|
||||
" Monitor deaktivieren" \
|
||||
" Displays erweitern" \
|
||||
" Displays spiegeln" \
|
||||
" Grafisches Display-Tool" |
|
||||
wofi_pick " Display"
|
||||
)"
|
||||
|
||||
case "$choice" in
|
||||
*"Status anzeigen"*)
|
||||
show_status
|
||||
;;
|
||||
*"Display-Konfig neu laden"*)
|
||||
hyprctl reload
|
||||
;;
|
||||
*"Monitor aktivieren"*)
|
||||
enable_preferred
|
||||
;;
|
||||
*"Monitor deaktivieren"*)
|
||||
disable_monitor
|
||||
;;
|
||||
*"Displays erweitern"*)
|
||||
extend_right
|
||||
;;
|
||||
*"Displays spiegeln"*)
|
||||
mirror_displays
|
||||
;;
|
||||
*"Grafisches Display-Tool"*)
|
||||
if command -v nwg-displays >/dev/null 2>&1; then
|
||||
nwg-displays
|
||||
elif command -v wdisplays >/dev/null 2>&1; then
|
||||
wdisplays
|
||||
else
|
||||
notify "Installiere nwg-displays oder wdisplays fuer ein grafisches Display-Tool."
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
23
config/hypr/Scripts/homelab-control.sh
Executable file
23
config/hypr/Scripts/homelab-control.sh
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
HYPR_DIR="$(cd -- "$SCRIPT_DIR/.." && pwd)"
|
||||
|
||||
notify() {
|
||||
notify-send "Homelab" "$1" >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
if ! command -v ags >/dev/null 2>&1; then
|
||||
notify "ags ist nicht installiert."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v sshpass >/dev/null 2>&1; then
|
||||
notify "sshpass ist nicht installiert."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "$HYPR_DIR"
|
||||
ags quit --instance homelab-control >/dev/null 2>&1 || true
|
||||
exec ags run "$HYPR_DIR/ags/homelab.tsx"
|
||||
49
config/hypr/Scripts/main-menu.sh
Executable file
49
config/hypr/Scripts/main-menu.sh
Executable file
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
if pgrep -x wofi >/dev/null; then
|
||||
pkill -x wofi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
choice="$(
|
||||
printf '%s\n' \
|
||||
" Apps" \
|
||||
" Dev Menue" \
|
||||
" Einstellungen" \
|
||||
" Terminal" \
|
||||
" Dateien" \
|
||||
" Hyprland neu laden" \
|
||||
" Session beenden" |
|
||||
wofi --dmenu --prompt " Hauptmenue" --insensitive
|
||||
)"
|
||||
|
||||
case "$choice" in
|
||||
*"Apps"*)
|
||||
wofi --show drun
|
||||
;;
|
||||
*"Dev Menue"*)
|
||||
"$SCRIPT_DIR/dev-menu.sh"
|
||||
;;
|
||||
*"Einstellungen"*)
|
||||
"$SCRIPT_DIR/settings-menu.sh"
|
||||
;;
|
||||
*"Terminal"*)
|
||||
kitty
|
||||
;;
|
||||
*"Dateien"*)
|
||||
nautilus
|
||||
;;
|
||||
*"Hyprland neu laden"*)
|
||||
hyprctl reload
|
||||
;;
|
||||
*"Session beenden"*)
|
||||
if command -v hyprshutdown >/dev/null 2>&1; then
|
||||
hyprshutdown
|
||||
else
|
||||
hyprctl dispatch exit
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
121
config/hypr/Scripts/network-menu.sh
Executable file
121
config/hypr/Scripts/network-menu.sh
Executable file
@@ -0,0 +1,121 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
notify() {
|
||||
notify-send " Netzwerk" "$1"
|
||||
}
|
||||
|
||||
require_nmcli() {
|
||||
if ! command -v nmcli >/dev/null 2>&1; then
|
||||
notify "nmcli ist nicht installiert."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
wofi_pick() {
|
||||
wofi --dmenu --prompt "$1" --insensitive
|
||||
}
|
||||
|
||||
wifi_status() {
|
||||
nmcli -t -f WIFI general | head -n 1
|
||||
}
|
||||
|
||||
active_connection() {
|
||||
nmcli -t -f NAME,TYPE connection show --active | awk -F: '$2 ~ /wireless|ethernet/ {print $1; exit}'
|
||||
}
|
||||
|
||||
connect_wifi() {
|
||||
nmcli radio wifi on
|
||||
nmcli device wifi rescan >/dev/null 2>&1 || true
|
||||
|
||||
local selection ssid security password
|
||||
selection="$(
|
||||
nmcli -t -f IN-USE,SSID,SECURITY,SIGNAL device wifi list |
|
||||
awk -F: '
|
||||
$2 != "" {
|
||||
icon = $1 == "*" ? "" : ""
|
||||
lock = $3 == "" ? "offen" : "gesichert"
|
||||
printf "%s %s [%s, %s%%]\n", icon, $2, lock, $4
|
||||
}
|
||||
' |
|
||||
wofi_pick " WLAN verbinden"
|
||||
)"
|
||||
|
||||
[ -n "$selection" ] || exit 0
|
||||
ssid="$(printf '%s\n' "$selection" | sed -E 's/^[^ ]+ //; s/ \[.*$//')"
|
||||
security="$(nmcli -t -f SSID,SECURITY device wifi list | awk -F: -v ssid="$ssid" '$1 == ssid {print $2; exit}')"
|
||||
|
||||
if [ -n "$security" ]; then
|
||||
password="$(printf '' | wofi --dmenu --password --prompt " Passwort fuer $ssid")"
|
||||
[ -n "$password" ] || exit 0
|
||||
nmcli device wifi connect "$ssid" password "$password" && notify "Verbunden mit $ssid."
|
||||
else
|
||||
nmcli device wifi connect "$ssid" && notify "Verbunden mit $ssid."
|
||||
fi
|
||||
}
|
||||
|
||||
saved_connections() {
|
||||
local selection name
|
||||
selection="$(
|
||||
nmcli -t -f NAME,TYPE connection show |
|
||||
awk -F: '$2 ~ /wireless|ethernet/ {printf " %s\n", $1}' |
|
||||
wofi_pick " Gespeicherte Verbindungen"
|
||||
)"
|
||||
|
||||
[ -n "$selection" ] || exit 0
|
||||
name="${selection#* }"
|
||||
nmcli connection up "$name" && notify "Verbindung $name gestartet."
|
||||
}
|
||||
|
||||
disconnect_network() {
|
||||
local conn
|
||||
conn="$(active_connection)"
|
||||
|
||||
if [ -z "$conn" ]; then
|
||||
notify "Keine aktive Netzwerkverbindung gefunden."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
nmcli connection down "$conn" && notify "Verbindung $conn getrennt."
|
||||
}
|
||||
|
||||
require_nmcli
|
||||
|
||||
current="$(active_connection)"
|
||||
[ -n "$current" ] || current="Nicht verbunden"
|
||||
|
||||
choice="$(
|
||||
printf '%s\n' \
|
||||
" WLAN verbinden" \
|
||||
" WLAN ein/aus" \
|
||||
" Gespeicherte Verbindungen" \
|
||||
" Aktive Verbindung trennen" \
|
||||
" Netzwerk neu scannen" \
|
||||
" Status: $current" |
|
||||
wofi_pick " Netzwerk"
|
||||
)"
|
||||
|
||||
case "$choice" in
|
||||
*"WLAN verbinden"*)
|
||||
connect_wifi
|
||||
;;
|
||||
*"WLAN ein/aus"*)
|
||||
if [ "$(wifi_status)" = "enabled" ]; then
|
||||
nmcli radio wifi off && notify "WLAN ausgeschaltet."
|
||||
else
|
||||
nmcli radio wifi on && notify "WLAN eingeschaltet."
|
||||
fi
|
||||
;;
|
||||
*"Gespeicherte Verbindungen"*)
|
||||
saved_connections
|
||||
;;
|
||||
*"Aktive Verbindung trennen"*)
|
||||
disconnect_network
|
||||
;;
|
||||
*"Netzwerk neu scannen"*)
|
||||
nmcli device wifi rescan && notify "WLAN-Scan gestartet."
|
||||
;;
|
||||
*"Status:"*)
|
||||
nmcli general status | wofi --dmenu --prompt " Netzwerkstatus"
|
||||
;;
|
||||
esac
|
||||
211
config/hypr/Scripts/power-menu.py
Executable file
211
config/hypr/Scripts/power-menu.py
Executable file
@@ -0,0 +1,211 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import shlex
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
gi.require_version("Gdk", "3.0")
|
||||
from gi.repository import Gdk, Gtk # noqa: E402
|
||||
|
||||
|
||||
HYPR_DIR = Path.home() / ".config" / "hypr"
|
||||
THEME_DIR = HYPR_DIR / "Themes"
|
||||
CURRENT_WALLPAPER = HYPR_DIR / "current-wallpaper"
|
||||
|
||||
|
||||
DEFAULT_THEME = {
|
||||
"NAME": "Power",
|
||||
"ACCENT": "#f38ba8",
|
||||
"ACCENT_2": "#cba6f7",
|
||||
"BACKGROUND_HEX": "#18141f",
|
||||
"PANEL_HEX": "#313244",
|
||||
"FOREGROUND": "#f5e0dc",
|
||||
"MUTED": "#a6adc8",
|
||||
"SELECTED_TEXT": "#11111b",
|
||||
}
|
||||
|
||||
|
||||
def parse_theme_file(path):
|
||||
theme = {}
|
||||
|
||||
for line in path.read_text(encoding="utf-8", errors="ignore").splitlines():
|
||||
line = line.strip()
|
||||
if not line or line.startswith("#") or "=" not in line:
|
||||
continue
|
||||
|
||||
key, value = line.split("=", 1)
|
||||
key = key.strip()
|
||||
value = value.strip()
|
||||
|
||||
try:
|
||||
parsed = shlex.split(value)
|
||||
theme[key] = parsed[0] if parsed else ""
|
||||
except ValueError:
|
||||
theme[key] = value.strip("\"'")
|
||||
|
||||
return theme
|
||||
|
||||
|
||||
def load_current_theme():
|
||||
current_wallpaper = ""
|
||||
if CURRENT_WALLPAPER.exists():
|
||||
current_wallpaper = CURRENT_WALLPAPER.read_text(encoding="utf-8", errors="ignore").strip()
|
||||
|
||||
for theme_file in sorted(THEME_DIR.glob("*.theme")):
|
||||
theme = parse_theme_file(theme_file)
|
||||
if theme.get("WALLPAPER") == current_wallpaper:
|
||||
return {**DEFAULT_THEME, **theme}
|
||||
|
||||
rose = THEME_DIR / "rose-night.theme"
|
||||
if rose.exists():
|
||||
return {**DEFAULT_THEME, **parse_theme_file(rose)}
|
||||
|
||||
return DEFAULT_THEME
|
||||
|
||||
|
||||
def run(command):
|
||||
subprocess.Popen(command, start_new_session=True)
|
||||
Gtk.main_quit()
|
||||
|
||||
|
||||
class PowerMenu(Gtk.Window):
|
||||
def __init__(self):
|
||||
super().__init__(title="Power")
|
||||
|
||||
self.theme = load_current_theme()
|
||||
self.set_decorated(False)
|
||||
self.set_resizable(False)
|
||||
self.set_keep_above(True)
|
||||
self.set_position(Gtk.WindowPosition.CENTER)
|
||||
self.set_type_hint(Gdk.WindowTypeHint.DIALOG)
|
||||
self.set_skip_taskbar_hint(True)
|
||||
self.set_skip_pager_hint(True)
|
||||
self.set_app_paintable(True)
|
||||
self.connect("key-press-event", self.on_key_press)
|
||||
self.connect("focus-out-event", lambda *_: Gtk.main_quit())
|
||||
|
||||
overlay = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=18)
|
||||
overlay.get_style_context().add_class("power-shell")
|
||||
|
||||
title = Gtk.Label(label=self.theme.get("NAME", "Power"))
|
||||
title.get_style_context().add_class("power-title")
|
||||
overlay.pack_start(title, False, False, 0)
|
||||
|
||||
grid = Gtk.Grid()
|
||||
grid.set_column_spacing(14)
|
||||
grid.set_row_spacing(14)
|
||||
grid.set_halign(Gtk.Align.CENTER)
|
||||
|
||||
actions = [
|
||||
("", "Sperren", ["hyprlock"]),
|
||||
("", "Ruhezustand", ["systemctl", "suspend"]),
|
||||
("", "Abmelden", ["hyprctl", "dispatch", "exit"]),
|
||||
("", "Neustart", ["systemctl", "reboot"]),
|
||||
("⏻", "Ausschalten", ["systemctl", "poweroff"]),
|
||||
("", "Abbrechen", None),
|
||||
]
|
||||
|
||||
for index, (icon, label, command) in enumerate(actions):
|
||||
button = self.make_button(icon, label, command)
|
||||
grid.attach(button, index % 3, index // 3, 1, 1)
|
||||
|
||||
overlay.pack_start(grid, False, False, 0)
|
||||
self.add(overlay)
|
||||
self.apply_css()
|
||||
|
||||
def make_button(self, icon, label, command):
|
||||
button = Gtk.Button()
|
||||
button.get_style_context().add_class("power-button")
|
||||
button.set_size_request(150, 118)
|
||||
button.set_relief(Gtk.ReliefStyle.NONE)
|
||||
|
||||
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8)
|
||||
box.set_halign(Gtk.Align.CENTER)
|
||||
box.set_valign(Gtk.Align.CENTER)
|
||||
|
||||
icon_label = Gtk.Label(label=icon)
|
||||
icon_label.get_style_context().add_class("power-icon")
|
||||
text_label = Gtk.Label(label=label)
|
||||
text_label.get_style_context().add_class("power-label")
|
||||
|
||||
box.pack_start(icon_label, False, False, 0)
|
||||
box.pack_start(text_label, False, False, 0)
|
||||
button.add(box)
|
||||
|
||||
if command:
|
||||
button.connect("clicked", lambda *_: run(command))
|
||||
else:
|
||||
button.connect("clicked", lambda *_: Gtk.main_quit())
|
||||
|
||||
return button
|
||||
|
||||
def apply_css(self):
|
||||
css = f"""
|
||||
window {{
|
||||
background: transparent;
|
||||
}}
|
||||
|
||||
.power-shell {{
|
||||
margin: 0;
|
||||
padding: 24px;
|
||||
border-radius: 26px;
|
||||
border: 1px solid {self.theme["ACCENT"]};
|
||||
background: alpha({self.theme["BACKGROUND_HEX"]}, 0.94);
|
||||
box-shadow: 0 22px 70px alpha(#000000, 0.55);
|
||||
}}
|
||||
|
||||
.power-title {{
|
||||
color: {self.theme["FOREGROUND"]};
|
||||
font-family: "JetBrainsMono Nerd Font", "JetBrains Mono", sans-serif;
|
||||
font-size: 18px;
|
||||
font-weight: 800;
|
||||
}}
|
||||
|
||||
.power-button {{
|
||||
color: {self.theme["FOREGROUND"]};
|
||||
background: alpha({self.theme["PANEL_HEX"]}, 0.82);
|
||||
border: 1px solid alpha({self.theme["ACCENT_2"]}, 0.42);
|
||||
border-radius: 18px;
|
||||
transition: 160ms ease;
|
||||
}}
|
||||
|
||||
.power-button:hover,
|
||||
.power-button:focus {{
|
||||
color: {self.theme["SELECTED_TEXT"]};
|
||||
background: linear-gradient(135deg, {self.theme["ACCENT"]}, {self.theme["ACCENT_2"]});
|
||||
border-color: {self.theme["ACCENT"]};
|
||||
}}
|
||||
|
||||
.power-icon {{
|
||||
font-family: "JetBrainsMono Nerd Font", "JetBrains Mono", sans-serif;
|
||||
font-size: 34px;
|
||||
font-weight: 800;
|
||||
}}
|
||||
|
||||
.power-label {{
|
||||
font-family: "JetBrainsMono Nerd Font", "JetBrains Mono", sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: 800;
|
||||
}}
|
||||
"""
|
||||
|
||||
provider = Gtk.CssProvider()
|
||||
provider.load_from_data(css.encode("utf-8"))
|
||||
Gtk.StyleContext.add_provider_for_screen(
|
||||
Gdk.Screen.get_default(),
|
||||
provider,
|
||||
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION,
|
||||
)
|
||||
|
||||
def on_key_press(self, _widget, event):
|
||||
if event.keyval in (Gdk.KEY_Escape, Gdk.KEY_q):
|
||||
Gtk.main_quit()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
window = PowerMenu()
|
||||
window.show_all()
|
||||
Gtk.main()
|
||||
128
config/hypr/Scripts/screenshot-menu.sh
Executable file
128
config/hypr/Scripts/screenshot-menu.sh
Executable file
@@ -0,0 +1,128 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
screenshot_dir="${XDG_PICTURES_DIR:-$HOME/Pictures}/Screenshots"
|
||||
|
||||
notify() {
|
||||
notify-send " Screenshot" "$1"
|
||||
}
|
||||
|
||||
require_cmd() {
|
||||
local cmd="$1"
|
||||
|
||||
if ! command -v "$cmd" >/dev/null 2>&1; then
|
||||
notify "$cmd ist nicht installiert."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
filename() {
|
||||
date +%Y-%m-%d_%H-%M-%S.png
|
||||
}
|
||||
|
||||
take_hyprshot() {
|
||||
local mode="$1"
|
||||
local name="$2"
|
||||
|
||||
require_cmd hyprshot
|
||||
mkdir -p "$screenshot_dir"
|
||||
hyprshot -m "$mode" -o "$screenshot_dir" -f "$name" -s
|
||||
printf '%s/%s\n' "$screenshot_dir" "$name"
|
||||
}
|
||||
|
||||
annotate_region() {
|
||||
local name path
|
||||
|
||||
require_cmd satty
|
||||
name="$(filename)"
|
||||
path="$(take_hyprshot region "$name")"
|
||||
satty --filename "$path" --output-filename "$path"
|
||||
}
|
||||
|
||||
quick_region() {
|
||||
local name
|
||||
|
||||
name="$(filename)"
|
||||
take_hyprshot region "$name" >/dev/null
|
||||
notify "Bereich gespeichert."
|
||||
}
|
||||
|
||||
quick_window() {
|
||||
local name
|
||||
|
||||
name="$(filename)"
|
||||
take_hyprshot window "$name" >/dev/null
|
||||
notify "Fenster gespeichert."
|
||||
}
|
||||
|
||||
quick_output() {
|
||||
local name
|
||||
|
||||
name="$(filename)"
|
||||
take_hyprshot output "$name" >/dev/null
|
||||
notify "Bildschirm gespeichert."
|
||||
}
|
||||
|
||||
copy_region() {
|
||||
require_cmd hyprshot
|
||||
hyprshot -m region --clipboard-only -s
|
||||
notify "Bereich in die Zwischenablage kopiert."
|
||||
}
|
||||
|
||||
show_menu() {
|
||||
require_cmd wofi
|
||||
|
||||
local choice
|
||||
choice="$(
|
||||
printf '%s\n' \
|
||||
" Bereich markieren" \
|
||||
" Bereich speichern" \
|
||||
" Fenster speichern" \
|
||||
" Bildschirm speichern" \
|
||||
" Bereich kopieren" |
|
||||
wofi --dmenu --prompt " Screenshot" --insensitive
|
||||
)"
|
||||
|
||||
case "$choice" in
|
||||
*"Bereich markieren"*)
|
||||
annotate_region
|
||||
;;
|
||||
*"Bereich speichern"*)
|
||||
quick_region
|
||||
;;
|
||||
*"Fenster speichern"*)
|
||||
quick_window
|
||||
;;
|
||||
*"Bildschirm speichern"*)
|
||||
quick_output
|
||||
;;
|
||||
*"Bereich kopieren"*)
|
||||
copy_region
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
case "${1:-menu}" in
|
||||
annotate-region)
|
||||
annotate_region
|
||||
;;
|
||||
region)
|
||||
quick_region
|
||||
;;
|
||||
window)
|
||||
quick_window
|
||||
;;
|
||||
output)
|
||||
quick_output
|
||||
;;
|
||||
copy-region)
|
||||
copy_region
|
||||
;;
|
||||
menu)
|
||||
show_menu
|
||||
;;
|
||||
*)
|
||||
notify "Unbekannter Screenshot-Modus: $1"
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
40
config/hypr/Scripts/settings-menu.sh
Executable file
40
config/hypr/Scripts/settings-menu.sh
Executable file
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
choice="$(
|
||||
printf '%s\n' \
|
||||
" Aussehen" \
|
||||
" Audio" \
|
||||
" Bluetooth" \
|
||||
" Display" \
|
||||
" Netzwerk" \
|
||||
" Screenshot" \
|
||||
" System" |
|
||||
wofi --dmenu --prompt " Einstellungen" --insensitive
|
||||
)"
|
||||
|
||||
case "$choice" in
|
||||
*"Aussehen"*)
|
||||
"$SCRIPT_DIR/appearance-menu.sh"
|
||||
;;
|
||||
*"Audio"*)
|
||||
"$SCRIPT_DIR/audio-menu.sh"
|
||||
;;
|
||||
*"Netzwerk"*)
|
||||
"$SCRIPT_DIR/network-menu.sh"
|
||||
;;
|
||||
*"Bluetooth"*)
|
||||
"$SCRIPT_DIR/bluetooth-menu.sh"
|
||||
;;
|
||||
*"Display"*)
|
||||
"$SCRIPT_DIR/display-menu.sh"
|
||||
;;
|
||||
*"Screenshot"*)
|
||||
"$SCRIPT_DIR/screenshot-menu.sh"
|
||||
;;
|
||||
*"System"*)
|
||||
"$SCRIPT_DIR/system-menu.sh"
|
||||
;;
|
||||
esac
|
||||
77
config/hypr/Scripts/system-menu.sh
Executable file
77
config/hypr/Scripts/system-menu.sh
Executable file
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
notify() {
|
||||
notify-send " System" "$1"
|
||||
}
|
||||
|
||||
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
start_detached() {
|
||||
local command_name="$1"
|
||||
local unit_name="${command_name//[^[:alnum:]_.-]/-}"
|
||||
|
||||
if command -v systemd-run >/dev/null 2>&1; then
|
||||
systemd-run --user --unit="$unit_name" --collect "$@" >/dev/null 2>&1 && return
|
||||
fi
|
||||
|
||||
if command -v setsid >/dev/null 2>&1; then
|
||||
setsid -f "$@" >/dev/null 2>&1
|
||||
else
|
||||
"$@" >/dev/null 2>&1 &
|
||||
fi
|
||||
}
|
||||
|
||||
restart_waybar() {
|
||||
local i
|
||||
|
||||
pkill -x waybar >/dev/null 2>&1 || true
|
||||
|
||||
for i in {1..20}; do
|
||||
pgrep -x waybar >/dev/null 2>&1 || break
|
||||
sleep 0.05
|
||||
done
|
||||
|
||||
pgrep -x waybar >/dev/null 2>&1 && pkill -9 -x waybar >/dev/null 2>&1 || true
|
||||
start_detached waybar
|
||||
}
|
||||
|
||||
choice="$(
|
||||
printf '%s\n' \
|
||||
" Hyprland neu laden" \
|
||||
" Waybar neu starten" \
|
||||
" Bildschirm heller" \
|
||||
" Bildschirm dunkler" \
|
||||
" Session beenden" |
|
||||
wofi --dmenu --prompt " System" --insensitive
|
||||
)"
|
||||
|
||||
case "$choice" in
|
||||
*"Hyprland neu laden"*)
|
||||
hyprctl reload
|
||||
;;
|
||||
*"Waybar neu starten"*)
|
||||
restart_waybar
|
||||
;;
|
||||
*"Bildschirm heller"*)
|
||||
if command -v brightnessctl >/dev/null 2>&1; then
|
||||
brightnessctl -e4 -n2 set 5%+
|
||||
else
|
||||
notify "brightnessctl ist nicht installiert."
|
||||
fi
|
||||
;;
|
||||
*"Bildschirm dunkler"*)
|
||||
if command -v brightnessctl >/dev/null 2>&1; then
|
||||
brightnessctl -e4 -n2 set 5%-
|
||||
else
|
||||
notify "brightnessctl ist nicht installiert."
|
||||
fi
|
||||
;;
|
||||
*"Session beenden"*)
|
||||
if command -v hyprshutdown >/dev/null 2>&1; then
|
||||
hyprshutdown
|
||||
else
|
||||
hyprctl dispatch exit
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
1204
config/hypr/Scripts/theme-menu.sh
Executable file
1204
config/hypr/Scripts/theme-menu.sh
Executable file
File diff suppressed because it is too large
Load Diff
7
config/hypr/Scripts/toggle-wofi.sh
Executable file
7
config/hypr/Scripts/toggle-wofi.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if pgrep -x wofi >/dev/null; then
|
||||
pkill -x wofi
|
||||
else
|
||||
wofi --show drun
|
||||
fi
|
||||
197
config/hypr/Scripts/wallpaper-menu.sh
Executable file
197
config/hypr/Scripts/wallpaper-menu.sh
Executable file
@@ -0,0 +1,197 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
HYPR_DIR="$(cd -- "$SCRIPT_DIR/.." && pwd)"
|
||||
WALLPAPER_DIR="${WALLPAPER_DIR:-$HOME/Bilder/Wallpaper}"
|
||||
HYPRPAPER_CONF="$HYPR_DIR/hyprpaper.conf"
|
||||
CURRENT_WALLPAPER="$HYPR_DIR/current-wallpaper"
|
||||
|
||||
TRANSITION_TYPE="${TRANSITION_TYPE:-grow}"
|
||||
TRANSITION_DURATION="${TRANSITION_DURATION:-1.0}"
|
||||
TRANSITION_FPS="${TRANSITION_FPS:-60}"
|
||||
TRANSITION_POS="${TRANSITION_POS:-center}"
|
||||
|
||||
notify() {
|
||||
notify-send " Wallpaper" "$1" >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
start_detached() {
|
||||
local command_name="$1"
|
||||
local unit_name="${command_name//[^[:alnum:]_.-]/-}"
|
||||
|
||||
if command -v systemd-run >/dev/null 2>&1; then
|
||||
systemd-run --user --unit="$unit_name" --collect "$@" >/dev/null 2>&1 && return
|
||||
fi
|
||||
|
||||
if command -v setsid >/dev/null 2>&1; then
|
||||
setsid -f "$@" >/dev/null 2>&1
|
||||
else
|
||||
"$@" >/dev/null 2>&1 &
|
||||
fi
|
||||
}
|
||||
|
||||
apply_wallpaper() {
|
||||
local wallpaper="$1"
|
||||
|
||||
cat >"$HYPRPAPER_CONF" <<EOF
|
||||
wallpaper {
|
||||
monitor =
|
||||
path = $wallpaper
|
||||
fit_mode = cover
|
||||
}
|
||||
EOF
|
||||
|
||||
printf '%s\n' "$wallpaper" >"$CURRENT_WALLPAPER"
|
||||
|
||||
if command -v awww >/dev/null 2>&1; then
|
||||
if ! pgrep -x awww-daemon >/dev/null 2>&1; then
|
||||
start_detached awww-daemon
|
||||
sleep 0.2
|
||||
fi
|
||||
|
||||
awww img "$wallpaper" \
|
||||
--transition-type "$TRANSITION_TYPE" \
|
||||
--transition-duration "$TRANSITION_DURATION" \
|
||||
--transition-fps "$TRANSITION_FPS" \
|
||||
--transition-pos "$TRANSITION_POS" >/dev/null 2>&1 || true
|
||||
return
|
||||
fi
|
||||
|
||||
if command -v swww >/dev/null 2>&1; then
|
||||
if ! pgrep -x swww-daemon >/dev/null 2>&1; then
|
||||
start_detached swww-daemon
|
||||
sleep 0.2
|
||||
fi
|
||||
|
||||
swww img "$wallpaper" \
|
||||
--transition-type "$TRANSITION_TYPE" \
|
||||
--transition-duration "$TRANSITION_DURATION" \
|
||||
--transition-fps "$TRANSITION_FPS" \
|
||||
--transition-pos "$TRANSITION_POS" >/dev/null 2>&1 || true
|
||||
return
|
||||
fi
|
||||
|
||||
if command -v hyprctl >/dev/null 2>&1; then
|
||||
if ! pgrep -x hyprpaper >/dev/null 2>&1; then
|
||||
start_detached hyprpaper
|
||||
sleep 0.2
|
||||
fi
|
||||
|
||||
hyprctl hyprpaper preload "$wallpaper" >/dev/null || true
|
||||
hyprctl hyprpaper wallpaper ",$wallpaper" >/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
preview_wallpaper() {
|
||||
local wallpaper="$1"
|
||||
|
||||
if command -v swayimg >/dev/null 2>&1; then
|
||||
start_detached swayimg "$wallpaper"
|
||||
return
|
||||
fi
|
||||
|
||||
if command -v imv >/dev/null 2>&1; then
|
||||
start_detached imv "$wallpaper"
|
||||
return
|
||||
fi
|
||||
|
||||
if command -v kitty >/dev/null 2>&1; then
|
||||
start_detached kitty \
|
||||
--class wallpaper-preview \
|
||||
--title "Wallpaper Vorschau" \
|
||||
sh -c 'clear; printf "%s\n\n" "$1"; kitty +kitten icat --fit both --align center "$1"; printf "\nEnter schliesst die Vorschau."; read -r _' \
|
||||
sh "$wallpaper"
|
||||
return
|
||||
fi
|
||||
|
||||
notify "Kein Vorschauprogramm gefunden."
|
||||
}
|
||||
|
||||
if [[ "${1:-}" == "--apply" ]]; then
|
||||
wallpaper="${2:-}"
|
||||
|
||||
if [[ -z "$wallpaper" || ! -f "$wallpaper" ]]; then
|
||||
notify "Wallpaper nicht gefunden."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
apply_wallpaper "$wallpaper"
|
||||
notify "$(basename "$wallpaper") angewendet."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "${1:-}" == "--preview" ]]; then
|
||||
wallpaper="${2:-}"
|
||||
|
||||
if [[ -z "$wallpaper" || ! -f "$wallpaper" ]]; then
|
||||
notify "Wallpaper nicht gefunden."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
preview_wallpaper "$wallpaper"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
pick_wallpaper() {
|
||||
local entries=()
|
||||
local wallpaper
|
||||
|
||||
mapfile -t wallpapers < <(
|
||||
find "$WALLPAPER_DIR" -maxdepth 1 -type f \
|
||||
\( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' -o -iname '*.webp' -o -iname '*.gif' \) |
|
||||
sort
|
||||
)
|
||||
|
||||
if ((${#wallpapers[@]} == 0)); then
|
||||
notify "Keine Bilder in $WALLPAPER_DIR gefunden."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for wallpaper in "${wallpapers[@]}"; do
|
||||
entries+=(" $(basename "$wallpaper")")
|
||||
done
|
||||
|
||||
choice="$(
|
||||
printf '%s\n' "${entries[@]}" |
|
||||
wofi --dmenu --prompt " Wallpaper" --insensitive
|
||||
)"
|
||||
|
||||
[[ -z "${choice:-}" ]] && exit 0
|
||||
|
||||
for i in "${!entries[@]}"; do
|
||||
if [[ "$choice" == "${entries[$i]}" ]]; then
|
||||
printf '%s\n' "${wallpapers[$i]}"
|
||||
return
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
while true; do
|
||||
wallpaper="$(pick_wallpaper)"
|
||||
[[ -z "${wallpaper:-}" ]] && exit 0
|
||||
|
||||
action="$(
|
||||
printf '%s\n' \
|
||||
" Vorschau" \
|
||||
" Anwenden" \
|
||||
" Zurueck" |
|
||||
wofi --dmenu --prompt " $(basename "$wallpaper")" --insensitive
|
||||
)"
|
||||
|
||||
case "$action" in
|
||||
*"Vorschau"*)
|
||||
preview_wallpaper "$wallpaper"
|
||||
;;
|
||||
*"Anwenden"*)
|
||||
apply_wallpaper "$wallpaper"
|
||||
notify "$(basename "$wallpaper") angewendet."
|
||||
exit 0
|
||||
;;
|
||||
*"Zurueck"*)
|
||||
;;
|
||||
*)
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
34
config/hypr/Themes/forest-neon.theme
Normal file
34
config/hypr/Themes/forest-neon.theme
Normal file
@@ -0,0 +1,34 @@
|
||||
NAME="Forest Neon"
|
||||
ICON=""
|
||||
WALLPAPER="/home/pascal/Bilder/Wallpaper/forest.jpg"
|
||||
TRANSITION_TYPE="grow"
|
||||
TRANSITION_DURATION="1.0"
|
||||
TRANSITION_FPS="60"
|
||||
TRANSITION_POS="center"
|
||||
ACTIVE_BORDER="rgba(00ff9cee) rgba(00cc88ee) 45deg"
|
||||
INACTIVE_BORDER="rgba(2a2a2aaa)"
|
||||
ACCENT="#00ff9c"
|
||||
ACCENT_2="#00cc88"
|
||||
BACKGROUND="rgba(20, 20, 30, 0.95)"
|
||||
BACKGROUND_SOFT="rgba(40, 40, 55, 0.8)"
|
||||
BACKGROUND_HEX="#14141e"
|
||||
PANEL_HEX="#282837"
|
||||
FOREGROUND="#cdd6f4"
|
||||
MUTED="#cccccc"
|
||||
SELECTED_TEXT="#000000"
|
||||
WAYBAR_PANEL="rgba(24, 24, 37, 0.72)"
|
||||
WAYBAR_ISLAND="rgba(5, 5, 9, 0.88)"
|
||||
WAYBAR_MUTED="#7f849c"
|
||||
WAYBAR_SUCCESS="#a6e3a1"
|
||||
WAYBAR_WARNING="#f9e2af"
|
||||
WAYBAR_DANGER="#f38ba8"
|
||||
WAYBAR_BLUE="#89b4fa"
|
||||
WAYBAR_CYAN="#89dceb"
|
||||
WAYBAR_ORANGE="#fab387"
|
||||
WAYBAR_PURPLE="#cba6f7"
|
||||
APP_THEME_MODE="prefer-dark"
|
||||
GNOME_ACCENT_COLOR="green"
|
||||
GTK_THEME_NAME="Adwaita"
|
||||
ICON_THEME_NAME="Papirus-ForestNeon"
|
||||
PAPIRUS_FOLDER_COLOR="green"
|
||||
KDE_COLOR_SCHEME="ForestNeon"
|
||||
34
config/hypr/Themes/rose-night.theme
Normal file
34
config/hypr/Themes/rose-night.theme
Normal file
@@ -0,0 +1,34 @@
|
||||
NAME="Rose Night"
|
||||
ICON=""
|
||||
WALLPAPER="/home/pascal/Bilder/Wallpaper/rose-pink.jpg"
|
||||
TRANSITION_TYPE="wipe"
|
||||
TRANSITION_DURATION="1.0"
|
||||
TRANSITION_FPS="60"
|
||||
TRANSITION_POS="center"
|
||||
ACTIVE_BORDER="rgba(f38ba8ee) rgba(cba6f7ee) 45deg"
|
||||
INACTIVE_BORDER="rgba(313244aa)"
|
||||
ACCENT="#f38ba8"
|
||||
ACCENT_2="#cba6f7"
|
||||
BACKGROUND="rgba(24, 20, 31, 0.95)"
|
||||
BACKGROUND_SOFT="rgba(49, 50, 68, 0.82)"
|
||||
BACKGROUND_HEX="#18141f"
|
||||
PANEL_HEX="#313244"
|
||||
FOREGROUND="#f5e0dc"
|
||||
MUTED="#cdd6f4"
|
||||
SELECTED_TEXT="#11111b"
|
||||
WAYBAR_PANEL="rgba(49, 50, 68, 0.76)"
|
||||
WAYBAR_ISLAND="rgba(24, 20, 31, 0.90)"
|
||||
WAYBAR_MUTED="#a6adc8"
|
||||
WAYBAR_SUCCESS="#f5c2e7"
|
||||
WAYBAR_WARNING="#f9e2af"
|
||||
WAYBAR_DANGER="#f38ba8"
|
||||
WAYBAR_BLUE="#cba6f7"
|
||||
WAYBAR_CYAN="#f5c2e7"
|
||||
WAYBAR_ORANGE="#fab387"
|
||||
WAYBAR_PURPLE="#cba6f7"
|
||||
APP_THEME_MODE="prefer-dark"
|
||||
GNOME_ACCENT_COLOR="pink"
|
||||
GTK_THEME_NAME="Adwaita"
|
||||
ICON_THEME_NAME="Papirus-RoseNight"
|
||||
PAPIRUS_FOLDER_COLOR="pink"
|
||||
KDE_COLOR_SCHEME="RoseNight"
|
||||
312
config/hypr/ags/homelab.css
Normal file
312
config/hypr/ags/homelab.css
Normal file
@@ -0,0 +1,312 @@
|
||||
* {
|
||||
all: unset;
|
||||
font-family: "JetBrainsMono Nerd Font", "Noto Sans", sans-serif;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.homelab-window {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.login-panel,
|
||||
.shell {
|
||||
border: 1px solid rgba(205, 214, 244, 0.16);
|
||||
border-radius: 16px;
|
||||
background: rgba(20, 20, 30, 0.97);
|
||||
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.45);
|
||||
color: #cdd6f4;
|
||||
}
|
||||
|
||||
.login-panel {
|
||||
min-width: 520px;
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.shell {
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
min-width: 218px;
|
||||
padding: 14px 10px;
|
||||
border-right: 1px solid rgba(205, 214, 244, 0.10);
|
||||
background: rgba(14, 16, 24, 0.72);
|
||||
}
|
||||
|
||||
.brand {
|
||||
padding: 8px 8px 14px;
|
||||
}
|
||||
|
||||
.brand-title {
|
||||
color: #00ff9c;
|
||||
font-size: 19px;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.brand-subtitle,
|
||||
.subtitle,
|
||||
.row-subtitle {
|
||||
color: #a6adc8;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.nav-button {
|
||||
min-height: 34px;
|
||||
padding: 7px 8px;
|
||||
border-radius: 8px;
|
||||
color: #cdd6f4;
|
||||
}
|
||||
|
||||
.nav-button:hover,
|
||||
.nav-button:focus {
|
||||
background: rgba(0, 255, 156, 0.14);
|
||||
}
|
||||
|
||||
.nav-button.active {
|
||||
background: rgba(0, 255, 156, 0.22);
|
||||
color: #00ff9c;
|
||||
}
|
||||
|
||||
.nav-icon {
|
||||
min-width: 24px;
|
||||
}
|
||||
|
||||
.nav-label {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.page-scroll {
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.header {
|
||||
min-height: 38px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 20px;
|
||||
font-weight: 750;
|
||||
color: #00ff9c;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
entry {
|
||||
padding: 10px 12px;
|
||||
border: 1px solid rgba(205, 214, 244, 0.14);
|
||||
border-radius: 10px;
|
||||
background: rgba(40, 40, 55, 0.82);
|
||||
color: #cdd6f4;
|
||||
}
|
||||
|
||||
entry:focus {
|
||||
border-color: rgba(0, 255, 156, 0.78);
|
||||
}
|
||||
|
||||
.grid,
|
||||
.live-strip,
|
||||
.service-grid {
|
||||
min-height: 92px;
|
||||
}
|
||||
|
||||
.card,
|
||||
.chart-card,
|
||||
.service-card,
|
||||
.table-row {
|
||||
border: 1px solid rgba(205, 214, 244, 0.10);
|
||||
border-radius: 8px;
|
||||
background: rgba(40, 40, 55, 0.62);
|
||||
}
|
||||
|
||||
.card {
|
||||
min-width: 220px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.wide-card {
|
||||
min-width: 0;
|
||||
min-height: 220px;
|
||||
}
|
||||
|
||||
.log-card {
|
||||
min-width: 0;
|
||||
min-height: 560px;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
min-height: 80px;
|
||||
}
|
||||
|
||||
.chart-card {
|
||||
min-width: 260px;
|
||||
min-height: 98px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.chart-card.cpu {
|
||||
border-color: rgba(0, 255, 156, 0.22);
|
||||
}
|
||||
|
||||
.chart-card.memory {
|
||||
border-color: rgba(137, 180, 250, 0.26);
|
||||
}
|
||||
|
||||
.chart-card.load {
|
||||
border-color: rgba(249, 226, 175, 0.24);
|
||||
}
|
||||
|
||||
.chart-card.docker,
|
||||
.chart-card.network {
|
||||
border-color: rgba(116, 199, 236, 0.24);
|
||||
}
|
||||
|
||||
.card-title {
|
||||
color: #00cc88;
|
||||
font-size: 12px;
|
||||
font-weight: 750;
|
||||
}
|
||||
|
||||
.card-value {
|
||||
color: #cdd6f4;
|
||||
}
|
||||
|
||||
.compact,
|
||||
.row-subtitle {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.percent-label,
|
||||
.chart-value {
|
||||
color: #f9e2af;
|
||||
font-size: 12px;
|
||||
font-weight: 750;
|
||||
}
|
||||
|
||||
.sparkline {
|
||||
color: #00ff9c;
|
||||
font-size: 25px;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.meter {
|
||||
min-height: 8px;
|
||||
border-radius: 6px;
|
||||
background: rgba(205, 214, 244, 0.10);
|
||||
}
|
||||
|
||||
.meter-fill {
|
||||
min-height: 8px;
|
||||
border-radius: 6px;
|
||||
background: linear-gradient(to right, #00ff9c, #89b4fa);
|
||||
}
|
||||
|
||||
.alerts {
|
||||
min-height: 32px;
|
||||
}
|
||||
|
||||
.alert,
|
||||
.pill {
|
||||
padding: 4px 8px;
|
||||
border-radius: 999px;
|
||||
background: rgba(205, 214, 244, 0.10);
|
||||
color: #cdd6f4;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.alert.ok,
|
||||
.pill.ok {
|
||||
background: rgba(0, 255, 156, 0.16);
|
||||
color: #00ff9c;
|
||||
}
|
||||
|
||||
.alert.warn,
|
||||
.pill.warn {
|
||||
background: rgba(249, 226, 175, 0.16);
|
||||
color: #f9e2af;
|
||||
}
|
||||
|
||||
.table-row {
|
||||
min-height: 72px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.container-main {
|
||||
min-width: 260px;
|
||||
}
|
||||
|
||||
.container-stats {
|
||||
min-width: 112px;
|
||||
}
|
||||
|
||||
.row-actions {
|
||||
min-width: 250px;
|
||||
}
|
||||
|
||||
.row-title {
|
||||
color: #cdd6f4;
|
||||
font-weight: 750;
|
||||
}
|
||||
|
||||
.service-card {
|
||||
min-width: 250px;
|
||||
min-height: 112px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.actions {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.button,
|
||||
.mini-button,
|
||||
.icon-button {
|
||||
padding: 8px 10px;
|
||||
border-radius: 8px;
|
||||
background: rgba(40, 40, 55, 0.82);
|
||||
color: #cdd6f4;
|
||||
}
|
||||
|
||||
.mini-button {
|
||||
padding: 6px 8px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.button:hover,
|
||||
.button:focus,
|
||||
.mini-button:hover,
|
||||
.mini-button:focus,
|
||||
.icon-button:hover,
|
||||
.icon-button:focus {
|
||||
background: rgba(0, 255, 156, 0.22);
|
||||
}
|
||||
|
||||
.primary {
|
||||
background: rgba(0, 255, 156, 0.24);
|
||||
color: #00ff9c;
|
||||
}
|
||||
|
||||
.danger {
|
||||
color: #f38ba8;
|
||||
}
|
||||
|
||||
.close {
|
||||
color: #f38ba8;
|
||||
}
|
||||
|
||||
.icon-button {
|
||||
min-width: 34px;
|
||||
min-height: 34px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: #f38ba8;
|
||||
}
|
||||
1124
config/hypr/ags/homelab.tsx
Normal file
1124
config/hypr/ags/homelab.tsx
Normal file
File diff suppressed because it is too large
Load Diff
115
config/hypr/ags/switcher.css
Normal file
115
config/hypr/ags/switcher.css
Normal file
@@ -0,0 +1,115 @@
|
||||
* {
|
||||
all: unset;
|
||||
font-family: "JetBrainsMono Nerd Font", "Noto Sans", sans-serif;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.switcher-window {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.switcher {
|
||||
min-width: 680px;
|
||||
padding: 18px;
|
||||
border: 1px solid alpha(@ags_fg, 0.18);
|
||||
border-radius: 16px;
|
||||
background: @ags_bg;
|
||||
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.45);
|
||||
color: @ags_fg;
|
||||
}
|
||||
|
||||
.header {
|
||||
min-height: 34px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.list-scroll {
|
||||
min-height: 130px;
|
||||
}
|
||||
|
||||
.item {
|
||||
padding: 10px;
|
||||
border: 1px solid alpha(@ags_fg, 0.10);
|
||||
border-radius: 10px;
|
||||
background: alpha(@ags_panel, 0.54);
|
||||
}
|
||||
|
||||
.item-row {
|
||||
min-height: 78px;
|
||||
}
|
||||
|
||||
.item:hover,
|
||||
.item:focus {
|
||||
border-color: alpha(@ags_accent, 0.72);
|
||||
background: alpha(@ags_panel, 0.82);
|
||||
}
|
||||
|
||||
.item.active {
|
||||
border-color: alpha(@ags_accent_2, 0.85);
|
||||
}
|
||||
|
||||
.preview {
|
||||
min-width: 96px;
|
||||
min-height: 56px;
|
||||
border-radius: 8px;
|
||||
background-color: alpha(@ags_panel, 0.80);
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.preview-empty {
|
||||
color: @ags_accent_2;
|
||||
}
|
||||
|
||||
.item-title {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.item-subtitle {
|
||||
margin-top: 4px;
|
||||
color: @ags_muted;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.swatches {
|
||||
min-width: 86px;
|
||||
}
|
||||
|
||||
.swatch {
|
||||
min-width: 18px;
|
||||
min-height: 18px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.16);
|
||||
}
|
||||
|
||||
.icon-button {
|
||||
min-width: 34px;
|
||||
min-height: 34px;
|
||||
border-radius: 8px;
|
||||
color: @ags_fg;
|
||||
background: alpha(@ags_panel, 0.62);
|
||||
}
|
||||
|
||||
.preview-button {
|
||||
min-width: 44px;
|
||||
min-height: 78px;
|
||||
}
|
||||
|
||||
.icon-button:hover,
|
||||
.icon-button:focus {
|
||||
background: alpha(@ags_accent, 0.28);
|
||||
}
|
||||
|
||||
.close {
|
||||
color: @ags_accent;
|
||||
}
|
||||
|
||||
.empty {
|
||||
min-height: 150px;
|
||||
color: @ags_muted;
|
||||
}
|
||||
321
config/hypr/ags/switcher.tsx
Normal file
321
config/hypr/ags/switcher.tsx
Normal file
@@ -0,0 +1,321 @@
|
||||
import app from "ags/gtk4/app";
|
||||
import { Astal, Gtk } from "ags/gtk4";
|
||||
import { readFile } from "ags/file";
|
||||
import { execAsync } from "ags/process";
|
||||
import css from "./switcher.css";
|
||||
import GLib from "gi://GLib";
|
||||
|
||||
type SwitcherItem = {
|
||||
type: "theme" | "wallpaper";
|
||||
path: string;
|
||||
name: string;
|
||||
icon?: string;
|
||||
wallpaper: string;
|
||||
active?: boolean;
|
||||
accent?: string;
|
||||
accent2?: string;
|
||||
muted?: string;
|
||||
};
|
||||
|
||||
const HYPR_DIR = GLib.getenv("HYPR_DIR") || "/home/pascal/.config/hypr";
|
||||
const SCRIPT_DIR = `${HYPR_DIR}/Scripts`;
|
||||
const THEME_DIR = GLib.getenv("HYPR_SWITCHER_THEME_DIR") || `${HYPR_DIR}/Themes`;
|
||||
const WALLPAPER_DIR = GLib.getenv("HYPR_SWITCHER_WALLPAPER_DIR")
|
||||
|| GLib.getenv("WALLPAPER_DIR")
|
||||
|| `${GLib.get_home_dir()}/Bilder/Wallpaper`;
|
||||
const CURRENT_WALLPAPER = `${HYPR_DIR}/current-wallpaper`;
|
||||
const IMAGE_EXTENSIONS = [".jpg", ".jpeg", ".png", ".webp", ".gif"];
|
||||
|
||||
type UiTheme = {
|
||||
accent: string;
|
||||
accent2: string;
|
||||
background: string;
|
||||
backgroundSoft: string;
|
||||
foreground: string;
|
||||
muted: string;
|
||||
panelHex: string;
|
||||
};
|
||||
|
||||
function notify(message: string) {
|
||||
execAsync(["notify-send", "AGS Switcher", message]).catch(console.error);
|
||||
}
|
||||
|
||||
function fileExists(path: string) {
|
||||
return GLib.file_test(path, GLib.FileTest.EXISTS);
|
||||
}
|
||||
|
||||
function readText(path: string) {
|
||||
try {
|
||||
return readFile(path);
|
||||
} catch {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
function listFiles(dir: string, predicate: (path: string, name: string) => boolean) {
|
||||
try {
|
||||
const directory = GLib.Dir.open(dir, 0);
|
||||
const files: string[] = [];
|
||||
let name = directory.read_name();
|
||||
|
||||
while (name !== null) {
|
||||
const path = `${dir}/${name}`;
|
||||
if (predicate(path, name)) {
|
||||
files.push(path);
|
||||
}
|
||||
name = directory.read_name();
|
||||
}
|
||||
|
||||
return files.sort((a, b) => a.localeCompare(b));
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
function shellValue(contents: string, key: string) {
|
||||
const regex = new RegExp(`^${key}=(["']?)(.*?)\\1$`, "m");
|
||||
return contents.match(regex)?.[2] || "";
|
||||
}
|
||||
|
||||
function activeTheme(): UiTheme {
|
||||
const activeWallpaper = currentWallpaper();
|
||||
const fallback = {
|
||||
accent: "#00ff9c",
|
||||
accent2: "#00cc88",
|
||||
background: "rgba(20, 20, 30, 0.95)",
|
||||
backgroundSoft: "rgba(40, 40, 55, 0.8)",
|
||||
foreground: "#cdd6f4",
|
||||
muted: "#cccccc",
|
||||
panelHex: "#282837",
|
||||
};
|
||||
|
||||
const themeFile = listFiles(THEME_DIR, (_path, name) => name.endsWith(".theme"))
|
||||
.find(path => shellValue(readText(path), "WALLPAPER") === activeWallpaper);
|
||||
|
||||
if (!themeFile) {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
const contents = readText(themeFile);
|
||||
return {
|
||||
accent: shellValue(contents, "ACCENT") || fallback.accent,
|
||||
accent2: shellValue(contents, "ACCENT_2") || fallback.accent2,
|
||||
background: shellValue(contents, "BACKGROUND") || fallback.background,
|
||||
backgroundSoft: shellValue(contents, "BACKGROUND_SOFT") || fallback.backgroundSoft,
|
||||
foreground: shellValue(contents, "FOREGROUND") || fallback.foreground,
|
||||
muted: shellValue(contents, "MUTED") || fallback.muted,
|
||||
panelHex: shellValue(contents, "PANEL_HEX") || fallback.panelHex,
|
||||
};
|
||||
}
|
||||
|
||||
function themeCss(theme: UiTheme) {
|
||||
return [
|
||||
`@define-color ags_accent ${theme.accent};`,
|
||||
`@define-color ags_accent_2 ${theme.accent2};`,
|
||||
`@define-color ags_bg ${theme.background};`,
|
||||
`@define-color ags_bg_soft ${theme.backgroundSoft};`,
|
||||
`@define-color ags_fg ${theme.foreground};`,
|
||||
`@define-color ags_muted ${theme.muted};`,
|
||||
`@define-color ags_panel ${theme.panelHex};`,
|
||||
css,
|
||||
].join("\n");
|
||||
}
|
||||
|
||||
function basename(path: string) {
|
||||
return GLib.path_get_basename(path);
|
||||
}
|
||||
|
||||
function currentWallpaper() {
|
||||
return readText(CURRENT_WALLPAPER).trim();
|
||||
}
|
||||
|
||||
function loadThemes(): SwitcherItem[] {
|
||||
return listFiles(THEME_DIR, (_path, name) => name.endsWith(".theme"))
|
||||
.map(path => {
|
||||
const contents = readText(path);
|
||||
return {
|
||||
type: "theme",
|
||||
path,
|
||||
name: shellValue(contents, "NAME") || basename(path).replace(/\.theme$/, ""),
|
||||
icon: shellValue(contents, "ICON") || "",
|
||||
wallpaper: shellValue(contents, "WALLPAPER"),
|
||||
accent: shellValue(contents, "ACCENT") || "#f38ba8",
|
||||
accent2: shellValue(contents, "ACCENT_2") || "#cba6f7",
|
||||
muted: shellValue(contents, "MUTED") || "#cdd6f4",
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function loadWallpapers(): SwitcherItem[] {
|
||||
const active = currentWallpaper();
|
||||
|
||||
return listFiles(WALLPAPER_DIR, (_path, name) =>
|
||||
IMAGE_EXTENSIONS.some(ext => name.toLowerCase().endsWith(ext)),
|
||||
).map(path => ({
|
||||
type: "wallpaper",
|
||||
path,
|
||||
name: basename(path),
|
||||
wallpaper: path,
|
||||
active: path === active,
|
||||
}));
|
||||
}
|
||||
|
||||
function applyItem(item: SwitcherItem) {
|
||||
const command = item.type === "theme"
|
||||
? [`${SCRIPT_DIR}/theme-menu.sh`, "--apply", item.path]
|
||||
: [`${SCRIPT_DIR}/wallpaper-menu.sh`, "--apply", item.path];
|
||||
|
||||
execAsync(command)
|
||||
.then(() => app.quit())
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
notify(`${item.name} konnte nicht angewendet werden.`);
|
||||
});
|
||||
}
|
||||
|
||||
function previewWallpaper(item: SwitcherItem) {
|
||||
execAsync([`${SCRIPT_DIR}/wallpaper-menu.sh`, "--preview", item.path]).catch(error => {
|
||||
console.error(error);
|
||||
notify(`${item.name} konnte nicht geoeffnet werden.`);
|
||||
});
|
||||
}
|
||||
|
||||
function Preview({ item }: { item: SwitcherItem }) {
|
||||
const hasImage = item.wallpaper && fileExists(item.wallpaper);
|
||||
|
||||
return (
|
||||
<box class={hasImage ? "preview" : "preview preview-empty"}>
|
||||
{hasImage
|
||||
? <image class="preview-image" file={item.wallpaper} pixelSize={92} />
|
||||
: <label label="" />}
|
||||
</box>
|
||||
);
|
||||
}
|
||||
|
||||
function Swatches({ item }: { item: SwitcherItem }) {
|
||||
return (
|
||||
<box class="swatches" spacing={6}>
|
||||
{[item.accent, item.accent2, item.muted].map(color => (
|
||||
<box class="swatch" css={`background: ${color};`} />
|
||||
))}
|
||||
</box>
|
||||
);
|
||||
}
|
||||
|
||||
function ItemButton({ item }: { item: SwitcherItem }) {
|
||||
const content = (
|
||||
<box spacing={14}>
|
||||
<Preview item={item} />
|
||||
<box
|
||||
orientation={Gtk.Orientation.VERTICAL}
|
||||
hexpand
|
||||
valign={Gtk.Align.CENTER}
|
||||
>
|
||||
<label
|
||||
class="item-title"
|
||||
xalign={0}
|
||||
ellipsize={3}
|
||||
label={`${item.icon || ""} ${item.name}`}
|
||||
/>
|
||||
<label
|
||||
class="item-subtitle"
|
||||
xalign={0}
|
||||
ellipsize={3}
|
||||
label={item.type === "theme"
|
||||
? basename(item.path)
|
||||
: item.active ? "Aktuelles Wallpaper" : item.path}
|
||||
/>
|
||||
</box>
|
||||
{item.type === "theme" ? <Swatches item={item} /> : <box />}
|
||||
</box>
|
||||
);
|
||||
|
||||
const applyButton = (
|
||||
<button
|
||||
class={`item ${item.active ? "active" : ""}`}
|
||||
hexpand
|
||||
onClicked={() => applyItem(item)}
|
||||
>
|
||||
{content}
|
||||
</button>
|
||||
);
|
||||
|
||||
if (item.type === "theme") {
|
||||
return applyButton;
|
||||
}
|
||||
|
||||
return (
|
||||
<box class="item-row" spacing={8}>
|
||||
{applyButton}
|
||||
<button
|
||||
class="icon-button preview-button"
|
||||
tooltipText="Vorschau"
|
||||
onClicked={() => previewWallpaper(item)}
|
||||
>
|
||||
<label label="" />
|
||||
</button>
|
||||
</box>
|
||||
);
|
||||
}
|
||||
|
||||
function SwitcherWindow(mode: string) {
|
||||
const isTheme = mode === "theme" || mode === "themes";
|
||||
const items = isTheme ? loadThemes() : loadWallpapers();
|
||||
const title = isTheme ? "Theme wechseln" : "Wallpaper wechseln";
|
||||
const empty = isTheme ? `Keine Themes in ${THEME_DIR}` : `Keine Bilder in ${WALLPAPER_DIR}`;
|
||||
|
||||
return (
|
||||
<window
|
||||
name="ags-hypr-switcher"
|
||||
namespace="ags-hypr-switcher"
|
||||
class="switcher-window"
|
||||
visible
|
||||
keymode={Astal.Keymode.EXCLUSIVE}
|
||||
anchor={Astal.WindowAnchor.TOP}
|
||||
application={app}
|
||||
>
|
||||
<box
|
||||
class="switcher"
|
||||
orientation={Gtk.Orientation.VERTICAL}
|
||||
spacing={16}
|
||||
marginTop={70}
|
||||
>
|
||||
<box class="header">
|
||||
<label class="title" hexpand xalign={0} label={title} />
|
||||
<button
|
||||
class="icon-button close"
|
||||
tooltipText="Schliessen"
|
||||
onClicked={() => app.quit()}
|
||||
>
|
||||
<label label="" />
|
||||
</button>
|
||||
</box>
|
||||
{items.length > 0
|
||||
? (
|
||||
<scrolledwindow
|
||||
class="list-scroll"
|
||||
hscrollbarPolicy={Gtk.PolicyType.NEVER}
|
||||
maxContentHeight={600}
|
||||
>
|
||||
<box orientation={Gtk.Orientation.VERTICAL} spacing={10}>
|
||||
{items.map(item => <ItemButton item={item} />)}
|
||||
</box>
|
||||
</scrolledwindow>
|
||||
)
|
||||
: (
|
||||
<box class="empty">
|
||||
<label label={empty} />
|
||||
</box>
|
||||
)}
|
||||
</box>
|
||||
</window>
|
||||
);
|
||||
}
|
||||
|
||||
app.start({
|
||||
css: themeCss(activeTheme()),
|
||||
instanceName: "hypr-switcher",
|
||||
main(mode = "wallpaper") {
|
||||
SwitcherWindow(mode);
|
||||
},
|
||||
});
|
||||
5
config/hypr/current-theme.conf
Normal file
5
config/hypr/current-theme.conf
Normal file
@@ -0,0 +1,5 @@
|
||||
# Generated by ~/.config/hypr/Scripts/theme-menu.sh
|
||||
general {
|
||||
col.active_border = rgba(00ff9cee) rgba(00cc88ee) 45deg
|
||||
col.inactive_border = rgba(2a2a2aaa)
|
||||
}
|
||||
1
config/hypr/current-wallpaper
Normal file
1
config/hypr/current-wallpaper
Normal file
@@ -0,0 +1 @@
|
||||
/home/pascal/Bilder/Wallpaper/forest.jpg
|
||||
308
config/hypr/hyprland.conf
Normal file
308
config/hypr/hyprland.conf
Normal file
@@ -0,0 +1,308 @@
|
||||
# #######################################################################################
|
||||
# AUTOGENERATED HYPRLAND CONFIG.
|
||||
# EDIT THIS CONFIG ACCORDING TO THE WIKI INSTRUCTIONS.
|
||||
# #######################################################################################
|
||||
|
||||
|
||||
|
||||
# This is an example Hyprland config file.
|
||||
# Refer to the wiki for more information.
|
||||
# https://wiki.hypr.land/Configuring/
|
||||
|
||||
# Please note not all available settings / options are set here.
|
||||
# For a full list, see the wiki
|
||||
|
||||
# You can split this configuration into multiple files
|
||||
# Create your files separately and then link them to this file like this:
|
||||
# source = ~/.config/hypr/myColors.conf
|
||||
|
||||
|
||||
################
|
||||
### MONITORS ###
|
||||
################
|
||||
|
||||
# See https://wiki.hypr.land/Configuring/Monitors/
|
||||
monitor=,preferred,auto,1
|
||||
|
||||
|
||||
###################
|
||||
### MY PROGRAMS ###
|
||||
###################
|
||||
|
||||
# See https://wiki.hypr.land/Configuring/Keywords/
|
||||
|
||||
# Set programs that you use
|
||||
$terminal = kitty
|
||||
$fileManager = nautilus
|
||||
$menu = wofi
|
||||
|
||||
|
||||
#################
|
||||
### AUTOSTART ###
|
||||
#################
|
||||
|
||||
# Autostart necessary processes (like notifications daemons, status bars, etc.)
|
||||
# Or execute your favorite apps at launch like this:
|
||||
|
||||
exec-once = sh -c 'if command -v awww-daemon >/dev/null 2>&1; then awww-daemon; elif command -v swww-daemon >/dev/null 2>&1; then swww-daemon; else hyprpaper; fi'
|
||||
exec-once = waybar
|
||||
exec-once = swaync
|
||||
|
||||
#############################
|
||||
### ENVIRONMENT VARIABLES ###
|
||||
#############################
|
||||
|
||||
# See https://wiki.hypr.land/Configuring/Environment-variables/
|
||||
|
||||
env = XCURSOR_SIZE,24
|
||||
env = HYPRCURSOR_SIZE,24
|
||||
env = QT_QPA_PLATFORMTHEME,qt6ct
|
||||
env = QT_STYLE_OVERRIDE,Fusion
|
||||
|
||||
# https://wiki.hypr.land/Configuring/Variables/#general
|
||||
general {
|
||||
gaps_in = 6
|
||||
gaps_out = 25
|
||||
|
||||
border_size = 2
|
||||
|
||||
col.active_border = rgba(00ff9cee) rgba(00cc88ee) 45deg
|
||||
col.inactive_border = rgba(2a2a2aaa)
|
||||
|
||||
resize_on_border = false
|
||||
allow_tearing = false
|
||||
|
||||
layout = dwindle
|
||||
}
|
||||
|
||||
source = ~/.config/hypr/current-theme.conf
|
||||
|
||||
# https://wiki.hypr.land/Configuring/Variables/#decoration
|
||||
decoration {
|
||||
rounding = 14
|
||||
rounding_power = 3
|
||||
|
||||
active_opacity = 0.90
|
||||
inactive_opacity = 0.75
|
||||
|
||||
shadow {
|
||||
enabled = true
|
||||
range = 20
|
||||
render_power = 4
|
||||
color = rgba(000000aa)
|
||||
}
|
||||
|
||||
blur {
|
||||
enabled = true
|
||||
size = 6
|
||||
passes = 2
|
||||
|
||||
vibrancy = 0.25
|
||||
vibrancy_darkness = 0.3
|
||||
}
|
||||
}
|
||||
|
||||
# https://wiki.hypr.land/Configuring/Variables/#animations
|
||||
animations {
|
||||
enabled = yes
|
||||
|
||||
# Curves
|
||||
bezier = smoothOut, 0.22, 1, 0.36, 1
|
||||
bezier = smoothIn, 0.64, 0, 0.78, 0
|
||||
bezier = smoothInOut, 0.83, 0, 0.17, 1
|
||||
bezier = soft, 0.25, 0.1, 0.25, 1
|
||||
bezier = quick, 0.3, 0, 0.1, 1
|
||||
|
||||
# Animations
|
||||
animation = global, 1, 8, soft
|
||||
|
||||
animation = border, 1, 5, smoothOut
|
||||
animation = fade, 1, 5, soft
|
||||
|
||||
animation = windows, 1, 6, smoothOut
|
||||
animation = windowsIn, 1, 6, smoothOut, popin 85%
|
||||
animation = windowsOut, 1, 5, smoothIn, popin 85%
|
||||
|
||||
animation = layers, 1, 5, smoothOut
|
||||
animation = layersIn, 1, 5, smoothOut, fade
|
||||
animation = layersOut, 1, 4, smoothIn, fade
|
||||
|
||||
animation = fadeIn, 1, 4, soft
|
||||
animation = fadeOut, 1, 4, soft
|
||||
animation = fadeLayersIn, 1, 4, soft
|
||||
animation = fadeLayersOut, 1, 4, soft
|
||||
|
||||
animation = workspaces, 1, 5, smoothInOut, slide
|
||||
animation = workspacesIn, 1, 5, smoothInOut, slide
|
||||
animation = workspacesOut, 1, 5, smoothInOut, slide
|
||||
|
||||
animation = zoomFactor, 1, 6, quick
|
||||
}
|
||||
|
||||
# See https://wiki.hypr.land/Configuring/Dwindle-Layout/ for more
|
||||
dwindle {
|
||||
pseudotile = true # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
|
||||
preserve_split = true # You probably want this
|
||||
}
|
||||
|
||||
# See https://wiki.hypr.land/Configuring/Master-Layout/ for more
|
||||
master {
|
||||
new_status = master
|
||||
}
|
||||
|
||||
# https://wiki.hypr.land/Configuring/Variables/#misc
|
||||
misc {
|
||||
force_default_wallpaper = -1 # Set to 0 or 1 to disable the anime mascot wallpapers
|
||||
disable_hyprland_logo = false # If true disables the random hyprland logo / anime girl background. :(
|
||||
}
|
||||
|
||||
|
||||
#############
|
||||
### INPUT ###
|
||||
#############
|
||||
|
||||
# https://wiki.hypr.land/Configuring/Variables/#input
|
||||
input {
|
||||
kb_layout = de
|
||||
kb_variant =
|
||||
kb_model =
|
||||
kb_options =
|
||||
kb_rules =
|
||||
|
||||
follow_mouse = 1
|
||||
|
||||
sensitivity = 0 # -1.0 - 1.0, 0 means no modification.
|
||||
|
||||
touchpad {
|
||||
natural_scroll = false
|
||||
}
|
||||
}
|
||||
|
||||
# See https://wiki.hypr.land/Configuring/Gestures
|
||||
gesture = 3, horizontal, workspace
|
||||
|
||||
# Example per-device config
|
||||
# See https://wiki.hypr.land/Configuring/Keywords/#per-device-input-configs for more
|
||||
device {
|
||||
name = epic-mouse-v1
|
||||
sensitivity = -0.5
|
||||
}
|
||||
|
||||
|
||||
###################
|
||||
### KEYBINDINGS ###
|
||||
###################
|
||||
|
||||
# See https://wiki.hypr.land/Configuring/Keywords/
|
||||
$mainMod = SUPER # Sets "Windows" key as main modifier
|
||||
|
||||
# Example binds, see https://wiki.hypr.land/Configuring/Binds/ for more
|
||||
bind = $mainMod, T, exec, $terminal
|
||||
bind = $mainMod, Q, killactive,
|
||||
bind = $mainMod, M, exec, ~/.config/hypr/Scripts/main-menu.sh
|
||||
bind = $mainMod, E, exec, $fileManager
|
||||
bind = $mainMod, N, exec, swaync-client -t
|
||||
bind = $mainMod, V, togglefloating,
|
||||
bind = $mainMod, R, exec, $menu
|
||||
bind = $mainMod, W, exec, ~/.config/hypr/Scripts/ags-switcher.sh wallpaper
|
||||
bind = $mainMod, P, exec, ~/.config/hypr/Scripts/power-menu.py
|
||||
bind = $mainMod, L, exec, hyprlock
|
||||
bind = $mainMod SHIFT, T, exec, ~/.config/hypr/Scripts/ags-switcher.sh theme
|
||||
bind = $mainMod SHIFT, S, exec, ~/.config/hypr/Scripts/screenshot-menu.sh annotate-region
|
||||
bind = $mainMod SHIFT, P, pseudo, # dwindle
|
||||
bind = $mainMod, J, layoutmsg, togglesplit # dwindle
|
||||
bind = $mainMod, SPACE, exec, ~/.config/hypr/Scripts/toggle-wofi.sh
|
||||
# Move focus with mainMod + arrow keys
|
||||
bind = $mainMod, left, movefocus, l
|
||||
bind = $mainMod, right, movefocus, r
|
||||
bind = $mainMod, up, movefocus, u
|
||||
bind = $mainMod, down, movefocus, d
|
||||
|
||||
# Switch existing workspaces with CTRL + mainMod + arrow keys
|
||||
bind = CTRL $mainMod, left, workspace, e-1
|
||||
bind = CTRL $mainMod, right, workspace, e+1
|
||||
|
||||
# Switch workspaces with mainMod + [0-9]
|
||||
bind = $mainMod, 1, workspace, 1
|
||||
bind = $mainMod, 2, workspace, 2
|
||||
bind = $mainMod, 3, workspace, 3
|
||||
bind = $mainMod, 4, workspace, 4
|
||||
bind = $mainMod, 5, workspace, 5
|
||||
bind = $mainMod, 6, workspace, 6
|
||||
bind = $mainMod, 7, workspace, 7
|
||||
bind = $mainMod, 8, workspace, 8
|
||||
bind = $mainMod, 9, workspace, 9
|
||||
bind = $mainMod, 0, workspace, 10
|
||||
|
||||
# Move active window to a workspace with mainMod + SHIFT + [0-9]
|
||||
bind = $mainMod SHIFT, 1, movetoworkspace, 1
|
||||
bind = $mainMod SHIFT, 2, movetoworkspace, 2
|
||||
bind = $mainMod SHIFT, 3, movetoworkspace, 3
|
||||
bind = $mainMod SHIFT, 4, movetoworkspace, 4
|
||||
bind = $mainMod SHIFT, 5, movetoworkspace, 5
|
||||
bind = $mainMod SHIFT, 6, movetoworkspace, 6
|
||||
bind = $mainMod SHIFT, 7, movetoworkspace, 7
|
||||
bind = $mainMod SHIFT, 8, movetoworkspace, 8
|
||||
bind = $mainMod SHIFT, 9, movetoworkspace, 9
|
||||
bind = $mainMod SHIFT, 0, movetoworkspace, 10
|
||||
|
||||
# Example special workspace (scratchpad)
|
||||
bind = $mainMod, S, togglespecialworkspace, magic
|
||||
bind = CTRL $mainMod, S, movetoworkspace, special:magic
|
||||
|
||||
# Scroll through existing workspaces with mainMod + scroll
|
||||
bind = $mainMod, mouse_down, workspace, e+1
|
||||
bind = $mainMod, mouse_up, workspace, e-1
|
||||
|
||||
# Move/resize windows with mainMod + LMB/RMB and dragging
|
||||
bindm = $mainMod, mouse:272, movewindow
|
||||
bindm = $mainMod, mouse:273, resizewindow
|
||||
|
||||
# Laptop multimedia keys for volume and LCD brightness
|
||||
bindel = ,XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+
|
||||
bindel = ,XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-
|
||||
bindel = ,XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
|
||||
bindel = ,XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle
|
||||
bindel = ,XF86MonBrightnessUp, exec, brightnessctl -e4 -n2 set 5%+
|
||||
bindel = ,XF86MonBrightnessDown, exec, brightnessctl -e4 -n2 set 5%-
|
||||
|
||||
# Requires playerctl
|
||||
bindl = , XF86AudioNext, exec, playerctl next
|
||||
bindl = , XF86AudioPause, exec, playerctl play-pause
|
||||
bindl = , XF86AudioPlay, exec, playerctl play-pause
|
||||
bindl = , XF86AudioPrev, exec, playerctl previous
|
||||
|
||||
##############################
|
||||
### WINDOWS AND WORKSPACES ###
|
||||
##############################
|
||||
|
||||
windowrule {
|
||||
# Ignore maximize requests from all apps. You'll probably like this.
|
||||
name = suppress-maximize-events
|
||||
match:class = .*
|
||||
|
||||
suppress_event = maximize
|
||||
}
|
||||
|
||||
windowrule {
|
||||
# Fix some dragging issues with XWayland
|
||||
name = fix-xwayland-drags
|
||||
match:class = ^$
|
||||
match:title = ^$
|
||||
match:xwayland = true
|
||||
match:float = true
|
||||
match:fullscreen = false
|
||||
match:pin = false
|
||||
|
||||
no_focus = true
|
||||
}
|
||||
|
||||
# Hyprland-run windowrule
|
||||
windowrule {
|
||||
name = move-hyprland-run
|
||||
|
||||
match:class = hyprland-run
|
||||
|
||||
move = 20 monitor_h-120
|
||||
float = yes
|
||||
}
|
||||
98
config/hypr/hyprlock.conf
Normal file
98
config/hypr/hyprlock.conf
Normal file
@@ -0,0 +1,98 @@
|
||||
# Generated by ~/.config/hypr/Scripts/theme-menu.sh
|
||||
|
||||
auth {
|
||||
pam:enabled = true
|
||||
pam:module = hyprlock
|
||||
|
||||
fingerprint:enabled = true
|
||||
fingerprint:ready_message = Finger auflegen zum Entsperren
|
||||
fingerprint:present_message = Fingerabdruck wird gelesen...
|
||||
fingerprint:retry_delay = 250
|
||||
}
|
||||
|
||||
general {
|
||||
disable_loading_bar = true
|
||||
hide_cursor = true
|
||||
grace = 0
|
||||
ignore_empty_input = true
|
||||
}
|
||||
|
||||
background {
|
||||
monitor =
|
||||
path = /home/pascal/Bilder/Wallpaper/forest.jpg
|
||||
blur_passes = 3
|
||||
blur_size = 8
|
||||
noise = 0.011
|
||||
contrast = 1.05
|
||||
brightness = 0.72
|
||||
vibrancy = 0.18
|
||||
vibrancy_darkness = 0.25
|
||||
}
|
||||
|
||||
label {
|
||||
monitor =
|
||||
text = Forest Neon
|
||||
color = rgba(0,204,136, 0.90)
|
||||
font_size = 22
|
||||
font_family = JetBrainsMono Nerd Font
|
||||
position = 0, 260
|
||||
halign = center
|
||||
valign = center
|
||||
}
|
||||
|
||||
label {
|
||||
monitor =
|
||||
text = cmd[update:1000] date +"%H:%M"
|
||||
color = rgba(0,255,156, 0.96)
|
||||
font_size = 92
|
||||
font_family = JetBrainsMono Nerd Font
|
||||
position = 0, 165
|
||||
halign = center
|
||||
valign = center
|
||||
}
|
||||
|
||||
label {
|
||||
monitor =
|
||||
text = cmd[update:60000] date +"%A, %d. %B"
|
||||
color = rgba(205,214,244, 0.82)
|
||||
font_size = 22
|
||||
font_family = JetBrainsMono Nerd Font
|
||||
position = 0, 92
|
||||
halign = center
|
||||
valign = center
|
||||
}
|
||||
|
||||
input-field {
|
||||
monitor =
|
||||
size = 390, 62
|
||||
outline_thickness = 2
|
||||
dots_size = 0.24
|
||||
dots_spacing = 0.28
|
||||
dots_center = true
|
||||
fade_on_empty = false
|
||||
rounding = 16
|
||||
|
||||
outer_color = rgba(0,255,156, 0.72)
|
||||
inner_color = rgba(20,20,30, 0.76)
|
||||
font_color = rgba(205,214,244, 0.92)
|
||||
placeholder_text = <i>Passwort oder Fingerprint</i>
|
||||
|
||||
check_color = rgba(0,204,136, 0.88)
|
||||
fail_color = rgba(243,139,168, 0.95)
|
||||
capslock_color = rgba(249,226,175, 0.95)
|
||||
|
||||
position = 0, -20
|
||||
halign = center
|
||||
valign = center
|
||||
}
|
||||
|
||||
label {
|
||||
monitor =
|
||||
text = cmd[update:1000] echo " pascal@PDEV-Yoga"
|
||||
color = rgba(204,204,204, 0.70)
|
||||
font_size = 16
|
||||
font_family = JetBrainsMono Nerd Font
|
||||
position = 0, -92
|
||||
halign = center
|
||||
valign = center
|
||||
}
|
||||
5
config/hypr/hyprpaper.conf
Normal file
5
config/hypr/hyprpaper.conf
Normal file
@@ -0,0 +1,5 @@
|
||||
wallpaper {
|
||||
monitor =
|
||||
path = /home/pascal/Bilder/Wallpaper/forest.jpg
|
||||
fit_mode = cover
|
||||
}
|
||||
279
config/hypr/sddm-theme/pascal-hypr/Main.qml
Normal file
279
config/hypr/sddm-theme/pascal-hypr/Main.qml
Normal file
@@ -0,0 +1,279 @@
|
||||
import QtQuick 2.0
|
||||
import SddmComponents 2.0
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
width: 1920
|
||||
height: 1080
|
||||
color: config.backgroundColor || "#18141f"
|
||||
|
||||
property int sessionIndex: session.index
|
||||
property color accent: config.accent || "#f38ba8"
|
||||
property color accent2: config.accent2 || "#cba6f7"
|
||||
property color backgroundColor: config.backgroundColor || "#18141f"
|
||||
property color panelColor: config.panelColor || "#313244"
|
||||
property color foreground: config.foreground || "#f5e0dc"
|
||||
property color muted: config.muted || "#cdd6f4"
|
||||
property color selectedText: config.selectedText || "#11111b"
|
||||
property string themeName: config.themeName || "Rose Night"
|
||||
|
||||
TextConstants { id: textConstants }
|
||||
|
||||
Connections {
|
||||
target: sddm
|
||||
|
||||
function onLoginSucceeded() {
|
||||
message.text = textConstants.loginSucceeded
|
||||
message.color = accent2
|
||||
}
|
||||
|
||||
function onLoginFailed() {
|
||||
password.text = ""
|
||||
message.text = textConstants.loginFailed
|
||||
message.color = "#f38ba8"
|
||||
}
|
||||
|
||||
function onInformationMessage(text) {
|
||||
message.text = text
|
||||
message.color = "#f38ba8"
|
||||
}
|
||||
}
|
||||
|
||||
Background {
|
||||
anchors.fill: parent
|
||||
source: config.background || ""
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
onStatusChanged: {
|
||||
if (status === Image.Error) {
|
||||
source = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "#000000"
|
||||
opacity: 0.42
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 0.0; color: Qt.rgba(0, 0, 0, 0.10) }
|
||||
GradientStop { position: 0.58; color: Qt.rgba(0, 0, 0, 0.38) }
|
||||
GradientStop { position: 1.0; color: Qt.rgba(0, 0, 0, 0.62) }
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
interval: 1000
|
||||
running: true
|
||||
repeat: true
|
||||
triggeredOnStart: true
|
||||
onTriggered: {
|
||||
clock.text = Qt.formatDateTime(new Date(), "HH:mm")
|
||||
date.text = Qt.formatDateTime(new Date(), "dddd, dd. MMMM yyyy")
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Math.max(42, parent.width * 0.055)
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Math.max(40, parent.height * 0.055)
|
||||
spacing: 2
|
||||
|
||||
Text {
|
||||
id: clock
|
||||
color: foreground
|
||||
font.pixelSize: Math.max(64, root.height * 0.105)
|
||||
font.weight: Font.Light
|
||||
}
|
||||
|
||||
Text {
|
||||
id: date
|
||||
color: muted
|
||||
opacity: 0.88
|
||||
font.pixelSize: Math.max(16, root.height * 0.023)
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: panel
|
||||
width: Math.min(430, root.width - 48)
|
||||
height: 430
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Math.max(28, parent.width * 0.075)
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
radius: 18
|
||||
color: panelColor
|
||||
opacity: 0.90
|
||||
border.color: accent
|
||||
border.width: 1
|
||||
|
||||
Rectangle {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
height: 4
|
||||
radius: 2
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 0.0; color: accent }
|
||||
GradientStop { position: 1.0; color: accent2 }
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 34
|
||||
spacing: 14
|
||||
|
||||
Text {
|
||||
text: sddm.hostName
|
||||
color: foreground
|
||||
font.pixelSize: 26
|
||||
font.bold: true
|
||||
elide: Text.ElideRight
|
||||
width: parent.width
|
||||
}
|
||||
|
||||
Text {
|
||||
text: themeName
|
||||
color: accent
|
||||
font.pixelSize: 14
|
||||
width: parent.width
|
||||
opacity: 0.92
|
||||
}
|
||||
|
||||
Item { width: 1; height: 10 }
|
||||
|
||||
Text {
|
||||
text: "Benutzer"
|
||||
color: muted
|
||||
font.pixelSize: 12
|
||||
opacity: 0.78
|
||||
}
|
||||
|
||||
TextBox {
|
||||
id: username
|
||||
width: parent.width
|
||||
height: 42
|
||||
text: userModel.lastUser
|
||||
color: backgroundColor
|
||||
borderColor: Qt.rgba(accent.r, accent.g, accent.b, 0.40)
|
||||
focusColor: accent
|
||||
hoverColor: accent2
|
||||
textColor: foreground
|
||||
radius: 10
|
||||
font.pixelSize: 16
|
||||
KeyNavigation.tab: password
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Passwort"
|
||||
color: muted
|
||||
font.pixelSize: 12
|
||||
opacity: 0.78
|
||||
}
|
||||
|
||||
PasswordBox {
|
||||
id: password
|
||||
width: parent.width
|
||||
height: 42
|
||||
color: backgroundColor
|
||||
borderColor: Qt.rgba(accent.r, accent.g, accent.b, 0.40)
|
||||
focusColor: accent
|
||||
hoverColor: accent2
|
||||
textColor: foreground
|
||||
radius: 10
|
||||
font.pixelSize: 16
|
||||
KeyNavigation.backtab: username
|
||||
KeyNavigation.tab: loginButton
|
||||
|
||||
Keys.onPressed: function(event) {
|
||||
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
|
||||
sddm.login(username.text, password.text, sessionIndex)
|
||||
event.accepted = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: session
|
||||
width: parent.width
|
||||
height: 36
|
||||
model: sessionModel
|
||||
index: sessionModel.lastIndex
|
||||
color: backgroundColor
|
||||
borderColor: Qt.rgba(accent.r, accent.g, accent.b, 0.40)
|
||||
focusColor: accent
|
||||
hoverColor: accent2
|
||||
menuColor: panelColor
|
||||
textColor: foreground
|
||||
arrowColor: accent
|
||||
arrowIcon: "angle-down.png"
|
||||
KeyNavigation.backtab: password
|
||||
KeyNavigation.tab: loginButton
|
||||
}
|
||||
|
||||
Button {
|
||||
id: loginButton
|
||||
width: parent.width
|
||||
height: 44
|
||||
text: "Anmelden"
|
||||
color: accent
|
||||
activeColor: accent2
|
||||
pressedColor: accent2
|
||||
disabledColor: muted
|
||||
borderColor: accent2
|
||||
textColor: selectedText
|
||||
font.pixelSize: 15
|
||||
onClicked: sddm.login(username.text, password.text, sessionIndex)
|
||||
KeyNavigation.backtab: session
|
||||
KeyNavigation.tab: shutdownButton
|
||||
}
|
||||
|
||||
Text {
|
||||
id: message
|
||||
width: parent.width
|
||||
color: muted
|
||||
text: ""
|
||||
font.pixelSize: 13
|
||||
wrapMode: Text.WordWrap
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Math.max(28, parent.width * 0.075)
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: Math.max(26, parent.height * 0.045)
|
||||
spacing: 10
|
||||
|
||||
Button {
|
||||
id: shutdownButton
|
||||
text: "Ausschalten"
|
||||
color: Qt.rgba(0, 0, 0, 0.42)
|
||||
activeColor: accent
|
||||
pressedColor: accent2
|
||||
borderColor: Qt.rgba(foreground.r, foreground.g, foreground.b, 0.35)
|
||||
textColor: foreground
|
||||
onClicked: sddm.powerOff()
|
||||
KeyNavigation.tab: rebootButton
|
||||
}
|
||||
|
||||
Button {
|
||||
id: rebootButton
|
||||
text: "Neustart"
|
||||
color: Qt.rgba(0, 0, 0, 0.42)
|
||||
activeColor: accent
|
||||
pressedColor: accent2
|
||||
borderColor: Qt.rgba(foreground.r, foreground.g, foreground.b, 0.35)
|
||||
textColor: foreground
|
||||
onClicked: sddm.reboot()
|
||||
KeyNavigation.backtab: shutdownButton
|
||||
}
|
||||
}
|
||||
}
|
||||
13
config/hypr/sddm-theme/pascal-hypr/metadata.desktop
Normal file
13
config/hypr/sddm-theme/pascal-hypr/metadata.desktop
Normal file
@@ -0,0 +1,13 @@
|
||||
[SddmGreeterTheme]
|
||||
Name=Pascal Hypr
|
||||
Description=Theme-aware SDDM login screen for Pascal's Hyprland setup
|
||||
Author=Pascal + Codex
|
||||
Copyright=2026
|
||||
License=MIT
|
||||
Type=sddm-theme
|
||||
Version=1.0
|
||||
MainScript=Main.qml
|
||||
ConfigFile=theme.conf
|
||||
Theme-Id=pascal-hypr
|
||||
Theme-API=2.0
|
||||
|
||||
11
config/hypr/sddm-theme/pascal-hypr/theme.conf
Normal file
11
config/hypr/sddm-theme/pascal-hypr/theme.conf
Normal file
@@ -0,0 +1,11 @@
|
||||
[General]
|
||||
background=/var/lib/pascal-sddm-theme/wallpaper.jpg
|
||||
themeName=Rose Night
|
||||
accent=#f38ba8
|
||||
accent2=#cba6f7
|
||||
backgroundColor=#18141f
|
||||
panelColor=#313244
|
||||
foreground=#f5e0dc
|
||||
muted=#cdd6f4
|
||||
selectedText=#11111b
|
||||
|
||||
6
config/hypr/sddm-theme/sddm.conf
Normal file
6
config/hypr/sddm-theme/sddm.conf
Normal file
@@ -0,0 +1,6 @@
|
||||
[Autologin]
|
||||
Session=hyprland
|
||||
|
||||
[Theme]
|
||||
Current=pascal-hypr
|
||||
|
||||
1
config/kitty/kitty.conf
Normal file
1
config/kitty/kitty.conf
Normal file
@@ -0,0 +1 @@
|
||||
background_opacity 0.70
|
||||
4
config/qt5ct/colors/ForestNeon.conf
Normal file
4
config/qt5ct/colors/ForestNeon.conf
Normal file
@@ -0,0 +1,4 @@
|
||||
[ColorScheme]
|
||||
active_colors=#ffcdd6f4, #ff282837, #ffffffff, #ffcccccc, #ff14141e, #ff282837, #ffcdd6f4, #ffffffff, #ffcdd6f4, #ff14141e, #ff14141e, #ff000000, #ff00ff9c, #ff000000, #ff00cc88, #fff38ba8, #ff282837, #ffcdd6f4, #ff282837, #ffcdd6f4, #80cccccc
|
||||
disabled_colors=#ffcccccc, #ff282837, #ffffffff, #ffcccccc, #ff14141e, #ff282837, #ffcccccc, #ffffffff, #ffcccccc, #ff14141e, #ff14141e, #ff000000, #ff282837, #ffcccccc, #ff00cc88, #fff38ba8, #ff282837, #ffcccccc, #ff282837, #ffcccccc, #80cccccc
|
||||
inactive_colors=#ffcdd6f4, #ff282837, #ffffffff, #ffcccccc, #ff14141e, #ff282837, #ffcdd6f4, #ffffffff, #ffcdd6f4, #ff14141e, #ff14141e, #ff000000, #ff00ff9c, #ff000000, #ff00cc88, #fff38ba8, #ff282837, #ffcdd6f4, #ff282837, #ffcdd6f4, #80cccccc
|
||||
4
config/qt5ct/colors/RoseNight.conf
Normal file
4
config/qt5ct/colors/RoseNight.conf
Normal file
@@ -0,0 +1,4 @@
|
||||
[ColorScheme]
|
||||
active_colors=#fff5e0dc, #ff313244, #ffffffff, #ffcdd6f4, #ff18141f, #ff313244, #fff5e0dc, #ffffffff, #fff5e0dc, #ff18141f, #ff18141f, #ff000000, #fff38ba8, #ff11111b, #ffcba6f7, #fff38ba8, #ff313244, #fff5e0dc, #ff313244, #fff5e0dc, #80cdd6f4
|
||||
disabled_colors=#ffcdd6f4, #ff313244, #ffffffff, #ffcdd6f4, #ff18141f, #ff313244, #ffcdd6f4, #ffffffff, #ffcdd6f4, #ff18141f, #ff18141f, #ff000000, #ff313244, #ffcdd6f4, #ffcba6f7, #fff38ba8, #ff313244, #ffcdd6f4, #ff313244, #ffcdd6f4, #80cdd6f4
|
||||
inactive_colors=#fff5e0dc, #ff313244, #ffffffff, #ffcdd6f4, #ff18141f, #ff313244, #fff5e0dc, #ffffffff, #fff5e0dc, #ff18141f, #ff18141f, #ff000000, #fff38ba8, #ff11111b, #ffcba6f7, #fff38ba8, #ff313244, #fff5e0dc, #ff313244, #fff5e0dc, #80cdd6f4
|
||||
28
config/qt5ct/qt5ct.conf
Normal file
28
config/qt5ct/qt5ct.conf
Normal file
@@ -0,0 +1,28 @@
|
||||
[Appearance]
|
||||
color_scheme_path=/home/pascal/.config/qt5ct/colors/ForestNeon.conf
|
||||
custom_palette=true
|
||||
icon_theme=Papirus-ForestNeon
|
||||
standard_dialogs=default
|
||||
style=Fusion
|
||||
|
||||
[Fonts]
|
||||
fixed="JetBrainsMono Nerd Font,10,-1,5,50,0,0,0,0,0"
|
||||
general="JetBrainsMono Nerd Font,10,-1,5,50,0,0,0,0,0"
|
||||
|
||||
[Interface]
|
||||
activate_item_on_single_click=1
|
||||
buttonbox_layout=0
|
||||
cursor_flash_time=1000
|
||||
dialog_buttons_have_icons=1
|
||||
double_click_interval=400
|
||||
gui_effects=@Invalid()
|
||||
keyboard_scheme=2
|
||||
menus_have_icons=true
|
||||
show_shortcuts_in_context_menus=true
|
||||
stylesheets=@Invalid()
|
||||
toolbutton_style=4
|
||||
underline_shortcut=1
|
||||
wheel_scroll_lines=3
|
||||
|
||||
[SettingsWindow]
|
||||
geometry=@ByteArray()
|
||||
4
config/qt6ct/colors/ForestNeon.conf
Normal file
4
config/qt6ct/colors/ForestNeon.conf
Normal file
@@ -0,0 +1,4 @@
|
||||
[ColorScheme]
|
||||
active_colors=#ffcdd6f4, #ff282837, #ffffffff, #ffcccccc, #ff14141e, #ff282837, #ffcdd6f4, #ffffffff, #ffcdd6f4, #ff14141e, #ff14141e, #ff000000, #ff00ff9c, #ff000000, #ff00cc88, #fff38ba8, #ff282837, #ffcdd6f4, #ff282837, #ffcdd6f4, #80cccccc
|
||||
disabled_colors=#ffcccccc, #ff282837, #ffffffff, #ffcccccc, #ff14141e, #ff282837, #ffcccccc, #ffffffff, #ffcccccc, #ff14141e, #ff14141e, #ff000000, #ff282837, #ffcccccc, #ff00cc88, #fff38ba8, #ff282837, #ffcccccc, #ff282837, #ffcccccc, #80cccccc
|
||||
inactive_colors=#ffcdd6f4, #ff282837, #ffffffff, #ffcccccc, #ff14141e, #ff282837, #ffcdd6f4, #ffffffff, #ffcdd6f4, #ff14141e, #ff14141e, #ff000000, #ff00ff9c, #ff000000, #ff00cc88, #fff38ba8, #ff282837, #ffcdd6f4, #ff282837, #ffcdd6f4, #80cccccc
|
||||
4
config/qt6ct/colors/RoseNight.conf
Normal file
4
config/qt6ct/colors/RoseNight.conf
Normal file
@@ -0,0 +1,4 @@
|
||||
[ColorScheme]
|
||||
active_colors=#fff5e0dc, #ff313244, #ffffffff, #ffcdd6f4, #ff18141f, #ff313244, #fff5e0dc, #ffffffff, #fff5e0dc, #ff18141f, #ff18141f, #ff000000, #fff38ba8, #ff11111b, #ffcba6f7, #fff38ba8, #ff313244, #fff5e0dc, #ff313244, #fff5e0dc, #80cdd6f4
|
||||
disabled_colors=#ffcdd6f4, #ff313244, #ffffffff, #ffcdd6f4, #ff18141f, #ff313244, #ffcdd6f4, #ffffffff, #ffcdd6f4, #ff18141f, #ff18141f, #ff000000, #ff313244, #ffcdd6f4, #ffcba6f7, #fff38ba8, #ff313244, #ffcdd6f4, #ff313244, #ffcdd6f4, #80cdd6f4
|
||||
inactive_colors=#fff5e0dc, #ff313244, #ffffffff, #ffcdd6f4, #ff18141f, #ff313244, #fff5e0dc, #ffffffff, #fff5e0dc, #ff18141f, #ff18141f, #ff000000, #fff38ba8, #ff11111b, #ffcba6f7, #fff38ba8, #ff313244, #fff5e0dc, #ff313244, #fff5e0dc, #80cdd6f4
|
||||
28
config/qt6ct/qt6ct.conf
Normal file
28
config/qt6ct/qt6ct.conf
Normal file
@@ -0,0 +1,28 @@
|
||||
[Appearance]
|
||||
color_scheme_path=/home/pascal/.config/qt6ct/colors/ForestNeon.conf
|
||||
custom_palette=true
|
||||
icon_theme=Papirus-ForestNeon
|
||||
standard_dialogs=default
|
||||
style=Fusion
|
||||
|
||||
[Fonts]
|
||||
fixed="JetBrainsMono Nerd Font,10,-1,5,50,0,0,0,0,0"
|
||||
general="JetBrainsMono Nerd Font,10,-1,5,50,0,0,0,0,0"
|
||||
|
||||
[Interface]
|
||||
activate_item_on_single_click=1
|
||||
buttonbox_layout=0
|
||||
cursor_flash_time=1000
|
||||
dialog_buttons_have_icons=1
|
||||
double_click_interval=400
|
||||
gui_effects=@Invalid()
|
||||
keyboard_scheme=2
|
||||
menus_have_icons=true
|
||||
show_shortcuts_in_context_menus=true
|
||||
stylesheets=@Invalid()
|
||||
toolbutton_style=4
|
||||
underline_shortcut=1
|
||||
wheel_scroll_lines=3
|
||||
|
||||
[SettingsWindow]
|
||||
geometry=@ByteArray()
|
||||
123
config/starship.toml
Normal file
123
config/starship.toml
Normal file
@@ -0,0 +1,123 @@
|
||||
# Generated by ~/.config/hypr/Scripts/theme-menu.sh
|
||||
add_newline = true
|
||||
palette = "hypr_theme"
|
||||
|
||||
format = """
|
||||
[╭─](fg:accent_2)$os$username$hostname$directory$git_branch$git_status$nodejs$python$rust$golang$cmd_duration$status$fill$time
|
||||
[╰─](fg:accent)$character
|
||||
"""
|
||||
|
||||
[palettes.hypr_theme]
|
||||
accent = "#00ff9c"
|
||||
accent_2 = "#00cc88"
|
||||
background = "#14141e"
|
||||
panel = "#282837"
|
||||
foreground = "#cdd6f4"
|
||||
muted = "#cccccc"
|
||||
selected = "#000000"
|
||||
success = "#a6e3a1"
|
||||
warning = "#f9e2af"
|
||||
danger = "#f38ba8"
|
||||
blue = "#89b4fa"
|
||||
cyan = "#89dceb"
|
||||
orange = "#fab387"
|
||||
purple = "#cba6f7"
|
||||
|
||||
[fill]
|
||||
symbol = " "
|
||||
style = "fg:panel"
|
||||
|
||||
[os]
|
||||
disabled = false
|
||||
format = "[ $symbol ](fg:selected bg:accent)[](fg:accent bg:panel)"
|
||||
style = "fg:selected bg:accent"
|
||||
|
||||
[os.symbols]
|
||||
Arch = ""
|
||||
CachyOS = ""
|
||||
Linux = ""
|
||||
Ubuntu = ""
|
||||
Debian = ""
|
||||
Fedora = ""
|
||||
NixOS = ""
|
||||
|
||||
[username]
|
||||
show_always = true
|
||||
style_user = "fg:foreground bg:panel bold"
|
||||
style_root = "fg:danger bg:panel bold"
|
||||
format = "[ $user](fg:foreground bg:panel bold)"
|
||||
|
||||
[hostname]
|
||||
ssh_only = false
|
||||
style = "fg:muted bg:panel"
|
||||
format = "[@$hostname ](fg:muted bg:panel)[](fg:panel bg:background)"
|
||||
|
||||
[directory]
|
||||
style = "fg:accent bg:background bold"
|
||||
read_only_style = "fg:danger bg:background bold"
|
||||
truncation_length = 3
|
||||
truncate_to_repo = true
|
||||
read_only = " "
|
||||
format = "[ $path$read_only ](fg:accent bg:background bold)"
|
||||
|
||||
[git_branch]
|
||||
symbol = ""
|
||||
style = "fg:purple bg:background bold"
|
||||
format = "[on $symbol $branch ](fg:purple bg:background bold)"
|
||||
|
||||
[git_status]
|
||||
style = "fg:warning bg:background bold"
|
||||
format = "([$all_status$ahead_behind ](fg:warning bg:background bold))"
|
||||
conflicted = "=${count} "
|
||||
ahead = "⇡${count} "
|
||||
behind = "⇣${count} "
|
||||
diverged = "⇕⇡${ahead_count}⇣${behind_count} "
|
||||
up_to_date = ""
|
||||
untracked = "?${count} "
|
||||
stashed = "*${count} "
|
||||
modified = "!${count} "
|
||||
staged = "+${count} "
|
||||
renamed = "»${count} "
|
||||
deleted = "x${count} "
|
||||
|
||||
[nodejs]
|
||||
symbol = ""
|
||||
style = "fg:success bg:background"
|
||||
format = "[$symbol $version ](fg:success bg:background)"
|
||||
|
||||
[python]
|
||||
symbol = ""
|
||||
style = "fg:warning bg:background"
|
||||
format = "[$symbol $version ](fg:warning bg:background)"
|
||||
|
||||
[rust]
|
||||
symbol = ""
|
||||
style = "fg:orange bg:background"
|
||||
format = "[$symbol $version ](fg:orange bg:background)"
|
||||
|
||||
[golang]
|
||||
symbol = ""
|
||||
style = "fg:cyan bg:background"
|
||||
format = "[$symbol $version ](fg:cyan bg:background)"
|
||||
|
||||
[cmd_duration]
|
||||
min_time = 300
|
||||
style = "fg:orange bg:background"
|
||||
format = "[took $duration ](fg:orange bg:background)"
|
||||
|
||||
[status]
|
||||
disabled = false
|
||||
style = "fg:danger bg:background bold"
|
||||
symbol = "✖"
|
||||
format = "[$symbol $status ](fg:danger bg:background bold)"
|
||||
|
||||
[time]
|
||||
disabled = false
|
||||
time_format = "%H:%M"
|
||||
style = "fg:muted"
|
||||
format = "[ $time ]($style)"
|
||||
|
||||
[character]
|
||||
success_symbol = "[❯](fg:accent bold)"
|
||||
error_symbol = "[❯](fg:danger bold)"
|
||||
vimcmd_symbol = "[❮](fg:accent_2 bold)"
|
||||
70
config/swaync/config.json
Normal file
70
config/swaync/config.json
Normal file
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"positionX": "right",
|
||||
"positionY": "top",
|
||||
"layer": "overlay",
|
||||
"control-center-width": 420,
|
||||
"control-center-height": 650,
|
||||
"notification-window-width": 360,
|
||||
"timeout": 5,
|
||||
"timeout-low": 3,
|
||||
"timeout-critical": 0,
|
||||
"fit-to-screen": true,
|
||||
"keyboard-shortcuts": true,
|
||||
"image-visibility": "when-available",
|
||||
"transition-time": 200,
|
||||
"hide-on-clear": true,
|
||||
|
||||
"widgets": [
|
||||
"title",
|
||||
"dnd",
|
||||
"mpris",
|
||||
"buttons-grid",
|
||||
"notifications"
|
||||
],
|
||||
|
||||
"widget-config": {
|
||||
"title": {
|
||||
"text": "Control Center",
|
||||
"clear-all-button": true,
|
||||
"button-text": "Leeren"
|
||||
},
|
||||
|
||||
"dnd": {
|
||||
"text": "Nicht stören"
|
||||
},
|
||||
|
||||
"mpris": {
|
||||
"image-size": 96,
|
||||
"image-radius": 12
|
||||
},
|
||||
|
||||
"buttons-grid": {
|
||||
"actions": [
|
||||
{
|
||||
"label": " WLAN",
|
||||
"command": "nm-connection-editor"
|
||||
},
|
||||
{
|
||||
"label": " Bluetooth",
|
||||
"command": "blueman-manager"
|
||||
},
|
||||
{
|
||||
"label": " Screenshot",
|
||||
"command": "mkdir -p ~/Bilder/Screenshots && grim -g \"$(slurp)\" ~/Bilder/Screenshots/$(date +%F_%H-%M-%S).png"
|
||||
},
|
||||
{
|
||||
"label": " Lock",
|
||||
"command": "hyprlock"
|
||||
},
|
||||
{
|
||||
"label": " Power",
|
||||
"command": "wlogout"
|
||||
},
|
||||
{
|
||||
"label": " Terminal",
|
||||
"command": "kitty"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
27
config/swaync/style.css
Normal file
27
config/swaync/style.css
Normal file
@@ -0,0 +1,27 @@
|
||||
* {
|
||||
font-family: "JetBrainsMono Nerd Font";
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.notification {
|
||||
background: rgba(20, 20, 30, 0.95);
|
||||
border-radius: 12px;
|
||||
border: 2px solid #00ff9c;
|
||||
box-shadow: 0 0 10px #00ff9c;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.control-center {
|
||||
background: rgba(20, 20, 30, 0.95);
|
||||
border-radius: 15px;
|
||||
border: 2px solid #00ff9c;
|
||||
}
|
||||
|
||||
.notification-title {
|
||||
color: #00cc88;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.notification-body {
|
||||
color: #cccccc;
|
||||
}
|
||||
174
config/waybar/config.jsonc
Normal file
174
config/waybar/config.jsonc
Normal file
@@ -0,0 +1,174 @@
|
||||
{
|
||||
"layer": "top",
|
||||
"position": "top",
|
||||
"height": 42,
|
||||
"margin-top": 8,
|
||||
"margin-left": 12,
|
||||
"margin-right": 12,
|
||||
"spacing": 6,
|
||||
|
||||
"modules-left": [
|
||||
"hyprland/workspaces"
|
||||
],
|
||||
|
||||
"modules-center": [
|
||||
"group/dynamic-island"
|
||||
],
|
||||
|
||||
"modules-right": [
|
||||
"cpu",
|
||||
"memory",
|
||||
"temperature",
|
||||
"pulseaudio",
|
||||
"network",
|
||||
"battery",
|
||||
"custom/notifications",
|
||||
"tray"
|
||||
],
|
||||
|
||||
"hyprland/workspaces": {
|
||||
"format": "{icon}",
|
||||
"format-icons": {
|
||||
"1": "1",
|
||||
"2": "2",
|
||||
"3": "3",
|
||||
"4": "4",
|
||||
"5": "5",
|
||||
"6": "6",
|
||||
"7": "7",
|
||||
"8": "8",
|
||||
"9": "9",
|
||||
"10": "10",
|
||||
"urgent": "!",
|
||||
"active": "●",
|
||||
"default": "○"
|
||||
},
|
||||
"on-click": "activate"
|
||||
},
|
||||
|
||||
"hyprland/window": {
|
||||
"format": "{}",
|
||||
"max-length": 28,
|
||||
"separate-outputs": true
|
||||
},
|
||||
|
||||
"group/dynamic-island": {
|
||||
"orientation": "horizontal",
|
||||
"drawer": {
|
||||
"transition-duration": 350,
|
||||
"children-class": "island-drawer",
|
||||
"transition-left-to-right": true
|
||||
},
|
||||
"modules": [
|
||||
"custom/dynamic-island",
|
||||
"custom/media-prev",
|
||||
"custom/media-toggle",
|
||||
"custom/media-next",
|
||||
"hyprland/window"
|
||||
]
|
||||
},
|
||||
|
||||
"custom/dynamic-island": {
|
||||
"exec": "/home/pascal/.config/waybar/scripts/island-media.sh",
|
||||
"return-type": "json",
|
||||
"interval": 1,
|
||||
"format": "{}",
|
||||
"on-click": "playerctl play-pause",
|
||||
"on-click-middle": "playerctl previous",
|
||||
"on-click-right": "playerctl next"
|
||||
},
|
||||
|
||||
"custom/media-prev": {
|
||||
"format": "",
|
||||
"tooltip-format": "Zurück",
|
||||
"on-click": "playerctl previous"
|
||||
},
|
||||
|
||||
"custom/media-toggle": {
|
||||
"exec": "playerctl status 2>/dev/null | grep -q Playing && echo || echo ",
|
||||
"interval": 1,
|
||||
"format": "{}",
|
||||
"tooltip-format": "Start/Pause",
|
||||
"on-click": "playerctl play-pause"
|
||||
},
|
||||
|
||||
"custom/media-next": {
|
||||
"format": "",
|
||||
"tooltip-format": "Weiter",
|
||||
"on-click": "playerctl next"
|
||||
},
|
||||
|
||||
"clock": {
|
||||
"format": " {:%H:%M}",
|
||||
"tooltip-format": "{:%A, %d. %B %Y}"
|
||||
},
|
||||
|
||||
"cpu": {
|
||||
"format": " {usage}%",
|
||||
"tooltip": true
|
||||
},
|
||||
|
||||
"memory": {
|
||||
"format": " {}%",
|
||||
"tooltip": true
|
||||
},
|
||||
|
||||
"temperature": {
|
||||
"hwmon-path-abs": "/sys/devices/platform/coretemp.0/hwmon",
|
||||
"input-filename": "temp1_input",
|
||||
"critical-threshold": 85,
|
||||
"format": " {temperatureC}°C",
|
||||
"format-critical": " {temperatureC}°C",
|
||||
"tooltip": true
|
||||
},
|
||||
|
||||
"battery": {
|
||||
"format": "{icon} {capacity}%",
|
||||
"format-icons": ["", "", "", "", ""],
|
||||
"states": {
|
||||
"warning": 30,
|
||||
"critical": 15
|
||||
}
|
||||
},
|
||||
|
||||
"network": {
|
||||
"format-wifi": " {signalStrength}%",
|
||||
"format-ethernet": " LAN",
|
||||
"format-disconnected": " Offline",
|
||||
"tooltip-format-wifi": "{essid} ({signalStrength}%)",
|
||||
"tooltip-format-ethernet": "{ifname}: {ipaddr}/{cidr}"
|
||||
},
|
||||
|
||||
"pulseaudio": {
|
||||
"format": "{icon} {volume}%",
|
||||
"format-muted": " Muted",
|
||||
"format-icons": {
|
||||
"default": ["", "", ""]
|
||||
}
|
||||
},
|
||||
|
||||
"custom/notifications": {
|
||||
"tooltip": true,
|
||||
"format": "{icon}",
|
||||
"format-icons": {
|
||||
"notification": "",
|
||||
"none": "",
|
||||
"dnd-notification": "",
|
||||
"dnd-none": "",
|
||||
"inhibited-notification": "",
|
||||
"inhibited-none": "",
|
||||
"dnd-inhibited-notification": "",
|
||||
"dnd-inhibited-none": ""
|
||||
},
|
||||
"return-type": "json",
|
||||
"exec-if": "which swaync-client",
|
||||
"exec": "swaync-client -swb",
|
||||
"on-click": "swaync-client -t",
|
||||
"on-click-right": "swaync-client -d",
|
||||
"escape": true
|
||||
},
|
||||
|
||||
"tray": {
|
||||
"spacing": 10
|
||||
}
|
||||
}
|
||||
39
config/waybar/scripts/island-media.sh
Executable file
39
config/waybar/scripts/island-media.sh
Executable file
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
json() {
|
||||
jq -Rn --arg value "$1" '$value'
|
||||
}
|
||||
|
||||
status="$(playerctl status 2>/dev/null || true)"
|
||||
time_now="$(date +%H:%M)"
|
||||
|
||||
if [[ "$status" == "Playing" || "$status" == "Paused" ]]; then
|
||||
title="$(playerctl metadata --format '{{ title }}' 2>/dev/null || true)"
|
||||
artist="$(playerctl metadata --format '{{ artist }}' 2>/dev/null || true)"
|
||||
player="$(playerctl metadata --format '{{ playerName }}' 2>/dev/null || true)"
|
||||
|
||||
[[ -z "$title" ]] && title="Media"
|
||||
|
||||
if [[ "$status" == "Playing" ]]; then
|
||||
icon=""
|
||||
class="playing"
|
||||
else
|
||||
icon=""
|
||||
class="paused"
|
||||
fi
|
||||
|
||||
text="$icon $title"
|
||||
[[ -n "$artist" ]] && text="$text · $artist"
|
||||
text="$text $time_now"
|
||||
tooltip="${player:-Player} (${status})"
|
||||
[[ -n "$artist$title" ]] && tooltip="$tooltip"$'\n'"$artist - $title"
|
||||
else
|
||||
text=" $time_now"
|
||||
tooltip="$(date '+%A, %d. %B %Y')"
|
||||
class="idle"
|
||||
fi
|
||||
|
||||
printf '{"text":%s,"tooltip":%s,"class":%s}\n' \
|
||||
"$(json "$text")" \
|
||||
"$(json "$tooltip")" \
|
||||
"$(json "$class")"
|
||||
206
config/waybar/style.css
Normal file
206
config/waybar/style.css
Normal file
@@ -0,0 +1,206 @@
|
||||
* {
|
||||
min-height: 0;
|
||||
font-family: "JetBrainsMono Nerd Font", "JetBrains Mono", sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
window#waybar {
|
||||
background: transparent;
|
||||
color: #cdd6f4;
|
||||
}
|
||||
|
||||
tooltip {
|
||||
background: rgba(20, 20, 30, 0.95);
|
||||
border: 1px solid #00ff9c;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
tooltip label {
|
||||
color: #cdd6f4;
|
||||
padding: 6px 8px;
|
||||
}
|
||||
|
||||
#workspaces {
|
||||
margin: 0 0 0 2px;
|
||||
padding: 4px;
|
||||
background: rgba(24, 24, 37, 0.72);
|
||||
border: 1px solid rgba(40, 40, 55, 0.8);
|
||||
border-radius: 18px;
|
||||
}
|
||||
|
||||
#workspaces button {
|
||||
min-width: 26px;
|
||||
margin: 0 2px;
|
||||
padding: 0 7px;
|
||||
color: #7f849c;
|
||||
background: transparent;
|
||||
border-radius: 14px;
|
||||
transition: all 180ms ease;
|
||||
}
|
||||
|
||||
#workspaces button.active {
|
||||
min-width: 34px;
|
||||
color: #000000;
|
||||
background: linear-gradient(135deg, #00ff9c, #00cc88);
|
||||
box-shadow: 0 0 14px rgba(40, 40, 55, 0.8);
|
||||
}
|
||||
|
||||
#workspaces button.urgent {
|
||||
color: #000000;
|
||||
background: #f38ba8;
|
||||
}
|
||||
|
||||
#workspaces button:hover {
|
||||
color: #cdd6f4;
|
||||
background: rgba(40, 40, 55, 0.8);
|
||||
}
|
||||
|
||||
#dynamic-island {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: rgba(5, 5, 9, 0.88);
|
||||
border-top: 1px solid rgba(40, 40, 55, 0.8);
|
||||
border-bottom: 1px solid #00ff9c;
|
||||
border-radius: 21px;
|
||||
box-shadow: 0 10px 28px rgba(0, 0, 0, 0.36);
|
||||
}
|
||||
|
||||
#custom-dynamic-island,
|
||||
#custom-media-prev,
|
||||
#custom-media-toggle,
|
||||
#custom-media-next,
|
||||
#window,
|
||||
#clock {
|
||||
margin: 0;
|
||||
padding: 0 11px;
|
||||
background: transparent;
|
||||
color: #cdd6f4;
|
||||
}
|
||||
|
||||
#custom-dynamic-island {
|
||||
min-width: 142px;
|
||||
padding-left: 16px;
|
||||
padding-right: 14px;
|
||||
color: #cdd6f4;
|
||||
border-radius: 21px;
|
||||
}
|
||||
|
||||
#custom-dynamic-island.playing {
|
||||
color: #a6e3a1;
|
||||
}
|
||||
|
||||
#custom-dynamic-island.paused {
|
||||
color: #f9e2af;
|
||||
}
|
||||
|
||||
#custom-dynamic-island.idle {
|
||||
color: #7f849c;
|
||||
}
|
||||
|
||||
#custom-media-prev,
|
||||
#custom-media-toggle,
|
||||
#custom-media-next {
|
||||
min-width: 20px;
|
||||
padding: 0 9px;
|
||||
color: #cdd6f4;
|
||||
border-radius: 14px;
|
||||
}
|
||||
|
||||
#custom-media-prev:hover,
|
||||
#custom-media-toggle:hover,
|
||||
#custom-media-next:hover {
|
||||
color: #000000;
|
||||
background: #00ff9c;
|
||||
}
|
||||
|
||||
#window {
|
||||
min-width: 90px;
|
||||
color: #cccccc;
|
||||
}
|
||||
|
||||
window#waybar.empty #window {
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
#clock {
|
||||
padding-right: 16px;
|
||||
color: #a6e3a1;
|
||||
}
|
||||
|
||||
.island-drawer {
|
||||
color: #7f849c;
|
||||
}
|
||||
|
||||
#cpu,
|
||||
#memory,
|
||||
#temperature,
|
||||
#pulseaudio,
|
||||
#network,
|
||||
#battery,
|
||||
#custom-notifications,
|
||||
#tray {
|
||||
margin: 0 2px;
|
||||
padding: 0 10px;
|
||||
background: rgba(24, 24, 37, 0.72);
|
||||
border: 1px solid rgba(40, 40, 55, 0.8);
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
#cpu {
|
||||
color: #89b4fa;
|
||||
}
|
||||
|
||||
#memory {
|
||||
color: #f9e2af;
|
||||
}
|
||||
|
||||
#temperature {
|
||||
color: #a6e3a1;
|
||||
}
|
||||
|
||||
#temperature.critical {
|
||||
color: #f38ba8;
|
||||
background: rgba(40, 40, 55, 0.8);
|
||||
}
|
||||
|
||||
#pulseaudio {
|
||||
color: #fab387;
|
||||
}
|
||||
|
||||
#pulseaudio.muted {
|
||||
color: #7f849c;
|
||||
}
|
||||
|
||||
#network {
|
||||
color: #89dceb;
|
||||
}
|
||||
|
||||
#network.disconnected {
|
||||
color: #f38ba8;
|
||||
}
|
||||
|
||||
#battery {
|
||||
color: #a6e3a1;
|
||||
}
|
||||
|
||||
#battery.warning {
|
||||
color: #f9e2af;
|
||||
}
|
||||
|
||||
#battery.critical {
|
||||
color: #f38ba8;
|
||||
background: rgba(40, 40, 55, 0.8);
|
||||
}
|
||||
|
||||
#custom-notifications {
|
||||
color: #cba6f7;
|
||||
}
|
||||
|
||||
#tray {
|
||||
padding-right: 12px;
|
||||
}
|
||||
11
config/wofi/config
Normal file
11
config/wofi/config
Normal file
@@ -0,0 +1,11 @@
|
||||
width=600
|
||||
height=400
|
||||
location=center
|
||||
show=drun
|
||||
prompt= Launch
|
||||
allow_images=true
|
||||
term=kitty
|
||||
style=/home/pascal/.config/wofi/style.css
|
||||
hide_scroll=true
|
||||
no_actions=true
|
||||
|
||||
55
config/wofi/style.css
Normal file
55
config/wofi/style.css
Normal file
@@ -0,0 +1,55 @@
|
||||
* {
|
||||
font-family: "JetBrainsMono Nerd Font";
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
window {
|
||||
margin: 0px;
|
||||
border: 2px solid #00ff9c;
|
||||
border-radius: 12px;
|
||||
background-color: rgba(20, 20, 30, 0.95);
|
||||
}
|
||||
|
||||
#input {
|
||||
margin: 10px;
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
border: none;
|
||||
background-color: rgba(40, 40, 55, 0.8);
|
||||
color: #00ff9c;
|
||||
}
|
||||
|
||||
#inner-box {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
#outer-box {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
#scroll {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
#text {
|
||||
margin: 5px;
|
||||
color: #cdd6f4;
|
||||
}
|
||||
|
||||
#entry {
|
||||
padding: 8px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
#entry:selected {
|
||||
background-color: #00ff9c;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
#entry:hover {
|
||||
background-color: rgba(40, 40, 55, 0.8);
|
||||
}
|
||||
|
||||
#img {
|
||||
margin-right: 8px;
|
||||
}
|
||||
Reference in New Issue
Block a user