Kubuntu screensaver xdg-screensaver broken

Bug #310351 reported by Al Williams on 2008-12-21
38
This bug affects 6 people
Affects Status Importance Assigned to Milestone
Xdg-utils
Unknown
Medium
xdg-utils (Debian)
Confirmed
Unknown
xdg-utils (Ubuntu)
Undecided
Unassigned

Bug Description

Binary package hint: kscreensaver

xdg-screensaver returns "bad call" for all values tested. Looking at the script, I'd guess it is because it detects the KDE desktop and tries to
use dcop when KDE4 has moved to dbus, but that's just a guess.

For example:
$ xdg-screensaver activate
call failed

lsb_release -rd -> Ubuntu 8.10
Flavor is kbuntu

Jonathan Thomas (echidnaman) wrote :

Yes, looking at the script dcop is the only method used when KDE is detected.

Hi,

Under KDE4, instead of calling the DBUS method UnInhibit, the script xdg-screensaver calls the method SetActive. This starts the screensaver immediately, and this is absolutely not the expected behaviour.

The function screensaver_freedesktop() in the script is broken (and there are some FIXME's around). Here's a diff of what it should look like:

diff --git a/usr/bin/xdg-screensaver b/xdg-screensaver
index 29e8e18..015cc2e 100755
--- a/usr/bin/xdg-screensaver
+++ b/xdg-screensaver
@@ -558,13 +558,13 @@ screensaver_freedesktop()
 {
     case "$1" in
         suspend)
- #FIXME (get/store cookie)
- qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.Inhibit $window_id xdg-screensaver > /dev/null
+ qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.Inhibit $window_id xdg-screensaver >| "$screensaver_file.cookie" 2> /dev/null
         result=$?
         ;;

         resume)
- qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.SetActive true > /dev/null
+ qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.UnInhibit `cat "$screensaver_file.cookie"` > /dev/null
+ rm -f "$screensaver_file.cookie"
         result=$?
         ;;

@@ -578,8 +578,8 @@ screensaver_freedesktop()
         ;;

         reset)
- #FIXME (cookies?)
- qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.UnInhibit $window_id > /dev/null
+ qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.UnInhibit `cat "$screensaver_file.cookie"` > /dev/null
+ rm -f "$screensaver_file.cookie"
         result=$?
         ;;

Best regards,

Thanks!

fabo, I'm going ahead and committing this (holler at me if you had something else in mind).

Now, if some kind soul could translate the (easier) qdbus calls to dbus-send ... :)

Hi, thanks a lot for being so quick!
I hope this will fix the issues I had, I'll keep you in touch if there are still problems.

Best regards,

Hello guys,

I think there is still a problem with the inhibition mechanism on KDE4 (and maybe any DE that uses the DBus interface). The call to the Inhibit method can't work because the calling process (qdbus or dbus-send) exits immediately.
Here's what the specification states:

        Name: Inhibit
        Args: DBUS_TYPE_STRING "application-name"
                        DBUS_TYPE_STRING "reason for inhibit"
        Returns: INT cookie
                        This is a random number used to identify the
                        request.
        Description: Request that saving the screen due to system
                        idleness be blocked until UnInhibit is called or the
                        calling process exits.

Found at:
http://lists.freedesktop.org/archives/xdg/2007-March/009187.html
(no idea at what point this reflects the actual implementation)

This kind of sucks, and the screensaver indeed activates itself as if no call to Inhibit were passed. (no matter what value I use as "application-name")
Using qdbusviewer and a small Qt program (processes that do not exit), I have been able to prevent the screensaver activation.

Sorry, I have no patch this time, I don't see any way to pass a call
from a Shell script without exiting :-(

Best regards and thanks again.

True, seems to me this interfaces was written not with xdg-utils in mind, and that apps should use the dbus method directly themselves.

Rémi Denis-Courmont (rdenis) wrote :

Upstream CVS xdg-screensaver was "fixed" to use DBus. It still does not work with KDE4 though.

Changed in xdg-utils:
status: Unknown → Confirmed
Changed in xdg-utils (Debian):
status: Unknown → Confirmed

Created an attachment (id=38251)
Use SimulateUserActivity. instead of Inhibit for D-Bus screensavers

The screensaver_freedesktop Inhibit call only prevents the screensaver from activating during the lifetime of the calling process. Unfortunately, since xdg-screensaver uses dbus-send to send the request, it expires as soon as the dbus-send process terminates.

Therefore, this patch changes the screensaver_freedesktop to use SimulateUserActivity in a screensaver_suspend_loop.

The ideal solution would be to change the specification for the D-Bus interface to either allow an option "OnBehalfOf" argument for the Inhibit method call or to add a new method allowing an application to send a request for another application. The D-Bus interface for the screensavers seems to have been created by freedesktop.org, so perhaps the Portland group can apply some pressure to the D-Bus interface designers so that we can finally have one application that allows interfacing with all screensavers--even those that don't, and won't ever, support D-Bus (like xscreensaver).

Changed in xdg-utils:
importance: Unknown → Medium
Changed in xdg-utils:
importance: Medium → Unknown
Changed in xdg-utils:
importance: Unknown → Medium
Changed in xdg-utils (Ubuntu):
status: New → Confirmed

Created attachment 111737
Patch to fix this bug

This patch fixes the bug. It necessitates a helper Perl script.

I'll have to think about this more, not keen on adding any perl dependencies.

What about the patch described in comment #6 ( https://bugs.freedesktop.org/show_bug.cgi?id=26085#c6 )? It uses the same exact approach as was used for GNOME screensaver as accepted in https://bugs.freedesktop.org/show_bug.cgi?id=29860 , specifically using SimulateUserActivity, which is already part of xdg-screensaver and it does not require any other helper scripts.

The SimulateActivity interface is not actually specified in the fd.o spec: http://people.freedesktop.org/~hadess/idle-inhibition-spec/re01.html

The only methods offered there are Inhibit and UnInhibit.

SimulateActivity is not implemented in GNOME 3, so the patch will not work there. The route I suggest will work on any system implementing the fd.o spec.

In general, I think that while one does have to be careful about dependencies in general. First, it is not unreasonable to assume that any system running one of the desktop environments that implement this DBus interface will have Perl installed. Of course, the Perl DBus implementation is not part of core Perl; I would be happy to make my patch emit a helpful error if it can't find the module. Secondly, for most users, xdg-utils will be installed from a system package, which can depend on the relevant Perl package (which is not large); as well, of course, as depending on Perl (since Perl is installed by default on many systems, e.g. Ubuntu and Mac OS X, the latter dependency will often not be needed).

I think I agree with Michael, would you mind rebasing your patch against latest xdg-screensaver.in ?

That said, I'll have to review what gnome (still) supports.

In short, maybe we can use SimulateUserActivity where it is available, and do something else where it isn't

Thanks, Rex. I happen to be a GNOME user myself, but more importantly, I need an xdg-screensaver that works for users there.

If you have any suggestions that you'd be happier with, I'm all ears. Note that we're talking about GNOME 3/gnome-shell, so gnome-screensaver can't be assumed.

Hi,

I am using xdg-screensaver with KDE4, and whereas Inhibit seems to disable the screen saver, it does not disable the screen autolock feature. Looking for the bug, I found that SimulateUserActivity had to be used, but I modified xdg-screensaver in a way that should make it still compatible with other window managers, by adding the look calling SimulateUserActivity in the track_window() function, while waiting for the xprop process to exit.

Regards.

diff --git a/scripts/xdg-screensaver.in b/scripts/xdg-screensaver.in
index 579b80e..84369cb 100644
--- a/scripts/xdg-screensaver.in
+++ b/scripts/xdg-screensaver.in
@@ -216,6 +216,13 @@ track_window()
   echo "$window_id:$xprop_pid" >> $tmpfile
   $MV "$tmpfile" "$screensaver_file"
   unlockfile
+ # in KDE4, simulating user activity prevents the screensaver autolock
+ if [ "$DE" = "kde" -a x"$KDE_SESSION_VERSION" = x"4" ]; then
+ while kill -0 $xprop_pid; do
+ qdbus org.freedesktop.ScreenSaver /ScreenSaver SimulateUserActivity > /dev/null
+ sleep 5
+ done
+ fi
   # Wait for xprop to edit, it means that the window disappeared
   wait $xprop_pid
   # Clean up the administration and resume the screensaver

Created attachment 117600
Call SimulateUserActivity in track_window() while waiting for xprop to exit

-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/xdg/xdg-utils/issues/36.

Changed in xdg-utils:
status: Confirmed → Unknown
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Duplicates of this bug

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.