56

Ubuntu 20.04 has decided we need 4 clicks to shut down:

  1. Click top right of screen arrow-down
  2. Expand "power off/logout" panel
  3. Click "Power off"
  4. Confirm you want to power off by choosing power off vs reboot etc

Let's cut out at least 2 clicks here... how?

UPDATE: This is a "Lounge PC" - operated by mouse (no power button within reach as the laptop is closed). We watch a film, we want to click to shutdown and not type commands.

18
  • 7
    You can add a shutdown icon to the dock: askubuntu.com/q/1160508/480481 – pomsky Jun 6 '20 at 9:31
  • 2
    It will not reduce the number of clicks, but you need not move (or even use) the mouse or touchpad: ctrl + alt + t to open a terminal window, type poweroff and press the Enter key. I find this more convenient than those 4 clicks to shutdown. – sudodus Jun 6 '20 at 9:32
  • 25
    How often are you shutting down that this is such an issue? – developerbmw Jun 6 '20 at 23:09
  • 5
    Can be reduced to 0 clicks if you hold down the power button for 8 seconds. – user9123 Jun 7 '20 at 16:04
  • 15
    @developerbmw I shut down my PC multiple times a day. I don't want a system consume energy while I am not using it, i.e. lunch-break. Also the psychological factor "the machine is off. I am not working right now" is important to me. Marc might have similar opinions. – Hermann Jun 8 '20 at 0:21
25

Reduce by two clicks

Option 1) Install the Poweroff Button on Topbar extension by Darknico. It adds a separate Power button on the right of the top bar.

Option 2) Create a "regular" launcher for "Power Off" (with thanks to pomsky). Either:

You may reduce with one more click by substituting the command in the launcher with "poweroff". Then, a single click on the launcher will immediately shut down the machine without confirmation dialog.

Reduce by one click

Option 3) Use the extension Bring Out Submenu Of Power Off/Logout Button by Pratap, or Simpler Off Menu by K3rcus. These extensions bring the items in the "Power Off/Log Out" submenu directly into the system menu, allowing to access them with one less click.

3
  • 2
    Just a pointer, in this answer, I used the gnome-session-quit --power-off command so that the user gets the confirmation dialog after clicking the shutdown icon. The process can be reduced by one step more by changing the Exec line to something like Exec=shutdown now. Then the system would shut down immediately after clicking the shutdown icon without showing any confirmation dialog. – pomsky Jun 6 '20 at 11:31
  • 5
    I considered adding this (also the command poweroff will do), but it becomes the heck dangerous with the launcher approach. A single wrong click immediately would take the system down. – vanadium Jun 6 '20 at 11:40
  • Of course, that's why I used the gnome-session-quit command instead in that answer. I just mentioned this point purely with respect to the "reducing number of steps as far as possible" aspect. – pomsky Jun 6 '20 at 20:28
34

You can easily make it 2 clicks:

  1. Open Settings
  2. Go to "Power"
  3. Change the "Power button action" dropdown to "Power off"

Now click the physical power button on your device and then select power off from the prompt - that is 2 clicks (1 if you don't count pressing the power button as a click).

3
17

Getting it down to 1 "click" (technically a button press):

By default, ubuntu shuts down the machine when you press the power button.

Then just wait 60 seconds for the machine to power off instead of clicking again.

1
  • 2
    I've updated my question: this is a lounge PC/Laptop with closed lid and no easy way to access the power button. I want to reduce clicks not introduce buttons/typing. – Marc Jun 8 '20 at 7:02
6

The answer is 0.

Install KShutdown, specify how long are you going to be online. As long as you stick to the plan and not mess with the time and save whatever you're doing 2 minutes prior. The machine will turn itself off, without you even touching it.

If you want to write your own command, start the terminal and type:

sudo shutdown -h +30

+30 (minutes) is an example. Change it to however long you want to stay online. And if you want the machine to turn itself off at a specific time, try:

sudo shutdown -h 20:30

(time is hypothetical, change it to whatever you want).

Note: Without the -h or -r switch it isn't a valid command.

1
  • 2
    eehh ? it is methods from the old times, meh. Not usable at all.. How about tool, which will detect that computer is in the IDLE for X minutes/hours and then will pursuit shutdown automatically ? – Reishin Jun 7 '20 at 23:41
6

Keyboard shortkey screenshot

I have the habit of creating my own keyboard shortcut to shutdown the PC because this is lot easier and less painful.

I have used too many buttons to avoid any accidental shutdown.

You can decrease it and make it like Super+P or something like that if you are careful enough.

1
  • I use this, but for sleep mode, it works great. I feel it's faster than even 1 mouse click once you get used to it. – Mark Jun 9 '20 at 13:45
2

0 clicks, a few clacks.

An alternative solution that doesn't require a mouse (just keyboard):

  1. Press and hold Ctrl+ALT+t

This brings up a terminal window.

  1. Type "poweroff" then hit the Enter key.
2
  • 1
    Fun fact: halt and init 0 both have fewer "clacks" than poweroff. – TSJNachos117 Jun 11 '20 at 6:07
  • OP doesn't have a keyboard, or at least easy access to one. – WinEunuuchs2Unix Jun 11 '20 at 19:43
2

Sony TV remote suspends laptop via network control

tvpowered (TV controls power to the computer) is a bash script that automatically suspends laptop when Sony Bravia TV is powered off. Additionally it will:

  • Turn off picture of TV to save power when you are not watching movies on TV.
  • Display pop-up bubble when you change volume of TV used for listening to music.

Please note this only works with Sony Bravia TVs.


Overview

When TV is turned off tvpowered automatically suspends, hibernates or powers off the laptop. Change the setting of SCTL global variable to control which action is taken.

tvpowered should be run as a normal user and called in Startup Applications.

Program design is straight forward:

  1. Wait for TV to be powered on.
  2. Begin fully active operation.
  3. Check if TV is powered off. If off go to step 5.
  4. Sleep for 3 seconds and repeat step 3.
  5. Suspend or Poweroff system when TV is powered off.
  6. If resuming from suspend go back to step 1.

In between these steps pop-up bubble messages appear on Desktop and are also logged to journalctl:

$ journalctl -xe | grep tvpower

Jun 11 18:11:20 tvpowered[27398]: TV is powered on. 'tvpowered' is now waiting for TV to power off.
Jun 11 18:11:47 tvpowered[28229]: TV Powered off. 'systemctl suspend' being called.
Jun 11 18:11:47 tvpowered[28238]: System powered back up. Checking if TV powered on. './tvpowered'.
Jun 11 18:12:26 tvpowered[31672]: TV is powered on. 'tvpowered' is now waiting for TV to power off.

tvpowered script

Copy and paste the script into a file on your computer and mark it executable with:

chmod a+x /path/to/tvpowered

Where /path/to/ is the directory name you created the file in.

You can also user your file manager (like Nautilus) to make the file executable.

In the script below there are a few constants you will need to set:

SCTL=suspend        # systemctl paramater: suspend or poweroff
IP=192.168.0.16     # IP address for Sony TV
PWRD=123            # Password for Sony TV IP Connect

tvpowered complete bash script

#!/bin/bash

# NAME: tvpowered
#
#       Original name slave2tv announced as politically incorrect after one day:
#       https://www.rt.com/news/491343-microsoft-coding-blacklists-slaves/
#
# DESC: When TV is powered off automatically suspend the laptop.
# DATE: June 9, 2020. Modified December 31, 2020
#
# NOTE: Written for Ask Ubuntu question:
#       https://askubuntu.com/questions/1247484/
#       4-clicks-to-shut-down-ubuntu-can-we-reduce-this

# UPDT: Jun 10 2020: Make name politically correct for Microsoft guidelines.
#       Change name from 'slave2tv' to 'tvpowered'. Abandon approach of polling
#       i2c, drm, i915, nvidia, xrandr, etc to see if monitor turned off. Setup
#       WiFi on TV instead and use Sony REST API to communicate TV status.

#       Jun 11 2020: Add pop-up bubble status messages. Add dependencies.
#       Add TenMinuteSpam. Add WaitUserSignOn. Add $SCTL constant. Convert
#       in-line code to mainline format.

#       Oct 03 2020: If ethernet disconnected we don't want to suspend.
#       Add TenMinuteSpam. Add WaitUserSignOn. Add $SCTL constant. Convert
#       in-line code to mainline format.

#       Oct 18 2020: If WiFi disconnected we don't want to suspend.

#       Dec 23 2020: After resume turn off picture with power savings.

#       Dec 31 2020: Fast popping bubble messages when volume changes.

# Sources:

# https://gist.github.com/kalleth/e10e8f3b8b7cb1bac21463b0073a65fb#cec-sonycec
# https://pro-bravia.sony.net/develop/integrate/rest-api/spec/service/audio/v1_0/setAudioVolume/index.html
# https://developer.sony.com/develop/audio-control-api/get-started/http-example#tutorial-step-2
# https://en.wikipedia.org/wiki/CURL
# https://stackoverflow.com/questions/7172784/how-do-i-post-json-data-with-curl
# https://stackoverflow.com/questions/2829613/how-do-you-tell-if-a-string-contains-another-string-in-posix-sh

SCTL=suspend        # systemctl paramater: suspend or poweroff
IP=192.168.0.16     # IP address for Sony TV
PWRD=123            # Password for Sony TV IP Connect (Pre-Shared key)

# Must have curl package.
command -v curl >/dev/null 2>&1 || { echo >&2 \
        "'curl' package required but it is not installed.  Aborting."; \
        exit 2; }

# Must have notify-send from libnotify-bin package
command -v notify-send >/dev/null 2>&1 || { echo >&2 \
        "libnotify-bin package required but it is not installed.  Aborting."; \
        exit 3; }

cURLit () {

    # $1 = JSON String in pretty format converted to file for cURL --data.
    # $2 = Sony subsystem to talk to, eg accessControl, audio, system, etc.
    # 3  = variable name to receive reply from TV

    local TEMP Result ReturnState

    # Declare mathres as reference to argument 3 provided (Bash 4.3 or greater)
    declare -n Result=$3  # ERROR: declare: `': not a valid identifier

    # Create temporary file in RAM for curl command
    TEMP=$(mktemp --tmpdir json.XXXXXXXX)
    echo "$1" > "$TEMP"

    # -s = silent
    Result=$(curl -s -H "Content-Type: application/json; charset=UTF-8" \
             -H "X-Auth-PSK: $PWRD" \
             --data @"$TEMP" \
             http://$IP/sony/"$2")
#echo "Result: $Result"    # Remove leading # for debugging
    ReturnState="$?"
    # TO-DO: check $? and if non-zero pop up dialog with $TEMP contents
    rm "$TEMP"

} # cURLit

GetPowerStatus () {

    local Reply ReturnState

    # Copy and paste JSON strings from Sony website: 
    # https://pro-bravia.sony.net/develop/integrate/rest-api/spec/service/system/v1_0/getPowerStatus/index.html
    JSONstr='{
                "method": "getPowerStatus",
                "id": 50,
                "params": [],
                "version": "1.0"
             }'

    cURLit "$JSONstr" "system" Reply    # No $ for Reply variable! pass pointer
    ReturnState="$?"

#echo "Reply: $Reply"    # Remove leading # for debugging
    # Reply: {"result":[{"status":"active"}],"id":50}
    #    or: {"result":[{"status":"standby"}],"id":50}

    # Does 'active' substring exist in TV's reply?
    [[ "${Reply#*active}" != "$Reply" ]] && return 0

    # TV is turned off
    # Might want timer tests to make sure we aren't repeatedly turning off
    return 1
    
} # GetPowerStatus

GetVolume () {

    # Copy and paste JSON strings from Sony website: 
    # https://pro-bravia.sony.net/develop/integrate/rest-api/spec/service/audio/v1_0/getVolumeInformation/index.html
    JSONstr='{
                "method": "getVolumeInformation",
                "id": 33,
                "params": [],
                "version": "1.0"
             }'
    
    # Then pass string to cURL for execution
    cURLit "$JSONstr" "audio" Reply

    # Sample output:
    #   Volume:, {"result":[[{"target":"speaker","volume":44,"mute":false,
    #   "maxVolume":100,"minVolume":0},{"target":"headphone","volume":15,
    #   "mute":false,"maxVolume":100,"minVolume":0}]],"id":33}

    Start="${Reply:41:4}"
    Volume=${Start%,*}

    return $Volume

} # GetVolume


log () {
    logger --id=$$ -t "tvpowered" "$1"
} # log


WaitForSignOn () {

    # tvpowered might be loaded during boot. The user name is required
    # for sending popup bubble messages and dialogs to screen. We must
    # wait until user signs on to get .Xauthority file settings.

    # code lifted from eyesome.sh
    SpamOn=10       # Causes 10 iterations of 2 second sleep
    SpamContext="Login"
    TotalWait=0

    # Wait for user to sign on then get Xserver access for xrandr calls
    UserName=""
    while [[ $UserName == "" ]]; do

        # Find UserName currently logged in.
        UserName="$(who -u | grep -F '(:0)' | head -n 1 | awk '{print $1}')"
        [[ $UserName != "" ]] && break

        sleep "$SpamLength"
        TotalWait=$(( TotalWait + SpamLength ))
    done

    if [[ $TotalWait != "0" ]] ; then
        log "Waited $TotalWait seconds for $UserName to login."
        xhost local:root
        export XAUTHORITY="/home/$UserName/.Xauthority"
    fi

} # WaitForSignOn


LastVolume=0
CurrVolume=0


TenMinuteSpam () {

    # If TV not powered up Spam user for 10 minutes that 'tvpowered' is running
    # and will shut down / suspend system

    WaitForSignOn   # Might be called by root during boot before user signed on.

    Cnt=0
    while : ; do

        GetPowerStatus
        if [[ "$?" == "0" ]] ; then
            log "TV is powered on. 'tvpowered' is now waiting for TV to power off."
            break
        else
            # Spam user every 60 seconds
            (( $(( Cnt % 20 )) == 0 )) && \
                notify-send --urgency=critical "tvpowered" \
                    -h string:x-canonical-private-synchronous:startup \
                    --icon=/usr/share/icons/gnome/48x48/devices/display.png \
                    "TV not communicating.\n Checking TV again..."
        fi
        sleep 3
        (( Cnt++ ))
    done
    
    GetVolume
    LastVolume="$?"
    notify-send --urgency=critical "tvpowered" \
        --icon=/usr/share/icons/gnome/48x48/devices/display.png \
        "Fully activated.\n System will $SCTL when TV powered off.  Volume: $LastVolume"
    
    return 0

} # TenMinuteSpam

###################################
#            MAINLINE             #
###################################

Main () {

    echo "$0: Initialization. Ensuring TV is powered on before starting."
    TenMinuteSpam
    echo "$0: Fully activated. Waiting for TV to powered off and then $SCTL."
    echo "$0: LastVolume: $LastVolume"

    Cnt=0
    FirstTime=true
    VolumeCnt=0             # TV Remote changed volume, so shrorter sleep

    while : ; do
        #etherup=$(cat /sys/class/net/e*/carrier) # Returns 1 even disconnected
        #wifi_up=$(cat /sys/class/net/w*/carrier)
        #if [[ $etherup <> "1" && $wifi_up <> "1" ]] ; then
        state=$(nmcli -f STATE -t g)            # Network manager takes .5 CPU
        if [[ $state == disconnected ]] ; then
            # Spam user every 60 * Cot seconds
            notify-send --urgency=critical "tvpowered" \
                -h string:x-canonical-private-synchronous:startup \
                --icon=/usr/share/icons/gnome/48x48/devices/display.png \
                "Internet not up.\nChecking Ethernet and/or  WiFi state again..."
            sleep $((Cnt * 60))
            (( Cnt++ ))
            continue
        else
            Cnt=0                               # Reset timer for next loop
        fi

        GetPowerStatus
        if [[ "$?" != "0" ]] ; then
            state=$(nmcli -f STATE -t g)        # Network manager takes .5 CPU
            if [[ $state == disconnected ]] ; then
                echo "Unexpected disconnect, aborting suspend."
            else
                log "TV Powered off. 'systemctl $SCTL' being called."
                systemctl "$SCTL"
                log "System powered back up. Checking if TV powered on. '$0'."
                sleep 10 #  Give system time to wake from suspend
                TenMinuteSpam
                /home/rick/sony/pictureoff.sh
            fi
        fi

        GetVolume
        CurrVolume="$?"
        # echo CurrVolume: $CurrVolume LastVolume: $LastVolume

        if [[ "$CurrVolume" != "$LastVolume" ]] ; then
            # Ask Ubuntu: https://askubuntu.com/a/871207/307523
            notify-send --urgency=critical "tvpowered" \
                -h string:x-canonical-private-synchronous:volume \
                --icon=/usr/share/icons/gnome/48x48/devices/audio-speakers.png \
                "Volume: $CurrVolume"
            LastVolume=$CurrVolume
            VolumeCnt=10
            # TODO: Process VolumeCnt internally in loop instead of larger loop
        fi

        if [[ $VolumeCnt > 0 ]]; then
            (( VolumeCnt-- ))
            SleepTime=.01
        else
            SleepTime=2.5
        fi

        sleep $SleepTime

        # Next iteration
        FirstTime=false
    done

    exit 0

} # Main

Main "$@"

Summary

I was inspired by OP's question and never realized how cumbersome and time-consuming my end of day suspend process used to be:

  1. Find where the cursor is on on one of three monitors
  2. Navigate to top right of whichever monitor and left click Cog menu
  3. Pull mouse down to suspend option
  4. Click suspend (being careful not to click shutdown next to it!)
  5. Power off Sony TV
  6. Power off Toshiba TV

tvpowered has eliminated time consuming steps 1. through 4.

0

I have a laptop by my television that I access with a wireless keyboard/touchpad device. I also keep the lid closed as well.

What I did is add a simple gnome extension called Gnome-Shutdown-Button. You can find a ton of these extensions at https://extensions.gnome.org/

It opens a dialogue that says "shutting down in 30 seconds" (it might be less) and offers a second option to shut down now.

1
  • Out of all the "mouse only" answers this is probably the best way. But you don't actually have a link to the application, just a link to all the applications in that world? – WinEunuuchs2Unix Jun 11 '20 at 19:46
-1

in terminal shutdown now do the trick for me

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.