Re: The future of session management in GNOME
- From: Havoc Pennington <hp redhat com>
- To: Dan Winship <danw novell com>
- Cc: desktop-devel-list gnome org
- Subject: Re: The future of session management in GNOME
- Date: Thu, 07 Sep 2006 00:25:12 -0400
Hi,
Here are the relevant specs btw:
http://www.xfree86.org/current/ice.pdf
http://www.xfree86.org/current/xsmp.pdf
http://www.xfree86.org/current/ICElib.pdf
http://www.xfree86.org/current/SMlib.pdf
(many distributions install these files with X)
(There are now a couple other more modern protocols called ICE, if you
do a web search, be careful)
(iirc the SMlib.pdf is the one that explains the most stuff, the state
diagrams in xsmp.pdf are also useful)
Dan Winship wrote:
In the last year or so, it's become fashionable to suggest ripping
XSMP out of GNOME and moving to a new, improved, simpler, presumably
dbus-based session management system. I'd like to argue that that's a
bad idea, and we should fix gnome-session and GnomeClient while still
sticking with XSMP.
I don't think you're crazy, but can I suggest a good approach might be:
- start from what the user benefits / scenarios are
- figure out in a top-down way what API we'd like _apps_ to have
- then figure out how to implement that or something like it
I suspect the "notify of logout" etc. API is something like that
GdkSession I posted (as David mentioned, I simplified it slightly) and
an idea for the "save state" API is a thing like:
gtk_window_set_save_state_key(GtkWindow, char*);
where if a window has a save state key set, then just before map it
restores any saved state under that key, and just before unmap it saves
as much state as makes sense (maximization, size, maybe even e.g. cursor
position in any contained text views). Some elaborations are possible
such as allowing apps to also add stuff to the state or tune what state
is saved, or allowing apps to get the state as a serialized string and
stuff it somewhere other than the default location.
This really drops the idea of "session state" and just has state for
each app (many apps will save the window state per-document though, by
setting a state key that includes a document filename, title, or guid).
This is how nautilus and firefox work right now for example. I think
probably other apps too.
I think an explicit XSMP API like GnomeClient or msm/gsmclient is a
pretty bad idea, will elaborate -
* The client side of the protocol is already implemented by
most GNOME and KDE apps, and many non-GNOME non-KDE apps.
There are lots of apps that connect to the session manager and maybe
implement the "please shut down" command, but I think nobody really
implements the XSMP state-saving stuff, at least not correctly or well.
When I've said in the past that XSMP sucks this is the part I meant. To
me the XSMP state-saving stuff is a disaster - it doesn't support the
right user experience, but it's "policy free" so is complex in order to
support 10 different hypothetical/useless wrong user experiences.
I've implemented the XSMP client side twice (gsmclient, metacity), the
server side once (msm), and the WM parts of the spec (metacity).
I _still_ am not sure I ever understood how to correctly save session
state in an application with XSMP, and even if I did, I forgot it
quickly. And even if I understood it, which I doubt, I'm pretty sure I'd
never manage to implement it without bugs because it's a complex state
machine with odd corner cases.
The GnomeClient level of API ("expose raw XSMP" pretty much) - or even
the slightly higher-level GsmClient - is just unusable and impractical.
The #1 evidence I'd cite is - open a bunch of apps from the main menu.
Log out saving session. Log back in. How similar is your desktop to when
you logged out?
Part of the problem is that this code path in an app rarely gets tested.
An advantage of nautilus/firefox style state-saving - just save globally
for the app, instead of "in a session" - is that it gets tested every
time people open and close a window. Also, of course, there's the user
benefit that state is restored every time they open and close a window,
and not just on login/logout. And the state can be per-document.
And the whole thing is transparent and doesn't require manual "setting
up your desktop"
Another way to look at why XSMP is broken is that there are two things:
- setting up your default desktop
- having apps guess that their last state is the one you're likely to
want again next
These really are not the same, XSMP mixes them together in a way that
breaks both of them. So for example an alternative is autostart for the
first one, and just have apps save their own state for the second one.
* XSMP does a number of useful session-managey things (logout
notification, logout cancellation, specifying apps that
should be restarted right away if they crash, specifying
commands to run at logout, etc) which we currently have no
other way of doing, so we'd be forced to reinvent half of
XSMP if we ditched it.
I don't think this is as compelling as the compatibility argument - the
XSMP spec only defines 16 ICE messages, and the whole spec is 21 pages.
If you simply ported XSMP from ICE to D-Bus, then what you'd have is
docs on 16 methods or signals.
If you dumped all the broken overcomplex state-saving goo and just had
logout management and application restart, I bet you could cut it in
half to 8 methods or so.
On top of that D-Bus automatically kills some of the messages, since
e.g. XSMP has to have Interact and then the InteractDone reply, but
D-Bus methods all have a reply anyway, so in the direct translation of
this you'd have only an Interact method with a return value.
Anyway, I think you'd end up with a really short spec.
* While XSMP does have lots of annoying bits, the basics are
well-understood (more so now than when gnome-session and
GnomeClient were written). Many of the bad aspects of
gnome-session are just gnome-session bugs / implementation
decisions, not intrinsic problems with XSMP.
On the implementation front, there is some amount of intrinsic problem
with libICE/libSM - they are total junk and make it difficult to write a
robust session manager app. One of the reasons is that they're much less
reentrancy-safe than glib programmers are used to - we're all spoiled to
Tim Janik's obsessive reentrancy paranoia. Anyway, it's possible to work
around, but "fun" ;-)
I think at one point KDE had forked libICE to fix it up a bit, don't
know if they still have that.
This doesn't mean we have to expose users to the full range of XSMP
possibilities (eg, multiple independently-resumable saved states). We
just decide what functionality we want to offer, and use XSMP to get
it (and extend XSMP where it doesn't do what we want, as we already
have).
I'm pretty sure I remember that the only way to extend XSMP is to add
properties. So you can probably build up a protocol extension based on
setting magic properties or something, but I don't think it's possible
to add new messages. (Of course it's possible to reimplement libSM and
libICE, or incompatibly break the ICE protocol, or things like that, but
without "extreme measures" I don't think XSMP is extensible.)
The system and user autostart items will be merged together
in some useful/clever way, probably involving a "Priority"
property a la gnome-session, and some way to indicate that
some apps want you to wait for them to register before
starting any other apps (ie, don't let apps map windows
until the window manager is running).
I think I was messing with some kind of "role" property to replace the
priority stuff in msm. like ROLE_APP, ROLE_WM, ROLE_PANEL, etc.
* XSMP-based saved sessions will be implemented as a thin
layer on top of this. When you save application state (at
logout or otherwise), the session manager will write out the
relevant XSMP properties for the app to a new "[Session
Management]" section of its .desktop file in ~/.autostart.
The place I'd diverge from XSMP is that I'd just save one
RestartCommand, and that RestartCommand should NOT point to a
save-context-specific bundle of state. i.e. saving an app should be
_exactly_ the same as sticking its normal .desktop file in autostart.
State would be remembered globally by the app, and be restored if I
reopen the same document or same window at any time, not just if I've
explicitly saved session, and not just on login.
So, copying a .desktop file into your ~/.autostart directory
would be exactly the same as having that app register itself
via XSMP with the RestartCommand and CloneCommand being the
.desktop file's Exec line, and the RestartStyleHint being
SmRestartAnyway.
It'd be just fine IMHO if "session management" were:
add_to_autostart("foo.desktop");
The only real downside is maybe setting up a bunch of terminal windows,
but the terminal app itself could have a "save this set of windows as
the default on startup" function - in fact, doesn't Firefox or Galeon
have a feature a lot like that?
* To reduce the number of special case hacks the session
manager contains for various bits of GNOME functionality,
we'll add a way for autostarted programs to make changes to
the session manager's environment; eg, setting GTK_MODULES
for a11y, setting G_DEBUG for unstable-series testing,
setting GNOME_KEYRING_SOCKET for the keyring manager,
etc--currently these are all done as special cases in
gnome-session.
There was some previous thread about having the session manager export a
couple of dbus methods like Putenv/Getenv, so env variables could change
dynamically during a session, I don't remember in what context this came up.
The clients would work like ssh-agent (print
out a few VARIABLE=value lines at startup and then fork or
exit), and there would be a new autostart .desktop property
indicating that the client behaves this way. The session
manager would start them, read their stdout, run the
appropriate putenv()s, and continue starting things up.
Wouldn't a config file (or gconf) be simpler if you just want to
statically configure env variables?
* The session management UI will be more icon-y and less
command-line-y than it is now.
I'd say ideally the session management UI is shot in the head. ;-) It's
kind of ridiculous. Why not just open nautilus on the autostart folder,
then take the one or two checkboxes (enable splash screen or whatever)
and move them somewhere else.
* In the session management UI, you can tell it to
take a currently-running app, and add it to the
autostarted apps list, and it will save its state
(ie, Local SaveYourself) and cause it to be started
the same way later. This is for things like "I want
my 17 gnome-terminals to launch in the correct
locations."
The terminal case is about the only example I can come up with where the
complex XSMP stuff kind of makes sense (and I think I made some sort of
valiant attempt to implement session save correctly in gnome-terminal,
come to think of it, that's why gnome-terminal has so many crazy command
line options).
Even so I wouldn't be at all surprised if you surveyed a few dozen
random sysadmin's systems if they weren't just manually running a
terminal command line with the right options to launch the terminals
they want. I wonder how many really use session saving to create their
default config.
And as I mentioned earlier, gnome-terminal could just have a "save this
configuration as my default" feature right in the app, problem solved.
For toolbar-type things (do people still use gkrellm?) this is also a
viable approach, though for many of those they can just do what e.g.
Google toolbar does on Windows - just remember their most recent state
across login/logout. Simple.
We also want a better client API than GnomeClient. GnomeClient is a
very very thin layer around XSMP, mostly because when it was written
there wasn't enough agreement about what certain parts of XSMP meant,
so it was impossible to abstract/simplify the API. As mentioned
before, this is somewhat fixed now[3], so we can make a nicer API
based on our new understanding. At the very least we want separate
"save_state" (Local SaveYourself) and "save_files" (Global
SaveYourself) signals, rather than a generic "save_yourself" signal
with 36 possible combinations of flags where almost every single app
in jhbuild that uses GnomeClient implements only one behavior that it
uses regardless of the flags passed (and often that behavior is not
100% correct for any of the 36 possibilities).
Just to be sure I said it enough times, I really think the right
simplification is to put a bullet in save_state as some kind of
session-driven event, and just have apps deal with state saving
themselves. Then the GnomeClient API is only the GdkSession kind of
stuff (logout notification, maybe something else).
This would make a gnome-session rewrite truly worthwhile, by really
changing the user and app developer model to something both simpler and
more powerful. (I say more powerful because I think apps can do a much
better job saving their state on their own.)
(And if we're moving the session management client to gtk, it should
support the equivalent Windows/Mac OS X session management
functionality as well. I think this is mostly just logout
notification/cancellation, plus the ability to add/remove programs
from the autostart list, but I haven't really investigated.)
I think that is what they have, because that is the sane thing to have,
and also what GNOME should have ;-)
This is a no-brainer - it's "better UI" and "easier to implement" all in
one awesome package!
Does this make sense or does someone want to put forth a stronger
argument for killing XSMP?
I'm not sure my argument is for killing XSMP; keeping it for logout
notification, maybe it's worthwhile to avoid weird incompatibility
issues or whatever. The price is essentially linking to libICE and
libSM, and an extra file descriptor per process, which is not a giant
cost to keep compatibility.
I do think the XSMP state-saving model is absurd and should be ignored,
however, even if XSMP is used for logout notification.
Havoc
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]