46

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.

  • 6
    You can add a shutdown icon to the dock: askubuntu.com/q/1160508/480481 – pomsky Jun 6 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 at 9:32
  • 25
    How often are you shutting down that this is such an issue? – developerbmw Jun 6 at 23:09
  • 5
    Can be reduced to 0 clicks if you hold down the power button for 8 seconds. – TR_SLimey Jun 7 at 16:04
  • 12
    @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 at 0:21
23

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.

| improve this answer | |
  • 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 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 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 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).

| improve this answer | |
18

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.

| improve this answer | |
  • 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 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.

| improve this answer | |
  • 1
    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 at 23:41
  • It would be a shock to be working away on something and have the computer suddenly power off. – WinEunuuchs2Unix Jun 11 at 19: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.

| improve this answer | |
  • 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 at 13:45
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.
| improve this answer | |
  • 1
    Fun fact: halt and init 0 both have fewer "clacks" than poweroff. – TSJNachos117 Jun 11 at 6:07
  • OP doesn't have a keyboard, or at least easy access to one. – WinEunuuchs2Unix Jun 11 at 19:43
2

0-clicks, TV remote powers down laptop at same time as TV

tvpowered (TV controls power to the computer) is a straight forward bash script created from technical articles widely available on the internet.

Please note this only works with Sony Bravia TVs. Of course you could probably patch the code for different TVs in short order as it only took a few hours to write from scratch. I also have a generic Toshiba 4K TV running Amazon's Fire OS and might be willing to look at a script version for it. Other than that if you have a different brand of TV you will have to do your own research, coding and most importantly testing.


Overview

When TV is turned off this tvpowered automatically suspends the laptop or powers it off. Change the setting of $SCTL variable (located at top of script) between suspend or poweroff.

tvpowered can be run as sudo during boot but, this hasn't been tested. It 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

Post a comment if you have any questions!

# NAME: tvpowered
# DESC: When TV is powered off automatically suspend the laptop.
# DATE: June 9, 2020. Modified June 11, 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: Change name from 'slave2tv' to 'tvpowered'. Abandon 
#       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.

# Credits:
# 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

    # 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

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

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" \
                    --icon=/usr/share/icons/gnome/48x48/devices/display.png \
                    "TV was powered off.\n Checking TV power state again..."
        fi
        sleep 3
        (( Cnt++ ))
    done

    notify-send --urgency=critical "tvpowered" \
        --icon=/usr/share/icons/gnome/48x48/devices/display.png \
        "Fully activated.\n System will $SCTL when TV powered off."

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

    while : ; do

        GetPowerStatus
        if [[ "$?" != "0" ]] ; then
            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
        fi

        sleep 3

    done

    exit 0

} # Main

Main "$@"

Summary

I was inspired by OP's question and never realized how cumbersome and time-consuming my process was. At the end of the night I'm also watching TV and decompressing from the day before bed. When it's time to suspend the laptop I'm sleepy and yet need to:

  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 HD TV
  6. Power off 4K TV

tvpowered has eliminated time consuming steps 1. through 4. Quickly hitting power buttons on two TV remotes also prevents a classic problem in Linux:

  • Assume you forget to power down laptop first and shut off a monitor first. After a minute or two your windows rearrange across the virtual screen workspace, or worse yet go into mirroring and panning mode.
  • If you don't have a function written like xreset to move monitors around you will loose lots of time doing that in system settings.

Enjoy

| improve this answer | |
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.

| improve this answer | |
  • 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 at 19:46
0

in terminal shutdown now do the trick for me

| improve this answer | |

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.