Thanks to a bug found in Spice's drag and drop implementation, I was able to
improve the integration of our guest agent (spice-vdagent) with the Desktop
Session on Linux and Windows. I enjoyed the process to solve those problems so I
thought a blog post could be interesting as well.
If you use Spice you might enjoy the feature of copying files from your client
machine to the guest by simply using the drag and drop feature. It works pretty
well and under the hood we are sending this data to spice-vdagent which copies
it to your Download or Desktop folder.
The problem is that you could transfer files with drag and drop while your guest
session was Locked (rhbz#1323623); even worse, it was also possible to
transfer files when your guest were on Login Screen, when no user was logged in
In order to fix both issues, we need to ask (someone) about the Session state,
the following questions "Is the session Locked?" and "Does this session belong
to a user?". Let's see how we can do that.
In order to solve this in the best way possible, I did not want to make
integration with specific Desktop Environment (DE) so, I started looking for a
cross Desktop API.
My first try was around org.freedesktop.ScreenSaver interface which worked
rather well. I had a few issues that I might be able to workaround but it did
not seem right to request ScreenSaver the state of your user session.
So I looked at logind from systemd and there I could find a very promising
'Lock' and 'Unlock' signals! I checked with gdbus monitor if this was being used
in my session with:
# get your session path with:
gdbus call --system --dest org.freedesktop.login1 \
--object-path /org/freedesktop/login1 \
# monitor it
gdbus monitor --system --dest org.freedesktop.login1 \
# Lock an then Unlock your session with GNOME and see:
/org/freedesktop/login1/session/_31: org.freedesktop.login1.Session.Unlock ()
So, the Unlock signal was emitted but not the Lock signal. I thought it could be
a bug so a filed #764773 to discuss it. It was not a bug and tracking the
Lock and Unlock signals was not the best approach.
After some discussion with halfline we agreed that extending logind would make
things easier. Lennart pointed that having a LockedHint property with
SetLockedHint method would be a nice thing to have.
This would make rather simple to programs like spice-vdagent to query the Locked
state of the Session.
The proposal was accepted and works well. One less bug to solve.
Back to the bad transfer over Login screen, that happens because we have a
spice-vdagent running for GDM so we can do things like resizing the display
correctly and as soon as possible.
The solution was rather simple here, all you need to do is to check your session
class. We are only interested in a session that belongs to "User" and
sd_session_get_class() can give you that.
That's it for Linux guests. I also patched our console-kit integration but I
don't plan to comment on it. Take a look in this commit to check for the
session class and this one to check if we are in a Locked session.
Many many thanks to halfline for his time and help, it was really fun.
I wasn't excited on the windows part so I postpone for some time but in the
end, It was surprisingly easy. We only have one bug here due the design
difference between our agents: the transfer while Guest is in Locked screen.
On Windows you can subscribe for session notifications and the event
WTSRegisterSessionNotification has WTS_SESSION_LOCK and WTS_SESSION_UNLOCK
types. Very handy. Minimum requirements say 'Windows Vista'
but it works on 'Windows XP' as well. Super!
As we were already listening to sessions notifications, I only had to handle the
lock/unlock events type (here).
I'm naive. I thought I would have much more work with Desktop integration on
Windows then on Linux! I'll be more careful with my thoughts next time :)
Bugs bugs bugs.
Saturday, June 25, 2016 15:10