1
\$\begingroup\$

This is a script I made while having trouble with xautolock and dimming of the screen right before locking it. I would like some tips for making it a bit more robust and to know of any disadvantages of it. I don't know how it works with multiple screens but I suspect it does not.

#!/bin/bash
# Lock screen in:
minutes=15
seconds=0
# How many seconds it takes to dim
dim_secs=5
idle_secs=$(( $minutes * 60 + $seconds )) # Screen timeout in seconds
idle_ms=$(( $idle_secs * 1000 ))
timeout=$idle_secs
while true; do
 sleep $timeout
 if pgrep xflock4 > /dev/null; then
 timeout=$idle_secs
 continue
 fi
 # After sleeping, check user idle time
 if [ $(xprintidle) -ge $idle_ms ]; then
 WINDOW=$(echo $(xwininfo -id $(xdotool getactivewindow) -stats | \
 egrep '(Width|Height):' | \
 awk '{print $NF}') | \
 sed -e 's/ /x/')
 SCREEN=$(xdpyinfo | grep -m1 dimensions | awk '{print 2ドル}')
 # If greater than timeout check if something's not in fullscreen and active
 if [ "$WINDOW" != "$SCREEN" ]; then
 interrupted=false # If dimming's been interrupted
 screen=$(xrandr -q | grep " connected" | awk '{print 1ドル;}') # Connected screen
 brightness=$(xrandr --verbose | grep -i brightness | cut -f2 -d ' ') # Current brightness
 start_time=$(date "+%s.%N") # Current time
 while true; do
 # Current brightness(0 to $brigtness), decided by time since dimming started
 br=$(echo "$brightness-$brightness*(($(date "+%s.%N")-$start_time)/$dim_secs)" | bc -l)
 if [ $(echo "$br >= 0" | bc) -eq 1 ]; then
 # Set the current brightness and sleep for a short while
 xrandr --output $screen --brightness $br
 sleep 0.01
 else
 # If brightness is less than 0 then it means that the
 # time since starting dimming is greater than $dim_secs
 break
 fi
 # If the user gave an input that's less than $idle_ms
 # Will always be less than $idle_ms if it was interrupted during dimming
 if [ $(xprintidle) -lt $idle_ms ]; then
 interrupted=true
 break
 fi
 done
 if $interrupted; then
 # If it was interrupted during dimming, reset brightness
 xrandr --output $screen --brightness $brightness
 else
 xset dpms force off # Turn screen off
 xrandr --output $screen --brightness $brightness # Reset brightness
 xflock4 # Lock screen
 fi
 fi
 fi
 # Timeout before checking idle time again
 timeout=$(echo "$idle_secs - $(xprintidle) / 1000 " | bc -l)
done
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Nov 25, 2014 at 19:37
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

You don't need to prefix variables with $ inside $(( ... )), this will work just as well:

idle_secs=$(( minutes * 60 + seconds )) # Screen timeout in seconds
idle_ms=$(( idle_secs * 1000 ))

In many places you pipe to a grep and then pipe to awk. Note that awk can perform many of the functions of grep, and using one process (awk) instead of two (grep + awk) would be more optimal.

Here are some examples. Instead of:

... | egrep '(Width|Height):' | awk '{print $NF}'

This is equivalent:

... | awk '/(Width|Height):/ {print $NF}'

Instead of:

... | grep -m1 dimensions | awk '{print 2ドル}'

This is equivalent:

... | awk '/dimensions/ {print 2ドル; exit}'

And so on, similarly at other places too, you get the idea.


Another common pattern I see at many places:

echo "$br >= 0" | bc -l

That is, using echo to pass a string to a command. A better way is using here-strings, like this:

bc -l <<< "$br >= 0"

This long line appears at multiple places, sometimes with minor variations:

# If it was interrupted during dimming, reset brightness
xrandr --output $screen --brightness $brightness

It would be better to move this to a function, for example reset_brightness, to reduce duplication of logic.

answered Nov 25, 2014 at 20:15
\$\endgroup\$
2
  • \$\begingroup\$ I get "pgrep: invalid option -- 'q'" \$\endgroup\$ Commented Nov 25, 2014 at 21:05
  • \$\begingroup\$ Ah... Worked in my system (BSD version), looks like GNU version doesn't have it. Thanks, removed that point. \$\endgroup\$ Commented Nov 25, 2014 at 21:10

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.