3

I'm using the xfce4 timer and I want the alarm to make the screen blink in addition to the pop-up alarm. Currenly I am using

xset dpms force off; sleep 3;  xset dpms force on

which lets the screen go off an on again but I would like it to blink with colors and faster if possible in a flashing style

Greetings

Max
  • 194

1 Answers1

4

I made a bash script to meet the objective:

flash-primary-screen.sh.gif

flash-primary-screen.sh bash script

Copy this bash script to your computer:

#!/bin/bash

# NAME: flash-primary-screen.sh
# PATH: ~/bin
# DESC: Flashes primary screen colours to alert timer has ended.
# DATE: November 15, 2018

# NOTE: Written for: https://askubuntu.com/a/1092835/307523
#       I'm looking for a command to flash screens (if possible in colors)

# Change 6 variables below to control screen flashing levels
MaxBright="1.5"
MinBright=".5"
MaxRed="2.0"
MaxGreen="2.0"
MaxBlue="2.0"
MinGamma=".5"

declare aXrandr=()

# Next two functions lifted from: eyesome internet sunrise/sunset time screen
# brightness and gamma controller: https://github.com/WinEunuuchs2Unix/eyesome

InitXrandrArray () {

    # Array is used for each monitor and searched by name.
    # Save time to search on connected/disconnected, primary monitor,
    # brightness level, gamma level.

    mapfile -t aXrandr < <(xrandr --verbose --current)

} # InitXrandrArray

SearchXrandrArray () {

    # Parms: $MonXrandrName = xrandr monitor name to search for.

    # NOTE: Entries in array follow predicatble order from xrandr --verbose:

    #       <MONITOR-NAME> connected / disconnected (line 1 of monitor entry)
    #       Gamma:      0.99:0.99:0.99              (line 5 of entry)
    #       Brightness: 0.99                        (line 6 of entry)
    #       CRTC:       9                           (line 8 of entry)

    fNameFnd=false
    fBrightnessFnd=false
    fGammaFnd=false
    fCrtcFnd=false
    XrandrConnection=disconnected
    XrandrPrimary=false
    XrandrGamma=""
    XrandrBrightness=""
    XrandrCRTC=""           # Laptop lid open value=0, lid closed=blank

    for (( i=0; i<"${#aXrandr[*]}"; i++ )) ; do

        line="${aXrandr[$i]}"
        # Have we looped to next monitor and not found search string?
        if [[ "$line" =~ " connected " ]] && [[ $fNameFnd == true ]] ; then
            break
        fi

        if [[ "$line" =~ ^"$MonXrandrName connected" ]]; then
            fNameFnd=true
            XrandrConnection=connected
            [[ "$line" =~ "primary" ]] && XrandrPrimary=true
        fi

        if [[ $fNameFnd == true ]] && [[ $fGammaFnd == false ]] ; then
            if [[ "$line" =~ "Gamma: " ]]; then
                fGammaFnd=true
                XrandrGamma="${line##* }"
                # TODO: Use `xgamma` for accuracy
            fi
        fi

        if [[ $fGammaFnd == true ]] && [[ $fBrightnessFnd == false ]] ; then
            if [[ "$line" =~ "Brightness: " ]]; then
                fBrightnessFnd=true
                XrandrBrightness="${line##* }"
            fi
        fi

        if [[ $fBrightnessFnd == true ]] && [[ $fCrtcFnd == false ]] ; then
            if [[ "$line" =~ "CRTC: " ]]; then
                fCrtcFnd=true
                XrandrCRTC="${line##* }"
                break
            fi
        fi

    done

} # SearchXrandrArray

FlipBright () {

    if [[ $NewBrightness == "$MaxBright" ]] ; then
        NewBrightness="$MinBright"
    else
        NewBrightness="$MaxBright"
    fi

} # FlipBright

CleanUp() {

    xrandr --output "$MonXrandrName" --gamma "$SaveGamma" \
           --brightness "$SaveBrightness"

    # Compensate for bug in Xrandr as of Nov 15, 2018 with second call
    InitXrandrArray
    SearchXrandrArray
    xrandr --output "$MonXrandrName" --gamma "$XrandrGamma"
    exit 0

} # CleanUp

Main () {

    trap CleanUp INT TERM

    # Get primary monitor current settings
    XrandrName=$(xrandr --current | grep primary)
    MonXrandrName="${XrandrName%% *}"
    InitXrandrArray
    SearchXrandrArray

    # Did we find primary monitor ok?
    if [[ $fBrightnessFnd == false ]] || [[ $fGammaFnd == false ]] ; then
        echo "Internal Error: Could not find Primary Screen brightness or gamma"
        echo XrandrPrimary: "$XrandrPrimary"
        echo aXrandr[0]: "${aXrandr[0]}"
        echo Brightness: "$XrandrBrightness"
        echo Gamma: "$XrandrGamma"
        exit 2
    fi

    # Restore these values when CleanUping program
    SaveBrightness="$XrandrBrightness"
    SaveGamma="$XrandrGamma"

    # Wait for <Ctrl>+C or until parent kills us.
    while true ; do
        if [[ $Red == true ]] ; then
            Red=false
            Green=true
            NewGamma="$MaxRed:$MinGamma:$MinGamma"
            FlipBright
        elif [[ $Green == true ]] ; then
            Green=false
            NewGamma="$MinGamma:$MaxGreen:$MinGamma"
            FlipBright
        else
            Red=true
            NewGamma="$MinGamma:$MinGamma:$MaxBlue"
            FlipBright
        fi

        xrandr --output "$MonXrandrName" --gamma "$NewGamma" \
       --brightness "$NewBrightness"

        sleep .2

    done

} # Main

Main "$@"

Mark the script as executable using:

chmod a+x /path/flash-primary-screen.sh

Where /path is the directory you placed the script.

Call the script from your program (or even the command line). To end the script press Ctrl+C.

Change the first 6 variables defined to manipulate the brightness level and color level changes.

Don't hesitate to ask questions or post suggestions in comment section below!


You can also have color flashing ASCII Art text in the terminal:

bashVTcodes.gif

Here is the script:

#!/bin/bash

From: http://wiki.bash-hackers.org/scripting/terminalcodes
DATA[0]="     _/  _/    _/                            _/    "
DATA[1]="  _/_/_/_/_/  _/_/_/      _/_/_/    _/_/_/  _/_/_/ "
DATA[2]="   _/  _/    _/    _/  _/    _/  _/_/      _/    _/"
DATA[3]="_/_/_/_/_/  _/    _/  _/    _/      _/_/  _/    _/ "
DATA[4]=" _/  _/    _/_/_/      _/_/_/  _/_/_/    _/    _/  "

# virtual coordinate system is X*Y ${#DATA} * 5

REAL_OFFSET_X=0
REAL_OFFSET_Y=0

draw_char() {
  V_COORD_X=$1
  V_COORD_Y=$2

  tput cup $((REAL_OFFSET_Y + V_COORD_Y)) $((REAL_OFFSET_X + V_COORD_X))

  printf %c ${DATA[V_COORD_Y]:V_COORD_X:1}
}


trap 'exit 1' INT TERM
trap 'tput setaf 9; tput cvvis; clear' EXIT

tput civis
clear

while :; do

for ((c=1; c <= 7; c++)); do
  tput setaf $c
  for ((x=0; x<${#DATA[0]}; x++)); do
    for ((y=0; y<=4; y++)); do
      draw_char $x $y
    done
  done
done

done

To generate the ASCII Art you can use Figlet or Toilet. See: When terminal is opened can I get current calendar and time displayed?

  • 1
    These are great scripts. Thanks for sharing them. I would suggest adding the following lines to the first one enabling the flashing to be stopped more easily: if [ "$#" -gt 0 ]; then Main & flasher=$!; xmessage "$@"; kill $flasher; else Main; fi – tbrk Aug 05 '21 at 13:00
  • @tbrk Thanks for the compliment! The script stops when <Ctrl> + C is used. I'm not sure advantage of change you are proposing? – WinEunuuchs2Unix Aug 05 '21 at 13:07
  • The xfce4 timer is a GUI-based component that simply executes the command it has been given when an alarm occurs. It does not display a terminal with the running command, so Ctrl-C cannot be used directly. Otherwise, you have to search for a process id and use kill while the screen is wildly flashing! – tbrk Aug 06 '21 at 08:16
  • @tbrk I don't use Xubuntu so am not familiar with the problem. Two things come to mind though: 1) have flashing run for 2 or 3 seconds only. 2) make flashing less extreme (narrower color /gamma range). – WinEunuuchs2Unix Aug 06 '21 at 12:31
  • Thanks for your response. Yes, you're right, but the xmessage/kill mod is simple and also works very well. – tbrk Aug 07 '21 at 19:52
  • Impressive script. Small fix for me and when I use only one monitor the script failed: had to modify XrandrName=$(xrandr --current | grep primary || xrandr --current | grep ' connected') as xrandr returned no "primary" entry. – MoonCactus May 30 '22 at 06:55