Hello, As apparently one of the last users of session management, because I shut down my computers about once every day, I run into problems about as often as I log into a session that is supposed to be restored. The number one problem is Konsole just not restoring. So I took some time to investigate the problem. The result is that there are several bugs that conspire to break session restore. It goes about like this:
- ksmserver (the session manager) sends clients the "SaveYourself" message and collects the responses. This works fine. - In Qt applications, this results in a call to QGuiApplicationPrivate::commitData(), which calls QApplicationPrivate::tryCloseAllWindows() after the part that sends the SaveYourselfDone response to the session manager. When QGuiApplication::quitOnLastWindowClosed() is true (the default), this results in the application quitting. - ksmserver notices that (e.g.) konsole has terminated and purges it from its internal data - ksmserver rounds up remaining processes, which at this point do not include konsole, and saves their restore data. konsole thus has saved its state, but ksmserver forgot about it and doesn't remember to do anything with konsole when restoring the session later. The two most obvious errors are thus: - QGuiApplicationPrivate::commitData() calling QApplicationPrivate::tryCloseAllWindows(), together with QGuiApplication::quitOnLastWindowClosed() being true by default. Quote from documentation of signal QGuiApplication::commitDataRequest(): "You should not exit the application within this signal. Instead, the session manager may or may not do this afterwards, depending on the context." Note that it says session manager and afterwards, not QGuiApplication and virtually immediately. - The session manager not "locking down" or better copying the list of clients *while* logging out. This would arguably only help buggy clients, but may still be a net positive. Why copy the list? Logout may be canceled, so it is valuable to keep the main client list updated for after logout cancellation. - Bonus: I've found that KMainWindowPrivate::init() calls QCoreApplication::setQuitLockEnabled(true), which is equivalent to QGuiApplication::setQuitOnLastWindowClosed(true), which is either redundant with the default or overrides something the user has explicitly changed. I noticed this while trying to narrow down the problem with a call to QGuiApplication::setQuitOnLastWindowClosed(false) from konsole's Application class. Which is not a good solution, but sufficient as a proof of concept fix. That fix works as far as session save and restore are concerned. So now I wonder what the chances are to fix those bugs. - Make ksmserver more robust in the face of clients dying too early, sure. I hope to get around to it Soon(TM). - Remove QCoreApplication::setQuitLockEnabled(true) from KMainWindowPrivate::init() - seems like a good idea to me, objections? - Remove any window closing from QGuiApplicationPrivate::commitData() - this is actually an old feature that was even modified in 2014 to fix a problem on Windows(?!) - I guess that one is there to prevent interaction after session saving, but it's a very crude way to do that. IMO it would be better to do nothing, it would be even better to block user input and possibly I/O handling for the duration of logout and unblock them when logout is canceled. Note: the Windows fix is about the method being expected to *kill* the application, which probably comes from a lack of knowledge about X session management which is the main purpose of that method. Commit 9835a63dde06a1e5d2f in qtbase. I'd be grateful for any additional insight and / or historical perspective. Cheers, Andreas