diff --git a/.zshrc b/.zshrc
index 4ea8e93..727bb9e 100644
--- a/.zshrc
+++ b/.zshrc
@@ -19,7 +19,7 @@ zstyle ':completion:*' menu select
source /home/nnduc/git/powerlevel10k/powerlevel10k.zsh-theme
-
+source /home/nnduc/git/zsh-autosuggestions/zsh-autosuggestions.zsh
zshaddhistory() {
whence ${${(z)1}[1]} >/dev/null || return 2
@@ -34,4 +34,4 @@ export PATH="$HOME/.local/bin:$PATH"
alias ls='ls --color=auto'
alias doc='docker-compose'
-source ~/git/zsh-autosuggestions/zsh-autosuggestions.zsh
+
diff --git a/i3/config b/i3/config
old mode 100644
new mode 100755
index 26d66ed..9886845
--- a/i3/config
+++ b/i3/config
@@ -10,7 +10,7 @@
# Please see https://i3wm.org/docs/userguide.html for a complete reference!
set $mod Mod1
-set $wallpaper '/home/nnduc/sync/images/wallpapers/suse.png'
+set $wallpaper '/sync/images/wallpapers/pexels-lumn.jpg'
set $terminal 'wezterm'
# Font for window titles. Will also be used by the bar unless a different font
# is used in the bar {} block below.
@@ -45,7 +45,7 @@ exec --no-startup-id nm-applet
exec --no-startup-id blueman-applet
exec --no-startup-id /usr/bin/gnome-keyring-daemon --start --components=ssh,pkcs11
exec --no-startup-id feh --bg-fill $wallpaper
-exec --no-startup-id pasystray
+#exec --no-startup-id pasystray
exec --no-startup-id polybar
set $refresh_i3status killall -SIGUSR1 i3status
@@ -237,10 +237,10 @@ bindsym $mod+r mode "resize"
bindsym $mod+Tab workspace back_and_forth
# class border bground text indicator child_border
- client.focused #05707E #05707E #FFFFFF #000000 #05707E
- client.placeholder #000000 #F1E3D3 #FFFFFF #000000 #0d100f
- client.unfocused #000000 #1B4D3E #FFFFFF #000000 #0d100f
- client.focused_inactive #333333 #C8C9C9 #7A858D #484E50 #5F676A
+ client.focused #3A7CA5 #3A7CA5 #E2EBF0 #0D1B27 #3A7CA5
+ client.placeholder #0D1B27 #0D1B27 #BDD5E4 #0D1B27 #0D1B27
+ client.unfocused #0D1B27 #152535 #6A8DA0 #0D1B27 #152535
+ client.focused_inactive #1A3347 #1A3347 #6A8DA0 #1A3347 #1A3347
#focused_workspace #4c7899 #285577 #ffff
# (No) Title Bars
diff --git a/i3/i3blocks.conf b/i3/i3blocks.conf
new file mode 100644
index 0000000..c9d1d3c
--- /dev/null
+++ b/i3/i3blocks.conf
@@ -0,0 +1,182 @@
+# i3blocks config file changed for EndeavourOS-i3 setup
+
+# source is available here:
+# https://raw.githubusercontent.com/endeavouros-team/endeavouros-i3wm-setup/main/etc/skel/.config/i3/i3blocks.conf
+# Maintainer: joekamprad [joekamprad //a_t// endeavouros.com]
+# Former Visual Designer: Florent Valetti [@FLVAL EndeavourOS]
+# created for i3wm setup on EndeavourOS
+# https://endeavouros.com
+
+# cheatsheet for icon fonts used on the block-bar:
+# https://fontawesome.com/v4.7/cheatsheet/
+
+# --> to update this run the following command:
+# wget --backups=1 https://raw.githubusercontent.com/endeavouros-team/endeavouros-i3wm-setup/main/etc/skel/.config/i3/i3blocks.conf -P ~/.config/i3/
+
+# Please see man i3blocks for a complete reference!
+# The man page is also hosted at http://vivien.github.io/i3blocks
+
+
+# List of valid properties:
+#
+# align
+# color
+# command
+# full_text
+# instance
+# interval
+# label
+# min_width
+# name
+# separator
+# separator_block_width
+# short_text
+# signal
+# urgent
+
+# Global properties
+#
+# The top properties below are applied to every block, but can be overridden.
+separator=false
+markup=pango
+
+#[Weather]
+#command=~/.config/i3/scripts/openweather
+#interval=1800
+#color=#7275b3
+
+[terminal]
+full_text=
+color=#807dfe
+command=i3-msg -q exec xfce4-terminal
+
+[browser]
+full_text=
+color=#ff7f81
+command=i3-msg -q exec firefox
+
+[files]
+full_text=
+color=#7f3fbf
+command=i3-msg -q exec thunar ~/
+
+#[mail]
+#full_text=
+#color=#dbcb75
+#command=i3-msg -q exec thunderbird
+
+[simple-2]
+full_text=: :
+color=#717171
+
+# Disk usage
+#
+# The directory defaults to $HOME if the instance is not specified.
+# The script may be called with a optional argument to set the alert
+# (defaults to 10 for 10%).
+[disk]
+label=
+instance=/
+command=~/.config/i3/scripts/disk
+interval=30
+
+# Memory usage
+#
+# The type defaults to "mem" if the instance is not specified.
+[memory]
+label=
+command=~/.config/i3/scripts/memory
+interval=2
+
+[cpu_usage]
+label=
+command=~/.config/i3/scripts/cpu_usage
+#min_width=CPU: 100.00%
+interval=2
+
+[CPU-temperature]
+label=
+command=~/.config/i3/scripts/temperature
+interval=30
+#T_WARN=70
+#T_CRIT=90
+#SENSOR_CHIP=""
+# where SENSOR_CHIP can be find with sensors output
+# can be used also for GPU temperature or other temperature sensors lm-sensors detects.
+
+# showing name of connected network (enable for wifi use)
+#[net]
+#label=
+#command=echo "$(LANG=C nmcli d | grep connected | awk '{print $4}')"
+#interval=30
+
+[bandwidth]
+command=~/.config/i3/scripts/bandwidth2
+interval=persist
+
+#[vpn]
+#command=~/.config/i3/scripts/vpn
+#init_color=#FFFF00
+#on_color=#00FF00
+#label=VPN:
+#interval=5
+
+# Battery indicator
+[battery]
+command=~/.config/i3/scripts/battery
+# change this to battery-pinebook-pro if you are running on pinebook-pro
+label=
+interval=30
+
+[simple-2]
+full_text=: :
+color=#717171
+
+[pavucontrol]
+full_text=♪
+command=pavucontrol
+
+[volume]
+command=~/.config/i3/scripts/volume
+interval=2
+
+# display keyboard layout name
+# for keyboard layouts switcher
+# see i3 config file
+# this needs xkblayout-state installed from the AUR:
+# https://aur.archlinux.org/packages/xkblayout-state-git
+#[keyboard-layout]
+#command=~/.config/i3/scripts/keyboard-layout
+#interval=2
+
+[keybindings]
+full_text=
+command=~/.config/i3/scripts/keyhint
+
+# power-profiles-daemon implementation:
+# needs package power-profiles-daemon installed and the service running see here:
+# https://wiki.archlinux.org/title/CPU_frequency_scaling#power-profiles-daemon
+
+#set power-profile
+[ppd_menu]
+full_text=
+command=~/.config/i3/scripts/power-profiles
+color=#407437
+
+#Show the current power-profile
+[ppd-status]
+command=~/.config/i3/scripts/ppd-status
+interval=5
+
+[time]
+#label=
+command=date '+%a %d %b %H:%M:%S'
+interval=1
+
+[shutdown_menu]
+full_text=
+command=~/.config/i3/scripts/powermenu
+
+[simple-2]
+full_text=: :
+color=#717171
diff --git a/i3/i3status.conf b/i3/i3status.conf
old mode 100644
new mode 100755
diff --git a/i3/keybindings b/i3/keybindings
new file mode 100644
index 0000000..f5edbc6
--- /dev/null
+++ b/i3/keybindings
@@ -0,0 +1,106 @@
+EndeavourOS i3wm Keybindings cheat sheet:
+
+--> to update this run the following command:
+wget --backups=1 https://raw.githubusercontent.com/endeavouros-team/endeavouros-i3wm-setup/main/.config/i3/keybindings -P ~/.config/i3/
+
+All sources and updates are available at GitHub:
+https://github.com/endeavouros-team/endeavouros-i3wm-setup
+
+For reference consult our WIKI:
+https://discovery.endeavouros.com/window-tiling-managers/i3-wm/
+
+ = windows key
+
+# start xfce4-terminal
++Return
+
+# kill focused window
++q
+
+# Application menu search by typing (fancy Rofi menu):
++d
+
+# Window switcher menu (fancy Rofi menu):
++t
+
+# fancy exit-menu on bottom right:
++Shift+e
+
+# Lock the system
+# lock with a picture or blurring the screen (options in config)
++l
+
+# reload the configuration file
++Shift+c
+
+# restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
++Shift+r
+
+# keybinding in fancy rofi (automated)
+F1
+
+# full keybinding list in editor:
++F1
+
+# change window focus
++j focus left
++k focus down
++b focus up
++o focus right
+
+# alternatively, you can use the cursor keys:
++Left focus left
++Down focus down
++Up focus up
++Right focus right
+
+# move a focused window
++Shift+j move left
++Shift+k move down
++Shift+b move up
++Shift+o move right
+
+# alternatively, you can use the cursor keys:
++Shift+Left move left
++Shift+Down move down
++Shift+Up move up
++Shift+Right move right
+
+# split in horizontal orientation
++h split h
+
+# split in vertical orientation
++v split v
+
+# enter fullscreen mode for the focused container
++f fullscreen toggle
+
+# change container layout (stacked, tabbed, toggle split)
++s layout stacking
++g layout tabbed
++e layout toggle split
+
+# toggle tiling / floating
++Shift+space floating toggle
+
+# change focus between tiling / floating windows
++space focus mode_toggle
+
+# focus the parent container
++a focus parent
+
+# focus the child container
+#+d focus child
+
+# resize floating window
++right mouse button
+
+## Multimedia Keys
+
+# Redirect sound to headphones
++p
+
+## App shortcuts
++w starts Firefox
++n starts Thunar
+ Button screenshot
diff --git a/i3/scripts/audio-device-switch b/i3/scripts/audio-device-switch
new file mode 100755
index 0000000..6077d38
--- /dev/null
+++ b/i3/scripts/audio-device-switch
@@ -0,0 +1,100 @@
+#!/usr/bin/env bash
+
+# audio-device-switch - audio device switch with a keybind
+# Adapted from this:
+# https://gist.githubusercontent.com/kbravh/1117a974f89cc53664e55823a55ac320/raw/9d04a10ae925074536047ae8100c6b0dbfc303d6/audio-device-switch.sh
+# Readme: https://gist.github.com/kbravh/1117a974f89cc53664e55823a55ac320
+# Creator: https://github.com/kbravh
+
+# Audio Output Switcher
+# This script will cycle to the next available audio output device.
+# It can be tied to a hotkey to easily be triggered.
+# This is handy, for example, for swapping between speakers and headphones.
+# This script will work on systems running PulseAudio or Pipewire services.
+
+
+
+# Check which sound server is running
+if pgrep pulseaudio >/dev/null; then
+ sound_server="pulseaudio"
+elif pgrep pipewire >/dev/null; then
+ sound_server="pipewire"
+else
+ echo "Neither PulseAudio nor PipeWire is running."
+ exit 1
+fi
+
+# Grab a count of how many audio sinks we have
+if [[ "$sound_server" == "pulseaudio" ]]; then
+ sink_count=$(pacmd list-sinks | grep -c "index:[[:space:]][[:digit:]]")
+ # Create an array of the actual sink IDs
+ sinks=()
+ mapfile -t sinks < <(pacmd list-sinks | grep 'index:[[:space:]][[:digit:]]' | sed -n -e 's/.*index:[[:space:]]\([[:digit:]]\)/\1/p')
+ # Get the ID of the active sink
+ active_sink=$(pacmd list-sinks | sed -n -e 's/[[:space:]]*\*[[:space:]]index:[[:space:]]\([[:digit:]]\)/\1/p')
+
+elif [[ "$sound_server" == "pipewire" ]]; then
+ sink_count=$(pactl list sinks | grep -c "Sink #[[:digit:]]")
+ # Create an array of the actual sink IDs
+ sinks=()
+ mapfile -t sinks < <(pactl list sinks | grep 'Sink #[[:digit:]]' | sed -n -e 's/.*Sink #\([[:digit:]]\)/\1/p')
+ # Get the ID of the active sink
+ active_sink_name=$(pactl info | grep 'Default Sink:' | sed -n -e 's/.*Default Sink:[[:space:]]\+\(.*\)/\1/p')
+ active_sink=$(pactl list sinks | grep -B 2 "$active_sink_name" | sed -n -e 's/Sink #\([[:digit:]]\)/\1/p' | head -n 1)
+fi
+
+# Get the ID of the last sink in the array
+final_sink=${sinks[$((sink_count - 1))]}
+
+# Find the index of the active sink
+for index in "${!sinks[@]}"; do
+ if [[ "${sinks[$index]}" == "$active_sink" ]]; then
+ active_sink_index=$index
+ fi
+done
+
+# Default to the first sink in the list
+next_sink=${sinks[0]}
+next_sink_index=0
+
+# If we're not at the end of the list, move up the list
+if [[ $active_sink -ne $final_sink ]]; then
+ next_sink_index=$((active_sink_index + 1))
+ next_sink=${sinks[$next_sink_index]}
+fi
+
+#change the default sink
+if [[ "$sound_server" == "pulseaudio" ]]; then
+ pacmd "set-default-sink ${next_sink}"
+elif [[ "$sound_server" == "pipewire" ]]; then
+ # Get the name of the next sink
+ next_sink_name=$(pactl list sinks | grep -C 2 "Sink #$next_sink" | sed -n -e 's/.*Name:[[:space:]]\+\(.*\)/\1/p' | head -n 1)
+ pactl set-default-sink "$next_sink_name"
+fi
+
+#move all inputs to the new sink
+if [[ "$sound_server" == "pulseaudio" ]]; then
+ for app in $(pacmd list-sink-inputs | sed -n -e 's/index:[[:space:]]\([[:digit:]]\)/\1/p'); do
+ pacmd "move-sink-input $app $next_sink"
+ done
+elif [[ "$sound_server" == "pipewire" ]]; then
+ for app in $(pactl list sink-inputs | sed -n -e 's/.*Sink Input #\([[:digit:]]\)/\1/p'); do
+ pactl "move-sink-input $app $next_sink"
+ done
+fi
+
+# Create a list of the sink descriptions
+sink_descriptions=()
+if [[ "$sound_server" == "pulseaudio" ]]; then
+ mapfile -t sink_descriptions < <(pacmd list-sinks | sed -n -e 's/.*alsa.name[[:space:]]=[[:space:]]"\(.*\)"/\1/p')
+elif [[ "$sound_server" == "pipewire" ]]; then
+ mapfile -t sink_descriptions < <(pactl list sinks | sed -n -e 's/.*Description:[[:space:]]\+\(.*\)/\1/p')
+fi
+
+# Find the index that matches our new active sink
+for sink_index in "${!sink_descriptions[@]}"; do
+ if [[ "$sink_index" == "$next_sink_index" ]]; then
+ notify-send -i audio-volume-high "Sound output switched to:" "${sink_descriptions[$sink_index]}"
+ exit
+ fi
+done
diff --git a/i3/scripts/bandwidth2 b/i3/scripts/bandwidth2
new file mode 100755
index 0000000..bd79e1a
--- /dev/null
+++ b/i3/scripts/bandwidth2
@@ -0,0 +1,109 @@
+#!/usr/bin/env bash
+#
+# Copyright (C) 2015 James Murphy
+# Licensed under the terms of the GNU GPL v2 only.
+#
+# i3blocks blocklet script to monitor bandwidth usage
+# detecting active device device
+# option to set used unit
+
+iface="${BLOCK_INSTANCE}"
+iface="${IFACE:-$iface}"
+dt="${DT:-3}"
+unit="${UNIT:-MB}"
+LABEL="${LABEL:-⇄ }" # down arrow up arrow
+printf_command="${PRINTF_COMMAND:-"printf \"${LABEL}%1.0f/%1.0f %s/s\\n\", rx, wx, unit;"}"
+
+function default_interface {
+ ip route | awk '/^default via/ {print $5; exit}'
+}
+
+function check_proc_net_dev {
+ if [ ! -f "/proc/net/dev" ]; then
+ echo "/proc/net/dev not found"
+ exit 1
+ fi
+}
+
+function list_interfaces {
+ check_proc_net_dev
+ echo "Interfaces in /proc/net/dev:"
+ grep -o "^[^:]\\+:" /proc/net/dev | tr -d " :"
+}
+
+while getopts i:t:u:p:lh opt; do
+ case "$opt" in
+ i) iface="$OPTARG" ;;
+ t) dt="$OPTARG" ;;
+ u) unit="$OPTARG" ;;
+ p) printf_command="$OPTARG" ;;
+ l) list_interfaces && exit 0 ;;
+ h) printf \
+"Usage: bandwidth3 [-i interface] [-t time] [-u unit] [-p printf_command] [-l] [-h]
+Options:
+-i\tNetwork interface to measure. Default determined using \`ip route\`.
+-t\tTime interval in seconds between measurements. Default: 3
+-u\tUnits to measure bytes in. Default: Mb
+\tAllowed units: Kb, KB, Mb, MB, Gb, GB, Tb, TB
+\tUnits may have optional it/its/yte/ytes on the end, e.g. Mbits, KByte
+-p\tAwk command to be called after a measurement is made.
+\tDefault: printf \" %%-5.1f/%%5.1f %%s/s\\\\n\", rx, wx, unit;
+\tExposed variables: rx, wx, tx, unit, iface
+-l\tList available interfaces in /proc/net/dev
+-h\tShow this help text
+" && exit 0;;
+ esac
+done
+
+check_proc_net_dev
+
+iface="${iface:-$(default_interface)}"
+while [ -z "$iface" ]; do
+ echo No default interface
+ sleep "$dt"
+ iface=$(default_interface)
+done
+
+case "$unit" in
+ Kb|Kbit|Kbits) bytes_per_unit=$((1024 / 8));;
+ KB|KByte|KBytes) bytes_per_unit=$((1024));;
+ Mb|Mbit|Mbits) bytes_per_unit=$((1024 * 1024 / 8));;
+ MB|MByte|MBytes) bytes_per_unit=$((1024 * 1024));;
+ Gb|Gbit|Gbits) bytes_per_unit=$((1024 * 1024 * 1024 / 8));;
+ GB|GByte|GBytes) bytes_per_unit=$((1024 * 1024 * 1024));;
+ Tb|Tbit|Tbits) bytes_per_unit=$((1024 * 1024 * 1024 * 1024 / 8));;
+ TB|TByte|TBytes) bytes_per_unit=$((1024 * 1024 * 1024 * 1024));;
+ *) echo Bad unit "$unit" && exit 1;;
+esac
+
+scalar=$((bytes_per_unit * dt))
+init_line=$(cat /proc/net/dev | grep "^[ ]*$iface:")
+if [ -z "$init_line" ]; then
+ echo Interface not found in /proc/net/dev: "$iface"
+ exit 1
+fi
+
+init_received=$(awk '{print $2}' <<< $init_line)
+init_sent=$(awk '{print $10}' <<< $init_line)
+
+(while true; do cat /proc/net/dev; sleep "$dt"; done) |\
+ stdbuf -oL grep "^[ ]*$iface:" |\
+ awk -v scalar="$scalar" -v unit="$unit" -v iface="$iface" '
+BEGIN {
+ old_received='"$init_received"'
+ old_sent='"$init_sent"'
+}
+{
+ received=$2
+ sent=$10
+ rx=(received-old_received)/scalar
+ wx=(sent-old_sent)/scalar
+ tx=rx+wx
+ old_received=received
+ old_sent=sent
+ if (rx >= 0 && wx >= 0) {
+ '"$printf_command"'
+ fflush(stdout)
+ }
+}
+'
diff --git a/i3/scripts/battery b/i3/scripts/battery
new file mode 100755
index 0000000..2d55dab
--- /dev/null
+++ b/i3/scripts/battery
@@ -0,0 +1,106 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2016 James Murphy
+# Licensed under the GPL version 2 only
+#
+# A battery indicator blocklet script for i3blocks
+
+from subprocess import check_output
+import os
+import re
+
+config = dict(os.environ)
+status = check_output(['acpi'], universal_newlines=True)
+
+if not status:
+ # stands for no battery found
+ color = config.get("color_10", "red")
+ fulltext = "\uf00d \uf240".format(color)
+ percentleft = 100
+else:
+ # if there is more than one battery in one laptop, the percentage left is
+ # available for each battery separately, although state and remaining
+ # time for overall block is shown in the status of the first battery
+ batteries = status.split("\n")
+ state_batteries=[]
+ commasplitstatus_batteries=[]
+ percentleft_batteries=[]
+ time = ""
+ for battery in batteries:
+ if battery!='':
+ state_batteries.append(battery.split(": ")[1].split(", ")[0])
+ commasplitstatus = battery.split(", ")
+ if not time:
+ time = commasplitstatus[-1].strip()
+ # check if it matches a time
+ time = re.match(r"(\d+):(\d+)", time)
+ if time:
+ time = ":".join(time.groups())
+ timeleft = " ({})".format(time)
+ else:
+ timeleft = ""
+
+ p = int(commasplitstatus[1].rstrip("%\n"))
+ if p>0:
+ percentleft_batteries.append(p)
+ commasplitstatus_batteries.append(commasplitstatus)
+ state = state_batteries[0]
+ commasplitstatus = commasplitstatus_batteries[0]
+ if percentleft_batteries:
+ percentleft = int(sum(percentleft_batteries)/len(percentleft_batteries))
+ else:
+ percentleft = 0
+
+ # stands for charging
+ color = config.get("color_charging", "yellow")
+ FA_LIGHTNING = "\uf0e7".format(color)
+
+ # stands for plugged in
+ FA_PLUG = "\uf1e6"
+
+ # stands for using battery
+ FA_BATTERY = "\uf240"
+
+ # stands for unknown status of battery
+ FA_QUESTION = "\uf128"
+
+
+ if state == "Discharging":
+ fulltext = FA_BATTERY + " "
+ elif state == "Full":
+ fulltext = FA_PLUG + " "
+ timeleft = ""
+ elif state == "Unknown":
+ fulltext = FA_QUESTION + " " + FA_BATTERY + " "
+ timeleft = ""
+ else:
+ fulltext = FA_LIGHTNING + " " + FA_PLUG + " "
+
+ def color(percent):
+ if percent < 10:
+ # exit code 33 will turn background red
+ return config.get("color_10", "#FFFFFF")
+ if percent < 20:
+ return config.get("color_20", "#FF3300")
+ if percent < 30:
+ return config.get("color_30", "#FF6600")
+ if percent < 40:
+ return config.get("color_40", "#FF9900")
+ if percent < 50:
+ return config.get("color_50", "#FFCC00")
+ if percent < 60:
+ return config.get("color_60", "#FFFF00")
+ if percent < 70:
+ return config.get("color_70", "#FFFF33")
+ if percent < 80:
+ return config.get("color_80", "#FFFF66")
+ return config.get("color_full", "#FFFFFF")
+
+ form = '{}%'
+ fulltext += form.format(color(percentleft), percentleft)
+ #fulltext += timeleft
+
+print(fulltext)
+print(fulltext)
+if percentleft < 10:
+ exit(33)
diff --git a/i3/scripts/battery-pinebook-pro b/i3/scripts/battery-pinebook-pro
new file mode 100755
index 0000000..45317d5
--- /dev/null
+++ b/i3/scripts/battery-pinebook-pro
@@ -0,0 +1,20 @@
+#!/usr/bin/env bash
+
+# simple Shellscript for i3blocks on Pinebook pro
+# 05012020 geri123 //at// gmx.net Gerhard S.
+# battery-symbols: you need the awesome-terminal-font package installed
+
+PERCENT=$(cat /sys/class/power_supply/cw2015-battery/capacity)
+STATUS=$(cat /sys/class/power_supply/cw2015-battery/status)
+case $((
+ $PERCENT >= 0 && $PERCENT <= 20 ? 1 :
+ $PERCENT > 20 && $PERCENT <= 40 ? 2 :
+ $PERCENT > 40 && $PERCENT <= 60 ? 3 :
+ $PERCENT > 60 && $PERCENT <= 80 ? 4 : 5)) in
+#
+ (1) echo $STATUS:"" :$PERCENT%;;
+ (2) echo $STATUS:"" :$PERCENT%;;
+ (3) echo $STATUS:"" :$PERCENT%;;
+ (4) echo $STATUS:"" :$PERCENT%;;
+ (5) echo $STATUS:"" :$PERCENT%;;
+esac
diff --git a/i3/scripts/blur-lock b/i3/scripts/blur-lock
new file mode 100755
index 0000000..2f6cc31
--- /dev/null
+++ b/i3/scripts/blur-lock
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+
+# simple screenlocker using i3lock that creates ablurred screenshot to overlay
+
+PICTURE=/tmp/i3lock.png
+SCREENSHOT="scrot -z $PICTURE"
+
+BLUR="5x4"
+
+$SCREENSHOT
+magick $PICTURE -blur $BLUR $PICTURE
+i3lock -i $PICTURE
+shred $PICTURE
+rm $PICTURE
diff --git a/i3/scripts/cpu_usage b/i3/scripts/cpu_usage
new file mode 100755
index 0000000..8d8a267
--- /dev/null
+++ b/i3/scripts/cpu_usage
@@ -0,0 +1,62 @@
+#!/usr/bin/perl
+#
+# Copyright 2014 Pierre Mavro
+# Copyright 2014 Vivien Didelot
+# Copyright 2014 Andreas Guldstrand
+#
+# Licensed under the terms of the GNU GPL v3, or any later version.
+
+use strict;
+use warnings;
+use utf8;
+use Getopt::Long;
+
+# default values
+my $t_warn = $ENV{T_WARN} // 50;
+my $t_crit = $ENV{T_CRIT} // 80;
+my $cpu_usage = -1;
+my $decimals = $ENV{DECIMALS} // 0;
+my $label = $ENV{LABEL} // "";
+
+sub help {
+ print "Usage: cpu_usage [-w ] [-c ] [-d ]\n";
+ print "-w : warning threshold to become yellow\n";
+ print "-c : critical threshold to become red\n";
+ print "-d : Use decimals for percentage (default is $decimals) \n";
+ exit 0;
+}
+
+GetOptions("help|h" => \&help,
+ "w=i" => \$t_warn,
+ "c=i" => \$t_crit,
+ "d=i" => \$decimals,
+);
+
+# Get CPU usage
+$ENV{LC_ALL}="en_US"; # if mpstat is not run under en_US locale, things may break, so make sure it is
+open (MPSTAT, 'mpstat 1 1 |') or die;
+while () {
+ if (/^.*\s+(\d+\.\d+)[\s\x00]?$/) {
+ $cpu_usage = 100 - $1; # 100% - %idle
+ last;
+ }
+}
+close(MPSTAT);
+
+$cpu_usage eq -1 and die 'Can\'t find CPU information';
+
+# Print short_text, full_text
+print "${label}";
+printf "%02.${decimals}f%%\n", $cpu_usage;
+print "${label}";
+printf "%02.${decimals}f%%\n", $cpu_usage;
+
+# Print color, if needed
+if ($cpu_usage >= $t_crit) {
+ print "#FF0000\n";
+ exit 33;
+} elsif ($cpu_usage >= $t_warn) {
+ print "#FFFC00\n";
+}
+
+exit 0;
diff --git a/i3/scripts/cputemp b/i3/scripts/cputemp
new file mode 100755
index 0000000..8a7d821
--- /dev/null
+++ b/i3/scripts/cputemp
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+
+# script to monitor temperatures in waybar/i3blocks e.t.c.
+# example only use `sensors` to find your names to replace `Tdie|Tctl|Package`
+# example output part from sensors:
+# zenpower-pci-00c3
+# Adapter: PCI adapter
+# SVI2_Core: 1.03 V
+# SVI2_SoC: 994.00 mV
+# Tdie: +53.1°C
+# Tctl: +53.1°C
+# Tccd1: +42.5°C
+# Tccd2: +43.2°C
+
+temp=$(sensors 2>/dev/null | grep -E 'Tdie|Tctl|Package id 0' | grep -oP '\+?[0-9]+\.\d+(?=°C)' | tr -d '+' | head -n1)
+
+echo "${temp}°C"
diff --git a/i3/scripts/disk b/i3/scripts/disk
new file mode 100755
index 0000000..e18c7aa
--- /dev/null
+++ b/i3/scripts/disk
@@ -0,0 +1,48 @@
+#!/usr/bin/env bash
+# Copyright (C) 2014 Julien Bonjean
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+DIR="${DIR:-$BLOCK_INSTANCE}"
+DIR="${DIR:-$HOME}"
+ALERT_LOW="${ALERT_LOW:-$1}"
+ALERT_LOW="${ALERT_LOW:-10}" # color will turn red under this value (default: 10%)
+
+LOCAL_FLAG="-l"
+if [ "$1" = "-n" ] || [ "$2" = "-n" ]; then
+ LOCAL_FLAG=""
+fi
+
+df -h -P $LOCAL_FLAG "$DIR" | awk -v label="$LABEL" -v alert_low=$ALERT_LOW '
+/\/.*/ {
+ # full text
+ print label $4
+
+ # short text
+ print label $4
+
+ use=$5
+
+ # no need to continue parsing
+ exit 0
+}
+
+END {
+ gsub(/%$/,"",use)
+ if (100 - use < alert_low) {
+ # color
+ print "#FF0000"
+ }
+}
+'
diff --git a/i3/scripts/empty_workspace b/i3/scripts/empty_workspace
new file mode 100755
index 0000000..fd21131
--- /dev/null
+++ b/i3/scripts/empty_workspace
@@ -0,0 +1,16 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2025 Johannes Kamprad
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# empty_workspace - open a new workspace automatically named with next number on i3
+
+
+MAX_DESKTOPS=20
+
+WORKSPACES=$(seq -s '\n' 1 1 ${MAX_DESKTOPS})
+
+EMPTY_WORKSPACE=$( (i3-msg -t get_workspaces | tr ',' '\n' | grep num | awk -F: '{print int($2)}' ; \
+ echo -e ${WORKSPACES} ) | sort -n | uniq -u | head -n 1)
+
+i3-msg workspace ${EMPTY_WORKSPACE}
diff --git a/i3/scripts/gputemp b/i3/scripts/gputemp
new file mode 100755
index 0000000..a63166c
--- /dev/null
+++ b/i3/scripts/gputemp
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+
+# script to monitor temperatures in waybar/i3blocks e.t.c.
+# example only use `sensors` to find your sensor to replace `i915-pci-0600`
+# example output part from sensors:
+# i915-pci-0600
+# Adapter: PCI adapter
+# in0: 630.00 mV
+# fan1: 0 RPM
+# temp1: +55.0°C
+# energy1: 1.26 MJ
+
+# examples using Nvidia tools:
+#echo "$(nvidia-smi --format=csv,noheader --query-gpu=temperature.gpu) °C"
+#echo "$(nvidia-settings -q gpucoretemp -t) °C"
+# example using sensor name:
+sensors 2>/dev/null | awk '/i915-pci-0600/{flag=1} flag && /temp1/ {gsub("\\+", "", $2); print $2, $3; exit}'
diff --git a/i3/scripts/import-gsettings b/i3/scripts/import-gsettings
new file mode 100755
index 0000000..b848168
--- /dev/null
+++ b/i3/scripts/import-gsettings
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+# needed for nwg-looks
+# usage: import-gsettings
+config="${XDG_CONFIG_HOME:-$HOME/.config}/gtk-3.0/settings.ini"
+if [ ! -f "$config" ]; then exit 1; fi
+
+gnome_schema="org.gnome.desktop.interface"
+gtk_theme="$(grep 'gtk-theme-name' "$config" | cut -d'=' -f2)"
+icon_theme="$(grep 'gtk-icon-theme-name' "$config" | cut -d'=' -f2)"
+cursor_theme="$(grep 'gtk-cursor-theme-name' "$config" | cut -d'=' -f2)"
+font_name="$(grep 'gtk-font-name' "$config" | cut -d'=' -f2)"
+gsettings set "$gnome_schema" gtk-theme "$gtk_theme"
+gsettings set "$gnome_schema" icon-theme "$icon_theme"
+gsettings set "$gnome_schema" cursor-theme "$cursor_theme"
+gsettings set "$gnome_schema" font-name "$font_name"
\ No newline at end of file
diff --git a/i3/scripts/keyhint b/i3/scripts/keyhint
new file mode 100755
index 0000000..34a123a
--- /dev/null
+++ b/i3/scripts/keyhint
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+
+# simple yad gui to show default keybindings
+
+Main() {
+ source /usr/share/endeavouros/scripts/eos-script-lib-yad || return 1
+
+ local command=(
+ eos_yad --title="EndeavourOS i3-wm keybindings:" --no-buttons --geometry=400x345-15-400 --list
+ --column=key: --column=description: --column=command:
+ "ESC" "close this app" ""
+ "=" "modkey" "(set mod Mod4)"
+ "+enter" "open a terminal" ""
+ "+Shift+n" "new empty workspace" ""
+ "+w" "open Browser" ""
+ "+n" "open Filebrowser" ""
+ "+d" "app menu" ""
+ "+q" "close focused app" ""
+ "Print-key" "screenshot" ""
+ "+Shift+e" "logout menu" ""
+ "F1" "open keybinding helper" ""
+ )
+
+ "${command[@]}"
+}
+
+Main "$@"
diff --git a/i3/scripts/keyhint-2 b/i3/scripts/keyhint-2
new file mode 100755
index 0000000..a5fd92f
--- /dev/null
+++ b/i3/scripts/keyhint-2
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+# keyhint rofi tool to search used keybindings in i3wm
+
+I3_CONFIG=$HOME/.config/i3/config
+mod_key=$(sed -nre 's/^set \$mod (.*)/\1/p' ${I3_CONFIG})
+grep "^bindsym" ${I3_CONFIG} \
+ | sed "s/-\(-\w\+\)\+//g;s/\$mod/${mod_key}/g;s/Mod1/Alt/g;s/exec //;s/bindsym //;s/^\s\+//;s/^\([^ ]\+\) \(.\+\)$/\2: \1/;s/^\s\+//" \
+ | tr -s ' ' \
+ | rofi -dmenu -theme ~/.config/rofi/rofikeyhint.rasi
diff --git a/i3/scripts/memory b/i3/scripts/memory
new file mode 100755
index 0000000..e60be50
--- /dev/null
+++ b/i3/scripts/memory
@@ -0,0 +1,69 @@
+#!/usr/bin/env bash
+# Copyright (C) 2014 Julien Bonjean
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+TYPE="${BLOCK_INSTANCE:-mem}"
+
+awk -v type=$TYPE '
+/^MemTotal:/ {
+ mem_total=$2
+}
+/^MemFree:/ {
+ mem_free=$2
+}
+/^Buffers:/ {
+ mem_free+=$2
+}
+/^Cached:/ {
+ mem_free+=$2
+}
+/^SwapTotal:/ {
+ swap_total=$2
+}
+/^SwapFree:/ {
+ swap_free=$2
+}
+END {
+ if (type == "swap") {
+ free=swap_free/1024/1024
+ used=(swap_total-swap_free)/1024/1024
+ total=swap_total/1024/1024
+ } else {
+ free=mem_free/1024/1024
+ used=(mem_total-mem_free)/1024/1024
+ total=mem_total/1024/1024
+ }
+
+ pct=0
+ if (total > 0) {
+ pct=used/total*100
+ }
+
+ # full text
+ # printf("%.1fG/%.1fG (%.f%%)\n", used, total, pct)
+
+ # short text
+ printf("%02.f%%\n", pct)
+
+ # color
+ if (pct > 90) {
+ print("#FF0000")
+ } else if (pct > 80) {
+ print("#FFAE00")
+ } else if (pct > 70) {
+ print("#FFF600")
+ }
+}
+' /proc/meminfo
diff --git a/i3/scripts/openweather b/i3/scripts/openweather
new file mode 100755
index 0000000..e41b833
--- /dev/null
+++ b/i3/scripts/openweather
@@ -0,0 +1,471 @@
+#!/usr/bin/env bash
+
+# openweater - OpenWeatherMap Weather Fetcher for Waybar/Status Bars
+#
+# Copyright (C) 2025 Johannes Kamprad
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+
+# openweater - OpenWeatherMap Weather Fetcher for Waybar/Status Bars
+# Secure API key handling with configurable locations
+# including setup script and help
+# Options:
+# -h, --help Show this help message
+# -c, --city-id ID Override city ID (required if not in config)
+# -k, --api-key KEY Override API key (not recommended, use config file)
+# -u, --units UNITS Units: metric, imperial, kelvin (default: $DEFAULT_UNITS)
+# -f, --force-refresh Force refresh (ignore cache)
+# --setup Interactive setup wizard
+# --show-config Show current configuration
+
+set -euo pipefail
+
+# Set C locale to avoid German decimal formatting issues
+export LC_NUMERIC=C
+export LC_ALL=C
+
+# Colors for output
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+NC='\033[0m' # No Color
+
+# Default configuration (no default location)
+DEFAULT_UNITS="metric"
+CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}"
+CONFIG_FILE="$CONFIG_DIR/openweather/config"
+CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/openweather"
+CACHE_FILE="$CACHE_DIR/weather_data"
+CACHE_DURATION=600 # 10 minutes
+
+# Logging functions
+log_error() {
+ echo -e "${RED}[ERROR]${NC} $*" >&2
+}
+
+log_warn() {
+ echo -e "${YELLOW}[WARN]${NC} $*" >&2
+}
+
+# Show help
+show_help() {
+ cat << EOF
+Usage: $(basename "$0") [OPTIONS]
+
+Secure OpenWeatherMap weather fetcher with configurable locations.
+
+Options:
+ -h, --help Show this help message
+ -c, --city-id ID Override city ID (required if not in config)
+ -k, --api-key KEY Override API key (not recommended, use config file)
+ -u, --units UNITS Units: metric, imperial, kelvin (default: $DEFAULT_UNITS)
+ -f, --force-refresh Force refresh (ignore cache)
+ --setup Interactive setup wizard
+ --show-config Show current configuration
+
+Configuration:
+ Config file: $CONFIG_FILE
+
+ Create config file with:
+ OPENWEATHER_API_KEY="your_api_key_here"
+ OPENWEATHER_CITY_ID="your_city_id" # Required
+ OPENWEATHER_UNITS="metric" # Optional
+
+Examples:
+ $(basename "$0") # Use config file settings
+ $(basename "$0") --city-id 5128581 # New York
+ $(basename "$0") --units imperial # Fahrenheit
+ $(basename "$0") --setup # Run setup wizard
+
+Get your free API key at: https://openweathermap.org/api
+Find city IDs at: https://openweathermap.org/find
+
+EOF
+}
+
+# Check dependencies
+check_dependencies() {
+ local missing_deps=()
+
+ for cmd in jq curl; do
+ if ! command -v "$cmd" >/dev/null 2>&1; then
+ missing_deps+=("$cmd")
+ fi
+ done
+
+ if [[ ${#missing_deps[@]} -gt 0 ]]; then
+ log_error "Missing required dependencies: ${missing_deps[*]}"
+ echo "Install with: sudo pacman -S ${missing_deps[*]}"
+ exit 1
+ fi
+}
+
+# Load configuration
+load_config() {
+ # Set defaults (no default city ID)
+ OPENWEATHER_CITY_ID=""
+ OPENWEATHER_UNITS="$DEFAULT_UNITS"
+
+ # Load from config file if it exists
+ if [[ -f "$CONFIG_FILE" ]]; then
+ source "$CONFIG_FILE"
+ fi
+
+ # Override with environment variables if set
+ OPENWEATHER_API_KEY="${OPENWEATHER_API_KEY:-}"
+ OPENWEATHER_CITY_ID="${OPENWEATHER_CITY_ID:-}"
+ OPENWEATHER_UNITS="${OPENWEATHER_UNITS:-$DEFAULT_UNITS}"
+}
+
+# Validate API key
+validate_api_key() {
+ if [[ -z "$OPENWEATHER_API_KEY" ]]; then
+ log_error "No API key found!"
+ echo
+ echo "To fix this:"
+ echo "1. Get free API key: https://openweathermap.org/api"
+ echo "2. Run setup wizard: $0 --setup"
+ echo "3. Or set environment variable: export OPENWEATHER_API_KEY=your_key"
+ echo "4. Or create config file: $CONFIG_FILE"
+ exit 1
+ fi
+
+ # Basic validation (OpenWeatherMap keys are typically 32 chars)
+ if [[ ${#OPENWEATHER_API_KEY} -ne 32 ]]; then
+ log_warn "API key length seems incorrect (expected 32 characters, got ${#OPENWEATHER_API_KEY})"
+ fi
+}
+
+# Validate city ID
+validate_city_id() {
+ if [[ -z "$OPENWEATHER_CITY_ID" ]]; then
+ log_error "No city ID found!"
+ echo
+ echo "To fix this:"
+ echo "1. Run setup wizard: $0 --setup"
+ echo "2. Or set environment variable: export OPENWEATHER_CITY_ID=your_city_id"
+ echo "3. Or add OPENWEATHER_CITY_ID=\"your_city_id\" to: $CONFIG_FILE"
+ echo "4. Or provide city ID via command line: $0 --city-id your_city_id"
+ echo
+ echo "Find city IDs at: https://openweathermap.org/find"
+ exit 1
+ fi
+
+ # Basic validation (city IDs are typically numeric)
+ if [[ ! "$OPENWEATHER_CITY_ID" =~ ^[0-9]+$ ]]; then
+ log_warn "City ID format seems incorrect (expected numeric, got: $OPENWEATHER_CITY_ID)"
+ fi
+}
+
+# Setup wizard
+run_setup() {
+ echo -e "${GREEN}=== OpenWeatherMap Setup Wizard ===${NC}"
+ echo
+
+ # Create config directory
+ mkdir -p "$(dirname "$CONFIG_FILE")"
+
+ # Get API key
+ echo "Get your free API key at: https://openweathermap.org/api"
+ echo
+ echo -n "Enter your OpenWeatherMap API key: "
+ read -r api_key
+
+ if [[ -z "$api_key" ]]; then
+ log_error "API key cannot be empty"
+ exit 1
+ fi
+
+ # Get city ID (required)
+ echo
+ echo "Find your city ID at: https://openweathermap.org/find"
+ echo -n "Enter city ID: "
+ read -r city_id
+
+ if [[ -z "$city_id" ]]; then
+ log_error "City ID cannot be empty"
+ exit 1
+ fi
+
+ # Get units (optional)
+ echo
+ echo "Available units: metric (°C), imperial (°F), kelvin (K)"
+ echo -n "Enter units [metric]: "
+ read -r units
+ units="${units:-metric}"
+
+ # Write config file
+ cat > "$CONFIG_FILE" << EOF
+# OpenWeatherMap Configuration
+# Generated by $(basename "$0") setup wizard on $(date)
+
+# Your API key from https://openweathermap.org/api
+OPENWEATHER_API_KEY="$api_key"
+
+# City ID from https://openweathermap.org/find
+OPENWEATHER_CITY_ID="$city_id"
+
+# Units: metric, imperial, kelvin
+OPENWEATHER_UNITS="$units"
+EOF
+
+ # Set secure permissions
+ chmod 600 "$CONFIG_FILE"
+
+ echo
+ echo -e "${GREEN}✅ Configuration saved to: $CONFIG_FILE${NC}"
+ echo -e "${GREEN}✅ File permissions set to 600 (user read/write only)${NC}"
+ echo
+ echo "Testing configuration..."
+
+ # Test the configuration
+ OPENWEATHER_API_KEY="$api_key"
+ OPENWEATHER_CITY_ID="$city_id"
+ OPENWEATHER_UNITS="$units"
+
+ if fetch_weather_data; then
+ echo -e "${GREEN}✅ Configuration test successful!${NC}"
+ else
+ log_error "Configuration test failed. Please check your API key and city ID."
+ exit 1
+ fi
+}
+
+# Show current configuration
+show_config() {
+ echo "=== Current Configuration ==="
+ echo "Config file: $CONFIG_FILE"
+ echo "Cache file: $CACHE_FILE"
+ echo "Cache duration: ${CACHE_DURATION}s"
+ echo
+
+ if [[ -f "$CONFIG_FILE" ]]; then
+ echo "Configuration:"
+ echo " API Key: ${OPENWEATHER_API_KEY:0:8}... (${#OPENWEATHER_API_KEY} chars)"
+ echo " City ID: $OPENWEATHER_CITY_ID"
+ echo " Units: $OPENWEATHER_UNITS"
+ else
+ echo "❌ No configuration file found at: $CONFIG_FILE"
+ echo "Run: $0 --setup"
+ fi
+}
+
+# Check cache validity
+is_cache_valid() {
+ [[ -f "$CACHE_FILE" ]] && \
+ [[ $(($(date +%s) - $(stat -c %Y "$CACHE_FILE" 2>/dev/null || echo 0))) -lt $CACHE_DURATION ]]
+}
+
+# Fetch weather data from API
+fetch_weather_data() {
+ local url="https://api.openweathermap.org/data/2.5/weather?id=${OPENWEATHER_CITY_ID}&units=${OPENWEATHER_UNITS}&appid=${OPENWEATHER_API_KEY}"
+
+ local response
+ if ! response=$(curl -sf "$url" 2>/dev/null); then
+ log_error "Failed to fetch weather data from API"
+ return 1
+ fi
+
+ # Validate JSON response
+ if ! echo "$response" | jq . >/dev/null 2>&1; then
+ log_error "Invalid JSON response from API"
+ return 1
+ fi
+
+ # Check for API error
+ local api_code
+ api_code=$(echo "$response" | jq -r '.cod // empty')
+ if [[ "$api_code" != "200" ]]; then
+ local api_message
+ api_message=$(echo "$response" | jq -r '.message // "Unknown API error"')
+ log_error "API Error ($api_code): $api_message"
+ return 1
+ fi
+
+ # Cache the response
+ mkdir -p "$CACHE_DIR"
+ echo "$response" > "$CACHE_FILE"
+
+ return 0
+}
+
+# Get weather data (from cache or API)
+get_weather_data() {
+ local force_refresh="${1:-false}"
+
+ if [[ "$force_refresh" != "true" ]] && is_cache_valid; then
+ cat "$CACHE_FILE"
+ else
+ if fetch_weather_data; then
+ cat "$CACHE_FILE"
+ else
+ # Fallback to cache if available
+ if [[ -f "$CACHE_FILE" ]]; then
+ log_warn "Using stale cache data due to API failure"
+ cat "$CACHE_FILE"
+ else
+ return 1
+ fi
+ fi
+ fi
+}
+
+# Calculate wind direction
+get_wind_direction() {
+ local degrees="$1"
+ local directions=(N NNE NE ENE E ESE SE SSE S SSW SW WSW W WNW NW NNW)
+ local index
+ index=$(awk "BEGIN {print int(($degrees % 360) / 22.5)}")
+ echo "${directions[$index]}"
+}
+
+# Get weather icon
+get_weather_icon() {
+ local condition="$1"
+ case "$condition" in
+ 'Clear') echo "☀" ;; # Clear sky
+ 'Clouds') echo "☁" ;; # Cloudy
+ 'Rain'|'Drizzle') echo "🌧" ;; # Rain
+ 'Snow') echo "❄" ;; # Snow
+ 'Thunderstorm') echo "⛈" ;; # Thunder
+ 'Mist'|'Fog') echo "🌫" ;; # Fog
+ *) echo "🌤" ;; # Default
+ esac
+}
+
+# Safe number formatting (handles locale issues)
+safe_printf() {
+ local format="$1"
+ local number="$2"
+
+ # Validate number is actually numeric
+ if [[ ! "$number" =~ ^-?[0-9]+(\.[0-9]+)?$ ]]; then
+ echo "0.0"
+ return 1
+ fi
+
+ # Use awk for reliable formatting regardless of locale
+ awk "BEGIN {printf \"$format\", $number}"
+}
+
+# Format weather output
+format_weather() {
+ local weather_data="$1"
+
+ # Parse weather data with error checking
+ local condition temp wind_speed_ms wind_deg
+ condition=$(echo "$weather_data" | jq -r '.weather[0].main // "Unknown"')
+ temp=$(echo "$weather_data" | jq -r '.main.temp // "0"')
+ wind_speed_ms=$(echo "$weather_data" | jq -r '.wind.speed // "0"')
+ wind_deg=$(echo "$weather_data" | jq -r '.wind.deg // "0"')
+
+ # Validate parsed data
+ [[ "$condition" == "null" ]] && condition="Unknown"
+ [[ "$temp" == "null" ]] && temp="0"
+ [[ "$wind_speed_ms" == "null" ]] && wind_speed_ms="0"
+ [[ "$wind_deg" == "null" ]] && wind_deg="0"
+
+ # Format temperature with safe formatting
+ local temp_formatted
+ temp_formatted=$(safe_printf "%.1f" "$temp")
+
+ # Convert wind speed to km/h with safe formatting
+ local wind_speed_kmh
+ wind_speed_kmh=$(awk "BEGIN {printf \"%.1f\", ($wind_speed_ms + 0) * 3.6}")
+
+ # Get wind direction
+ local wind_dir
+ wind_dir=$(get_wind_direction "$wind_deg")
+
+ # Get weather icon
+ local icon
+ icon=$(get_weather_icon "$condition")
+
+ # Format unit symbol
+ local unit_symbol
+ case "$OPENWEATHER_UNITS" in
+ "imperial") unit_symbol="°F" ;;
+ "kelvin") unit_symbol="K" ;;
+ *) unit_symbol="°C" ;;
+ esac
+
+ # Output formatted weather
+ echo "${icon} ${temp_formatted}${unit_symbol}, ${wind_speed_kmh} km/h ${wind_dir}"
+}
+
+# Main function
+main() {
+ local city_id_override=""
+ local api_key_override=""
+ local units_override=""
+ local force_refresh="false"
+
+ # Parse command line arguments
+ while [[ $# -gt 0 ]]; do
+ case $1 in
+ -h|--help)
+ show_help
+ exit 0
+ ;;
+ -c|--city-id)
+ city_id_override="$2"
+ shift 2
+ ;;
+ -k|--api-key)
+ api_key_override="$2"
+ shift 2
+ ;;
+ -u|--units)
+ units_override="$2"
+ shift 2
+ ;;
+ -f|--force-refresh)
+ force_refresh="true"
+ shift
+ ;;
+ --setup)
+ check_dependencies
+ run_setup
+ exit 0
+ ;;
+ --show-config)
+ load_config
+ show_config
+ exit 0
+ ;;
+ *)
+ log_error "Unknown option: $1"
+ show_help
+ exit 1
+ ;;
+ esac
+ done
+
+ # Check dependencies
+ check_dependencies
+
+ # Load configuration
+ load_config
+
+ # Apply overrides
+ [[ -n "$city_id_override" ]] && OPENWEATHER_CITY_ID="$city_id_override"
+ [[ -n "$api_key_override" ]] && OPENWEATHER_API_KEY="$api_key_override"
+ [[ -n "$units_override" ]] && OPENWEATHER_UNITS="$units_override"
+
+ # Validate configuration
+ validate_api_key
+ validate_city_id
+
+ # Get and format weather data
+ local weather_data
+ if weather_data=$(get_weather_data "$force_refresh"); then
+ format_weather "$weather_data"
+ else
+ echo "⚠️ Weather data unavailable"
+ exit 1
+ fi
+}
+
+# Run main function
+main "$@"
diff --git a/i3/scripts/power-profiles b/i3/scripts/power-profiles
new file mode 100755
index 0000000..6c901b3
--- /dev/null
+++ b/i3/scripts/power-profiles
@@ -0,0 +1,64 @@
+#!/usr/bin/env bash
+
+# Simple power-profiles-daemon switcher using rofi and static theme, with notification
+#
+# Copyright (C) 2025 Johannes Kamprad
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# needs rofi config:
+# $HOME/.config/rofi/powermenu.rasi
+
+ROFI_THEME="${HOME}/.config/rofi/power-profiles.rasi"
+
+# Dependency checks
+command -v powerprofilesctl >/dev/null 2>&1 || { echo "powerprofilesctl not found"; exit 1; }
+command -v rofi >/dev/null 2>&1 || { echo "rofi not found"; exit 1; }
+if ! command -v notify-send >/dev/null 2>&1; then
+ notify_send_missing=true
+fi
+
+current_profile="$(powerprofilesctl get 2>/dev/null)"
+ROFI_ARGS=(-dmenu -i -theme "$ROFI_THEME" -p "Change Profile" -mesg "Current used: $current_profile" -markup-rows)
+
+# Menu entries
+cancel=" Cancel"
+perf=" Performance"
+balanced=" Balanced"
+powersave=" Power Saver"
+# sets chancel to be on top
+options="$cancel"
+
+if powerprofilesctl list | grep -q "performance"; then
+ options="$options\n$perf"
+fi
+if powerprofilesctl list | grep -q "balanced"; then
+ options="$options\n$balanced"
+fi
+if powerprofilesctl list | grep -q "power-saver"; then
+ options="$options\n$powersave"
+fi
+
+# Show menu
+chosen="$(echo -e "$options" | rofi "${ROFI_ARGS[@]}")"
+
+# Run selection
+case $chosen in
+ "$perf")
+ powerprofilesctl set performance
+ ;;
+ "$balanced")
+ powerprofilesctl set balanced
+ ;;
+ "$powersave")
+ powerprofilesctl set power-saver
+ ;;
+ "$cancel"|"")
+ exit 0
+ ;;
+esac
+
+# Send notification if available
+if [[ "$chosen" != "$cancel" && -z "${notify_send_missing}" ]]; then
+ notify-send -i dialog-information "Power Profile Changed" "New profile: ${chosen}"
+fi
diff --git a/i3/scripts/powermenu b/i3/scripts/powermenu
new file mode 100755
index 0000000..6111806
--- /dev/null
+++ b/i3/scripts/powermenu
@@ -0,0 +1,81 @@
+#!/usr/bin/env bash
+
+#
+# powermenu - a very simple rofi powermenu
+#
+# Copyright (C) 2025 Johannes Kamprad
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# needs rofi config:
+# $HOME/.config/rofi/powermenu.rasi
+# set to be used in i3wm
+
+ROFI_THEME="${HOME}/.config/rofi/powermenu.rasi"
+# Define possible lock scripts/commands (edit this list as you like)
+LOCK_SCRIPTS=("${HOME}/.config/i3/scripts/blur-lock" "i3lock")
+
+# Find available lock script
+find_lock_script() {
+ for script in "${LOCK_SCRIPTS[@]}"; do
+ # Handle command names vs full paths
+ if [[ "$script" =~ ^[a-zA-Z0-9_-]+$ ]]; then
+ # It's a command name, check if available
+ if command -v "$script" >/dev/null 2>&1; then
+ echo "$script"
+ return 0
+ fi
+ else
+ # It's a path, check if file exists and is executable
+ if [[ -x "$script" ]]; then
+ echo "$script"
+ return 0
+ fi
+ fi
+ done
+ return 1
+}
+
+# Menu entries
+chancel=" Cancel"
+lock=" Lock"
+logout=" Logout"
+reboot=" Reboot"
+shutdown=" Shutdown"
+suspend=" Suspend"
+hibernate=" Hibernate"
+
+
+# Add lock only if script is found
+if lockcmd="$(find_lock_script)"; then
+ options="$chancel\n$lock\n$logout\n$reboot\n$shutdown\n$suspend\n$hibernate"
+else
+ options="$chancel\n$logout\n$reboot\n$shutdown\n$suspend\n$hibernate"
+fi
+
+chosen="$(echo -e "$options" | rofi -dmenu -i -p "Power Menu" \
+ -theme $ROFI_THEME)"
+
+case $chosen in
+ "$lock")
+ $lockcmd
+ ;;
+ "$cancel"|"")
+ exit 0
+ ;;
+ "$logout")
+ i3-msg exit
+ ;;
+ "$reboot")
+ systemctl reboot
+ ;;
+ "$shutdown")
+ systemctl poweroff
+ ;;
+ "$suspend")
+ systemctl suspend
+ ;;
+ "$hibernate")
+ systemctl hibernate
+ ;;
+esac
diff --git a/i3/scripts/ppd-status b/i3/scripts/ppd-status
new file mode 100755
index 0000000..92ab169
--- /dev/null
+++ b/i3/scripts/ppd-status
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+
+
+# power-profiles-daemon implementation:
+# needs package power-profiles-daemon installed and the service running see here:
+# https://wiki.archlinux.org/title/CPU_frequency_scaling#power-profiles-daemon
+# used in i3-blocks: ~/.config/i3/i3blocks.conf together with: ~/.config/i3/scripts/power-profiles
+
+
+# assign tags or translations to each profile
+declare -A tags
+tags=(
+ [performance]="Performance"
+ [balanced]="Balanced"
+ [power-saver]="Power saver"
+)
+
+# Get current profile
+current_profile=$(/usr/bin/powerprofilesctl get)
+
+# Get tag from the array
+profile_tag=${tags[$current_profile]}
+
+# Show tag on i3block
+echo "${profile_tag:-$current_profile}"
diff --git a/i3/scripts/temperature b/i3/scripts/temperature
new file mode 100755
index 0000000..69dcc63
--- /dev/null
+++ b/i3/scripts/temperature
@@ -0,0 +1,75 @@
+#!/usr/bin/env perl
+
+# Copyright 2014 Pierre Mavro
+# Copyright 2014 Vivien Didelot
+# Copyright 2014 Andreas Guldstrand
+# Copyright 2014 Benjamin Chretien
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Edited by Andreas Lindlbauer
+
+use strict;
+use warnings;
+use utf8;
+use Getopt::Long;
+
+binmode(STDOUT, ":utf8");
+
+# default values
+my $t_warn = $ENV{T_WARN} || 70;
+my $t_crit = $ENV{T_CRIT} || 90;
+my $chip = $ENV{SENSOR_CHIP} || "";
+my $temperature = -9999;
+my $label = "😀 ";
+
+sub help {
+ print "Usage: temperature [-w ] [-c ] [--chip ]\n";
+ print "-w : warning threshold to become yellow\n";
+ print "-c : critical threshold to become red\n";
+ print "--chip : sensor chip\n";
+ exit 0;
+}
+
+GetOptions("help|h" => \&help,
+ "w=i" => \$t_warn,
+ "c=i" => \$t_crit,
+ "chip=s" => \$chip);
+
+# Get chip temperature
+open (SENSORS, "sensors -u $chip |") or die;
+while () {
+ if (/^\s+temp1_input:\s+[\+]*([\-]*\d+\.\d)/) {
+ $temperature = $1;
+ last;
+ }
+}
+close(SENSORS);
+
+$temperature eq -9999 and die 'Cannot find temperature';
+
+if ($temperature < 45) {
+ $label = '';
+} elsif ($temperature < 55) {
+ $label = '';
+} elsif ($temperature < 65) {
+ $label = '';
+} elsif ($temperature < 75) {
+ $label = '';
+} else {
+ $label = '';
+}
+# Print short_text, full_text
+print "${label}";
+print " $temperature°C\n";
+print "${label}";
+print " $temperature°C\n";
+
+# Print color, if needed
+if ($temperature >= $t_crit) {
+ print "#FF0000\n";
+ exit 33;
+} elsif ($temperature >= $t_warn) {
+ print "#FFFC00\n";
+}
+
+exit 0;
diff --git a/i3/scripts/volume b/i3/scripts/volume
new file mode 100755
index 0000000..97f2693
--- /dev/null
+++ b/i3/scripts/volume
@@ -0,0 +1,46 @@
+#!/usr/bin/env bash
+# i3blocks volume block for PipeWire (PulseAudio compatible)
+
+STEP=${1:-5%}
+
+# Default sink
+SINK=$(pactl info | awk '/Default Sink/ {print $3}')
+[[ -z "$SINK" ]] && { echo "No audio"; exit 0; }
+
+# Handle scroll/middle-click
+case "$BLOCK_BUTTON" in
+ 3) pactl set-sink-mute "$SINK" toggle ;; # right click = mute/unmute
+ 4) pactl set-sink-volume "$SINK" +$STEP ;; # scroll up
+ 5) pactl set-sink-volume "$SINK" -$STEP ;; # scroll down
+esac
+
+# Get current volume (front-left channel)
+VOL=$(pactl list sinks | awk -v s="$SINK" '
+ $0 ~ "Name: " s {found=1}
+ found && /Volume:/ {gsub("%","",$5); print $5; exit}
+')
+
+# Get mute state
+MUTED=$(pactl list sinks | awk -v s="$SINK" '
+ $0 ~ "Name: " s {found=1}
+ found && /Mute:/ {print $2; exit}
+')
+
+# Choose symbol
+AUDIO_HIGH=''
+AUDIO_MED=''
+AUDIO_LOW=''
+AUDIO_MUTED=''
+MED_THRESH=50
+LOW_THRESH=0
+
+if [[ "$MUTED" == "no" ]]; then
+ SYMB=$AUDIO_HIGH
+ [[ $VOL -le $MED_THRESH ]] && SYMB=$AUDIO_MED
+ [[ $VOL -le $LOW_THRESH ]] && SYMB=$AUDIO_LOW
+else
+ SYMB=$AUDIO_MUTED
+fi
+
+# Single-line output for i3blocks
+echo "${SYMB} ${VOL}%"
diff --git a/i3/scripts/volume_brightness.sh b/i3/scripts/volume_brightness.sh
new file mode 100755
index 0000000..676c6d3
--- /dev/null
+++ b/i3/scripts/volume_brightness.sh
@@ -0,0 +1,95 @@
+#!/usr/bin/env bash
+
+# original source: https://gitlab.com/Nmoleo/i3-volume-brightness-indicator
+# changed to use brightnessctl [xbacklight is non functional on modern hardware]
+# by joekamprad [Aug 2025]
+
+bar_color="#7f7fff"
+volume_step=1
+brightness_step=5
+max_volume=100
+notification_timeout=1000 # in ms
+
+# Uses regex to get volume from pactl
+function get_volume {
+ pactl get-sink-volume @DEFAULT_SINK@ | grep -Po '[0-9]{1,3}(?=%)' | head -1
+}
+
+# Uses regex to get mute status from pactl
+function get_mute {
+ pactl get-sink-mute @DEFAULT_SINK@ | grep -Po '(?<=Mute: )(yes|no)'
+}
+
+# Uses brightnessctl instead of xbacklight
+function get_brightness {
+ brightnessctl g | awk '{print int($1)}'
+ # You could also use: brightnessctl info | grep -Po '(?<=Current brightness: )[0-9]+'
+}
+
+# Calculates brightness percentage
+function get_brightness_percent {
+ current=$(brightnessctl g)
+ max=$(brightnessctl m)
+ percent=$(( 100 * current / max ))
+ echo $percent
+}
+
+function get_volume_icon {
+ volume=$(get_volume)
+ mute=$(get_mute)
+ if [ "$volume" -eq 0 ] || [ "$mute" == "yes" ] ; then
+ volume_icon=""
+ elif [ "$volume" -lt 50 ]; then
+ volume_icon=""
+ else
+ volume_icon=""
+ fi
+}
+
+function get_brightness_icon {
+ brightness_icon=""
+}
+
+function show_volume_notif {
+ volume=$(get_volume)
+ get_volume_icon
+ notify-send -i volume_icon -t 1000 "Volume" "$volume_icon $volume%" -h int:value:$volume -h string:x-canonical-private-synchronous:volume
+}
+
+
+function show_brightness_notif {
+ get_brightness_icon
+ brightness=$(get_brightness_percent)
+ notify-send -i brightness_icon -t $notification_timeout -h string:x-dunst-stack-tag:brightness_notif -h int:value:$brightness "$brightness_icon $brightness%"
+}
+
+
+
+case $1 in
+ volume_up)
+ pactl set-sink-mute @DEFAULT_SINK@ 0
+ volume=$(get_volume)
+ if [ $(( "$volume" + "$volume_step" )) -gt $max_volume ]; then
+ pactl set-sink-volume @DEFAULT_SINK@ $max_volume%
+ else
+ pactl set-sink-volume @DEFAULT_SINK@ +$volume_step%
+ fi
+ show_volume_notif
+ ;;
+ volume_down)
+ pactl set-sink-volume @DEFAULT_SINK@ -$volume_step%
+ show_volume_notif
+ ;;
+ volume_mute)
+ pactl set-sink-mute @DEFAULT_SINK@ toggle
+ show_volume_notif
+ ;;
+ brightness_up)
+ brightnessctl s +$brightness_step% > /dev/null
+ show_brightness_notif
+ ;;
+ brightness_down)
+ brightnessctl s $brightness_step%- > /dev/null
+ show_brightness_notif
+ ;;
+esac
diff --git a/i3/scripts/volume_brightness2.sh b/i3/scripts/volume_brightness2.sh
new file mode 100755
index 0000000..cd78d77
--- /dev/null
+++ b/i3/scripts/volume_brightness2.sh
@@ -0,0 +1,168 @@
+#!/usr/bin/env bash
+
+# original source: https://gitlab.com/Nmoleo/i3-volume-brightness-indicator
+# alternative to volume_brightness.sh that uses brightnessctl for both keyboard & screen brightness
+
+# See README.md for usage instructions
+volume_step=1
+keyboard_brightness_step=20
+screen_brightness_step=1
+max_volume=100
+notification_timeout=1000
+
+# Specify Icon Theme here:
+volume_theme_icon="audio-volume-high"
+screen_brightness_theme_icon="display-brightness"
+keyboard_brightness_theme_icon="display-brightness"
+
+# Keyboard Backlight device detection here:
+device_cache="/tmp/kbd_backlight_device"
+
+if [ -f "$device_cache" ]; then
+ # If there is cache, load it into device
+ device=$(cat "$device_cache")
+else
+ # If there is no cache, create one
+ device=$(brightnessctl --list | grep -Po '\w+::kbd_backlight')
+ echo "$device" > "$device_cache"
+fi
+
+# Uses regex to get volume from pactl
+function get_volume {
+ pactl get-sink-volume @DEFAULT_SINK@ | grep -Po '[0-9]{1,3}(?=%)' | head -1
+}
+
+# Uses regex to get mute status from pactl
+function get_mute {
+ pactl get-sink-mute @DEFAULT_SINK@ | grep -Po '(?<=Mute: )(yes|no)'
+}
+
+# Get keyboard_brightness from brightnessctl
+function get_keyboard_brightness {
+ if [ -n "$device" ]; then
+ keyboard_curr=$(brightnessctl -d "$device" get)
+ keyboard_max=$(brightnessctl -d "$device" max)
+ echo $(( keyboard_curr * 100 / keyboard_max))
+ fi
+}
+
+
+# Grabs screen brightness and formats it out of 100
+function get_screen_brightness {
+ screen_curr=$(brightnessctl -q get)
+ screen_max=$(brightnessctl -q max)
+ echo $(( screen_curr * 100 / screen_max ))
+}
+
+# Returns a mute icon, a volume-low icon, or a volume-high icon, depending on the volume
+function get_volume_icon {
+ volume=$(get_volume)
+ mute=$(get_mute)
+ if [ "$volume" -eq 0 ] || [ "$mute" == "yes" ] ; then
+ volume_icon=""
+ elif [ "$volume" -lt 50 ] ; then
+ volume_icon=""
+ else
+ volume_icon=""
+ fi
+}
+
+# Always returns the same icon - I couldn't get the brightness-low icon to work with fontawesome
+function get_keyboard_brightness_icon {
+ kb_brightness=$(get_keyboard_brightness)
+ if [ "$kb_brightness" -eq 0 ] ; then
+ keyboard_brightness_icon="" # unfilled circle
+ elif [ "$kb_brightness" -lt 50 ] ; then
+ keyboard_brightness_icon="" # fa-adjust (low brightness)
+ else
+ keyboard_brightness_icon="" # full circle (high brightness)
+ fi
+}
+
+function get_screen_brightness_icon {
+ sc_brightness=$(get_screen_brightness)
+ if [ "$sc_brightness" -eq 0 ] ; then
+ screen_brightness_icon="" # unfilled circle
+ elif [ "$sc_brightness" -lt 50 ] ; then
+ screen_brightness_icon="" # fa-adjust (low brightness)
+ else
+ screen_brightness_icon="" # full circle (high brightness)
+ fi
+}
+
+# Displays a volume notification using notify-send
+function show_volume_notif {
+ mute=$(get_mute)
+ volume=$(get_volume)
+ get_volume_icon
+ notify-send -i $volume_theme_icon -t $notification_timeout "Volume" "$volume_icon $volume%" -h int:value:$volume -h string:x-canonical-private-synchronous:volume
+}
+
+# Displays a keyboard_brightness notification
+function show_keyboard_brightness_notif {
+ keyboard_brightness=$(get_keyboard_brightness)
+ # Debug Purposes:
+ # echo $keyboard_brightness
+ get_keyboard_brightness_icon
+ notify-send -i $keyboard_brightness_theme_icon -t $notification_timeout "Keyboard Brightness" -h string:x-dunst-stack-tag:keyboard_brightness_notif -h int:value:$keyboard_brightness "$keyboard_brightness_icon $keyboard_brightness%"
+}
+
+# Displays a screen_brightness notification
+function show_screen_brightness_notif {
+ screen_brightness=$(get_screen_brightness)
+ # Debug Purposes:
+ # echo $screen_brightness
+ get_screen_brightness_icon
+ notify-send -i $screen_brightness_theme_icon -t $notification_timeout "Screen Brightness" -h string:x-dunst-stack-tag:screen_brightness_notif -h int:value:$screen_brightness "$screen_brightness_icon $screen_brightness%"
+}
+
+# Main function - Takes user input, "volume_up", "volume_down", "keyboard_brightness_up", "keyboard_brightness_down", "brightness_up", or "brightness_down"
+case $1 in
+ volume_up)
+ # Unmutes and increases volume, then displays the notification
+ pactl set-sink-mute @DEFAULT_SINK@ 0
+ volume=$(get_volume)
+ if [ $(( "$volume" + "$volume_step" )) -gt $max_volume ]; then
+ pactl set-sink-volume @DEFAULT_SINK@ $max_volume%
+ else
+ pactl set-sink-volume @DEFAULT_SINK@ +$volume_step%
+ fi
+ show_volume_notif
+ ;;
+
+ volume_down)
+ # Raises volume and displays the notification
+ pactl set-sink-volume @DEFAULT_SINK@ -$volume_step%
+ show_volume_notif
+ ;;
+
+ volume_mute)
+ # Toggles mute and displays the notification
+ pactl set-sink-mute @DEFAULT_SINK@ toggle
+ show_volume_notif
+ ;;
+
+ keyboard_brightness_up)
+ # Increases keyboard brightness and displays the notification
+ brightnessctl -d "$device" set ${keyboard_brightness_step}+
+ show_keyboard_brightness_notif
+ ;;
+
+ keyboard_brightness_down)
+ # Decreases keyboard brightness and displays the notification
+ brightnessctl -d "$device" set ${keyboard_brightness_step}-
+ show_keyboard_brightness_notif
+ ;;
+
+ screen_brightness_up)
+ # Increases screen brightness and displays the notification
+ brightnessctl -q set ${screen_brightness_step}%+
+ show_screen_brightness_notif
+ ;;
+
+ screen_brightness_down)
+ # Decreases screen brightness and displays the notification
+ brightnessctl -q set ${screen_brightness_step}%-
+ show_screen_brightness_notif
+ ;;
+esac
diff --git a/i3/scripts/vpn b/i3/scripts/vpn
new file mode 100755
index 0000000..bcf54ee
--- /dev/null
+++ b/i3/scripts/vpn
@@ -0,0 +1,25 @@
+#!/usr/bin/env sh
+
+# Parses output from nmcli to show the current connected VPN name/status for i3block
+# Source: https://github.com/vivien/i3blocks-contrib/tree/master/nm-vpn
+# uncomment in $HOME/.config/i3/i3blocks.conf if you want to use it
+
+init_color=${init_color:-#FFFF00}
+on_color=${on_color:-#00FF00}
+export init_color on_color
+nmcli -t connection show --active | awk -F ':' '
+BEGIN {
+ init_color=ENVIRON["init_color"]
+ on_color=ENVIRON["on_color"]
+}
+$3=="vpn" {
+ name=$1
+ status="INIT"
+ color=init_color
+}
+$3=="tun" || ($4~/^tap/ || $3~/^tap/) {
+ if(!name) name=$1
+ status="ON"
+ color=on_color
+}
+END {if(status) printf("%s\n%s\n%s\n", name, status, color)}'
diff --git a/polybar/config.ini b/polybar/config.ini
old mode 100644
new mode 100755
index ddb2256..13eaf9c
--- a/polybar/config.ini
+++ b/polybar/config.ini
@@ -18,13 +18,13 @@
[colors]
background-alt = #00000000
-foreground = A3D1C6
-primary = #B3D8A8
-altprime = #B3D8A8
-secondary = #FBFFE4
-altsecondary = #BEABA7EF
-alert = #A54242
-disabled = FBFFE4
+foreground = #1A2533
+primary = #2D6A8A
+altprime = #2D6A8A
+secondary = #0D1B27
+altsecondary = #3A7CA5EF
+alert = #A52020
+disabled = #4A6878
[bar/example]
bottom = false
@@ -34,10 +34,11 @@ radius = 8
; dpi = 96
-background = #1B4D3E
+background = #00000000
foreground = ${colors.foreground}
tray-position = right
+tray-background = #C8D8E8
line-size = 2pt
border-size = 0