2

I've Debian jessie and xfce. When I push the power button, my system is suspended. When I press any key on my keyboard the system wake up and I get the login prompt of Xscreensaver (screen lock is active). Now if I push the power button the system does not suspend, I must login and then I can suspend the system with the power button. Is there a way to suspend the system from the login screen of Xscreensaver?

  • Can you post your ` /etc/acpi/events/powerbtn`? I want to see of it is using powerbtn.sh for handling the power button. – iyrin Feb 2 '15 at 12:34
  • event=button[ /]power action=/etc/acpi/powerbtn-acpi-support.sh – Pioz Feb 2 '15 at 16:48
  • tl;dr the only way for it to work is to break the grab – iyrin Feb 3 '15 at 15:51
1

Xscreensaver is functioning properly. From what I understand, XGrabKeyboard is used by Xscreensaver which is grabbing the keys while the login window is displayed. The short answer is that you can't normally use the power button on the locked screen, but I did look through a lot of documentation and some code to figure out why this is and what possible solutions may exist.

There are only a few exceptions for bypassing the Xscreensaver lock, all of which rely on the use of lower level keyboard shortcuts1.

Backdoor #1: Ctrl-Alt-Backspace. This keystroke kills the X server, and on some systems, leaves you at a text console. If the user launched X11 manually, that text console will still be logged in. To disable this keystroke globally and permanently, you need to set the DontZap flag in your xorg.conf or XF86Config or XF86Config-4 file (whichever name is in use on your system). See the manual for XF86Config (or variant) for more details.

Backdoor #2: Ctrl-Alt-F1, Ctrl-Alt-F2, etc. These keystrokes will switch to a different virtual console, while leaving the console that X11 is running on locked. If you left a shell logged in on another virtual console, it is unprotected. So don't leave yourself logged in on other consoles. You can disable VT switching globally and permanently by setting DontVTSwitch in your xorg.conf, but that might make your system harder to use.

Backdoor #3: Alt-SysRq-F. This is the Linux kernel "OOM-killer" keystroke. It shoots down random long-running programs of its choosing, and so might might target and kill xscreensaver, and there's no way for xscreensaver to protect itself from that. You can disable it globally with: sudo 'echo 176 > /proc/sys/kernel/sysrq'

Backdoor #4: Ctrl-Alt-KP_Multiply. This keystroke kills any X11 app that holds a lock, so typing this will kill xscreensaver and unlock the screen. This "feature" showed up in the X server in 2008, and as of 2011, some vendors are shipping it turned on by default. How nice. You can disable it by turning off AllowClosedownGrabs in xorg.conf.

As it is, you can configure Xorg to AllowClosedownGrabs to close the Xscreensaver process holding the lock orAllowDeactivateGrabs to deactivate and active keyboard grabs2. This of course renders the lock useless to anyone with physical access to your keyboard, but you should be able to at least test your power button to see if it suspends the machine after using the AllowClosedownGrabs or AllowDeactivateGrabs shortcut.

If you are successful in suspending the machine at this point, then at least we know there is some level of keymapping with actions that control the server's behavior without getting caught by XGrabkeyboard.

The shortcut Ctrl-Alt-FX will switch the virtual terminal via XF86_Switch_VT_X, where X is the number of the F key 1-12, while the screen is locked. So we know that these keys from xkb are not being grabbed.

Excerpt of output of grep -r "XF86_Switch" /usr/share/X11/xkb/ shows:

/usr/share/X11/xkb/compat/xfree86:    interpret  XF86_Switch_VT_1 {
/usr/share/X11/xkb/symbols/srvr_ctrl:   symbols[Group1]= [ F1, F1, F1, F1, XF86_Switch_VT_1 ]

If you look at these files, you'll notice they also contain the key combinations for cancelling keyboard grabs and for killing a client that has grab in effect.

So, if there is a way to have the power button suspend during the locked screen, it might require a custom xkb key for the power button. It would also have to make use of Ungrab to ungrab all currently active grabs.

That's about as far as I can take you for now. It may warrant a couple of new question specifically regarding xkb key mapping of the power button, as well as mapping a key to use Ungrab as seen below.

From commit 7d2543a3cb3089241982ce4f8984fd723d5312a1 3

Add four new private XKB actions for debugging:
    * PrGrbs: print active grabs to the log file
    * Ungrab: ungrab all currently active grabs
    * ClsGrb: kill clients with active grabs
    * PrWins: dump the current window tree to the log file

To use these, you need to modify your XKB maps, e.g. the following to
have Ctrl+Alt+(F9-F12) mapped to the above:
 - compat/xfree86:
    interpret XF86LogGrabInfo {
        action = Private(type=0x86, data="PrGrbs");
    };
    interpret XF86Ungrab {
        action = Private(type=0x86, data="Ungrab");
    }
    interpret XF86ClearGrab {
        action = Private(type=0x86, data="ClsGrb");
    }
    interpret XF86LogWindowTree {
        action = Private(type=0x86, data="PrWins");
    }

 - symbols/pc:
    key <FK09> {        type="CTRL+ALT", [ Return, XF86LogGrabInfo      ]   };
    key <FK10> {        type="CTRL+ALT", [ Return, XF86Ungrab           ]   };
    key <FK11> {        type="CTRL+ALT", [ Return, XF86ClearGrab        ]   };
    key <FK12> {        type="CTRL+ALT", [ Return, XF86LogWindowTree    ]   };

Edit: The power button event from ACPI may be functioning normally, but it is not being processed due to the XGrabServer4 lock used by xscreensaver5.

The XGrabServer function disables processing of requests and close downs on all other connections than the one this request arrived on.

The only way I know of to get around this is by enabling the AllowClosedownGrabs options and using the Ctrl+Alt+Keypad-Multiply key combination6.

Note that the options AllowDeactivateGrabs and AllowClosedownGrabs will allow users to remove the grab used by screen saver/locker programs.

If you really want to nerd out on it, you can try to write a patch for xscreensaver to support the power button (maybe listen for ACPI event, XUngrabServer, issue the event again). It would have to grab again when the system resumes, otherwise the lock is pointless. I don't know what other security implications this would have.

Edit 2: Testing with xfce4-power-manager-settings set to shutdown when power button is pressed, it works while the screen is locked. I believe this is because only the scancode for the power button is required for handling by ACPI and handling at the level of the window manager is not necessary.

Testing with the power button set to Suspend is grabbed by xscreensaver and prevented.

I read the following7, and decided to test pm-suspend while xscreensaver was running to make sure it wasn't being interfered with directly.

xfce4-power-manager, which uses pkexec to call pm-suspend. pkexec allows execution of a program as another user, in this case root.

First I ran sudo ls to enter the password and grant the user temporary sudo privileges.

Next I ran the following commands:

sleep 60 && xscreensaver-command -lock &
sleep 60 && sudo pm-suspend

The screen was locked, followed by the system being suspended as expected.

I believe that suspend is handled at the level of the window manager and xfce4-power-manager relies on the xkb key mapping to handle it after the scancode into a keycode that can be handled at the window manager level. This would explain why it is subject to the grab and prevented from executing pm-suspend8.

The udev keymaps are correct. As I said, on the kernel level there is only KEY_SLEEP (suspend to RAM) and KEY_SUSPEND (suspend to disk, aka hibernate).

On the X.org level, /usr/share/X11/xkb/keycodes/evdev assigns to KEY_SLEEP and to KEY_SUSPEND. /usr/share/X11/xkb/symbols/inet then maps to XF86Sleep and to XF86Suspend, mirroring the evdev naming.

This is similar on my system if I'm reading it correctly:

grep -r "Suspend" /usr/share/X11/xkb/

Output:

/usr/share/X11/xkb/geometry/everex:    indicator "Suspend"  { left=112; };
/usr/share/X11/xkb/keycodes/evdev:  indicator 7  = "Suspend";
/usr/share/X11/xkb/symbols/inet:    key <I213>   {      [ XF86Suspend           ]       };
/usr/share/X11/xkb/server-0.xkb:    indicator 7 = "Suspend";
/usr/share/X11/xkb/server-0.xkb:    key <I213> {         [     XF86Suspend ] };

Edit 3: Try configuring ACPI to suspend directly instead of using xfce4-power-manager, if that is the case.

You may need to write a shell script to be called from /etc/acpi/events/powerbtn to handle this correctly. See How to suspend and hibernate a laptop under Linux

You'll probably have to use xscreensaver-command -lock in your script before suspending if you want make sure the screen is locked when the system is restored. Xscreensaver checks whether the screen is already locked and will output xscreensaver-command: already locked. if it is.

  • Interesting! And what about keys that generate ACPI events? Those are probably handled in the kernel, so those would still work I suppose? – Michel Feb 2 '15 at 9:05
  • The scancodes for the power button are at the kernel level. sourcecodebrowser.com/acpid/2.0.14/input__layer_8c_source.html A scancode is mapped to a keycode. A keycode is mapped to a keysym. wiki.archlinux.org/index.php/Extra_keyboard_keys It does look like events are handled based on the scancode wiki.archlinux.org/index.php/Acpid So now I am confused as to how the window manager is preventing this. – iyrin Feb 2 '15 at 11:48
  • 1
    The question is: is the window manager preventing this? Maybe the asker hasn't configured systemd/acpid to react to these ACPI events, it might be that everything is handled by a power manager app, which reacts on the keysyms, which are blocked by the screenlocker... – Michel Feb 2 '15 at 12:24
  • Yeah that's what I'm thinking. – iyrin Feb 2 '15 at 12:34
  • 1
    Michel, that seems to be exactly what's happening, at as far as testing in my end. I'm assuming OP's system is also relying on xfce4-power-manager. – iyrin Feb 4 '15 at 17:57
0

The problem is (probably) that some program in your xfce session is handling suspend button press events, i.e., some power manager program in your systray. If the screen is locked, all key presses are intercepted by the screensaver, including the suspend button.

A fix might be to check your /etc/systemd/logind.conf, here, systemd button handling is configured. If it has HandleSuspendKey=suspend, systemd will initiate a suspend if the suspend button is pressed. However, I'm not sure what the effect will be if your screen is unlocked! You might need to tell your power manager program to ignore suspend button presses. It's hard to give a complete answer, but I hope that this answer will at least give you a nudge in the right direction.

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.