I am batman
This commit is contained in:
83
scripts/amdgpu.py
Executable file
83
scripts/amdgpu.py
Executable file
@@ -0,0 +1,83 @@
|
||||
import pyamdgpuinfo
|
||||
import json
|
||||
|
||||
def format_frequency(frequency_hz: int) -> str:
|
||||
"""
|
||||
Takes a frequency (in Hz) and normalizes it: `Hz`, `MHz`, or `GHz`
|
||||
|
||||
Returns:
|
||||
str: frequency string with the appropriate suffix applied
|
||||
"""
|
||||
return (
|
||||
format_size(frequency_hz, binary=False)
|
||||
.replace("B", "Hz")
|
||||
.replace("bytes", "Hz")
|
||||
)
|
||||
|
||||
def format_size(size: int, binary=True) -> str:
|
||||
"""
|
||||
Format size in bytes to a human-readable format.
|
||||
|
||||
Args:
|
||||
size (int): Size in bytes.
|
||||
binary (bool): If True, use binary (base 1024) units.
|
||||
|
||||
Returns:
|
||||
str: Formatted size string.
|
||||
"""
|
||||
suffixes = ["B", "KiB", "MiB", "GiB", "TiB"] if binary else ["B", "KB", "MB", "GB", "TB"]
|
||||
base = 1024 if binary else 1000
|
||||
index = 0
|
||||
|
||||
while size >= base and index < len(suffixes) - 1:
|
||||
size /= base
|
||||
index += 1
|
||||
|
||||
return f"{size:.0f} {suffixes[index]}"
|
||||
|
||||
def main():
|
||||
# Detect the number of GPUs available
|
||||
n_devices = pyamdgpuinfo.detect_gpus()
|
||||
|
||||
if n_devices == 0:
|
||||
print("No AMD GPUs detected.")
|
||||
return
|
||||
|
||||
# Get GPU information for the first GPU (index 0)
|
||||
first_gpu = pyamdgpuinfo.get_gpu(0)
|
||||
|
||||
try:
|
||||
# Query GPU temperature
|
||||
temperature = first_gpu.query_temperature()
|
||||
temperature = f"{temperature:.0f}°C" # Format temperature to 2 digits with "°C"
|
||||
|
||||
# Query GPU core clock
|
||||
core_clock_hz = first_gpu.query_sclk() # In Hz
|
||||
formatted_core_clock = format_frequency(core_clock_hz)
|
||||
|
||||
# Query GPU power consumption
|
||||
power_usage = first_gpu.query_power()
|
||||
|
||||
# Query GPU load
|
||||
gpu_load = first_gpu.query_load()
|
||||
formatted_gpu_load = f"{gpu_load:.1f}%" # Format GPU load to 1 decimal place
|
||||
|
||||
# Create a dictionary with the GPU information
|
||||
gpu_info = {
|
||||
"GPU Temperature": temperature,
|
||||
"GPU Load": formatted_gpu_load,
|
||||
"GPU Core Clock": formatted_core_clock,
|
||||
"GPU Power Usage": f"{power_usage} Watts"
|
||||
}
|
||||
|
||||
# Convert the dictionary to a JSON string, ensure_ascii=False to prevent escaping
|
||||
json_output = json.dumps(gpu_info, ensure_ascii=False)
|
||||
|
||||
# Print the JSON string
|
||||
print(json_output)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error: {str(e)}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
84
scripts/animations.sh
Executable file
84
scripts/animations.sh
Executable file
@@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Define paths
|
||||
scrDir=$(dirname "$(realpath "$0")")
|
||||
source "$scrDir/globalcontrol.sh"
|
||||
config_dir="$HOME/.config"
|
||||
animations_dir="$config_dir/hypr/animations"
|
||||
animations_conf="$config_dir/hypr/animations.conf"
|
||||
rofi_theme="$config_dir/rofi/clipboard.rasi"
|
||||
|
||||
# Set rofi scaling
|
||||
[[ "${rofiScale}" =~ ^[0-9]+$ ]] || rofiScale=10
|
||||
r_scale="configuration {font: \"JetBrainsMono Nerd Font ${rofiScale}\";}"
|
||||
wind_border=$((hypr_border * 3 / 2))
|
||||
elem_border=$([ $hypr_border -eq 0 ] && echo "5" || echo $hypr_border)
|
||||
|
||||
# Evaluate spawn position
|
||||
readarray -t curPos < <(hyprctl cursorpos -j | jq -r '.x,.y')
|
||||
readarray -t monRes < <(hyprctl -j monitors | jq '.[] | select(.focused==true) | .width,.height,.scale,.x,.y')
|
||||
readarray -t offRes < <(hyprctl -j monitors | jq -r '.[] | select(.focused==true).reserved | map(tostring) | join("\n")')
|
||||
monRes[2]="$(echo "${monRes[2]}" | sed "s/\.//")"
|
||||
monRes[0]="$(( ${monRes[0]} * 100 / ${monRes[2]} ))"
|
||||
monRes[1]="$(( ${monRes[1]} * 100 / ${monRes[2]} ))"
|
||||
curPos[0]="$(( ${curPos[0]} - ${monRes[3]} ))"
|
||||
curPos[1]="$(( ${curPos[1]} - ${monRes[4]} ))"
|
||||
|
||||
if [ "${curPos[0]}" -ge "$((${monRes[0]} / 2))" ] ; then
|
||||
x_pos="east"
|
||||
x_off="-$(( ${monRes[0]} - ${curPos[0]} - ${offRes[2]} ))"
|
||||
else
|
||||
x_pos="west"
|
||||
x_off="$(( ${curPos[0]} - ${offRes[0]} ))"
|
||||
fi
|
||||
|
||||
if [ "${curPos[1]}" -ge "$((${monRes[1]} / 2))" ] ; then
|
||||
y_pos="south"
|
||||
y_off="-$(( ${monRes[1]} - ${curPos[1]} - ${offRes[3]} ))"
|
||||
else
|
||||
y_pos="north"
|
||||
y_off="$(( ${curPos[1]} - ${offRes[1]} ))"
|
||||
fi
|
||||
|
||||
r_override="window{location:${x_pos} ${y_pos};anchor:${x_pos} ${y_pos};x-offset:${x_off}px;y-offset:${y_off}px;border:${hypr_width}px;border-radius:${wind_border}px;} wallbox{border-radius:${elem_border}px;} element{border-radius:${elem_border}px;}"
|
||||
|
||||
# Ensure the animations directory exists
|
||||
if [ ! -d "$animations_dir" ]; then
|
||||
notify-send "Error" "Animations directory does not exist at $animations_dir"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# List available .conf files in animations directory
|
||||
animation_files=$(ls "$animations_dir"/*.conf 2>/dev/null)
|
||||
if [ -z "$animation_files" ]; then
|
||||
notify-send "Error" "No .conf files found in $animations_dir"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Display options using Rofi with custom scaling, positioning, and placeholder
|
||||
selected_animation=$(echo "$animation_files" | awk -F/ '{print $NF}' | \
|
||||
rofi -dmenu \
|
||||
-p "Select animation" \
|
||||
-theme-str "entry { placeholder: \"Select animation...\"; }" \
|
||||
-theme-str "${r_scale}" \
|
||||
-theme-str "${r_override}" \
|
||||
-theme "$rofi_theme")
|
||||
|
||||
# Exit if no selection was made
|
||||
if [ -z "$selected_animation" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Generate the new source line
|
||||
selected_path="$animations_dir/$selected_animation"
|
||||
new_source_line="source = $selected_path"
|
||||
|
||||
# Update the animations.conf file
|
||||
if grep -q "^source = " "$animations_conf"; then
|
||||
sed -i "s|^source = .*|$new_source_line|" "$animations_conf"
|
||||
else
|
||||
echo "$new_source_line" >> "$animations_conf"
|
||||
fi
|
||||
|
||||
# Notify the user
|
||||
notify-send "Animation Updated" "Sourced $selected_animation"
|
||||
228
scripts/batterynotify.sh
Executable file
228
scripts/batterynotify.sh
Executable file
@@ -0,0 +1,228 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
undock=false
|
||||
scrDir=$(dirname "$(realpath "$0")")
|
||||
source $scrDir/globalcontrol.sh
|
||||
batterynotify_conf="${hydeConfDir}/hyde.conf" # Shared with hyde configuration
|
||||
config_info() {
|
||||
cat << EOF
|
||||
|
||||
Modify $batterynotify_conf to set options.
|
||||
|
||||
STATUS THRESHOLD INTERVAL
|
||||
Full $battery_full_threshold $notify Minutes
|
||||
Critical $battery_critical_threshold $timer Seconds then '$execute_critical'
|
||||
Low $battery_low_threshold $interval Percent then '$execute_low'
|
||||
Unplug $unplug_charger_threshold $interval Percent then '$execute_unplug'
|
||||
|
||||
Charging: $execute_charging
|
||||
Discharging: $execute_discharging
|
||||
EOF
|
||||
}
|
||||
|
||||
is_laptop() { # Check if the system is a laptop
|
||||
if grep -q "Battery" /sys/class/power_supply/BAT*/type; then
|
||||
return 0 # It's a laptop
|
||||
else
|
||||
echo "No battery detected. If you think this is an error please post a report to the repo"
|
||||
exit 0 # It's not a laptop
|
||||
fi
|
||||
}
|
||||
is_laptop
|
||||
fn_verbose () {
|
||||
if $verbose; then
|
||||
cat << VERBOSE
|
||||
=============================================
|
||||
Battery Status: $battery_status
|
||||
Battery Percentage: $battery_percentage
|
||||
=============================================
|
||||
VERBOSE
|
||||
fi
|
||||
}
|
||||
fn_notify () { # Send notification
|
||||
|
||||
notify-send -a "Power" $1 -u $2 "$3" "$4" -p # Call the notify-send command with the provided arguments \$1 is the flags \$2 is the urgency \$3 is the title \$4 is the message
|
||||
}
|
||||
fn_percentage () {
|
||||
if [[ "$battery_percentage" -ge "$unplug_charger_threshold" ]] && [[ "$battery_status" != "Discharging" ]] && [[ "$battery_status" != "Full" ]] && (( (battery_percentage - last_notified_percentage) >= $interval )); then if $verbose; then echo "Prompt:UNPLUG: $battery_unplug_threshold $battery_status $battery_percentage" ; fi
|
||||
fn_notify "-t 5000 " "CRITICAL" "Battery Charged" "Battery is at $battery_percentage%. You can unplug the charger!"
|
||||
last_notified_percentage=$battery_percentage
|
||||
elif [[ "$battery_percentage" -le "$battery_critical_threshold" ]]; then
|
||||
count=$(( timer > $mnt ? timer : $mnt )) # reset count
|
||||
while [ $count -gt 0 ] && [[ $battery_status == "Discharging"* ]]; do
|
||||
for battery in /sys/class/power_supply/BAT*; do battery_status=$(< "$battery/status") ; done
|
||||
if [[ $battery_status != "Discharging" ]] ; then break ; fi
|
||||
fn_notify "-t 5000 -r 69 " "CRITICAL" "Battery Critically Low" "$battery_percentage% is critically low. Device will execute $execute_critical in $((count/60)):$((count%60)) ."
|
||||
count=$((count-1))
|
||||
sleep 1
|
||||
done
|
||||
[ $count -eq 0 ] && fn_action
|
||||
elif [[ "$battery_percentage" -le "$battery_low_threshold" ]] && [[ "$battery_status" == "Discharging" ]] && (( (last_notified_percentage - battery_percentage) >= $interval )); then if $verbose; then echo "Prompt:LOW: $battery_low_threshold $battery_status $battery_percentage" ; fi
|
||||
fn_notify "-t 5000 " "CRITICAL" "Battery Low" "Battery is at $battery_percentage%. Connect the charger."
|
||||
last_notified_percentage=$battery_percentage
|
||||
fi
|
||||
}
|
||||
fn_action () { #handles the $execute_critical command #? This is special as it will try to execute always
|
||||
count=$(( timer > $mnt ? timer : $mnt )) # reset count
|
||||
nohup $execute_critical
|
||||
}
|
||||
|
||||
fn_status () {
|
||||
if [[ $battery_percentage -ge $battery_full_threshold ]] && [[ "$battery_status" != *"Discharging"* ]]; then echo "Full and $battery_status"
|
||||
battery_status="Full" ;fi
|
||||
case "$battery_status" in # Handle the power supply status
|
||||
"Discharging") if $verbose; then echo "Case:$battery_status Level: $battery_percentage" ;fi
|
||||
if [[ "$prev_status" != "Discharging" ]] || [[ "$prev_status" == "Full" ]] ; then
|
||||
prev_status=$battery_status
|
||||
urgency=$([[ $battery_percentage -le "$battery_low_threshold" ]] && echo "CRITICAL" || echo "NORMAL")
|
||||
fn_notify "-t 5000 -r 54321 " "$urgency" "Charger Plug OUT" "Battery is at $battery_percentage%."
|
||||
$execute_discharging
|
||||
fi
|
||||
fn_percentage
|
||||
;;
|
||||
"Not"*|"Charging") if $verbose; then echo "Case:$battery_status Level: $battery_percentage" ;fi
|
||||
if [[ "$prev_status" == "Discharging" ]] || [[ "$prev_status" == "Not"* ]] ; then
|
||||
prev_status=$battery_status
|
||||
count=$(( timer > $mnt ? timer : $mnt )) # reset count
|
||||
urgency=$([[ "$battery_percentage" -ge $unplug_charger_threshold ]] && echo "CRITICAL" || echo "NORMAL")
|
||||
fn_notify "-t 5000 -r 54321 " "$urgency" "Charger Plug In" "Battery is at $battery_percentage%."
|
||||
$execute_charging
|
||||
fi
|
||||
fn_percentage
|
||||
;;
|
||||
"Full") if $verbose; then echo "Case:$battery_status Level: $battery_percentage" ;fi
|
||||
if [[ $battery_status != "Discharging" ]]; then
|
||||
now=$(date +%s)
|
||||
if [[ "$prev_status" == *"harging"* ]] || ((now - lt >= $((notify*60)) )); then
|
||||
fn_notify "-t 5000 -r 54321" "CRITICAL" "Battery Full" "Please unplug your Charger"
|
||||
prev_status=$battery_status lt=$now
|
||||
$execute_charging
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
if [[ ! -f "/tmp/hyprdots.batterynotify.status.fallback.$battery_status-$$" ]]; then
|
||||
echo "Status: '==>> "$battery_status" <<==' Script on Fallback mode,Unknown power supply status.Please copy this line and raise an issue to the Github Repo.Also run 'ls /tmp/hyprdots.batterynotify' to see the list of lock files.*"
|
||||
touch "/tmp/hyprdots.batterynotify.status.fallback.$battery_status-$$"
|
||||
fi
|
||||
fn_percentage
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
get_battery_info() { #TODO Might change this if we can get an effective way to parse dbus. I will do it some time...
|
||||
total_percentage=0 battery_count=0
|
||||
for battery in /sys/class/power_supply/BAT*; do
|
||||
battery_status=$(<"$battery/status") battery_percentage=$(<"$battery/capacity")
|
||||
total_percentage=$((total_percentage + battery_percentage))
|
||||
battery_count=$((battery_count + 1))
|
||||
done
|
||||
battery_percentage=$((total_percentage / battery_count)) #? For Multiple Battery
|
||||
}
|
||||
|
||||
fn_status_change () { # Handle when status changes
|
||||
get_battery_info
|
||||
# Add these two lines at the beginning of the function
|
||||
local executed_low=false
|
||||
local executed_unplug=false
|
||||
|
||||
if [ "$battery_status" != "$last_battery_status" ] || [ "$battery_percentage" != "$last_battery_percentage" ]; then
|
||||
last_battery_status=$battery_status
|
||||
last_battery_percentage=$battery_percentage # Check if battery status or percentage has changed
|
||||
fn_verbose
|
||||
fn_percentage
|
||||
|
||||
if [[ "$battery_percentage" -le "$battery_low_threshold" ]] && ! $executed_low; then $execute_low
|
||||
executed_low=true executed_unplug=false
|
||||
fi
|
||||
if [[ "$battery_percentage" -ge "$unplug_charger_threshold" ]] && ! $executed_unplug; then $execute_unplug
|
||||
executed_unplug=true executed_low=false
|
||||
fi
|
||||
|
||||
if $undock; then fn_status; fi
|
||||
fi
|
||||
}
|
||||
|
||||
# resume_processes() { for pid in $pids ; do if [ "$pid" -ne "$current_pid" ] ; then kill -CONT $pid ; notify-send -a "Battery Notify" -t 2000 -r 9889 -u "CRITICAL" "Debugging ENDED, Resuming Regular Process" ; fi ; done }
|
||||
|
||||
main() { # Main function
|
||||
rm -fr /tmp/hyprdots.batterynotify* # Cleaning the lock file
|
||||
battery_full_threshold=${battery_full_threshold:-100}
|
||||
battery_critical_threshold=${battery_critical_threshold:-5}
|
||||
unplug_charger_threshold=${unplug_charger_threshold:-80}
|
||||
battery_low_threshold=${battery_low_threshold:-20}
|
||||
timer=${timer:-120}
|
||||
notify=${notify:-1140}
|
||||
interval=${interval:-5}
|
||||
execute_critical=${execute_critical:-"systemctl suspend"}
|
||||
execute_low=${execute_low:-}
|
||||
execute_unplug=${execute_unplug:-}
|
||||
|
||||
config_info
|
||||
if $verbose; then for line in "Verbose Mode is ON..." "" "" "" "" ; do echo $line ; done;
|
||||
#TODO Might still need this in the future but for now we don't have any battery notify issues
|
||||
# current_pid=$$
|
||||
# pids=$(pgrep -f "/usr/bin/env bash ${scrDir}/batterynotify.sh" )
|
||||
# for pid in $pids ; do if [ "$pid" -ne $current_pid ] ;then kill -STOP "$pid" ;notify-send -a "Battery Notify" -t 2000 -r 9889 -u "CRITICAL" "Debugging STARTED, Pausing Regular Process" ;fi ; done ; trap resume_processes SIGINT ;
|
||||
fi
|
||||
get_battery_info # initiate the function
|
||||
last_notified_percentage=$battery_percentage
|
||||
prev_status=$battery_status
|
||||
dbus-monitor --system "type='signal',interface='org.freedesktop.DBus.Properties',path='$(upower -e | grep battery)'" 2> /dev/null | while read -r battery_status_change; do fn_status_change ; done
|
||||
}
|
||||
|
||||
verbose=false
|
||||
case "$1" in
|
||||
-m|--modify)
|
||||
EDITOR="${EDITOR:-code}" #* Use VS Code as the default editor
|
||||
echo -e "[Editor]: $EDITOR \n To change editor, run 'export EDITOR=preferred-editor' \n[Modifying]: $batterynotify_conf \nPress Any Key if done editing"
|
||||
#kitty -o allow_remote_control=yes -o listen_on=unix:/tmp/mykitty $(which $EDITOR) "$batterynotify_conf" > /dev/null 2>&1 &
|
||||
kitty "$(which $EDITOR)" "$batterynotify_conf" > /dev/null 2>&1 &
|
||||
LAST_MD5SUM=$(md5sum "$batterynotify_conf")
|
||||
while true; do CURRENT_MD5SUM=$(md5sum "$batterynotify_conf")
|
||||
if [ "$CURRENT_MD5SUM" != "$LAST_MD5SUM" ]; then
|
||||
notify-send "Config Changed: Needs reboot or restart $0"
|
||||
LAST_MD5SUM="$CURRENT_MD5SUM"
|
||||
fi ; read -t 2 -n 1 > /dev/null && break #? loop every 2 seconds
|
||||
done
|
||||
exit 0
|
||||
;;
|
||||
-i|--info)
|
||||
config_info
|
||||
exit 0
|
||||
;;
|
||||
-v|--verbose)
|
||||
verbose=true
|
||||
;;
|
||||
-*)
|
||||
cat << HELP
|
||||
Usage: $0 [options]
|
||||
|
||||
[-m|--modify] Modify configuration file
|
||||
[-i|--info] Display configuration information
|
||||
[-v|--verbose] Debugging mode
|
||||
[-h|--help] This Message
|
||||
HELP
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
mnc=2 mxc=50 mnl=10 mxl=80 mnu=50 mxu=100 mnt=60 mxt=1000 mnf=80 mxf=100 mnn=1 mxn=1140 mni=1 mxi=10 #Defaults Ranges
|
||||
check_range() {
|
||||
local var=$1 min=$2 max=$3 error_message=$4
|
||||
if [[ $var =~ ^[0-9]+$ ]] && (( var >= min && var <= max )); then
|
||||
var=$var ; shift 2
|
||||
else
|
||||
echo -e "$1 WARNING: $error_message must be $min - $max." >&2
|
||||
fi
|
||||
}
|
||||
|
||||
check_range "$battery_full_threshold" $mnf $mxf "Full Threshold"
|
||||
check_range "$battery_critical_threshold" $mnc $mxc "Critical Threshold"
|
||||
check_range "$battery_low_threshold" $mnl $mxl "Low Threshold"
|
||||
check_range "$unplug_charger_threshold" $mnu $mxu "Unplug Threshold"
|
||||
check_range "$timer" $mnt $mxt "Timer"
|
||||
check_range "$notify" $mnn $mxn "Notify"
|
||||
check_range "$interval" $mni $mxi "Interval"
|
||||
|
||||
main
|
||||
111
scripts/brightnesscontrol.sh
Executable file
111
scripts/brightnesscontrol.sh
Executable file
@@ -0,0 +1,111 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Check if the script is already running
|
||||
pgrep -cf "${0##*/}" | grep -qv 1 && echo "An instance of the script is already running..." && exit 1
|
||||
|
||||
scrDir=`dirname "$(realpath "$0")"`
|
||||
source $scrDir/globalcontrol.sh
|
||||
|
||||
# Check if SwayOSD is installed
|
||||
use_swayosd=false
|
||||
if command -v swayosd-client >/dev/null 2>&1 && pgrep -x swayosd-server >/dev/null; then
|
||||
use_swayosd=true
|
||||
fi
|
||||
|
||||
print_error()
|
||||
{
|
||||
cat << EOF
|
||||
$(basename ${0}) <action> [step] [mode]
|
||||
...valid actions are...
|
||||
i -- <i>ncrease brightness [+5%]
|
||||
d -- <d>ecrease brightness [-5%]
|
||||
|
||||
Example:
|
||||
$(basename ${0}) i 10 # Increase brightness by 10%
|
||||
$(basename ${0}) d # Decrease brightness by default step (5%)
|
||||
$(basename ${0}) i 5 -q # Increase brightness by 5% quietly
|
||||
EOF
|
||||
}
|
||||
notify="${waybar_brightness_notification:-true}" # Default: notifications are enabled
|
||||
action="" # Will store 'increase' or 'decrease'
|
||||
step=5 # Default step value
|
||||
|
||||
# Parse all arguments
|
||||
for arg in "$@"; do
|
||||
case $arg in
|
||||
i|-i)
|
||||
[ -n "$action" ] &&
|
||||
{
|
||||
echo -e "\033[38;2;255;0;0mOne or more actions are provided\033[0m";
|
||||
print_error;
|
||||
exit 1;
|
||||
} # Prevent multiple actions
|
||||
action="increase" ;; # Increase brightness
|
||||
d|-d)
|
||||
[ -n "$action" ] &&
|
||||
{
|
||||
echo -e "\033[38;2;255;0;0mOne or more actions are provided\033[0m";
|
||||
print_error;
|
||||
exit 1;
|
||||
} # Prevent multiple actions
|
||||
action="decrease" ;; # Decrease brightness
|
||||
q|-q)
|
||||
notify=false ;; # Disabling notification
|
||||
[0-9]*)
|
||||
if ! echo "$arg" | grep -Eq '^[0-9]+$'; then
|
||||
print_error
|
||||
exit 1
|
||||
fi
|
||||
step=$arg ;; # Step value
|
||||
*)
|
||||
print_error && exit 1 ;; # Invalid input
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$action" ]; then # If actions are missing with mode/value
|
||||
echo -e "\033[38;2;255;0;0mActions are not provided\033[0m"
|
||||
print_error
|
||||
exit 1
|
||||
fi
|
||||
|
||||
send_notification() {
|
||||
brightness=`brightnessctl info | grep -oP "(?<=\()\d+(?=%)" | cat`
|
||||
brightinfo=$(brightnessctl info | awk -F "'" '/Device/ {print $2}')
|
||||
angle="$(((($brightness + 2) / 5) * 5))"
|
||||
ico="$HOME/.config/dunst/icons/vol/vol-${angle}.svg"
|
||||
bar=$(seq -s "." $(($brightness / 15)) | sed 's/[0-9]//g')
|
||||
notify-send -a "t2" -r 91190 -t 800 -i "${ico}" "${brightness}${bar}" "${brightinfo}"
|
||||
}
|
||||
|
||||
get_brightness() {
|
||||
brightnessctl -m | grep -o '[0-9]\+%' | head -c-2
|
||||
}
|
||||
|
||||
|
||||
case $action in
|
||||
increase) # increase the backlight
|
||||
if [[ $(get_brightness) -lt 10 ]] ; then
|
||||
# increase the backlight by 1% if less than 10%
|
||||
step=1
|
||||
fi
|
||||
|
||||
$use_swayosd && swayosd-client --brightness raise "$step" && exit 0
|
||||
brightnessctl set +${step}%
|
||||
[ "$notify" = true ] && send_notification ;;
|
||||
decrease) # decrease the backlight
|
||||
|
||||
if [[ $(get_brightness) -le 10 ]] ; then
|
||||
# decrease the backlight by 1% if less than 10%
|
||||
step=1
|
||||
fi
|
||||
|
||||
if [[ $(get_brightness) -le 1 ]]; then
|
||||
brightnessctl set ${step}%
|
||||
$use_swayosd && exit 0
|
||||
else
|
||||
$use_swayosd && swayosd-client --brightness lower "$step" && exit 0
|
||||
brightnessctl set ${step}%-
|
||||
fi
|
||||
|
||||
[ "$notify" = true ] && send_notification ;;
|
||||
esac
|
||||
16
scripts/center-window.sh
Executable file
16
scripts/center-window.sh
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Toggle single_window_aspect_ratio in dwindle layout
|
||||
# This script toggles between enforcing a 1:1 aspect ratio and allowing full width
|
||||
|
||||
# Get current dwindle settings
|
||||
CURRENT_RATIO=$(hyprctl getoption dwindle:single_window_aspect_ratio | grep -oP 'vec2: \K.*')
|
||||
|
||||
if [ "$CURRENT_RATIO" = "[1, 1]" ]; then
|
||||
# Disable aspect ratio (set to 0 0 to disable)
|
||||
hyprctl keyword dwindle:single_window_aspect_ratio "0 0"
|
||||
else
|
||||
# Enable aspect ratio (1 1 for square)
|
||||
hyprctl keyword dwindle:single_window_aspect_ratio "1 1"
|
||||
fi
|
||||
|
||||
9
scripts/cliphist-paste.sh
Executable file
9
scripts/cliphist-paste.sh
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
selected_item="$(/run/current-system/sw/bin/cliphist list | rofi -dmenu -i -p 'Clipboard')"
|
||||
|
||||
[ -z "$selected_item" ] && exit 0
|
||||
|
||||
printf '%s' "$selected_item" | /run/current-system/sw/bin/cliphist decode | /run/current-system/sw/bin/wl-copy
|
||||
sleep 0.05
|
||||
/run/current-system/sw/bin/wtype -M ctrl -k v -m ctrl
|
||||
182
scripts/cliphist.sh
Executable file
182
scripts/cliphist.sh
Executable file
@@ -0,0 +1,182 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Set variables
|
||||
scrDir=$(dirname "$(realpath "$0")")
|
||||
source "$scrDir/globalcontrol.sh"
|
||||
roconf="${confDir}/rofi/clipboard.rasi"
|
||||
favoritesFile="${HOME}/.cliphist_favorites"
|
||||
|
||||
# Set rofi scaling
|
||||
[[ "${rofiScale}" =~ ^[0-9]+$ ]] || rofiScale=10
|
||||
r_scale="configuration {font: \"JetBrainsMono Nerd Font ${rofiScale}\";}"
|
||||
wind_border=$((hypr_border * 3 / 2))
|
||||
elem_border=$([ $hypr_border -eq 0 ] && echo "5" || echo $hypr_border)
|
||||
|
||||
# Evaluate spawn position
|
||||
readarray -t curPos < <(hyprctl cursorpos -j | jq -r '.x,.y')
|
||||
readarray -t monRes < <(hyprctl -j monitors | jq '.[] | select(.focused==true) | .width,.height,.scale,.x,.y')
|
||||
readarray -t offRes < <(hyprctl -j monitors | jq -r '.[] | select(.focused==true).reserved | map(tostring) | join("\n")')
|
||||
monRes[2]="$(echo "${monRes[2]}" | sed "s/\.//")"
|
||||
monRes[0]="$(( ${monRes[0]} * 100 / ${monRes[2]} ))"
|
||||
monRes[1]="$(( ${monRes[1]} * 100 / ${monRes[2]} ))"
|
||||
curPos[0]="$(( ${curPos[0]} - ${monRes[3]} ))"
|
||||
curPos[1]="$(( ${curPos[1]} - ${monRes[4]} ))"
|
||||
|
||||
if [ "${curPos[0]}" -ge "$((${monRes[0]} / 2))" ] ; then
|
||||
x_pos="east"
|
||||
x_off="-$(( ${monRes[0]} - ${curPos[0]} - ${offRes[2]} ))"
|
||||
else
|
||||
x_pos="west"
|
||||
x_off="$(( ${curPos[0]} - ${offRes[0]} ))"
|
||||
fi
|
||||
|
||||
if [ "${curPos[1]}" -ge "$((${monRes[1]} / 2))" ] ; then
|
||||
y_pos="south"
|
||||
y_off="-$(( ${monRes[1]} - ${curPos[1]} - ${offRes[3]} ))"
|
||||
else
|
||||
y_pos="north"
|
||||
y_off="$(( ${curPos[1]} - ${offRes[1]} ))"
|
||||
fi
|
||||
|
||||
r_override="window{location:${x_pos} ${y_pos};anchor:${x_pos} ${y_pos};x-offset:${x_off}px;y-offset:${y_off}px;border:${hypr_width}px;border-radius:${wind_border}px;} wallbox{border-radius:${elem_border}px;} element{border-radius:${elem_border}px;}"
|
||||
|
||||
# Show main menu if no arguments are passed
|
||||
if [ $# -eq 0 ]; then
|
||||
main_action=$(echo -e "History\nDelete\nView Favorites\nManage Favorites\nClear History" | rofi -dmenu -theme-str "entry { placeholder: \"Choose action\";}" -theme-str "${r_scale}" -theme-str "${r_override}" -config "${roconf}")
|
||||
else
|
||||
main_action="History"
|
||||
fi
|
||||
|
||||
case "${main_action}" in
|
||||
"History")
|
||||
selected_item=$(stash list | rofi -dmenu -theme-str "entry { placeholder: \"History...\";}" -theme-str "${r_scale}" -theme-str "${r_override}" -config "${roconf}")
|
||||
if [ -n "$selected_item" ]; then
|
||||
echo "$selected_item" | stash decode | wl-copy
|
||||
notify-send "Copied to clipboard."
|
||||
fi
|
||||
;;
|
||||
"Delete")
|
||||
selected_item=$(stash list | rofi -dmenu -theme-str "entry { placeholder: \"Delete...\";}" -theme-str "${r_scale}" -theme-str "${r_override}" -config "${roconf}")
|
||||
if [ -n "$selected_item" ]; then
|
||||
echo "$selected_item" | stash delete
|
||||
notify-send "Deleted."
|
||||
fi
|
||||
;;
|
||||
"View Favorites")
|
||||
if [ -f "$favoritesFile" ] && [ -s "$favoritesFile" ]; then
|
||||
# Read each Base64 encoded favorite as a separate line
|
||||
mapfile -t favorites < "$favoritesFile"
|
||||
|
||||
# Prepare a list of decoded single-line representations for rofi
|
||||
decoded_lines=()
|
||||
for favorite in "${favorites[@]}"; do
|
||||
decoded_favorite=$(echo "$favorite" | base64 --decode)
|
||||
# Replace newlines with spaces for rofi display
|
||||
single_line_favorite=$(echo "$decoded_favorite" | tr '\n' ' ')
|
||||
decoded_lines+=("$single_line_favorite")
|
||||
done
|
||||
|
||||
selected_favorite=$(printf "%s\n" "${decoded_lines[@]}" | rofi -dmenu -theme-str "entry { placeholder: \"View Favorites\";}" -theme-str "${r_scale}" -theme-str "${r_override}" -config "${roconf}")
|
||||
if [ -n "$selected_favorite" ]; then
|
||||
# Find the index of the selected favorite
|
||||
index=$(printf "%s\n" "${decoded_lines[@]}" | grep -nxF "$selected_favorite" | cut -d: -f1)
|
||||
# Use the index to get the Base64 encoded favorite
|
||||
if [ -n "$index" ]; then
|
||||
selected_encoded_favorite="${favorites[$((index - 1))]}"
|
||||
# Decode and copy the full multi-line content to clipboard
|
||||
echo "$selected_encoded_favorite" | base64 --decode | wl-copy
|
||||
notify-send "Copied to clipboard."
|
||||
else
|
||||
notify-send "Error: Selected favorite not found."
|
||||
fi
|
||||
fi
|
||||
else
|
||||
notify-send "No favorites."
|
||||
fi
|
||||
;;
|
||||
"Manage Favorites")
|
||||
manage_action=$(echo -e "Add to Favorites\nDelete from Favorites\nClear All Favorites" | rofi -dmenu -theme-str "entry { placeholder: \"Manage Favorites\";}" -theme-str "${r_scale}" -theme-str "${r_override}" -config "${roconf}")
|
||||
|
||||
case "${manage_action}" in
|
||||
"Add to Favorites")
|
||||
# Show clipboard history to add to favorites
|
||||
item=$(stash list | rofi -dmenu -theme-str "entry { placeholder: \"Add to Favorites...\";}" -theme-str "${r_scale}" -theme-str "${r_override}" -config "${roconf}")
|
||||
if [ -n "$item" ]; then
|
||||
full_item=$(echo "$item" | stash decode)
|
||||
encoded_item=$(echo "$full_item" | base64 -w 0)
|
||||
|
||||
# Check if the item is already in the favorites file
|
||||
if grep -Fxq "$encoded_item" "$favoritesFile"; then
|
||||
notify-send "Item is already in favorites."
|
||||
else
|
||||
# Add the encoded item to the favorites file
|
||||
echo "$encoded_item" >> "$favoritesFile"
|
||||
notify-send "Added in favorites."
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
"Delete from Favorites")
|
||||
if [ -f "$favoritesFile" ] && [ -s "$favoritesFile" ]; then
|
||||
# Read each Base64 encoded favorite as a separate line
|
||||
mapfile -t favorites < "$favoritesFile"
|
||||
|
||||
# Prepare a list of decoded single-line representations for rofi
|
||||
decoded_lines=()
|
||||
for favorite in "${favorites[@]}"; do
|
||||
decoded_favorite=$(echo "$favorite" | base64 --decode)
|
||||
# Replace newlines with spaces for rofi display
|
||||
single_line_favorite=$(echo "$decoded_favorite" | tr '\n' ' ')
|
||||
decoded_lines+=("$single_line_favorite")
|
||||
done
|
||||
|
||||
selected_favorite=$(printf "%s\n" "${decoded_lines[@]}" | rofi -dmenu -theme-str "entry { placeholder: \"Remove from Favorites...\";}" -theme-str "${r_scale}" -theme-str "${r_override}" -config "${roconf}")
|
||||
if [ -n "$selected_favorite" ]; then
|
||||
index=$(printf "%s\n" "${decoded_lines[@]}" | grep -nxF "$selected_favorite" | cut -d: -f1)
|
||||
if [ -n "$index" ]; then
|
||||
selected_encoded_favorite="${favorites[$((index - 1))]}"
|
||||
|
||||
# Handle case where only one item is present
|
||||
if [ "$(wc -l < "$favoritesFile")" -eq 1 ]; then
|
||||
# Remove the single encoded item from the file
|
||||
> "$favoritesFile"
|
||||
else
|
||||
# Remove the selected encoded item from the favorites file
|
||||
grep -vF -x "$selected_encoded_favorite" "$favoritesFile" > "${favoritesFile}.tmp" && mv "${favoritesFile}.tmp" "$favoritesFile"
|
||||
fi
|
||||
notify-send "Item removed from favorites."
|
||||
else
|
||||
notify-send "Error: Selected favorite not found."
|
||||
fi
|
||||
fi
|
||||
else
|
||||
notify-send "No favorites to remove."
|
||||
fi
|
||||
;;
|
||||
"Clear All Favorites")
|
||||
if [ -f "$favoritesFile" ] && [ -s "$favoritesFile" ]; then
|
||||
confirm=$(echo -e "Yes\nNo" | rofi -dmenu -theme-str "entry { placeholder: \"Clear All Favorites?\";}" -theme-str "${r_scale}" -theme-str "${r_override}" -config "${roconf}")
|
||||
if [ "$confirm" = "Yes" ]; then
|
||||
> "$favoritesFile"
|
||||
notify-send "All favorites have been deleted."
|
||||
fi
|
||||
else
|
||||
notify-send "No favorites to delete."
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "Invalid action"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
"Clear History")
|
||||
if [ "$(echo -e "Yes\nNo" | rofi -dmenu -theme-str "entry { placeholder: \"Clear Clipboard History?\";}" -theme-str "${r_scale}" -theme-str "${r_override}" -config "${roconf}")" == "Yes" ] ; then
|
||||
stash db wipe --expired
|
||||
notify-send "Clipboard history cleared."
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "Invalid action"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
64
scripts/cpuinfo.sh
Executable file
64
scripts/cpuinfo.sh
Executable file
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
map_floor() {
|
||||
|
||||
IFS=', ' read -r -a pairs <<< "$1"
|
||||
|
||||
if [[ ${pairs[-1]} != *":"* ]]; then
|
||||
def_val="${pairs[-1]}"
|
||||
unset 'pairs[${#pairs[@]}-1]'
|
||||
fi
|
||||
for pair in "${pairs[@]}"; do
|
||||
IFS=':' read -r key value <<< "$pair"
|
||||
if [ ${2%%.*} -gt $key ]; then
|
||||
echo "$value"
|
||||
return
|
||||
fi
|
||||
done
|
||||
[ -n "$def_val" ] && echo $def_val || echo " "
|
||||
}
|
||||
|
||||
# Define glyphs
|
||||
if [[ $NO_EMOJI -eq 1 ]]; then
|
||||
temp_lv="85:, 65:, 45:☁, ❄"
|
||||
else
|
||||
temp_lv="85:🌋, 65:🔥, 45:☁️, ❄️"
|
||||
fi
|
||||
util_lv="90:, 60:, 30:, "
|
||||
|
||||
# Get static CPU information
|
||||
model=$(lscpu | awk -F': ' '/Model name/ {gsub(/^ *| *$| CPU.*/,"",$2); print $2}')
|
||||
maxfreq=$(lscpu | awk '/CPU max MHz/ { sub(/\..*/,"",$4); print $4}')
|
||||
|
||||
# Get CPU stat
|
||||
statFile=$(cat /proc/stat | head -1)
|
||||
prevStat=$(awk '{print $2+$3+$4+$6+$7+$8 }' <<< $statFile)
|
||||
prevIdle=$(awk '{print $5 }' <<< $statFile)
|
||||
|
||||
while true; do
|
||||
# Get CPU stat
|
||||
statFile=$(cat /proc/stat | head -1)
|
||||
currStat=$(awk '{print $2+$3+$4+$6+$7+$8 }' <<< $statFile)
|
||||
currIdle=$(awk '{print $5 }' <<< $statFile)
|
||||
diffStat=$((currStat-prevStat))
|
||||
diffIdle=$((currIdle-prevIdle))
|
||||
|
||||
# Get dynamic CPU information
|
||||
utilization=$(awk -v stat="$diffStat" -v idle="$diffIdle" 'BEGIN {printf "%.1f", (stat/(stat+idle))*100}')
|
||||
temperature=$(sensors | awk -F': ' '/Package id 0|Tctl/ { gsub(/^ *\+?|\..*/,"",$2); print $2; f=1; exit} END { if (!f) print "N/A"; }')
|
||||
frequency=$(cat /proc/cpuinfo | awk '/cpu MHz/{ sum+=$4; c+=1 } END { printf "%.0f", sum/c }')
|
||||
|
||||
# Generate glyphs
|
||||
icons=$(echo "$(map_floor "$util_lv" $utilization)$(map_floor "$temp_lv" $temperature)")
|
||||
speedo=$(echo ${icons:0:1})
|
||||
thermo=$(echo ${icons:1:1})
|
||||
emoji=$(echo ${icons:2})
|
||||
|
||||
# Print the output
|
||||
echo "{\"text\":\"$thermo $temperature°C\", \"tooltip\":\"$model\n$thermo Temperature: $temperature°C $emoji\n$speedo Utilization: $utilization%\n Clock Speed: $frequency/$maxfreq MHz\"}"
|
||||
|
||||
# Store state and sleep
|
||||
prevStat=$currStat
|
||||
prevIdle=$currIdle
|
||||
sleep 5
|
||||
done
|
||||
5
scripts/dontkillsteam.sh
Executable file
5
scripts/dontkillsteam.sh
Executable file
@@ -0,0 +1,5 @@
|
||||
if [[ $(hyprctl activewindow -j | jq -r ".class") == "Steam" ]]; then
|
||||
xdotool windowunmap $(xdotool getactivewindow)
|
||||
else
|
||||
hyprctl dispatch killactive ""
|
||||
fi
|
||||
96
scripts/gamelauncher.sh
Executable file
96
scripts/gamelauncher.sh
Executable file
@@ -0,0 +1,96 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# set variables
|
||||
MODE=${1:-5}
|
||||
scrDir=`dirname "$(realpath "$0")"`
|
||||
source $scrDir/globalcontrol.sh
|
||||
ThemeSet="${confDir}/hypr/themes/theme.conf"
|
||||
RofiConf="${confDir}/rofi/steam/gamelauncher_${MODE}.rasi"
|
||||
|
||||
# set rofi override
|
||||
elem_border=$(( hypr_border * 2 ))
|
||||
icon_border=$(( elem_border - 3 ))
|
||||
r_override="element{border-radius:${elem_border}px;} element-icon{border-radius:${icon_border}px;}"
|
||||
|
||||
fn_steam() {
|
||||
# check steam mount paths
|
||||
SteamPaths=`grep '"path"' $SteamLib | awk -F '"' '{print $4}'`
|
||||
ManifestList=`find $SteamPaths/steamapps/ -type f -name "appmanifest_*.acf" 2>/dev/null`
|
||||
|
||||
# read installed games
|
||||
GameList=$(echo "$ManifestList" | while read acf
|
||||
do
|
||||
appid=`grep '"appid"' $acf | cut -d '"' -f 4`
|
||||
if [ -f ${SteamThumb}/${appid}_library_600x900.jpg ] ; then
|
||||
game=`grep '"name"' $acf | cut -d '"' -f 4`
|
||||
echo "$game|$appid"
|
||||
else
|
||||
continue
|
||||
fi
|
||||
done | sort)
|
||||
|
||||
# launch rofi menu
|
||||
RofiSel=$( echo "$GameList" | while read acf
|
||||
do
|
||||
appid=`echo $acf | cut -d '|' -f 2`
|
||||
game=`echo $acf | cut -d '|' -f 1`
|
||||
echo -en "$game\x00icon\x1f${SteamThumb}/${appid}_library_600x900.jpg\n"
|
||||
done | rofi -dmenu -theme-str "${r_override}" -config $RofiConf)
|
||||
|
||||
# launch game
|
||||
if [ ! -z "$RofiSel" ] ; then
|
||||
launchid=`echo "$GameList" | grep "$RofiSel" | cut -d '|' -f 2`
|
||||
${steamlaunch} -applaunch "${launchid} [gamemoderun %command%]" &
|
||||
# dunstify "t1" -a "Launching ${RofiSel}..." -i ${SteamThumb}/${launchid}_header.jpg -r 91190 -t 2200
|
||||
notify-send -a "t1" -i "${SteamThumb}/${launchid}_header.jpg" "Launching ${RofiSel}..."
|
||||
|
||||
fi
|
||||
}
|
||||
|
||||
fn_lutris() {
|
||||
[ ! -e "${icon_path}" ] && icon_path="${HOME}/.local/share/lutris/coverart"
|
||||
[ ! -e "${icon_path}" ] && icon_path="${HOME}/.cache/lutris/coverart"
|
||||
meta_data="/tmp/hyprdots-$(id -u)-lutrisgames.json"
|
||||
|
||||
# Retrieve the list of games from Lutris in JSON format
|
||||
#TODO Only call this if new apps are installed...
|
||||
# [ ! -s "${meta_data}" ] &&
|
||||
notify-send -a "t1" "Please wait... " -t 4000
|
||||
|
||||
eval "${run_lutris}" -j -l 2> /dev/null| jq --arg icons "$icon_path/" --arg prefix ".jpg" '.[] |= . + {"select": (.name + "\u0000icon\u001f" + $icons + .slug + $prefix)}' > "${meta_data}"
|
||||
|
||||
[ ! -s "${meta_data}" ] && notify-send -a "t1" "Cannot Fetch Lutris Games!" && exit 1
|
||||
|
||||
|
||||
CHOICE=$(jq -r '.[].select' "${meta_data}" | rofi -dmenu -p Lutris -theme-str "${r_override}" -config "${RofiConf}" )
|
||||
[ -z "$CHOICE" ] && exit 0
|
||||
SLUG=$(jq -r --arg choice "$CHOICE" '.[] | select(.name == $choice).slug' "${meta_data}" )
|
||||
notify-send -a "t1" -i "${icon_path}/${SLUG}.jpg" "Launching ${CHOICE}..."
|
||||
exec xdg-open "lutris:rungame/${SLUG}"
|
||||
}
|
||||
|
||||
# Handle if flatpak or pkgmgr
|
||||
run_lutris=""
|
||||
( flatpak list --columns=application | grep -q "net.lutris.Lutris" ) && run_lutris="flatpak run net.lutris.Lutris" ; icon_path="${HOME}/.var/app/net.lutris.Lutris/data/lutris/coverart/"
|
||||
[ -z "${run_lutris}" ] && ( pkg_installed 'lutris' ) && run_lutris="lutris"
|
||||
|
||||
if [ -z "${run_lutris}" ] || echo "$*" | grep -q "steam" ; then
|
||||
# set steam library
|
||||
if pkg_installed steam ; then
|
||||
SteamLib="${XDG_DATA_HOME:-$HOME/.local/share}/Steam/config/libraryfolders.vdf"
|
||||
SteamThumb="${XDG_DATA_HOME:-$HOME/.local/share}/Steam/appcache/librarycache"
|
||||
steamlaunch="steam"
|
||||
else
|
||||
SteamLib="$HOME/.var/app/com.valvesoftware.Steam/.local/share/Steam/config/libraryfolders.vdf"
|
||||
SteamThumb="$HOME/.var/app/com.valvesoftware.Steam/.local/share/Steam/appcache/librarycache"
|
||||
steamlaunch="flatpak run com.valvesoftware.Steam"
|
||||
fi
|
||||
|
||||
if [ ! -f $SteamLib ] || [ ! -d $SteamThumb ] ; then
|
||||
notify-send -a "t1" "Steam library not found!"
|
||||
exit 1
|
||||
fi
|
||||
fn_steam
|
||||
else
|
||||
fn_lutris
|
||||
fi
|
||||
16
scripts/gamemode.nix
Normal file
16
scripts/gamemode.nix
Normal file
@@ -0,0 +1,16 @@
|
||||
{ pkgs }:
|
||||
|
||||
pkgs.writeShellScriptBin "gamemode" ''
|
||||
# Toggle animations on/off for gaming mode
|
||||
status=$(${pkgs.hyprland}/bin/hyprctl getoption animations:enabled | grep -oP 'int: \K[0-9]+')
|
||||
|
||||
if [ "$status" = "1" ]; then
|
||||
# Disable animations
|
||||
${pkgs.hyprland}/bin/hyprctl keyword animations:enabled 0
|
||||
${pkgs.libnotify}/bin/notify-send "Gamemode: ON" "Animations disabled"
|
||||
else
|
||||
# Enable animations
|
||||
${pkgs.hyprland}/bin/hyprctl keyword animations:enabled 1
|
||||
${pkgs.libnotify}/bin/notify-send "Gamemode: OFF" "Animations enabled"
|
||||
fi
|
||||
''
|
||||
29
scripts/gamemode.sh
Executable file
29
scripts/gamemode.sh
Executable file
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env sh
|
||||
HYPRGAMEMODE=$(hyprctl getoption animations:enabled | sed -n '1p' | awk '{print $2}')
|
||||
|
||||
# Waybar performance
|
||||
FILE="$HOME/.config/waybar/style.css"
|
||||
|
||||
sed -i 's/\/\* \(.*animation:.*\) \*\//\1/g' $FILE
|
||||
sed -i 's/\/\* \(.*transition:.*\) \*\//\1/g' $FILE
|
||||
if [ $HYPRGAMEMODE = 1 ]; then
|
||||
sed -i 's/^\(.*animation:.*\)$/\/\* \1 \*\//g' $FILE
|
||||
sed -i 's/^\(.*transition:.*\)$/\/\* \1 \*\//g' $FILE
|
||||
fi
|
||||
killall waybar
|
||||
waybar >/dev/null 2>&1 &
|
||||
|
||||
# Hyprland performance
|
||||
if [ $HYPRGAMEMODE = 1 ]; then
|
||||
hyprctl --batch "\
|
||||
keyword animations:enabled 0;\
|
||||
keyword decoration:drop_shadow 0;\
|
||||
keyword decoration:blur:enabled 0;\
|
||||
keyword general:gaps_in 0;\
|
||||
keyword general:gaps_out 0;\
|
||||
keyword general:border_size 1;\
|
||||
keyword decoration:rounding 0"
|
||||
exit
|
||||
else
|
||||
hyprctl reload
|
||||
fi
|
||||
159
scripts/globalcontrol.sh
Executable file
159
scripts/globalcontrol.sh
Executable file
@@ -0,0 +1,159 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
|
||||
#// hyde envs
|
||||
|
||||
export confDir="${XDG_CONFIG_HOME:-$HOME/.config}"
|
||||
export hydeConfDir="${confDir}/hyde"
|
||||
export cacheDir="$HOME/.cache/hyde"
|
||||
export thmbDir="${cacheDir}/thumbs"
|
||||
export dcolDir="${cacheDir}/dcols"
|
||||
export hashMech="sha1sum"
|
||||
|
||||
get_hashmap()
|
||||
{
|
||||
unset wallHash
|
||||
unset wallList
|
||||
unset skipStrays
|
||||
unset verboseMap
|
||||
|
||||
for wallSource in "$@"; do
|
||||
[ -z "${wallSource}" ] && continue
|
||||
[ "${wallSource}" == "--skipstrays" ] && skipStrays=1 && continue
|
||||
[ "${wallSource}" == "--verbose" ] && verboseMap=1 && continue
|
||||
|
||||
hashMap=$(find "${wallSource}" -type f \( -iname "*.gif" -o -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" \) -exec "${hashMech}" {} + | sort -k2)
|
||||
if [ -z "${hashMap}" ] ; then
|
||||
echo "WARNING: No image found in \"${wallSource}\""
|
||||
continue
|
||||
fi
|
||||
|
||||
while read -r hash image ; do
|
||||
wallHash+=("${hash}")
|
||||
wallList+=("${image}")
|
||||
done <<< "${hashMap}"
|
||||
done
|
||||
|
||||
if [ -z "${#wallList[@]}" ] || [[ "${#wallList[@]}" -eq 0 ]] ; then
|
||||
if [[ "${skipStrays}" -eq 1 ]] ; then
|
||||
return 1
|
||||
else
|
||||
echo "ERROR: No image found in any source"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "${verboseMap}" -eq 1 ]] ; then
|
||||
echo "// Hash Map //"
|
||||
for indx in "${!wallHash[@]}" ; do
|
||||
echo ":: \${wallHash[${indx}]}=\"${wallHash[indx]}\" :: \${wallList[${indx}]}=\"${wallList[indx]}\""
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
get_themes()
|
||||
{
|
||||
unset thmSortS
|
||||
unset thmListS
|
||||
unset thmWallS
|
||||
unset thmSort
|
||||
unset thmList
|
||||
unset thmWall
|
||||
|
||||
while read thmDir ; do
|
||||
if [ ! -e "$(readlink "${thmDir}/wall.set")" ] ; then
|
||||
get_hashmap "${thmDir}" --skipstrays || continue
|
||||
echo "fixig link :: ${thmDir}/wall.set"
|
||||
ln -fs "${wallList[0]}" "${thmDir}/wall.set"
|
||||
fi
|
||||
[ -f "${thmDir}/.sort" ] && thmSortS+=("$(head -1 "${thmDir}/.sort")") || thmSortS+=("0")
|
||||
thmListS+=("$(basename "${thmDir}")")
|
||||
thmWallS+=("$(readlink "${thmDir}/wall.set")")
|
||||
done < <(find "${hydeConfDir}/themes" -mindepth 1 -maxdepth 1 -type d)
|
||||
|
||||
while IFS='|' read -r sort theme wall ; do
|
||||
thmSort+=("${sort}")
|
||||
thmList+=("${theme}")
|
||||
thmWall+=("${wall}")
|
||||
done < <(parallel --link echo "{1}\|{2}\|{3}" ::: "${thmSortS[@]}" ::: "${thmListS[@]}" ::: "${thmWallS[@]}" | sort -n -k 1 -k 2)
|
||||
|
||||
if [ "${1}" == "--verbose" ] ; then
|
||||
echo "// Theme Control //"
|
||||
for indx in "${!thmList[@]}" ; do
|
||||
echo -e ":: \${thmSort[${indx}]}=\"${thmSort[indx]}\" :: \${thmList[${indx}]}=\"${thmList[indx]}\" :: \${thmWall[${indx}]}=\"${thmWall[indx]}\""
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
[ -f "${hydeConfDir}/hyde.conf" ] && source "${hydeConfDir}/hyde.conf"
|
||||
|
||||
case "${enableWallDcol}" in
|
||||
0|1|2|3) ;;
|
||||
*) enableWallDcol=0 ;;
|
||||
esac
|
||||
|
||||
if [ -z "${hydeTheme}" ] || [ ! -d "${hydeConfDir}/themes/${hydeTheme}" ] ; then
|
||||
get_themes
|
||||
hydeTheme="${thmList[0]}"
|
||||
fi
|
||||
|
||||
export hydeTheme
|
||||
export hydeThemeDir="${hydeConfDir}/themes/${hydeTheme}"
|
||||
export wallbashDir="${hydeConfDir}/wallbash"
|
||||
export enableWallDcol
|
||||
|
||||
|
||||
#// hypr vars
|
||||
|
||||
if printenv HYPRLAND_INSTANCE_SIGNATURE &> /dev/null; then
|
||||
export hypr_border="$(hyprctl -j getoption decoration:rounding | jq '.int')"
|
||||
export hypr_width="$(hyprctl -j getoption general:border_size | jq '.int')"
|
||||
fi
|
||||
|
||||
|
||||
#// extra fns
|
||||
|
||||
pkg_installed()
|
||||
{
|
||||
local pkgIn=$1
|
||||
if pacman -Qi "${pkgIn}" &> /dev/null ; then
|
||||
return 0
|
||||
elif pacman -Qi "flatpak" &> /dev/null && flatpak info "${pkgIn}" &> /dev/null ; then
|
||||
return 0
|
||||
elif command -v "${pkgIn}" &> /dev/null ; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
get_aurhlpr()
|
||||
{
|
||||
if pkg_installed yay
|
||||
then
|
||||
aurhlpr="yay"
|
||||
elif pkg_installed paru
|
||||
then
|
||||
aurhlpr="paru"
|
||||
fi
|
||||
}
|
||||
|
||||
set_conf()
|
||||
{
|
||||
local varName="${1}"
|
||||
local varData="${2}"
|
||||
touch "${hydeConfDir}/hyde.conf"
|
||||
|
||||
if [ $(grep -c "^${varName}=" "${hydeConfDir}/hyde.conf") -eq 1 ] ; then
|
||||
sed -i "/^${varName}=/c${varName}=\"${varData}\"" "${hydeConfDir}/hyde.conf"
|
||||
else
|
||||
echo "${varName}=\"${varData}\"" >> "${hydeConfDir}/hyde.conf"
|
||||
fi
|
||||
}
|
||||
|
||||
set_hash()
|
||||
{
|
||||
local hashImage="${1}"
|
||||
"${hashMech}" "${hashImage}" | awk '{print $1}'
|
||||
}
|
||||
|
||||
292
scripts/gpuinfo.sh
Executable file
292
scripts/gpuinfo.sh
Executable file
@@ -0,0 +1,292 @@
|
||||
#!/usr/bin/env bash
|
||||
# shellcheck disable=SC2312
|
||||
# shellcheck disable=SC1090
|
||||
scrDir=`dirname "$(realpath "$0")"`
|
||||
gpuQ="/tmp/hyprdots-${UID}-gpuinfo-query"
|
||||
tired=false
|
||||
[[ " $* " =~ " tired " ]] && ! grep -q "tired" "${gpuQ}" && echo "tired=true" >>"${gpuQ}"
|
||||
[[ " $* " =~ " no_emoji " ]] && ! grep -q "NO_EMOJI" "${gpuQ}" && echo "NO_EMOJI=1" >>"${gpuQ}"
|
||||
|
||||
if [[ ! " $* " =~ " startup " ]]; then
|
||||
gpuQ="${gpuQ}$2"
|
||||
fi
|
||||
detect() { # Auto detect Gpu used by Hyprland(declared using env = WLR_DRM_DEVICES) Sophisticated?
|
||||
card=$(echo "${WLR_DRM_DEVICES}" | cut -d':' -f1 | cut -d'/' -f4)
|
||||
# shellcheck disable=SC2010
|
||||
slot_number=$(ls -l /dev/dri/by-path/ | grep "${card}" | awk -F'pci-0000:|-card' '{print $2}')
|
||||
vendor_id=$(lspci -nn -s "${slot_number}" )
|
||||
declare -A vendors=(["10de"]="nvidia" ["8086"]="intel" ["1002"]="amd")
|
||||
for vendor in "${!vendors[@]}"; do
|
||||
if [[ ${vendor_id} == *"${vendor}"* ]]; then
|
||||
initGPU="${vendors[${vendor}]}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [[ -n ${initGPU} ]]; then
|
||||
$0 --use "${initGPU}" startup
|
||||
fi
|
||||
}
|
||||
|
||||
query() {
|
||||
nvidia_flag=0 amd_flag=0 intel_flag=0
|
||||
touch "${gpuQ}"
|
||||
|
||||
if lsmod | grep -q 'nouveau'; then
|
||||
echo "nvidia_gpu=\"Linux\"" >>"${gpuQ}" #? Incase If nouveau is installed
|
||||
echo "nvidia_flag=1 # Using nouveau an open-source nvidia driver" >>"${gpuQ}"
|
||||
elif command -v nvidia-smi &> /dev/null; then
|
||||
nvidia_gpu=$(nvidia-smi --query-gpu=gpu_name --format=csv,noheader,nounits | head -n 1)
|
||||
if [[ -n "${nvidia_gpu}" ]] ; then # Check for NVIDIA GPU
|
||||
if [[ "${nvidia_gpu}" == *"NVIDIA-SMI has failed"* ]]; then #? Second Layer for dGPU
|
||||
echo "nvidia_flag=0 # NVIDIA-SMI has failed" >> "${gpuQ}"
|
||||
else
|
||||
nvidia_address=$(lspci | grep -Ei "VGA|3D" | grep -i "${nvidia_gpu/NVIDIA /}" | cut -d' ' -f1)
|
||||
{ echo "nvidia_address=\"${nvidia_address}\""
|
||||
echo "nvidia_gpu=\"${nvidia_gpu/NVIDIA /}\""
|
||||
echo "nvidia_flag=1"
|
||||
} >> "${gpuQ}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if lspci -nn | grep -E "(VGA|3D)" | grep -iq "1002"; then
|
||||
amd_gpu="$(lspci -nn | grep -Ei "VGA|3D" | grep -m 1 "1002" | awk -F'Advanced Micro Devices, Inc. ' '{gsub(/ *\[[^\]]*\]/,""); gsub(/ *\([^)]*\)/,""); print $2}')"
|
||||
amd_address=$(lspci | grep -Ei "VGA|3D" | grep -i "${amd_gpu}" | cut -d' ' -f1)
|
||||
{ echo "amd_address=\"${amd_address}\""
|
||||
echo "amd_flag=1" # Check for Amd GPU
|
||||
echo "amd_gpu=\"${amd_gpu}\""
|
||||
} >> "${gpuQ}";fi
|
||||
|
||||
if lspci -nn | grep -E "(VGA|3D)" | grep -iq "8086"; then
|
||||
intel_gpu="$(lspci -nn | grep -Ei "VGA|3D" | grep -m 1 "8086" | awk -F'Intel Corporation ' '{gsub(/ *\[[^\]]*\]/,""); gsub(/ *\([^)]*\)/,""); print $2}')"
|
||||
intel_address=$(lspci | grep -Ei "VGA|3D" | grep -i "${intel_gpu}" | cut -d' ' -f1)
|
||||
{ echo "intel_address=\"${intel_address}\""
|
||||
echo "intel_flag=1" # Check for Intel GPU
|
||||
echo "intel_gpu=\"${intel_gpu}\""
|
||||
} >>"${gpuQ}"; fi
|
||||
|
||||
if ! grep -q "prioGPU=" "${gpuQ}" && [[ -n "${WLR_DRM_DEVICES}" ]]; then
|
||||
trap detect EXIT
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
toggle() {
|
||||
if [[ -n "$1" ]]; then
|
||||
next_prioGPU="$1_flag"
|
||||
else
|
||||
# Initialize gpu_flags and prioGPU if they don't exist
|
||||
if ! grep -q "gpu_flags=" "${gpuQ}"; then
|
||||
gpu_flags=$(grep "flag=1" "${gpuQ}" | cut -d '=' -f 1 | tr '\n' ' ' | tr -d '#')
|
||||
echo "" >> "${gpuQ}"
|
||||
echo "gpu_flags=\"${gpu_flags[*]}\"" >> "${gpuQ}"
|
||||
fi
|
||||
|
||||
if ! grep -q "prioGPU=" "${gpuQ}"; then
|
||||
gpu_flags=$(grep "gpu_flags=" "${gpuQ}" | cut -d'=' -f 2)
|
||||
initGPU=$(echo "${gpu_flags}" | cut -d ' ' -f 1)
|
||||
echo "prioGPU=${initGPU}" >> "${gpuQ}"
|
||||
fi
|
||||
mapfile -t anchor < <(grep "flag=1" "${gpuQ}" | cut -d '=' -f 1)
|
||||
prioGPU=$(grep "prioGPU=" "${gpuQ}" | cut -d'=' -f 2) # Get the current prioGPU from the file
|
||||
# Find the index of the current prioGPU in the anchor array
|
||||
for index in "${!anchor[@]}"; do
|
||||
if [[ "${anchor[${index}]}" = "${prioGPU}" ]]; then
|
||||
current_index=${index}
|
||||
fi
|
||||
done
|
||||
next_index=$(( (current_index + 1) % ${#anchor[@]} ))
|
||||
next_prioGPU=${anchor[${next_index}]#\#}
|
||||
fi
|
||||
|
||||
# Set the next prioGPU and remove the '#' character
|
||||
sed -i 's/^\(nvidia_flag=1\|amd_flag=1\|intel_flag=1\)/#\1/' "${gpuQ}" # Comment out all the gpu flags in the file
|
||||
sed -i "s/^#${next_prioGPU}/${next_prioGPU}/" "${gpuQ}" # Uncomment the next prioGPU in the file
|
||||
sed -i "s/prioGPU=${prioGPU}/prioGPU=${next_prioGPU}/" "${gpuQ}" # Update the prioGPU in the file
|
||||
}
|
||||
|
||||
# Thee shalt find the greatest one,
|
||||
# He who not more than the chosen one
|
||||
map_floor() {
|
||||
|
||||
# From the depths of the string, words arise,
|
||||
# Keys in pairs, a treasure in disguise.
|
||||
IFS=', ' read -r -a pairs <<< "$1"
|
||||
|
||||
# If the final token stands alone and bold,
|
||||
# Declare it the default, its worth untold.
|
||||
if [[ ${pairs[-1]} != *":"* ]]; then
|
||||
def_val="${pairs[-1]}"
|
||||
unset 'pairs[${#pairs[@]}-1]'
|
||||
fi
|
||||
|
||||
# Scans the map, a peak it seeks,
|
||||
# The highest passed, the value speaks.
|
||||
for pair in "${pairs[@]}"; do
|
||||
IFS=':' read -r key value <<< "$pair"
|
||||
|
||||
# Behold! Thou holds the secrets they seek,
|
||||
# Declare it and silence the whispers unique.
|
||||
if [ ${2%%.*} -gt $key ]; then
|
||||
echo "$value"
|
||||
return
|
||||
fi
|
||||
done
|
||||
|
||||
# On this lonely shore, where silence dwells
|
||||
# Even the waves, echoes words unheard
|
||||
[ -n "$def_val" ] && echo $def_val || echo " "
|
||||
}
|
||||
|
||||
generate_json() {
|
||||
# Generate glyphs
|
||||
icons=$(echo "$(map_floor "$util_lv" $utilization)$(map_floor "$temp_lv" $temperature)")
|
||||
speedo=$(echo ${icons:0:1})
|
||||
thermo=$(echo ${icons:1:1})
|
||||
emoji=$(echo ${icons:2})
|
||||
|
||||
local json="{\"text\":\"${thermo} ${temperature}°C\", \"tooltip\":\"${primary_gpu}\n${thermo} Temperature: ${temperature}°C ${emoji}"
|
||||
#? Soon Add Something incase needed.
|
||||
declare -A tooltip_parts
|
||||
if [[ -n "${utilization}" ]]; then tooltip_parts["\n$speedo Utilization: "]="${utilization}%" ; fi
|
||||
if [[ -n "${current_clock_speed}" ]] && [[ -n "${max_clock_speed}" ]]; then tooltip_parts["\n Clock Speed: "]="${current_clock_speed}/${max_clock_speed} MHz" ; fi
|
||||
if [[ -n "${gpu_load}" ]]; then tooltip_parts["\n$speedo Utilization: "]="${gpu_load}%" ; fi
|
||||
if [[ -n "${core_clock}" ]]; then tooltip_parts["\n Clock Speed: "]="${core_clock} MHz" ;fi
|
||||
if [[ -n "${power_usage}" ]]; then if [[ -n "${power_limit}" ]]; then
|
||||
tooltip_parts["\n Power Usage: "]="${power_usage}/${power_limit} W"
|
||||
else
|
||||
tooltip_parts["\n Power Usage: "]="${power_usage} W"
|
||||
fi
|
||||
fi
|
||||
if [[ -n "${power_discharge}" ]] && [[ "${power_discharge}" != "0" ]]; then tooltip_parts["\n Power Discharge: "]="${power_discharge} W" ;fi
|
||||
|
||||
for key in "${!tooltip_parts[@]}"; do
|
||||
local value="${tooltip_parts[${key}]}"
|
||||
if [[ -n "${value}" && "${value}" =~ [a-zA-Z0-9] ]]; then
|
||||
json+="${key}${value}"
|
||||
fi
|
||||
done
|
||||
json="${json}\"}"
|
||||
echo "${json}"
|
||||
}
|
||||
|
||||
general_query() { # Function to get temperature from 'sensors'
|
||||
filter=''
|
||||
temperature=$(sensors | ${filter} grep -m 1 -E "(edge|Package id.*|another keyword)" | awk -F ':' '{print int($2)}') #! We can get json data from sensors too
|
||||
# gpu_load=$()
|
||||
# core_clock=$()
|
||||
for file in /sys/class/power_supply/BAT*/power_now; do
|
||||
[[ -f "${file}" ]] && power_discharge=$(awk '{print $1*10^-6 ""}' "${file}") && break
|
||||
done
|
||||
[[ -z "${power_discharge}" ]] && for file in /sys/class/power_supply/BAT*/current_now; do
|
||||
[[ -e "${file}" ]] && power_discharge=$(awk -v current="$(cat "${file}")" -v voltage="$(cat "${file/current_now/voltage_now}")" 'BEGIN {print (current * voltage) / 10^12 ""}') && break
|
||||
done
|
||||
# power_limit=$()
|
||||
utilization=$(top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | awk '{print 100 - $1" "}')
|
||||
current_clock_speed=$(awk '{sum += $1; n++} END {if (n > 0) print sum / n / 1000 ""}' /sys/devices/system/cpu/cpufreq/policy*/scaling_cur_freq)
|
||||
max_clock_speed=$(awk '{print $1/1000}' /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq)
|
||||
}
|
||||
|
||||
intel_GPU() { #? Function to query basic intel GPU
|
||||
primary_gpu="Intel ${intel_gpu}"
|
||||
general_query
|
||||
}
|
||||
|
||||
nvidia_GPU() { #? Function to query Nvidia GPU
|
||||
primary_gpu="NVIDIA ${nvidia_gpu}"
|
||||
if [[ "${nvidia_gpu}" == "Linux" ]]; then general_query ; return ; fi #? Open source driver
|
||||
#? Tired Flag for not using nvidia-smi if GPU is in suspend mode.
|
||||
if ${tired}; then is_suspend="$(cat /sys/bus/pci/devices/0000:"${nvidia_address}"/power/runtime_status)"
|
||||
if [[ ${is_suspend} == *"suspend"* ]]; then
|
||||
printf '{"text":"", "tooltip":"%s ⏾ Suspended mode"}' "${primary_gpu}"; exit ;fi
|
||||
fi
|
||||
gpu_info=$(nvidia-smi --query-gpu=temperature.gpu,utilization.gpu,clocks.current.graphics,clocks.max.graphics,power.draw,power.limit --format=csv,noheader,nounits)
|
||||
# Split the comma-separated values into an array
|
||||
IFS=',' read -ra gpu_data <<< "${gpu_info}"
|
||||
# Extract individual values
|
||||
temperature="${gpu_data[0]// /}"
|
||||
utilization="${gpu_data[1]// /}"
|
||||
current_clock_speed="${gpu_data[2]// /}"
|
||||
max_clock_speed="${gpu_data[3]// /}"
|
||||
power_usage="${gpu_data[4]// /}"
|
||||
power_limit="${gpu_data[5]// /}"
|
||||
}
|
||||
|
||||
amd_GPU() { #? Function to query amd GPU
|
||||
primary_gpu="AMD ${amd_gpu}"
|
||||
# Execute the AMD GPU Python script and use its output
|
||||
amd_output=$(python3 ${scrDir}/amdgpu.py)
|
||||
if [[ ! ${amd_output} == *"No AMD GPUs detected."* ]] && [[ ! ${amd_output} == *"Unknown query failure"* ]]; then
|
||||
# Extract GPU Temperature, GPU Load, GPU Core Clock, and GPU Power Usage from amd_output
|
||||
temperature=$(echo "${amd_output}" | jq -r '.["GPU Temperature"]' | sed 's/°C//')
|
||||
gpu_load=$(echo "${amd_output}" | jq -r '.["GPU Load"]' | sed 's/%//')
|
||||
core_clock=$(echo "${amd_output}" | jq -r '.["GPU Core Clock"]' | sed 's/ GHz//;s/ MHz//')
|
||||
power_usage=$(echo "${amd_output}" | jq -r '.["GPU Power Usage"]' | sed 's/ Watts//')
|
||||
|
||||
|
||||
else
|
||||
general_query
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ ! -f "${gpuQ}" ]]; then
|
||||
query ; echo -e "Initialized Variable:\n$(cat "${gpuQ}")\n\nReboot or '$0 --reset' to RESET Variables"
|
||||
fi
|
||||
source "${gpuQ}"
|
||||
case "$1" in
|
||||
"--toggle"|"-t")
|
||||
toggle
|
||||
echo -e "Sensor: ${next_prioGPU} GPU" | sed 's/_flag//g'
|
||||
exit
|
||||
;;
|
||||
"--use"|"-u")
|
||||
toggle "$2"
|
||||
;;
|
||||
"--reset"|"-rf")
|
||||
rm -fr "${gpuQ}"*
|
||||
query
|
||||
echo -e "Initialized Variable:\n$(cat "${gpuQ}" || true)\n\nReboot or '$0 --reset' to RESET Variables"
|
||||
exit
|
||||
;;
|
||||
*"-"*)
|
||||
gpu_flags=$(grep "flag=1" "${gpuQ}" | cut -d '=' -f 1 | tr '\n' ' ' | tr -d '#')
|
||||
cat << EOF
|
||||
|
||||
Available GPU: ${gpu_flags//_flag/}
|
||||
[options]
|
||||
--toggle * Toggle available GPU
|
||||
--use [GPU] * Only call the specified GPU (Useful for adding specific GPU on waybar)
|
||||
--reset * Remove & restart all query
|
||||
|
||||
[flags]
|
||||
tired * Adding this option will not query nvidia-smi if gpu is in suspend mode
|
||||
startup * Useful if you want a certain GPU to be set at startup
|
||||
no_emoji * Use glyphs instead of emoji
|
||||
|
||||
* If ${USER} declared env = WLR_DRM_DEVICES on hyprland then use this as the primary GPU
|
||||
EOF
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
|
||||
# Define glyphs
|
||||
if [[ $NO_EMOJI -eq 1 ]]; then
|
||||
temp_lv="85:, 65:, 45:☁, ❄"
|
||||
else
|
||||
temp_lv="85:🌋, 65:🔥, 45:☁️, ❄️"
|
||||
fi
|
||||
util_lv="90:, 60:, 30:, "
|
||||
|
||||
nvidia_flag=${nvidia_flag:-0} intel_flag=${intel_flag:-0} amd_flag=${amd_flag:-0}
|
||||
#? Based on the flags, call the corresponding function multi flags means multi GPU.
|
||||
if [[ "${nvidia_flag}" -eq 1 ]]; then
|
||||
nvidia_GPU
|
||||
elif [[ "${amd_flag}" -eq 1 ]]; then
|
||||
amd_GPU
|
||||
elif [[ "${intel_flag}" -eq 1 ]]; then
|
||||
intel_GPU
|
||||
else primary_gpu="Not found"
|
||||
general_query
|
||||
fi
|
||||
|
||||
generate_json #? AutoGen the Json txt for Waybar
|
||||
96
scripts/install.sh
Normal file
96
scripts/install.sh
Normal file
@@ -0,0 +1,96 @@
|
||||
# #!/usr/bin/env bash
|
||||
# # install.sh - Setup Cody's Dotfiles Environment (Nix + Home Manager)
|
||||
#
|
||||
# set -e
|
||||
# # Always cd to the parent (repo root) so all operations work from repo base directory
|
||||
# cd "$(dirname "$0")/.."
|
||||
#
|
||||
# # Colors for prettiness
|
||||
# green='\033[0;32m'
|
||||
# red='\033[0;31m'
|
||||
# yellow='\033[1;33m'
|
||||
# normal='\033[0m'
|
||||
#
|
||||
# info() { echo -e "${green}[INFO]${normal} $*"; }
|
||||
# warn() { echo -e "${yellow}[WARN]${normal} $*"; }
|
||||
# err() { echo -e "${red}[ERROR]${normal} $*"; }
|
||||
#
|
||||
# ## Step 1: Check for Nix
|
||||
# if ! command -v nix &> /dev/null; then
|
||||
# err "Nix is not installed! Please install Nix first: https://nixos.org/download.html"
|
||||
# exit 1
|
||||
# else
|
||||
# info "Nix is installed."
|
||||
# fi
|
||||
#
|
||||
# ## Step 2: Enable flakes (if needed)
|
||||
# if ! nix --experimental-features 'nix-command flakes' flake show &> /dev/null; then
|
||||
# warn "Nix flakes may not be enabled. Ensure your Nix version supports flakes!"
|
||||
# info "Try adding experimental-features in /etc/nix/nix.conf or your user config."
|
||||
# exit 1
|
||||
# else
|
||||
# info "Nix flakes are working."
|
||||
# fi
|
||||
#
|
||||
# ## Step 3: Home Manager presence (not mandatory but recommended)
|
||||
# if ! nix flake show | grep -q 'homeConfigurations'; then
|
||||
# warn "Home Manager config not detected in flake output. Ensure it's declared if you want full integration."
|
||||
# fi
|
||||
#
|
||||
# ## Step 4: Detect host
|
||||
# HOST="$(hostname)"
|
||||
#
|
||||
# # Step 4a: Ensure hosts/ exists
|
||||
# if [[ ! -d hosts ]]; then
|
||||
# warn "No hosts/ directory detected. Creating one."
|
||||
# mkdir hosts
|
||||
# info "Created hosts/ directory."
|
||||
# fi
|
||||
#
|
||||
# # Step 4b: Prompt for host if needed; create scaffold if host missing
|
||||
# if [[ ! -d "hosts/$HOST" ]]; then
|
||||
# warn "No host config found for '$HOST' in hosts/."
|
||||
# ls -1 hosts/ || info "No hosts configured yet."
|
||||
# read -rp "Enter the host name you want to use (type exactly): " HOST
|
||||
# if [[ ! -d "hosts/$HOST" ]]; then
|
||||
# info "Scaffolding minimal host config in hosts/$HOST ..."
|
||||
# mkdir -p "hosts/$HOST"
|
||||
# # Make home.nix
|
||||
# cat > "hosts/$HOST/home.nix" << EOF
|
||||
# { config, pkgs, ... }:
|
||||
# {
|
||||
# home.username = "$USER";
|
||||
# home.homeDirectory = "/home/$USER";
|
||||
# programs.zsh.enable = true;
|
||||
# home.stateVersion = "24.05";
|
||||
# }
|
||||
# EOF
|
||||
# # Make configuration.nix
|
||||
# cat > "hosts/$HOST/configuration.nix" << EOF
|
||||
# { config, pkgs, ... }:
|
||||
# {
|
||||
# imports = [ ];
|
||||
# networking.hostName = "$HOST";
|
||||
# system.stateVersion = "24.05";
|
||||
# }
|
||||
# EOF
|
||||
# info "Scaffolded hosts/$HOST/home.nix and configuration.nix."
|
||||
# warn "You MUST now add this new host to your flake.nix under nixosConfigurations and/or homeConfigurations."
|
||||
# info "See hosts/$HOST/home.nix and configuration.nix for templates."
|
||||
# fi
|
||||
# fi
|
||||
# info "Using host: $HOST"
|
||||
#
|
||||
# ## Step 5: Run Home Manager activation
|
||||
# info "Applying Nix Flake config using Home Manager..."
|
||||
# nix run .#homeConfigurations."$HOST".activationPackage
|
||||
#
|
||||
# ## Step 6: Symlink basic shell dotfiles (optional)
|
||||
# info "Symlinking .p10k.zsh (Powerlevel10k config)..."
|
||||
# ln -sf "$PWD/.p10k.zsh" "$HOME/.p10k.zsh"
|
||||
#
|
||||
# info "Install complete!"
|
||||
# echo -e "${green}Dotfiles and system config applied for $HOST. You may wish to relogin, or reload your shell, or review configs now.${normal}"
|
||||
#
|
||||
# exit 0
|
||||
|
||||
418
scripts/keybinds_hint.sh
Executable file
418
scripts/keybinds_hint.sh
Executable file
@@ -0,0 +1,418 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#* jq to parse and create a metadata.
|
||||
#* Users are advised to use bindd to explicitly add the description
|
||||
#* Please inform us if there are new Categories upstream will try to add comments to this script
|
||||
#* Khing 🦆
|
||||
|
||||
pkill -x rofi && exit
|
||||
scrDir=$(dirname "$(realpath "$0")")
|
||||
source "$scrDir/globalcontrol.sh"
|
||||
|
||||
confDir="${XDG_CONFIG_HOME:-$HOME/.config}"
|
||||
keyconfDir="$confDir/hypr"
|
||||
kb_hint_conf=("$keyconfDir/hyprland.conf" "$keyconfDir/keybindings.conf" "$keyconfDir/userprefs.conf" )
|
||||
tmpMapDir="/tmp"
|
||||
tmpMap="$tmpMapDir/hyde-keybinds.jq"
|
||||
keycodeFile="${hydeConfDir}/keycode.kb"
|
||||
modmaskFile="${hydeConfDir}/modmask.kb"
|
||||
keyFile="${hydeConfDir}/key.kb"
|
||||
categoryFile="${hydeConfDir}/category.kb"
|
||||
dispatcherFile="${hydeConfDir}/dispatcher.kb"
|
||||
|
||||
roDir="$confDir/rofi"
|
||||
roconf="$HOME/.config/rofi/user.rasi"
|
||||
|
||||
HELP() {
|
||||
cat <<HELP
|
||||
Usage: $(basename "$0") [options]
|
||||
Options:
|
||||
-j Show the JSON format
|
||||
-p Show the pretty format
|
||||
-d Add custom delimiter symbol (default '>')
|
||||
-f Add custom file
|
||||
-w Custom width
|
||||
-h Custom height
|
||||
--help Display this help message
|
||||
Example:
|
||||
$(basename "$0") -j -p -d '>' -f custom_file.txt -w 80 -h 90"
|
||||
Users can also add a global overrides inside ${hydeConfDir}/hyde.conf
|
||||
Available overrides:
|
||||
|
||||
kb_hint_delim=">" ﯦ add a custom custom delimiter
|
||||
kb_hint_conf=("file1.conf" "file2.conf") ﯦ add a custom keybinds.conf path (add it like an array)
|
||||
kb_hint_width="30em" ﯦ custom width supports [ 'em' '%' 'px' ]
|
||||
kb_hint_height="35em" ﯦ custom height supports [ 'em' '%' 'px' ]
|
||||
kb_hint_line=13 ﯦ adjust how many lines are listed
|
||||
|
||||
Users can also add a key overrides inside ${hydeConfDir}
|
||||
List of file override:
|
||||
${keycodeFile} => keycode
|
||||
${modmaskFile} => modmask
|
||||
${keyFile} => keys
|
||||
${categoryFile} => category
|
||||
${dispatcherFile} => dispatcher
|
||||
|
||||
Example for keycode override
|
||||
create a file named $keycodeFile and use the following format:
|
||||
|
||||
"number": "display name/symbol",
|
||||
"61": "/",
|
||||
|
||||
HELP
|
||||
}
|
||||
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case "$1" in
|
||||
-j) # show the json format
|
||||
kb_hint_json=true
|
||||
;;
|
||||
-p) # show the pretty format
|
||||
kb_hint_pretty=true
|
||||
;;
|
||||
-d) # Add custom delimiter symbol default '>'
|
||||
shift
|
||||
kb_hint_delim="$1"
|
||||
;;
|
||||
-f) # Add custom file
|
||||
shift
|
||||
kb_hint_conf+=("${@}")
|
||||
;;
|
||||
-w) # Custom kb_hint_width
|
||||
shift
|
||||
kb_hint_width="$1"
|
||||
;;
|
||||
-h) # Custom height
|
||||
shift
|
||||
kb_hint_height="$1"
|
||||
;;
|
||||
-l) # Custom number of line
|
||||
shift
|
||||
kb_hint_line="$1"
|
||||
;;
|
||||
-*) # Add Help message
|
||||
HELP
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
#? Read all the variables in the configuration file
|
||||
#! Intentional globbing on the $keyconf variable
|
||||
# shellcheck disable=SC2086
|
||||
keyVars="$(awk -F '=' '/^ *\$/ && !/^ *#[^#]/ || /^ *##/ {gsub(/^ *\$| *$/, "", $1); gsub(/#.*/, "", $2); gsub(/^ *| *$/, "", $2); print $1 "='\''"$2"'\''"}' ${kb_hint_conf[@]})"
|
||||
keyVars+="
|
||||
"
|
||||
keyVars+="HOME=$HOME"
|
||||
# echo "$keyVars"
|
||||
|
||||
#? This part substitutes the variables into the actual value.
|
||||
#TODO It will be easier if hyprland will expose the variables.
|
||||
substitute_vars() {
|
||||
local s="$1"
|
||||
local IFS=$'\n'
|
||||
for var in $keyVars; do
|
||||
varName="${var%%=*}"
|
||||
varValue="${var#*=}"
|
||||
varValue="${varValue#\'}"
|
||||
varValue="${varValue%\'}"
|
||||
s="${s//\$$varName/$varValue}"
|
||||
done
|
||||
IFS=$' \t\n'
|
||||
echo "$s"
|
||||
}
|
||||
#? Other accurate but risky option
|
||||
# eval "$keyVars"
|
||||
# substitute_vars() {
|
||||
# local s="$1"
|
||||
# local IFS=$'\n'
|
||||
# for var in $keyVars; do
|
||||
# varName="${var%%=*}"
|
||||
# s="${s//\$$varName/${!varName}}"
|
||||
# done
|
||||
# IFS=$' \t\n'
|
||||
# echo "$s"
|
||||
# }
|
||||
|
||||
initialized_comments=$(awk -F ',' '!/^#/ && /bind*/ && $3 ~ /exec/ && NF && $4 !~ /^ *$/ { print $4}' ${kb_hint_conf[@]} | sed "s#\"#'#g")
|
||||
comments=$(substitute_vars "$initialized_comments" | awk -F'#' \
|
||||
'{gsub(/^ */, "", $1);\
|
||||
gsub(/ *$/, "", $1);\
|
||||
split($2, a, " ");\
|
||||
a[1] = toupper(substr(a[1], 1, 1)) substr(a[1], 2);\
|
||||
$2 = a[1]; for(i=2;\
|
||||
i<=length(a); i++) $2 = $2" "a[i];\
|
||||
gsub(/^ */, "", $2);\
|
||||
gsub(/ *$/, "", $2);\
|
||||
if (length($1) > 0) print "\""$1"\" : \""(length($2) > 0 ? $2 : $1)"\","}' |
|
||||
awk '!seen[$0]++')
|
||||
# echo "$comments"
|
||||
|
||||
cat <<OVERRIDES >$tmpMap
|
||||
# hyde-keybinds.jq
|
||||
#! This is Our Translator for some binds #🦆
|
||||
def executables_mapping: { #? Derived from .args to parse scripts to be Readable
|
||||
#? Auto Generated Comment Conversion
|
||||
$comments
|
||||
#? Defaults
|
||||
" empty " : "Empty",
|
||||
"r+1" : "Relative Right",
|
||||
"r-1" : "Relative Left",
|
||||
"e+1" : "Next",
|
||||
"e-1" : "Previous",
|
||||
"movewindow" : "Move window",
|
||||
"resizewindow" : "Resize window",
|
||||
"d" : "Down",
|
||||
"l" : "Left",
|
||||
"r" : "Right",
|
||||
"u" : "Up",
|
||||
"f" : "Forward",
|
||||
"b" : "Backward",
|
||||
|
||||
};
|
||||
|
||||
def keycode_mapping: { #? Fetches keycode from a file
|
||||
"0": "",
|
||||
$([ -f "${keycodeFile}" ] && cat "${keycodeFile}")
|
||||
};
|
||||
|
||||
def modmask_mapping: { #? Define mapping for modmask numbers represents bitmask
|
||||
"64": " ", #? SUPER Also added 2 En space ' ' <<<
|
||||
"8": "ALT",
|
||||
"4": "CTRL",
|
||||
"1": "SHIFT",
|
||||
"0": " ",
|
||||
$([ -f "${modmaskFile}" ] && cat "${modmaskFile}")
|
||||
};
|
||||
|
||||
def key_mapping: { #?Define mappings for .keys to be readable symbols
|
||||
"mouse_up" : "",
|
||||
"mouse_down" : "",
|
||||
"mouse:272" : "",
|
||||
"mouse:273" : "",
|
||||
"UP" : "",
|
||||
"DOWN" : "",
|
||||
"LEFT" : "",
|
||||
"RIGHT" : "",
|
||||
"XF86AudioLowerVolume" : "",
|
||||
"XF86AudioMicMute" : "",
|
||||
"XF86AudioMute" : "",
|
||||
"XF86AudioNext" : "",
|
||||
"XF86AudioPause" : "",
|
||||
"XF86AudioPlay" : "",
|
||||
"XF86AudioPrev" : "",
|
||||
"XF86AudioRaiseVolume" : "",
|
||||
"XF86MonBrightnessDown" : "",
|
||||
"XF86MonBrightnessUp" : "",
|
||||
"switch:on:Lid Switch" : "",
|
||||
"backspace" : " ",
|
||||
$([ -f "${keyFile}" ] && cat "${keyFile}")
|
||||
};
|
||||
def category_mapping: { #? Define Category Names, derive from Dispatcher #? This will serve as the Group header
|
||||
"exec" : "Execute a Command:",
|
||||
"global": "Global:",
|
||||
"exit" : "Exit Hyprland Session",
|
||||
"fullscreen" : "Toggle Functions",
|
||||
"fakefullscreen" : "Toggle Functions",
|
||||
"mouse" : "Mouse functions",
|
||||
"movefocus" : "Window functions",
|
||||
"movewindow" : "Window functions",
|
||||
"resizeactive" : "Window functions",
|
||||
"togglefloating" : "Toggle Functions",
|
||||
"togglegroup" : "Toggle Functions",
|
||||
"togglespecialworkspace" : "Toggle Functions",
|
||||
"togglesplit" : "Toggle Functions",
|
||||
"workspace" : "Navigate Workspace",
|
||||
"movetoworkspace" : "Navigate Workspace",
|
||||
"movetoworkspacesilent" : "Navigate Workspace",
|
||||
"changegroupactive" : "Change Active Group",
|
||||
$([ -f "${categoryFile}" ] && cat "${categoryFile}")
|
||||
};
|
||||
def arg_mapping: { #! Do not Change this used for Demo only... As this will change .args! will be fatal
|
||||
"arg2": "mapped_arg2",
|
||||
};
|
||||
|
||||
def description_mapping: { #? Derived from dispatcher and Gives Description for Dispatchers; Basically translates dispatcher.
|
||||
"movefocus": "Move Focus",
|
||||
"resizeactive": "Resize Active Floating Window",
|
||||
"exit" : "End Hyprland Session",
|
||||
"movetoworkspacesilent" : "Silently Move to Workspace",
|
||||
"movewindow" : "Move Window",
|
||||
"exec" : "" , #? Remove exec as executable will give the Description from separate function
|
||||
"movetoworkspace" : "Move To Workspace:",
|
||||
"workspace" : "Navigate to Workspace:",
|
||||
"togglefloating" : "Toggle Floating",
|
||||
"fullscreen" : "Toggle Fullscreen",
|
||||
"togglegroup" : "Toggle Group",
|
||||
"togglesplit" : "Toggle Split",
|
||||
"togglespecialworkspace" : "Toggle Special Workspace",
|
||||
"mouse" : "Use Mouse",
|
||||
"changegroupactive" : "Switch Active group",
|
||||
$([ -f "${dispatcherFile}" ] && cat "${dispatcherFile}")
|
||||
};
|
||||
|
||||
OVERRIDES
|
||||
|
||||
#? Script to re Modify hyprctl json output
|
||||
#? Basically we are using jq to handle json data and outputs a pretty and friendly output
|
||||
jsonData="$(
|
||||
hyprctl binds -j | jq -L "$tmpMapDir" -c '
|
||||
include "hyde-keybinds";
|
||||
|
||||
#? Functions to Convert modmask into Keys, There should be a better math for this but Im lazy
|
||||
#? Also we can just map it manually too
|
||||
def get_keys:
|
||||
if . == 0 then
|
||||
""
|
||||
elif . >= 64 then
|
||||
. -= 64 | modmask_mapping["64"] + " " + get_keys
|
||||
elif . >= 32 then
|
||||
. -= 32 | modmask_mapping["32"] + " " + get_keys
|
||||
elif . >= 16 then
|
||||
. -= 16 | modmask_mapping["16"] + " " + get_keys
|
||||
elif . >= 8 then
|
||||
. -= 8 | modmask_mapping["8"] + " " + get_keys
|
||||
elif . >= 4 then
|
||||
. -= 4 | modmask_mapping["4"] + " " + get_keys
|
||||
elif . >= 2 then
|
||||
. -= 2 | modmask_mapping["2"] + " " + get_keys
|
||||
elif . >= 1 then
|
||||
. -= 1 | modmask_mapping["1"] + " " + get_keys
|
||||
else
|
||||
.
|
||||
end;
|
||||
def get_keycode:
|
||||
(keycode_mapping[(. | tostring)] // .); #? use the keycode conversion... and turn to string
|
||||
|
||||
.[] | #? Filter 1
|
||||
.dispatcher as $dispatcher | .desc_dispatcher = $dispatcher | #? Value conversions for the description
|
||||
.dispatcher as $dispatcher | .category = $dispatcher | #? Value conversions for the category
|
||||
.arg as $arg | .desc_executable = $arg | #? creates new key .desc_executable to be use later
|
||||
.modmask |= (get_keys | ltrimstr(" ")) | #? Execute Momask conversions, b
|
||||
.keycode |= (get_keycode // .) | #? Apply the get_keycode transformation
|
||||
.key |= (key_mapping[.] // .) | #? Apply the get_key
|
||||
# .keybind = (.modmask | tostring // "") + (.key // "") | #! Same as below but without the keycode
|
||||
.keybind = (.modmask | tostring // "") + (.key // "") + ((.keycode // 0) | tostring) | #? Show the keybindings
|
||||
.flags = " locked=" + (.locked | tostring) + " mouse=" + (.mouse | tostring) + " release=" + (.release | tostring) + " repeat=" + (.repeat | tostring) + " non_consuming=" + (.non_consuming | tostring) | #? This are the flags repeat,lock etc
|
||||
.category |= (category_mapping[.] // .) | #? Group by Categories will be use for headers
|
||||
#!if .modmask and .modmask != " " and .modmask != "" then .modmask |= (split(" ") | map(select(length > 0)) | if length > 1 then join(" + ") else .[0] end) else .modmask = "" end |
|
||||
if .keybind and .keybind != " " and .keybind != "" then .keybind |= (split(" ") | map(select(length > 0)) | if length > 1 then join(" + ") else .[0] end) else .keybind = "" end | #? Clean up
|
||||
.arg |= (arg_mapping[.] // .) | #? See above for how arg is converted
|
||||
#! .desc_executable |= gsub(".sh"; "") | #? Maybe Useful soon removes ".sh" to file
|
||||
#? Creates a key desc... for fallback if "has description" is false
|
||||
.desc_executable |= (executables_mapping[.] // .) | #? exclusive for "exec" dispatchers
|
||||
.desc_dispatcher |= (description_mapping[.] // .) | #? for all other dispatchers
|
||||
.description = if .has_description == false then "\(.desc_dispatcher) \(.desc_executable)" else.description end
|
||||
' #* <---- There is a ' do not delete this'
|
||||
)"
|
||||
|
||||
#? Now we have the metadata we can Group it accordingly
|
||||
GROUP() {
|
||||
awk -v cols="$cols" -F '!=!' '
|
||||
{
|
||||
category = $1
|
||||
binds[category] = binds[category]? binds[category] "\n" $0 : $0
|
||||
}
|
||||
|
||||
END {
|
||||
n = asorti(binds, b)
|
||||
for (i = 1; i <= n; i++) {
|
||||
print b[i] # Print the header name
|
||||
gsub(/\[.*\] =/, "", b[i])
|
||||
split(binds[b[i]], lines, "\n")
|
||||
for (j in lines) {
|
||||
line = substr(lines[j], index(lines[j], "=") + 2)
|
||||
print line
|
||||
}
|
||||
for (j = 1; j <= cols; j++) printf "━"
|
||||
printf "\n"
|
||||
}
|
||||
}'
|
||||
}
|
||||
|
||||
#? Display the JSON format
|
||||
[ "$kb_hint_json" = true ] && jq <<< "$jsonData" && exit 0
|
||||
|
||||
#? Format this is how the keybinds are displayed.
|
||||
DISPLAY() { awk -v kb_hint_delim="${kb_hint_delim:->}" -F '!=!' '{if ($0 ~ /=/ && $6 != "") printf "%-25s %-2s %-30s\n", $5, kb_hint_delim, $6; else if ($0 ~ /=/) printf "%-25s\n", $5; else print $0}'; }
|
||||
|
||||
#? Extra design use for distinction
|
||||
header="$(printf "%-35s %-1s %-20s\n" " Keybinds" "" "Description")"
|
||||
cols=$(tput cols)
|
||||
cols=${cols:-999}
|
||||
linebreak="$(printf '%.0s━' $(seq 1 "${cols}") "")"
|
||||
|
||||
#! this Part Gives extra loading time as I don't have efforts to make single space for each class
|
||||
metaData="$(jq -r '"\(.category) !=! \(.modmask) !=! \(.key) !=! \(.dispatcher) !=! \(.arg) !=! \(.keybind) !=! \(.description) !=! \(.flags)"' <<< "${jsonData}" | tr -s ' ' | sort -k 1)"
|
||||
|
||||
#? This formats the pretty output
|
||||
display="$(GROUP <<< "$metaData" | DISPLAY)"
|
||||
|
||||
# output=$(echo -e "${header}\n${linebreak}\n${primMenu}\n${linebreak}\n${display}")
|
||||
output=$(echo -e "${header}\n${linebreak}\n${display}")
|
||||
|
||||
[ "$kb_hint_pretty" = true ] && echo -e "$output" && exit 0
|
||||
|
||||
#? will display on the terminal if rofi is not found or have -j flag
|
||||
if ! command -v rofi &>/dev/null; then
|
||||
echo "$output"
|
||||
echo "rofi not detected. Displaying on terminal instead"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
#? Put rofi configuration here
|
||||
# Read hypr theme border
|
||||
wind_border=$((hypr_border * 3 / 2))
|
||||
elem_border=$([ "$hypr_border" -eq 0 ] && echo "5" || echo "$hypr_border")
|
||||
|
||||
# TODO Dynamic scaling for text and the window >>> I do not know if rofi is capable of this
|
||||
r_width="width: ${kb_hint_width:-35em};"
|
||||
r_height="height: ${kb_hint_height:-35em};"
|
||||
r_listview="listview { lines: ${kb_hint_line:-13}; }"
|
||||
r_override="window {$r_height $r_width border: ${hypr_width}px; border-radius: ${wind_border}px;} entry {border-radius: ${elem_border}px;} element {border-radius: ${elem_border}px;} ${r_listview} "
|
||||
|
||||
# Read hypr font size
|
||||
fnt_override=$(gsettings get org.gnome.desktop.interface font-name | awk '{gsub(/'\''/,""); print $NF}')
|
||||
fnt_override="configuration {font: \"JetBrainsMono Nerd Font ${fnt_override}\";}"
|
||||
|
||||
# Read hypr theme icon
|
||||
icon_override=$(gsettings get org.gnome.desktop.interface icon-theme | sed "s/'//g")
|
||||
icon_override="configuration {icon-theme: \"${icon_override}\";}"
|
||||
|
||||
#? Actions to do when selected
|
||||
selected=$(echo "$output" | rofi -dmenu -p -i -theme-str "${fnt_override}" -theme-str "${r_override}" -theme-str "${icon_override}" -config "${roconf}" | sed 's/.*\s*//')
|
||||
if [ -z "$selected" ]; then exit 0; fi
|
||||
|
||||
sel_1=$(awk -F "${kb_hint_delim:->}" '{print $1}' <<< "$selected" | awk '{$1=$1};1')
|
||||
sel_2=$(awk -F "${kb_hint_delim:->}" '{print $2}' <<< "$selected" | awk '{$1=$1};1')
|
||||
run="$(grep "$sel_1" <<< "$metaData" | grep "$sel_2")"
|
||||
|
||||
run_flg="$(echo "$run" | awk -F '!=!' '{print $8}')"
|
||||
run_sel="$(echo "$run" | awk -F '!=!' '{gsub(/^ *| *$/, "", $5); if ($5 ~ /[[:space:]]/ && $5 !~ /^[0-9]+$/ && substr($5, 1, 1) != "-") print $4, "\""$5"\""; else print $4, $5}')"
|
||||
# echo "$run_sel" ; echo "$run_flg"
|
||||
|
||||
#?
|
||||
RUN() { case "$(eval "hyprctl dispatch $run_sel")" in *"Not enough arguments"*) exec $0 ;; esac }
|
||||
|
||||
#? If flag is repeat then repeat rofi if not then just execute once
|
||||
if [ -n "$run_sel" ] && [ "$(echo "$run_sel" | wc -l)" -eq 1 ]; then
|
||||
eval "$run_flg"
|
||||
if [ "$repeat" = true ]; then
|
||||
|
||||
while true; do
|
||||
repeat_command=$(echo -e "Repeat" | rofi -dmenu -no-custom -p "[Enter] repeat; [ESC] exit") #? Needed a separate Rasi ? Dunno how to make; Maybe Something like confirmation rasi for buttons Yes and No then the -p will be the Question like Proceed? Repeat?
|
||||
|
||||
if [ "$repeat_command" = "Repeat" ]; then
|
||||
# Repeat the command here
|
||||
RUN
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
else
|
||||
RUN
|
||||
fi
|
||||
else
|
||||
exec $0
|
||||
fi
|
||||
10
scripts/keyboardswitch.sh
Executable file
10
scripts/keyboardswitch.sh
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
scrDir=`dirname "$(realpath "$0")"`
|
||||
source $scrDir/globalcontrol.sh
|
||||
|
||||
hyprctl switchxkblayout all next
|
||||
|
||||
layMain=$(hyprctl -j devices | jq '.keyboards' | jq '.[] | select (.main == true)' | awk -F '"' '{if ($2=="active_keymap") print $4}')
|
||||
notify-send -a "t1" -r 91190 -t 800 -i "~/.config/dunst/icons/keyboard.svg" "${layMain}"
|
||||
|
||||
35
scripts/launch-vm.sh
Normal file
35
scripts/launch-vm.sh
Normal file
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
ISO_URL="https://blackarch.org/blackarch-linux-live-2023.12.01-x86_64.iso"
|
||||
ISO_PATH="$HOME/blackarch.iso"
|
||||
VM_DISK="$HOME/blackarch.qcow2"
|
||||
|
||||
# Ensure required binaries are available
|
||||
nix shell nixpkgs#qemu nixpkgs#wget -c bash <<EOF
|
||||
|
||||
# Check if ISO exists, if not, download it
|
||||
if [ ! -f "$ISO_PATH" ]; then
|
||||
echo "Downloading BlackArch ISO..."
|
||||
wget -O "$ISO_PATH" "$ISO_URL"
|
||||
fi
|
||||
|
||||
# Create VM disk if it doesn’t exist
|
||||
if [ ! -f "$VM_DISK" ]; then
|
||||
echo "Creating BlackArch VM disk..."
|
||||
qemu-img create -f qcow2 "$VM_DISK" 50G
|
||||
fi
|
||||
|
||||
echo "Launching BlackArch VM..."
|
||||
qemu-system-x86_64 \
|
||||
-enable-kvm \
|
||||
-m 4096 \
|
||||
-smp 4 \
|
||||
-cpu host \
|
||||
-drive file="$VM_DISK",format=qcow2 \
|
||||
-cdrom "$ISO_PATH" \
|
||||
-boot d \
|
||||
-netdev user,id=net0 -device e1000,netdev=net0 \
|
||||
-display default,show-cursor=on
|
||||
|
||||
EOF
|
||||
|
||||
85
scripts/logoutlaunch.sh
Executable file
85
scripts/logoutlaunch.sh
Executable file
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
|
||||
#// Check if wlogout is already running
|
||||
|
||||
if pgrep -x "wlogout" > /dev/null
|
||||
then
|
||||
pkill -x "wlogout"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
#// set file variables
|
||||
|
||||
scrDir=`dirname "$(realpath "$0")"`
|
||||
source $scrDir/globalcontrol.sh
|
||||
[ -z "${1}" ] || wlogoutStyle="${1}"
|
||||
wLayout="${confDir}/wlogout/layout_${wlogoutStyle}"
|
||||
wlTmplt="${confDir}/wlogout/style_${wlogoutStyle}.css"
|
||||
|
||||
if [ ! -f "${wLayout}" ] || [ ! -f "${wlTmplt}" ] ; then
|
||||
echo "ERROR: Config ${wlogoutStyle} not found..."
|
||||
wlogoutStyle=1
|
||||
wLayout="${confDir}/wlogout/layout_${wlogoutStyle}"
|
||||
wlTmplt="${confDir}/wlogout/style_${wlogoutStyle}.css"
|
||||
fi
|
||||
|
||||
|
||||
#// detect monitor res
|
||||
|
||||
x_mon=$(hyprctl -j monitors | jq '.[] | select(.focused==true) | .width')
|
||||
y_mon=$(hyprctl -j monitors | jq '.[] | select(.focused==true) | .height')
|
||||
hypr_scale=$(hyprctl -j monitors | jq '.[] | select (.focused == true) | .scale' | sed 's/\.//')
|
||||
|
||||
|
||||
#// scale config layout and style
|
||||
|
||||
case "${wlogoutStyle}" in
|
||||
1) wlColms=6
|
||||
export mgn=$(( y_mon * 28 / hypr_scale ))
|
||||
export hvr=$(( y_mon * 23 / hypr_scale )) ;;
|
||||
2) wlColms=2
|
||||
export x_mgn=$(( x_mon * 35 / hypr_scale ))
|
||||
export y_mgn=$(( y_mon * 25 / hypr_scale ))
|
||||
export x_hvr=$(( x_mon * 32 / hypr_scale ))
|
||||
export y_hvr=$(( y_mon * 20 / hypr_scale )) ;;
|
||||
esac
|
||||
|
||||
|
||||
#// scale font size
|
||||
|
||||
export fntSize=$(( y_mon * 2 / 100 ))
|
||||
|
||||
|
||||
#// detect wallpaper brightness
|
||||
|
||||
[ -f "${cacheDir}/wall.dcol" ] && source "${cacheDir}/wall.dcol"
|
||||
# Theme mode: detects the color-scheme set in hypr.theme and falls back if nothing is parsed.
|
||||
if [ "${enableWallDcol}" -eq 0 ]; then
|
||||
colorScheme="$({ grep -q "^[[:space:]]*\$COLOR[-_]SCHEME\s*=" "${hydeThemeDir}/hypr.theme" && grep "^[[:space:]]*\$COLOR[-_]SCHEME\s*=" "${hydeThemeDir}/hypr.theme" | cut -d '=' -f2 | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' ;} ||
|
||||
grep 'gsettings set org.gnome.desktop.interface color-scheme' "${hydeThemeDir}/hypr.theme" | awk -F "'" '{print $((NF - 1))}')"
|
||||
colorScheme=${colorScheme:-$(gsettings get org.gnome.desktop.interface color-scheme)}
|
||||
# should be declared explicitly so we can easily debug
|
||||
grep -q "dark" <<< "${colorScheme}" && dcol_mode="dark"
|
||||
grep -q "light" <<< "${colorScheme}" && dcol_mode="light"
|
||||
[ -f "${hydeThemeDir}/theme.dcol" ] && source "${hydeThemeDir}/theme.dcol"
|
||||
fi
|
||||
[ "${dcol_mode}" == "dark" ] && export BtnCol="white" || export BtnCol="black"
|
||||
|
||||
|
||||
#// eval hypr border radius
|
||||
|
||||
export active_rad=$(( hypr_border * 5 ))
|
||||
export button_rad=$(( hypr_border * 8 ))
|
||||
|
||||
|
||||
#// eval config files
|
||||
|
||||
wlStyle="$(envsubst < $wlTmplt)"
|
||||
|
||||
|
||||
#// launch wlogout
|
||||
|
||||
wlogout -b "${wlColms}" -c 0 -r 0 -m 0 --layout "${wLayout}" --css <(echo "${wlStyle}") --protocol layer-shell
|
||||
|
||||
183
scripts/mediaplayer.py
Executable file
183
scripts/mediaplayer.py
Executable file
@@ -0,0 +1,183 @@
|
||||
#!/usr/bin/env python3
|
||||
import gi
|
||||
gi.require_version("Playerctl", "2.0")
|
||||
from gi.repository import Playerctl, GLib
|
||||
from gi.repository.Playerctl import Player
|
||||
import argparse
|
||||
import logging
|
||||
import sys
|
||||
import signal
|
||||
import gi
|
||||
import json
|
||||
import os
|
||||
from typing import List
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def signal_handler(sig, frame):
|
||||
logger.info("Received signal to stop, exiting")
|
||||
sys.stdout.write("\n")
|
||||
sys.stdout.flush()
|
||||
# loop.quit()
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
class PlayerManager:
|
||||
def __init__(self, selected_player=None):
|
||||
self.manager = Playerctl.PlayerManager()
|
||||
self.loop = GLib.MainLoop()
|
||||
self.manager.connect(
|
||||
"name-appeared", lambda *args: self.on_player_appeared(*args))
|
||||
self.manager.connect(
|
||||
"player-vanished", lambda *args: self.on_player_vanished(*args))
|
||||
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
signal.signal(signal.SIGTERM, signal_handler)
|
||||
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
|
||||
self.selected_player = selected_player
|
||||
|
||||
self.init_players()
|
||||
|
||||
def init_players(self):
|
||||
for player in self.manager.props.player_names:
|
||||
if self.selected_player is not None and self.selected_player != player.name:
|
||||
logger.debug(f"{player.name} is not the filtered player, skipping it")
|
||||
continue
|
||||
self.init_player(player)
|
||||
|
||||
def run(self):
|
||||
logger.info("Starting main loop")
|
||||
self.loop.run()
|
||||
|
||||
def init_player(self, player):
|
||||
logger.info(f"Initialize new player: {player.name}")
|
||||
player = Playerctl.Player.new_from_name(player)
|
||||
player.connect("playback-status",
|
||||
self.on_playback_status_changed, None)
|
||||
player.connect("metadata", self.on_metadata_changed, None)
|
||||
self.manager.manage_player(player)
|
||||
self.on_metadata_changed(player, player.props.metadata)
|
||||
|
||||
def get_players(self) -> List[Player]:
|
||||
return self.manager.props.players
|
||||
|
||||
def write_output(self, text, player, tooltip):
|
||||
logger.debug(f"Writing output: {text}")
|
||||
|
||||
output = {"text": text,
|
||||
"class": "custom-" + player.props.player_name,
|
||||
"alt": player.props.player_name,
|
||||
"tooltip": tooltip}
|
||||
|
||||
sys.stdout.write(json.dumps(output) + "\n")
|
||||
sys.stdout.flush()
|
||||
|
||||
def clear_output(self):
|
||||
sys.stdout.write("\n")
|
||||
sys.stdout.flush()
|
||||
|
||||
def on_playback_status_changed(self, player, status, _=None):
|
||||
logger.debug(f"Playback status changed for player {player.props.player_name}: {status}")
|
||||
self.on_metadata_changed(player, player.props.metadata)
|
||||
|
||||
def get_first_playing_player(self):
|
||||
players = self.get_players()
|
||||
logger.debug(f"Getting first playing player from {len(players)} players")
|
||||
if len(players) > 0:
|
||||
# if any are playing, show the first one that is playing
|
||||
# reverse order, so that the most recently added ones are preferred
|
||||
for player in players[::-1]:
|
||||
if player.props.status == "Playing":
|
||||
return player
|
||||
# if none are playing, show the first one
|
||||
return players[0]
|
||||
else:
|
||||
logger.debug("No players found")
|
||||
return None
|
||||
|
||||
def show_most_important_player(self):
|
||||
logger.debug("Showing most important player")
|
||||
# show the currently playing player
|
||||
# or else show the first paused player
|
||||
# or else show nothing
|
||||
current_player = self.get_first_playing_player()
|
||||
if current_player is not None:
|
||||
self.on_metadata_changed(current_player, current_player.props.metadata)
|
||||
else:
|
||||
self.clear_output()
|
||||
|
||||
def on_metadata_changed(self, player, metadata, _=None):
|
||||
logger.debug(f"Metadata changed for player {player.props.player_name}")
|
||||
player_name = player.props.player_name
|
||||
artist = player.get_artist()
|
||||
title = player.get_title()
|
||||
|
||||
track_info = ""
|
||||
if player_name == "spotify" and "mpris:trackid" in metadata.keys() and ":ad:" in player.props.metadata["mpris:trackid"]:
|
||||
track_info = "Advertisement"
|
||||
elif artist is not None and title is not None:
|
||||
track_info = f"{artist} - {title}"
|
||||
else:
|
||||
track_info = title
|
||||
tooltip = track_info
|
||||
if track_info:
|
||||
if player.props.status == "Playing":
|
||||
track_info = " " + track_info
|
||||
else:
|
||||
track_info = " " + track_info
|
||||
# only print output if no other player is playing
|
||||
current_playing = self.get_first_playing_player()
|
||||
if current_playing is None or current_playing.props.player_name == player.props.player_name:
|
||||
self.write_output(track_info, player, tooltip)
|
||||
else:
|
||||
logger.debug(f"Other player {current_playing.props.player_name} is playing, skipping")
|
||||
|
||||
def on_player_appeared(self, _, player):
|
||||
logger.info(f"Player has appeared: {player.name}")
|
||||
if player is not None and (self.selected_player is None or player.name == self.selected_player):
|
||||
self.init_player(player)
|
||||
else:
|
||||
logger.debug(
|
||||
"New player appeared, but it's not the selected player, skipping")
|
||||
|
||||
def on_player_vanished(self, _, player):
|
||||
logger.info(f"Player {player.props.player_name} has vanished")
|
||||
self.show_most_important_player()
|
||||
|
||||
def parse_arguments():
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
# Increase verbosity with every occurrence of -v
|
||||
parser.add_argument("-v", "--verbose", action="count", default=0)
|
||||
|
||||
# Define for which player we"re listening
|
||||
parser.add_argument("--player")
|
||||
|
||||
parser.add_argument("--enable-logging", action="store_true")
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def main():
|
||||
arguments = parse_arguments()
|
||||
|
||||
# Initialize logging
|
||||
if arguments.enable_logging:
|
||||
logfile = os.path.join(os.path.dirname(
|
||||
os.path.realpath(__file__)), "media-player.log")
|
||||
logging.basicConfig(filename=logfile, level=logging.DEBUG,
|
||||
format="%(asctime)s %(name)s %(levelname)s:%(lineno)d %(message)s")
|
||||
|
||||
# Logging is set by default to WARN and higher.
|
||||
# With every occurrence of -v it's lowered by one
|
||||
logger.setLevel(max((3 - arguments.verbose) * 10, 0))
|
||||
|
||||
logger.info("Creating player manager")
|
||||
if arguments.player:
|
||||
logger.info(f"Filtering for player: {arguments.player}")
|
||||
player = PlayerManager(arguments.player)
|
||||
player.run()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
57
scripts/move-floating.sh
Normal file
57
scripts/move-floating.sh
Normal file
@@ -0,0 +1,57 @@
|
||||
# #!/usr/bin/env bash
|
||||
#
|
||||
# # Move floating window or fallback to tiling move
|
||||
# direction=$1
|
||||
# amount=${2:-10}
|
||||
#
|
||||
# # normalize direction to the single-letter hyprctl form
|
||||
# case "${direction,,}" in
|
||||
# left|l) dir=l ;;
|
||||
# right|r) dir=r ;;
|
||||
# up|u|top|t) dir=u ;;
|
||||
# down|d|bottom|b) dir=d ;;
|
||||
# *)
|
||||
# echo "Usage: move-floating.sh <left|right|up|down|l|r|u|d> [amount]"
|
||||
# exit 1
|
||||
# ;;
|
||||
# esac
|
||||
#
|
||||
# # ensure dependencies
|
||||
# if ! command -v hyprctl >/dev/null 2>&1; then
|
||||
# echo "hyprctl not found in PATH" >&2
|
||||
# exit 1
|
||||
# fi
|
||||
# if ! command -v jq >/dev/null 2>&1; then
|
||||
# echo "jq not found in PATH" >&2
|
||||
# exit 1
|
||||
# fi
|
||||
#
|
||||
# if hyprctl activewindow -j | jq -r .floating | grep -q true; then
|
||||
# hyprctl dispatch moveactive "$dir" "$amount"
|
||||
# else
|
||||
# hyprctl dispatch movewindow "$dir"
|
||||
# fi
|
||||
#
|
||||
#!/usr/bin/env sh
|
||||
# move_floating.sh
|
||||
|
||||
STEP=50
|
||||
case "$1" in
|
||||
l)
|
||||
hyprctl dispatch moveactive -50 0
|
||||
;;
|
||||
r)
|
||||
hyprctl dispatch moveactive 50 0
|
||||
;;
|
||||
u)
|
||||
hyprctl dispatch moveactive 0 -50
|
||||
;;
|
||||
d)
|
||||
hyprctl dispatch moveactive 0 50
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {left|right|up|down}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
55
scripts/notifications.py
Executable file
55
scripts/notifications.py
Executable file
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import subprocess
|
||||
import json
|
||||
import sys
|
||||
|
||||
def get_dunst_history():
|
||||
result = subprocess.run(['dunstctl', 'history'], stdout=subprocess.PIPE)
|
||||
history = json.loads(result.stdout.decode('utf-8'))
|
||||
return history
|
||||
|
||||
def format_history(history):
|
||||
count = len(history['data'][0])
|
||||
alt = 'none'
|
||||
tooltip_click = []
|
||||
tooltip_click.append(" Notifications")
|
||||
tooltip_click.append(" scroll-down: history pop")
|
||||
tooltip_click.append(" click-left: Enable & Disable DND")
|
||||
tooltip_click.append(" click-middle: clear history")
|
||||
tooltip_click.append(" click-right: close all")
|
||||
|
||||
tooltip = []
|
||||
|
||||
if count > 0:
|
||||
notifications = history['data'][0][:10] # Get the first 10 notifications
|
||||
for notification in notifications:
|
||||
body = notification.get('body', {}).get('data', '')
|
||||
category = notification.get('category', {}).get('data', '')
|
||||
if category:
|
||||
alt = category + '-notification'
|
||||
tooltip.append(f" {body} ({category})\n")
|
||||
else:
|
||||
alt = 'notification'
|
||||
tooltip.append(f" {body}\n")
|
||||
|
||||
isDND = subprocess.run(['dunstctl', 'get-pause-level'], stdout=subprocess.PIPE)
|
||||
isDND = isDND.stdout.decode('utf-8').strip()
|
||||
if isDND != '0':
|
||||
alt = "dnd"
|
||||
formatted_history = {
|
||||
"text": str(count),
|
||||
"alt": alt,
|
||||
"tooltip": '\n '.join(tooltip_click) + '\n\n ' + '\n '.join(tooltip),
|
||||
"class": alt
|
||||
}
|
||||
return formatted_history
|
||||
|
||||
def main():
|
||||
history = get_dunst_history()
|
||||
formatted_history = format_history(history)
|
||||
sys.stdout.write(json.dumps(formatted_history) + '\n')
|
||||
sys.stdout.flush()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
85
scripts/open-calendar-floating.sh
Executable file
85
scripts/open-calendar-floating.sh
Executable file
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Open Google Calendar as a floating web app window using Firefox
|
||||
|
||||
# Check if Firefox is already running with the calendar
|
||||
EXISTING=$(pgrep -f "firefox.*calendar.google.com" | head -1)
|
||||
if [ ! -z "$EXISTING" ]; then
|
||||
# Focus the existing window instead
|
||||
WINDOW_ADDRESS=$(hyprctl clients -j | jq -r ".[] | select(.pid == $EXISTING) | .address" | head -1)
|
||||
if [ ! -z "$WINDOW_ADDRESS" ]; then
|
||||
hyprctl dispatch focuswindow "address:$WINDOW_ADDRESS"
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Create a dedicated Firefox profile for calendar app
|
||||
PROFILE_DIR="$HOME/.mozilla/firefox/calendar-app"
|
||||
if [ ! -d "$PROFILE_DIR" ]; then
|
||||
mkdir -p "$PROFILE_DIR/chrome"
|
||||
# Create user.js to customize Firefox UI
|
||||
cat > "$PROFILE_DIR/user.js" << 'EOF'
|
||||
// Hide Firefox UI elements
|
||||
user_pref("browser.chrome.toolbar_tips", false);
|
||||
user_pref("browser.tabs.drawInTitlebar", true);
|
||||
user_pref("browser.tabs.tabmanager.enabled", false);
|
||||
user_pref("browser.uidensity", 2);
|
||||
|
||||
// Disable notifications and other UI clutter
|
||||
user_pref("extensions.activeThemeID", "firefox-compact-dark@mozilla.org");
|
||||
user_pref("browser.startup.homepage_override.mstone", "ignore");
|
||||
|
||||
// Hide various UI elements
|
||||
user_pref("toolkit.legacyUserProfileCustomizations.stylesheets", true);
|
||||
EOF
|
||||
|
||||
# Create userChrome.css to hide the toolbar and tabs
|
||||
cat > "$PROFILE_DIR/chrome/userChrome.css" << 'EOF'
|
||||
/* Hide the entire toolbar area */
|
||||
#navigator-toolbox {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Hide tabs bar */
|
||||
#TabsToolbar {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Hide sidebar button */
|
||||
#sidebar-button {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Make content fill the window */
|
||||
#content {
|
||||
margin: 0 !important;
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Open Firefox with the dedicated profile in a new window
|
||||
firefox --new-instance --profile "$PROFILE_DIR" "https://calendar.google.com" &
|
||||
FIREFOX_PID=$!
|
||||
|
||||
# Wait for window to open
|
||||
sleep 1.5
|
||||
|
||||
# Get the window address
|
||||
WINDOW_ADDRESS=$(hyprctl clients -j | jq -r ".[] | select(.pid == $FIREFOX_PID) | .address" | head -1)
|
||||
|
||||
if [ ! -z "$WINDOW_ADDRESS" ]; then
|
||||
# Make it floating
|
||||
hyprctl dispatch togglefloating "address:$WINDOW_ADDRESS"
|
||||
|
||||
# Resize to a smaller window size (900x700)
|
||||
hyprctl dispatch resizewindowpixel "exact 900 700" "address:$WINDOW_ADDRESS"
|
||||
|
||||
# Center it on screen
|
||||
hyprctl dispatch centerwindow "address:$WINDOW_ADDRESS"
|
||||
|
||||
# Collapse sidebar - press 'm' to toggle sidebar in Google Calendar
|
||||
(
|
||||
sleep 2
|
||||
xdotool search --name "calendar" key "m" 2>/dev/null || true
|
||||
) &
|
||||
fi
|
||||
10
scripts/polkitkdeauth.sh
Executable file
10
scripts/polkitkdeauth.sh
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Use different directory on NixOS
|
||||
if [ -d /run/current-system/sw/libexec ]; then
|
||||
libDir=/run/current-system/sw/libexec
|
||||
else
|
||||
libDir=/usr/lib
|
||||
fi
|
||||
|
||||
${libDir}/polkit-gnome/polkit-gnome-authentication-agent-1 &
|
||||
77
scripts/quickapps.sh
Executable file
77
scripts/quickapps.sh
Executable file
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# set variables
|
||||
|
||||
scrDir=`dirname "$(realpath "$0")"`
|
||||
source $scrDir/globalcontrol.sh
|
||||
roconf="~/.config/rofi/quickapps.rasi"
|
||||
|
||||
if [ $# -eq 0 ] ; then
|
||||
echo "usage: ./quickapps.sh <app1> <app2> ... <app[n]>"
|
||||
exit 1
|
||||
else
|
||||
appCount="$#"
|
||||
fi
|
||||
|
||||
|
||||
# set position
|
||||
|
||||
x_mon=$( cat /sys/class/drm/*/modes | head -1 )
|
||||
y_mon=$( echo $x_mon | cut -d 'x' -f 2 )
|
||||
x_mon=$( echo $x_mon | cut -d 'x' -f 1 )
|
||||
|
||||
x_cur=$(hyprctl cursorpos | sed 's/ //g')
|
||||
y_cur=$( echo $x_cur | cut -d ',' -f 2 )
|
||||
x_cur=$( echo $x_cur | cut -d ',' -f 1 )
|
||||
|
||||
if [ ${x_cur} -le $(( x_mon/3 )) ] ; then
|
||||
x_rofi="west"
|
||||
x_offset="x-offset: 20px;"
|
||||
elif [ ${x_cur} -ge $(( x_mon/3*2 )) ] ; then
|
||||
x_rofi="east"
|
||||
x_offset="x-offset: -20px;"
|
||||
else
|
||||
unset x_rofi
|
||||
fi
|
||||
|
||||
if [ ${y_cur} -le $(( y_mon/3 )) ] ; then
|
||||
y_rofi="north"
|
||||
y_offset="y-offset: 20px;"
|
||||
elif [ ${y_cur} -ge $(( y_mon/3*2 )) ] ; then
|
||||
y_rofi="south"
|
||||
y_offset="y-offset: -20px;"
|
||||
else
|
||||
unset y_rofi
|
||||
fi
|
||||
|
||||
if [ ! -z $x_rofi ] || [ ! -z $y_rofi ] ; then
|
||||
pos="window {location: $y_rofi $x_rofi; $x_offset $y_offset}"
|
||||
fi
|
||||
|
||||
|
||||
# override rofi
|
||||
|
||||
dockHeight=$(( x_mon * 3 / 100))
|
||||
dockWidth=$(( dockHeight * appCount ))
|
||||
iconSize=$(( dockHeight - 4 ))
|
||||
wind_border=$(( hypr_border * 3/2 ))
|
||||
r_override="window{height:${dockHeight};width:${dockWidth};border-radius:${wind_border}px;} listview{columns:${appCount};} element{border-radius:${wind_border}px;} element-icon{size:${iconSize}px;}"
|
||||
|
||||
|
||||
# launch rofi menu
|
||||
|
||||
if [ -d /run/current-system/sw/share/applications ]; then
|
||||
appDir=/run/current-system/sw/share/applications
|
||||
else
|
||||
appDir=/usr/share/applications
|
||||
fi
|
||||
|
||||
RofiSel=$( for qapp in "$@"
|
||||
do
|
||||
Lkp=`grep "$qapp" $appDir/* | grep 'Exec=' | awk -F ':' '{print $1}' | head -1`
|
||||
Ico=`grep 'Icon=' $Lkp | awk -F '=' '{print $2}' | head -1`
|
||||
echo -en "${qapp}\x00icon\x1f${Ico}\n"
|
||||
done | rofi -no-fixed-num-lines -dmenu -theme-str "${r_override}" -theme-str "${pos}" -config $roconf)
|
||||
|
||||
$RofiSel &
|
||||
|
||||
20
scripts/resetxdgportal.sh
Executable file
20
scripts/resetxdgportal.sh
Executable file
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
sleep 1
|
||||
killall xdg-desktop-portal-hyprland
|
||||
killall xdg-desktop-portal-gnome
|
||||
killall xdg-desktop-portal-kde
|
||||
killall xdg-desktop-portal-lxqt
|
||||
killall xdg-desktop-portal-wlr
|
||||
killall xdg-desktop-portal
|
||||
sleep 1
|
||||
|
||||
# Use different directory on NixOS
|
||||
if [ -d /run/current-system/sw/libexec ]; then
|
||||
libDir=/run/current-system/sw/libexec
|
||||
else
|
||||
libDir=/usr/lib
|
||||
fi
|
||||
|
||||
$libDir/xdg-desktop-portal-hyprland &
|
||||
sleep 2
|
||||
$libDir/xdg-desktop-portal &
|
||||
84
scripts/rofi-network.sh
Executable file
84
scripts/rofi-network.sh
Executable file
@@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Simple rofi-based WiFi network manager with pywal color support
|
||||
|
||||
# Function to get WiFi networks
|
||||
get_networks() {
|
||||
nmcli --fields SSID,SIGNAL device wifi list 2>/dev/null | tail -n +2 | awk '
|
||||
{
|
||||
ssid = $1
|
||||
signal = $2
|
||||
if (ssid == "") next
|
||||
|
||||
# Skip duplicates
|
||||
if (seen[ssid]) next
|
||||
seen[ssid] = 1
|
||||
|
||||
# Signal strength icons
|
||||
if (signal >= 75) icon = ""
|
||||
else if (signal >= 50) icon = ""
|
||||
else if (signal >= 25) icon = ""
|
||||
else icon = ""
|
||||
|
||||
printf "%s %s (%d%%)\n", icon, ssid, signal
|
||||
}' | sort -u
|
||||
}
|
||||
|
||||
# Start background scan immediately
|
||||
nmcli device wifi rescan >/dev/null 2>&1 &
|
||||
SCAN_PID=$!
|
||||
|
||||
# Get initial networks (cached from previous scan)
|
||||
networks=$(get_networks)
|
||||
|
||||
# Add action options at the top
|
||||
menu="📶 Refresh Networks
|
||||
🔆 Enable WiFi
|
||||
🔅 Disable WiFi
|
||||
---
|
||||
$networks"
|
||||
|
||||
# Show rofi menu with network theme
|
||||
selected=$(echo "$menu" | rofi -dmenu -theme network -p "WiFi" 2>/dev/null)
|
||||
|
||||
[[ -z "$selected" ]] && exit 0
|
||||
|
||||
case "$selected" in
|
||||
"📶 Refresh Networks")
|
||||
# Trigger a scan and call self again after short delay
|
||||
nmcli device wifi rescan >/dev/null 2>&1
|
||||
sleep 1
|
||||
bash "$0"
|
||||
;;
|
||||
"🔆 Enable WiFi")
|
||||
nmcli radio wifi on
|
||||
notify-send "WiFi" "WiFi enabled" 2>/dev/null
|
||||
;;
|
||||
"🔅 Disable WiFi")
|
||||
nmcli radio wifi off
|
||||
notify-send "WiFi" "WiFi disabled" 2>/dev/null
|
||||
;;
|
||||
"---")
|
||||
;;
|
||||
*)
|
||||
# Extract SSID from selection (remove icon and signal strength)
|
||||
ssid=$(echo "$selected" | sed 's/^[^ ]* \(.*\) ([0-9]*%)$/\1/')
|
||||
|
||||
# Try to connect
|
||||
if nmcli connection show | grep -q "^$ssid"; then
|
||||
# Already saved connection
|
||||
nmcli connection up "$ssid" 2>/dev/null && \
|
||||
notify-send "WiFi" "Connected to $ssid" 2>/dev/null || \
|
||||
notify-send "WiFi" "Failed to connect to $ssid" 2>/dev/null
|
||||
else
|
||||
# Need password
|
||||
password=$(rofi -dmenu -password -theme network \
|
||||
-p "Password for $ssid" 2>/dev/null)
|
||||
if [[ -n "$password" ]]; then
|
||||
nmcli device wifi connect "$ssid" password "$password" 2>/dev/null && \
|
||||
notify-send "WiFi" "Connected to $ssid" 2>/dev/null || \
|
||||
notify-send "WiFi" "Failed to connect to $ssid" 2>/dev/null
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
8
scripts/rofi-wallpaper-preview.sh
Normal file
8
scripts/rofi-wallpaper-preview.sh
Normal file
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Rofi preview using chafa
|
||||
# $1 is the file path of the wallpaper
|
||||
if [[ -f "$1" ]]; then
|
||||
chafa "$1" --fill=block --symbols=block --size=30x15
|
||||
fi
|
||||
|
||||
2
scripts/rofilaunch.sh
Executable file
2
scripts/rofilaunch.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
rofi -show drun -theme ~/.config/rofi/config.rasi
|
||||
51
scripts/rofiselect.sh
Executable file
51
scripts/rofiselect.sh
Executable file
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
|
||||
#// set variables
|
||||
|
||||
scrDir="$(dirname "$(realpath "$0")")"
|
||||
source "${scrDir}/globalcontrol.sh"
|
||||
rofiConf="${confDir}/rofi/selector.rasi"
|
||||
rofiStyleDir="${confDir}/rofi/styles"
|
||||
rofiAssetDir="${confDir}/rofi/assets"
|
||||
|
||||
|
||||
#// set rofi scaling
|
||||
|
||||
[[ "${rofiScale}" =~ ^[0-9]+$ ]] || rofiScale=10
|
||||
r_scale="configuration {font: \"JetBrainsMono Nerd Font ${rofiScale}\";}"
|
||||
elem_border=$(( hypr_border * 5 ))
|
||||
icon_border=$(( elem_border - 5 ))
|
||||
|
||||
|
||||
#// scale for monitor
|
||||
|
||||
mon_x_res=$(hyprctl -j monitors | jq '.[] | select(.focused==true) | .width')
|
||||
mon_scale=$(hyprctl -j monitors | jq '.[] | select(.focused==true) | .scale' | sed "s/\.//")
|
||||
mon_x_res=$(( mon_x_res * 100 / mon_scale ))
|
||||
|
||||
|
||||
#// generate config
|
||||
|
||||
elm_width=$(( (20 + 12 + 16 ) * rofiScale ))
|
||||
max_avail=$(( mon_x_res - (4 * rofiScale) ))
|
||||
col_count=$(( max_avail / elm_width ))
|
||||
[[ "${col_count}" -gt 5 ]] && col_count=5
|
||||
r_override="window{width:100%;} listview{columns:${col_count};} element{orientation:vertical;border-radius:${elem_border}px;} element-icon{border-radius:${icon_border}px;size:20em;} element-text{enabled:false;}"
|
||||
|
||||
|
||||
#// launch rofi menu
|
||||
|
||||
RofiSel=$(ls ${rofiStyleDir}/style_*.rasi | awk -F '[_.]' '{print $((NF - 1))}' | while read styleNum
|
||||
do
|
||||
echo -en "${styleNum}\x00icon\x1f${rofiAssetDir}/style_${styleNum}.png\n"
|
||||
done | sort -n | rofi -dmenu -theme-str "${r_override}" -config "${rofiConf}" -select "${rofiStyle}")
|
||||
|
||||
|
||||
#// apply rofi style
|
||||
|
||||
if [ ! -z "${RofiSel}" ] ; then
|
||||
set_conf "rofiStyle" "${RofiSel}"
|
||||
notify-send -a "t1" -r 91190 -t 2200 -i "${rofiAssetDir}/style_${RofiSel}.png" " style ${RofiSel} applied..."
|
||||
fi
|
||||
|
||||
63
scripts/screenshot.sh
Executable file
63
scripts/screenshot.sh
Executable file
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Restores the shader after screenshot has been taken
|
||||
restore_shader() {
|
||||
if [ -n "$shader" ]; then
|
||||
hyprshade on "$shader"
|
||||
fi
|
||||
}
|
||||
|
||||
# Saves the current shader and turns it off
|
||||
save_shader() {
|
||||
shader=$(hyprshade current)
|
||||
hyprshade off
|
||||
trap restore_shader EXIT
|
||||
}
|
||||
|
||||
save_shader # Saving the current shader
|
||||
|
||||
if [ -z "$XDG_PICTURES_DIR" ]; then
|
||||
XDG_PICTURES_DIR="$HOME/Pictures"
|
||||
fi
|
||||
|
||||
scrDir=$(dirname "$(realpath "$0")")
|
||||
source $scrDir/globalcontrol.sh
|
||||
swpy_dir="${confDir}/swappy"
|
||||
save_dir="${2:-$XDG_PICTURES_DIR/Screenshots}"
|
||||
save_file=$(date +'%y%m%d_%Hh%Mm%Ss_screenshot.png')
|
||||
temp_screenshot="/tmp/screenshot.png"
|
||||
|
||||
mkdir -p $save_dir
|
||||
mkdir -p $swpy_dir
|
||||
echo -e "[Default]\nsave_dir=$save_dir\nsave_filename_format=$save_file" >$swpy_dir/config
|
||||
|
||||
function print_error
|
||||
{
|
||||
cat <<"EOF"
|
||||
./screenshot.sh <action>
|
||||
...valid actions are...
|
||||
p : print all screens
|
||||
s : snip current screen
|
||||
sf : snip current screen (frozen)
|
||||
m : print focused monitor
|
||||
EOF
|
||||
}
|
||||
|
||||
case $1 in
|
||||
p) # print all outputs
|
||||
grimblast copysave screen $temp_screenshot && restore_shader && swappy -f $temp_screenshot ;;
|
||||
s) # drag to manually snip an area / click on a window to print it
|
||||
grimblast copysave area $temp_screenshot && restore_shader && swappy -f $temp_screenshot ;;
|
||||
sf) # frozen screen, drag to manually snip an area / click on a window to print it
|
||||
grimblast --freeze copysave area $temp_screenshot && restore_shader && swappy -f $temp_screenshot ;;
|
||||
m) # print focused monitor
|
||||
grimblast copysave output $temp_screenshot && restore_shader && swappy -f $temp_screenshot ;;
|
||||
*) # invalid option
|
||||
print_error ;;
|
||||
esac
|
||||
|
||||
rm "$temp_screenshot"
|
||||
|
||||
if [ -f "${save_dir}/${save_file}" ]; then
|
||||
notify-send -a "t1" -i "${save_dir}/${save_file}" "saved in ${save_dir}"
|
||||
fi
|
||||
239
scripts/set-wallpaper.sh
Executable file
239
scripts/set-wallpaper.sh
Executable file
@@ -0,0 +1,239 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# -----------------------------
|
||||
# CONFIGURATION
|
||||
# -----------------------------
|
||||
WALLPAPER_DIR="$HOME/Pictures/wallpapers"
|
||||
WAYBAR_CONFIG_DIR="$HOME/.config/waybar"
|
||||
ROFI_CONFIG_DIR="$HOME/.config/rofi"
|
||||
INDEX_FILE="/tmp/current_wallpaper_index"
|
||||
|
||||
# Collect wallpapers
|
||||
WALLPAPERS=("${WALLPAPER_DIR}"/*)
|
||||
TOTAL_WALLPAPERS=${#WALLPAPERS[@]}
|
||||
|
||||
# Load current index
|
||||
if [[ -f "$INDEX_FILE" ]]; then
|
||||
CURRENT_INDEX=$(<"$INDEX_FILE")
|
||||
else
|
||||
CURRENT_INDEX=0
|
||||
fi
|
||||
|
||||
# -----------------------------
|
||||
# HELPER FUNCTIONS
|
||||
# -----------------------------
|
||||
|
||||
extract_rofi_colors() {
|
||||
if [[ -f "$HOME/.cache/wal/colors-rofi-dark.rasi" ]]; then
|
||||
awk '/^\* {/,/^}/' "$HOME/.cache/wal/colors-rofi-dark.rasi" > "$ROFI_CONFIG_DIR/colors.rasi" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
update_hyprlock_colors() {
|
||||
# Extract colors from pywal JSON and update hyprlock config
|
||||
local colors_json="$HOME/.cache/wal/colors.json"
|
||||
|
||||
if [[ -f "$colors_json" ]]; then
|
||||
# This function is called after set_wallpaper, which updates the symlink
|
||||
# Hyprlock will read the new wallpaper on next lock
|
||||
# Note: Colors in hyprlock.nix are set statically at build time
|
||||
# so they won't update dynamically - only the wallpaper updates
|
||||
:
|
||||
fi
|
||||
}
|
||||
|
||||
copy_current_wallpaper() {
|
||||
local wallpaper="$1"
|
||||
local wallpaper_filename=$(basename "$wallpaper")
|
||||
local output_file="$ROFI_CONFIG_DIR/current_wallpaper.$(echo "$wallpaper_filename" | awk -F. '{print $NF}')"
|
||||
|
||||
# Remove existing file if it's read-only
|
||||
if [[ -f "$output_file" ]]; then
|
||||
chmod u+w "$output_file" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
cp "$wallpaper" "$output_file" 2>/dev/null || true
|
||||
}
|
||||
|
||||
generate_posting_theme() {
|
||||
# Generate posting theme from pywal colors
|
||||
local WAL_COLORS="${XDG_CACHE_HOME:-$HOME/.cache}/wal/colors"
|
||||
|
||||
if [ ! -f "$WAL_COLORS" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
# Read colors from wal
|
||||
mapfile -t COLORS < "$WAL_COLORS"
|
||||
|
||||
# Extract colors (wal provides 16 colors)
|
||||
BG="${COLORS[0]}" # background
|
||||
COLOR1="${COLORS[1]}" # red
|
||||
COLOR2="${COLORS[2]}" # green
|
||||
COLOR3="${COLORS[3]}" # yellow
|
||||
COLOR4="${COLORS[4]}" # blue
|
||||
COLOR5="${COLORS[5]}" # magenta
|
||||
COLOR6="${COLORS[6]}" # cyan
|
||||
|
||||
POSTING_THEME_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/posting/themes"
|
||||
mkdir -p "$POSTING_THEME_DIR"
|
||||
|
||||
# Generate theme from pywal colors with proper variable substitution
|
||||
cat > "$POSTING_THEME_DIR/pywal.yaml" <<THEMEOF
|
||||
# Posting theme generated from pywal colors
|
||||
name: pywal
|
||||
primary: '$COLOR4' # Blue from wal
|
||||
secondary: '$COLOR3' # Yellow from wal
|
||||
accent: '$COLOR6' # Cyan from wal
|
||||
background: '$BG' # Black background from wal
|
||||
surface: '$COLOR1' # Dark red for panels
|
||||
panel: '$COLOR2' # Green for panel backgrounds
|
||||
error: '$COLOR1' # Red for errors
|
||||
success: '$COLOR2' # Green for success
|
||||
warning: '$COLOR3' # Yellow for warnings
|
||||
dark: true
|
||||
|
||||
author: "pywal"
|
||||
description: "Posting theme synchronized with pywal colors"
|
||||
|
||||
text_area:
|
||||
gutter: "bold $COLOR6"
|
||||
cursor: "reverse"
|
||||
cursor_line: "dim"
|
||||
selection: "reverse"
|
||||
|
||||
url:
|
||||
base: "italic $COLOR6"
|
||||
protocol: "bold $COLOR4"
|
||||
separator: "dim"
|
||||
|
||||
syntax:
|
||||
json_key: "italic $COLOR4"
|
||||
json_string: "$COLOR2"
|
||||
json_number: "$COLOR6"
|
||||
json_boolean: "$COLOR2"
|
||||
json_null: "underline $COLOR6"
|
||||
|
||||
method:
|
||||
get: "$COLOR4"
|
||||
post: "$COLOR2"
|
||||
put: "$COLOR3"
|
||||
delete: "$COLOR1"
|
||||
patch: "$COLOR6"
|
||||
options: "$COLOR5"
|
||||
head: "$COLOR5"
|
||||
|
||||
variable:
|
||||
resolved: "black on $COLOR2"
|
||||
unresolved: "black on $COLOR1"
|
||||
THEMEOF
|
||||
}
|
||||
|
||||
set_wallpaper() {
|
||||
local wallpaper="${WALLPAPERS[$CURRENT_INDEX]}"
|
||||
echo "Setting wallpaper: $wallpaper"
|
||||
|
||||
# Change wallpaper using swww
|
||||
swww img "$wallpaper" --transition-type random
|
||||
|
||||
# Generate colors with pywal (also generates colors-hyprland.conf via template)
|
||||
wal -i "$wallpaper"
|
||||
|
||||
# Generate posting theme from the new pywal colors
|
||||
generate_posting_theme
|
||||
|
||||
# Update Pywalfox Firefox theme (if firefox is running)
|
||||
if pgrep firefox > /dev/null; then
|
||||
pywalfox update
|
||||
fi
|
||||
|
||||
# Reload Hyprland to apply new colors from generated config
|
||||
hyprctl reload
|
||||
|
||||
# Copy Waybar color scheme
|
||||
cp "$HOME/.cache/wal/colors-waybar.css" "$WAYBAR_CONFIG_DIR/colors-waybar.css"
|
||||
cp "$HOME/.cache/wal/colors-waybar.css" "$HOME/.config/wlogout/colors-waybar.css"
|
||||
cp "$HOME/.cache/wal/colors-wal.vim" "$HOME/.config/nvim/colors-wal.vim"
|
||||
cp "$HOME/.cache/wal/colors.css" "$HOME/.config/wlogout/colors.css"
|
||||
|
||||
# Extract Rofi colors
|
||||
extract_rofi_colors
|
||||
|
||||
# Copy current wallpaper for Rofi preview
|
||||
copy_current_wallpaper "$wallpaper"
|
||||
|
||||
# Symlink wallpaper for hyprlock
|
||||
ln -sf "$wallpaper" "$HOME/.cache/hyprlock_wallpaper"
|
||||
|
||||
# Update hyprlock colors dynamically using hyprctl
|
||||
update_hyprlock_colors
|
||||
|
||||
|
||||
# Reload swaync to apply new colors (CSS is cached until service restarts)
|
||||
systemctl --user restart swaync.service 2>/dev/null || true
|
||||
|
||||
# Reload waybar to apply new colors
|
||||
pkill -SIGUSR2 waybar 2>/dev/null || true
|
||||
|
||||
# Reload nvim colors if running
|
||||
if pgrep nvim > /dev/null; then
|
||||
nvim --server /tmp/nvim.pipe --remote-send '<Esc>:source $HOME/.cache/wal/colors-wal.vim<CR>'
|
||||
fi
|
||||
}
|
||||
|
||||
next_wallpaper() {
|
||||
CURRENT_INDEX=$(( (CURRENT_INDEX + 1) % TOTAL_WALLPAPERS ))
|
||||
echo "$CURRENT_INDEX" > "$INDEX_FILE"
|
||||
set_wallpaper
|
||||
}
|
||||
|
||||
prev_wallpaper() {
|
||||
CURRENT_INDEX=$(( (CURRENT_INDEX - 1 + TOTAL_WALLPAPERS) % TOTAL_WALLPAPERS ))
|
||||
echo "$CURRENT_INDEX" > "$INDEX_FILE"
|
||||
set_wallpaper
|
||||
}
|
||||
select_wallpaper_rofi() {
|
||||
local THUMB_DIR="$HOME/.cache/wallpaper-thumbs"
|
||||
|
||||
local selected=$(
|
||||
for wp in "${WALLPAPERS[@]}"; do
|
||||
filename="$(basename "$wp")"
|
||||
name_no_ext="${filename%.*}"
|
||||
|
||||
thumb=$(find "$THUMB_DIR" -maxdepth 1 -type f -name "${name_no_ext}_*.png" | head -n1)
|
||||
|
||||
[[ -z "$thumb" ]] && thumb="$wp"
|
||||
|
||||
# IMPORTANT: real null byte + icon metadata
|
||||
printf "%s\0icon\x1f%s\n" "$filename" "$thumb"
|
||||
done | rofi -dmenu -i -show-icons \
|
||||
-theme "$HOME/.config/rofi/wallpaper.rasi"
|
||||
)
|
||||
|
||||
if [[ -n "$selected" ]]; then
|
||||
for i in "${!WALLPAPERS[@]}"; do
|
||||
if [[ "$(basename "${WALLPAPERS[$i]}")" == "$selected" ]]; then
|
||||
CURRENT_INDEX=$i
|
||||
echo "$CURRENT_INDEX" > "$INDEX_FILE"
|
||||
set_wallpaper
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
next)
|
||||
next_wallpaper
|
||||
;;
|
||||
prev)
|
||||
prev_wallpaper
|
||||
;;
|
||||
rofi)
|
||||
select_wallpaper_rofi
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {next|prev|rofi}"
|
||||
;;
|
||||
esac
|
||||
|
||||
50
scripts/setup-firefox-calendar-profile.sh
Executable file
50
scripts/setup-firefox-calendar-profile.sh
Executable file
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Setup Firefox calendar app profile with custom UI customizations
|
||||
# Dark Reader should be installed manually via about:addons
|
||||
|
||||
PROFILE_DIR="$HOME/.mozilla/firefox/calendar-app"
|
||||
|
||||
# Create profile directory if it doesn't exist
|
||||
mkdir -p "$PROFILE_DIR/chrome"
|
||||
|
||||
# Create user.js with preferences
|
||||
cat > "$PROFILE_DIR/user.js" << 'EOF'
|
||||
// Hide Firefox UI elements
|
||||
user_pref("browser.chrome.toolbar_tips", false);
|
||||
user_pref("browser.tabs.drawInTitlebar", true);
|
||||
user_pref("browser.tabs.tabmanager.enabled", false);
|
||||
user_pref("browser.uidensity", 2);
|
||||
|
||||
// Disable notifications and other UI clutter
|
||||
user_pref("extensions.activeThemeID", "firefox-compact-dark@mozilla.org");
|
||||
user_pref("browser.startup.homepage_override.mstone", "ignore");
|
||||
|
||||
// Hide various UI elements
|
||||
user_pref("toolkit.legacyUserProfileCustomizations.stylesheets", true);
|
||||
EOF
|
||||
|
||||
# Create userChrome.css to hide the toolbar and tabs
|
||||
cat > "$PROFILE_DIR/chrome/userChrome.css" << 'EOF'
|
||||
/* Hide the entire toolbar area */
|
||||
#navigator-toolbox {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Hide tabs bar */
|
||||
#TabsToolbar {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Hide sidebar button */
|
||||
#sidebar-button {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Make content fill the window */
|
||||
#content {
|
||||
margin: 0 !important;
|
||||
}
|
||||
EOF
|
||||
|
||||
echo "Firefox calendar app profile configured successfully"
|
||||
9
scripts/switch-workspace.sh
Normal file
9
scripts/switch-workspace.sh
Normal file
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
current_workspace=$(hyprctl monitors | grep "active workspace" | awk '{print $NF}')
|
||||
if [ "$1" == "up" ]; then
|
||||
new_workspace=$((current_workspace + 1))
|
||||
elif [ "$1" == "down" ]; then
|
||||
new_workspace=$((current_workspace - 1))
|
||||
fi
|
||||
hyprctl dispatch workspace "$new_workspace"
|
||||
265
scripts/swwwallbash.sh
Executable file
265
scripts/swwwallbash.sh
Executable file
@@ -0,0 +1,265 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
#// set variables
|
||||
|
||||
export scrDir="$(dirname "$(realpath "$0")")"
|
||||
source "${scrDir}/globalcontrol.sh"
|
||||
wallbashImg="${1}"
|
||||
|
||||
|
||||
#// validate input
|
||||
|
||||
if [ -z "${wallbashImg}" ] || [ ! -f "${wallbashImg}" ] ; then
|
||||
echo "Error: Input wallpaper not found!"
|
||||
exit 1
|
||||
fi
|
||||
wallbashOut="${dcolDir}/$(set_hash "${wallbashImg}").dcol"
|
||||
|
||||
if [ ! -f "${wallbashOut}" ] ; then
|
||||
"${scrDir}/swwwallcache.sh" -w "${wallbashImg}" &> /dev/null
|
||||
fi
|
||||
|
||||
set -a
|
||||
source "${wallbashOut}"
|
||||
if [ -f "${hydeThemeDir}/theme.dcol" ] && [ "${enableWallDcol}" -eq 0 ] ; then
|
||||
source "${hydeThemeDir}/theme.dcol"
|
||||
echo "[theme] Overriding dominant colors from \"${hydeTheme}\""
|
||||
echo "[note] Remove \"${hydeThemeDir}/theme.dcol\" to use wallpaper dominant colors"
|
||||
fi
|
||||
[ "${dcol_mode}" == "dark" ] && dcol_invt="light" || dcol_invt="dark"
|
||||
set +a
|
||||
|
||||
|
||||
#// deploy wallbash colors
|
||||
|
||||
fn_wallbash () {
|
||||
local tplt="${1}"
|
||||
[ -f "${hydeConfDir}/hyde.conf" ] && source "${hydeConfDir}/hyde.conf"
|
||||
# Skips the the template declared in ./hyde.conf
|
||||
[[ " ${skip_wallbash[@]} " =~ " ${tplt} " ]] && echo "[skip: template] ${tplt}" && return 0
|
||||
eval target="$(head -1 "${tplt}" | awk -F '|' '{print $1}')"
|
||||
[ ! -d "$(dirname "${target}")" ] && echo "[skip: no dir] \"${target}\"" && return 0
|
||||
appexe="$(head -1 "${tplt}" | awk -F '|' '{print $2}')"
|
||||
sed '1d' "${tplt}" > "${target}"
|
||||
|
||||
if [[ "${enableWallDcol}" -eq 2 && "${dcol_mode}" == "light" ]] || [[ "${enableWallDcol}" -eq 3 && "${dcol_mode}" == "dark" ]] ; then
|
||||
sed -i 's/<wallbash_mode>/'"${dcol_invt}"'/g
|
||||
s/<wallbash_pry1>/'"${dcol_pry4}"'/g
|
||||
s/<wallbash_txt1>/'"${dcol_txt4}"'/g
|
||||
s/<wallbash_1xa1>/'"${dcol_4xa9}"'/g
|
||||
s/<wallbash_1xa2>/'"${dcol_4xa8}"'/g
|
||||
s/<wallbash_1xa3>/'"${dcol_4xa7}"'/g
|
||||
s/<wallbash_1xa4>/'"${dcol_4xa6}"'/g
|
||||
s/<wallbash_1xa5>/'"${dcol_4xa5}"'/g
|
||||
s/<wallbash_1xa6>/'"${dcol_4xa4}"'/g
|
||||
s/<wallbash_1xa7>/'"${dcol_4xa3}"'/g
|
||||
s/<wallbash_1xa8>/'"${dcol_4xa2}"'/g
|
||||
s/<wallbash_1xa9>/'"${dcol_4xa1}"'/g
|
||||
s/<wallbash_pry2>/'"${dcol_pry3}"'/g
|
||||
s/<wallbash_txt2>/'"${dcol_txt3}"'/g
|
||||
s/<wallbash_2xa1>/'"${dcol_3xa9}"'/g
|
||||
s/<wallbash_2xa2>/'"${dcol_3xa8}"'/g
|
||||
s/<wallbash_2xa3>/'"${dcol_3xa7}"'/g
|
||||
s/<wallbash_2xa4>/'"${dcol_3xa6}"'/g
|
||||
s/<wallbash_2xa5>/'"${dcol_3xa5}"'/g
|
||||
s/<wallbash_2xa6>/'"${dcol_3xa4}"'/g
|
||||
s/<wallbash_2xa7>/'"${dcol_3xa3}"'/g
|
||||
s/<wallbash_2xa8>/'"${dcol_3xa2}"'/g
|
||||
s/<wallbash_2xa9>/'"${dcol_3xa1}"'/g
|
||||
s/<wallbash_pry3>/'"${dcol_pry2}"'/g
|
||||
s/<wallbash_txt3>/'"${dcol_txt2}"'/g
|
||||
s/<wallbash_3xa1>/'"${dcol_2xa9}"'/g
|
||||
s/<wallbash_3xa2>/'"${dcol_2xa8}"'/g
|
||||
s/<wallbash_3xa3>/'"${dcol_2xa7}"'/g
|
||||
s/<wallbash_3xa4>/'"${dcol_2xa6}"'/g
|
||||
s/<wallbash_3xa5>/'"${dcol_2xa5}"'/g
|
||||
s/<wallbash_3xa6>/'"${dcol_2xa4}"'/g
|
||||
s/<wallbash_3xa7>/'"${dcol_2xa3}"'/g
|
||||
s/<wallbash_3xa8>/'"${dcol_2xa2}"'/g
|
||||
s/<wallbash_3xa9>/'"${dcol_2xa1}"'/g
|
||||
s/<wallbash_pry4>/'"${dcol_pry1}"'/g
|
||||
s/<wallbash_txt4>/'"${dcol_txt1}"'/g
|
||||
s/<wallbash_4xa1>/'"${dcol_1xa9}"'/g
|
||||
s/<wallbash_4xa2>/'"${dcol_1xa8}"'/g
|
||||
s/<wallbash_4xa3>/'"${dcol_1xa7}"'/g
|
||||
s/<wallbash_4xa4>/'"${dcol_1xa6}"'/g
|
||||
s/<wallbash_4xa5>/'"${dcol_1xa5}"'/g
|
||||
s/<wallbash_4xa6>/'"${dcol_1xa4}"'/g
|
||||
s/<wallbash_4xa7>/'"${dcol_1xa3}"'/g
|
||||
s/<wallbash_4xa8>/'"${dcol_1xa2}"'/g
|
||||
s/<wallbash_4xa9>/'"${dcol_1xa1}"'/g
|
||||
s/<wallbash_pry1_rgba(\([^)]*\))>/'"${dcol_pry4_rgba}"'/g
|
||||
s/<wallbash_txt1_rgba(\([^)]*\))>/'"${dcol_txt4_rgba}"'/g
|
||||
s/<wallbash_1xa1_rgba(\([^)]*\))>/'"${dcol_4xa9_rgba}"'/g
|
||||
s/<wallbash_1xa2_rgba(\([^)]*\))>/'"${dcol_4xa8_rgba}"'/g
|
||||
s/<wallbash_1xa3_rgba(\([^)]*\))>/'"${dcol_4xa7_rgba}"'/g
|
||||
s/<wallbash_1xa4_rgba(\([^)]*\))>/'"${dcol_4xa6_rgba}"'/g
|
||||
s/<wallbash_1xa5_rgba(\([^)]*\))>/'"${dcol_4xa5_rgba}"'/g
|
||||
s/<wallbash_1xa6_rgba(\([^)]*\))>/'"${dcol_4xa4_rgba}"'/g
|
||||
s/<wallbash_1xa7_rgba(\([^)]*\))>/'"${dcol_4xa3_rgba}"'/g
|
||||
s/<wallbash_1xa8_rgba(\([^)]*\))>/'"${dcol_4xa2_rgba}"'/g
|
||||
s/<wallbash_1xa9_rgba(\([^)]*\))>/'"${dcol_4xa1_rgba}"'/g
|
||||
s/<wallbash_pry2_rgba(\([^)]*\))>/'"${dcol_pry3_rgba}"'/g
|
||||
s/<wallbash_txt2_rgba(\([^)]*\))>/'"${dcol_txt3_rgba}"'/g
|
||||
s/<wallbash_2xa1_rgba(\([^)]*\))>/'"${dcol_3xa9_rgba}"'/g
|
||||
s/<wallbash_2xa2_rgba(\([^)]*\))>/'"${dcol_3xa8_rgba}"'/g
|
||||
s/<wallbash_2xa3_rgba(\([^)]*\))>/'"${dcol_3xa7_rgba}"'/g
|
||||
s/<wallbash_2xa4_rgba(\([^)]*\))>/'"${dcol_3xa6_rgba}"'/g
|
||||
s/<wallbash_2xa5_rgba(\([^)]*\))>/'"${dcol_3xa5_rgba}"'/g
|
||||
s/<wallbash_2xa6_rgba(\([^)]*\))>/'"${dcol_3xa4_rgba}"'/g
|
||||
s/<wallbash_2xa7_rgba(\([^)]*\))>/'"${dcol_3xa3_rgba}"'/g
|
||||
s/<wallbash_2xa8_rgba(\([^)]*\))>/'"${dcol_3xa2_rgba}"'/g
|
||||
s/<wallbash_2xa9_rgba(\([^)]*\))>/'"${dcol_3xa1_rgba}"'/g
|
||||
s/<wallbash_pry3_rgba(\([^)]*\))>/'"${dcol_pry2_rgba}"'/g
|
||||
s/<wallbash_txt3_rgba(\([^)]*\))>/'"${dcol_txt2_rgba}"'/g
|
||||
s/<wallbash_3xa1_rgba(\([^)]*\))>/'"${dcol_2xa9_rgba}"'/g
|
||||
s/<wallbash_3xa2_rgba(\([^)]*\))>/'"${dcol_2xa8_rgba}"'/g
|
||||
s/<wallbash_3xa3_rgba(\([^)]*\))>/'"${dcol_2xa7_rgba}"'/g
|
||||
s/<wallbash_3xa4_rgba(\([^)]*\))>/'"${dcol_2xa6_rgba}"'/g
|
||||
s/<wallbash_3xa5_rgba(\([^)]*\))>/'"${dcol_2xa5_rgba}"'/g
|
||||
s/<wallbash_3xa6_rgba(\([^)]*\))>/'"${dcol_2xa4_rgba}"'/g
|
||||
s/<wallbash_3xa7_rgba(\([^)]*\))>/'"${dcol_2xa3_rgba}"'/g
|
||||
s/<wallbash_3xa8_rgba(\([^)]*\))>/'"${dcol_2xa2_rgba}"'/g
|
||||
s/<wallbash_3xa9_rgba(\([^)]*\))>/'"${dcol_2xa1_rgba}"'/g
|
||||
s/<wallbash_pry4_rgba(\([^)]*\))>/'"${dcol_pry1_rgba}"'/g
|
||||
s/<wallbash_txt4_rgba(\([^)]*\))>/'"${dcol_txt1_rgba}"'/g
|
||||
s/<wallbash_4xa1_rgba(\([^)]*\))>/'"${dcol_1xa9_rgba}"'/g
|
||||
s/<wallbash_4xa2_rgba(\([^)]*\))>/'"${dcol_1xa8_rgba}"'/g
|
||||
s/<wallbash_4xa3_rgba(\([^)]*\))>/'"${dcol_1xa7_rgba}"'/g
|
||||
s/<wallbash_4xa4_rgba(\([^)]*\))>/'"${dcol_1xa6_rgba}"'/g
|
||||
s/<wallbash_4xa5_rgba(\([^)]*\))>/'"${dcol_1xa5_rgba}"'/g
|
||||
s/<wallbash_4xa6_rgba(\([^)]*\))>/'"${dcol_1xa4_rgba}"'/g
|
||||
s/<wallbash_4xa7_rgba(\([^)]*\))>/'"${dcol_1xa3_rgba}"'/g
|
||||
s/<wallbash_4xa8_rgba(\([^)]*\))>/'"${dcol_1xa2_rgba}"'/g
|
||||
s/<wallbash_4xa9_rgba(\([^)]*\))>/'"${dcol_1xa1_rgba}"'/g' "${target}"
|
||||
else
|
||||
sed -i 's/<wallbash_mode>/'"${dcol_mode}"'/g
|
||||
s/<wallbash_pry1>/'"${dcol_pry1}"'/g
|
||||
s/<wallbash_txt1>/'"${dcol_txt1}"'/g
|
||||
s/<wallbash_1xa1>/'"${dcol_1xa1}"'/g
|
||||
s/<wallbash_1xa2>/'"${dcol_1xa2}"'/g
|
||||
s/<wallbash_1xa3>/'"${dcol_1xa3}"'/g
|
||||
s/<wallbash_1xa4>/'"${dcol_1xa4}"'/g
|
||||
s/<wallbash_1xa5>/'"${dcol_1xa5}"'/g
|
||||
s/<wallbash_1xa6>/'"${dcol_1xa6}"'/g
|
||||
s/<wallbash_1xa7>/'"${dcol_1xa7}"'/g
|
||||
s/<wallbash_1xa8>/'"${dcol_1xa8}"'/g
|
||||
s/<wallbash_1xa9>/'"${dcol_1xa9}"'/g
|
||||
s/<wallbash_pry2>/'"${dcol_pry2}"'/g
|
||||
s/<wallbash_txt2>/'"${dcol_txt2}"'/g
|
||||
s/<wallbash_2xa1>/'"${dcol_2xa1}"'/g
|
||||
s/<wallbash_2xa2>/'"${dcol_2xa2}"'/g
|
||||
s/<wallbash_2xa3>/'"${dcol_2xa3}"'/g
|
||||
s/<wallbash_2xa4>/'"${dcol_2xa4}"'/g
|
||||
s/<wallbash_2xa5>/'"${dcol_2xa5}"'/g
|
||||
s/<wallbash_2xa6>/'"${dcol_2xa6}"'/g
|
||||
s/<wallbash_2xa7>/'"${dcol_2xa7}"'/g
|
||||
s/<wallbash_2xa8>/'"${dcol_2xa8}"'/g
|
||||
s/<wallbash_2xa9>/'"${dcol_2xa9}"'/g
|
||||
s/<wallbash_pry3>/'"${dcol_pry3}"'/g
|
||||
s/<wallbash_txt3>/'"${dcol_txt3}"'/g
|
||||
s/<wallbash_3xa1>/'"${dcol_3xa1}"'/g
|
||||
s/<wallbash_3xa2>/'"${dcol_3xa2}"'/g
|
||||
s/<wallbash_3xa3>/'"${dcol_3xa3}"'/g
|
||||
s/<wallbash_3xa4>/'"${dcol_3xa4}"'/g
|
||||
s/<wallbash_3xa5>/'"${dcol_3xa5}"'/g
|
||||
s/<wallbash_3xa6>/'"${dcol_3xa6}"'/g
|
||||
s/<wallbash_3xa7>/'"${dcol_3xa7}"'/g
|
||||
s/<wallbash_3xa8>/'"${dcol_3xa8}"'/g
|
||||
s/<wallbash_3xa9>/'"${dcol_3xa9}"'/g
|
||||
s/<wallbash_pry4>/'"${dcol_pry4}"'/g
|
||||
s/<wallbash_txt4>/'"${dcol_txt4}"'/g
|
||||
s/<wallbash_4xa1>/'"${dcol_4xa1}"'/g
|
||||
s/<wallbash_4xa2>/'"${dcol_4xa2}"'/g
|
||||
s/<wallbash_4xa3>/'"${dcol_4xa3}"'/g
|
||||
s/<wallbash_4xa4>/'"${dcol_4xa4}"'/g
|
||||
s/<wallbash_4xa5>/'"${dcol_4xa5}"'/g
|
||||
s/<wallbash_4xa6>/'"${dcol_4xa6}"'/g
|
||||
s/<wallbash_4xa7>/'"${dcol_4xa7}"'/g
|
||||
s/<wallbash_4xa8>/'"${dcol_4xa8}"'/g
|
||||
s/<wallbash_4xa9>/'"${dcol_4xa9}"'/g
|
||||
s/<wallbash_pry1_rgba(\([^)]*\))>/'"${dcol_pry1_rgba}"'/g
|
||||
s/<wallbash_txt1_rgba(\([^)]*\))>/'"${dcol_txt1_rgba}"'/g
|
||||
s/<wallbash_1xa1_rgba(\([^)]*\))>/'"${dcol_1xa1_rgba}"'/g
|
||||
s/<wallbash_1xa2_rgba(\([^)]*\))>/'"${dcol_1xa2_rgba}"'/g
|
||||
s/<wallbash_1xa3_rgba(\([^)]*\))>/'"${dcol_1xa3_rgba}"'/g
|
||||
s/<wallbash_1xa4_rgba(\([^)]*\))>/'"${dcol_1xa4_rgba}"'/g
|
||||
s/<wallbash_1xa5_rgba(\([^)]*\))>/'"${dcol_1xa5_rgba}"'/g
|
||||
s/<wallbash_1xa6_rgba(\([^)]*\))>/'"${dcol_1xa6_rgba}"'/g
|
||||
s/<wallbash_1xa7_rgba(\([^)]*\))>/'"${dcol_1xa7_rgba}"'/g
|
||||
s/<wallbash_1xa8_rgba(\([^)]*\))>/'"${dcol_1xa8_rgba}"'/g
|
||||
s/<wallbash_1xa9_rgba(\([^)]*\))>/'"${dcol_1xa9_rgba}"'/g
|
||||
s/<wallbash_pry2_rgba(\([^)]*\))>/'"${dcol_pry2_rgba}"'/g
|
||||
s/<wallbash_txt2_rgba(\([^)]*\))>/'"${dcol_txt2_rgba}"'/g
|
||||
s/<wallbash_2xa1_rgba(\([^)]*\))>/'"${dcol_2xa1_rgba}"'/g
|
||||
s/<wallbash_2xa2_rgba(\([^)]*\))>/'"${dcol_2xa2_rgba}"'/g
|
||||
s/<wallbash_2xa3_rgba(\([^)]*\))>/'"${dcol_2xa3_rgba}"'/g
|
||||
s/<wallbash_2xa4_rgba(\([^)]*\))>/'"${dcol_2xa4_rgba}"'/g
|
||||
s/<wallbash_2xa5_rgba(\([^)]*\))>/'"${dcol_2xa5_rgba}"'/g
|
||||
s/<wallbash_2xa6_rgba(\([^)]*\))>/'"${dcol_2xa6_rgba}"'/g
|
||||
s/<wallbash_2xa7_rgba(\([^)]*\))>/'"${dcol_2xa7_rgba}"'/g
|
||||
s/<wallbash_2xa8_rgba(\([^)]*\))>/'"${dcol_2xa8_rgba}"'/g
|
||||
s/<wallbash_2xa9_rgba(\([^)]*\))>/'"${dcol_2xa9_rgba}"'/g
|
||||
s/<wallbash_pry3_rgba(\([^)]*\))>/'"${dcol_pry3_rgba}"'/g
|
||||
s/<wallbash_txt3_rgba(\([^)]*\))>/'"${dcol_txt3_rgba}"'/g
|
||||
s/<wallbash_3xa1_rgba(\([^)]*\))>/'"${dcol_3xa1_rgba}"'/g
|
||||
s/<wallbash_3xa2_rgba(\([^)]*\))>/'"${dcol_3xa2_rgba}"'/g
|
||||
s/<wallbash_3xa3_rgba(\([^)]*\))>/'"${dcol_3xa3_rgba}"'/g
|
||||
s/<wallbash_3xa4_rgba(\([^)]*\))>/'"${dcol_3xa4_rgba}"'/g
|
||||
s/<wallbash_3xa5_rgba(\([^)]*\))>/'"${dcol_3xa5_rgba}"'/g
|
||||
s/<wallbash_3xa6_rgba(\([^)]*\))>/'"${dcol_3xa6_rgba}"'/g
|
||||
s/<wallbash_3xa7_rgba(\([^)]*\))>/'"${dcol_3xa7_rgba}"'/g
|
||||
s/<wallbash_3xa8_rgba(\([^)]*\))>/'"${dcol_3xa8_rgba}"'/g
|
||||
s/<wallbash_3xa9_rgba(\([^)]*\))>/'"${dcol_3xa9_rgba}"'/g
|
||||
s/<wallbash_pry4_rgba(\([^)]*\))>/'"${dcol_pry4_rgba}"'/g
|
||||
s/<wallbash_txt4_rgba(\([^)]*\))>/'"${dcol_txt4_rgba}"'/g
|
||||
s/<wallbash_4xa1_rgba(\([^)]*\))>/'"${dcol_4xa1_rgba}"'/g
|
||||
s/<wallbash_4xa2_rgba(\([^)]*\))>/'"${dcol_4xa2_rgba}"'/g
|
||||
s/<wallbash_4xa3_rgba(\([^)]*\))>/'"${dcol_4xa3_rgba}"'/g
|
||||
s/<wallbash_4xa4_rgba(\([^)]*\))>/'"${dcol_4xa4_rgba}"'/g
|
||||
s/<wallbash_4xa5_rgba(\([^)]*\))>/'"${dcol_4xa5_rgba}"'/g
|
||||
s/<wallbash_4xa6_rgba(\([^)]*\))>/'"${dcol_4xa6_rgba}"'/g
|
||||
s/<wallbash_4xa7_rgba(\([^)]*\))>/'"${dcol_4xa7_rgba}"'/g
|
||||
s/<wallbash_4xa8_rgba(\([^)]*\))>/'"${dcol_4xa8_rgba}"'/g
|
||||
s/<wallbash_4xa9_rgba(\([^)]*\))>/'"${dcol_4xa9_rgba}"'/g' "${target}"
|
||||
fi
|
||||
|
||||
[ -z "${appexe}" ] || bash -c "${appexe}"
|
||||
}
|
||||
|
||||
export -f fn_wallbash
|
||||
|
||||
[ -n "$HYPRLAND_INSTANCE_SIGNATURE" ] && hyprctl keyword misc:disable_autoreload 1 -q && trap 'hyprctl reload -q && echo "[swwwallbash] reload :: Hyprland"' EXIT
|
||||
|
||||
#// switch theme <//> wall based colors
|
||||
|
||||
if [ "${enableWallDcol}" -eq 0 ] && [[ "${reload_flag}" -eq 1 ]] ; then
|
||||
|
||||
echo ":: deploying ${hydeTheme} colors :: ${dcol_mode} wallpaper detected"
|
||||
mapfile -d '' -t deployList < <(find "${hydeThemeDir}" -type f -name "*.theme" -print0)
|
||||
|
||||
while read -r pKey ; do
|
||||
fKey="$(find "${hydeThemeDir}" -type f -name "$(basename "${pKey%.dcol}.theme")")"
|
||||
[ -z "${fKey}" ] && deployList+=("${pKey}")
|
||||
done < <(find "${wallbashDir}/Wall-Dcol" -type f -name "*.dcol")
|
||||
|
||||
parallel fn_wallbash ::: "${deployList[@]}"
|
||||
|
||||
elif [ "${enableWallDcol}" -gt 0 ] ; then
|
||||
|
||||
echo ":: deploying wallbash colors :: ${dcol_mode} wallpaper detected"
|
||||
find "${wallbashDir}/Wall-Dcol" -type f -name "*.dcol" | parallel fn_wallbash {}
|
||||
|
||||
fi
|
||||
|
||||
# Theme mode: detects the color-scheme set in hypr.theme and falls back if nothing is parsed.
|
||||
if [ "${enableWallDcol}" -eq 0 ]; then
|
||||
colorScheme="$({ grep -q "^[[:space:]]*\$COLOR-SCHEME\s*=" "${hydeThemeDir}/hypr.theme" && grep "^[[:space:]]*\$COLOR-SCHEME\s*=" "${hydeThemeDir}/hypr.theme" | cut -d '=' -f2 | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' ;} ||
|
||||
grep 'gsettings set org.gnome.desktop.interface color-scheme' "${hydeThemeDir}/hypr.theme" | awk -F "'" '{print $((NF - 1))}')"
|
||||
colorScheme=${colorScheme:-$(gsettings get org.gnome.desktop.interface color-scheme)}
|
||||
# should be declared explicitly so we can easily debug
|
||||
grep -q "dark" <<< "${colorScheme}" && enableWallDcol=2
|
||||
grep -q "light" <<< "${colorScheme}" && enableWallDcol=3
|
||||
fi
|
||||
|
||||
find "${wallbashDir}/Wall-Ways" -type f -name "*.dcol" | parallel fn_wallbash {}
|
||||
91
scripts/swwwallcache.sh
Executable file
91
scripts/swwwallcache.sh
Executable file
@@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
|
||||
#// set variables
|
||||
|
||||
export scrDir="$(dirname "$(realpath "$0")")"
|
||||
source "${scrDir}/globalcontrol.sh"
|
||||
export thmbDir
|
||||
export dcolDir
|
||||
|
||||
[ -d "${hydeThemeDir}" ] && cacheIn="${hydeThemeDir}" || exit 1
|
||||
[ -d "${thmbDir}" ] || mkdir -p "${thmbDir}"
|
||||
[ -d "${dcolDir}" ] || mkdir -p "${dcolDir}"
|
||||
[ -d "${cacheDir}/landing" ] || mkdir -p "${cacheDir}/landing"
|
||||
|
||||
if [ ! -z "${wallbashCustomCurve}" ] && [[ "${wallbashCustomCurve}" =~ ^([0-9]+[[:space:]][0-9]+\\n){8}[0-9]+[[:space:]][0-9]+$ ]] ; then
|
||||
export wallbashCustomCurve
|
||||
echo ":: wallbash --custom \"${wallbashCustomCurve}\""
|
||||
else
|
||||
export wallbashCustomCurve="32 50\n42 46\n49 40\n56 39\n64 38\n76 37\n90 33\n94 29\n100 20"
|
||||
fi
|
||||
|
||||
|
||||
#// define functions
|
||||
|
||||
fn_wallcache()
|
||||
{
|
||||
local x_hash="${1}"
|
||||
local x_wall="${2}"
|
||||
[ ! -e "${thmbDir}/${x_hash}.thmb" ] && magick "${x_wall}"[0] -strip -resize 1000 -gravity center -extent 1000 -quality 90 "${thmbDir}/${x_hash}.thmb"
|
||||
[ ! -e "${thmbDir}/${x_hash}.sqre" ] && magick "${x_wall}"[0] -strip -thumbnail 500x500^ -gravity center -extent 500x500 "${thmbDir}/${x_hash}.sqre"
|
||||
[ ! -e "${thmbDir}/${x_hash}.blur" ] && magick "${x_wall}"[0] -strip -scale 10% -blur 0x3 -resize 100% "${thmbDir}/${x_hash}.blur"
|
||||
[ ! -e "${thmbDir}/${x_hash}.quad" ] && magick "${thmbDir}/${x_hash}.sqre" \( -size 500x500 xc:white -fill "rgba(0,0,0,0.7)" -draw "polygon 400,500 500,500 500,0 450,0" -fill black -draw "polygon 500,500 500,0 450,500" \) -alpha Off -compose CopyOpacity -composite "${thmbDir}/${x_hash}.png" && mv "${thmbDir}/${x_hash}.png" "${thmbDir}/${x_hash}.quad"
|
||||
{ [ ! -e "${dcolDir}/${x_hash}.dcol" ] || [ "$(wc -l < "${dcolDir}/${x_hash}.dcol")" -ne 89 ] ;} && "${scrDir}/wallbash.sh" --custom "${wallbashCustomCurve}" "${thmbDir}/${x_hash}.thmb" "${dcolDir}/${x_hash}" &> /dev/null
|
||||
}
|
||||
|
||||
fn_wallcache_force()
|
||||
{
|
||||
local x_hash="${1}"
|
||||
local x_wall="${2}"
|
||||
magick "${x_wall}"[0] -strip -resize 1000 -gravity center -extent 1000 -quality 90 "${thmbDir}/${x_hash}.thmb"
|
||||
magick "${x_wall}"[0] -strip -thumbnail 500x500^ -gravity center -extent 500x500 "${thmbDir}/${x_hash}.sqre"
|
||||
magick "${x_wall}"[0] -strip -scale 10% -blur 0x3 -resize 100% "${thmbDir}/${x_hash}.blur"
|
||||
magick "${thmbDir}/${x_hash}.sqre" \( -size 500x500 xc:white -fill "rgba(0,0,0,0.7)" -draw "polygon 400,500 500,500 500,0 450,0" -fill black -draw "polygon 500,500 500,0 450,500" \) -alpha Off -compose CopyOpacity -composite "${thmbDir}/${x_hash}.png" && mv "${thmbDir}/${x_hash}.png" "${thmbDir}/${x_hash}.quad"
|
||||
"${scrDir}/wallbash.sh" --custom "${wallbashCustomCurve}" "${thmbDir}/${x_hash}.thmb" "${dcolDir}/${x_hash}" &> /dev/null
|
||||
}
|
||||
|
||||
export -f fn_wallcache
|
||||
export -f fn_wallcache_force
|
||||
|
||||
|
||||
#// evaluate options
|
||||
|
||||
while getopts "w:t:f" option ; do
|
||||
case $option in
|
||||
w ) # generate cache for input wallpaper
|
||||
if [ -z "${OPTARG}" ] || [ ! -f "${OPTARG}" ] ; then
|
||||
echo "Error: Input wallpaper \"${OPTARG}\" not found!"
|
||||
exit 1
|
||||
fi
|
||||
cacheIn="${OPTARG}"
|
||||
;;
|
||||
t ) # generate cache for input theme
|
||||
cacheIn="$(dirname "${hydeThemeDir}")/${OPTARG}"
|
||||
if [ ! -d "${cacheIn}" ] ; then
|
||||
echo "Error: Input theme \"${OPTARG}\" not found!"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
f ) # full cache rebuild
|
||||
cacheIn="$(dirname "${hydeThemeDir}")"
|
||||
mode="_force"
|
||||
;;
|
||||
* ) # invalid option
|
||||
echo "... invalid option ..."
|
||||
echo "$(basename "${0}") -[option]"
|
||||
echo "w : generate cache for input wallpaper"
|
||||
echo "t : generate cache for input theme"
|
||||
echo "f : full cache rebuild"
|
||||
exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
|
||||
#// generate cache
|
||||
|
||||
wallPathArray=("${cacheIn}")
|
||||
wallPathArray+=("${wallAddCustomPath[@]}")
|
||||
get_hashmap "${wallPathArray[@]}"
|
||||
parallel --bar --link "fn_wallcache${mode}" ::: "${wallHash[@]}" ::: "${wallList[@]}"
|
||||
exit 0
|
||||
73
scripts/swwwallkon.sh
Executable file
73
scripts/swwwallkon.sh
Executable file
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
|
||||
#// Set variables
|
||||
|
||||
scrDir=$(dirname "$(realpath "$0")")
|
||||
source "${scrDir}/globalcontrol.sh"
|
||||
scrName="$(basename "$0")"
|
||||
kmenuPath="$HOME/.local/share/kio/servicemenus"
|
||||
kmenuDesk="${kmenuPath}/hydewallpaper.desktop"
|
||||
tgtPath="$(dirname "${hydeThemeDir}")"
|
||||
get_themes
|
||||
|
||||
|
||||
#// Evaluate options
|
||||
|
||||
while getopts "t:w:" option ; do
|
||||
case $option in
|
||||
|
||||
t ) # Set theme
|
||||
for x in "${!thmList[@]}" ; do
|
||||
if [ "${thmList[x]}" == "$OPTARG" ] ; then
|
||||
setTheme="${thmList[x]}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
[ -z "${setTheme}" ] && echo "Error: '$OPTARG' theme not available..." && exit 1
|
||||
;;
|
||||
|
||||
w ) # Set wallpaper
|
||||
if [ -f "$OPTARG" ] && file --mime-type "$OPTARG" | grep -q 'image/' ; then
|
||||
setWall="$OPTARG"
|
||||
else
|
||||
echo "Error: '$OPTARG' is not an image file..."
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
* ) # Refresh menu
|
||||
unset setTheme
|
||||
unset setWall
|
||||
;;
|
||||
|
||||
esac
|
||||
done
|
||||
|
||||
|
||||
#// Regenerate desktop
|
||||
|
||||
if [ ! -z "${setTheme}" ] && [ ! -z "${setWall}" ] ; then
|
||||
|
||||
inwallHash="$(set_hash "${setWall}")"
|
||||
get_hashmap "${tgtPath}/${setTheme}"
|
||||
if [[ "${wallHash[@]}" == *"${inwallHash}"* ]] ; then
|
||||
notify-send -a "t2" -i "${thmbDir}/${inwallHash}.sqre" "Error" "Hash matched in ${setTheme}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
cp "${setWall}" "${tgtPath}/${setTheme}/wallpapers"
|
||||
ln -fs "${tgtPath}/${setTheme}/wallpapers/$(basename "${setWall}")" "${tgtPath}/${setTheme}/wall.set"
|
||||
|
||||
"${scrDir}/themeswitch.sh" -s "${setTheme}"
|
||||
notify-send -a "t1" -i "${thmbDir}/${inwallHash}.sqre" "Wallpaper set in ${setTheme}"
|
||||
|
||||
else
|
||||
|
||||
echo -e "[Desktop Entry]\nType=Service\nMimeType=image/png;image/jpeg;image/jpg;image/gif\nActions=Menu-Refresh$(printf ";%s" "${thmList[@]}")\nX-KDE-Submenu=Set As Wallpaper...\n\n[Desktop Action Menu-Refresh]\nName=.: Refresh List :.\nExec=${scrName}" > "${kmenuDesk}"
|
||||
for i in "${!thmList[@]}" ; do
|
||||
echo -e "\n[Desktop Action ${thmList[i]}]\nName=${thmList[i]}\nExec=${scrName} -t \"${thmList[i]}\" -w %u" >> "${kmenuDesk}"
|
||||
done
|
||||
|
||||
fi
|
||||
|
||||
0
scripts/swwwallpaper.sh
Executable file
0
scripts/swwwallpaper.sh
Executable file
52
scripts/swwwallselect.sh
Executable file
52
scripts/swwwallselect.sh
Executable file
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
|
||||
#// set variables
|
||||
|
||||
scrDir="$(dirname "$(realpath "$0")")"
|
||||
source "${scrDir}/globalcontrol.sh"
|
||||
rofiConf="${confDir}/rofi/selector.rasi"
|
||||
|
||||
|
||||
#// set rofi scaling
|
||||
|
||||
[[ "${rofiScale}" =~ ^[0-9]+$ ]] || rofiScale=10
|
||||
r_scale="configuration {font: \"JetBrainsMono Nerd Font ${rofiScale}\";}"
|
||||
elem_border=$(( hypr_border * 3 ))
|
||||
|
||||
|
||||
#// scale for monitor
|
||||
|
||||
mon_x_res=$(hyprctl -j monitors | jq '.[] | select(.focused==true) | .width')
|
||||
mon_scale=$(hyprctl -j monitors | jq '.[] | select(.focused==true) | .scale' | sed "s/\.//")
|
||||
mon_x_res=$(( mon_x_res * 100 / mon_scale ))
|
||||
|
||||
|
||||
#// generate config
|
||||
|
||||
elm_width=$(( (28 + 8 + 5) * rofiScale ))
|
||||
max_avail=$(( mon_x_res - (4 * rofiScale) ))
|
||||
col_count=$(( max_avail / elm_width ))
|
||||
r_override="window{width:100%;} listview{columns:${col_count};spacing:5em;} element{border-radius:${elem_border}px;orientation:vertical;} element-icon{size:28em;border-radius:0em;} element-text{padding:1em;}"
|
||||
|
||||
|
||||
#// launch rofi menu
|
||||
|
||||
currentWall="$(basename "$(readlink "${hydeThemeDir}/wall.set")")"
|
||||
wallPathArray=("${hydeThemeDir}")
|
||||
wallPathArray+=("${wallAddCustomPath[@]}")
|
||||
get_hashmap "${wallPathArray[@]}"
|
||||
rofiSel=$(parallel --link echo -en "\$(basename "{1}")"'\\x00icon\\x1f'"${thmbDir}"'/'"{2}"'.sqre\\n' ::: "${wallList[@]}" ::: "${wallHash[@]}" | rofi -dmenu -theme-str "${r_scale}" -theme-str "${r_override}" -config "${rofiConf}" -select "${currentWall}")
|
||||
|
||||
|
||||
#// apply wallpaper
|
||||
|
||||
if [ ! -z "${rofiSel}" ] ; then
|
||||
for i in "${!wallPathArray[@]}" ; do
|
||||
setWall="$(find "${wallPathArray[i]}" -type f -name "${rofiSel}")"
|
||||
[ -z "${setWall}" ] || break
|
||||
done
|
||||
"${scrDir}/swwwallpaper.sh" -s "${setWall}"
|
||||
notify-send -a "t1" -i "${thmbDir}/$(set_hash "${setWall}").sqre" " ${rofiSel}"
|
||||
fi
|
||||
|
||||
14
scripts/sysmonlaunch.sh
Executable file
14
scripts/sysmonlaunch.sh
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
scrDir="$(dirname "$(realpath "$0")")"
|
||||
source "${scrDir}/globalcontrol.sh"
|
||||
pkgChk=("io.missioncenter.MissionCenter" "htop" "btop" "top")
|
||||
|
||||
for sysMon in "${!pkgChk[@]}"; do
|
||||
[ "${sysMon}" -gt 0 ] && term=$(cat $HOME/.config/hypr/keybindings.conf | grep ^'$term' | cut -d '=' -f2)
|
||||
if pkg_installed "${pkgChk[sysMon]}" ; then
|
||||
pkill -x "${pkgChk[sysMon]}" || ${term} "${pkgChk[sysMon]}" &
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
53
scripts/systemupdate.sh
Executable file
53
scripts/systemupdate.sh
Executable file
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Check release
|
||||
if [ ! -f /etc/arch-release ] ; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# source variables
|
||||
scrDir=$(dirname "$(realpath "$0")")
|
||||
source "$scrDir/globalcontrol.sh"
|
||||
get_aurhlpr
|
||||
export -f pkg_installed
|
||||
fpk_exup="pkg_installed flatpak && flatpak update"
|
||||
|
||||
# Trigger upgrade
|
||||
if [ "$1" == "up" ] ; then
|
||||
trap 'pkill -RTMIN+20 waybar' EXIT
|
||||
command="
|
||||
fastfetch
|
||||
$0 upgrade
|
||||
${aurhlpr} -Syu
|
||||
$fpk_exup
|
||||
read -n 1 -p 'Press any key to continue...'
|
||||
"
|
||||
kitty --title systemupdate sh -c "${command}"
|
||||
fi
|
||||
|
||||
# Check for AUR updates
|
||||
aur=$(${aurhlpr} -Qua | wc -l)
|
||||
ofc=$( (while pgrep -x checkupdates > /dev/null ; do sleep 1; done) ; checkupdates | wc -l)
|
||||
|
||||
# Check for flatpak updates
|
||||
if pkg_installed flatpak ; then
|
||||
fpk=$(flatpak remote-ls --updates | wc -l)
|
||||
fpk_disp="\n Flatpak $fpk"
|
||||
else
|
||||
fpk=0
|
||||
fpk_disp=""
|
||||
fi
|
||||
|
||||
# Calculate total available updates
|
||||
upd=$(( ofc + aur + fpk ))
|
||||
|
||||
[ "${1}" == upgrade ] && printf "[Official] %-10s\n[AUR] %-10s\n[Flatpak] %-10s\n" "$ofc" "$aur" "$fpk" && exit
|
||||
|
||||
# Show tooltip
|
||||
if [ $upd -eq 0 ] ; then
|
||||
upd="" #Remove Icon completely
|
||||
# upd="" #If zero Display Icon only
|
||||
echo "{\"text\":\"$upd\", \"tooltip\":\" Packages are up to date\"}"
|
||||
else
|
||||
echo "{\"text\":\" $upd\", \"tooltip\":\" Official $ofc\n AUR $aur$fpk_disp\"}"
|
||||
fi
|
||||
27
scripts/testrunner.sh
Executable file
27
scripts/testrunner.sh
Executable file
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
scrDir=`dirname "$(realpath "$0")"`
|
||||
source $scrDir/globalcontrol.sh
|
||||
rofDir="${confDir}/rofi"
|
||||
|
||||
if [ "${1}" == "--verbose" ] || [ "${1}" == "-v" ] ; then
|
||||
|
||||
case ${enableWallDcol} in
|
||||
0) wallbashStatus="disabled";;
|
||||
1) wallbashStatus="enabled // auto change based on wallpaper brightness";;
|
||||
2) wallbashStatus="enabled // dark mode --forced";;
|
||||
3) wallbashStatus="enabled // light mode --forced";;
|
||||
esac
|
||||
|
||||
echo -e "\n\ncurrent theme :: \"${hydeTheme}\" :: \"$(readlink "${hydeThemeDir}/wall.set")\""
|
||||
echo -e "wallbash status :: ${enableWallDcol} :: ${wallbashStatus}\n"
|
||||
get_themes
|
||||
|
||||
for x in "${!thmList[@]}" ; do
|
||||
echo -e "\nTheme $((x + 1)) :: \${thmList[${x}]}=\"${thmList[x]}\" :: \${thmWall[${x}]}=\"${thmWall[x]}\"\n"
|
||||
get_hashmap "$(dirname "${hydeThemeDir}")/${thmList[x]}" --verbose
|
||||
echo -e "\n"
|
||||
done
|
||||
|
||||
exit 0
|
||||
fi
|
||||
59
scripts/themeselect.sh
Executable file
59
scripts/themeselect.sh
Executable file
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
|
||||
#// set variables
|
||||
|
||||
scrDir="$(dirname "$(realpath "$0")")"
|
||||
source "${scrDir}/globalcontrol.sh"
|
||||
rofiConf="${confDir}/rofi/selector.rasi"
|
||||
|
||||
|
||||
#// set rofi scaling
|
||||
|
||||
[[ "${rofiScale}" =~ ^[0-9]+$ ]] || rofiScale=10
|
||||
r_scale="configuration {font: \"JetBrainsMono Nerd Font ${rofiScale}\";}"
|
||||
elem_border=$(( hypr_border * 5 ))
|
||||
icon_border=$(( elem_border - 5 ))
|
||||
|
||||
|
||||
#// scale for monitor
|
||||
|
||||
mon_x_res=$(hyprctl -j monitors | jq '.[] | select(.focused==true) | .width')
|
||||
mon_scale=$(hyprctl -j monitors | jq '.[] | select(.focused==true) | .scale' | sed "s/\.//")
|
||||
mon_x_res=$(( mon_x_res * 100 / mon_scale ))
|
||||
|
||||
|
||||
#// generate config
|
||||
|
||||
case "${themeSelect}" in
|
||||
2) # adapt to style 2
|
||||
elm_width=$(( (20 + 12) * rofiScale * 2 ))
|
||||
max_avail=$(( mon_x_res - (4 * rofiScale) ))
|
||||
col_count=$(( max_avail / elm_width ))
|
||||
r_override="window{width:100%;background-color:#00000003;} listview{columns:${col_count};} element{border-radius:${elem_border}px;background-color:@main-bg;} element-icon{size:20em;border-radius:${icon_border}px 0px 0px ${icon_border}px;}"
|
||||
thmbExtn="quad" ;;
|
||||
*) # default to style 1
|
||||
elm_width=$(( (23 + 12 + 1) * rofiScale * 2 ))
|
||||
max_avail=$(( mon_x_res - (4 * rofiScale) ))
|
||||
col_count=$(( max_avail / elm_width ))
|
||||
r_override="window{width:100%;} listview{columns:${col_count};} element{border-radius:${elem_border}px;padding:0.5em;} element-icon{size:23em;border-radius:${icon_border}px;}"
|
||||
thmbExtn="sqre" ;;
|
||||
esac
|
||||
|
||||
|
||||
#// launch rofi menu
|
||||
|
||||
get_themes
|
||||
|
||||
rofiSel=$(for i in ${!thmList[@]} ; do
|
||||
echo -en "${thmList[i]}\x00icon\x1f${thmbDir}/$(set_hash "${thmWall[i]}").${thmbExtn}\n"
|
||||
done | rofi -dmenu -theme-str "${r_scale}" -theme-str "${r_override}" -config "${rofiConf}" -select "${hydeTheme}")
|
||||
|
||||
|
||||
#// apply theme
|
||||
|
||||
if [ ! -z "${rofiSel}" ] ; then
|
||||
"${scrDir}/themeswitch.sh" -s "${rofiSel}"
|
||||
notify-send -a "t1" -i "$HOME/.config/dunst/icons/hyprdots.png" " ${rofiSel}"
|
||||
fi
|
||||
|
||||
42
scripts/themestyle.sh
Executable file
42
scripts/themestyle.sh
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
#// set variables
|
||||
scrDir="$(dirname "$(realpath "$0")")"
|
||||
source "${scrDir}/globalcontrol.sh"
|
||||
rofiConf="${confDir}/rofi/selector.rasi"
|
||||
rofiAssetDir="${confDir}/rofi/assets"
|
||||
|
||||
#// set rofi scaling
|
||||
[[ "${rofiScale}" =~ ^[0-9]+$ ]] || rofiScale=15
|
||||
r_scale="configuration {font: \"JetBrainsMono Nerd Font ${rofiScale}\";}"
|
||||
elem_border=$(( hypr_border * 5 ))
|
||||
icon_border=$(( elem_border - 5 ))
|
||||
|
||||
#// defining 2 png files to select from
|
||||
options="Style 1\x00icon\x1f${rofiAssetDir}/theme_style_1.png\nStyle 2\x00icon\x1f${rofiAssetDir}/theme_style_2.png"
|
||||
|
||||
#// generate config
|
||||
mon_x_res=$(hyprctl -j monitors | jq '.[] | select(.focused==true) | .width')
|
||||
mon_scale=$(hyprctl -j monitors | jq '.[] | select(.focused==true) | .scale' | sed "s/\.//")
|
||||
mon_x_res=$(( mon_x_res * 100 / mon_scale ))
|
||||
|
||||
elm_width=$(( (20 + 12 + 16 ) * rofiScale ))
|
||||
max_avail=$(( mon_x_res - (4 * rofiScale) ))
|
||||
col_count=$(( max_avail / elm_width ))
|
||||
[[ "${col_count}" -gt 5 ]] && col_count=5
|
||||
r_override="window{width:100%;} listview{columns:${col_count};} element{orientation:vertical;border-radius:${elem_border}px;} element-icon{border-radius:${icon_border}px;size:20em;} element-text{enabled:false;}"
|
||||
|
||||
#// launch rofi menu
|
||||
RofiSel=$(echo -e "$options" | rofi -dmenu -theme-str "${r_override}" -config "${rofiConf}")
|
||||
|
||||
#// apply selected theme
|
||||
if [ ! -z "${RofiSel}" ]; then
|
||||
#// extract selected style number ('Style 1' -> '1')
|
||||
selectedStyle=$(echo "${RofiSel}" | awk -F '\x00' '{print $1}' | sed 's/Style //')
|
||||
|
||||
#// notify the user
|
||||
notify-send -a "t1" -r 91190 -t 2200 -i "${rofiAssetDir}/theme_style_${selectedStyle}.png" "Style ${selectedStyle} applied..."
|
||||
|
||||
#// save selection in config file
|
||||
set_conf "themeSelect" "${selectedStyle}"
|
||||
fi
|
||||
121
scripts/themeswitch.sh
Executable file
121
scripts/themeswitch.sh
Executable file
@@ -0,0 +1,121 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
|
||||
#// set variables
|
||||
|
||||
scrDir="$(dirname "$(realpath "$0")")"
|
||||
source "${scrDir}/globalcontrol.sh"
|
||||
[ -z "${hydeTheme}" ] && echo "ERROR: unable to detect theme" && exit 1
|
||||
get_themes
|
||||
|
||||
|
||||
#// define functions
|
||||
|
||||
Theme_Change()
|
||||
{
|
||||
local x_switch=$1
|
||||
for i in ${!thmList[@]} ; do
|
||||
if [ "${thmList[i]}" == "${hydeTheme}" ] ; then
|
||||
if [ "${x_switch}" == 'n' ] ; then
|
||||
setIndex=$(( (i + 1) % ${#thmList[@]} ))
|
||||
elif [ "${x_switch}" == 'p' ] ; then
|
||||
setIndex=$(( i - 1 ))
|
||||
fi
|
||||
themeSet="${thmList[setIndex]}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
#// evaluate options
|
||||
|
||||
while getopts "nps:" option ; do
|
||||
case $option in
|
||||
|
||||
n ) # set next theme
|
||||
Theme_Change n
|
||||
export xtrans="grow" ;;
|
||||
|
||||
p ) # set previous theme
|
||||
Theme_Change p
|
||||
export xtrans="outer" ;;
|
||||
|
||||
s ) # set selected theme
|
||||
themeSet="$OPTARG" ;;
|
||||
|
||||
* ) # invalid option
|
||||
echo "... invalid option ..."
|
||||
echo "$(basename "${0}") -[option]"
|
||||
echo "n : set next theme"
|
||||
echo "p : set previous theme"
|
||||
echo "s : set input theme"
|
||||
exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
|
||||
#// update control file
|
||||
|
||||
if ! $(echo "${thmList[@]}" | grep -wq "${themeSet}") ; then
|
||||
themeSet="${hydeTheme}"
|
||||
fi
|
||||
|
||||
set_conf "hydeTheme" "${themeSet}"
|
||||
echo ":: applying theme :: \"${themeSet}\""
|
||||
export reload_flag=1
|
||||
source "${scrDir}/globalcontrol.sh"
|
||||
|
||||
|
||||
#// hypr
|
||||
[ -n "$HYPRLAND_INSTANCE_SIGNATURE" ] && hyprctl keyword misc:disable_autoreload 1 -q
|
||||
sed '1d' "${hydeThemeDir}/hypr.theme" > "${confDir}/hypr/themes/theme.conf" # Useless and already handled by swwwallbash.sh but kept for robustness
|
||||
gtkTheme="$(
|
||||
{ grep -q "^[[:space:]]*\$GTK[-_]THEME\s*=" "${hydeThemeDir}/hypr.theme" && grep "^[[:space:]]*\$GTK[-_]THEME\s*=" "${hydeThemeDir}/hypr.theme" | cut -d '=' -f2 | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' ;} ||
|
||||
grep 'gsettings set org.gnome.desktop.interface gtk-theme' "${hydeThemeDir}/hypr.theme" | awk -F "'" '{print $((NF - 1))}'
|
||||
)"
|
||||
|
||||
gtkIcon="$(
|
||||
{ grep -q "^[[:space:]]*\$ICON[-_]THEME\s*=" "${hydeThemeDir}/hypr.theme" && grep "^[[:space:]]*\$ICON[-_]THEME\s*=" "${hydeThemeDir}/hypr.theme" | cut -d '=' -f2 | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' ;} ||
|
||||
grep 'gsettings set org.gnome.desktop.interface icon-theme' "${hydeThemeDir}/hypr.theme" | awk -F "'" '{print $(NF - 1)}'
|
||||
)"
|
||||
|
||||
#// qtct
|
||||
|
||||
sed -i "/^icon_theme=/c\icon_theme=${gtkIcon}" "${confDir}/qt5ct/qt5ct.conf"
|
||||
sed -i "/^icon_theme=/c\icon_theme=${gtkIcon}" "${confDir}/qt6ct/qt6ct.conf"
|
||||
sed -i "/^Theme=/c\Theme=${gtkIcon}" "${confDir}/kdeglobals"
|
||||
|
||||
#// gtk3
|
||||
|
||||
sed -i "/^gtk-theme-name=/c\gtk-theme-name=${gtkTheme}" $confDir/gtk-3.0/settings.ini
|
||||
sed -i "/^gtk-icon-theme-name=/c\gtk-icon-theme-name=${gtkIcon}" $confDir/gtk-3.0/settings.ini
|
||||
|
||||
|
||||
#// gtk4
|
||||
|
||||
if [ -d /run/current-system/sw/share/themes ] ; then
|
||||
themeDir=/run/current-system/sw/share/themes
|
||||
else
|
||||
themeDir=~/.themes
|
||||
fi
|
||||
rm -rf "${confDir}/gtk-4.0"
|
||||
ln -s "${themeDir}/${gtkTheme}/gtk-4.0" "${confDir}/gtk-4.0"
|
||||
|
||||
|
||||
#// flatpak GTK
|
||||
|
||||
if pkg_installed flatpak ; then
|
||||
if [ "${enableWallDcol}" -eq 0 ] ; then
|
||||
flatpak --user override --env=GTK_THEME="${gtkTheme}"
|
||||
flatpak --user override --env=ICON_THEME="${gtkIcon}"
|
||||
else
|
||||
flatpak --user override --env=GTK_THEME="Wallbash-Gtk"
|
||||
flatpak --user override --env=ICON_THEME="${gtkIcon}"
|
||||
fi
|
||||
fi
|
||||
|
||||
#// wallpaper
|
||||
|
||||
"${scrDir}/swwwallpaper.sh" -s "$(readlink "${hydeThemeDir}/wall.set")"
|
||||
|
||||
4
scripts/tmux-session-manager
Executable file
4
scripts/tmux-session-manager
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
exec "$SCRIPT_DIR/tmux-session-manager.sh" "$@"
|
||||
409
scripts/tmux-session-manager.sh
Executable file
409
scripts/tmux-session-manager.sh
Executable file
@@ -0,0 +1,409 @@
|
||||
#!/usr/bin/env bash
|
||||
# Tmux Session Manager - Manage multiple named tmux sessions with persistence
|
||||
# Usage: tmux-session-manager.sh [session-name] [action]
|
||||
# Actions: save, restore, list, delete
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SESSION_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/tmux/sessions"
|
||||
RESURRECT_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/tmux/resurrect"
|
||||
|
||||
# Create directories if they don't exist
|
||||
mkdir -p "$SESSION_DIR" "$RESURRECT_DIR"
|
||||
|
||||
show_usage() {
|
||||
cat <<EOF
|
||||
Tmux Session Manager - Manage multiple named tmux sessions with persistence
|
||||
|
||||
Usage: tmux-session-manager [command] [options]
|
||||
|
||||
Commands:
|
||||
list List all saved session configurations
|
||||
create <name> Create or switch to a named session
|
||||
save <name> Manually save current session state
|
||||
restore <name> Restore a specific named session
|
||||
delete <name> Delete a named session configuration
|
||||
restore-all Restore all sessions at once
|
||||
auto-save Automatically save all active sessions (for cron/timer)
|
||||
|
||||
Examples:
|
||||
tmux-session-manager create main # Create/switch to 'main' session
|
||||
tmux-session-manager save work # Save current session as 'work'
|
||||
tmux-session-manager restore dev # Restore 'dev' session
|
||||
tmux-session-manager list # List all sessions
|
||||
EOF
|
||||
}
|
||||
|
||||
last_snapshot_sessions() {
|
||||
local last_file="$RESURRECT_DIR/last"
|
||||
|
||||
if [ ! -f "$last_file" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
awk -F '\t' '$1 == "pane" { print $2 }' "$last_file" | sort -u
|
||||
}
|
||||
|
||||
session_path_matches_name() {
|
||||
local session="$1"
|
||||
local desired_name="$2"
|
||||
local desired_basename="$desired_name"
|
||||
local path=""
|
||||
|
||||
if [[ "$desired_name" == _* ]]; then
|
||||
desired_basename=".${desired_name#_}"
|
||||
fi
|
||||
|
||||
while IFS= read -r path; do
|
||||
[ -n "$path" ] || continue
|
||||
if [ "$(basename "$path")" = "$desired_basename" ]; then
|
||||
return 0
|
||||
fi
|
||||
done < <(tmux list-panes -t "=${session}" -F "#{pane_current_path}" 2>/dev/null)
|
||||
|
||||
if [ "$desired_name" = "main" ]; then
|
||||
while IFS= read -r path; do
|
||||
[ -n "$path" ] || continue
|
||||
if [ "$path" = "$HOME" ]; then
|
||||
return 0
|
||||
fi
|
||||
done < <(tmux list-panes -t "=${session}" -F "#{pane_current_path}" 2>/dev/null)
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
run_resurrect_restore() {
|
||||
local restore_script
|
||||
restore_script="$(tmux show-options -gv @resurrect-restore-script-path 2>/dev/null || true)"
|
||||
|
||||
if [ -z "$restore_script" ]; then
|
||||
echo "Error: Could not determine resurrect restore script path"
|
||||
return 1
|
||||
fi
|
||||
|
||||
tmux run-shell "$restore_script"
|
||||
}
|
||||
|
||||
run_resurrect_save() {
|
||||
local save_script
|
||||
save_script="$(tmux show-options -gv @resurrect-save-script-path 2>/dev/null || true)"
|
||||
|
||||
if [ -z "$save_script" ]; then
|
||||
echo "Error: Could not determine resurrect save script path"
|
||||
return 1
|
||||
fi
|
||||
|
||||
tmux run-shell "$save_script quiet"
|
||||
}
|
||||
|
||||
save_session() {
|
||||
local session_name="$1"
|
||||
|
||||
# Get the current session if not specified
|
||||
if [ -z "$session_name" ]; then
|
||||
session_name=$(tmux display-message -p '#{session_name}' 2>/dev/null || echo "")
|
||||
if [ -z "$session_name" ]; then
|
||||
echo "Error: No active tmux session found"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if session exists
|
||||
if ! tmux has-session -t "$session_name" 2>/dev/null; then
|
||||
echo "Error: Session '$session_name' does not exist"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Save session using resurrect script
|
||||
run_resurrect_save
|
||||
|
||||
echo "Saving session '$session_name'..."
|
||||
sleep 1
|
||||
|
||||
# Also create a backup of the session state
|
||||
local backup_file="$SESSION_DIR/${session_name}.state"
|
||||
tmux capture-pane -t "$session_name" -p > "$backup_file" || true
|
||||
|
||||
echo "Session '$session_name' saved"
|
||||
}
|
||||
|
||||
restore_session() {
|
||||
local session_name="$1"
|
||||
local bootstrap_session="__tsm_restore_bootstrap"
|
||||
local trigger_session=""
|
||||
local restored=0
|
||||
local renamed=0
|
||||
local candidate_session=""
|
||||
local -a before_sessions=()
|
||||
local -a after_sessions=()
|
||||
local -a new_sessions=()
|
||||
|
||||
if [ -z "$session_name" ]; then
|
||||
echo "Error: Session name required"
|
||||
show_usage
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Use resurrect to restore the most recent snapshot.
|
||||
# A target session might not currently exist, so trigger restore from any live session.
|
||||
echo "Restoring session '$session_name' from latest resurrect save..."
|
||||
|
||||
while IFS= read -r session; do
|
||||
[ -n "$session" ] && before_sessions+=("$session")
|
||||
done < <(tmux list-sessions -F "#{session_name}" 2>/dev/null || true)
|
||||
|
||||
if ! tmux list-sessions >/dev/null 2>&1; then
|
||||
tmux new-session -d -s "$bootstrap_session"
|
||||
trigger_session="$bootstrap_session"
|
||||
else
|
||||
while IFS= read -r session; do
|
||||
if [ -n "$session" ]; then
|
||||
trigger_session="$session"
|
||||
break
|
||||
fi
|
||||
done < <(tmux list-sessions -F "#{session_name}" 2>/dev/null)
|
||||
fi
|
||||
|
||||
if [ -z "$trigger_session" ]; then
|
||||
echo "Error: Could not find a tmux session to trigger restore"
|
||||
return 1
|
||||
fi
|
||||
|
||||
run_resurrect_restore
|
||||
|
||||
for _ in $(seq 1 20); do
|
||||
if tmux has-session -t "$session_name" 2>/dev/null; then
|
||||
restored=1
|
||||
break
|
||||
fi
|
||||
sleep 0.25
|
||||
done
|
||||
|
||||
while IFS= read -r session; do
|
||||
[ -n "$session" ] && after_sessions+=("$session")
|
||||
done < <(tmux list-sessions -F "#{session_name}" 2>/dev/null || true)
|
||||
|
||||
if [ "$restored" -eq 0 ]; then
|
||||
for session in "${after_sessions[@]}"; do
|
||||
local existed=0
|
||||
for before in "${before_sessions[@]}"; do
|
||||
if [ "$session" = "$before" ]; then
|
||||
existed=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ "$existed" -eq 0 ]; then
|
||||
new_sessions+=("$session")
|
||||
fi
|
||||
done
|
||||
|
||||
# Give resurrect a moment to fully materialize pane paths before matching.
|
||||
for _ in $(seq 1 20); do
|
||||
candidate_session=""
|
||||
|
||||
for session in "${new_sessions[@]}"; do
|
||||
if session_path_matches_name "$session" "$session_name"; then
|
||||
candidate_session="$session"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# If no brand-new session matched, fall back to any current session.
|
||||
# This handles cases where restore reused existing numeric sessions.
|
||||
if [ -z "$candidate_session" ]; then
|
||||
for session in "${after_sessions[@]}"; do
|
||||
if [ "$session" = "$session_name" ]; then
|
||||
continue
|
||||
fi
|
||||
if session_path_matches_name "$session" "$session_name"; then
|
||||
candidate_session="$session"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -n "$candidate_session" ]; then
|
||||
break
|
||||
fi
|
||||
|
||||
sleep 0.25
|
||||
done
|
||||
|
||||
if [ -z "$candidate_session" ] && [ "${#new_sessions[@]}" -eq 1 ]; then
|
||||
candidate_session="${new_sessions[0]}"
|
||||
fi
|
||||
|
||||
if [ -n "$candidate_session" ] && ! tmux has-session -t "$session_name" 2>/dev/null; then
|
||||
tmux rename-session -t "=${candidate_session}" "$session_name"
|
||||
restored=1
|
||||
renamed=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$trigger_session" = "$bootstrap_session" ] && tmux has-session -t "$bootstrap_session" 2>/dev/null; then
|
||||
tmux kill-session -t "$bootstrap_session" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
if [ "$restored" -eq 1 ]; then
|
||||
if [ "$renamed" -eq 1 ]; then
|
||||
echo "Session '$session_name' restored by renaming '$candidate_session'"
|
||||
else
|
||||
echo "Session '$session_name' restored and available"
|
||||
fi
|
||||
else
|
||||
local snapshot_sessions
|
||||
snapshot_sessions="$(last_snapshot_sessions | tr '\n' ' ' | sed 's/[[:space:]]*$//')"
|
||||
if [ -n "$snapshot_sessions" ]; then
|
||||
echo "Restore was triggered, but '$session_name' was not found in the latest snapshot (contains: $snapshot_sessions)"
|
||||
else
|
||||
echo "Restore was triggered, but '$session_name' was not found and no snapshot sessions were detected"
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
create_session() {
|
||||
local session_name="$1"
|
||||
|
||||
if [ -z "$session_name" ]; then
|
||||
echo "Error: Session name required"
|
||||
show_usage
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check if session already exists
|
||||
if tmux has-session -t "$session_name" 2>/dev/null; then
|
||||
echo "Session '$session_name' already exists, attaching..."
|
||||
tmux attach-session -t "=${session_name}"
|
||||
else
|
||||
echo "Creating new session '$session_name'..."
|
||||
tmux new-session -d -s "$session_name"
|
||||
tmux send-keys -t "$session_name" "# Session: $session_name" Enter
|
||||
echo "Session '$session_name' created"
|
||||
tmux attach-session -t "=${session_name}"
|
||||
fi
|
||||
}
|
||||
|
||||
list_sessions() {
|
||||
echo "Available tmux sessions:"
|
||||
tmux list-sessions -F "#{session_name}: #{session_windows} windows" 2>/dev/null || echo "No tmux sessions found"
|
||||
|
||||
echo ""
|
||||
echo "Session names in latest resurrect snapshot:"
|
||||
local snapshot_sessions
|
||||
snapshot_sessions="$(last_snapshot_sessions)"
|
||||
if [ -n "$snapshot_sessions" ]; then
|
||||
echo "$snapshot_sessions"
|
||||
else
|
||||
echo "No resurrect snapshot found"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Saved session labels (local backups):"
|
||||
if [ -d "$SESSION_DIR" ]; then
|
||||
ls -1 "$SESSION_DIR" 2>/dev/null | sed 's/.state$//' | sort | uniq || echo "No saved sessions"
|
||||
else
|
||||
echo "No saved sessions"
|
||||
fi
|
||||
}
|
||||
|
||||
delete_session() {
|
||||
local session_name="$1"
|
||||
|
||||
if [ -z "$session_name" ]; then
|
||||
echo "Error: Session name required"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Kill the tmux session if it exists
|
||||
if tmux has-session -t "$session_name" 2>/dev/null; then
|
||||
tmux kill-session -t "=${session_name}"
|
||||
echo "Killed tmux session '$session_name'"
|
||||
fi
|
||||
|
||||
# Remove saved state files
|
||||
rm -f "$SESSION_DIR/${session_name}.state"
|
||||
echo "Deleted session configuration '$session_name'"
|
||||
}
|
||||
|
||||
restore_all_sessions() {
|
||||
local bootstrap_session="__tsm_restore_bootstrap"
|
||||
local trigger_session=""
|
||||
|
||||
echo "Restoring all sessions from latest resurrect save..."
|
||||
|
||||
if ! tmux list-sessions >/dev/null 2>&1; then
|
||||
tmux new-session -d -s "$bootstrap_session"
|
||||
trigger_session="$bootstrap_session"
|
||||
else
|
||||
while IFS= read -r session; do
|
||||
if [ -n "$session" ]; then
|
||||
trigger_session="$session"
|
||||
break
|
||||
fi
|
||||
done < <(tmux list-sessions -F "#{session_name}" 2>/dev/null)
|
||||
fi
|
||||
|
||||
if [ -z "$trigger_session" ]; then
|
||||
echo "Error: Could not find a tmux session to trigger restore"
|
||||
return 1
|
||||
fi
|
||||
|
||||
run_resurrect_restore
|
||||
sleep 1
|
||||
|
||||
if [ "$trigger_session" = "$bootstrap_session" ] && tmux has-session -t "$bootstrap_session" 2>/dev/null; then
|
||||
tmux kill-session -t "=${bootstrap_session}" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
echo "Restore triggered for all sessions"
|
||||
}
|
||||
|
||||
auto_save() {
|
||||
echo "Auto-saving all active tmux sessions..."
|
||||
while IFS= read -r session; do
|
||||
save_session "$session" || true
|
||||
done < <(tmux list-sessions -F "#{session_name}" 2>/dev/null)
|
||||
echo "All sessions auto-saved"
|
||||
}
|
||||
|
||||
# Main command dispatcher
|
||||
main() {
|
||||
local command="${1:-list}"
|
||||
local arg="${2:-}"
|
||||
|
||||
case "$command" in
|
||||
list)
|
||||
list_sessions
|
||||
;;
|
||||
create)
|
||||
create_session "$arg"
|
||||
;;
|
||||
save)
|
||||
save_session "$arg"
|
||||
;;
|
||||
restore)
|
||||
restore_session "$arg"
|
||||
;;
|
||||
delete)
|
||||
delete_session "$arg"
|
||||
;;
|
||||
restore-all)
|
||||
restore_all_sessions
|
||||
;;
|
||||
auto-save)
|
||||
auto_save
|
||||
;;
|
||||
--help|-h|help)
|
||||
show_usage
|
||||
;;
|
||||
*)
|
||||
echo "Unknown command: $command"
|
||||
show_usage
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
||||
22
scripts/togglepowermode.nix
Normal file
22
scripts/togglepowermode.nix
Normal file
@@ -0,0 +1,22 @@
|
||||
{ pkgs }:
|
||||
|
||||
pkgs.writeShellScriptBin "togglepowermode" ''
|
||||
# Toggle between performance and power saving mode
|
||||
config_dir="$HOME/.config/hypr"
|
||||
power_mode_file="$config_dir/power_mode"
|
||||
|
||||
mkdir -p "$config_dir"
|
||||
|
||||
# Read current mode or default to balanced
|
||||
current_mode=$(cat "$power_mode_file" 2>/dev/null || echo "balanced")
|
||||
|
||||
if [ "$current_mode" = "powersave" ]; then
|
||||
# Switch to performance mode
|
||||
echo "performance" > "$power_mode_file"
|
||||
echo "Performance Mode"
|
||||
else
|
||||
# Switch to powersave mode
|
||||
echo "powersave" > "$power_mode_file"
|
||||
echo "Power Saving Mode"
|
||||
fi
|
||||
''
|
||||
22
scripts/update-hyprland-colors.sh
Executable file
22
scripts/update-hyprland-colors.sh
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Update Hyprland border colors based on pywal colors
|
||||
# This script reads the pywal colors.json and applies them to Hyprland
|
||||
|
||||
COLORS_JSON="$HOME/.cache/wal/colors.json"
|
||||
|
||||
if [[ ! -f "$COLORS_JSON" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract colors from pywal (remove the # prefix)
|
||||
ACTIVE_COLOR=$(jq -r '.colors.color7' "$COLORS_JSON" | sed 's/#//')
|
||||
INACTIVE_COLOR=$(jq -r '.colors.color8' "$COLORS_JSON" | sed 's/#//')
|
||||
|
||||
# Add alpha channel (ff for fully opaque)
|
||||
ACTIVE_COLOR="0xff${ACTIVE_COLOR}"
|
||||
INACTIVE_COLOR="0xff${INACTIVE_COLOR}"
|
||||
|
||||
# Apply colors to Hyprland
|
||||
hyprctl keyword "general:col.active_border" "$ACTIVE_COLOR"
|
||||
hyprctl keyword "general:col.inactive_border" "$INACTIVE_COLOR"
|
||||
163
scripts/volumecontrol.sh
Executable file
163
scripts/volumecontrol.sh
Executable file
@@ -0,0 +1,163 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Source global control script
|
||||
scrDir=$(dirname "$(realpath "$0")")
|
||||
source "$scrDir/globalcontrol.sh"
|
||||
|
||||
# Check if SwayOSD is installed
|
||||
use_swayosd=false
|
||||
if command -v swayosd-client >/dev/null 2>&1 && pgrep -x swayosd-server >/dev/null; then
|
||||
use_swayosd=true
|
||||
fi
|
||||
|
||||
# Define functions
|
||||
|
||||
print_usage() {
|
||||
cat <<EOF
|
||||
Usage: $(basename "$0") -[device] <action> [step]
|
||||
|
||||
Devices/Actions:
|
||||
-i Input device
|
||||
-o Output device
|
||||
-p Player application
|
||||
-s Select output device
|
||||
-t Toggle to next output device
|
||||
|
||||
Actions:
|
||||
i Increase volume
|
||||
d Decrease volume
|
||||
m Toggle mute
|
||||
|
||||
Optional:
|
||||
step Volume change step (default: 5)
|
||||
|
||||
Examples:
|
||||
$(basename "$0") -o i 5 # Increase output volume by 5
|
||||
$(basename "$0") -i m # Toggle input mute
|
||||
$(basename "$0") -p spotify d 10 # Decrease Spotify volume by 10
|
||||
$(basename "$0") -p '' d 10 # Decrease volume by 10 for all players
|
||||
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
notify_vol() {
|
||||
angle=$(( (($vol + 2) / 5) * 5 ))
|
||||
ico="${icodir}/vol-${angle}.svg"
|
||||
bar=$(seq -s "." $(($vol / 15)) | sed 's/[0-9]//g')
|
||||
notify-send -a "t2" -r 91190 -t 800 -i "${ico}" "${vol}${bar}" "${nsink}"
|
||||
}
|
||||
|
||||
notify_mute() {
|
||||
mute=$(pamixer "${srce}" --get-mute | cat)
|
||||
[ "${srce}" == "--default-source" ] && dvce="mic" || dvce="speaker"
|
||||
if [ "${mute}" == "true" ]; then
|
||||
notify-send -a "t2" -r 91190 -t 800 -i "${icodir}/muted-${dvce}.svg" "muted" "${nsink}"
|
||||
else
|
||||
notify-send -a "t2" -r 91190 -t 800 -i "${icodir}/unmuted-${dvce}.svg" "unmuted" "${nsink}"
|
||||
fi
|
||||
}
|
||||
|
||||
change_volume() {
|
||||
local action=$1
|
||||
local step=$2
|
||||
local device=$3
|
||||
local delta="-"
|
||||
local mode="--output-volume"
|
||||
|
||||
[ "${action}" = "i" ] && delta="+"
|
||||
[ "${srce}" = "--default-source" ] && mode="--input-volume"
|
||||
case $device in
|
||||
"pamixer")
|
||||
$use_swayosd && swayosd-client ${mode} "${delta}${step}" && exit 0
|
||||
pamixer $srce -"$action" "$step"
|
||||
vol=$(pamixer $srce --get-volume)
|
||||
;;
|
||||
"playerctl")
|
||||
playerctl --player="$srce" volume "$(awk -v step="$step" 'BEGIN {print step/100}')${delta}"
|
||||
vol=$(playerctl --player="$srce" volume | awk '{ printf "%.0f\n", $0 * 100 }')
|
||||
;;
|
||||
esac
|
||||
|
||||
notify_vol
|
||||
}
|
||||
|
||||
toggle_mute() {
|
||||
local device=$1
|
||||
local mode="--output-volume"
|
||||
[ "${srce}" = "--default-source" ] && mode="--input-volume"
|
||||
case $device in
|
||||
"pamixer")
|
||||
$use_swayosd && swayosd-client "${mode}" mute-toggle && exit 0
|
||||
pamixer $srce -t
|
||||
notify_mute
|
||||
;;
|
||||
"playerctl")
|
||||
local volume_file="/tmp/$(basename "$0")_last_volume_${srce:-all}"
|
||||
if [ "$(playerctl --player="$srce" volume | awk '{ printf "%.2f", $0 }')" != "0.00" ]; then
|
||||
playerctl --player="$srce" volume | awk '{ printf "%.2f", $0 }' > "$volume_file"
|
||||
playerctl --player="$srce" volume 0
|
||||
else
|
||||
if [ -f "$volume_file" ]; then
|
||||
last_volume=$(cat "$volume_file")
|
||||
playerctl --player="$srce" volume "$last_volume"
|
||||
else
|
||||
playerctl --player="$srce" volume 0.5 # Default to 50% if no saved volume
|
||||
fi
|
||||
fi
|
||||
notify_mute
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
select_output() {
|
||||
local selection=$1
|
||||
if [ -n "$selection" ]; then
|
||||
device=$(pactl list sinks | grep -C2 -F "Description: $selection" | grep Name | cut -d: -f2 | xargs)
|
||||
if pactl set-default-sink "$device"; then
|
||||
notify-send -t 2000 -r 2 -u low "Activated: $selection"
|
||||
else
|
||||
notify-send -t 2000 -r 2 -u critical "Error activating $selection"
|
||||
fi
|
||||
else
|
||||
pactl list sinks | grep -ie "Description:" | awk -F ': ' '{print $2}' | sort
|
||||
fi
|
||||
}
|
||||
|
||||
toggle_output() {
|
||||
local default_sink=$(pamixer --get-default-sink | awk -F '"' 'END{print $(NF - 1)}')
|
||||
mapfile -t sink_array < <(select_output)
|
||||
local current_index=$(printf '%s\n' "${sink_array[@]}" | grep -n "$default_sink" | cut -d: -f1)
|
||||
local next_index=$(( (current_index % ${#sink_array[@]}) + 1 ))
|
||||
local next_sink="${sink_array[next_index-1]}"
|
||||
select_output "$next_sink"
|
||||
}
|
||||
|
||||
# Main script logic
|
||||
|
||||
# Set default variables
|
||||
icodir="${confDir}/dunst/icons/vol"
|
||||
step=5
|
||||
# Parse options
|
||||
while getopts "iop:st" opt; do
|
||||
case $opt in
|
||||
i) device="pamixer"; srce="--default-source"; nsink=$(pamixer --list-sources | awk -F '"' 'END {print $(NF - 1)}') ;;
|
||||
o) device="pamixer"; srce=""; nsink=$(pamixer --get-default-sink | awk -F '"' 'END{print $(NF - 1)}') ;;
|
||||
p) device="playerctl"; srce="${OPTARG}"; nsink=$(playerctl --list-all | grep -w "$srce") ;;
|
||||
s) select_output "$(select_output | rofi -dmenu -config "${confDir}/rofi/notification.rasi")"; exit ;;
|
||||
t) toggle_output; exit ;;
|
||||
*) print_usage ;;
|
||||
esac
|
||||
done
|
||||
|
||||
shift $((OPTIND-1))
|
||||
|
||||
# Check if device is set
|
||||
[ -z "$device" ] && print_usage
|
||||
|
||||
# Execute action
|
||||
case $1 in
|
||||
i|d) change_volume "$1" "${2:-$step}" "$device" ;;
|
||||
m) toggle_mute "$device" ;;
|
||||
*) print_usage ;;
|
||||
esac
|
||||
220
scripts/wallbash.sh
Executable file
220
scripts/wallbash.sh
Executable file
@@ -0,0 +1,220 @@
|
||||
#!/usr/bin/env bash
|
||||
#|---/ /+---------------------------------------------+---/ /|#
|
||||
#|--/ /-| Script to generate color palette from image |--/ /-|#
|
||||
#|-/ /--| Prasanth Rangan |-/ /--|#
|
||||
#|/ /---+---------------------------------------------+/ /---|#
|
||||
|
||||
|
||||
#// accent color profile
|
||||
|
||||
colorProfile="default"
|
||||
wallbashCurve="32 50\n42 46\n49 40\n56 39\n64 38\n76 37\n90 33\n94 29\n100 20"
|
||||
sortMode="auto"
|
||||
|
||||
while [ $# -gt 0 ] ; do
|
||||
case "$1" in
|
||||
-v|--vibrant) colorProfile="vibrant"
|
||||
wallbashCurve="18 99\n32 97\n48 95\n55 90\n70 80\n80 70\n88 60\n94 40\n99 24"
|
||||
;;
|
||||
-p|--pastel) colorProfile="pastel"
|
||||
wallbashCurve="10 99\n17 66\n24 49\n39 41\n51 37\n58 34\n72 30\n84 26\n99 22"
|
||||
;;
|
||||
-m|--mono) colorProfile="mono"
|
||||
wallbashCurve="10 0\n17 0\n24 0\n39 0\n51 0\n58 0\n72 0\n84 0\n99 0"
|
||||
;;
|
||||
-c|--custom)
|
||||
shift
|
||||
if [ -n "${1}" ] && [[ "${1}" =~ ^([0-9]+[[:space:]][0-9]+\\n){8}[0-9]+[[:space:]][0-9]+$ ]] ; then
|
||||
colorProfile="custom"
|
||||
wallbashCurve="${1}"
|
||||
else
|
||||
echo "Error: Custom color curve format is incorrect ${1}"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
-d|--dark) sortMode="dark"
|
||||
colSort=""
|
||||
;;
|
||||
-l|--light) sortMode="light"
|
||||
colSort="-r"
|
||||
;;
|
||||
*) break
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
|
||||
#// set variables
|
||||
|
||||
wallbashImg="${1}"
|
||||
wallbashColors=4
|
||||
wallbashFuzz=70
|
||||
wallbashRaw="${2:-"${wallbashImg}"}.mpc"
|
||||
wallbashOut="${2:-"${wallbashImg}"}.dcol"
|
||||
wallbashCache="${2:-"${wallbashImg}"}.cache"
|
||||
|
||||
|
||||
#// color modulations
|
||||
|
||||
pryDarkBri=116
|
||||
pryDarkSat=110
|
||||
pryDarkHue=88
|
||||
pryLightBri=100
|
||||
pryLightSat=100
|
||||
pryLightHue=114
|
||||
txtDarkBri=188
|
||||
txtLightBri=16
|
||||
|
||||
|
||||
#// input image validation
|
||||
|
||||
if [ -z "${wallbashImg}" ] || [ ! -f "${wallbashImg}" ] ; then
|
||||
echo "Error: Input file not found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
magick -ping "${wallbashImg}" -format "%t" info: &> /dev/null
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "Error: Unsuppoted image format ${wallbashImg}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "wallbash ${colorProfile} profile :: ${sortMode} :: Colors ${wallbashColors} :: Fuzzy ${wallbashFuzz} :: \"${wallbashOut}\""
|
||||
mkdir -p "${cacheDir}/${cacheThm}"
|
||||
> "${wallbashOut}"
|
||||
|
||||
|
||||
#// define functions
|
||||
|
||||
rgb_negative() {
|
||||
local inCol=$1
|
||||
local r=${inCol:0:2}
|
||||
local g=${inCol:2:2}
|
||||
local b=${inCol:4:2}
|
||||
local r16=$((16#$r))
|
||||
local g16=$((16#$g))
|
||||
local b16=$((16#$b))
|
||||
r=$(printf "%02X" $((255 - $r16)))
|
||||
g=$(printf "%02X" $((255 - $g16)))
|
||||
b=$(printf "%02X" $((255 - $b16)))
|
||||
echo "${r}${g}${b}"
|
||||
}
|
||||
|
||||
rgba_convert() {
|
||||
local inCol=$1
|
||||
local r=${inCol:0:2}
|
||||
local g=${inCol:2:2}
|
||||
local b=${inCol:4:2}
|
||||
local r16=$((16#$r))
|
||||
local g16=$((16#$g))
|
||||
local b16=$((16#$b))
|
||||
printf "rgba(%d,%d,%d,\1341)\n" "$r16" "$g16" "$b16"
|
||||
}
|
||||
|
||||
fx_brightness() {
|
||||
local inCol="${1}"
|
||||
local fxb=$(magick "${inCol}" -colorspace gray -format "%[fx:mean]" info:)
|
||||
if awk -v fxb="${fxb}" 'BEGIN {exit !(fxb < 0.5)}' ; then
|
||||
return 0 #// echo ":: ${fxb} :: dark :: ${inCol}"
|
||||
else
|
||||
return 1 #// echo ":: ${fxb} :: light :: ${inCol}"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
#// quantize raw primary colors
|
||||
|
||||
magick -quiet -regard-warnings "${wallbashImg}"[0] -alpha off +repage "${wallbashRaw}"
|
||||
readarray -t dcolRaw <<< $(magick "${wallbashRaw}" -depth 8 -fuzz ${wallbashFuzz}% +dither -kmeans ${wallbashColors} -depth 8 -format "%c" histogram:info: | sed -n 's/^[ ]*\(.*\):.*[#]\([0-9a-fA-F]*\) .*$/\1,\2/p' | sort -r -n -k 1 -t ",")
|
||||
|
||||
if [ ${#dcolRaw[*]} -lt ${wallbashColors} ] ; then
|
||||
echo -e "RETRYING :: distinct colors ${#dcolRaw[*]} is less than ${wallbashColors} palette color..."
|
||||
readarray -t dcolRaw <<< $(magick "${wallbashRaw}" -depth 8 -fuzz ${wallbashFuzz}% +dither -kmeans $((wallbashColors + 2)) -depth 8 -format "%c" histogram:info: | sed -n 's/^[ ]*\(.*\):.*[#]\([0-9a-fA-F]*\) .*$/\1,\2/p' | sort -r -n -k 1 -t ",")
|
||||
fi
|
||||
|
||||
|
||||
#// sort colors based on image brightness
|
||||
|
||||
if [ "${sortMode}" == "auto" ] ; then
|
||||
if fx_brightness "${wallbashRaw}" ; then
|
||||
sortMode="dark"
|
||||
colSort=""
|
||||
else
|
||||
sortMode="light"
|
||||
colSort="-r"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "dcol_mode=\"${sortMode}\"" >> "${wallbashOut}"
|
||||
dcolHex=($(echo -e "${dcolRaw[@]:0:$wallbashColors}" | tr ' ' '\n' | awk -F ',' '{print $2}' | sort ${colSort}))
|
||||
greyCheck=$(magick "${wallbashRaw}" -colorspace HSL -channel g -separate +channel -format "%[fx:mean]" info:)
|
||||
|
||||
if (( $(awk 'BEGIN {print ('"$greyCheck"' < 0.12)}') )); then
|
||||
wallbashCurve="10 0\n17 0\n24 0\n39 0\n51 0\n58 0\n72 0\n84 0\n99 0"
|
||||
fi
|
||||
|
||||
|
||||
#// loop for derived colors
|
||||
|
||||
for (( i=0; i<${wallbashColors}; i++ )) ; do
|
||||
|
||||
|
||||
#// generate missing primary colors
|
||||
|
||||
if [ -z "${dcolHex[i]}" ] ; then
|
||||
|
||||
if fx_brightness "xc:#${dcolHex[i - 1]}" ; then
|
||||
modBri=$pryDarkBri
|
||||
modSat=$pryDarkSat
|
||||
modHue=$pryDarkHue
|
||||
else
|
||||
modBri=$pryLightBri
|
||||
modSat=$pryLightSat
|
||||
modHue=$pryLightHue
|
||||
fi
|
||||
|
||||
echo -e "dcol_pry$((i + 1)) :: regen missing color"
|
||||
dcol[i]=$(magick xc:"#${dcolHex[i - 1]}" -depth 8 -normalize -modulate ${modBri},${modSat},${modHue} -depth 8 -format "%c" histogram:info: | sed -n 's/^[ ]*\(.*\):.*[#]\([0-9a-fA-F]*\) .*$/\2/p')
|
||||
|
||||
fi
|
||||
|
||||
echo "dcol_pry$((i + 1))=\"${dcolHex[i]}\"" >> "${wallbashOut}"
|
||||
echo "dcol_pry$((i + 1))_rgba=\"$( rgba_convert "${dcolHex[i]}" )\"" >> "${wallbashOut}"
|
||||
|
||||
|
||||
#// generate primary text colors
|
||||
|
||||
nTxt=$(rgb_negative ${dcolHex[i]})
|
||||
|
||||
if fx_brightness "xc:#${dcolHex[i]}" ; then
|
||||
modBri=$txtDarkBri
|
||||
else
|
||||
modBri=$txtLightBri
|
||||
fi
|
||||
|
||||
tcol=$(magick xc:"#${nTxt}" -depth 8 -normalize -modulate ${modBri},10,100 -depth 8 -format "%c" histogram:info: | sed -n 's/^[ ]*\(.*\):.*[#]\([0-9a-fA-F]*\) .*$/\2/p')
|
||||
echo "dcol_txt$((i + 1))=\"${tcol}\"" >> "${wallbashOut}"
|
||||
echo "dcol_txt$((i + 1))_rgba=\"$( rgba_convert "${tcol}" )\"" >> "${wallbashOut}"
|
||||
|
||||
|
||||
#// generate accent colors
|
||||
|
||||
xHue=$(magick xc:"#${dcolHex[i]}" -colorspace HSB -format "%c" histogram:info: | awk -F '[hsb(,]' '{print $2}')
|
||||
acnt=1
|
||||
|
||||
echo -e "${wallbashCurve}" | sort -n ${colSort} | while read -r xBri xSat
|
||||
do
|
||||
acol=$(magick xc:"hsb(${xHue},${xSat}%,${xBri}%)" -depth 8 -format "%c" histogram:info: | sed -n 's/^[ ]*\(.*\):.*[#]\([0-9a-fA-F]*\) .*$/\2/p')
|
||||
echo "dcol_$((i + 1))xa${acnt}=\"${acol}\"" >> "${wallbashOut}"
|
||||
echo "dcol_$((i + 1))xa${acnt}_rgba=\"$( rgba_convert "${acol}" )\"" >> "${wallbashOut}"
|
||||
((acnt++))
|
||||
done
|
||||
|
||||
done
|
||||
|
||||
|
||||
#// cleanup temp cache
|
||||
|
||||
rm -f "${wallbashRaw}" "${wallbashCache}"
|
||||
|
||||
22
scripts/wallbashcava.sh
Executable file
22
scripts/wallbashcava.sh
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
scrDir=`dirname "$(realpath "$0")"`
|
||||
source $scrDir/globalcontrol.sh
|
||||
cvaDir="${confDir}/cava"
|
||||
CAVA_CONF="${cvaDir}/config"
|
||||
WALL_DCOL="${cvaDir}/Wall-Dcol"
|
||||
KEY_LINE='### HYPRDOTS CAVA: Autogenerated line below for wallbash###'
|
||||
|
||||
if pkg_installed cava ; then
|
||||
|
||||
sed -i "/${KEY_LINE}/,\$d" "${CAVA_CONF}"
|
||||
if grep -q "${KEY_LINE}" "${CAVA_CONF}"; then
|
||||
sed -i "/${KEY_LINE}/r ${WALL_DCOL}" "${CAVA_CONF}"
|
||||
else
|
||||
echo "${KEY_LINE}" >> "${CAVA_CONF}"
|
||||
sed -i "/${KEY_LINE}/r ${WALL_DCOL}" "${CAVA_CONF}"
|
||||
fi
|
||||
|
||||
pkill -USR2 cava
|
||||
|
||||
fi
|
||||
41
scripts/wallbashcode.sh
Executable file
41
scripts/wallbashcode.sh
Executable file
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
#// set variables
|
||||
scrDir="$(dirname "$(realpath "$0")")"
|
||||
source "${scrDir}/globalcontrol.sh"
|
||||
readarray -t codeConf < <(find "${confDir}" -mindepth 1 -maxdepth 1 -type d -name "Code*" -o -name "VSCodium*" -o -name "Cursor*" | sort)
|
||||
readarray -t codeVsix < <(find "$HOME" -mindepth 1 -maxdepth 1 -type d -name ".vscode*" -o -name ".cursor" | sort)
|
||||
tmpFile="/tmp/$(id -u)$(basename ${0}).tmp"
|
||||
tgtFile="extensions/undefined_publisher.wallbash-0.0.1/themes/wallbash-color-theme.json"
|
||||
|
||||
#// install ext
|
||||
|
||||
for i in "${!codeVsix[@]}" ;do
|
||||
if [ ! -f "${codeVsix[i]}/${tgtFile}" ] ; then
|
||||
[ -f "${cacheDir}/landing/Code_Wallbash.vsix" ] || curl -L -o "${cacheDir}/landing/Code_Wallbash.vsix" https://github.com/prasanthrangan/hyprdots/raw/main/Source/arcs/Code_Wallbash.vsix
|
||||
case ${codeVsix[i]} in
|
||||
*".cursor"*)
|
||||
echo "[wallbashcode] Cursor IDE: Manual intervention required for extension installation."
|
||||
echo "[wallbashcode] Read the instructions here: https://www.cursor.com/how-to-install-extension "
|
||||
;;
|
||||
*)
|
||||
pkg_installed code-insiders && code-insiders --install-extension "${cacheDir}/landing/Code_Wallbash.vsix"
|
||||
pkg_installed code && code --install-extension "${cacheDir}/landing/Code_Wallbash.vsix"
|
||||
pkg_installed vscodium && vscodium --install-extension "${cacheDir}/landing/Code_Wallbash.vsix"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
[ -d "$(dirname "${codeVsix[i]}/${tgtFile}")" ] && cp "${cacheDir}/landing/wallbashcode.json" "${codeVsix[i]}/${tgtFile}"
|
||||
done
|
||||
|
||||
#// apply theme
|
||||
|
||||
for i in "${!codeConf[@]}" ; do
|
||||
[ -d "${codeConf[i]}/User" ] || continue
|
||||
[ -f "${codeConf[i]}/User/settings.json" ] || echo -e "{\n \"workbench.colorTheme\":\"wallbash\" \n}" > "${codeConf[i]}/User/settings.json"
|
||||
extTheme="$(jq -r '.["workbench.colorTheme"]' "${codeConf[i]}/User/settings.json")"
|
||||
|
||||
if [ "${extTheme}" != "wallbash" ] ; then
|
||||
jq '.["workbench.colorTheme"] = "wallbash"' "${codeConf[i]}/User/settings.json" > "${tmpFile}" && mv "${tmpFile}" "${codeConf[i]}/User/settings.json"
|
||||
fi
|
||||
done
|
||||
30
scripts/wallbashdiscord.sh
Executable file
30
scripts/wallbashdiscord.sh
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
|
||||
#// source variables
|
||||
|
||||
scrDir="$(dirname "$(realpath "$0")")"
|
||||
source "${scrDir}/globalcontrol.sh"
|
||||
discord_col="${cacheDir}/landing/discord.css"
|
||||
declare -a client_list=()
|
||||
|
||||
|
||||
#// List more clients
|
||||
|
||||
client_list+=("$HOME/.config/Vencord/settings/quickCss.css")
|
||||
client_list+=("$HOME/.config/vesktop/settings/quickCss.css")
|
||||
client_list+=("$HOME/.var/app/dev.vencord.Vesktop/config/vesktop/settings/quickCss.css")
|
||||
client_list+=("$HOME/.config/WebCord/Themes/theme.css")
|
||||
client_list+=("$HOME/.var/app/io.github.spacingbat3.webcord/config/WebCord/Themes/theme.css")
|
||||
client_list+=("$HOME/.var/app/xyz.armcord.ArmCord/config/ArmCord/themes/theme.css")
|
||||
|
||||
|
||||
#// main loop
|
||||
|
||||
for client_css in "${client_list[@]}" ; do
|
||||
eval client_css="${client_css}"
|
||||
if [[ -d $(dirname "${client_css}") ]] ; then
|
||||
cp "${discord_col}" "${client_css}"
|
||||
fi
|
||||
done
|
||||
|
||||
16
scripts/wallbashdunst.sh
Executable file
16
scripts/wallbashdunst.sh
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# set variables
|
||||
|
||||
scrDir=`dirname "$(realpath "$0")"`
|
||||
source $scrDir/globalcontrol.sh
|
||||
dstDir="${confDir}/dunst"
|
||||
|
||||
# regen conf
|
||||
|
||||
export hypr_border
|
||||
envsubst < "${dstDir}/dunst.conf" > "${dstDir}/dunstrc"
|
||||
envsubst < "${dstDir}/wallbash.conf" >> "${dstDir}/dunstrc"
|
||||
killall dunst
|
||||
dunst &
|
||||
|
||||
23
scripts/wallbashqt.sh
Executable file
23
scripts/wallbashqt.sh
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
|
||||
# set variables
|
||||
|
||||
scrDir=`dirname "$(realpath "$0")"`
|
||||
source $scrDir/globalcontrol.sh
|
||||
|
||||
|
||||
# sync qt5 and qt6 colors
|
||||
|
||||
cp "${confDir}/qt5ct/colors.conf" "${confDir}/qt6ct/colors.conf"
|
||||
|
||||
|
||||
# restart dolphin
|
||||
|
||||
a_ws=$(hyprctl -j activeworkspace | jq '.id')
|
||||
dpid=$(hyprctl -j clients | jq --arg wid "$a_ws" '.[] | select(.workspace.id == ($wid | tonumber)) | select(.class == "org.kde.dolphin") | .pid')
|
||||
if [ ! -z ${dpid} ] ; then
|
||||
hyprctl dispatch closewindow pid:${dpid}
|
||||
hyprctl dispatch exec dolphin &
|
||||
fi
|
||||
|
||||
42
scripts/wallbashspotify.sh
Executable file
42
scripts/wallbashspotify.sh
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
|
||||
# set variables
|
||||
|
||||
scrDir="$(dirname "$(realpath "$0")")"
|
||||
source "${scrDir}/globalcontrol.sh"
|
||||
|
||||
|
||||
# regen conf
|
||||
|
||||
if pkg_installed spotify && pkg_installed spicetify-cli ; then
|
||||
|
||||
if [ ! -w /opt/spotify ] || [ ! -w /opt/spotify/Apps ]; then
|
||||
notify-send -a "Hyprdots" "Permission needed for Wallbash Spotify theme"
|
||||
pkexec chmod a+wr /opt/spotify
|
||||
pkexec chmod a+wr /opt/spotify/Apps -R
|
||||
fi
|
||||
|
||||
if [ "$(spicetify config | awk '{if ($1=="color_scheme") print $2}')" != "Wallbash" ] || [[ "${*}" == *"--reset"* ]] ; then
|
||||
spicetify &> /dev/null
|
||||
mkdir -p ~/.config/spotify
|
||||
touch ~/.config/spotify/prefs
|
||||
sptfyConf=$(spicetify -c)
|
||||
spotfy_flags='--ozone-platform=wayland'
|
||||
sed -i -e "/^prefs_path/ s+=.*$+= $HOME/.config/spotify/prefs+g" \
|
||||
-e "/^spotify_launch_flags/ s+=.*$+= $spotfy_flags+g" "$sptfyConf"
|
||||
curl -L -o ${cacheDir}/landing/Spotify_Sleek.tar.gz https://github.com/prasanthrangan/hyprdots/raw/main/Source/arcs/Spotify_Sleek.tar.gz
|
||||
tar -xzf ${cacheDir}/landing/Spotify_Sleek.tar.gz -C ~/.config/spicetify/Themes/
|
||||
spicetify backup apply
|
||||
spicetify config current_theme Sleek
|
||||
spicetify config color_scheme Wallbash
|
||||
spicetify apply
|
||||
fi
|
||||
|
||||
if pgrep -x spotify > /dev/null ; then
|
||||
pkill -x spicetify
|
||||
spicetify -q watch -s &
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
61
scripts/wallbashtoggle.sh
Executable file
61
scripts/wallbashtoggle.sh
Executable file
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
|
||||
#// set variables
|
||||
|
||||
scrDir="$(dirname "$(realpath "$0")")"
|
||||
source "${scrDir}/globalcontrol.sh"
|
||||
TgtScr="$scrDir/globalcontrol.sh"
|
||||
rofiConf="${confDir}/rofi/wallbash.rasi"
|
||||
wallbashModes=("theme" "auto" "dark" "light")
|
||||
|
||||
|
||||
#// rofi select mode
|
||||
|
||||
rofi_wallbash()
|
||||
{
|
||||
[[ "${rofiScale}" =~ ^[0-9]+$ ]] || rofiScale=10
|
||||
r_scale="configuration {font: \"JetBrainsMono Nerd Font ${rofiScale}\";}"
|
||||
elem_border=$(( hypr_border * 4 ))
|
||||
r_override="window{border-radius:${elem_border}px;} element{border-radius:${elem_border}px;}"
|
||||
rofiSel=$(parallel echo {} ::: "${wallbashModes[@]}" | rofi -dmenu -theme-str "${r_scale}" -theme-str "${r_override}" -config "${rofiConf}" -select "${wallbashModes[${enableWallDcol}]}")
|
||||
if [ ! -z "${rofiSel}" ] ; then
|
||||
setMode="$(parallel --link echo {} ::: "${!wallbashModes[@]}" ::: "${wallbashModes[@]}" ::: "${rofiSel}" | awk '{if ($2 == $3) print $1}')"
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
#// switch mode
|
||||
|
||||
step_wallbash()
|
||||
{
|
||||
for i in "${!wallbashModes[@]}" ; do
|
||||
if [ "${enableWallDcol}" == "${i}" ] ; then
|
||||
if [ "${1}" == "n" ] ; then
|
||||
setMode=$(( (i + 1) % ${#wallbashModes[@]} ))
|
||||
elif [ "${1}" == "p" ] ; then
|
||||
setMode=$(( i - 1 ))
|
||||
fi
|
||||
break
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
#// apply wallbash mode
|
||||
|
||||
case "${1}" in
|
||||
m|-m|--menu) rofi_wallbash ;;
|
||||
n|-n|--next) step_wallbash n ;;
|
||||
p|-p|--prev) step_wallbash p ;;
|
||||
*) step_wallbash n ;;
|
||||
esac
|
||||
|
||||
export reload_flag=1
|
||||
[[ "${setMode}" -lt 0 ]] && setMode=$((${#wallbashModes[@]} - 1))
|
||||
set_conf "enableWallDcol" "${setMode}"
|
||||
"${scrDir}/themeswitch.sh"
|
||||
notify-send -a "t1" -i "$HOME/.config/dunst/icons/hyprdots.png" " ${wallbashModes[setMode]} mode"
|
||||
|
||||
41
scripts/waybar-cava.sh
Normal file
41
scripts/waybar-cava.sh
Normal file
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
bar="▁ ▂ ▃ ▄ ▅ ▆ ▇ █"
|
||||
dict="s/;//g"
|
||||
for ((i=0; i<${#bar}; i++)); do
|
||||
dict+=";s/$i/${bar:$i:1}/g"
|
||||
done
|
||||
|
||||
RUNTIME_DIR="${XDG_RUNTIME_DIR:-/tmp}"
|
||||
pidfile="$RUNTIME_DIR/waybar-cava.pid"
|
||||
if [ -f "$pidfile" ]; then
|
||||
oldpid=$(cat "$pidfile" || true)
|
||||
if [ -n "$oldpid" ] && kill -0 "$oldpid" 2>/dev/null; then
|
||||
kill "$oldpid" 2>/dev/null || true
|
||||
sleep 0.1
|
||||
fi
|
||||
fi
|
||||
echo $$ > "$pidfile"
|
||||
|
||||
config_file=$(mktemp "$RUNTIME_DIR/waybar-cava.XXXXXX.conf")
|
||||
cleanup() { rm -f "$config_file" "$pidfile"; }
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
cat >"$config_file" <<EOF
|
||||
[general]
|
||||
framerate = 30
|
||||
bars = 10
|
||||
|
||||
[input]
|
||||
method = pulse
|
||||
source = auto
|
||||
|
||||
[output]
|
||||
method = raw
|
||||
raw_target = /dev/stdout
|
||||
data_format = ascii
|
||||
ascii_max_range = 7
|
||||
EOF
|
||||
|
||||
exec cava -p "$config_file" | sed -u "$dict"
|
||||
8
scripts/waybar-toggle.sh
Normal file
8
scripts/waybar-toggle.sh
Normal file
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
if pgrep -f waybar >/dev/null; then
|
||||
pkill -f waybar
|
||||
else
|
||||
waybar &
|
||||
fi
|
||||
|
||||
130
scripts/waybar_cava.sh
Executable file
130
scripts/waybar_cava.sh
Executable file
@@ -0,0 +1,130 @@
|
||||
#!/usr/bin/env bash
|
||||
#----- Optimized bars animation without much CPU usage increase --------
|
||||
#----- Optimized bars animation without much CPU usage increase pt2 --------
|
||||
|
||||
# Default values
|
||||
scrDir="$(dirname "$(realpath "$0")")"
|
||||
# shellcheck disable=SC1091
|
||||
source "${scrDir}/globalcontrol.sh"
|
||||
|
||||
usage() {
|
||||
cat <<HELP
|
||||
Usage: $(basename "$0") [OPTIONS]
|
||||
Options:
|
||||
--bar <waybar_cava_bar> Specify the characters to use for the bar animation (default: ▁▂▃▄▅▆▇█).
|
||||
--width <waybar_cava_width> Specify the width of the bar.
|
||||
--range <waybar_cava_range> Specify the range of the bar.
|
||||
--help Display this help message and exit.
|
||||
--restart Restart the waybar_cava.
|
||||
--stb <waybar_cava_stbmode> Specify the standby mode for waybar cava (default: 0).
|
||||
0: clean - totally hides the module
|
||||
1: blank - makes module expand as spaces
|
||||
2: full - occupies the module with full bar
|
||||
3: low - makes the module display the lowest set bar
|
||||
*: string - displays a string
|
||||
HELP
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Parse command line arguments using getopt
|
||||
if ! ARGS=$(getopt -o "hr" -l "help,bar:,width:,range:,restart,stb:" -n "$0" -- "$@"); then
|
||||
usage
|
||||
fi
|
||||
|
||||
eval set -- "$ARGS"
|
||||
while true; do
|
||||
case "$1" in
|
||||
--help | -h)
|
||||
usage
|
||||
;;
|
||||
--bar)
|
||||
waybar_cava_bar="$2"
|
||||
shift 2
|
||||
;;
|
||||
--width)
|
||||
waybar_cava_width="$2"
|
||||
shift 2
|
||||
;;
|
||||
--range)
|
||||
waybar_cava_range="$2"
|
||||
shift 2
|
||||
;;
|
||||
--restart) # restart by killing all waybar_cava
|
||||
pkill -f "cava -p /tmp/bar_cava_config"
|
||||
exit 0
|
||||
;;
|
||||
--stb)
|
||||
waybar_cava_stbmode="$2"
|
||||
shift 2
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
bar="${waybar_cava_bar:-▁▂▃▄▅▆▇█}"
|
||||
|
||||
# // waybar_cava_stbmode - standby mode for waybar cava - default 0
|
||||
# 0: clean - totally hides the module
|
||||
# 1: blank - makes module expand as spaces
|
||||
# 2: full - occupies the module with full bar
|
||||
# 3: low - makes the module display the lowest set bar
|
||||
# <string>: - displays a string
|
||||
case ${waybar_cava_stbmode:-} in
|
||||
0)
|
||||
stbBar=''
|
||||
;; # Clean
|
||||
1)
|
||||
stbBar=" "
|
||||
;; # Invisible char
|
||||
2)
|
||||
stbBar="${bar: -1}"
|
||||
;; # Full bar
|
||||
3)
|
||||
stbBar="${bar:0:1}"
|
||||
;; # Lowest bar
|
||||
*)
|
||||
asciiBar="${waybar_cava_stbmode:-${bar}}"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Calculate the length of the bar outside the loop
|
||||
bar_length=${#bar}
|
||||
bar_width=${waybar_cava_width:-${bar_length}}
|
||||
bar_range=${waybar_cava_range:-$((bar_length - 1))}
|
||||
# Create dictionary to replace char with bar
|
||||
dict="s/;//g"
|
||||
stbAscii=$(printf '0%.0s' $(seq 1 "${bar_width}")) # predicts the amount of ancii characters to be used
|
||||
[ -n "${asciiBar}" ] || asciiBar="${stbAscii//0/${stbBar}}"
|
||||
|
||||
dict="$dict;s/${stbAscii}/${asciiBar}/g"
|
||||
i=0
|
||||
while [ $i -lt "${bar_length}" ] || [ $i -lt "${bar_width}" ]; do
|
||||
if [ $i -lt "${bar_length}" ]; then
|
||||
dict="$dict;s/$i/${bar:$i:1}/g"
|
||||
fi
|
||||
((i++))
|
||||
done
|
||||
|
||||
# Create cava config
|
||||
config_file="/tmp/bar_cava_config"
|
||||
cat >"$config_file" <<EOF
|
||||
[general]
|
||||
bars = ${bar_width}
|
||||
sleep_timer = 1
|
||||
[input]
|
||||
method = pulse
|
||||
source = auto
|
||||
[output]
|
||||
method = raw
|
||||
raw_target = /dev/stdout
|
||||
data_format = ascii
|
||||
ascii_max_range = ${bar_range}
|
||||
EOF
|
||||
|
||||
cava -p "$config_file" | sed -u "${dict}"
|
||||
148
scripts/wbarconfgen.sh
Executable file
148
scripts/wbarconfgen.sh
Executable file
@@ -0,0 +1,148 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
|
||||
# read control file and initialize variables
|
||||
|
||||
export scrDir="$(dirname "$(realpath "$0")")"
|
||||
source "${scrDir}/globalcontrol.sh"
|
||||
waybar_dir="${confDir}/waybar"
|
||||
modules_dir="$waybar_dir/modules"
|
||||
conf_file="$waybar_dir/config.jsonc"
|
||||
conf_ctl="$waybar_dir/config.ctl"
|
||||
|
||||
readarray -t read_ctl < $conf_ctl
|
||||
num_files="${#read_ctl[@]}"
|
||||
switch=0
|
||||
|
||||
|
||||
# update control file to set next/prev mode
|
||||
|
||||
if [ $num_files -gt 1 ]
|
||||
then
|
||||
for (( i=0 ; i<$num_files ; i++ ))
|
||||
do
|
||||
flag=`echo "${read_ctl[i]}" | cut -d '|' -f 1`
|
||||
if [ $flag -eq 1 ] && [ "$1" == "n" ] ; then
|
||||
nextIndex=$(( (i + 1) % $num_files ))
|
||||
switch=1
|
||||
break;
|
||||
|
||||
elif [ $flag -eq 1 ] && [ "$1" == "p" ] ; then
|
||||
nextIndex=$(( i - 1 ))
|
||||
switch=1
|
||||
break;
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ $switch -eq 1 ] ; then
|
||||
update_ctl="${read_ctl[nextIndex]}"
|
||||
reload_flag=1
|
||||
sed -i "s/^1/0/g" $conf_ctl
|
||||
awk -F '|' -v cmp="$update_ctl" '{OFS=FS} {if($0==cmp) $1=1; print$0}' $conf_ctl > $waybar_dir/tmp && mv $waybar_dir/tmp $conf_ctl
|
||||
fi
|
||||
|
||||
|
||||
# overwrite config from header module
|
||||
|
||||
export set_sysname=`hostnamectl hostname`
|
||||
export w_position=`grep '^1|' $conf_ctl | cut -d '|' -f 3`
|
||||
|
||||
# setting explicit waybar output
|
||||
|
||||
if [ ${#waybar_output[@]} -gt 0 ]; then
|
||||
w_output=$(printf '"%s", ' "${waybar_output[@]}")
|
||||
w_output=${w_output%, } # Remove the trailing comma and space
|
||||
echo "[outputs] $w_output"
|
||||
fi
|
||||
export w_output="${w_output:-\"*\"}"
|
||||
|
||||
# setting waybar position
|
||||
|
||||
case ${w_position} in
|
||||
left) export hv_pos="width" ; export r_deg=90 ;;
|
||||
right) export hv_pos="width" ; export r_deg=270 ;;
|
||||
*) export hv_pos="height" ; export r_deg=0 ;;
|
||||
esac
|
||||
|
||||
export w_height=`grep '^1|' $conf_ctl | cut -d '|' -f 2`
|
||||
if [ -z $w_height ] ; then
|
||||
y_monres=`cat /sys/class/drm/*/modes | head -1 | cut -d 'x' -f 2`
|
||||
export w_height=$(( y_monres*2/100 ))
|
||||
fi
|
||||
|
||||
export i_size=$(( w_height*6/10 ))
|
||||
if [ $i_size -lt 12 ] ; then
|
||||
export i_size="12"
|
||||
fi
|
||||
|
||||
export i_theme="$(
|
||||
{ grep -q "^[[:space:]]*\$ICON[-_]THEME\s*=" "${hydeThemeDir}/hypr.theme" && grep "^[[:space:]]*\$ICON[-_]THEME\s*=" "${hydeThemeDir}/hypr.theme" | cut -d '=' -f2 | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' ;} ||
|
||||
grep 'gsettings set org.gnome.desktop.interface icon-theme' "${hydeThemeDir}/hypr.theme" | awk -F "'" '{print $((NF - 1))}'
|
||||
)"
|
||||
export i_task=$(( w_height*6/10 ))
|
||||
if [ $i_task -lt 16 ] ; then
|
||||
export i_task="16"
|
||||
fi
|
||||
export i_priv=$(( w_height*6/13 ))
|
||||
if [ $i_priv -lt 12 ] ; then
|
||||
export i_priv="12"
|
||||
fi
|
||||
|
||||
envsubst < $modules_dir/header.jsonc > $conf_file
|
||||
|
||||
|
||||
# module generator function
|
||||
|
||||
gen_mod()
|
||||
{
|
||||
local pos=$1
|
||||
local col=$2
|
||||
local mod=""
|
||||
|
||||
mod=`grep '^1|' $conf_ctl | cut -d '|' -f ${col}`
|
||||
mod="${mod//(/"custom/l_end"}"
|
||||
mod="${mod//)/"custom/r_end"}"
|
||||
mod="${mod//[/"custom/sl_end"}"
|
||||
mod="${mod//]/"custom/sr_end"}"
|
||||
mod="${mod//\{/"custom/rl_end"}"
|
||||
mod="${mod//\}/"custom/rr_end"}"
|
||||
mod="${mod// /"\",\""}"
|
||||
|
||||
echo -e "\t\"modules-${pos}\": [\"custom/padd\",\"${mod}\",\"custom/padd\"]," >> $conf_file
|
||||
write_mod=`echo $write_mod $mod`
|
||||
}
|
||||
|
||||
|
||||
# write positions for modules
|
||||
|
||||
echo -e "\n\n// positions generated based on config.ctl //\n" >> $conf_file
|
||||
gen_mod left 4
|
||||
gen_mod center 5
|
||||
gen_mod right 6
|
||||
|
||||
|
||||
# copy modules/*.jsonc to the config
|
||||
|
||||
echo -e "\n\n// sourced from modules based on config.ctl //\n" >> $conf_file
|
||||
echo "$write_mod" | sed 's/","/\n/g ; s/ /\n/g' | awk -F '/' '{print $NF}' | awk -F '#' '{print}' | awk '!x[$0]++' | while read mod_cpy
|
||||
do
|
||||
if [ -f $modules_dir/$mod_cpy.jsonc ] ; then
|
||||
envsubst < $modules_dir/$mod_cpy.jsonc >> $conf_file
|
||||
fi
|
||||
done
|
||||
|
||||
cat $modules_dir/footer.jsonc >> $conf_file
|
||||
|
||||
|
||||
# generate style
|
||||
|
||||
$scrDir/wbarstylegen.sh
|
||||
|
||||
|
||||
# restart waybar
|
||||
|
||||
if [ "$reload_flag" == "1" ] ; then
|
||||
killall waybar
|
||||
waybar --config ${waybar_dir}/config.jsonc --style ${waybar_dir}/style.css > /dev/null 2>&1 &
|
||||
fi
|
||||
118
scripts/wbarstylegen.sh
Executable file
118
scripts/wbarstylegen.sh
Executable file
@@ -0,0 +1,118 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
|
||||
# detect hypr theme and initialize variables
|
||||
|
||||
scrDir=`dirname "$(realpath "$0")"`
|
||||
source $scrDir/globalcontrol.sh
|
||||
waybar_dir="${confDir}/waybar"
|
||||
modules_dir="$waybar_dir/modules"
|
||||
conf_ctl="$waybar_dir/config.ctl"
|
||||
in_file="$waybar_dir/modules/style.css"
|
||||
out_file="$waybar_dir/style.css"
|
||||
src_file="${confDir}/hypr/themes/theme.conf"
|
||||
|
||||
|
||||
# calculate height from control file or monitor res
|
||||
|
||||
b_height=`grep '^1|' $conf_ctl | cut -d '|' -f 2`
|
||||
|
||||
if [ -z $b_height ] || [ "$b_height" == "0" ]; then
|
||||
y_monres=`cat /sys/class/drm/*/modes | head -1 | cut -d 'x' -f 2`
|
||||
b_height=$(( y_monres*3/100 ))
|
||||
fi
|
||||
|
||||
|
||||
# calculate values based on height
|
||||
|
||||
export b_radius=$(( b_height*70/100 )) # block rad 70% of height (type1)
|
||||
export c_radius=$(( b_height*25/100 )) # block rad 25% of height {type2}
|
||||
export t_radius=$(( b_height*25/100 )) # tooltip rad 25% of height
|
||||
export e_margin=$(( b_height*30/100 )) # block margin 30% of height
|
||||
export e_paddin=$(( b_height*10/100 )) # block padding 10% of height
|
||||
export g_margin=$(( b_height*14/100 )) # module margin 14% of height
|
||||
export g_paddin=$(( b_height*15/100 )) # module padding 15% of height
|
||||
export w_radius=$(( b_height*30/100 )) # workspace rad 30% of height
|
||||
export w_margin=$(( b_height*10/100 )) # workspace margin 10% of height
|
||||
export w_paddin=$(( b_height*10/100 )) # workspace padding 10% of height
|
||||
export w_padact=$(( b_height*40/100 )) # workspace active padding 40% of height
|
||||
export s_fontpx=$(( b_height*34/100 )) # font size 34% of height
|
||||
|
||||
if [ $b_height -lt 30 ] ; then
|
||||
export e_paddin=0
|
||||
fi
|
||||
if [ $s_fontpx -lt 10 ] ; then
|
||||
export s_fontpx=10
|
||||
fi
|
||||
|
||||
|
||||
# adjust values for vert/horz
|
||||
|
||||
export w_position=`grep '^1|' $conf_ctl | cut -d '|' -f 3`
|
||||
case ${w_position} in
|
||||
top|bottom)
|
||||
export x1g_margin=${g_margin}
|
||||
export x2g_margin=0
|
||||
export x3g_margin=${g_margin}
|
||||
export x4g_margin=0
|
||||
export x1rb_radius=0
|
||||
export x2rb_radius=${b_radius}
|
||||
export x3rb_radius=${b_radius}
|
||||
export x4rb_radius=0
|
||||
export x1lb_radius=${b_radius}
|
||||
export x2lb_radius=0
|
||||
export x3lb_radius=0
|
||||
export x4lb_radius=${b_radius}
|
||||
export x1rc_radius=0
|
||||
export x2rc_radius=${c_radius}
|
||||
export x3rc_radius=${c_radius}
|
||||
export x4rc_radius=0
|
||||
export x1lc_radius=${c_radius}
|
||||
export x2lc_radius=0
|
||||
export x3lc_radius=0
|
||||
export x4lc_radius=${c_radius}
|
||||
export x1="top"
|
||||
export x2="bottom"
|
||||
export x3="left"
|
||||
export x4="right" ;;
|
||||
left|right)
|
||||
export x1g_margin=0
|
||||
export x2g_margin=${g_margin}
|
||||
export x3g_margin=0
|
||||
export x4g_margin=${g_margin}
|
||||
export x1rb_radius=0
|
||||
export x2rb_radius=0
|
||||
export x3rb_radius=${b_radius}
|
||||
export x4rb_radius=${b_radius}
|
||||
export x1lb_radius=${b_radius}
|
||||
export x2lb_radius=${b_radius}
|
||||
export x3lb_radius=0
|
||||
export x4lb_radius=0
|
||||
export x1rc_radius=0
|
||||
export x2rc_radius=${c_radius}
|
||||
export x3rc_radius=${c_radius}
|
||||
export x4rc_radius=0
|
||||
export x1lc_radius=${c_radius}
|
||||
export x2lc_radius=0
|
||||
export x3lc_radius=0
|
||||
export x4lc_radius=${c_radius}
|
||||
export x1="left"
|
||||
export x2="right"
|
||||
export x3="top"
|
||||
export x4="bottom" ;;
|
||||
esac
|
||||
|
||||
|
||||
# list modules and generate theme style
|
||||
|
||||
export modules_ls=$(grep -m 1 '".*.": {' --exclude="$modules_dir/footer.jsonc" $modules_dir/*.jsonc | cut -d '"' -f 2 | awk -F '/' '{ if($1=="custom") print "#custom-"$NF"," ; else print "#"$NF","}')
|
||||
envsubst < $in_file > $out_file
|
||||
|
||||
|
||||
# override rounded couners
|
||||
|
||||
hypr_border=`awk -F '=' '{if($1~" rounding ") print $2}' $src_file | sed 's/ //g'`
|
||||
if [ "$hypr_border" == "0" ] ; then
|
||||
sed -i "/border-radius: /c\ border-radius: 0px;" $out_file
|
||||
fi
|
||||
|
||||
21
scripts/windowpin.sh
Executable file
21
scripts/windowpin.sh
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# enable float
|
||||
WinFloat=$(hyprctl -j clients | jq '.[] | select(.focusHistoryID == 0) | .floating')
|
||||
WinPinned=$(hyprctl -j clients | jq '.[] | select(.focusHistoryID == 0) | .pinned')
|
||||
|
||||
if [ "${WinFloat}" == "false" ] && [ "${WinPinned}" == "false" ] ; then
|
||||
hyprctl dispatch togglefloating active
|
||||
fi
|
||||
|
||||
# toggle pin
|
||||
hyprctl dispatch pin active
|
||||
|
||||
# disable float
|
||||
WinFloat=$(hyprctl -j clients | jq '.[] | select(.focusHistoryID == 0) | .floating')
|
||||
WinPinned=$(hyprctl -j clients | jq '.[] | select(.focusHistoryID == 0) | .pinned')
|
||||
|
||||
if [ "${WinFloat}" == "true" ] && [ "${WinPinned}" == "false" ] ; then
|
||||
hyprctl dispatch togglefloating active
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user