! Please note that this is a snapshot of our old Bugzilla server, which is read only since May 29, 2020. Please go to gitlab.xfce.org for our new server !
on 'suspend' : locking only occurs after resume, desktop is visible (with wor...
Status:
RESOLVED: FIXED
Product:
Xfce4-screensaver
Component:
General

Comments

Description squalou.jenkins 2019-09-05 12:14:19 CEST
I have screensaver with lock enabled. Works fine.
When I suspend my laptop (on lid switch most of the time), then I resume, 
- unlocked desktop shows forst for 2 seconds or so
- then only the lock screen appears

It's as if suspend was done before locking mechanism has a chance to trigger, or resume finishes entirely (with desktop show) before locking happens.

NOTE 1 : I see the same behaviour when using 'slock' as a locker, and not specifically xfce4-screensaver .... so maybe this bufg should be filed elsewhere, no idea where though. 

NOTE 2 :  This bug is somehow related to the last reark in this one : https://bugzilla.xfce.org/show_bug.cgi?id=14906
Comment 1 squalou.jenkins 2019-09-05 12:16:06 CEST
Sorry, saved the issue too fast. Here are environment details :

OS : Linux Arch  
kernel: 4.19.58-1-lts #1 SMP Wed Jul 10 18:19:13 CEST 2019 x86_64 GNU/Linux
xfce4-screensaver 0.1.8
Comment 2 squalou.jenkins 2019-09-05 13:47:07 CEST
Here's the --debug log output 


```
xfce4-screensaver --debug
[gs_debug_init] gs-debug.c:115 (13:42:33.545):	 Debugging enabled
[main] xfce4-screensaver.c:97 (13:42:33.546):	 Initializing xfce4-screensaver 0.1.8
[init_session_id] gs-listener-dbus.c:2039 (13:42:33.550):	 Got session-id: /org/freedesktop/login1/session/_32
[gs_listener_x11_set_timeouts] gs-listener-x11.c:312 (13:42:33.550):	 Saver timeout updated to 300 seconds
[gs_listener_x11_acquire] gs-listener-x11.c:288 (13:42:33.551):	 ScreenSaver Registered
[listener_dbus_handle_system_message] gs-listener-dbus.c:1361 (13:42:49.979):	 Handling Logind PrepareForSleep
[listener_dbus_handle_system_message] gs-listener-dbus.c:1367 (13:42:49.980):	 Logind requested session lock
[gs_grab_grab_root] gs-grab-x11.c:347 (13:42:49.980):	 Grabbing the root window
[gs_grab_get] gs-grab-x11.c:104 (13:42:49.992):	 Grabbing devices for window=168
[gs_manager_create_windows_for_display] gs-manager.c:1071 (13:42:50.000):	 Creating 1 windows for display :0.0
[gs_manager_create_window_for_monitor] gs-manager.c:950 (13:42:50.000):	 Creating a Window [0,0] (1920x1080) for monitor 0
[update_geometry] gs-window-x11.c:285 (13:42:50.001):	 Got geometry for monitor: x=0 y=0 w=1920 h=1080
[update_geometry] gs-window-x11.c:297 (13:42:50.002):	 Using geometry for monitor: x=0 y=0 w=1920 h=1080
[gs_window_set_lock_active] gs-window-x11.c:1605 (13:42:50.002):	 Setting lock active: 1
[get_best_visual_for_display] gs-window-x11.c:476 (13:43:00.527):	 Found best GL visual for display :0.0: 0x111
[update_geometry] gs-window-x11.c:285 (13:43:00.527):	 Got geometry for monitor: x=0 y=0 w=1920 h=1080
[update_geometry] gs-window-x11.c:297 (13:43:00.527):	 Using geometry for monitor: x=0 y=0 w=1920 h=1080
[update_geometry] gs-window-x11.c:285 (13:43:00.527):	 Got geometry for monitor: x=0 y=0 w=1920 h=1080
[update_geometry] gs-window-x11.c:297 (13:43:00.527):	 Using geometry for monitor: x=0 y=0 w=1920 h=1080
[gs_window_move_resize_window] gs-window-x11.c:330 (13:43:00.535):	 Move and/or resize window: x=0 y=0 w=1920 h=1080
[update_geometry] gs-window-x11.c:285 (13:43:00.536):	 Got geometry for monitor: x=0 y=0 w=1920 h=1080
[update_geometry] gs-window-x11.c:297 (13:43:00.536):	 Using geometry for monitor: x=0 y=0 w=1920 h=1080
[gs_window_move_resize_window] gs-window-x11.c:330 (13:43:00.536):	 Move and/or resize window: x=0 y=0 w=1920 h=1080
[update_geometry] gs-window-x11.c:285 (13:43:00.536):	 Got geometry for monitor: x=0 y=0 w=1920 h=1080
[update_geometry] gs-window-x11.c:297 (13:43:00.536):	 Using geometry for monitor: x=0 y=0 w=1920 h=1080
[gs_window_move_resize_window] gs-window-x11.c:330 (13:43:00.536):	 Move and/or resize window: x=0 y=0 w=1920 h=1080
[gs_window_clear] gs-window-x11.c:225 (13:43:00.537):	 Clearing widgets
[widget_clear_all_children] gs-window-x11.c:208 (13:43:00.537):	 Clearing all child windows
[widget_clear_all_children] gs-window-x11.c:208 (13:43:00.538):	 Clearing all child windows
[window_show_cb] gs-manager.c:782 (13:43:00.544):	 Handling window show
[gs_job_set_command] gs-job.c:219 (13:43:00.561):	 Setting command for job: 'NULL'
[add_dpms_timer] gs-manager.c:561 (13:43:00.561):	 Scheduling DPMS change after screensaver is idling for 5 minute
[gs_listener_send_signal_active_changed] gs-listener-dbus.c:222 (13:43:00.561):	 Sending the ActiveChanged(TRUE) signal on the session bus
[listener_dbus_handle_system_message] gs-listener-dbus.c:1361 (13:43:00.562):	 Handling Logind PrepareForSleep
[listener_dbus_handle_system_message] gs-listener-dbus.c:1373 (13:43:00.562):	 Logind requested session unlock
[find_window_at_pointer] gs-manager.c:621 (13:43:00.562):	 Requesting unlock for display :0.0
[find_window_at_pointer] gs-manager.c:621 (13:43:00.596):	 Requesting unlock for display :0.0
[window_dialog_up_changed_cb] gs-manager.c:880 (13:43:00.596):	 Handling window dialog up changed: up
[handle_window_dialog_up] gs-manager.c:810 (13:43:00.596):	 Handling dialog up
[handle_window_dialog_up] gs-manager.c:825 (13:43:00.596):	 Initiate pointer-less grab move to 0x5630bcc1e370
[gs_grab_move] gs-grab-x11.c:203 (13:43:00.596):	 Moving devices grab from 168 to 380000C
[gs_grab_move] gs-grab-x11.c:211 (13:43:00.596):	 *** Doing X server grab
[gs_grab_release] gs-grab-x11.c:170 (13:43:00.596):	 Ungrabbing devices
[gs_grab_get] gs-grab-x11.c:104 (13:43:00.596):	 Grabbing devices for window=380000C
[gs_grab_release] gs-grab-x11.c:170 (13:43:00.596):	 Ungrabbing devices
[gs_grab_get] gs-grab-x11.c:125 (13:43:00.596):	 Regrabbing keyboard
[gs_grab_move] gs-grab-x11.c:241 (13:43:00.597):	 *** Releasing X server grab
[handle_window_dialog_up] gs-manager.c:832 (13:43:00.597):	 Suspending jobs
[gs_job_suspend] gs-job.c:527 (13:43:00.597):	 Suspending job
[gs_window_xevent] gs-window-x11.c:628 (13:43:00.597):	 Not raising our windows
[window_map_event_cb] gs-manager.c:744 (13:43:00.597):	 Handling window map_event event
[manager_maybe_grab_window] gs-manager.c:664 (13:43:00.597):	 Initiate grab move to 0x5630bcc1e370
[gs_grab_move] gs-grab-x11.c:203 (13:43:00.597):	 Moving devices grab from 380000C to 380000C
[gs_grab_move] gs-grab-x11.c:211 (13:43:00.597):	 *** Doing X server grab
[gs_grab_release] gs-grab-x11.c:170 (13:43:00.597):	 Ungrabbing devices
[gs_grab_get] gs-grab-x11.c:104 (13:43:00.597):	 Grabbing devices for window=380000C
[gs_grab_move] gs-grab-x11.c:241 (13:43:00.597):	 *** Releasing X server grab
[manager_maybe_start_job_for_window] gs-manager.c:160 (13:43:00.597):	 Not starting job because dialog is up
[window_obscured_cb] gs-manager.c:793 (13:43:00.598):	 Handling window obscured: obscured
[gs_job_stop] gs-job.c:499 (13:43:00.598):	 Stopping job
[gs_job_stop] gs-job.c:502 (13:43:00.598):	 Could not stop job: pid not defined
[window_obscured_cb] gs-manager.c:793 (13:43:00.598):	 Handling window obscured: unobscured
[manager_maybe_start_job_for_window] gs-manager.c:160 (13:43:00.598):	 Not starting job because dialog is up
[gs_window_xevent] gs-window-x11.c:628 (13:43:00.598):	 Not raising our windows
[update_geometry] gs-window-x11.c:285 (13:43:00.600):	 Got geometry for monitor: x=0 y=0 w=1920 h=1080
[update_geometry] gs-window-x11.c:297 (13:43:00.600):	 Using geometry for monitor: x=0 y=0 w=1920 h=1080
[gs_window_move_resize_window] gs-window-x11.c:330 (13:43:00.600):	 Move and/or resize window: x=0 y=0 w=1920 h=1080
[update_geometry] gs-window-x11.c:285 (13:43:00.600):	 Got geometry for monitor: x=0 y=0 w=1920 h=1080
[update_geometry] gs-window-x11.c:297 (13:43:00.600):	 Using geometry for monitor: x=0 y=0 w=1920 h=1080
[gs_window_move_resize_window] gs-window-x11.c:330 (13:43:00.601):	 Move and/or resize window: x=0 y=0 w=1920 h=1080
[popup_dialog] gs-window-x11.c:1516 (13:43:00.601):	 Popping up dialog
[popup_dialog] gs-window-x11.c:1552 (13:43:00.602):	 Executing /usr/lib/xfce4-screensaver-dialog --monitor='0' --height='1080' --width='1920' --verbose
[gs_window_xevent] gs-window-x11.c:640 (13:43:00.605):	 Not raising our windows
[update_geometry] gs-window-x11.c:285 (13:43:00.619):	 Got geometry for monitor: x=0 y=0 w=1920 h=1080
[update_geometry] gs-window-x11.c:297 (13:43:00.619):	 Using geometry for monitor: x=0 y=0 w=1920 h=1080
[gs_window_move_resize_window] gs-window-x11.c:330 (13:43:00.619):	 Move and/or resize window: x=0 y=0 w=1920 h=1080
[update_geometry] gs-window-x11.c:285 (13:43:00.619):	 Got geometry for monitor: x=0 y=0 w=1920 h=1080
[update_geometry] gs-window-x11.c:297 (13:43:00.619):	 Using geometry for monitor: x=0 y=0 w=1920 h=1080
[gs_window_move_resize_window] gs-window-x11.c:330 (13:43:00.619):	 Move and/or resize window: x=0 y=0 w=1920 h=1080
[error_watch] gs-window-x11.c:892 (13:43:00.676):	 Command output: [gs_debug_init] gs-debug.c:115 (13:43:00.675):	 Debugging enabled

[error_watch] gs-window-x11.c:892 (13:43:00.713):	 Command output: [redraw_background] gs-lock-plug.c:1423 (13:43:00.713):	 Redrawing background

[dialog_process_watch] gs-window-x11.c:1404 (13:43:00.805):	 Command output: WINDOW ID=148897798

[gs_window_xevent] gs-window-x11.c:640 (13:43:00.808):	 Not raising our windows
[update_geometry] gs-window-x11.c:285 (13:43:00.808):	 Got geometry for monitor: x=0 y=0 w=1920 h=1080
[update_geometry] gs-window-x11.c:297 (13:43:00.808):	 Using geometry for monitor: x=0 y=0 w=1920 h=1080
[gs_window_move_resize_window] gs-window-x11.c:330 (13:43:00.808):	 Move and/or resize window: x=0 y=0 w=1920 h=1080
[update_geometry] gs-window-x11.c:285 (13:43:00.808):	 Got geometry for monitor: x=0 y=0 w=1920 h=1080
[update_geometry] gs-window-x11.c:297 (13:43:00.808):	 Using geometry for monitor: x=0 y=0 w=1920 h=1080
[gs_window_move_resize_window] gs-window-x11.c:330 (13:43:00.808):	 Move and/or resize window: x=0 y=0 w=1920 h=1080
[gs_window_xevent] gs-window-x11.c:628 (13:43:00.808):	 Not raising our windows
[gs_window_xevent] gs-window-x11.c:640 (13:43:00.808):	 Not raising our windows
[gs_window_xevent] gs-window-x11.c:640 (13:43:00.809):	 Not raising our windows
[gs_window_xevent] gs-window-x11.c:628 (13:43:00.809):	 Not raising our windows
[gs_window_xevent] gs-window-x11.c:628 (13:43:00.809):	 Not raising our windows
[error_watch] gs-window-x11.c:892 (13:43:00.973):	 Command output: [auth_message_handler] xfce4-screensaver-dialog.c:236 (13:43:00.973):	 Got message style 1: 'Password: '

[error_watch] gs-window-x11.c:892 (13:43:00.974):	 Command output: [gs_lock_plug_enable_prompt] gs-lock-plug.c:1104 (13:43:00.974):	 Setting prompt to: 

[error_watch] gs-window-x11.c:892 (13:43:04.320):	 Command output: [request_response] xfce4-screensaver-dialog.c:148 (13:43:04.320):	 Got response: -2

[error_watch] gs-window-x11.c:892 (13:43:04.455):	 Command output: [do_auth_check] xfce4-screensaver-dialog.c:304 (13:43:04.454):	 Verify user returned: TRUE

[dialog_process_watch] gs-window-x11.c:1404 (13:43:04.455):	 Command output: RESPONSE=OK

[dialog_process_watch] gs-window-x11.c:1418 (13:43:04.455):	 Got OK response
[gs_window_dialog_finish] gs-window-x11.c:1327 (13:43:04.455):	 Dialog finished
[keyboard_process_finish] gs-window-x11.c:1197 (13:43:04.455):	 Keyboard finished
[gs_window_clear] gs-window-x11.c:225 (13:43:04.461):	 Clearing widgets
[widget_clear_all_children] gs-window-x11.c:208 (13:43:04.461):	 Clearing all child windows
[widget_clear_all_children] gs-window-x11.c:208 (13:43:04.461):	 Clearing all child windows
[window_dialog_up_changed_cb] gs-manager.c:880 (13:43:04.461):	 Handling window dialog up changed: down
[handle_window_dialog_down] gs-manager.c:848 (13:43:04.461):	 Handling dialog down
[gs_grab_move] gs-grab-x11.c:197 (13:43:04.461):	 Window 380000C is already grabbed, skipping
[manager_maybe_start_job_for_window] gs-manager.c:175 (13:43:04.461):	 Starting job for window
[gs_job_start] gs-job.c:453 (13:43:04.461):	 Starting job
[gs_job_start] gs-job.c:468 (13:43:04.461):	 No command set for job.
[add_dpms_timer] gs-manager.c:561 (13:43:04.461):	 Scheduling DPMS change after screensaver is idling for 5 minute
[gs_window_xevent] gs-window-x11.c:640 (13:43:04.461):	 Not raising our windows
[gs_window_xevent] gs-window-x11.c:628 (13:43:04.461):	 Not raising our windows
[update_geometry] gs-window-x11.c:285 (13:43:04.462):	 Got geometry for monitor: x=0 y=0 w=1920 h=1080
[update_geometry] gs-window-x11.c:297 (13:43:04.462):	 Using geometry for monitor: x=0 y=0 w=1920 h=1080
[gs_window_move_resize_window] gs-window-x11.c:330 (13:43:04.462):	 Move and/or resize window: x=0 y=0 w=1920 h=1080
[update_geometry] gs-window-x11.c:285 (13:43:04.462):	 Got geometry for monitor: x=0 y=0 w=1920 h=1080
[update_geometry] gs-window-x11.c:297 (13:43:04.462):	 Using geometry for monitor: x=0 y=0 w=1920 h=1080
[gs_window_move_resize_window] gs-window-x11.c:330 (13:43:04.462):	 Move and/or resize window: x=0 y=0 w=1920 h=1080
[gs_grab_release] gs-grab-x11.c:170 (13:43:04.462):	 Ungrabbing devices
[gs_job_stop] gs-job.c:499 (13:43:04.462):	 Stopping job
[gs_job_stop] gs-job.c:502 (13:43:04.462):	 Could not stop job: pid not defined
[gs_window_dialog_finish] gs-window-x11.c:1327 (13:43:04.466):	 Dialog finished
[keyboard_process_finish] gs-window-x11.c:1197 (13:43:04.466):	 Keyboard finished
[gs_window_clear] gs-window-x11.c:225 (13:43:04.466):	 Clearing widgets
[widget_clear_all_children] gs-window-x11.c:208 (13:43:04.466):	 Clearing all child windows
[widget_clear_all_children] gs-window-x11.c:208 (13:43:04.466):	 Clearing all child windows
[gs_window_dialog_finish] gs-window-x11.c:1327 (13:43:04.468):	 Dialog finished
[keyboard_process_finish] gs-window-x11.c:1197 (13:43:04.468):	 Keyboard finished
[gs_listener_send_signal_active_changed] gs-listener-dbus.c:222 (13:43:04.468):	 Sending the ActiveChanged(FALSE) signal on the session bus
```
Comment 3 squalou.jenkins 2019-09-08 09:29:39 CEST
Workaround available : using systemd 'sleep' hook to delay 1second the post-resume.

Compared to this article, create a file called /etc/systemd/system/suspend@my-usename.service  (replacing my-username by ... your username :) ) instead of /etc/systemd/system/suspend@.service

https://wiki.archlinux.org/index.php/Power_management#Suspend/resume_service_files
Comment 4 Michael Weiser 2019-09-23 19:37:57 CEST
Created attachment 9051 
Add systemd sleep inhibitor

Looking at the timestamps in debug output it seems to me that systemd is simply suspending too fast for xfce4-screensaver to activate the lock screen. Indeed according to debug messages handling of PrepareForSleep happens only after resume:

# src/xfce4-screensaver --debug --no-daemon
[gs_debug_init] gs-debug.c:115 (02:22:43.147):	 Debugging enabled
[main] xfce4-screensaver.c:97 (02:22:43.147):	 Initializing xfce4-screensaver 0.1.8
[init_session_id] gs-listener-dbus.c:2039 (02:22:43.153):	 Got session-id: /org/freedesktop/login1/session/_34
[gs_listener_x11_set_timeouts] gs-listener-x11.c:312 (02:22:43.153):	 Saver timeout updated to 300 seconds
[gs_listener_x11_set_timeouts] gs-listener-x11.c:318 (02:22:43.153):	 Lock timeout updated to 60 seconds
[gs_listener_x11_acquire] gs-listener-x11.c:288 (02:22:43.154):	 ScreenSaver Registered
<Lid close>
<System asleep for about 7 seconds>
<Lid open>
<Desktop visible for about 1 second>
[listener_dbus_handle_system_message] gs-listener-dbus.c:1361 (02:22:52.025):	 Handling Logind PrepareForSleep
[listener_dbus_handle_system_message] gs-listener-dbus.c:1367 (02:22:52.025):	 Logind requested session lock
[gs_grab_grab_root] gs-grab-x11.c:347 (02:22:52.025):	 Grabbing the root window
<Lock screen is activated>

Adding a sleep delay inhibitor lock[1] makes the problem go away since it gives xfce4-screensaver time to activate the lock screen before allowing systemd to continue suspending the system:

# src/xfce4-screensaver --debug --no-daemon
[gs_debug_init] gs-debug.c:115 (02:27:23.132):	 Debugging enabled
[main] xfce4-screensaver.c:97 (02:27:23.132):	 Initializing xfce4-screensaver 0.1.8
[init_session_id] gs-listener-dbus.c:2116 (02:27:23.137):	 Got session-id: /org/freedesktop/login1/session/_34
[gs_listener_init] gs-listener-dbus.c:2142 (02:27:23.137):	 Acquiring logind sleep inhibitor lock
[gs_listener_x11_set_timeouts] gs-listener-x11.c:312 (02:27:23.139):	 Saver timeout updated to 300 seconds
[gs_listener_x11_set_timeouts] gs-listener-x11.c:318 (02:27:23.139):	 Lock timeout updated to 60 seconds
[gs_listener_x11_acquire] gs-listener-x11.c:288 (02:27:23.140):	 ScreenSaver Registered
<Lid close>
[listener_dbus_handle_system_message] gs-listener-dbus.c:1432 (02:27:28.585):	 Handling Logind PrepareForSleep
[listener_dbus_handle_system_message] gs-listener-dbus.c:1438 (02:27:28.585):	 Logind requested session lock
[gs_grab_grab_root] gs-grab-x11.c:347 (02:27:28.585):	 Grabbing the root window
[...]
<System asleep for about 7 seconds>
<Lid open>
<Lock screen immediately present>
[listener_dbus_handle_system_message] gs-listener-dbus.c:1432 (02:27:36.807):	 Handling Logind PrepareForSleep
[listener_dbus_handle_system_message] gs-listener-dbus.c:1447 (02:27:36.807):	 Reinstating logind sleep inhibitor lock
[listener_dbus_handle_system_message] gs-listener-dbus.c:1450 (02:27:36.810):	 Logind requested session unlock

The attached patch is tested with systemd 243rc2 and xfce4-screensaver git HEAD (github mirror) and 0.1.8 release. A quick read of ConsoleKit docs suggests they have a similar interface for the same reason so that it should work with CK as well.

[1] https://www.freedesktop.org/wiki/Software/systemd/inhibit/#takingdelaylocks
Comment 5 Michael Weiser 2019-11-30 12:49:41 CET
I've been using my patch for some time now without problems and solving this delayed locking on resume problem for me. How can I help to get it into xfce4-screensaver for good?
Comment 6 Jarno Suni 2019-12-31 13:43:32 CET
related report https://bugzilla.xfce.org/show_bug.cgi?id=10089
Comment 7 Jarno Suni 2019-12-31 13:58:05 CET
If you disable locking on suspend in xfce4-screensaver settings and use 

xflock4 && xfce4-session-logout -s

on terminal instead for suspending, does that help?
Comment 8 Michael Weiser 2019-12-31 14:47:57 CET
No, if I compile xfce4-screensaver without my inhibitor patch, disable locking on suspend and call the command sequence (where xflock4 in my case obviously calls xfce4-screensaver --lock), I get an immediate suspend and can see the desktop for half a second upon resume. If I add the patch back in, suspend seems to take about a second longer and the lock screen is reliably present and the desktop invisible upon resume. So systemd still seems to be too fast in suspending even when calling xflock4 explicitly.
Comment 9 Jarno Suni 2019-12-31 16:16:36 CET
The race condition should be handled so that xflock4 does not exit before it has locked the screen (if possible) which does not seem to be the case with xfce4-screensaver.
Comment 10 Michael Weiser 2019-12-31 18:07:03 CET
Unfortunately, suspend is a very complex subject on Linux, aggravated by the number of possibilities how the user can trigger it, how the desktop environment becomes aware of it, how the system then actually does it, the large number of components involved (systemd/pm-utils/acpi/consolekit/policykit/xfce4-{session,power-manager,screensaver}/dbus) and their complex interactions via command and dbus calls. This extends into the DE as well: Calling xflock4 is not the only way how other XFCE components interact with the screensaver (more below).

In my case, and this seems to be the default nowadays, I have systemd handling power management actions. This is configured in /etc/systemd/logind.conf by actually not configuring anything:

[Login]
[...]
#InhibitDelayMaxSec=5
#HandlePowerKey=poweroff
#HandleSuspendKey=suspend
#HandleHibernateKey=hibernate
#HandleLidSwitch=suspend
#HandleLidSwitchExternalPower=suspend
#HandleLidSwitchDocked=ignore
#PowerKeyIgnoreInhibited=no
#SuspendKeyIgnoreInhibited=no
#HibernateKeyIgnoreInhibited=no
#LidSwitchIgnoreInhibited=yes

xfce4-power-manager integrates with systemd by taking over handling of power management events in order to potentially present the user with a UI before executing some action. It does this by registering an inhibitor lock of type block for power management key press events:

# systemd-inhibit
WHO                 UID  USER PID     COMM            WHAT                                                     WHY                                       MODE
NetworkManager      0    root 1055    NetworkManager  sleep                                                    NetworkManager needs to turn off networks delay
UPower              0    root 1560    upowerd         sleep                                                    Pause device polling                      delay
xfce4-power-manager 1000 m    2959932 xfce4-power-man handle-power-key:handle-suspend-key:handle-hibernate-key xfce4-power-manager handles these events  block

Pressing the power button may then e.g. trigger display of the XFCE logout dialog where the user may chose suspend. In this case, xfce4-power-manager actually tries to do lots of stuff explicitly and sequentially, e.g. triggering NetworkManager to shut down network interfaces and the screensaver to lock the screen. Then it will do a DBus call into systemd's logind to trigger the actual suspend (for which it has not registered an inhibitor).

According to xfce4-power-manager-1.6.5/src/xfce-screensaver.c:xfce_screensaver_lock(), xfce4-power-manager will not call xflock4 if it can reach the screensaver via DBus. It knows about and tries the DBus interfaces of Freedesktop, Gnome, Mate and XFCE screensavers, the latter being implemented by xfce4-screeensaver. xfce4-screensaver-command, which is used by xflock4, also uses DBus.

I have no deeper knowledge of DBus but would expect service implementors to be careful with strictly synchronous behaviour here to avoid live- and deadlocks through dbus call cycles. So a response from the screensaver to the Lock DBus call should IMO be taken to mean "I will lock the screen" and not "I have locked the screen".

This seems to be what NetworkManager does, as can be told by a number of sleep calls in the NetworkManager code:

xfpm-network-manager.c:xfpm_network_manager_sleep():
[...]
    /* Sleep 0.5 second to allow the nm applet to disconnect*/
    g_usleep (500000);

xfpm-power.c:xfpm_power_sleep():
[...]
    if ( lock_screen )
    {
#ifdef WITH_NETWORK_MANAGER
        if ( network_manager_sleep )
        {
            /* 2 seconds, to give network manager time to sleep */
            g_usleep (2000000);
        }
#endif

Also, in my case, xfce4-power-manager does not register for handling the lid switch event even though I have configured it to suspend on lid switch. This may be a bug.

I have not looked into that though, because having xfce4-power-manager try to do a synchronous suspend sequence with an inherently asynchronous DBus handling a large number of external components with widely varying implementations is IMO bound to fail miserably and completely unnecessary *if* systemd/logind is available. (Knowing nothing about ConsoleKit, the code suggests that it provides functionality similar to logind.)

In the case of logind, each individual component that needs to do stuff before being suspended can register their own suspend inhibitor. As can be seen from the output of systemd-inhibit above, NetworkManager already does this. So all the DBus and sleep cruft in xfce4-power-manager becomes completely unnecessary (again: *if* logind is available). My patch adds the same for xfce4-screensaver:

# systemd-inhibit | grep screen
xfce4-screensaver   1000 m    1639 xfce4-screensav sleep                                                    Locking screen before sleep               delay

To summarize: Working with a suspend inhibitor provides a self-organizing call sequence synchronized by systemd's logind as the central component:

1. Power Button pressed
2. standard action in systemd suppressed by block inhibitor for power button key
3. xfce4-power-manager triggered via inhibitor
4. Suspend selected by user in UI
5. suspend triggered via dbus by xfce4-power-manager
6. suspend delayed by suspend inhibitor locks
7. NetworkManager triggered by inhibitor lock releases network interfaces
8. xfce4-screensaver triggered by inhibitor lock locks screen
9. suspend carried out by systemd after NetworkManager and xfce4-screensaver release inhibitor locks

Hope this helps clarify the intention here.
Comment 11 Jarno Suni 2020-01-01 22:10:16 CET
I can not reproduce this bug with xfce4-screensaver (0.1.8) or slock in Xubuntu 19.10 (that uses systemd). 

Using DBUS service has been discussed in https://bugzilla.xfce.org/show_bug.cgi?id=15310

Bug https://bugzilla.xfce.org/show_bug.cgi?id=10610 may be relevant in general case.

Special note: if I use xscreensaver and if I have set display fading for xscreensaver, the fading process may finish only after resuming from suspend. Currently, there is a bug in xscreensaver related to that issue: https://bugs.launchpad.net/ubuntu/+source/xscreensaver/+bug/1858027
Comment 12 Michael Weiser 2020-01-01 23:34:07 CET
> I can not reproduce this bug with xfce4-screensaver (0.1.8) or slock in Xubuntu 19.10 (that uses systemd). 
  
As I tried to show in comment 4, in my case xfce4-screensaver clearly does not get a chance to lock the screen before the system is suspended. What does it look like in your case?

> Using DBUS service has been discussed in https://bugzilla.xfce.org/show_bug.cgi?id=15310

This sounds like exactly the kind of live/deadlock problem I was talking about that needs to be avoided. Falling back to shell scripts certainly gives users a chance to tweak and work around it. But waiting for some seconds somewhere can IMO only ever serve as a band-aid and will never fully solve the underlying problem.

As the log in comment 4 shows, in my case logind is actually the one requesting the session lock via xfce4-screensaver's DBus service ("Logind requested session lock" in xfce4-screensaver-0.1.8/src/gs-listener-dbus.c:listener_dbus_handle_system_message()). So logind lid switch handling seems to be a supported mechanism of triggering screen locking.

But then xfce4-screensaver is not given enough time to actually lock the screen. systemd developers are aware of the problem and provide inhibitor locks as a remedy. So if we're doing the one, why not do the other?

I have also now found why xfce4-power-manager is not registering a block inhibitor for lid switch events: There is a setting logind-handle-lid-switch which gets set to true if "Lock screen when going to sleep" is on and the lid action for either "on battery" or "on ac" condition is set to "suspend". The relevant code is in xfce4-power-manager-1.6.5/settings/xfpm-settings.c:xfpm_update_logind_handle_lid_switch() and reads:

    // logind-handle-lid-switch = true when: lock_on_suspend == true and (lid_switch_on_ac == suspend or lid_switch_on_battery == suspend)
    xfconf_channel_set_bool (channel, XFPM_PROPERTIES_PREFIX LOGIND_HANDLE_LID_SWITCH, lock_on_suspend && (lid_switch_on_ac == 1 || lid_switch_on_battery == 1));

If logind-handle-lid-switch is true, xfce4-power-manager will not register the block inhibitor for lid switch events. So it is actively deferring lid switch handling to logind when an actual system sleep is to be expected. That means it is accepted that it will not get a chance to explicitly trigger any preparatory actions before suspend. This is not a problem if all other components which need to do preparations before sleep have registered their own inhibitors as I propose for xfce4-screensaver here.

As is to be expected, the screen is indeed locked by xfce4-power-manager when I set the lid switch action to "lock screen", since nothing else is going to happen in this case, particularly nothing triggered by logind. Or to phrase it the other way around: The whole point of intercepting the lid switch action through the block inhibitor lock by xfce4-power-manager is to prevent system sleep and do something else instead. But *if* a system sleep is indeed what the user wants, xfce4-power-manager totally defers to logind for that and xfce4-screensaver needs to (and can) handle that without power manager's help.
Comment 13 Jarno Suni 2020-01-02 00:13:47 CET
Is the problem specific to suspending by closing the lid? I am using a PC so I did not test.
Comment 14 Michael Weiser 2020-01-02 01:25:27 CET
No. As said in comment 8 it also happens with other means of triggering suspend.
Comment 15 Michael Weiser 2020-01-10 11:35:01 CET
BTW: mate-screensaver has the same thing: https://github.com/mate-desktop/mate-screensaver/blob/master/src/gs-listener-dbus.c#L1620. Ironically, according to the commit message (https://github.com/mate-desktop/mate-screensaver/commit/234e5c835559b0afe56c2af246e2148ac5b47a07), they ported the PrepareForSleep bit back from xfss and added the inhibitor lock for exactly the same reason we're discussing here.
Comment 16 Git Bot editbugs 2020-01-15 11:33:50 CET
Michael Weiser referenced this bugreport in commit f2d07a3736f6767e69bb1e1ab3e3efbe068d199d

Add systemd sleep inhibitor (bug #15929)

https://git.xfce.org/apps/xfce4-screensaver/commit?id=f2d07a3736f6767e69bb1e1ab3e3efbe068d199d
Comment 17 Sean Davis editbugs 2020-01-15 11:34:23 CET
This patch seems acceptable to me. Applied above.

Bug #15929

Reported by:
squalou.jenkins
Reported on: 2019-09-05
Last modified on: 2020-01-15

People

Assignee:
Sean Davis
CC List:
2 users

Version

Version:
unspecified

Attachments

Add systemd sleep inhibitor (4.53 KB, patch)
2019-09-23 19:37 CEST , Michael Weiser
no flags

Additional information