Lots of small updates related to move to Alpine linux
M .config/i3/config +10 -19
@@ 19,7 19,8 @@ set $term --no-startup-id st
 
 # Font for window titles. Will also be used by the bar unless a different font
 # is used in the bar {} block below.
-font pango:monospace 14
+#font pango:monospace 14
+font pango:DejaVu Sans Mono 14
 
 # This font is widely installed, provides lots of unicode glyphs, right-to-left
 # text rendering and scalability on retina/hidpi displays (thanks to pango).

          
@@ 66,7 67,7 @@ set $transparent		#00000000
 
 
 bar {
-	font pango:Source Sans Pro-10 12
+	font pango:DejaVu Sans Mono 12
 	colors {
 		background		$darkblack
 		statusline		$darkwhite

          
@@ 84,12 85,6 @@ bar {
 }
 
 
-#SYSTEMD
-set $shutdown sudo shutdown -h now
-set $reboot sudo reboot
-set $netrefresh --no-startup-id sudo systemctl restart NetworkManager
-set $hibernate sudo systemctl suspend
-
 # Use Mouse+$mod to drag floating windows to their wanted position
 floating_modifier $mod
 

          
@@ 271,10 266,8 @@ bindsym $mod+Shift+g mode "$mode_gaps"
 # lock screen
 bindsym $mod+x			exec --no-startup-id betterlockscreen --lock
 
-# Shutdown, reboot, exit i3
-bindsym $mod+Shift+x		exec --no-startup-id prompt "Are you sure you want to shutdown?" "$shutdown"
-bindsym $mod+Shift+BackSpace	exec --no-startup-id prompt "Are you sure you want to reboot?" "$reboot"
-bindsym $mod+Shift+Escape 	exec --no-startup-id prompt "Are you sure you want to leave i3?" "i3-msg exit"
+# exit i3
+bindsym $mod+Shift+Escape 	exit
 
 # Previous workspace
 bindsym $mod+Tab		workspace back_and_forth

          
@@ 315,7 308,6 @@ bindsym $mod+Shift+o		exec --no-startup-
 # Screenshot stuff
 
 # take a screenshot of a screen region and copy it to a clipboard
-bindsym --release Shift+Print exec --no-startup-id scregcp -s /home/pjs/Downloads/
 bindsym --release $mod+Shift+backslash exec --no-startup-id scregcp -s /home/pjs/Downloads/
 # take a screenshot of a whole window and copy it to a clipboard
 bindsym --release Print exec --no-startup-id scregcp /home/pjs/Dropbox/Screenshots/

          
@@ 333,9 325,9 @@ for_window [instance="keepassxc"] floati
 #for_window [instance="surf" title=".*\sWhatsApp$"] floating enable, resize set 1245 673, move scratchpad, border pixel 5
 
 # Telegram
-bindsym $mod+Shift+t [class="TelegramDesktop" instance="Telegram" title=".*$"] scratchpad show, move position center
-for_window [class="TelegramDesktop" instance="Telegram" title=".*$"] floating enable, resize set 1545 873, move scratchpad, border pixel 5
-for_window [class="Telegram" instance="Telegram" title="Choose file.*$"] floating enable
+bindsym $mod+Shift+t [class="TelegramDesktop" instance="telegram-desktop" title=".*$"] scratchpad show, move position center
+for_window [class="TelegramDesktop" instance="telegram-desktop" title=".*$"] floating enable, resize set 1545 873, move scratchpad, border pixel 5
+for_window [class="TelegramDesktop" instance="telegram-desktop" title="Choose Files"] floating enable
 
 # Specific window configs
 for_window [instance="Blueman-manager"] floating enable

          
@@ 345,10 337,9 @@ exec --no-startup-id dunst
 exec --no-startup-id nm-applet
 exec --no-startup-id blueman-applet
 exec --no-startup-id compton --xrender-sync-fence
-exec --no-startup-id dropbox.py start
+exec --no-startup-id maestral start
 exec --no-startup-id $term -n dropdown
 exec --no-startup-id keepassxc
-#exec --no-startup-id surf -S https://web.whatsapp.com
-exec --no-startup-id Telegram
+exec --no-startup-id telegram-desktop
 exec --no-startup-id mpd
 exec --no-startup-id i3mpdupdate

          
M .config/i3blocks/config +6 -4
@@ 12,7 12,8 @@ color=#d70a53
 
 
 [weather]
-command=i3weather2.sh "90703"
+#command=i3weather2.sh "90703"
+command=i3weather3
 interval=3600
 color=#e97ac8
 

          
@@ 41,6 42,7 @@ color=#d70a53
 markup=pango
 
 [load_average]
+command=i3load_average
 label=
 interval=10
 color=#6c71c4

          
@@ 48,12 50,12 @@ color=#6c71c4
 [iface]
 label=
 command=i3iface
-instance=enp0s31f6
+instance=eth0
 interval=10
 
 [wifi]
 #label=
-instance=wlp2s0
+instance=wlan0
 command=i3wifi
 color=#d33682
 interval=10

          
@@ 66,6 68,6 @@ interval=5
 
 [time]
 label=
-command=i3time.sh
+command=i3time
 interval=5
 color=#50C878

          
M .hgrc +5 -1
@@ 4,6 4,7 @@ editor = vim -c "r ~/.hgtemplate"
 ssh = ssh -C
 merge = internal:merge
 tweakdefaults = True
+color = never
 
 [extensions]
 hgext.graphlog =

          
@@ 15,6 16,7 @@ purge =
 shelve = 
 patchbomb =
 histedit = 
+evolve =
 #hggit = /Users/pjs/src/hg-git/hggit
 
 [alias]

          
@@ 27,6 29,7 @@ show = log --stat --pager=always -pr
 nudge = push --rev .
 ball = !$HG branches; $HG bookmarks
 pull = pull --rebase
+describe = log -r . -T "{latesttag}{sub('^-0-.*', '', '-{latesttagdistance}-m{node|short}')}\n"
 
 [diff]
 git = 1

          
@@ 42,7 45,8 @@ method = /usr/local/bin/msmtp
 from = Peter Sanchez <pjs@petersanchez.com>
 
 [patchbomb]
-intro = never
+#intro = never
+intro = always
 confirm = true
 
 [git]

          
M .localbashrc +3 -7
@@ 2,14 2,14 @@ OSTYPE=`uname -s`
 if [ "$OSTYPE" == "FreeBSD" ]; then
   alias ls='ls -F'
 else
-  alias ls='ls -F --quoting-style=literal'
+  alias ls='ls -F --color=none'
 fi
 
 alias stelnet='openssl s_client -connect '
 
 # Mutt / IMAP
-alias mutt='cd ~/Downloads && /usr/local/bin/neomutt && pkill -RTMIN+12 i3blocks'
-alias matterhorn='cd ~/Downloads && matterhorn'
+alias mutt='cd ~/Downloads && /usr/bin/neomutt && pkill -RTMIN+12 i3blocks'
+alias matterhorn='cd ~/Downloads && ~/src/matterhorn/matterhorn'
 
 # Helpers
 alias pscom='ssh -A base.netlandish.com'

          
@@ 58,10 58,6 @@ export GOTOOLCHAIN=path
 # https://sourcehut.org/blog/2023-01-09-gomodulemirror/
 export GOPRIVATE=git.sr.ht
 
-# XXX Remove once the bug below is fixed:
-# https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1876219
-export MESA_LOADER_DRIVER_OVERRIDE=i965
-
 export PATH="$HOME/bin:$HOME/.local/bin:$GOBIN:$HOME/.gem/ruby/2.5.0/bin:/home/pjs/src/google-cloud-sdk/bin:$HOME/.nvm/versions/node/v13.5.0/bin:$PATH"
 
 export NVM_DIR="$HOME/.nvm"

          
M .profile +8 -0
@@ 61,6 61,14 @@ else
     VESTR=""
 fi
 
+if test -z "${XDG_RUNTIME_DIR}"; then
+  export XDG_RUNTIME_DIR=/tmp/$(id -u)-runtime-dir
+  if ! test -d "${XDG_RUNTIME_DIR}"; then
+    mkdir "${XDG_RUNTIME_DIR}"
+    chmod 0700 "${XDG_RUNTIME_DIR}"
+  fi
+fi
+
 alias activate="source ./env/bin/activate"
 
 # Helpers

          
M README.md +1 -6
@@ 5,11 5,6 @@ 
 This config is obviously forever under construction but I finally have my setup
 to a place where I feel comfortable working day to day.
 
-Quick background: I haven't run a Linux workstation in about 15 years. So
-coming back and toying with all the config options has been fun. However, I'm
-sure there are much better ways to do some of the things I'm doing.  Please
-don't be shy with the tips and pointers :)
-
 ## Notes
 
 I believe I've included all relevant config files, scripts and images to mirror

          
@@ 18,7 13,7 @@ my setup. However, there are a few thing
 - I run i3-gaps w/ i3blocks and i3lock-color.
 - I have my own version of [suckless terminal][st] (st) with just a few patches
   applied. You can [see my copy here][pst]
-- The OS is currently Ubuntu 20.04, though this shouldn't matter.
+- The OS is currently Alpine Linux 3.18, though this shouldn't matter.
 - See `.config/apps_to_build.md` for a list of applications that I built
   manually
 - **Specifically i3-gaps and i3lock-color. Things will not work without these**

          
M bin/betterlockscreen +914 -304
@@ 1,364 1,974 @@ 
 #!/usr/bin/env bash
 
-# Author : Pavan Jadhaw
-# Github Profile : https://github.com/pavanjadhaw
-# Project Repository : https://github.com/pavanjadhaw/betterlockscreen
-
-# find your resolution so images can be resized to match your screen resolution
-res=$(xdpyinfo | grep dimensions | sed -r 's/^[^0-9]*([0-9]+x[0-9]+).*$/\1/')
-
-init_filenames() {
-	#$1 resolution
-
-	# create folder in ~/.cache/i3lock directory
-	res_folder="$HOME/.cache/i3lock/$1"
-	folder="$HOME/.cache/i3lock/current"
-        echo "Got" $@ $res_folder
-	if [ ! -d  $folder -o -n "$2" ]
-	then
-	    rm $folder
-	    ln -s $res_folder $folder
-	fi
+# Author : Copyright (c) 2017-2022 Pavan Jadhaw, and others (https://github.com/betterlockscreen/betterlockscreen/graphs/contributors)
+# Project Repository : https://github.com/betterlockscreen/betterlockscreen
 
-	# ratio for rectangle to be drawn for time background on lockscreen
-	# Original Image
-	orig_wall="$folder/wall.png"
-
-	# Versions (from here)
-	# You can use these images to set different versions as wallpaper
-	# lockscreen background.
-	resized="$folder/resized.png" # resized image for your resolution
-
-	# images to be used as wallpaper
-	dim="$folder/dim.png" # image with subtle overlay of black
-	blur="$folder/blur.png" # blurred version
-	dimblur="$folder/dimblur.png"
-
-	# lockscreen images (images to be used as lockscreen background)
-	l_resized="$folder/l_resized.png"
-	l_dim="$folder/l_dim.png"
-	l_blur="$folder/l_blur.png"
-	l_dimblur="$folder/l_dimblur.png"
+cmd_exists () {
+    command -v "$1" >/dev/null
 }
 
-init_filenames $res
+init_config () {
+
+    # default options
+    display_on=0
+    span_image=false
+    lock_timeout=300
+    fx_list=(dim blur dimblur pixel dimpixel color)
+    dim_level=40
+    blur_level=1
+    pixel_scale=10,1000
+    solid_color=333333
+    description=""
+    quiet=false
+    i3lockcolor_bin="i3lock-color"
+
+    if ! cmd_exists "$i3lockcolor_bin" && cmd_exists "i3lock"; then
+        i3lockcolor_bin="i3lock"
+    fi
+
+    # default theme
+    loginbox=00000066
+    loginshadow=00000000
+    locktext="Type password to unlock..."
+    font="sans-serif"
+    ringcolor=ffffffff
+    insidecolor=00000000
+    separatorcolor=00000000
+    ringvercolor=ffffffff
+    insidevercolor=00000000
+    ringwrongcolor=ffffffff
+    insidewrongcolor=d23c3dff
+    timecolor=ffffffff
+    time_format="%H:%M:%S"
+    greetercolor=ffffffff
+    layoutcolor=ffffffff
+    keyhlcolor=d23c3dff
+    bshlcolor=d23c3dff
+    verifcolor=ffffffff
+    wrongcolor=d23c3dff
+    modifcolor=d23c3dff
+    bgcolor=000000ff
+    wallpaper_cmd="feh --bg-fill"
+    time_format="%H:%M:%S"
 
+    # read user config
+    USER_CONF="${XDG_CONFIG_HOME:-$HOME/.config}/betterlockscreenrc"
+    if [ -e "$USER_CONF" ]; then
+        # shellcheck source=/dev/null
+        source "$USER_CONF"
+    fi
+
+    if ! cmd_exists "$i3lockcolor_bin"; then
+        echof error "Unable to find i3lock-color binary under detected/configured name: '$i3lockcolor_bin'!"
+        exit
+    fi
+
+    # Please make sure to adjust this before release!
+    VERSION="4.0.4"
+
+    # paths
+    CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/betterlockscreen"
+    CUR_DIR="$CACHE_DIR/current"
+
+    # wallpaper
+    CUR_W_RESIZE="$CUR_DIR/wall_resize.png"
+    CUR_W_DIM="$CUR_DIR/wall_dim.png"
+    CUR_W_BLUR="$CUR_DIR/wall_blur.png"
+    CUR_W_DIMBLUR="$CUR_DIR/wall_dimblur.png"
+    CUR_W_PIXEL="$CUR_DIR/wall_pixel.png"
+    CUR_W_DIMPIXEL="$CUR_DIR/wall_dimpixel.png"
+    CUR_W_COLOR="$CUR_DIR/wall_color.png"
+
+    # lockscreen
+    CUR_L_RESIZE="$CUR_DIR/lock_resize.png"
+    CUR_L_DIM="$CUR_DIR/lock_dim.png"
+    CUR_L_BLUR="$CUR_DIR/lock_blur.png"
+    CUR_L_DIMBLUR="$CUR_DIR/lock_dimblur.png"
+    CUR_L_PIXEL="$CUR_DIR/lock_pixel.png"
+    CUR_L_DIMPIXEL="$CUR_DIR/lock_dimpixel.png"
+    CUR_L_COLOR="$CUR_DIR/lock_color.png"
+
+    # Original DPMS timeout
+    DEFAULT_TIMEOUT=$(cut -d ' ' -f4 <<< "$(xset q | sed -n '25p')")
+    # Original DPMS status
+    DEFAULT_DPMS=$(xset q | awk '/^[[:blank:]]*DPMS is/ {print $(NF)}')
+
+    # Dunst
+    DUNST_INSTALLED=false && [[ -e "$(command -v dunstctl)" ]] && DUNST_INSTALLED=true
+    DUNST_IS_PAUSED=false && [[ "$DUNST_INSTALLED" == "true" ]] && DUNST_IS_PAUSED=$(dunstctl is-paused)
+
+    # Feh
+    FEH_INSTALLED=false && [[ -e "$(command -v feh)" ]] && FEH_INSTALLED=true
+}
+
+# called before screen is locked
 prelock() {
-    if [ ! -z "$(pidof dunst)" ] ; then
-        pkill -u "$USER" -USR1 dunst
+
+    # set dpms timeout
+    if [ "$DEFAULT_DPMS" == "Enabled" ]; then
+        xset dpms "$lock_timeout"
+    fi
+
+    # If dusnt is already paused don't pause it again
+    if [[ "$DUNST_INSTALLED" == "true" && "$DUNST_IS_PAUSED" == "false" ]]; then
+        dunstctl set-paused true
+    fi
+
+    if [[ "$runsuspend" = "true" ]]; then
+        lockargs="$lockargs -n"
     fi
 }
 
+# lock screen with specified image
 lock() {
-	#$1 image path
-	letterEnteredColor=d23c3dff
-	letterRemovedColor=d23c3dff
-	passwordCorrect=00000000
-	passwordIncorrect=d23c3dff
-	background=00000000
-	foreground=ffffffff
-	timeout="10000"
-	i3lock \
-		-t -i "$1" \
-		--timepos="x+110:h-70" \
-		--datepos="x+135:h-45" \
-		--clock --datestr "Type password to unlock..." \
-		--insidecolor=$background --ringcolor=$foreground --line-uses-inside \
-		--keyhlcolor=$letterEnteredColor --bshlcolor=$letterRemovedColor --separatorcolor=$background \
-		--insidevercolor=$passwordCorrect --insidewrongcolor=$passwordIncorrect \
-		--ringvercolor=$foreground --ringwrongcolor=$foreground --indpos="x+280:h-70" \
-		--radius=20 --ring-width=4 --veriftext="" --wrongtext="" \
-		--verifcolor="$foreground" --timecolor="$foreground" --datecolor="$foreground" \
-		--noinputtext="" --force-clock $lockargs
+
+    echof act "Locking screen..."
+
+    local image="$1"
+    local fontlg=32
+    local fontmd=16
+    local fontsm=12
+
+    $i3lockcolor_bin \
+        --image "$image" \
+        --color "$bgcolor" \
+        --screen "$display_on" \
+        --ind-pos="x+310:y+h-80" \
+        --radius=25 \
+        --ring-width=5 \
+        --inside-color="$insidecolor" \
+        --ring-color="$ringcolor" \
+        --separator-color=$separatorcolor \
+        --insidever-color="$insidevercolor" \
+        --insidewrong-color="$insidewrongcolor" \
+        --ringver-color="$ringvercolor" \
+        --ringwrong-color="$ringwrongcolor" \
+        --line-uses-inside \
+        --keyhl-color="$keyhlcolor" \
+        --bshl-color="$bshlcolor" \
+        --clock --force-clock \
+        --time-pos="ix-265:iy-10" \
+        --time-align 1 \
+        --time-str "$time_format" \
+        --time-color="$timecolor" \
+        --time-font="$font" \
+        --time-size="$fontlg" \
+        --date-str "" \
+        --greeter-pos="ix-265:iy+12" \
+        --greeter-align 1 \
+        --greeter-text "$locktext" \
+        --greeter-color="$greetercolor" \
+        --greeter-font="$font" \
+        --greeter-size="$fontmd" \
+        --layout-pos="ix-265:iy+32" \
+        --layout-align 1 \
+        --layout-color="$layoutcolor" \
+        --layout-font="$font" \
+        --layout-size="$fontsm" \
+        --keylayout "${keylayout:-0}" \
+        --verif-pos="ix+35:iy-34" \
+        --verif-align 2 \
+        --verif-text="Verifying..." \
+        --verif-color="$verifcolor" \
+        --verif-font="$font" \
+        --verif-size="$fontsm" \
+        --wrong-pos="ix+24:iy-34" \
+        --wrong-align 2 \
+        --wrong-text="Failure!" \
+        --wrong-color="$wrongcolor" \
+        --wrong-font="$font" \
+        --wrong-size="$fontsm" \
+        --modif-pos="ix+45:iy+43" \
+        --modif-align 2 \
+        --modif-size="$fontsm" \
+        --modif-color="$modifcolor" \
+        --noinput-text="" \
+        --pass-media-keys \
+        --pass-screen-keys \
+        --pass-volume-keys \
+        --pass-power-keys \
+        "${lockargs[@]}"
 }
 
+# in case image isn't found
+failsafe() {
+
+    echof act "Locking screen... (FAILSAFE MODE)"
+
+    local fontlg=32
+    local fontmd=16
+    local fontsm=12
+
+    $i3lockcolor_bin \
+        --color "$bgcolor" \
+        --ind-pos="x+310:y+h-80" \
+        --radius=25 \
+        --ring-width=5 \
+        --inside-color="$insidecolor" \
+        --ring-color="$ringcolor" \
+        --separator-color=$separatorcolor \
+        --insidever-color="$insidevercolor" \
+        --insidewrong-color="$insidewrongcolor" \
+        --ringver-color="$ringvercolor" \
+        --ringwrong-color="$ringwrongcolor" \
+        --line-uses-inside \
+        --keyhl-color="$keyhlcolor" \
+        --bshl-color="$bshlcolor" \
+        --clock --force-clock \
+        --time-pos="ix-265:iy-10" \
+        --time-align 1 \
+        --time-str "$time_format" \
+        --time-color="$timecolor" \
+        --time-font="$font" \
+        --time-size="$fontlg" \
+        --date-str "" \
+        --greeter-pos="ix-265:iy+12" \
+        --greeter-align 1 \
+        --greeter-text "$locktext" \
+        --greeter-color="$greetercolor" \
+        --greeter-font="$font" \
+        --greeter-size="$fontmd" \
+        --layout-pos="ix-265:iy+32" \
+        --layout-align 1 \
+        --layout-color="$layoutcolor" \
+        --layout-font="$font" \
+        --layout-size="$fontsm" \
+        --keylayout "${keylayout:-0}" \
+        --verif-pos="ix+45:iy-35" \
+        --verif-align 2 \
+        --verif-text="Verifying..." \
+        --verif-color="$verifcolor" \
+        --verif-font="$font" \
+        --verif-size="$fontsm" \
+        --wrong-pos="ix+45:iy-35" \
+        --wrong-align 2 \
+        --wrong-text="Failure!" \
+        --wrong-color="$wrongcolor" \
+        --wrong-font="$font" \
+        --wrong-size="$fontsm" \
+        --modif-pos="ix+45:iy+43" \
+        --modif-align 2 \
+        --modif-size="$fontsm" \
+        --modif-color="$modifcolor" \
+        --noinput-text="" \
+        --pass-media-keys \
+        --pass-screen-keys \
+        --pass-volume-keys \
+        --pass-power-keys
+}
+
+
+# called after screen is unlocked
 postlock() {
-    if [ ! -z "$(pidof dunst)" ] ; then
-        pkill -u "$USER" -USR2 dunst
+
+    # restore default dpms timeout
+    if [ "$DEFAULT_DPMS" == "Enabled" ]; then
+        xset dpms "$DEFAULT_TIMEOUT"
+    fi
+
+    # If dunst already paused before locking don't unpause dunst
+    if [[ "$DUNST_INSTALLED" == "true" && "$DUNST_IS_PAUSED" == "false" ]]; then
+        dunstctl set-paused false
     fi
     sleep 5 && [[ 4000 -lt $(xssstate -i) ]] && pgrep -x i3lock && xset dpms force off
 }
 
-rec_get_random() {
-	dir="$1"
-	if [ ! -d "$dir" ]; then
-		user_input="$dir"
-		return
-	fi
-	dir=($dir/*)
-	dir=${dir[RANDOM % ${#dir[@]}]}
-	rec_get_random "$dir"
+
+# select effect and lock screen
+lockselect() {
+
+    echof act "Running prelock..."
+    prelock
+
+    case "$1" in
+        dim) if [ -f "$CUR_L_DIM" ]; then lock "$CUR_L_DIM"; else failsafe; fi ;;
+        blur) if [ -f "$CUR_L_BLUR" ]; then lock "$CUR_L_BLUR"; else failsafe; fi ;;
+        dimblur) if [ -f "$CUR_L_DIMBLUR" ]; then lock "$CUR_L_DIMBLUR"; else failsafe; fi ;;
+        pixel) if [ -f "$CUR_L_PIXEL" ]; then lock "$CUR_L_PIXEL"; else failsafe; fi ;;
+        dimpixel) if [ -f "$CUR_L_DIMPIXEL" ]; then lock "$CUR_L_DIMPIXEL"; else failsafe; fi ;;
+        color) if [ -f "$CUR_L_COLOR" ]; then lock "$CUR_L_COLOR"; else failsafe; fi ;;
+        *) if [ -f "$CUR_L_RESIZE" ]; then lock "$CUR_L_RESIZE"; else failsafe; fi ;;
+    esac
+
+    echof act "Running postlock..."
+    postlock
+}
+
+# calculate adjustments for hidpi displays
+logical_px() {
+
+    # $1: number of pixels to convert
+    # $2: 1 for width. 2 for height
+    local pixels="$1"
+    local direction="$2"
+    local dpi
+
+    # use DPI set by user in .Xresources
+    dpi=$(xrdb -q | grep -oP '^\s*Xft.dpi:\s*\K\d+' | bc)
+
+    # or get dpi value from xdpyinfo
+    if [ -z "$dpi" ]; then
+        dpi=$(xdpyinfo | sed -En "s/\s*resolution:\s*([0-9]*)x([0-9]*)\s.*/\\$direction/p" | head -n1)
+    fi
+
+    # adjust scaling
+    if [ -n "$dpi" ]; then
+        local scale
+        scale=$(echo "scale=3; $dpi / 96.0" | bc)
+        echo "$scale * $pixels / 1" | bc
+    else
+        # return the default value if no DPI is set
+        echo "$pixels"
+    fi
+}
+
+# get total resolution, sets $TOTAL_SIZE
+get_total_size () {
+    TOTAL_SIZE=$(xdpyinfo | grep -w "dimensions" | sed -r 's/^[^0-9]*([0-9]+x[0-9]+).*$/\1/')
 }
 
-lockselect() {
-	case "$1" in
-		"")
-			# default lockscreen
-			prelock
-			lock "$l_resized" && $2
-			postlock
-			;;
+# get list of displays, sets $DISPLAY_LIST
+get_display_list () {
+    local count=0
+    mapfile -t displays < <(xrandr --listactivemonitors)
+    for display in "${displays[@]:1}"; do
+        ((count++))
+        display="$(echo "$display" | sed -r 's/\/[0-9]*//g')"
+        IFS=' ' read -r -a info  <<< "$display"
+        DISPLAY_LIST+=("$count ${info[3]} ${info[2]}")
+    done
+}
+
+# populate $WALL_LIST depending on number of displays and images passed
+get_wall_list() {
+
+    local paths=("$@")
+    declare -ga WALL_LIST
+
+    # multiple images and spanning conflict, bail out
+    if [ "${#paths[@]}" -gt 1 ] && [ "$span_image" = true ]; then
+        echof err "Can't use --span with multiple images!"
+        exit 1
+    fi
+
+    # if spanning return 1 image
+    if [ "$span_image" = true ]; then
+        get_image "${paths[0]}"
+
+    # if # paths is 1
+    elif [ "${#paths[@]}" -eq 1 ]; then
+        for ((i=0; i<${#DISPLAY_LIST[@]}; i++)); do
+            # add same image to $WALL_LIST for each display
+            get_image "${paths[0]}"
+        done
 
-		dim)
-			# lockscreen with dimmed background
-			prelock
-			lock "$l_dim" && $2
-			postlock
-			;;
+    # if # of paths equals # of displays
+    elif [ ${#paths[@]} -eq "${#DISPLAY_LIST[@]}" ]; then
+        for ((i=0; i<${#DISPLAY_LIST[@]}; i++)); do
+            # add each image to $WALL_LIST
+            get_image "${paths[$i]}"
+        done
+
+    # if # of paths differ from # of display, bail out
+    else
+        echof err "${#paths[@]} images provided for ${#DISPLAY_LIST[@]} displays!"
+        exit 1
+    fi
+}
+
+# get image path, append to $WALL_LIST
+get_image() {
 
-		blur)
-			# set lockscreen with blurred background
-			prelock
-			lock "$l_blur" && $2
-			postlock
-			;;
+    local path="$1"
 
-		dimblur)
-			# set lockscreen with dimmed + blurred background
-			prelock
-			lock "$l_dimblur" && $2
-			postlock
-			;;
-	esac
+    # we have a file
+    if [ -f "$path" ]; then
+        WALL_LIST+=("$path")
+        return
+    # we have a directory
+    elif [ -d "$path" ]; then
+        dir=("$path"/*)
+        rdir="${dir[RANDOM % ${#dir[@]}]}"
+        get_image "$rdir" # <-- calls itself
+    # not file or directory, bail out
+    else
+        echof err "invalid path: $path"
+        exit 1
+    fi
+
 }
 
-usage() {
+# scale base image and generate effects
+resize_and_render () {
+
+    local base="$1"
+    local path="$2"
+    local resolution="$3"
+
+    # resource paths
+    RES_RESIZE="$path/resize.png"
+    RES_DIM="$path/dim.png"
+    RES_BLUR="$path/blur.png"
+    RES_DIMBLUR="$path/dimblur.png"
+    RES_PIXEL="$path/pixel.png"
+    RES_DIMPIXEL="$path/dimpixel.png"
+    RES_COLOR="$path/color.png"
+
+    # resize
+    base_resize "$base" "$RES_RESIZE" "$resolution"
+
+    # effects
+    for effect in "${fx_list[@]}"; do
+        case $effect in
+            dim) fx_dim "$RES_RESIZE" "$RES_DIM";;
+            blur) fx_blur "$RES_RESIZE" "$RES_BLUR" "$resolution";;
+            dimblur) fx_dimblur "$RES_RESIZE" "$RES_DIMBLUR" "$resolution";;
+            pixel) fx_pixel "$RES_RESIZE" "$RES_PIXEL";;
+            dimpixel) fx_dimpixel "$RES_RESIZE" "$RES_DIMPIXEL";;
+            color) fx_color "$RES_COLOR" "$resolution";;
+        esac
+    done
+
+}
+
+# apply resize
+base_resize() {
+
+    local input="$1"
+    local output="$2"
+    local size="$3"
 
-		echo "Important: Update the image cache (e.g. betterlockscreen -u path/to/image.jpg)."
-		echo "	Image cache must be updated to initially configure or update wallpaper used"
-		echo
-		echo
-		echo "See: https://github.com/pavanjadhaw/betterlockscreen for additional info..."
-		echo
-		echo
-		echo "Options:"
-		echo
-		echo "	-h --help"
+    echof act "Resizing base image..."
+    eval convert "$input" \
+        -resize "$size""^" \
+        -gravity center \
+        -extent "$size" \
+        "$output"
+}
+
+# apply dim
+fx_dim() {
+    local input="$1"
+    local output="$2"
+
+    echof act "Rendering 'dim' effect..."
+    eval convert "$input" \
+        -fill black -colorize "$dim_level"% \
+        "$output"
+}
+
+# apply blur
+fx_blur() {
+    local input="$1"
+    local output="$2"
+    local size="$3"
+
+    echof act "Rendering 'blur' effect..."
+    blur_shrink=$(echo "scale=2; 20 / $blur_level" | bc)
+    blur_sigma=$(echo "scale=2; 0.6 * $blur_level" | bc)
+    eval convert "$input" \
+        -filter Gaussian \
+        -resize "$blur_shrink%" \
+        -define "filter:sigma=$blur_sigma" \
+        -resize "$size^" -gravity center -extent "$size" \
+        "$output"
+}
+
+# apply dimblur
+fx_dimblur() {
+    local input="$1"
+    local output="$2"
+    local size="$3"
 
-		echo "		For help (e.g. betterlockscreen -h or betterlockscreen --help)."
-		echo
-		echo
-		echo "	-u --update"
-		echo "		to update image cache, you should do this before using any other options"
-		echo "		E.g: betterlockscreen -u path/to/image.png when image.png is custom background"
-		echo "		Or you can use betterlockscreen -u path/to/imagedir and a random file will be selected."
-		echo
-		echo
-		echo "	-l --lock"
-		echo "		to lock screen (e.g. betterlockscreen -l)"
-		echo "		you can also use dimmed or blurred background for lockscreen."
-		echo "		E.g: betterlockscreen -l dim (for dimmed background)"
-		echo "		E.g: betterlockscreen -l blur (for blurred background)"
-		echo "		E.g: betterlockscreen -l dimblur (for dimmed + blurred background)"
-		echo
-		echo
-		echo "	-s --suspend"
-		echo "		to suspend system and lock screen (e.g. betterlockscreen -s)"
-		echo "		you can also use dimmed or blurred background for lockscreen."
-		echo "		E.g: betterlockscreen -s dim (for dimmed background)"
-		echo "		E.g: betterlockscreen -s blur (for blurred background)"
-		echo "		E.g: betterlockscreen -s dimblur (for dimmed + blurred background)"
-		echo
-		echo
-		echo "	-w --wall"
-		echo "		you can also set lockscreen background as wallpaper"
-		echo "		to set wallpaper (e.g. betterlockscreen -w or betterlockscreen --wall)"
-		echo "		you can also use dimmed or blurred variants."
-		echo "		E.g: betterlockscreen -w dim (for dimmed wallpaper)"
-		echo "		E.g: betterlockscreen -w blur (for blurred wallpaper)"
-		echo "		E.g: betterlockscreen -w dimblur (for dimmed + blurred wallpaper)"
-		echo
-		echo
-		echo "	-r --resolution"
-		echo "		to be used after -u"
-		echo "		used to set a custom resolution for the image cache."
-		echo "		E.g: betterlockscreen -u path/to/image.png -r 1920x1080"
-		echo "		E.g: betterlockscreen -u path/to/image.png --resolution 3840x1080"
-		echo
-		echo
-		echo "	-b --blur"
-		echo "		to be used after -u"
-		echo "		used to set blur intensity. Default to 1."
-		echo "		E.g: betterlockscreen -u path/to/image.png -b 3"
-		echo "		E.g: betterlockscreen -u path/to/image.png --blur 0.5"
+    echof act "Rendering 'dimblur' effect..."
+    blur_shrink=$(echo "scale=2; 20 / $blur_level" | bc)
+    blur_sigma=$(echo "scale=2; 0.6 * $blur_level" | bc)
+    eval convert "$input" \
+        -fill black -colorize "$dim_level"% \
+        -filter Gaussian \
+        -resize "$blur_shrink%" \
+        -define "filter:sigma=$blur_sigma" \
+        -resize "$size^" -gravity center -extent "$size" \
+        "$output"
+}
+
+# pixelate
+fx_pixel() {
+    local input="$1"
+    local output="$2"
+
+    echof act "Rendering 'pixel' effect..."
+    IFS=',' read -ra range <<< "$pixel_scale"
+    eval convert "$input" \
+        -scale "${range[0]}"% -scale "${range[1]}"% \
+        "$output"
+}
+
+# apply dimpixel
+fx_dimpixel() {
+    local input="$1"
+    local output="$2"
+
+    echof act "Rendering 'dimpixel' effect..."
+    IFS=',' read -ra range <<< "$pixel_scale"
+    eval convert "$input" \
+        -fill black -colorize "$dim_level"% \
+        -scale "${range[0]}"% -scale "${range[1]}"% \
+        "$output"
+}
+
+# create solid color
+fx_color() {
+    local output="$1"
+    local size="$2"
+
+    echof act "Rendering 'color' effect..."
+    eval convert -size "$size" canvas:\#"$solid_color" "$RES_COLOR"
+}
+
+# create loginbox rectangle, set "$RECTANGLE"
+create_loginbox () {
+    RECTANGLE="$CUR_DIR/rectangle.png"
+    local shadow="$CUR_DIR/shadow.png"
+    local width height
+    width=$(logical_px 340 1)
+    height=$(logical_px 100 2)
+    convert -size "$width"x"$height" xc:\#"$loginbox" -fill none "$RECTANGLE"
+    convert "$RECTANGLE" \
+        \( -clone 0 -background \#"$loginshadow" -shadow 100x5+0+0 \) +swap \
+        -background none -layers merge +repage "$shadow"
+    composite -compose Dst_Out -gravity center \
+        "$RECTANGLE" "$shadow" -alpha Set "$shadow"
+    convert "$shadow" "$RECTANGLE" -geometry +10+10 -composite "$RECTANGLE"
+    [[ "$shadow" ]] && rm "$shadow"
+}
+
+# create rectangle with description, set "$DESCRECT"
+create_description () {
+    DESCRECT="$CUR_DIR/description.png"
+    local shadow="$CUR_DIR/shadow.png"
+    convert -background none -family "$(fc-match "$font" family)" -style Normal -pointsize 14 -fill \#"$greetercolor" label:"\ $description\ " -bordercolor \#"$loginbox" -border 10 "$DESCRECT"
+    convert "$DESCRECT" \
+        \( -clone 0 -background \#"$loginshadow" -shadow 100x5+0+0 \) +swap \
+        -background none -layers merge +repage "$shadow"
+    composite -compose Dst_Out -gravity center \
+        "$DESCRECT" "$shadow" -alpha Set "$shadow"
+    convert "$shadow" "$DESCRECT" -geometry +10+10 -composite "$DESCRECT"
+    [[ "$shadow" ]] && rm "$shadow"
+}
+
+# delete and recreate directory
+purge_cache () {
+    if [[ -d "$1" ]]; then
+        rm -r "$1"
+    fi
+    mkdir -p "$1"
 }
 
-# Options
-case "$1" in
-	"")
-		if [ ! -f $l_dim ]; then
-			echo "Important: Update the image cache (e.g. betterlockscreen -u path/to/image.jpg)."
-			echo
-			echo "		Image cache must be updated to initially configure or update wallpaper used"
-			echo
-			echo "See also: For other set of options and help use help command."
-			echo "E.g. betterlockscreen -h or betterlockscreen --help"
+# update lockscreen and wallpaper images
+update () {
+
+    local images=("$@")
+
+    echof act "Updating image cache..."
+    mkdir -p "$CACHE_DIR" &>/dev/null
+
+    get_display_list # DISPLAY_LIST
+    get_total_size # TOTAL_SIZE
+    echof info "Detected ${#DISPLAY_LIST[@]} display(s) @ $TOTAL_SIZE total resolution"
+
+    get_wall_list "${images[@]}" # WALL_LIST
+    echof info "Original image(s): ${WALL_LIST[*]##*/}"
+
+    # Prepare description box to obtain width for positioning
+    local descwidth
+    local descheight
+    if [ -z "$description" ]; then
+        descwidth=0
+        descheight=0
+    else
+        create_description
+        descwidth=$(identify -format "%[fx:w]" "$DESCRECT")
+        descheight=$(identify -format "%[fx:h]" "$DESCRECT")
+    fi
+
+    for ((i=0; i<${#DISPLAY_LIST[@]}; i++)); do
+        display="${DISPLAY_LIST[$i]}"
+        USER_WALL="${WALL_LIST[$i]}"
+
+        # escape spaces for IM
+        if echo "$USER_WALL" | grep -E -q "[[:space:]]"; then
+            USER_WALL="${USER_WALL// /\\ }"
+        fi
+
+        IFS=' ' read -r -a dinfo  <<< "$display"
+        local id="${dinfo[0]}"
+        local device="${dinfo[1]}"
+        local geometry="${dinfo[2]}"
+
+        read -r -a cols <<< "${geometry//[x+-]/ }"
+        local position="${geometry#*"${cols[1]}"}"
+        local resolution="${geometry%"${position}"*}"
+
+        if [[ $id -eq "$display_on" ]] || [[ "$display_on" -eq 0 ]]; then
 
-			echo
-			echo "See: https://github.com/pavanjadhaw/betterlockscreen for addition info..."
-			exit 1
-		else
-			echo
-			echo "Seems you havent provided any argument, see below for usage info"
-			echo
-			echo "See also: For other set of options and help use help command."
+            IFS='x' read -r -a dimension <<< "$resolution"
+            res_x="${dimension[0]}"
+            res_y="${dimension[1]}"
+            read -r -a val <<< "${position//[+-]/ }"
+            read -r -a sym <<< "${position//[0-9]/ }"
+            pos_x="${sym[0]}${val[0]}"
+            pos_y="${sym[1]}${val[1]}"
 
-			echo "E.g. betterlockscreen -h or betterlockscreen --help"
+            rect_x=$((pos_x + $(logical_px 15 1)))
+            rect_y=$((pos_y + res_y - $(logical_px 140 2)))
+            positions+=("+$((rect_x))+$((rect_y))")
+
+            descrect_x=$((pos_x + res_x - descwidth - $(logical_px 15 1)))
+            descrect_y=$((pos_y + res_y - descheight - $(logical_px 20 2)))
+            positions_desc+=("+$((descrect_x))+$((descrect_y))")
+        fi
+
+        local path="$CACHE_DIR/$id-$device"
+        purge_cache "$path"
 
-			echo
-			echo "See: https://github.com/pavanjadhaw/betterlockscreen for addition info..."
-			echo
-			exit 1
-		fi
-		;;
+        if [ "$span_image" = true ]; then
+            if [ "$id" -gt 1 ]; then
+                continue
+            else
+                device="[span]"
+                id="*"
+                resolution="$TOTAL_SIZE"
+            fi
+        fi
+
+        echof info "Processing display: $device ($id)"
+        echof info "Resolution: $resolution"
 
-	-h | --help)
+        if [ "$span_image" = true ]; then
+            resize_and_render "$USER_WALL" "$path" "$resolution"
+        else
+            resize_and_render "$USER_WALL" "$path" "$resolution"
 
-	usage
-		;;
+            PARAM_RESIZE="$PARAM_RESIZE $RES_RESIZE -geometry $position -composite "
+            PARAM_DIM="$PARAM_DIM $RES_DIM -geometry $position -composite "
+            PARAM_BLUR="$PARAM_BLUR $RES_BLUR -geometry $position -composite "
+            PARAM_DIMBLUR="$PARAM_DIMBLUR $RES_DIMBLUR -geometry $position -composite "
+            PARAM_PIXEL="$PARAM_PIXEL $RES_PIXEL -geometry $position -composite "
+            PARAM_DIMPIXEL="$PARAM_DIMPIXEL $RES_DIMPIXEL -geometry $position -composite "
+            PARAM_COLOR="$PARAM_COLOR $RES_COLOR -geometry $position -composite "
+        fi
+
+    done
+
+    purge_cache "$CUR_DIR"
 
-	-l | --lock)
-		lockargs="-e"
-		lockselect "$2"
-		;;
+    if [ "$span_image" = true ] || [ ${#DISPLAY_LIST[@]} -lt 2 ]; then
+        echof act "Rendering final wallpaper images..."
+        [[ -f "$RES_RESIZE" ]] && eval "cp $RES_RESIZE $CUR_W_RESIZE"
+        [[ -f "$RES_DIM" ]] && eval "cp $RES_DIM $CUR_W_DIM"
+        [[ -f "$RES_BLUR" ]] && eval "cp $RES_BLUR $CUR_W_BLUR"
+        [[ -f "$RES_DIMBLUR" ]] && eval "cp $RES_DIMBLUR $CUR_W_DIMBLUR"
+        [[ -f "$RES_PIXEL" ]] && eval "cp $RES_PIXEL $CUR_W_PIXEL"
+        [[ -f "$RES_DIMPIXEL" ]] && eval "cp $RES_DIMPIXEL $CUR_W_DIMPIXEL"
+        [[ -f "$RES_COLOR" ]] && eval "cp $RES_COLOR $CUR_W_COLOR"
+    else
+        echof act "Creating canvas: $TOTAL_SIZE"
+        [[ -f "$RES_RESIZE" ]] && eval "convert -size $TOTAL_SIZE 'xc:blue' $CUR_W_RESIZE"
+        [[ -f "$RES_DIM" ]] && eval "convert -size $TOTAL_SIZE 'xc:blue' $CUR_W_DIM"
+        [[ -f "$RES_BLUR" ]] && eval "convert -size $TOTAL_SIZE 'xc:blue' $CUR_W_BLUR"
+        [[ -f "$RES_DIMBLUR" ]] && eval "convert -size $TOTAL_SIZE 'xc:blue' $CUR_W_DIMBLUR"
+        [[ -f "$RES_PIXEL" ]] && eval "convert -size $TOTAL_SIZE 'xc:blue' $CUR_W_PIXEL"
+        [[ -f "$RES_DIMPIXEL" ]] && eval "convert -size $TOTAL_SIZE 'xc:blue' $CUR_W_DIMPIXEL"
+        [[ -f "$RES_COLOR" ]] && eval "convert -size $TOTAL_SIZE 'xc:blue' $CUR_W_COLOR"
 
-	-s | --suspend)
-		lockselect "$2" "systemctl suspend"
-		;;
+        echof act "Rendering final wallpaper images..."
+        [[ -f "$CUR_W_RESIZE" ]] && eval "convert $CUR_W_RESIZE $PARAM_RESIZE $CUR_W_RESIZE"
+        [[ -f "$CUR_W_DIM" ]] && eval "convert $CUR_W_DIM $PARAM_DIM $CUR_W_DIM"
+        [[ -f "$CUR_W_BLUR" ]] && eval "convert $CUR_W_BLUR $PARAM_BLUR $CUR_W_BLUR"
+        [[ -f "$CUR_W_DIMBLUR" ]] && eval "convert $CUR_W_DIMBLUR $PARAM_DIMBLUR $CUR_W_DIMBLUR"
+        [[ -f "$CUR_W_PIXEL" ]] && eval "convert $CUR_W_PIXEL $PARAM_PIXEL $CUR_W_PIXEL"
+        [[ -f "$CUR_W_DIMPIXEL" ]] && eval "convert $CUR_W_DIMPIXEL $PARAM_DIMPIXEL $CUR_W_DIMPIXEL"
+        [[ -f "$CUR_W_COLOR" ]] && eval "convert $CUR_W_COLOR $PARAM_COLOR $CUR_W_COLOR"
+    fi
+
+    echof act "Rendering final lockscreen images..."
 
-	-w | --wall)
-		case "$2" in
-			"")
-				# set resized image as wallpaper if no argument is supplied by user
-				feh --bg-fill $resized
-				;;
+    create_loginbox
+    for pos in "${positions[@]}"; do
+        PARAM_RECT="$PARAM_RECT $RECTANGLE -geometry $pos -composite "
+    done
+
+    if [ -n "$description" ]; then
+        create_description
+        for descpos in "${positions_desc[@]}"; do
+            PARAM_RECT="$PARAM_RECT $DESCRECT -geometry $descpos -composite "
+        done
+    fi
 
-			dim)
-				# set dimmed image as wallpaper
-				feh --bg-fill $dim
-				;;
+    [[ -f "$CUR_W_RESIZE" ]] && eval "convert $CUR_W_RESIZE $PARAM_RECT $CUR_L_RESIZE"
+    [[ -f "$CUR_W_DIM" ]] && eval "convert $CUR_W_DIM $PARAM_RECT $CUR_L_DIM"
+    [[ -f "$CUR_W_BLUR" ]] && eval "convert $CUR_W_BLUR $PARAM_RECT $CUR_L_BLUR"
+    [[ -f "$CUR_W_DIMBLUR" ]] && eval "convert $CUR_W_DIMBLUR $PARAM_RECT $CUR_L_DIMBLUR"
+    [[ -f "$CUR_W_PIXEL" ]] && eval "convert $CUR_W_PIXEL $PARAM_RECT $CUR_L_PIXEL"
+    [[ -f "$CUR_W_DIMPIXEL" ]] && eval "convert $CUR_W_DIMPIXEL $PARAM_RECT $CUR_L_DIMPIXEL"
+    [[ -f "$CUR_W_COLOR" ]] && eval "convert $CUR_W_COLOR $PARAM_RECT $CUR_L_COLOR"
+
+    [[ "$RECTANGLE" ]] && rm "$RECTANGLE"
+    [[ "$DESCRECT" ]] && rm "$DESCRECT"
+
+    echof ok "Done"
 
-			blur)
-				# set blurred image as wallpaper
-				feh --bg-fill $blur
-				;;
+}
+
+# set wallpaper with effect
+wallpaper() {
+
+    local effect="$1"
+
+    # make wallpaper span displays
+    get_display_list
+    if [ "$span_image" = true ] || [[ "${#DISPLAY_LIST[@]}" -gt 1 ]]; then
+        wallpaper_cmd="$wallpaper_cmd --no-xinerama"
+    fi
 
-			dimblur)
-				# set dimmed + blurred image as wallpaper
-				feh --bg-fill $dimblur
-				;;
-		esac
-		;;
+    # set wallpaper
+    case "$effect" in
+        dim) wallpaper="$CUR_W_DIM";;
+        blur) wallpaper="$CUR_W_BLUR";;
+        dimblur) wallpaper="$CUR_W_DIMBLUR";;
+        pixel) wallpaper="$CUR_W_PIXEL";;
+        dimpixel) wallpaper="$CUR_W_DIMPIXEL";;
+        color) wallpaper="$CUR_W_COLOR";;
+        *) wallpaper="$CUR_W_RESIZE";;
+    esac
+    eval "$wallpaper_cmd $wallpaper"
+}
 
-	-u | --update)
-		background="$2"
-		shift 2
+# wrap echo with fancy prefix
+echof() {
+
+    local prefix="$1"
+    local message="$2"
 
-		# default blur level
-		blur_level=1
+    case "$prefix" in
+        header) msgpfx="[\e[1;95mB\e[m]";;
+        info) msgpfx="[\e[1;97m=\e[m]";;
+        act) msgpfx="[\e[1;92m*\e[m]";;
+        ok) msgpfx="[\e[1;93m+\e[m]";;
+        error) msgpfx="[\e[1;91m!\e[m]";;
+        *) msgpfx="";;
+    esac
+    [ "$quiet" != true ] && echo -e "$msgpfx $message"
+}
 
-		# parse update arguments
-		while [ $# -gt 0 ]; do
-			case "$1" in
-			-r | --resolution )
-				res="$2"
-				init_filenames $res force
-				shift 2
-				;;
-			-b | --blur )
-				blur_level="$2"
-				shift 2
-				;;
-			*)
-				shift ;;
-			esac
-		done
-
-		rectangles=" "
-		SR=$(xrandr --query | grep ' connected' | grep -o '[0-9][0-9]*x[0-9][0-9]*[^ ]*')
-		for RES in $SR; do
-			SRA=(${RES//[x+]/ })
-			CX=$((${SRA[2]} + 25))
-			CY=$((${SRA[1]} - 30))
-			rectangles+="rectangle $CX,$CY $((CX+300)),$((CY-80)) "
-		done
+# help message
+usage() {
+    echo
+    echo "Usage: betterlockscreen [-u <PATH>] [-l <EFFECT>] [-w <EFFECT>]"
+    echo
+    echo "  -q --quiet"
+    echo "      Do not produce any text output on locking"
+    echo
+    echo "  -u --update <PATH>"
+    echo "      Update lock screen image"
+    echo
+    echo "  -l --lock <EFFECT>"
+    echo "      Lock screen with cached image"
+    echo
+    echo "  -w --wall <EFFECT>"
+    echo "      Set wallpaper with cached image"
+    echo
+    echo "Additional arguments:"
+    echo
+    echo "  --display <N>"
+    echo "      Set display to draw loginbox"
+    echo
+    echo "  --span"
+    echo "      Scale image to span multiple displays"
+    echo
+    echo "  --off <N>"
+    echo "      Turn display off after N seconds"
+    echo
+    echo "  --fx <EFFECT,EFFECT,EFFECT>"
+    echo "      List of effects to generate"
+    echo
+    echo "  --desc <DESCRIPTION>"
+    echo "      Set a description for the new lock screen image"
+    echo "      (Only has an effect in combination with --update)"
+    echo
+    echo "  --show-layout"
+    echo "      Show current keyboard layout"
+    echo
+    echo "  --wallpaper-cmd <command>"
+    echo "      to set your custom wallpaper setter"
+    echo
+    echo "  --time-format <format>"
+    echo "      to set the time format used by i3lock-color"
+    echo
+    echo "  -- <ARGS>"
+    echo "      Pass additional arguments to i3lock"
+    echo
+    echo "Effects arguments:"
+    echo
+    echo "  --dim <N>"
+    echo "      Dim image N percent (0-100)"
+    echo
+    echo "  --blur <N>"
+    echo "      Blur image N amount (0.0-1.0)"
+    echo
+    echo "  --pixel <N,N>"
+    echo "      Pixelate image with N shrink and N grow (unsupported)"
+    echo
+    echo "  --color <HEX>"
+    echo "      Solid color background with HEX"
+    echo
+    exit 1
+}
 
-		# User supplied Image
-		user_image="$folder/user_image.png"
+init_config
+
+# show usage when no arguments passed
+[[ "$1" = "" ]] && usage
 
-		# create folder
-		if [ ! -d $folder ]; then
-			echo "Creating '$folder' directory to cache processed images."
-			mkdir -p "$folder"
-		fi
+# process arguments
+lockargs=()
+for arg in "$@"; do
+    [[ "${arg:0:1}" = '-' ]] || continue
 
-		# get random file in dir if passed argument is a dir
-		rec_get_random "$background"
+    case "$1" in
+
+        -q | --quiet)
+            quiet=true
+            shift
+            ;;
 
-		# get user image
-		cp "$user_input" "$user_image"
-		if [ ! -f $user_image ]; then
-			echo "Please specify the path to the image you would like to use"
-			exit 1
-		fi
+        -u | --update)
+            runupdate=true
+            imagepaths+=("$2")
+            shift 2
+            ;;
+
+        -s | --suspend)
+            runsuspend=true
+            ;&
 
-		# replace orignal with user image
-		cp "$user_image" "$orig_wall"
-		rm "$user_image"
+        -l | --lock)
+            runlock=true
+            if [[ ${2:0:1} = '-' ]]; then
+                shift 1
+            else
+                lockstyle="$2"; shift 2
+            fi
+            ;;
 
-		echo "Generating alternate images based on the image you specified,"
-		echo "please wait this might take few seconds..."
+        -w | --wall)
+            wallpaper "$2"
+            shift 2
+            ;;
 
-		# wallpapers
+        --wallpaper-cmd)
+            wallpaper_cmd="$2"
+            shift 2
+            ;;
+
+        --time-format)
+            time_format="$2"
+            shift 2
+            ;;
 
-		echo
-		echo "Converting provided image to match your resolution..."
-		# resize image
-		convert "$orig_wall" -resize "$res""^" -gravity center -extent "$res" "$resized"
+        --display)
+            display_on="$2"
+            shift 2
+            ;;
+
+        --span)
+            span_image=true
+            shift 1
+            ;;
+
+        --off)
+            lock_timeout="$2"
+            shift 2
+            ;;
 
-		echo
-		echo "Applying dim and blur effect to resized image"
-		# dim
-		convert "$resized" -fill black -colorize 40% "$dim"
+        --text)
+            locktext="$2"
+            shift 2
+            ;;
+
+        --show-layout)
+            keylayout="$2";
+            shift 2
+            ;;
 
-		# blur
-		blur_shrink=$(echo "scale=2; 20 / $blur_level" | bc)
-		blur_sigma=$(echo "scale=2; 0.6 * $blur_level" | bc)
-		convert "$resized" \
-			-filter Gaussian \
-			-resize "$blur_shrink%" \
-			-define "filter:sigma=$blur_sigma" \
-			-resize "$res^" -gravity center -extent "$res" \
-			"$blur"
+        --fx)
+            IFS=',' read -ra fx_list <<< "$2"
+            shift 2
+            ;;
+
+        --dim)
+            dim_level="$2"
+            shift 2
+            ;;
+
+        --blur)
+            blur_level="$2"
+            shift 2
+            ;;
 
-		# dimblur
-		convert "$dim" \
-			-filter Gaussian \
-			-resize "$blur_shrink%" \
-			-define "filter:sigma=$blur_sigma" \
-			-resize "$res^" -gravity center -extent "$res" \
-			"$dimblur"
+        --pixel)
+            pixel_scale="$2"
+            shift 2
+            ;;
+
+        --color)
+            solid_color="${2//\#/}"
+            shift 2
+            ;;
 
-		# lockscreen backgrounds
+        --desc)
+            description="$2"
+            shift 2
+            ;;
 
-		echo
-		echo "Caching images for faster screen locking"
-		# resized
-	convert "$resized" -draw "fill rgba(0, 0, 0, 0.4) $rectangles" "$l_resized"
+        -v | --version)
+            echo
+            echo "Betterlockscreen: version: v$VERSION (dunst: $DUNST_INSTALLED, feh: $FEH_INSTALLED)"
+            $i3lockcolor_bin --version
+            convert --version
+
+            if [[ "$DUNST_INSTALLED" == "true" ]]; then
+                dunstctl debug
+            fi
 
-		# dim
-		convert "$dim" -draw "fill rgba(0, 0, 0, 0.4) $rectangles" "$l_dim"
+            if [[ "$FEH_INSTALLED" == "true" ]]; then
+                feh --version
+            fi
 
-		# blur
-		convert "$blur" -draw "fill rgba(0, 0, 0, 0.4) $rectangles" "$l_blur"
+            break
+            ;;
+
+        --)
+            lockargs+=("${@:2}")
+            break
+            ;;
 
-		# blur
-		convert "$dimblur" -draw "fill rgba(0, 0, 0, 0.4) $rectangles" "$l_dimblur"
-		echo
-		echo "All required changes have been applied"
-		;;
+        -h | --help | *)
+            usage
+            break
+            ;;
+    esac
+done
+
+echof header "Betterlockscreen"
 
-	*)
-		echo "invalid argument"
-		;;
-esac
+# Run image generation
+[[ $runupdate ]] && update "${imagepaths[@]}"
+
+# Activate lockscreen
+[[ $runsuspend ]] || lockargs+=(-n)
+[[ $runlock ]] && lockselect "$lockstyle" && \
+    { [[ $runsuspend ]] && systemctl suspend; }
+
+exit 0

          
M bin/enable_natural_scroll +13 -1
@@ 7,7 7,7 @@ synclient VertScrollDelta=-113
 synclient MaxTapTime=0
 
 
-MX=$(xinput list --id-only 'pointer:MX Master')
+MX=$(xinput list --id-only 'pointer:MX Master Mouse')
 if [ -n "$MX" ]; then
     # Enable Natural scrolling. To get ID see:
     # xinput list-props $MX (ie, 20)

          
@@ 17,4 17,16 @@ if [ -n "$MX" ]; then
         MXID=$(echo $GSTR | sed -e 's/.*(//' -e 's/).*//')
         xinput set-prop $MX $MXID 1
     fi
+else
+    MX=$(xinput list --id-only 'pointer:Logitech MX Master')
+    if [ -n "$MX" ]; then
+        # Enable Natural scrolling. To get ID see:
+        # xinput list-props $MX (ie, 20)
+        GSTR=$(xinput list-props $MX | grep "libinput Natural Scrolling Enabled (")
+        MXV=$(echo $GSTR | cut -d: -f2 | sed -e 's/ //g')
+        if [ "$MXV" = "0" ]; then
+            MXID=$(echo $GSTR | sed -e 's/.*(//' -e 's/).*//')
+            xinput set-prop $MX $MXID 1
+        fi
+    fi
 fi

          
M bin/sync_contacts.sh +1 -1
@@ 3,7 3,7 @@ 
 
 runfetchflag="/home/pjs/.nofetchcontacts"
 imapserver="imap.gmail.com"
-sync_cmd="/usr/local/bin/vdirsyncer sync"
+sync_cmd="/usr/bin/vdirsyncer sync"
 
 # Don't run fetch?
 if [ -f $runfetchflag ]; then

          
M bin/syncmail.sh +5 -5
@@ 4,7 4,7 @@ 
 
 runfetchflag="/home/pjs/.nofetchimap"
 imapserver="mail.netlandish.com"
-mailsync="/usr/local/bin/mbsync -q PeterPS PeterNL PeterIM"
+mailsync="/usr/bin/mbsync -q PeterPS PeterIM PeterNL-inbox"
 updatesearch="/usr/bin/notmuch new"
 
 # Don't run fetch?

          
@@ 28,13 28,13 @@ case $netactive in
     echo  > ~/.config/.maildl
     pkill -RTMIN+12 i3blocks
     $mailsync
-    if [ $? -ne 0 ]
+    if [ $? -eq 0 ]
     then
-      echo "ERROR" > ~/.config/.maildl
+      $updatesearch
+      cat /dev/null > ~/.config/.maildl
       pkill -RTMIN+12 i3blocks
     else 
-      $updatesearch
-      cat /dev/null > ~/.config/.maildl
+      echo "ERROR $?" > ~/.config/.maildl
       pkill -RTMIN+12 i3blocks
     fi
 ;;

          
M irssi/config +59 -32
@@ 1,30 1,36 @@ 
 servers = (
   {
-    address = "chat.freenode.net";
-    chatnet = "freenode";
-    port = "6697";
-    use_ssl = "yes";
-    ssl_verify = "yes";
-    ssl_cert = "~/.irssi/freenode/cert.pem";
-    ssl_pkey = "~/.irssi/freenode/key.pem";
-    autoconnect = "yes";
-  },
-  {
     address = "irc.colosolutions.net";
     chatnet = "efnet";
     port = "9999";
     use_ssl = "yes";
     ssl_verify = "no";
     autoconnect = "yes";
+  },
+  {
+    address = "irc.libera.chat";
+    chatnet = "libera";
+    port = "6697";
+    use_tls = "yes";
+    tls_cert = "~/.irssi/libera/libera.pem";
+    tls_verify = "no";
+    autoconnect = "yes";
+  },
+  {
+    address = "irc.oftc.net";
+    chatnet = "oftc";
+    port = "6697";
+    use_tls = "yes";
+    tls_cert = "~/.irssi/oftc/pjs.pem";
+    tls_verify = "yes";
+    autoconnect = "yes";
   }
 );
 
 chatnets = {
-  freenode = {
-    type = "IRC";
-    autosendcmd = "/^msg nickserv identify NOTREALPASSWD;wait 2000";
-  };
   efnet = { type = "IRC"; };
+  libera = { type = "IRC"; };
+  oftc = { type = "IRC"; };
 };
 
 aliases = {

          
@@ 283,16 289,26 @@ statusbar = {
 settings = {
   core = { real_name = "Peter Sanchez"; user_name = "pjs"; nick = "pjs"; };
   "fe-text" = { actlist_sort = "refnum"; };
-  "fe-common/core" = { theme = "more_readable"; };
+  "fe-common/core" = { 
+    theme = "more_readable";
+    use_status_window = "yes";
+  };
 };
 channels = (
-  { name = "#django"; chatnet = "freenode"; autojoin = "yes"; },
-  { name = "#mercurial"; chatnet = "freenode"; autojoin = "yes"; },
-  { name = "#i3"; chatnet = "freenode"; autojoin = "yes"; },
-  { name = "#ubuntu"; chatnet = "freenode"; autojoin = "yes"; },
-  { name = "#freebsd"; chatnet = "freenode"; autojoin = "yes"; },
-  { name = "#sr.ht"; chatnet = "freenode"; autojoin = "yes"; },
-  { name = "#postgresql"; chatnet = "freenode"; autojoin = "yes"; }
+  { name = "#django"; chatnet = "libera"; autojoin = "yes"; },
+  { name = "#mercurial"; chatnet = "libera"; autojoin = "yes"; },
+  { name = "#i3"; chatnet = "oftc"; autojoin = "yes"; },
+  { name = "#alpine-linux"; chatnet = "oftc"; autojoin = "yes"; },
+  { name = "#freebsd"; chatnet = "libera"; autojoin = "yes"; },
+  { name = "#sr.ht"; chatnet = "libera"; autojoin = "yes"; },
+  { name = "#postgresql"; chatnet = "libera"; autojoin = "yes"; },
+  { name = "#unixgods"; chatnet = "efnet"; autojoin = "yes"; },
+  { 
+    name = "#sr.ht.watercooler";
+    chatnet = "libera";
+    autojoin = "yes";
+  },
+  { name = "#go-nuts"; chatnet = "libera"; autojoin = "yes"; }
 );
 windows = {
   1 = { immortal = "yes"; name = "(status)"; level = "ALL"; };

          
@@ 302,7 318,7 @@ windows = {
         type = "CHANNEL";
         chat_type = "IRC";
         name = "#django";
-        tag = "freenode";
+        tag = "libera";
       }
     );
   };

          
@@ 312,17 328,17 @@ windows = {
         type = "CHANNEL";
         chat_type = "IRC";
         name = "#mercurial";
-        tag = "freenode";
+        tag = "libera";
       }
     );
   };
   4 = {
     items = (
-      {
+      { 
         type = "CHANNEL";
         chat_type = "IRC";
         name = "#i3";
-        tag = "freenode";
+        tag = "oftc";
       }
     );
   };

          
@@ 332,7 348,7 @@ windows = {
         type = "CHANNEL";
         chat_type = "IRC";
         name = "#ubuntu";
-        tag = "freenode";
+        tag = "libera";
       }
     );
   };

          
@@ 342,7 358,7 @@ windows = {
         type = "CHANNEL";
         chat_type = "IRC";
         name = "#freebsd";
-        tag = "freenode";
+        tag = "libera";
       }
     );
   };

          
@@ 352,7 368,7 @@ windows = {
         type = "CHANNEL";
         chat_type = "IRC";
         name = "#sr.ht";
-        tag = "freenode";
+        tag = "libera";
       }
     );
   };

          
@@ 362,7 378,7 @@ windows = {
         type = "CHANNEL";
         chat_type = "IRC";
         name = "#postgresql";
-        tag = "freenode";
+        tag = "libera";
       }
     );
   };

          
@@ 381,10 397,21 @@ windows = {
       {
         type = "CHANNEL";
         chat_type = "IRC";
-        name = "#millionaires";
-        tag = "efnet";
+        name = "#sr.ht.watercooler";
+        tag = "libera";
+      }
+    );
+  };
+  11 = {
+    items = (
+      {
+        type = "CHANNEL";
+        chat_type = "IRC";
+        name = "#go-nuts";
+        tag = "libera";
       }
     );
   };
 };
 mainwindows = { 1 = { first_line = "1"; lines = "37"; }; };
+ignores = ( { level = "JOINS PARTS QUITS"; } );

          
M mutt/muttrc +10 -10
@@ 166,7 166,7 @@ macro index,pager ,b "<shell-escape>pkil
 
 # Folder Hooks
 folder-hook 'pjs-petersanchez.com/*' 'source ~/.mutt/muttrc.pscom'
-folder-hook 'petersanchez-gmail.com/*' 'source ~/.mutt/muttrc.gmail'
+#folder-hook 'petersanchez-gmail.com/*' 'source ~/.mutt/muttrc.gmail'
 folder-hook 'peter-netlandish.com/*' 'source ~/.mutt/muttrc.netlandish'
 folder-hook 'peter-insightminers.com/*' 'source ~/.mutt/muttrc.insightminers'
 

          
@@ 175,7 175,7 @@ macro index <f2> '<change-folder>+pjs-pe
 macro index <f3> '<change-folder>+peter-netlandish.com/INBOX<enter>'
 macro index <f4> '<change-folder>+peter-insightminers.com/INBOX<enter>'
 macro index <f5> '<change-folder>+temporary/search<enter>'
-macro index <f6> '<change-folder>+petersanchez-gmail.com/INBOX<enter>'
+#macro index <f6> '<change-folder>+petersanchez-gmail.com/INBOX<enter>'
 
 # Sourcehut specific
 #macro compose A '<enter-command>my_hdr X-Sourcehut-Patchset-Update: APPLIED<enter>'

          
@@ 184,7 184,7 @@ macro index <f6> '<change-folder>+peters
 
 # GnuPG / PGP
 #set crypt_use_gpgme=yes
-set crypt_autosign=yes
+#set crypt_autosign=yes
 set crypt_verify_sig=yes
 set crypt_replysign=yes
 set crypt_replyencrypt=yes

          
@@ 275,13 275,13 @@ named-mailboxes	"Insight Miners" +peter-
 		"  Archive" +peter-insightminers.com/archive \
 		"  Sent" +peter-insightminers.com/sent
 
-named-mailboxes	"GMail" +petersanchez-gmail.com/INBOX \
-		"  Archive" +petersanchez-gmail.com/archive \
-		"  Sent" +petersanchez-gmail.com/sent \
-		"  Drafts" +petersanchez-gmail.com/drafts \
-		"  Todo" +petersanchez-gmail.com/todo \
-		"  Needs Reply" +petersanchez-gmail.com/needs_reply \
-		"  Travel" +petersanchez-gmail.com/Travel
+#named-mailboxes	"GMail" +petersanchez-gmail.com/INBOX \
+#		"  Archive" +petersanchez-gmail.com/archive \
+#		"  Sent" +petersanchez-gmail.com/sent \
+#		"  Drafts" +petersanchez-gmail.com/drafts \
+#		"  Todo" +petersanchez-gmail.com/todo \
+#		"  Needs Reply" +petersanchez-gmail.com/needs_reply \
+#		"  Travel" +petersanchez-gmail.com/Travel
 
 named-mailboxes "Search Results" +temporary/search 
 

          
M mutt/muttrc.insightminers +1 -1
@@ 6,7 6,7 @@ set use_from = yes
 set signature = ~/.mutt/signature.insightminers
 unset record
 
-set sendmail = "/usr/local/bin/msmtp -a insightminers"
+set sendmail = "/usr/bin/msmtp -a insightminers"
 set sendmail_wait = 0
 
 # Sync email

          
M mutt/muttrc.netlandish +1 -1
@@ 6,7 6,7 @@ set use_from = yes
 set signature = ~/.mutt/signature.netlandish
 unset record
 
-set sendmail = "/usr/local/bin/msmtp -a netlandish"
+set sendmail = "/usr/bin/msmtp -a netlandish"
 set sendmail_wait = 0
 
 # Sync email

          
M mutt/muttrc.pscom +1 -1
@@ 8,7 8,7 @@ set from = "pjs@petersanchez.com"
 set use_from = yes
 set signature = ~/.mutt/signature.pscom
 
-set sendmail = "/usr/local/bin/msmtp -a pscom"
+set sendmail = "/usr/bin/msmtp -a pscom"
 set sendmail_wait = 0
 
 # Sync email

          
M vim/vimrc +5 -0
@@ 22,6 22,9 @@ set wildmode=longest,list,full   " Enabl
 " These are files we are not likely to want to edit or read.
 set suffixes=.bak,~,.swp,.o,.info,.aux,.log,.dvi,.bbl,.blg,.brf,.cb,.ind,.idx,.ilg,.inx,.out,.toc
 
+" Needed since moving to Alpine
+set background=light
+
 " Temporary
 set nomodeline
 

          
@@ 456,6 459,8 @@ let g:vim_markdown_folding_disabled=1
 let g:ale_linters = {'python': ['flake8'], 'go': ['golint', 'gopls']}
 let g:ale_fixers = {'python': ['black', 'isort'], 'go': ['gofmt', 'goimports']}
 let g:ale_fix_on_save = 1
+" disable inline errors, so annoying
+let g:ale_virtualtext_cursor=0
 nnoremap <leader>a :ALEToggle<cr>
 nmap <silent> <leader>k <Plug>(ale_previous_wrap)
 nmap <silent> <leader>j <Plug>(ale_next_wrap)