My power button doesn't work under LXDE. How can I fix this?

The ACPID way


Overview

There are numerous ways of fixing this issue. If you look through the web you will find suggestions on installing power managers used in other desktop environments (DEs) like xfce4-power-manager or gnome-settings-daemon. However, as an LXDE user you are probably striving for a lightweight solution. One lightweight way to display a logout menu on power button press is to utilize an ACPID script.

What is ACPID?

From the ArchWiki:

acpid is a flexible and extensible daemon for delivering ACPI events. It listens on /proc/acpi/event and when an event occurs, executes programs to handle the event. These events are triggered by certain actions, such as:

  • Pressing special keys, including the Power/Sleep/Suspend button

  • Closing a notebook lid (Un)Plugging an AC power adapter from a notebook

  • (Un)Plugging phone jack etc.

Installation

sudo apt-get install acpi acpid

Configuration

Open /etc/acpi/powerbtn.sh in a text editor of your choice, e.g. leafpad:

gksudo leafpad /etc/acpi/powerbtn.sh

At the end of the file you will find the following passage:

# If all else failed, just initiate a plain shutdown.
/sbin/shutdown -h now "Power button pressed"

Just before this passage add the following snippet:

# If LXDE is running execute lxsession-logout
if [ -n $(pidof lxsession) ]; then
    for x in /tmp/.X11-unix/*; do
       displaynum=`echo $x | sed s#/tmp/.X11-unix/X##`
       getXuser;
       if [ x"$XAUTHORITY" != x"" ]; then
           export DISPLAY=":$displaynum"
           export _LXSESSION_PID=`pidof lxsession`
           lxsession-logout
           exit
       fi
    done
fi

Most of the snippet consists of functions and commands that make sure that a graphical application like the logout menu can be run by ACPID (setting environment variables like XUSER and DISPLAY).

Note: If you have GNOME components running in your LXDE session (e.g. nautilus, various daemons) the session detection might go wrong. In these cases I would advise you to insert the code in the following way:

  if pidof x $PMS > /dev/null; then
     if [ -n $(pidof lxsession) ]; then
        for x in /tmp/.X11-unix/*; do
           displaynum=`echo $x | sed s#/tmp/.X11-unix/X##`
           getXuser;
           if [ x"$XAUTHORITY" != x"" ]; then
           export DISPLAY=":$displaynum"
           export _LXSESSION_PID=`pidof lxsession`
           killall lxsession-logout
           lxsession-logout
           fi
        done
        echo "if correct"
        exit
             else
                 exit
     fi
<...>

Troubleshooting

For some unknown reason these functions don't always work. In that case you will have to replace the snippet above with the following one:

if [ -n $(pidof lxsession) ]; then
   export DISPLAY=:0
   export _LXSESSION_PID=$(pidof lxsession)
   export XUSER=user
   export XAUTHORITY=/home/user/.Xauthority
   lxsession-logout
   exit
fi

The environment variables are hard-coded in this one. Make sure to substitute user for your own user name. It should work for most single-user system configurations.

Here's another workaround, just in case none of the variants above work. Replace the getXuser function with the following passage:

getXuser() {
        user=`pinky -fw | awk '{ if ($2 == ":'$displaynum'" || $(NF) == ":'$displaynum'" ) { print $1; exit; } }'`
        if [ x"$user" = x"" ]; then
                startx=`pgrep -n startx`
                if [ x"$startx" != x"" ]; then
                        user=`ps -o user --no-headers $startx`
                fi
        fi
        if [ x"$user" = x"" ]; then                           # lines added
               user=$(pinky -fw | awk '{ print $1; exit; }')  # lines added
        fi                                                    # lines added
        if [ x"$user" != x"" ]; then
                userhome=`getent passwd $user | cut -d: -f6`
                export XAUTHORITY=$userhome/.Xauthority
        else
                export XAUTHORITY=""
        fi
        export XUSER=$user
}

What does it do?

The powerbtn.sh script is triggered by ACPID each time the power button is pressed. As you can see it already includes a number of checks for common DEs like Unity, GNOME and KDE. These checks are there to make sure that the shutdown event is handled by the respective power manager. Alas, LXDE doesn't have one of those built in.

That's why we added a snippet of our own that does the checking for ACPID. If it detects an LXDE session it makes sure that your PC isn't just shut down right away and instead launches the logout menu you should be familiar with.

With these changes you should now be able to launch your logout menu with your hardware power button - without needing to install a bulky power manager. And even better, this does not interfere with other DEs in any way.

Sources

http://www.ollie-reardon.co.uk/lxde-tip-power-button-not-working/

https://wiki.archlinux.org/index.php/Acpid

http://forum.lxde.org/viewtopic.php?f=8&t=205


Further reading

Lubuntu - power button doesn't turn off computer,

Laptop power button not working

https://bugs.launchpad.net/xfce4-power-manager/+bug/1008650

https://unix.stackexchange.com/questions/87259/why-wont-this-shutdown-script-work-when-executed-by-acpid


It seems that LXDE does not include the lxsession-logout package. Install the package by typing this in terminal:

sudo apt install lxsession-logout

I know this is an old thread, but I just experienced this problem and could not find a direct answer anywhere.