#!/usr/bin/env bash # Author : Copyright (c) 2017-2022 Pavan Jadhaw, and others (https://github.com/betterlockscreen/betterlockscreen/graphs/contributors) # Project Repository : https://github.com/betterlockscreen/betterlockscreen cmd_exists () { command -v "$1" >/dev/null } 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.3" # 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() { # 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() { 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() { # 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 } # 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/') } # 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 # 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() { local path="$1" # 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 } # 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" 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" 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" } # 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 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]}" 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" 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" if [ "$span_image" = true ]; then resize_and_render "$USER_WALL" "$path" "$resolution" else resize_and_render "$USER_WALL" "$path" "$resolution" 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" 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" 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..." 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 [[ -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" } # 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 # 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" } # wrap echo with fancy prefix echof() { local prefix="$1" local message="$2" 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" } # help message usage() { echo echo "Usage: betterlockscreen [-u ] [-l ] [-w ]" echo echo " -q --quiet" echo " Do not produce any text output on locking" echo echo " -u --update " echo " Update lock screen image" echo echo " -l --lock " echo " Lock screen with cached image" echo echo " -w --wall " echo " Set wallpaper with cached image" echo echo "Additional arguments:" echo echo " --display " echo " Set display to draw loginbox" echo echo " --span" echo " Scale image to span multiple displays" echo echo " --off " echo " Turn display off after N seconds" echo echo " --fx " echo " List of effects to generate" echo echo " --desc " 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 " echo " to set your custom wallpaper setter" echo echo " --time-format " echo " to set the time format used by i3lock-color" echo echo " -- " echo " Pass additional arguments to i3lock" echo echo "Effects arguments:" echo echo " --dim " echo " Dim image N percent (0-100)" echo echo " --blur " echo " Blur image N amount (0.0-1.0)" echo echo " --pixel " echo " Pixelate image with N shrink and N grow (unsupported)" echo echo " --color " echo " Solid color background with HEX" echo exit 1 } init_config # show usage when no arguments passed [[ "$1" = "" ]] && usage # process arguments lockargs=() for arg in "$@"; do [[ "${arg:0:1}" = '-' ]] || continue case "$1" in -q | --quiet) quiet=true shift ;; -u | --update) runupdate=true imagepaths+=("$2") shift 2 ;; -s | --suspend) runsuspend=true ;& -l | --lock) runlock=true if [[ ${2:0:1} = '-' ]]; then shift 1 else lockstyle="$2"; shift 2 fi ;; -w | --wall) wallpaper "$2" shift 2 ;; --wallpaper-cmd) wallpaper_cmd="$2" shift 2 ;; --time-format) time_format="$2" shift 2 ;; --display) display_on="$2" shift 2 ;; --span) span_image=true shift 1 ;; --off) lock_timeout="$2" shift 2 ;; --text) locktext="$2" shift 2 ;; --show-layout) keylayout="$2"; shift 2 ;; --fx) IFS=',' read -ra fx_list <<< "$2" shift 2 ;; --dim) dim_level="$2" shift 2 ;; --blur) blur_level="$2" shift 2 ;; --pixel) pixel_scale="$2" shift 2 ;; --color) solid_color="${2//\#/}" shift 2 ;; --desc) description="$2" shift 2 ;; -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 if [[ "$FEH_INSTALLED" == "true" ]]; then feh --version fi break ;; --) lockargs+=("${@:2}") break ;; -h | --help | *) usage break ;; esac done echof header "Betterlockscreen" # Run image generation [[ $runupdate ]] && update "${imagepaths[@]}" # Activate lockscreen [[ $runsuspend ]] || lockargs+=(-n) [[ $runlock ]] && lockselect "$lockstyle" && \ { [[ $runsuspend ]] && loginctl suspend; } exit 0