Rambles around computer science
Diverting trains of thought, wasting precious time
Tue, 29 Sep 2009
Standalone ksmserver, part 2: getting it right
I blogged previously about my attempts
to use KDE's session manager in a standalone fashion (with fvwm,
in my case). What I presented there isn't entirely satisfactory, mainly because not all window sizes
and positions get restored when restoring the session. I've finally worked out why. Unfortunately,
this has also revealed that some content in the previous post is wrong. Allow me to correct myself
here.
- To end the session, ask the session manager, but leave the window manager
running. My earlier config has fvwm calling ksmserver on its way out, in SessionExitFunc.
Don't do this. If you do, then fvwm won't be running by the time ksmserver saves the session. This
is why the window positions weren't getting saved---fvwm saves them in response to
WM_SAVE_YOURSELF, which it only receives when closed down by the session manager like any
other client. The right way is to avoid quitting the window manager---just tell the session manager
to exit. To this effect, in fvwm my “Quit” button now just does
SaveQuitSession, and ksmserver does the rest.
- ksmserver -r doesn't do what you (might) think it does. The
ksmserver --help output claims that this option “restores the saved user session if
available”. Sounds like what you want? It's probably not. There are two kinds of session in
ksmserver: “saved at previous logout” and “saved by user”. The normal
behaviour (although it's configurable in ksmserverrc) is to restore the former, which
probably is what you want. The -r option just switches to doing the latter. Here's the code
(from the end of main.cpp).
if ( args->isSet("restore") && ! screenCountChanged )
server->restoreSession( SESSION_BY_USER );
else if ( loginMode == "default" || screenCountChanged )
server->startDefaultSession();
else if ( loginMode == "restorePreviousLogout" )
server->restoreSession( SESSION_PREVIOUS_LOGOUT );
else if ( loginMode == "restoreSavedSession" )
server->restoreSession( SESSION_BY_USER );
else
server->startDefaultSession();
Make sure WM restarts don't end the session. This is another reason not to do
anything in SessionExitFunc: it gets called on restarts too. My SessionExitFunc is now empty.
Previously, it was DCOP-calling logout on ksmserver, hence ending the session rather than
seamlessly restarting the window manager.
ksmserver replicates the functionality of smproxy. In legacy.cpp
there's a bunch of code which does roughly what smproxy does. It's complete with disgusting hacks
for substituting “firefox” for “firefox-bin” in
WM_COMMAND, and similarly for other Mozilla applications. (They should just set
WM_COMMAND to the right thing, of course, but they're broken.)
So, all you need in your fvwm config is something like the following.
AddToFunc SessionInitFunction
+ I Exec dcop klauncher klauncher autoStart 3; \
dcop ksmserver ksmserver autoStart0Done; \
dcop ksmserver ksmserver kcmPhase1Done; \
dcop ksmserver ksmserver autoStart1Done; \
dcop ksmserver ksmserver kcmPhase2Done; \
sleep 4; dcop ksmserver ksmserver autoStart2Done
# assuming you quit using a Quit-Verify menu...
AddToMenu Quit-Verify "Quit" SaveQuitSession
[/devel]
permanent link
contact
validate this page