Bug 26085 - xdg-screensaver resume activates the screensaver on KDE4
Summary: xdg-screensaver resume activates the screensaver on KDE4
Status: REOPENED
Alias: None
Product: Portland
Classification: Unclassified
Component: xdg-utils (show other bugs)
Version: 1.0
Hardware: All Linux (All)
: medium normal
Assignee: Fathi Boudra
QA Contact:
URL:
Whiteboard:
Keywords: patch
Depends on:
Blocks:
 
Reported: 2010-01-17 12:45 UTC by Jean-Philippe André
Modified: 2015-08-09 23:04 UTC (History)
3 users (show)

See Also:
i915 platform:
i915 features:


Attachments
Use SimulateUserActivity. instead of Inhibit for D-Bus screensavers (5.42 KB, patch)
2010-08-28 19:10 UTC, Michael T. Dean
Details | Splinter Review
Patch to fix this bug (5.75 KB, patch)
2015-01-04 21:31 UTC, Reuben Thomas
Details | Splinter Review
Call SimulateUserActivity in track_window() while waiting for xprop to exit (729 bytes, patch)
2015-08-09 23:04 UTC, Gilles Chanteperdrix
Details | Splinter Review

Note You need to log in before you can comment on or make changes to this bug.
Description Jean-Philippe André 2010-01-17 12:45:00 UTC
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,
Comment 1 Rex Dieter 2010-01-18 05:29:38 UTC
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 ... :)
Comment 2 Rex Dieter 2010-01-18 05:38:50 UTC
committed.
Comment 3 Jean-Philippe André 2010-01-18 06:59:52 UTC
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,
Comment 4 Jean-Philippe André 2010-01-21 05:20:36 UTC
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.
Comment 5 Rex Dieter 2010-02-21 10:14:28 UTC
True, seems to me this interfaces was written not with xdg-utils in mind, and that apps should use the dbus method directly themselves.
Comment 6 Michael T. Dean 2010-08-28 19:10:35 UTC
Created attachment 38251 [details] [review]
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).
Comment 7 Reuben Thomas 2015-01-04 21:31:48 UTC
Created attachment 111737 [details] [review]
Patch to fix this bug

This patch fixes the bug. It necessitates a helper Perl script.
Comment 8 Rex Dieter 2015-01-15 15:59:43 UTC
I'll have to think about this more, not keen on adding any perl dependencies.
Comment 9 Michael T. Dean 2015-01-15 16:23:07 UTC
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.
Comment 10 Reuben Thomas 2015-01-15 20:50:52 UTC
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).
Comment 11 Rex Dieter 2015-01-15 21:48:21 UTC
I think I agree with Michael, would you mind rebasing your patch against latest xdg-screensaver.in ?
Comment 12 Rex Dieter 2015-01-15 21:50:30 UTC
That said, I'll have to review what gnome (still) supports.
Comment 13 Rex Dieter 2015-01-15 21:51:15 UTC
In short, maybe we can use SimulateUserActivity where it is available, and do something else where it isn't
Comment 14 Reuben Thomas 2015-01-15 21:52:46 UTC
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.
Comment 15 Gilles Chanteperdrix 2015-08-09 20:40:52 UTC
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
Comment 16 Gilles Chanteperdrix 2015-08-09 23:04:40 UTC
Created attachment 117600 [details] [review]
Call SimulateUserActivity in track_window() while waiting for xprop to exit


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.