feat: Add lockscreen spots effect

This commit is contained in:
2025-10-22 16:24:45 +11:00
parent 9287396d75
commit cc3ceda272
4 changed files with 463 additions and 5 deletions

View File

@@ -12,6 +12,8 @@ auth {
# GENERAL # GENERAL
general { general {
hide_cursor = true hide_cursor = true
screencopy_mode = 0
immediate_render = false
} }
animation { animation {
@@ -21,13 +23,17 @@ animation {
# BACKGROUND # BACKGROUND
background { background {
path = $HOME/.config/lockpaper path = screenshot
blur_passes = 2
#reload_time = 15 #reload_time = 15
#reload_cmd = echo $HOME/.config/lockpaper #reload_cmd = echo $HOME/.config/lockpaper
blur_passes = 0 # blur_passes = 0
crossfade_time = 1 crossfade_time = 1
} }
# AUTO BACKGROUND
# AUTO BACKGROUND END
# TIME # TIME
label { label {
text = $TIME text = $TIME
@@ -108,4 +114,4 @@ input-field {
capslock_color = rgb(255, 0, 0) capslock_color = rgb(255, 0, 0)
halign = left halign = left
valign = center valign = center
} }

View File

@@ -16,7 +16,7 @@ bind = $mainMod, Q, killactive,
bind = $mainMod, F, togglefloating, bind = $mainMod, F, togglefloating,
bind = $mainMod, space, exec, $menu bind = $mainMod, space, exec, $menu
bind = ALT, SPACE, exec, ~/.config/hypr/scripts/search-windows.sh bind = ALT, SPACE, exec, ~/.config/hypr/scripts/search-windows.sh
bind = $mainMod, L, exec, hyprlock bind = $mainMod, L, exec, /home/nathan/.config/hypr/scripts/lock-image.sh
bind = $mainMod, H, exec, alacritty --class float -e ~/.config/hypr/scripts/help.py bind = $mainMod, H, exec, alacritty --class float -e ~/.config/hypr/scripts/help.py
#bind = $mainMod, V, exec, [float] alacritty --class clipse -e /home/nathan/.local/bin/clipse #bind = $mainMod, V, exec, [float] alacritty --class clipse -e /home/nathan/.local/bin/clipse
@@ -148,6 +148,14 @@ bind = , 2, exec, hyprpanel -q
bind = , 2, exec, hyprpanel bind = , 2, exec, hyprpanel
bind = , 2, submap, reset bind = , 2, submap, reset
bind = CTRL, 3, movetoworkspace, special:alternate
bind = CTRL, 3, submap, reset
bind = , 3, togglespecialworkspace, alternate
bind = , 3, submap, reset
bind = , T, exec, hyprctl notify 5 2000 0 "Select text to copy to clipboard..." bind = , T, exec, hyprctl notify 5 2000 0 "Select text to copy to clipboard..."
bind = , T, exec, ~/.config/OCR4Linux/OCR4Linux.sh --lang eng -r bind = , T, exec, ~/.config/OCR4Linux/OCR4Linux.sh --lang eng -r
bind = , T, submap, reset bind = , T, submap, reset

View File

@@ -0,0 +1,64 @@
#!/usr/bin/env bash
# Path to hyprlock configuration file
CONF="$HOME/.config/hypr/hyprlock.conf"
# Get the list of outputs
mapfile -t outputs < <(hyprctl -j monitors | jq -r '.[].name')
# Generate the background blocks for each output
block=""
for output in "${outputs[@]}"; do
block+=$'background {\n'
block+=$" monitor = ${output}\n"
block+=$" path = screenshot\n"
block+=$" reload_time = 0\n"
block+=$" reload_cmd = echo \"/tmp/${output}-lockscreen.png\"\n"
block+=$" crossfade_time = 1\n"
block+=$'}\n\n'
done
# Insert the generated blocks into the configuration file
awk -v content="$block" '
/^# AUTO BACKGROUND$/ { print; print content; inside=1; next }
inside && /^# AUTO BACKGROUND END$/ { print; inside=0; next }
inside { next }
{ print }
' "$CONF" > "${CONF}.tmp" && mv "${CONF}.tmp" "$CONF"
# Take a screenshot of each output before locking (!THIS IS SLOW!)
for output in "${outputs[@]}"; do
grim -o "$output" "/tmp/${output}-lockscreen.png" &
done
wait
# Start hyprlock while we process the images
/home/nathan/Git/hyprlock/build/hyprlock &
# Apply image effect to each screenshot
for output in "${outputs[@]}"; do
# Apply blur effect using spots.sh
/home/nathan/.config/hypr/scripts/spots.sh -s 8 "/tmp/${output}-lockscreen.png" "/tmp/${output}-lockscreen.png" &
done
# Wait for all image processing to complete
while pgrep -x spots.sh >/dev/null; do
sleep 0.1
done
# Notify hyprlock to reload backgrounds
echo "Reloading hyprlock backgrounds..."
pkill -USR2 hyprlock
# Wait for hyprlock to exit
while pgrep -x hyprlock >/dev/null; do
echo "Waiting for hyprlock to exit..."
sleep 1
done
# Cleanup: Restore hyprlock.conf to original state
sed -i '/^# AUTO BACKGROUND$/,/^# AUTO BACKGROUND END$/{//!d}' "$CONF"
# Remove the screenshots
for output in "${outputs[@]}"; do
rm "/tmp/${output}-lockscreen.png"
done

380
.config/hypr/scripts/spots.sh Executable file
View File

@@ -0,0 +1,380 @@
#!/bin/bash
#
# Developed by Fred Weinhaus 8/4/2011 .......... 5/28/2015
#
# ------------------------------------------------------------------------------
#
# Licensing:
#
# Copyright © Fred Weinhaus
#
# My scripts are available free of charge for non-commercial use, ONLY.
#
# For use of my scripts in commercial (for-profit) environments or
# non-free applications, please contact me (Fred Weinhaus) for
# licensing arrangements. My email address is fmw at alink dot net.
#
# If you: 1) redistribute, 2) incorporate any of these scripts into other
# free applications or 3) reprogram them in another scripting language,
# then you must contact me for permission, especially if the result might
# be used in a commercial or for-profit environment.
#
# My scripts are also subject, in a subordinate manner, to the ImageMagick
# license, which can be found at: http://www.imagemagick.org/script/license.php
#
# ------------------------------------------------------------------------------
#
####
#
# USAGE: spots [-s size] [-t type] [-p pad] [-b bgcolor] [-e edge] [-E ecolor] [-B brightness] [-C Contrast] infile [spotfile] outfile
# USAGE: spots [-help]
#
# OPTIONS:
#
# -s size spot size expressed as WxH in pixels; default=5x5
# -t type type of spot shape; choices are: circle (or c),
# square (or s), or diamond (or d); default=circle
# -p pad padding or border around spot cell in pixels on
# each side; integer>=0; default=1
# -b bgcolor background color to apply to image where spot
# does not cover; any valid IM color; default=black
# -e edge edge thickness accent around spot shape;
# integer>=0; default=0
# -E ecolor color of accent edge around spot shape;
# any valid IM color; default=gray
# -B brightness percent change in brightness of spots;
# integer; default=0
# -C contrast percent change in contrast of spots;
# integer; default=0
#
#
###
#
# NAME: SPOTS
#
# PURPOSE: Converts the image into a series of uniform-colored spots.
#
# DESCRIPTION: SPOTS converts the image into a series of uniform-colored
# spots. The shape of spots allowed are: circle (ellipse), square (rectangle)
# or diamond. The spot size may be adjusted. A colored edge may also be
# placed around each spot. An optional spotfile may be provided to define
# some other shape than those built-in.
#
#
# OPTIONS:
#
# -s size ... SIZE is the WxH dimensions of the spot cell. Values are a
# pair of positive integers separated by an x. The default=5x5. If only
# one value is provided, it will be used for both. This parameter is
# ignored if a spotfile is provided.
#
# -t type ... TYPE is the type of spot shape. The choices are: circle (or c),
# square (or s), diamond (or d). These may be asymmetric as ellipses or
# rectangles as controlled by the size parameters. This parameter is
# ignored if a spotfile is provided.
#
# -p pad ... PAD is the border around the spot cell. Values are integers>=0.
# The default=0.
#
# -b bgcolor ... BGCOLOR is the color to apply to the image between the spots.
# Any valid IM color is allowed. The default=black.
#
# -e edge ... EDGE is the thickness of the optional edge hightlight around
# the spot shape. Values are integers>=0. The default=0.
#
# -E ecolor ... ECOLOR is the color of the edge highlight. Any valid IM color
# is allowed. The default=gray.
#
# -B brightness ... BRIGHTNESS is the percent change in brightness of the
# spot colors. Values are integers. The default=0
#
# -C contrast ... CONTRAST is the percent change in contrast of the
# spot colors. Values are integers. The default=0
#
# The spotfile must be a binary mask with white for the shape and black
# for the background and no alpha channel.
#
# REQUIREMENTS: IM 6.3.6-1 or higher due to the use of
# -define distort:viewport=WxH+X+Y with -distort SRT.
#
# CAVEAT: No guarantee that this script will work on all platforms,
# nor that trapping of inconsistent parameters is complete and
# foolproof. Use At Your Own Risk.
#
######
#
# set default values
size="5x5" # spot WxH
type="circle" # circle, square, diamond
pad=1 # border padding
edge=0 # edge width
ecolor="gray" # edge color
bgcolor="black" # background color
bri=0 # brightness
con=0 # contrast
# set directory for temporary files
dir="." # suggestions are dir="." or dir="/tmp"
# set up functions to report Usage and Usage with Description
PROGNAME=`type $0 | awk '{print $3}'` # search for executable on path
PROGDIR=`dirname $PROGNAME` # extract directory of program
PROGNAME=`basename $PROGNAME` # base name of program
usage1()
{
echo >&2 ""
echo >&2 "$PROGNAME:" "$@"
sed >&2 -e '1,/^####/d; /^###/g; /^#/!q; s/^#//; s/^ //; 4,$p' "$PROGDIR/$PROGNAME"
}
usage2()
{
echo >&2 ""
echo >&2 "$PROGNAME:" "$@"
sed >&2 -e '1,/^####/d; /^######/g; /^#/!q; s/^#*//; s/^ //; 4,$p' "$PROGDIR/$PROGNAME"
}
# function to report error messages
errMsg()
{
echo ""
echo $1
echo ""
usage1
exit 1
}
# function to test for minus at start of value of second part of option 1 or 2
checkMinus()
{
test=`echo "$1" | grep -c '^-.*$'` # returns 1 if match; 0 otherwise
[ $test -eq 1 ] && errMsg "$errorMsg"
}
# test for correct number of arguments and get values
if [ $# -eq 0 ]
then
# help information
echo ""
usage2
exit 0
elif [ $# -gt 19 ]
then
errMsg "--- TOO MANY ARGUMENTS WERE PROVIDED ---"
else
while [ $# -gt 0 ]
do
# get parameter values
case "$1" in
-help) # help information
echo ""
usage2
exit 0
;;
-s) # get size
shift # to get the next parameter
# test if parameter starts with minus sign
errorMsg="--- INVALID SIZE SPECIFICATION ---"
checkMinus "$1"
size=`expr "$1" : '\([0-9]*[x]*[0-9]*\)'`
[ "$size" = "" ] && errMsg "--- SIZE=$size MUST BE A PAIR OF POSITIVE INTEGERS (with no sign) SEPARATED BY AN x ---"
;;
-t) # type
shift # to get the next parameter
# test if parameter starts with minus sign
errorMsg="--- INVALID TYPE SPECIFICATION ---"
checkMinus "$1"
# test mode values
type="$1"
type=`echo "$type" | tr "[:upper:]" "[:lower:]"`
case "$type" in
circle|c) type="circle" ;;
square|s) type="square" ;;
diamond|d) type="diamond" ;;
*) errMsg "--- TYPE=$type IS AN INVALID VALUE ---"
esac
;;
-p) # get pad
shift # to get the next parameter
# test if parameter starts with minus sign
errorMsg="--- INVALID PAD SPECIFICATION ---"
checkMinus "$1"
pad=`expr "$1" : '\([0-9]*\)'`
[ "$pad" = "" ] && errMsg "--- PAD=$pad MUST BE A NON-NEGATIVE INTEGER (with no sign) ---"
;;
-b) # get bgcolor
shift # to get the next parameter
# test if parameter starts with minus sign
errorMsg="--- INVALID BGCOLOR SPECIFICATION ---"
checkMinus "$1"
bgcolor="$1"
;;
-e) # get edge
shift # to get the next parameter
# test if parameter starts with minus sign
errorMsg="--- INVALID EDGE SPECIFICATION ---"
checkMinus "$1"
edge=`expr "$1" : '\([0-9]*\)'`
[ "$edge" = "" ] && errMsg "--- EDGE=$edge MUST BE A NON-NEGATIVE INTEGER (with no sign) ---"
;;
-E) # get ecolor
shift # to get the next parameter
# test if parameter starts with minus sign
errorMsg="--- INVALID ECOLOR SPECIFICATION ---"
checkMinus "$1"
ecolor="$1"
;;
-B) # get brightness
shift # to get the next parameter
# test if parameter starts with minus sign
errorMsg="--- INVALID BRIGHTNESS SPECIFICATION ---"
#checkMinus "$1"
bri=`expr "$1" : '\([-0-9]*\)'`
[ "$bri" = "" ] && errMsg "--- BRIGHTNESS=$bri MUST BE AN INTEGER (with no sign) ---"
;;
-C) # get contrast
shift # to get the next parameter
# test if parameter starts with minus sign
errorMsg="--- INVALID CONTRAST SPECIFICATION ---"
#checkMinus "$1"
con=`expr "$1" : '\([-0-9]*\)'`
[ "$con" = "" ] && errMsg "--- CONTRAST=$con MUST BE AN INTEGER (with no sign) ---"
;;
-) # STDIN and end of arguments
break
;;
-*) # any other - argument
errMsg "--- UNKNOWN OPTION ---"
;;
*) # end of arguments
break
;;
esac
shift # next option
done
#
# get infile and outfile and spotfile
if [ $# -eq 3 ]; then
infile="$1"
spotfile="$2"
outfile="$3"
elif [ $# -eq 2 ]; then
infile="$1"
outfile="$2"
else
errMsg "--- INCONSISTENT NUMBER OF IMAGES PROVIDED ---"
fi
fi
# test that infile provided
[ "$infile" = "" ] && errMsg "NO INPUT FILE SPECIFIED"
# test that outfile provided
[ "$outfile" = "" ] && errMsg "NO OUTPUT FILE SPECIFIED"
# create temp files
tmpA1="$dir/spots_1_$$.mpc"
tmpB1="$dir/spots_1_$$.cache"
tmpA2="$dir/spots_2_$$.mpc"
tmpB2="$dir/spots_2_$$.cache"
trap "rm -f $tmpA1 $tmpB1 $tmpA2 $tmpB2;" 0
trap "rm -f $tmpA1 $tmpB1 $tmpA2 $tmpB2; exit 1" 1 2 3 15
trap "rm -f $tmpA1 $tmpB1 $tmpA2 $tmpB2; exit 1" ERR
# setup brightness contrast
if [ "$bri" = "0" -a "$con" = "0" ]; then
bricon=""
else
bricon="-brightness-contrast $bri,$con"
fi
# test input image
convert -quiet "$infile" $bricon -clamp +repage "$tmpA1" ||
errMsg "--- FILE $infile DOES NOT EXIST OR IS NOT AN ORDINARY FILE, NOT READABLE OR HAS ZERO SIZE ---"
# test spot file if exists
if [ "$spotfile" != "" ]; then
convert -quiet "$spotfile" -alpha off +repage "$tmpA2" ||
errMsg "--- FILE $spotfile DOES NOT EXIST OR IS NOT AN ORDINARY FILE, NOT READABLE OR HAS ZERO SIZE ---"
fi
# get image width, height and aspect
ww=`convert $tmpA1 -ping -format "%w" info:`
hh=`convert $tmpA1 -ping -format "%h" info:`
# get size of spot and center of spot and last pixel of spot and pad size
if [ "$spotfile" = "" ]; then
sw=`echo $size | cut -dx -f1`
sh=`echo $size | cut -dx -f2`
scx=`convert xc: -format "%[fx:($sw-1)/2]" info:`
scy=`convert xc: -format "%[fx:($sh-1)/2]" info:`
lx=$((sw-1))
ly=$((sh-1))
# get pad size
pw=$((sw+2*pad))
ph=$((sh+2*pad))
else
pw=`convert $tmpA2 -ping -format "%w" info:`
ph=`convert $tmpA2 -ping -format "%h" info:`
fi
if [ "$spotfile" = "" ]; then
if [ "$pad" = "0" ]; then
padding=""
else
padding="-bordercolor black -border $pad"
fi
# create spot template
if [ "$type" = "circle" ]; then
convert -size ${sw}x${sh} xc:black \
+antialias -fill white -draw "ellipse $scx,$scy $scx,$scy 0,360" -alpha off \
$padding \
$tmpA2
elif [ "$type" = "square" ]; then
convert -size ${sw}x${sh} xc:black \
+antialias -fill white -draw "rectangle 0,0 $lx,$ly" -alpha off \
$padding \
$tmpA2
elif [ "$type" = "diamond" ]; then
convert -size ${sw}x${sh} xc:black \
+antialias -fill white -draw "polygon $scx,0 $lx,$scy $scx,$ly 0,$scy" -alpha off \
$padding \
$tmpA2
fi
fi
# compute xmin and ymin and virtual canvas size
xmin=`convert xc: -format "%[fx:ceil($ww/$pw)]" info:`
ymin=`convert xc: -format "%[fx:ceil($hh/$ph)]" info:`
www=`convert xc: -format "%[fx:$xmin*$pw]" info:`
hhh=`convert xc: -format "%[fx:$ymin*$ph]" info:`
# process image
if [ "$edge" = "0" ]; then
convert \( $tmpA1 -define distort:viewport=${www}x${hhh}+0+0 -virtual-pixel mirror -distort SRT 0 \
-scale ${xmin}x${ymin}! -scale ${www}x${hhh}! -crop ${ww}x${hh}+0+0 +repage \) \
\( $tmpA2 -write mpr:tile +delete -size ${ww}x${hh}! tile:mpr:tile \) \
-alpha off -compose copy_opacity -composite -compose over \
-background $bgcolor -flatten \
"$outfile"
else
convert \( $tmpA1 -define distort:viewport=${www}x${hhh}+0 -virtual-pixel mirror -distort SRT 0 \
-scale ${xmin}x${ymin}! -scale ${www}x${hhh}! -crop ${ww}x${hh}+0+0 +repage \) \
\( $tmpA2 -write mpr:tile +delete -size ${ww}x${hh}! tile:mpr:tile \) \
\( -clone 1 -threshold 0 -edge $edge -clamp -fill $ecolor -opaque white -transparent black \) \
\( -clone 0 -clone 1 -alpha off -compose copy_opacity -composite -compose over \
-background $bgcolor -flatten \) \
-delete 0,1 +swap -compose over -composite \
"$outfile"
fi
exit 0