deskflow / deskflow

Deskflow lets you share one mouse and keyboard between multiple computers on Windows, macOS and Linux. It's like a software KVM (but without video).
https://deskflow.org
GNU General Public License v2.0
12.41k stars 3.73k forks source link

Support for gnome-screensaver as well as xscreensaver #112

Closed nbolton closed 9 years ago

nbolton commented 10 years ago

Imported issue:

Many Linux distributions no longer use xscreensaver as the default
screensaver - depending on whether one uses GNOME or KDE, the screensaver
comes with the DE now. Part of the reason for this may be that jwz (the
author of xscreensaver) no longer uses Linux and so xscreensaver support
has waned somewhat.

As a GNOME user, I would like to see synergy+ have the ability to invoke
the screensaver in a synchronized manner using gnome-screensaver.
Something similar probably would need to be done for KDE, but I don't know
anything about that environment.

From what I've read, there's a dbus event that can be used to activate the
screensaver. I don't know anything about dbus programming myself or I
would look at submitting a patch for this myself.

nbolton commented 10 years ago

Sounds like an appropriate enhancement. I will mark this as accepted.

nbolton commented 10 years ago

This would be really great.

nbolton commented 10 years ago

I would also appreciate this myself! As a very heavy Ubuntu user in addition to 1
windows computer, I really need this working! Please!!!

nbolton commented 10 years ago

I too would appreciate this feature greatly

nbolton commented 10 years ago

I believe that this is no longer an enhancement but a bugfix because the majority of
Linux users that would use synergy are using gnome-screensaver, the screensaver's
failure to sync is a major problem. I would be willing to look into fixing this
myself.

nbolton commented 10 years ago

This is something I miss a lot on my KDE laptop. Now, I had a look around and it
seems it could be quite simple to fix with DBus. Perhaps the same solution works for
both KDE and GNOME. On my desktop, simply sending this message works:

qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.SetActive True

There's a nice blog post about Dbus and this very example at
"http://foss-boss.blogspot.com/2008/11/ride-d-bus-control-your-linux-desktop.html":http://foss-boss.blogspot.com/2008/11/ride-d-bus-control-your-linux-desktop.html

nbolton commented 10 years ago

That's actually an interesting way of doing it. I just don't see how to adapt it for
gnome...

rohan@rohan-laptop:~$ qdbus org.freedesktop.ScreenSaver /ScreenSaver
org.freedesktop.ScreenSaver.SetActive True
Service 'org.freedesktop.ScreenSaver' does not exist.

That's the response I got. It's something we should at least look into.

nbolton commented 10 years ago

Hmmmm, I know very little about this stuff (I tend to be deeply dug down into
servers...), but the blog post I referenced above suggested it should work under
GNOME too, perhaps the service isn't running, or something? Also, it seems it would
be libdbus that one would use to actually write the code, perhaps qdbus is tied to
Qt/KDE? What do you get if you do:

qdbus | grep freedesktop

Regardless of how to do it for GNOME, this is the Right Way[tm] to do it for KDE. :-)

nbolton commented 10 years ago

Here's the response to that command.

rohan@rohan-laptop:~$ qdbus | grep freedesktop
org.freedesktop.ReserveDevice1.Audio0
org.freedesktop.Notifications
org.freedesktop.compiz
org.freedesktop.NetworkManagerUserSettings
org.freedesktop.DBus

I think it's there but the screensaver isn't tied in (I'm on Gnome)

nbolton commented 10 years ago

Hmmm, yeah, it seems like it isn't working that way. Perhaps a good idea to ask some
GNOME-people about this, as it would be nice to write the code to support any
freedesktop, not depend on any DE.

nbolton commented 10 years ago

BTW, since DBUS support might be something separate from gnome-screensaver-support,
would it be a good idea to post a separate issue for it, or would that just clutter
the issue tracker?

nbolton commented 10 years ago

I would recommend just changing the topic information to dbus support. It would be
much better than supporting either Gnome-screensaver or kde-screensaver because in
theory it would support both!

nbolton commented 10 years ago

As the original reporter, I think the proposal from comment #12 is an excellent
suggestion.

nbolton commented 10 years ago

Yup, sounds good! I don't think I have the privileges to do it, any takers?

nbolton commented 10 years ago

I think that we need nick.bolton.uk to do it, :P

Nick (that's your cue, :P)

nbolton commented 10 years ago

FYI, on my Ubuntu system, I have a dbus topic "org.gnome.ScreenSaver":

qdbus org.gnome.ScreenSaver /
method QString org.freedesktop.DBus.Introspectable.Introspect()
signal void org.gnome.ScreenSaver.ActiveChanged(bool new_value)
method void org.gnome.ScreenSaver.Cycle()
method bool org.gnome.ScreenSaver.GetActive()
method uint org.gnome.ScreenSaver.GetActiveTime()
method QStringList org.gnome.ScreenSaver.GetInhibitors()
method uint org.gnome.ScreenSaver.Inhibit(QString application_name, QString reason)
method void org.gnome.ScreenSaver.Lock()
method void org.gnome.ScreenSaver.SetActive(bool value)
method void org.gnome.ScreenSaver.SimulateUserActivity()
method uint org.gnome.ScreenSaver.Throttle(QString application_name, QString reason)
method void org.gnome.ScreenSaver.UnInhibit(uint cookie)
method void org.gnome.ScreenSaver.UnThrottle(uint cookie)

Seems to have most of the same methods as the freedesktop one listed in that article.
I'd guess that it wouldn't be too hard to support both topics.

nbolton commented 10 years ago

After looking at DBus standards, not all screensavers can be accessed from the DBus interface. For example, xscreensaver does not seem to be advertised in DBus. Also, using Xlib for this does not seem to be working on my computer.

DBus does define a standard for screensavers though, the problem is knowing which one to use if there are more than one available. This will most likely be dependent on the DE in use.

nbolton commented 10 years ago

I have been using Synergy for a while (5+ years?). One of things that I never got to work right was any type of screensaver synchronization. I recently took a look at the new project site, and I want to contribute something back. I put together a bash script to sync the screensavers among all of my synergy-enabled computers. I am not sure that this is the best place to post this (please let me know if it's not), but it seemed the most relevant.

Anyway, I am currently running 3 Ubuntu 11.04 computers with a simple synergy.conf. I setup ssh key authentication with all 3 of the computers so that I can ssh from any one of them to any other without a password. This allows me to issue the requisite commands remotely.

I didn't use dbus-monitor to detect session idle because if you leave the mouse on a client screen, gnome-screensaver doesn't want to activate, so the state doesn't change. Interestingly, if you move the mouse pointer back to the server screen, the screensaver will trigger.

I used xprintidle to get the idle time of the session. I turned off gnome-screensaver automatic activation through its normal configuration and let my script handle triggering it. When I detect idle, I kill synergys, activate the server screensaver, then reactivate synergys. Then the dbus-monitor will see the ActiveChange and activate the clients' screensavers. This allows all screens to lock. You could put some power commands to force monitors off, too.

You can also manually lock the screen with ctrl-alt-l on the server and the clients will lock, too. I went further and reassigned ctrl-alt-l on my clients to

  
ssh synergyserver "killall synergys;export DISPLAY=:0.0;gnome-screensaver-command -l;/usr/bin/synergys"  

This way, you can lock the whole thing from any screen.

Like I said, I am running Ubuntu 11.04 and gnome-screensaver, but this should be easily adapted to kde, or xscreensaver with some command substitutions.

So here's my bash hack:

  
 #! /bin/bash  

 # synsync  
 #  
 # A script to synchronize screensavers/locking with synergy.  
 # This was written in an attempt to get around the limitation  
 # that leaving the cursor on a client screen will not allow   
 # the screensaver to activate on the synergy server.  
 #  
 # I really have no idea if this is fixed in later versions of synergy.  
 #   
 # This script needs:  
 #  
 # xprintidle  
 # gnome-screensaver (you should be able to substitute the commands   
 #   from your screensaver to make this work for kde or xscreensaver, etc.)  
 # bc  
 # ssh  
 #  
 # You need to set up passwordless ssh between the computers involved.  
 # See using ssh-keygen and ssh-copy-id  
 #  
 # I disable the automatic activation on idle in the screensaver prefs  
 # and let this script do the activation.  You can put this in your session  
 # startup applications.  
 #  
 # This works for me.  YMMV.  
 #  
 # Alex Copeland  
 # alex *you_know_what_goes_here* abacinate.com  
 # 5/2011  

 # kill everything if you ctrl-c   
 # mostly needed this for testing  

trap 'echo "TERMINATING"  
/usr/local/bin/synsync -k  
exit 0' 2  

 # time you want to pass (in minutes) before activating screensaver  
TIMETOWAIT=25  

 # Array containing the resolvable names of your synergy clients  
 # You have to have ssh without passwords set up for this to work  
SYNERGYCLIENTS=(synergyclient1 synergyclient2 )  

SYNSYNCPID=/tmp/synsyncpid  

if [ "$1" == "--kill" ] || [ "$1" == "-k" ]  
  then  
  if [ -e $SYNSYNCPID ]  
    then  
    running=$(cat $SYNSYNCPID)  
    ps -o pid= --ppid $running | xargs kill   
    kill $running  
    rm -f $SYNSYNCPID  
    exit 0  
  else  
    echo "No PID file found."  
    exit 1  
  fi  
fi  

 # Put the script PID in a temp file  
echo $$ > $SYNSYNCPID  

 # Spawn and fork the dbus monitoring to the background.  
 # This is what watches for the state to change then activates the   
 # client screensavers.  
dbus-monitor --session "type='signal',interface='org.gnome.ScreenSaver',member='ActiveChanged'" |  
  while read line  
    do  
    if echo $line | grep "boolean true" > /dev/null 2>&1  
      then  
      for client in "${SYNERGYCLIENTS[@]}"   
        do   
        # You could also add xset dpms force off         
        ssh $client "export DISPLAY=:0.0;gnome-screensaver-command -l"  
      done  
      sleep 5  
    elif echo $line | grep "boolean false" > /dev/null 2>&1  
      then  
      for client in "${SYNERGYCLIENTS[@]}"  
        do  
        ssh $client "export DISPLAY=:0.0; xset dpms force on; gnome-screensaver-command -d"  
       done  
    fi  
  done &   

 # This is what detects session idleness using xprintidle  
isidle="no"  
while true  
  do  
  export DISPLAY=:0.0  

  idlems=$(/usr/bin/xprintidle)  
  idle=$(echo $idlems / 60000 | bc)  

  if [ $idle -ge $TIMETOWAIT ] && [ "$isidle" == "no" ]  
    then  
    isidle="yes"  
    killall synergys  
    gnome-screensaver-command -l  
    sleep 5  
    synergys  
  elif [ $idle -lt $TIMETOWAIT ] && [ "$isidle" == "yes" ]  
    then  
    isidle="no"  
  fi  

  sleep 30  
done  

exit 0