-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added screen locker with dual monitors support from meskarune/i3lock-…
- Loading branch information
Showing
10 changed files
with
237 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,236 @@ | ||
#!/usr/bin/env bash | ||
# Author: Dolores Portalatin <[email protected]> | ||
# Dependencies: imagemagick, i3lock-color-git, scrot, wmctrl (optional) | ||
set -o errexit -o noclobber -o nounset | ||
|
||
# Determines the brightness of the screenshot | ||
# $1 - Image file to check | ||
# $2 - Arguments passed to 'convert'. For example this can be used to crop the image, to just sample a part of it | ||
get_brightness() { | ||
# Quite fast way of getting a brightness value | ||
convert "$1" +repage $2 -colorspace gray -format "%[fx:round(100*mean)]" info: | ||
} | ||
|
||
# Determines the width of the given text when processed using the text_options flag | ||
# $1 - The text to checked | ||
# Prints the text width in pixels to stdout | ||
get_text_width() { | ||
# empty text or text containing only whitespace would throw an error so we just return zero | ||
if [ -z "${1// }" ]; then | ||
echo 0 | ||
return | ||
fi | ||
convert "${text_options[@]}" label:"$1" -format "%[fx:w]\n" info: | ||
} | ||
|
||
# Calculates the absolute positions for the lock and text or the given monitor, generates the command line arguemnts | ||
# for convert that apply the lock icon and the text to the proper locations and adds them to the decorations_params array | ||
# $1 - Monitor Width | ||
# $2 - Monitor Height | ||
# $3 - X Offset | ||
# $4 - Y Offset | ||
# Prints the brigthness in the center of the monitor to file descriptor 3 | ||
# This is used to determine the average brightness in the centers of all the monitors and to then set the proper colors | ||
# for i3lock-color | ||
process_monitor() { | ||
width=$1 | ||
height=$2 | ||
x_offset=$3 | ||
y_offset=$4 | ||
|
||
# center coordinates relative to the current monitor | ||
x_mid=$((width / 2)) | ||
y_mid=$((height / 2)) | ||
|
||
# absolute X, Y coordinates of the top left edge of the text | ||
x_text=$((x_offset + x_mid - (text_width / 2))) | ||
y_text=$((y_offset + y_mid + 160)) | ||
|
||
# absolute X, Y coordinates of the top left edge of the icon | ||
# The lock icon has dimensions 60x60, we subtract half of that from each dimension | ||
# If the lock dimensions ever change, these values here need to be changed too | ||
x_icon=$((x_offset + x_mid - 30)) | ||
y_icon=$((y_offset + y_mid - 30)) | ||
|
||
# Get brightness for the middle of the monitor | ||
brightness="$(get_brightness "$image" "-crop 100x100+$x_icon+$y_icon")" | ||
|
||
if [ "$brightness" -gt "$threshold" ]; then # bright background image and black text | ||
text_color="black" | ||
icon="$scriptpath/icons/lockdark.png" | ||
else # dark background image and white text | ||
text_color="white" | ||
icon="$scriptpath/icons/lock.png" | ||
fi | ||
|
||
decoration_params+=(+repage) | ||
|
||
if [ "$text_width" -ne 0 ]; then | ||
# Only add text flags, if there actually is text | ||
decoration_params+=("${text_options[@]}" -fill "$text_color" -annotate "+$x_text+$y_text" "$text") | ||
fi | ||
|
||
decoration_params+=("$icon" -geometry "+$x_icon+$y_icon" -composite) | ||
|
||
|
||
# Write brightness to file descriptor | ||
exec 3<<< "$brightness" | ||
} | ||
|
||
# get path where the script is located to find the lock icon | ||
scriptpath=$(readlink -f -- "$0") | ||
scriptpath=${scriptpath%/*} | ||
|
||
hue=(-level "0%,100%,0.6") | ||
effect=(-filter Gaussian -resize 20% -define "filter:sigma=1.5" -resize 500.5%) | ||
# default system sans-serif font | ||
font=$(convert -list font | awk "{ a[NR] = \$2 } /family: $(fc-match sans -f "%{family}\n")/ { print a[NR-1]; exit }") | ||
|
||
image="$(mktemp --suffix=.png)" | ||
|
||
# brightness value to compare to, everything above is considered white and everything below black | ||
threshold="40" | ||
|
||
desktop="" | ||
shot=(import -window root) | ||
i3lock_cmd=(i3lock -i "$image") | ||
shot_custom=false | ||
|
||
options="Options: | ||
-h, --help This help menu. | ||
-d, --desktop Attempt to minimize all windows before locking. | ||
-g, --greyscale Set background to greyscale instead of color. | ||
-p, --pixelate Pixelate the background instead of blur, runs faster. | ||
-f <fontname>, --font <fontname> Set a custom font. | ||
-t <text>, --text <text> Set a custom text prompt. | ||
-l, --listfonts Display a list of possible fonts for use with -f/--font. | ||
Note: this option will not lock the screen, it displays | ||
the list and exits immediately. | ||
-n, --nofork Do not fork i3lock after starting. | ||
-- Must be last option. Set command to use for taking a | ||
screenshot. Default is 'import -window root'. Using 'scrot' | ||
or 'maim' will increase script speed and allow setting | ||
custom flags like having a delay." | ||
|
||
# move pipefail down as for some reason "convert -list font" returns 1 | ||
set -o pipefail | ||
trap 'rm -f "$image"' EXIT | ||
temp="$(getopt -o :hdnpglt:f: -l desktop,help,listfonts,nofork,pixelate,greyscale,text:,font: --name "$0" -- "$@")" | ||
eval set -- "$temp" | ||
|
||
# l10n support | ||
text="Type password to unlock" | ||
case "${LANG:-}" in | ||
de_* ) text="Bitte Passwort eingeben" ;; # Deutsch | ||
da_* ) text="Indtast adgangskode" ;; # Danish | ||
en_* ) text="Type password to unlock" ;; # English | ||
es_* ) text="Ingrese su contraseña" ;; # Española | ||
fr_* ) text="Entrez votre mot de passe" ;; # Français | ||
id_* ) text="Masukkan kata sandi Anda" ;; # Bahasa Indonesia | ||
it_* ) text="Inserisci la password" ;; # Italian | ||
pl_* ) text="Podaj hasło" ;; # Polish | ||
pt_* ) text="Digite a senha para desbloquear" ;; # Português | ||
ru_* ) text="Введите пароль" ;; # Russian | ||
* ) text="Type password to unlock" ;; # Default to English | ||
esac | ||
|
||
while true ; do | ||
case "$1" in | ||
-h|--help) | ||
printf "Usage: %s [options]\n\n%s\n\n" "${0##*/}" "$options"; exit 1 ;; | ||
-d|--desktop) desktop=$(command -V wmctrl) ; shift ;; | ||
-g|--greyscale) hue=(-level "0%,100%,0.6" -set colorspace Gray -separate -average) ; shift ;; | ||
-p|--pixelate) effect=(-scale 10% -scale 1000%) ; shift ;; | ||
-f|--font) | ||
case "$2" in | ||
"") shift 2 ;; | ||
*) font=$2 ; shift 2 ;; | ||
esac ;; | ||
-t|--text) text=$2 ; shift 2 ;; | ||
-l|--listfonts) | ||
convert -list font | awk -F: '/Font: / { print $2 }' | sort -du | command -- ${PAGER:-less} | ||
exit 0 ;; | ||
-n|--nofork) i3lock_cmd+=(--nofork) ; shift ;; | ||
--) shift; shot_custom=true; break ;; | ||
*) echo "error" ; exit 1 ;; | ||
esac | ||
done | ||
|
||
if "$shot_custom" && [[ $# -gt 0 ]]; then | ||
shot=("$@"); | ||
fi | ||
|
||
text_options=(-font "$font" -pointsize 26) | ||
text_width=$(get_text_width "$text") | ||
|
||
command -- "${shot[@]}" "$image" | ||
|
||
# All the arguments to be passed to convert, to add the lock and text to the monitors is collected here so that we can | ||
# apply them in a single call to convert | ||
decoration_params=() | ||
|
||
# We collect the brightness values from all the monitors and average them, from that we determine which flags to pass to | ||
# i3lock-color since the colors for i3lock-color cannot be specified per monitor. | ||
# We could also just call get_brightness on the whole image but process_monitor samples only the center | ||
# of the screen where the lock actually is, so we get a better value for the brightness | ||
sum_brightness=0 | ||
num_monitors=0 | ||
|
||
# Loop through all connected monitors (as reported by xrandr) | ||
# For each monitor the convert arguments to add the lock and text to that monitor are generated | ||
while read -r monitor; do | ||
if [[ "$monitor" =~ ([0-9]+)x([0-9]+)\+([0-9]+)\+([0-9]+) ]]; then | ||
width=${BASH_REMATCH[1]} | ||
height=${BASH_REMATCH[2]} | ||
x_offset=${BASH_REMATCH[3]} | ||
y_offset=${BASH_REMATCH[4]} | ||
|
||
# We get the return value from the function by using a new file descriptor | ||
# The traditional approach of using $(process_monitor ...) and echo doesn't work because it forks into a | ||
# subshell and then process_monitor cannot access decoration_params | ||
exec 3>&- | ||
process_monitor "$width" "$height" "$x_offset" "$y_offset" && read -r brightness <&3 | ||
exec 3>&- | ||
|
||
sum_brightness=$((brightness + sum_brightness)) | ||
num_monitors=$((num_monitors + 1)) | ||
fi | ||
done <<<"$(xrandr --verbose | grep "\bconnected\b")" | ||
|
||
convert "$image" "${hue[@]}" "${effect[@]}" "${decoration_params[@]}" "$image" | ||
|
||
avg_brightness=$((sum_brightness / num_monitors)) | ||
|
||
if [ "$avg_brightness" -gt "$threshold" ]; then # Screenshot is rather bright, so we use dark colors | ||
param=("--textcolor=00000000" "--insidecolor=0000001c" "--ringcolor=0000003e" \ | ||
"--linecolor=00000000" "--keyhlcolor=ffffff80" "--ringvercolor=ffffff00" \ | ||
"--separatorcolor=22222260" "--insidevercolor=ffffff1c" \ | ||
"--ringwrongcolor=ffffff55" "--insidewrongcolor=ffffff1c") | ||
else # Bright colors | ||
param=("--textcolor=ffffff00" "--insidecolor=ffffff1c" "--ringcolor=ffffff3e" \ | ||
"--linecolor=ffffff00" "--keyhlcolor=00000080" "--ringvercolor=00000000" \ | ||
"--separatorcolor=22222260" "--insidevercolor=0000001c" \ | ||
"--ringwrongcolor=00000055" "--insidewrongcolor=0000001c") | ||
fi | ||
|
||
# If invoked with -d/--desktop, we'll attempt to minimize all windows (ie. show | ||
# the desktop) before locking. | ||
${desktop} ${desktop:+-k on} | ||
|
||
# try to use i3lock with prepared parameters | ||
if ! "${i3lock_cmd[@]}" "${param[@]}" >/dev/null 2>&1; then | ||
# We have failed, lets get back to stock one | ||
"${i3lock_cmd[@]}" | ||
fi | ||
|
||
# As above, if we were passed -d/--desktop, we'll attempt to restore all windows | ||
# after unlocking. | ||
${desktop} ${desktop:+-k off} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.