It’s time to talk about session management. It might even be interesting.
The basic idea is that when you log in, you want your desktop to look like it did when you logged out. There is a program called the session manager which starts up all the programs which were running when you logged out, and tells them that they’re being restored. It is smart enough to call the window manager first. The specs which govern this, if you really want to read them, are §5 of the ICCCM and XSMP.
You can compile Metacity with session management turned off, but most people don’t. If you’re running a copy of Metacity which knows about session management, and you’re running under a session manager, then the session manager will tell Metacity to save state when you log out, and give it a session string. Metacity will write out a single file named after that string, including the position, minimised/maximised state, size, and so on of each window. When you log back in, the session manager tells Metacity the name of the file, and it will reload all the information.
This is the icky part: remember how the session runs the window manager before any of the applications? Metacity now has a list of the windows that were open before you logged out, and none of them have been opened again yet, because the applications haven’t run. So Metacity keeps a list, and when the applications start and open their windows, Metacity will place them how they were beforehand.
So what we have here is window matching. Gentle reader, when you hear the words “window matching”, you have my permission to scream bloody murder. There is simply currently no good way to do it, and so we don’t. What do we match on? The window’s title, its role, its class, or what? We don’t do window matching in Metacity, because there is no good way to do it at present. Rather, we leave that to power-user tools like Devil’s Pie, where people who really want this behaviour and have enough time to specify exactly what they want in detail can do so.
But, as you’ve noted, we do do window matching in Metacity: we just pretend we don’t. And we don’t in general, but session management forces our hand. Every time we open a window (if there’s session management going on), we make a list of session windows which were opened by the application with the same session client ID and have the same resource name and class and the same role setting. Then we use the settings of any matching window which has the same title; if we don’t find one, we use the settings of any matching window which has the same type; if we don’t find one, we give up on window matching. (“The same” above includes the case where they’re both null.)
That was pretty complicated. Add to that complexity the fact that most applications don’t even set the role and resource settings to anything useful, and you begin to see why we (supposedly) don’t do window matching in Metacity.
Now, there are five possible ways forward for us:
1) Carry on as we are.
But we have this directory “~/.metacity”, which clutters up people’s home directories and has to be cleared if they want to remove all state. “~/.metacity” only ever contains the directory “sessions”, anyway.
2) Move metacity session data to “~/.gnome2/metacity/session”.
You might think this was the obvious way forward, but it isn’t going to happen because…
3) Move metacity session data to “~/.config/metacity/session”.
As GNOME bug 518596 points out, freedesktop.org is standardising hidden directory names across all desktops. The name to use based on this idea depends whether our session files are configuration data, cached data, or some other kind of data; this has been discussed on that bug and consensus seems to be that they’re configuration data.
However, if we’re going to move to another directory, we should also consider:
4) Move metacity session data to “~/.config/metacity/session” and change the format.
The existing format is based on GMarkup, but does pretty much exactly what GMarkup is bad at. It is also generally rather inelegant. It would be very simple indeed to replace it with a GKeyFile-based system; there’s almost a one-to-one mapping with the API in many places. We’d know that files in the new place were in the new format and files in the old place in the old, and after a few years perhaps we could drop support for reading back the files in the old place (how long do people keep session files around for, anyway)?
But the most radical solution is:
5) Abolish session management (or at least session management within the window manager).
This suggestion has come from a number of people. The reasons given so far are: XSMP has so many problems that we’re better off not implementing it at all than implementing it partially; we really shouldn’t be even attempting to do this because it involves window matching, which is an impossible problem anyway; Sven Herzberg apparently gave a talk at last year’s GUADEC that said that applications should be responsible for restoring their windows because they know how to do so and the window manager can’t know in general.
Photo by Mark Norman Francis, cc-by-nc.
i’m not sure to understand
GNOME has session management which allow the user to restore his windows at next start
is it based on Metacity ?
But GNOME session management doesn’t allow to restore windows on their own desktop (in case of you use multiple desktops). I’ve read that Devil’s Pie can do that but there’s no GUI for it.
Is it what this article is about ?
No, session management in general isn’t based on Metacity– just the placement of windows. If Metacity isn’t restoring windows to the original desktop, you have found a bug.
Devil’s Pie does something separate to what Metacity does here. This article is about how Metacity places windows when you log in. Devil’s Pie has the ability to arrange windows when you open an application at any point; the article is not about that.
ok, tank you for your answer
It’s interesting to hear that Metacity also needs to do the black-art of window-matching. We have the same problem in Awn (https://launchpad.net/awn), for matching launcher icons (.desktop files) to newly-opened windows.
As you stated, there’s currently no good way of doing it, and the code in Awn that deals with this has had many extra matching rules bolted on it over the past year. This is something which I hope to rewrite in the next few months, but I’m dreading it as there is a high chance of introducing regressions. It would be great if there was a sane way of doing this, without lots of application-specific special casing.
> 5) Abolish session management (or at least session management within the window manager).
You can’t abolish session management *just* within the window manager, because XSMP says the window manager restores window positions, so if you don’t, then session management won’t work right. Eg, I know for sure that if you resume a saved gedit state without having metacity resume its window positions, that you will end up with all of your gedit windows being 200×200 (the default size for a GtkWindow, which is much too small to be useful for gedit). I’m not sure how other apps behave; some might at least default to a reasonable size, if not the actual correct size.
As for having apps remember their own state, there are two levels of that. On the one hand, there’s “apps should remember a default window size” and/or “apps should remember the window size the user last used for a given document”, and apps can already do that, and I think there’s a reasonable amount of agreement that they *should* do that as well.
On the other hand, there’s full-blown session state saving of the sort that allegedly happens when you save-session-on-logout now, where you’re trying to restore not just window size, but actually the exact global arrangement of all windows that you had previously. This is something that it’s not possible for apps to handle entirely on their own currently, because in some WMs, it’s not possible for apps to figure out everything that the window manager considers relevant to their position. (In particular, IIRC, in a WM that uses large desktops rather than multiple workspaces, there’s no reliable way for a newly-launched app to request to be launched outside the current viewport. Likewise, if the WM offers any clever functionality beyond what the EWMH discusses, like pinning to some-but-not-all workspaces, there’s no way for a window to generically be able to figure out that it’s in that state and then restore it correctly later). There are also other things that it’s theoretically possible for the windows to figure out on their own, but that it’s much easier to get right if the WM is playing along too. (Eg, getting the window stacking order correct.)
One argument is that this latter sort of state saving is crack and we don’t care. OTOH, if we *do* care, then one way to fix it so that apps can save and restore their own state would be to add a new EWMH hint, say “_NET_WM_WINDOW_STATE_ATOMS” or something, which the WM would set on a window, to a list of other atoms. And when the app wants to save its state, it would just fetch the values of all of the atoms listed in that property, and save their values, and then later on when it wants to recreate that state, it just creates a new window with all of those atoms set to the saved values.
You can’t abolish session management *just* within the window manager, because XSMP says the window manager restores window positions, so if you don’t, then session management won’t work right.
Well, that was rather the point: the two people who I know to have suggested this think XSMP is poorly designed, so they don’t really mind what it says we should do.
Taking the fifth option would presumably require checking that all major applications (that we had some control over) were capable of restoring their windows correctly. gedit would certainly fall into this category.
(I only made the mental connection the other day that having the WM deal with this means that everyone has a huge list on disk of the titles of the webpage they were looking at when they logged out or their laptop ran out of power, since that’s kept in the window title. That’s presumably something that a browser might want to do differently, but the WM can’t know any better.)
“Well, that was rather the point: the two people who I know to have suggested this think XSMP is poorly designed, so they don’t really mind what it says we should do.”
Hm… I guess I meant “you can’t do this *now*, without breaking things”, not “you can’t do this at all! you have to maintain that code FOREVER BWAHAHA”. :)
Actually, I haven’t proposed to drop the burden of window-state-saving to the application developer, IMHO (and I think several others agree here) the toolkit should be responsible for that (so the app developer will only have to give some little hints to the toolkit).
Sounds like a good plan. Did the GTK folks ever get anything together, do you know? Is there maybe a bug?