Causes of session management problems in Plasma 5
Andreas Hartmetz
ahartmetz at gmail.com
Tue Nov 24 01:02:46 GMT 2015
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
More information about the kde-core-devel
mailing list