make the calls to ksmserver async. dbus will queue other calls while ksmserver is budy for us.

this way window management doesn't stutter when stopping/starting activities.
This commit is contained in:
Aaron Seigo 2011-11-24 15:54:48 +01:00
parent 290b990c5b
commit 26953d412c

42
sm.cpp
View file

@ -31,6 +31,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "workspace.h"
#include "client.h"
#include <QDBusInterface>
#include <QDBusPendingCall>
#include <QSocketNotifier>
#include <QSessionManager>
#include <kdebug.h>
@ -206,6 +207,7 @@ bool Workspace::stopActivity(const QString &id)
return false; //ksmserver doesn't queue requests (yet)
//FIXME what about session *loading*?
}
//ugly hack to avoid dbus deadlocks
QMetaObject::invokeMethod(this, "reallyStopActivity", Qt::QueuedConnection, Q_ARG(QString, id));
//then lie and assume it worked.
@ -214,18 +216,19 @@ bool Workspace::stopActivity(const QString &id)
void Workspace::reallyStopActivity(const QString &id)
{
QStringList openActivities = openActivityList();
kDebug() << id;
const QStringList openActivities = openActivityList();
QSet<QByteArray> saveSessionIds;
QSet<QByteArray> dontCloseSessionIds;
kDebug() << id;
for (ClientList::Iterator it = clients.begin(); it != clients.end(); ++it) {
Client* c = (*it);
QByteArray sessionId = c->sessionId();
if (sessionId.isEmpty())
const QByteArray sessionId = c->sessionId();
if (sessionId.isEmpty()) {
continue; //TODO support old wm_command apps too?
}
kDebug() << sessionId;
//kDebug() << sessionId;
//if it's on the activity that's closing, it needs saving
//but if a process is on some other open activity, I don't wanna close it yet
@ -234,12 +237,14 @@ void Workspace::reallyStopActivity(const QString &id)
dontCloseSessionIds << sessionId;
continue;
}
QStringList activities = c->activities();
const QStringList activities = c->activities();
foreach (const QString & activityId, activities) {
if (activityId == id)
if (activityId == id) {
saveSessionIds << sessionId;
else if (openActivities.contains(activityId))
} else if (openActivities.contains(activityId)) {
dontCloseSessionIds << sessionId;
}
}
}
@ -248,10 +253,11 @@ void Workspace::reallyStopActivity(const QString &id)
QStringList saveAndClose;
QStringList saveOnly;
foreach (const QByteArray & sessionId, saveSessionIds) {
if (dontCloseSessionIds.contains(sessionId))
if (dontCloseSessionIds.contains(sessionId)) {
saveOnly << sessionId;
else
} else {
saveAndClose << sessionId;
}
}
kDebug() << "saveActivity" << id << saveAndClose << saveOnly;
@ -259,13 +265,10 @@ void Workspace::reallyStopActivity(const QString &id)
//pass off to ksmserver
QDBusInterface ksmserver("org.kde.ksmserver", "/KSMServer", "org.kde.KSMServerInterface");
if (ksmserver.isValid()) {
QDBusMessage reply = ksmserver.call("saveSubSession", id, saveAndClose, saveOnly);
if (reply.type() == QDBusMessage::ErrorMessage)
kDebug() << "dbus error:" << reply.errorMessage();
else
kDebug() << "dbus succeeded";
} else
ksmserver.asyncCall("saveSubSession", id, saveAndClose, saveOnly);
} else {
kDebug() << "couldn't get ksmserver interface";
}
}
/*!
@ -336,6 +339,7 @@ bool Workspace::startActivity(const QString &id)
if (sessionSaving()) {
return false; //ksmserver doesn't queue requests (yet)
}
if (!allActivities_.contains(id)) {
return false; //bogus id
}
@ -344,11 +348,7 @@ bool Workspace::startActivity(const QString &id)
QDBusInterface ksmserver("org.kde.ksmserver", "/KSMServer", "org.kde.KSMServerInterface");
if (ksmserver.isValid()) {
QDBusMessage reply = ksmserver.call("restoreSubSession", id);
if (reply.type() == QDBusMessage::ErrorMessage) {
kDebug() << "dbus error:" << reply.errorMessage();
return false;
}
ksmserver.asyncCall("restoreSubSession", id);
} else {
kDebug() << "couldn't get ksmserver interface";
return false;