Xfce Forum

Sub domains

You are not logged in.

#1 2022-03-13 17:38:25

Registered: 2022-03-13
Posts: 1

I did some digging into the whole "screen could not be locked" thing

Hi! Been fiddling around w/ XFCE for a couple days while I get Linux working on a friend's computer. big_smile

The other day I was tinkering with the lid behavior and once-over-ing suspend/lock functionality (glad I did...) and I encountered the good ol' "None of the screen lock tools ran successfully, the screen will not be locked" message.

After digging into why a bit.... *sigh* wow I found a bit of a mess. Whatever the stage is after "rabbithole", where things start to feel legitimately scary... I found that. Just a little bit.

This is not strictly a bug report. Bug reports are nice and straightforward and affect one program and involve some "okay so this logic *here* is what very obviously needs fixing". The following is none of those things. Instead I sadly offer you a pile of arrows all pointing at each other, which I can only reasonably evaluate as the byproduct of the limitations of a very human volunteer workforce crashing into scope-of-effort scale issues that can (IMHO) very easily be seen to be honest limitations, and which I regard as such.

So I simply submit The State Of This Situation I Found, which I'm posting here because a) I'm currently running XFCE while experiencing these issues, b) XFCE's power manager is the source of the error popup, and c) I found multiple search results for the XFCE forum while digging around, but none for the GitLab, and realistically speaking the more people that stumble on this, the more accurate data you'll have about how impactful this is in the wild.

To a point I can totally see that some of this info should be in the bugtracker, but I honestly don't think I have enough context (about the bigger picture) to slice and dice this into constructively actionable issues.

I view XFCE substantially as the piano player here. This situation isn't XFCE's fault, and in an ideal world this would all get straightforwardly fixed at a higher level of abstraction.

So, it sounds like I'm describing fixing world hunger here. What's going on...?

I started my journey (after googling the noted infamous error message) at https://superuser.com/a/1568473: an answer that helpfully points straight into the XFCE source, specifically xfce_screensaver_lock(): https://github.com/xfce-mirror/xfce4-po … ver.c#L499

This function analyses which screensaver I'm running and then does whatever the proprietary logical thing is for that screensaver. Cool. So... what's the function actually doing in practice? Let's start by chucking it into gdb and printing saver->priv->screensaver_type!

...Oh. Debian is missing the -dbgsym packages for XFCE. I see some suggestions they may be present in the cross-arch ports, but they're nowhere to be found in the main x86_64 repo. Feature request plz? smile

Alright... we can't do it the nice way; let's drop xfce4-power-manager into strace instead.

244009 sendmsg(6, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="l\1\0\1\0\0\0\0C\0\0\0u\0\0\0\1\1o\0\34\0\0\0/org/freedesktop/ScreenSaver\0\0\0\0\2\1s\0\33\0\0\0org.freedesktop.ScreenSaver\0\0\0\0\0\6\1s\0\7\0\0\0:1.8338\0\10\1g\0\0\0\0\0\3\1s\0\4\0\0\0Lock\0\0\0\0", iov_len=136}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, MSG_NOSIGNAL <unfinished ...>
244007 <... read resumed>"\1\0\0\0\0\0\0\0", 16) = 8
244009 <... sendmsg resumed>)           = 136
244007 poll([{fd=16, events=POLLIN}], 1, 25000 <unfinished ...>
244009 poll([{fd=6, events=POLLIN}, {fd=7, events=POLLIN}, {fd=14, events=POLLIN}], 3, 0) = 0 (Timeout)
244009 poll([{fd=6, events=POLLIN}, {fd=7, events=POLLIN}, {fd=14, events=POLLIN}], 3, -1) = 1 ([{fd=6, revents=POLLIN}])
244009 write(7, "\1\0\0\0\0\0\0\0", 8)  = 8
244009 recvmsg(6, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="l\3\1\1B\0\0\09\0\0\0h\0\0\0", iov_len=16}], msg_iovlen=1, msg_controllen=0, msg_flags=MSG_CMSG_CLOEXEC}, MSG_CMSG_CLOEXEC) = 16
244009 poll([{fd=6, events=POLLIN}], 1, 0) = 1 ([{fd=6, revents=POLLIN}])
244009 recvmsg(6, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="\5\1u\0C\0\0\0\6\1s\0\7\0\0\0:1.8882\0\4\1s\0(\0\0\0org.freedesktop.DBus.Error.UnknownMethod\0\0\0\0\0\0\0\0\10\1g\0\1s\0\0\7\1s\0\7\0\0\0:1.8338\0=\0\0\0Unknown method Lock or interface org.freedesktop.ScreenSaver.\0", iov_len=170}], msg_iovlen=1, msg_controllen=0, msg_flags=MSG_CMSG_CLOEXEC}, MSG_CMSG_CLOEXEC) = 170



After a bit of ineffectual stumbling around with dbus-send and gdbus I learned about d-feet, which let me click around and explore the D-Bus hierarchy (which I have no experience with) and was of great assistance at getting a handle on paths and methods and destinations and figuring out what's going on.

Screenshots can technically disappear and I want this info to be a tad resilient, so explaining the situation using gdbus, we can see that...

$ gdbus introspect -e -d org.freedesktop.ScreenSaver -o /org/freedesktop/ScreenSaver
node /org/freedesktop/ScreenSaver {
  interface org.freedesktop.DBus.Peer {
      GetMachineId(out s machine_uuid);
  interface org.freedesktop.DBus.Introspectable {
      Introspect(out s data);
  interface org.freedesktop.DBus.Properties {
      Get(in  s interface,
          in  s property,
          out v value);
      GetAll(in  s interface,
             out a{sv} properties);
      Set(in  s interface,
          in  s property,
          in  v value);
      PropertiesChanged(s interface,
                        a{sv} changed_properties,
                        as invalidated_properties);
  interface org.freedesktop.ScreenSaver {
      Inhibit(in  s arg_0,
              in  s arg_1,
              out u arg_2);
      UnInhibit(in  u arg_0);

...I don't seem to have a Lock method available. Because of course it isn't available in wat-land.

Double wat.

d-feet showed the service owner of org.freedesktop.ScreenSaver to be "xscreensaver-systemd", which I can also verify using gdbus for completeness:

$ gdbus call --session --dest org.freedesktop.DBus --object-path / --method org.freedesktop.DBus.GetConnectionUnixProcessID org.freedesktop.ScreenSaver
(uint32 8720,)
$ ps aux | grep 8720
i336        8720  0.0  0.0   5712  2884 pts/13   S+   16:10   0:00 xscreensaver-systemd

Checking the (apparently-canonical reference for the) source to xscreensaver-systemd.c (https://github.com/mato/xscreensaver-sy … emd.c#L466) I see a picture that's very consistent with d-feet's and gdbus' view of the DBus side of the fence:

static const sd_bus_vtable
xscreensaver_dbus_vtable[] = {
    SD_BUS_METHOD("Inhibit", "ss", "u", xscreensaver_method_inhibit,
    SD_BUS_METHOD("UnInhibit", "u", "", xscreensaver_method_uninhibit,

So; xscreensaver-systemd doesn't implement Lock, only Inhibit and UnInhibit. Interesting.

I note that xfce4-power-manager is trying to invoke the Lock method because xfce_screensaver_setup() (https://github.com/xfce-mirror/xfce4-po … ver.c#L230) has decided the screensaver is of type SCREENSAVER_TYPE_FREEDESKTOP (solely) because the DBus destination "org.freedesktop.ScreenSaver" is responsive. (xscreensaver-systemd takes ownership of just that destination.)

Right then, let's disable xscreensaver-systemd. Kill it and... OK, it isn't running anymore (and nothing auto-restarted it). Good. Let's try triggering the lid switch again and...

*A wild lock screen appears!*

Yay! It works, I think! Now let's try unlock...ing. Why does... everything feel weirdly... slow all of a sudden...? Oh there we go it just had to catch u--

None of the screen lock tools ran successfully, the screen will not be locked.

OH COME ON SERIOUSLY WHAT IS IT THIS TIME... and why did it appear after a delay after a successful lock and unlock, during which everything slowed down for a minute? What's up with that?

Ok, with xscreensaver-systemd completely out of the picture, it looks like xfce4-power-manager's gone through DBus and picked the MATE screensaver daemon to poke at, which I also have installed (since I wanted to install a mix of desktop environments for comparison purposes, and also present a realistic first impression of the fragmentation of the status quo... touche).

12093 <... read resumed>"\1\0\0\0\0\0\0\0", 16) = 8
12091 read(15,  <unfinished ...>
12093 sendmsg(6, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="l\1\0\1\0\0\0\0O\0\0\0e\0\0\0\1\1o\0\25\0\0\0/org/mate/ScreenSaver\0\0\0\2\1s\0\24\0\0\0org.mate.ScreenSaver\0\0\0\0\6\1s\0\6\0\0\0:1.334\0\0\10\1g\0\0\0\0\0\3\1s\0\4\0\0\0Lock\0\0\0\0", iov_len=120}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, MSG_NOSIGNAL <unfinished ...>
12091 <... read resumed>"\1\0\0\0\0\0\0\0", 16) = 8
12093 <... sendmsg resumed>)            = 120
12091 poll([{fd=15, events=POLLIN}], 1, 25000 <unfinished ...>

This does actually work, and lock the screen. But it has issues of its own that I haven't looked into yet, the biggest being that

$ gdbus call -e -d org.mate.ScreenSaver -o / -m org.mate.ScreenSaver.Lock
Error: Timeout was reached

its DBus interface seems to be somehow broken. To be specific, the invocation above does immediately trigger a screen lock, but when I promptly unlock I come back to a gdbus command that's still waiting to exit... which it finally does about 20 seconds later with the noted error message. Similarly when I invoke the Lock method through d-feet, it puts

'g-io-error-quark: Timeout was reached (24)'

into the Method output field if I leave the Execute D-Bus Method window open for long enough.

I'm not really sure what's up with the MATE screensaver daemon; I note that if I restart it with --no-daemon --debug I see that

[gs_listener_send_signal_active_changed] gs-listener-dbus.c:236 (01:15:13):      Sending the ActiveChanged(TRUE) signal on the session bus
[gs_listener_send_signal_active_changed] gs-listener-dbus.c:236 (01:15:15):      Sending the ActiveChanged(FALSE) signal on the session bus

it does seem to interact with DBus perfectly fine (so it doesn't appear to be internally getting stuck or anything) *after* the lock screen has been dismissed. I don't know whether to interpret a prototype of "Lock () -> ()" as "sends an empty ("()") method return" or "caller should not expect a method return", and who/what is broken here. Given that gdbus also hangs I do wonder if *something* should be being kicked back over DBus. It would seem xfce4-power-manager is also waiting for a reply, and depending on moon alignment and whether the current second ends in a 2, this has variously inhibited opening new terminals (ctrl-alt-t) and generally interacting with my session. I'm not sure if xfce4-power-manager is wedged for the duration or whether something is blocked elsewhere in the chain.

The second issue I noticed, which is even more bizarre, is that when I properly close and reopen the laptop lid (and don't just stuff replayed SW_LID events into /dev/input/event2...) I find that the lockscreen often displays for a fraction of a second (possibly one or two 60fps frames) and then reverts back to the last image on the screen at the time it was locked (which is great for security). I assume this is some sort of pathological interaction with xfwm4's compositor and possibly the Intel driver (on HD Graphics 3000), but whatever it is, the lock screen is still very much engaged despite every pixel on the screen suggesting otherwise, and a) the mouse pointer changes to show where the textboxes are in the lock dialog, and b) I indeed must type the password before the session is usable again. I was thrown for a loop for about a minute before I realized what was going on.

I should probably go ask the MATE folks what's going on about these two... at some point... smile but to be completely honest this *gestures at post* is the realistic limit of my attention span, and I do need to finish setting this computer up here, so... for reference this is a <week old stock install of Debian 11.2, and this Gateway NE56R isn't especially exotic, so... OK I might get to it. tongue

In any case, after uninstalling mate-screensaver (and mate-screensaver-common - which is where the DBus .service file is hiding) to kick xfce4-power-manager into looking further afield, we get to... org.cinnamon.ScreenSaver (dun dun dun), which also shows up in a d-feet search for "screen" and is also in the whitelist of screensavers that xfce4-power-manager specifically looks for.

Before I continue, I note that I never explicitly installed Cinnamon, simply because I hadn't gotten to it yet: the cinnamon and cinnamon-desktop-environment base packages are not installed. *However*, Something™ (I don't know what) pulled in cinnamon-screensaver (along with cinnamon-session, cinnamon-desktop-data, etc), and while I have no idea *what* pulled them in, my point is that I have a known-broken installation of cinnamon-screensaver.

It is thus not surprising that clicking the entry for org.cinnamon.ScreenSaver in d-feet promptly plonks a giant error message onto the screen, and introspecting via gdbus does the same thing:

$ gdbus introspect -e -d org.cinnamon.ScreenSaver -o /
Error: GDBus.Error:org.freedesktop.DBus.Error.Spawn.ChildSignaled: Process org.cinnamon.ScreenSaver received signal 5

Yay. Why?

$ cinnamon-screensaver

(cinnamon-screensaver:13887): GLib-GIO-ERROR **: 02:37:16.024: Settings schema 'org.cinnamon.keyboard' is not installed
Trace/breakpoint trap

huh, a SIGTRAP. Wow.

Alright, ...uh...

$ apt-file search org.cinnamon.keyboard


$ locate org.cinnamon

...ah! So that's how they're formatted:

$ apt-file search org.cinnamon.gschema
cinnamon-common: /usr/share/glib-2.0/schemas/org.cinnamon.gschema.xml

Setting up cinnamon-common (4.8.6-2) ...
Processing triggers for libglib2.0-0:amd64 (2.66.8-1) ...
Processing triggers for hicolor-icon-theme (0.17-2) ...

$ cinnamon-screensaver
Traceback (most recent call last):
  File "/usr/bin/cinnamon-screensaver", line 117, in <module>
    main = Main()
  File "/usr/bin/cinnamon-screensaver", line 61, in __init__
    from service import ScreensaverService
  File "/usr/share/cinnamon-screensaver/service.py", line 9, in <module>
    from manager import ScreensaverManager
  File "/usr/share/cinnamon-screensaver/manager.py", line 10, in <module>
    from stage import Stage
  File "/usr/share/cinnamon-screensaver/stage.py", line 18, in <module>
    from osk import OnScreenKeyboard
  File "/usr/share/cinnamon-screensaver/osk.py", line 5, in <module>
    gi.require_version('Caribou', '1.0')
  File "/usr/lib/python3/dist-packages/gi/__init__.py", line 126, in require_version
    raise ValueError('Namespace %s not available' % namespace)
ValueError: Namespace Caribou not available

fojsoniusecfoibuywerpiuqwroiuywoefiu *sigh*

OK, one caribou package later Cinnamon's screen locker finally works (and looks really nice to boot, I might add).

Til next bug... :v


To close, I have two points.

To users, if your setup is broken, this is sadly the level of spelunking that may be necessary to fix it. Don't be afraid to pull strace out or tackle DBus if it seems necessary, indeed, consider it the new normal - because as much as I don't like it, it's clear this is where the Linux desktop status quo is at now, and it's pretty obvious things are only going to go further in this direction in the future. Platform consistency and user-experience cohesion starts with the users - and while it's often done in a brusque and unreassuring manner, open source uniquely offers agency to motivated users to at least try and dig into problems and holistically understand them (to a limited extent), and offers an incredible opportunity to actually take responsibility for getting stuff fixed. You might not identify exactly how to solve something, but you can still make a difference that is quite hard to do in commercial software. Thank you for attending my amateur TED talk tongue

To the devs, I would say that screen locking obviously must Always Work, and IMHO the heuristics and logic in xfce4-power-manager, which have a measurable impact on system security, are sufficiently simplistic that they are either directly insecure (eg, bailing out and showing a dialog at screen lock time saying "the screen will not be locked"... that's not sane), and/or they supply a sufficiently broken/fragile/temperamental/inconsistent/unpredictable/unstable/disconcerting enough user experience that the user may simply give up and bail at trying to get screen locking properly working (changing Power Manager > System > Laptop Lid > When laptop lid is closed to "Switch off display" completely fixes everything, with the small exception that the system no longer auto-locks), which is just the same end result as "directly insecure" with more steps.

I mention the noise and shuffle of getting Cinnamon working, and pointed out that it was known-broken, as substance for the argument that screen locking needs to completely sidestep this kind of stuff and fail safe by design. I show how my system was broken to demonstrate the kind of squarely off-in-the-weeds edge case that xfce4-power-manager should ideally respond to by throwing its hands up in the air, punting and resorting to some sort of default failsafe.

I note that the second-from-top answer in the StackExchange thread I linked to earlier outlines an approach of replacing the full contents of xfce_screensaver_lock() with the Glib equivalent of system("xflock4"). Perhaps this is an indication that a global user override is in order; yes, it's an admission of defeat that the heuristics don't Just Work™, but IMHO if the user is prepared to take responsibility for how their screen is locked, said presumably-motivated user will also likely be able to carefully evaluate and verify "yes the computer has locked correctly" much more effectively than xfce4-power-manager can... so punting to the user may be the simplest way to solve this whole mess.

I also note that, if I remove cinnamon-screensaver, because for example I might want to just use XScreenSaver (with its OCD-about-security battle-tested unlock dialog), such that there are no screensavers listed in DBus, xfce4-power-manager falls back to running a command, and all that works. Buuuut, if I also want screensaver inhibition to work (for example in mpv)... I'm stuck with whatever special snowflake handshake mpv does with XScreenSaver directly, since firing xscreensaver-systemd back up so I can go through the standard org.freedesktop.ScreenSaver.Inhibit method plonks me back in "the screen will not be locked" land again because xfce4-power-manager once again sees "org.freedesktop.ScreenSaver" and assumes it can call a Lock method on it.

Serious question: how do I solve for this use case?

Zooming out somewhat, I think that it should be appreciably (and comfortingly) straightforward to add *some* resilience to xfce4-power-manager: screen_saver_proxy_setup() could go one step further than simply looking for service owners and declare shenanigans if it doesn't also find a Lock method, for example. A Test button somewhere in the power manager GUI might also be straightforward. Extra debugging (additional debug statements, and maybe even the ability to enable DBG() calls with a commandline argument) could also be helpful. Maybe. I honestly don't have adequate focus and perspective to identify the correct sweet spot between effort and impact in this scenario. I'm definitely out of my depth going beyond just reporting.

On that note, thanks for taking the time to read this.

And thanks very much for XFCE.

Last edited by i336_ (2022-03-13 18:06:08)


Board footer

Powered by FluxBB