67

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.

Marc
  • 803
  • 7
    You can add a shutdown icon to the dock: https://askubuntu.com/q/1160508/480481 – pomsky Jun 06 '20 at 09: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 06 '20 at 09:32
  • 25
    How often are you shutting down that this is such an issue? – brettwhiteman Jun 06 '20 at 23:09
  • 5
    Can be reduced to 0 clicks if you hold down the power button for 8 seconds. – user9123 Jun 07 '20 at 16:04
  • 2
    what happens when you press the power button of your computer? – njzk2 Jun 07 '20 at 21:54
  • 16
    @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 08 '20 at 00:21
  • How about the Ubuntu equivalent of shutdown /s /t 0? – Mast Jun 08 '20 at 06:32
  • 1
    How do you turn it on? If that means opening the lid and pressing the power on button ... Stack Tracers's answer is correct: open the lid and press the power on button to shutdown ;) – Rinzwind Jun 08 '20 at 07:34
  • Indeed there is a power button we use to switch on but it's a pain to open the case - shutdown should not require real-world button pushing IMO. #LazyUsers – Marc Jun 08 '20 at 08:43
  • 1
    It's also not "such an issue" - I just feel stupid when I need 10 steps to do something which is really only 1 or 2 steps.@developerbmw – Marc Jun 08 '20 at 08:54
  • Do you close your applications before powering off or leave them open? – WinEunuuchs2Unix Jun 08 '20 at 11:51
  • 2
    @sudodus I do [Alt+F2]init 0[Enter]; that's fewer keystrokes for the same effect. – the default. Jun 08 '20 at 14:19
  • 2
    What's your current process for starting a movie? Do you autoplay a disc, pull up a web page, or run a media player? You could, for example, set the PC to shut down (or ask if it should) automatically when you exit your media player. – A C Jun 08 '20 at 17:44
  • Couple of options: 1) power off dialog pops up when you exit your movie player 2) power off when you turn off your TV (more complicated but doable). – WinEunuuchs2Unix Jun 08 '20 at 22:49
  • 1
    How many clicks does it take to put it into sleep now? – user3528438 Jun 08 '20 at 23:37
  • 1
    I eagerly await a solution that remaps Shutdown to the left click. – J. Mini Jun 09 '20 at 12:41
  • @Marc there r many answers here.. you didn't accept one.. are you looking for something else than these answers? If yes can you edit the question on what factors you like to achieve in two clicks? – PRATAP Jun 13 '20 at 12:10
  • 1
    Hello, there is no rush. I was hoping there was a native way without hacks and extensions to get Ubunto to add say a power button to the task bar or something. – Marc Jun 13 '20 at 13:34

9 Answers9

39

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).

Daniel M.
  • 1,903
26

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.

vanadium
  • 88,010
  • 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 06 '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 06 '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 06 '20 at 20:28
16

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.

  • 3
    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 08 '20 at 07:02
7

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.

pomsky
  • 68,507
Pranav
  • 1,200
  • 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 09 '20 at 13:45
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.

Gryu
  • 7,559
  • 9
  • 33
  • 52
  • 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 07 '20 at 23:41
3

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.
Joshua
  • 51
2

Sony TV remote suspends laptop

This answer is based on IoT (Inernet of Things).

tvpowered (TV controls power to the computer) is a bash script. When you press the power button on your Sony TV remote:

  • The Sony TV will be shut off
  • The Google Android TV will be shut off
  • The light behind the Sony TV will be shut off
  • The light behind the Google TV will be shut off
  • The laptop will be put to sleep

Additionally the tvpowered script 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.

volume change.gif

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.19     # IP address for Sony TV on LAN
ADB_IP=192.168.0.21 # IP address for Google TV on LAN for Android Debug Bridge
PWRD=123            # Password for Sony TV IP Connect

tvpowered complete bash script

#!/bin/bash

NAME: tvpowered

PATH: /usr/bin/ OR ~/bin (/home/USERNAME/bin) OR /mnt/e/bin/

DESC: When TV is powered off automatically suspend the laptop.

DATE: June 9, 2020. Modified March 30, 2023.

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.

Jan 09 2021: Improve performance and reduce system resources.

Jan 31 2021: Switch from /tmp to /run/user/1000 (RAM).

Mar 13 2023: New IP address 19 after power outage.

Mar 26 2023: Change volume partial UTF-8 ticks from 4 to 8.

Mar 28 2023: Change call to pictureoff

Mar 30 2023: Google TV to sleep (TV Remote Power Off).

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 parameter: 'suspend' or 'poweroff' IP=192.168.0.19 # IP address for Sony TV on LAN ADB_IP=192.168.0.21 # IP address for Google TV on LAN for Android Debug Bridge 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; }

Must have adb (Android Debug Bridge) package

command -v adb >/dev/null 2>&1 || { echo >&2
"'adb' package required but it is not installed. Aborting.";
exit 4; }

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=/run/user/1000 tvpowered.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"

# Test string

#curl -s -H "Content-Type: application/json; charset=UTF-8" -H "X-Auth-PSK: 123" --data "{ "method": "getPowerStatus", "id": 50, "params": [], "version": "1.0" }" http://192.168.0.16sony/system } # 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="$?"                    # Usually '6', not checked.

#echo "ReturnState: $ReturnState Reply: $Reply"    # Remove # 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 (standby) or no network (blank)
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

Bar="" # Global Volume Level bar

VolumeBar () {

Bar=""                      # Progress Bar / Volume level
Len=25                      # Length of Progress Bar / Volume level
Div=4                       # Divisor into Volume for # of full blocks
Fill="▒"                    # Fill background up to $Len
Parts=8                     # Divisor into  Volume for # of part blocks
# UTF-8 left blocks: 1, 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8
Arr=("█" "▏" "▎" "▍" "▌" "▋" "▊" "█")

FullBlock=$((${1} / Div))   # Number of full blocks
PartBlock=$((${1} % Parts)) # Size of partial block (array index)

while [[ $FullBlock -gt 0 ]]; do
    Bar="$Bar${Arr[0]}"     # Add 1 full block into Progress Bar
    (( FullBlock-- ))       # Decrement full blocks counter
done

# If remainder zero no partial block, else append character from array
if [[ $PartBlock -gt 0 ]]; then
    Bar="$Bar${Arr[$PartBlock]}"
fi

while [[ "${#Bar}" -lt "$Len" ]]; do
    Bar="$Bar$Fill"         # Pad Progress Bar with fill character
done

} # VolumeBar

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

    if GetPowerStatus ; 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="$?"
VolumeBar $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 $Bar"

adb connect "$ABD_IP"  # Connect to Google TV.
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 shorter sleep

while : ; do

    if ! GetPowerStatus; then

        # START FROM ABOVE: 
        # This was causing 2% CPU drain with Network Manager and
        # debus-daemon. So move from above GetPowerStatus to below.

        # If network down then wait for it to come up. 
        #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

        # END FROM ABOVE: If network down then wait for it to come up


        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."
            adb connect "$ABD_IP"  # Connect to Google TV.
            adb shell input keyevent 26  # Google TV to sleep (remote off)
            systemctl "$SCTL"
            # systemctl will suspend. When resuming we hit next line
            log "System powered back up. Checking if TV powered on. '$0'."
            sleep 10                        # Time to wake from suspend
            TenMinuteSpam                   # Wait for network connection
            pictureoff                      # Picture off energy saving
        fi
    fi

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

    if [[ "$CurrVolume" != "$LastVolume" ]] ; then
        # Make volume bar using progress bar methods
        VolumeBar $CurrVolume
        # 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 $Bar"
        LastVolume=$CurrVolume
        VolumeCnt=100  # For 1 second, faster checks for volume change
        # TODO: Process VolumeCnt internally in loop instead of larger loop
    fi

    if [[ $VolumeCnt > 0 ]]; then
        (( VolumeCnt-- ))
        SleepTime=.01
    else
        SleepTime=.75
    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.

EDIT: A website was made to document tvpowered


Bonus - Turn of Light Behind TV

For nighttime viewing, there is a light behind the TV. Whenever the laptop goes to sleep, it first shuts off the light.

Create the script /etc/NetworkManager/dispatcher.d/pre-down.d/smartplug_off and place into it:

#!/bin/bash

NAME: smartplug_off

PATH: /etc/NetworkManager/dispatcher.d/pre-down.d

DESC: Turn off smartplug light power for TV light

DATE: March 7, 2020.

CALL: Called by Network Manager before going down. Network manager in turn

is called by systemd during suspend/hibernate/shutdown

NOTE: myisp.sh and hs100.sh must be installed for hs100 tp-link power plug.

https://developer.gnome.org/NetworkManager/stable/NetworkManager.html

PlugName="192.168.0.15"

status=$(hs100.sh -i "$PlugName" check | cut -f2) if [ $status == "OFF" ] ; then : # Nothing to do already off elif [ $status == "ON" ] ; then hs100.sh -i "$PlugName" off else echo Error hs100.sh not responding check connection and IP "$PlugName". fi

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.

  • 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

sda11
  • 9