So after my latest X.org upgrade I forgot to recompile the xf86-input-evdev module as well. So of course when I ran startx again, my shiny KDE desktop came straight up… and I couldn’t move the mouse or use the keyboard. Drat.
Now I’ve been much more careful to cleanly shutdown KDE when possible ever since I started losing rc files with my previous filesystem. And besides which, I couldn’t use Ctrl-Alt-Backspace even if I wanted. So what I did instead was login with my laptop to try and shutdown KDE.
Of course, there’s still the tricky issue of how to cleanly shutdown your running session from a completely different shell. Luckily ksmserver (the process responsible for performing the shutdown) has a DBus interface:
kde-svn@midna ~ $ qdbus org.kde.ksmserver /KSMServer method bool org.kde.KSMServerInterface.canShutdown() method QString org.kde.KSMServerInterface.currentSession() method void org.kde.KSMServerInterface.logout(int, int, int) method void org.kde.KSMServerInterface.resumeStartup(QString) snip
Of course, that’s what I get when I run if from my current KDE session. I was worried that in my ssh shell there would be problems with accessing the D-Bus session. So imagine my surprise when I was wrong, the command worked just fine even with no environment variable set. Huh.
Although it saved me from what I was going to do (look through /proc/pid/environ for a process that I knew was in the DBus session), it was still unexpected to me. Turns out that DBus will, if the environment variable is unset, try to “autolaunch” the session bus. This entails looking in the X session and in ~/.dbus/session-bus/ to look for the information on the DBus session, and if not able to locate the session, to simply launch another DBus session. In my case the information was available in ~/.dbus/session-bus/.
So I’m impressed, I was expecting it to be a giant pain in the ass and it was actually ridiculously simple.
Btw, the conclusion to the tale was: qdbus org.kde.ksmserver /KSMServer org.kde.KSMServerInterface.logout 0 0 0. The three parameters were annoying for me to lookup so here it is:
The real signature: KSMServerInterface::logout( KWorkSpace::ShutdownConfirm, KWorkSpace::ShutdownType, KWorkSpace::ShutdownMode ). The parameters are essentially the same as in KWorkSpace::canShutdown() (link edited to work 2012-05-06), and the values are defined on that API page as well. One thing to note is that the final 0 (shutdown mode) is actually useless since we’re not requesting that a shutdown happen, only a logout. If we were requesting a shutdown, the shutdown mode is what selects whether to force a shutdown/reboot even if other people were also logged in, for instance.
Kind of as an aside, I’ve taken the liberty of updating my GPG keys due to the relative insecurity and low strength of the 1024-bit DSA key I had before. It should have a fingerprint of 5406 ECE8 3665 DA9D 201D 3572 0BAF 0C9C 7B6A E9F2, and is available here. Maybe someday I’ll even be able to attend a keysigning event to get it signed by someone else. :-/
Thanks! I’ve always wondered how to do that.
many thanks, i’ve been trying to find documentation on those three int’s too. funny that i should find it here, and not on a kde website. oh well. in case it’s useful to you, here are the docs for the gnome version (not to incite DE wars, but because i was looking for them too)
http://www.gnome.org/~mccann/gnome-session/docs/gnome-session.html#org.gnome.SessionManager.Logout
ps: did you get your answer from the source, or is there some magical documentation somewhere else?
pps: in case you happen to know and don’t mind being asked, what is the *correct* way to detect which desktop environment is running. at the moment i have something that looks like (python):
def session():
# this was adapted from:
# http://gitweb.compiz-fusion.org/?p=fusion/misc/compiz-manager;a=blob;f=compiz-manager
# TODO: is there a better way to implement this ?
if os.name == ‘nt’: return ‘windows’
elif os.getenv(‘KDE_FULL_SESSION’) == ‘true’: return ‘kde’
elif os.getenv(‘GNOME_DESKTOP_SESSION_ID’) != ”: return ‘gnome’
else: return ”
cheers!
_J
James: I looked at the source but it ended up being available at the documentation for KWorkspace IIRC. Of course how you go from session management to KWorkspace is kind of strange to me but eh, whatever.
I have no clue how to detect if you’re running under a GNOME session but KDE_FULL_SESSION is the way to detect KDE. Note that it’s only been implemented since 3.5.5 so as long as you don’t need to detect older KDE sessions that should be fine.
If you need to separate between KDE 3.5 and KDE 4 you can use the KDE_SESSION_VERSION variable added in KDE 4.
Please see kdebase/workspace/startkde.cmake for more information (or just vim `which startkde` if you have KDE installed). grep for KDE_FULL_SESSION.
thanks for the KDE_SESSION_VERSION info.
i’ve made a post here: http://dazzle.cs.mcgill.ca/wordpress/?p=11 which references your blog.
(i’m trying to document things i find useful, such as how you’ve done above)
thanks again!
Hi,
The link to the parameter documentation named
KWorkSpace::canShutdown()
changed from
sorry, accidently hit submit,
was trying to say that the link changed to
http://api.kde.org/4.x-api/kde-workspace-apidocs/libs/kworkspace/html/namespaceKWorkSpace.html
(no base in kdebase anymore)
@mandarin: Thanks for the update, I’ve fixed the link in the post.
Pingback: logging out of $SESSION | The Technical Blog of James