plasma: implement session manager

comes along with plenty of other changes

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2024-05-07 10:46:00 +03:00
parent 51a8d78114
commit fb686dc3c1
42 changed files with 281 additions and 360 deletions

View file

@ -836,7 +836,7 @@ void DolphinMainWindow::openTerminal()
dir = url.toLocalFile(); dir = url.toLocalFile();
} }
KToolInvocation::invokeTerminal(QString(), dir); KToolInvocation::self()->invokeTerminal(QString(), dir);
} }
void DolphinMainWindow::editSettings() void DolphinMainWindow::editSettings()

View file

@ -86,6 +86,7 @@ int main(int argc, char **argv)
{ {
DolphinApplication app; DolphinApplication app;
app.enableSessionManagement();
if (app.isSessionRestored()) { if (app.isSessionRestored()) {
app.restoreSession(); app.restoreSession();
} }

View file

@ -135,7 +135,8 @@ void KateMailFilesPluginView::slotMail()
} // check selected docs done } // check selected docs done
if ( ! urls.count() ) if ( ! urls.count() )
return; return;
KToolInvocation::invokeMailer( QString(), // to KToolInvocation::self()->invokeMailer(
QString(), // to
QString(), // cc QString(), // cc
QString(), // subject QString(), // subject
QString(), // body QString(), // body

View file

@ -202,7 +202,7 @@ void KateSessionApplet::slotOnItemClicked(const QModelIndex &index)
else if ( id > 2 ) else if ( id > 2 )
args <<"-n"<< "--start"<<m_sessions[ id-3 ]; args <<"-n"<< "--start"<<m_sessions[ id-3 ];
KToolInvocation::kdeinitExec("kate", args); KToolInvocation::self()->kdeinitExec("kate", args);
} }
void KateSessionApplet::createConfigurationInterface(KConfigDialog *parent) void KateSessionApplet::createConfigurationInterface(KConfigDialog *parent)

View file

@ -53,7 +53,7 @@ void KateHelpButton::setIconState(IconState state)
void KateHelpButton::invokeHelp() void KateHelpButton::invokeHelp()
{ {
KToolInvocation::invokeHelp(m_section, "kate"); KToolInvocation::self()->invokeHelp(m_section, "kate");
} }
void KateHelpButton::setSection(const QString& section) void KateHelpButton::setSection(const QString& section)

View file

@ -805,8 +805,9 @@ KateCommandLineBar::KateCommandLineBar (KateView *view, QWidget *parent)
setFocusProxy (m_lineEdit); setFocusProxy (m_lineEdit);
} }
void KateCommandLineBar::showHelpPage() { void KateCommandLineBar::showHelpPage()
KToolInvocation::invokeHelp("advanced-editing-tools-commandline","kate"); {
KToolInvocation::self()->invokeHelp("advanced-editing-tools-commandline","kate");
} }
KateCommandLineBar::~KateCommandLineBar() KateCommandLineBar::~KateCommandLineBar()

View file

@ -365,7 +365,7 @@ int main( int argc, char **argv )
} }
#ifdef Q_WS_X11 #ifdef Q_WS_X11
// make the world happy, we are started, kind of... // make the world happy, it are started, kind of...
KStartupInfo::appStarted (); KStartupInfo::appStarted ();
#endif #endif
@ -377,6 +377,7 @@ int main( int argc, char **argv )
KateApp app (args); KateApp app (args);
if (app.shouldExit()) return 0; if (app.shouldExit()) return 0;
app.enableSessionManagement();
// execute ourself ;) // execute ourself ;)
return app.exec(); return app.exec();
} }

View file

@ -825,7 +825,7 @@ void KateMainWindow::slotOpenWithMenuAction(QAction* a)
void KateMainWindow::pluginHelp() void KateMainWindow::pluginHelp()
{ {
KToolInvocation::invokeHelp (QString(), "kate-plugins"); KToolInvocation::self()->invokeHelp (QString(), "kate-plugins");
} }
void KateMainWindow::aboutEditor() void KateMainWindow::aboutEditor()

View file

@ -672,7 +672,7 @@ void KAccessConfig::save()
// make kaccess reread the configuration // make kaccess reread the configuration
// turning a11y features off needs to be done by kaccess // turning a11y features off needs to be done by kaccess
// so run it to clear any enabled features and it will exit if it should // so run it to clear any enabled features and it will exit if it should
KToolInvocation::startServiceByDesktopName("kaccess"); KToolInvocation::self()->startServiceByDesktopName("kaccess");
emit changed(false); emit changed(false);
} }
@ -774,7 +774,7 @@ extern "C"
Q_DECL_EXPORT void kcminit_access() Q_DECL_EXPORT void kcminit_access()
{ {
KConfig config("kaccessrc", KConfig::NoGlobals); KConfig config("kaccessrc", KConfig::NoGlobals);
KToolInvocation::startServiceByDesktopName("kaccess"); KToolInvocation::self()->startServiceByDesktopName("kaccess");
} }
} }

View file

@ -68,9 +68,9 @@ extern "C"
// Tell klauncher to set the XCURSOR_THEME and XCURSOR_SIZE environment // Tell klauncher to set the XCURSOR_THEME and XCURSOR_SIZE environment
// variables when launching applications. // variables when launching applications.
KToolInvocation::setLaunchEnv("XCURSOR_THEME", theme); KToolInvocation::self()->setLaunchEnv("XCURSOR_THEME", theme);
if (!size.isEmpty()) { if (!size.isEmpty()) {
KToolInvocation::setLaunchEnv("XCURSOR_SIZE", size); KToolInvocation::self()->setLaunchEnv("XCURSOR_SIZE", size);
} }
#endif #endif
delete config; delete config;

View file

@ -557,7 +557,7 @@ void MouseConfig::save()
group.writeEntry("MKCurve", mk_curve->value()); group.writeEntry("MKCurve", mk_curve->value());
// restart kaccess // restart kaccess
KToolInvocation::startServiceByDesktopName("kaccess"); KToolInvocation::self()->startServiceByDesktopName("kaccess");
emit changed(false); emit changed(false);
} }

View file

@ -256,7 +256,7 @@ bool ThemePage::applyTheme(const CursorTheme *theme, const int size)
} }
// Set up the proper launch environment for newly started apps // Set up the proper launch environment for newly started apps
KToolInvocation::setLaunchEnv("XCURSOR_THEME", theme->name()); KToolInvocation::self()->setLaunchEnv("XCURSOR_THEME", theme->name());
// Update the Xcursor X resources // Update the Xcursor X resources
runRdb(); runRdb();

View file

@ -92,7 +92,7 @@ static void applyGtkStyles(bool active, int version)
// Pass env. var to klauncher. // Pass env. var to klauncher.
QString name = gtkEnvVar(version); QString name = gtkEnvVar(version);
QString value = list.join(":"); QString value = list.join(":");
KToolInvocation::setLaunchEnv(name, value); KToolInvocation::self()->setLaunchEnv(name, value);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View file

@ -162,7 +162,7 @@ void RandrMonitorModule::processX11Event( XEvent* e )
void RandrMonitorModule::showKcm() void RandrMonitorModule::showKcm()
{ {
KToolInvocation::kdeinitExec("kcmshell4", QStringList() << "randr"); KToolInvocation::self()->kdeinitExec("kcmshell4", QStringList() << "randr");
} }
void RandrMonitorModule::tryAutoConfig() void RandrMonitorModule::tryAutoConfig()
@ -244,7 +244,7 @@ void RandrMonitorModule::switchDisplay()
return; return;
} }
// no idea what to do here // no idea what to do here
KToolInvocation::kdeinitExec( "kcmshell4", QStringList() << "randr" ); KToolInvocation::self()->kdeinitExec( "kcmshell4", QStringList() << "randr" );
} }
void RandrMonitorModule::resumedFromSuspend() void RandrMonitorModule::resumedFromSuspend()

View file

@ -176,7 +176,7 @@ void KCrashModule::slotDirty(const QString &path)
kcrashargs.append(kcrashdisplay); kcrashargs.append(kcrashdisplay);
} }
kDebug() << "Restarting" << kcrashfilepath << kcrashapppath << kcrashargs; kDebug() << "Restarting" << kcrashfilepath << kcrashapppath << kcrashargs;
KToolInvocation::kdeinitExec(kcrashapppath, kcrashargs); KToolInvocation::self()->kdeinitExec(kcrashapppath, kcrashargs);
} }
} }
} }
@ -195,9 +195,9 @@ void KCrashModule::slotReport()
const QString kcrashreporturl = knotification->property("_k_url").toString(); const QString kcrashreporturl = knotification->property("_k_url").toString();
knotification->close(); knotification->close();
if (kcrashreporturl.startsWith(QLatin1String("mailto:"))) { if (kcrashreporturl.startsWith(QLatin1String("mailto:"))) {
KToolInvocation::invokeMailer(kcrashreporturl, QString::fromLatin1("Crash report")); KToolInvocation::self()->invokeMailer(kcrashreporturl, QString::fromLatin1("Crash report"));
} else { } else {
KToolInvocation::invokeBrowser(kcrashreporturl); KToolInvocation::self()->invokeBrowser(kcrashreporturl);
} }
} }

View file

@ -167,7 +167,7 @@ void KHostName::changeSessionManager()
return; return;
} }
sm = "local/"+newName+sm.mid(i); sm = "local/"+newName+sm.mid(i);
KToolInvocation::setLaunchEnv(QString::fromLatin1("SESSION_MANAGER"), sm); KToolInvocation::self()->setLaunchEnv(QString::fromLatin1("SESSION_MANAGER"), sm);
} }
int main(int argc, char **argv) int main(int argc, char **argv)

View file

@ -233,7 +233,7 @@ void KInfoCenter::resetCondition()
void KInfoCenter::helpClickedSlot() void KInfoCenter::helpClickedSlot()
{ {
KToolInvocation::invokeHelp(QString(), m_contain->serviceName()); KToolInvocation::self()->invokeHelp(QString(), m_contain->serviceName());
} }
void KInfoCenter::exportClickedSlot() void KInfoCenter::exportClickedSlot()

View file

@ -84,7 +84,7 @@ void KNetAttach::slotPageChanged(int)
void KNetAttach::slotHelpClicked() void KNetAttach::slotHelpClicked()
{ {
KToolInvocation::invokeHelp(QString(), "knetattach"); KToolInvocation::self()->invokeHelp(QString(), "knetattach");
} }
void KNetAttach::setInformationText(const QString &type) void KNetAttach::setInformationText(const QString &type)

View file

@ -495,7 +495,7 @@ void SessionController::handleOpenWithAction()
void SessionController::configureWebShortcuts() void SessionController::configureWebShortcuts()
{ {
KToolInvocation::kdeinitExec("kcmshell4", QStringList() << "ebrowsing"); KToolInvocation::self()->kdeinitExec("kcmshell4", QStringList() << "ebrowsing");
} }
void SessionController::sendSignal(QAction* action) void SessionController::sendSignal(QAction* action)

View file

@ -71,6 +71,7 @@ int main(int argc, char** argv)
// create a new application instance // create a new application instance
Application app; Application app;
app.enableSessionManagement();
// make sure the d&d popup menu provided by libkonq get translated. // make sure the d&d popup menu provided by libkonq get translated.
KGlobal::locale()->insertCatalog("libkonq"); KGlobal::locale()->insertCatalog("libkonq");

View file

@ -98,7 +98,7 @@ KStart::KStart()
} }
} else { } else {
QString error; QString error;
if (KToolInvocation::startServiceByDesktopPath(exe, url, &error) != 0) { if (KToolInvocation::self()->startServiceByDesktopPath(exe, url, &error) != 0) {
kError() << error; kError() << error;
} }
} }

View file

@ -224,7 +224,7 @@ bool HostConnector::useCustom() const
void HostConnector::slotHelp() void HostConnector::slotHelp()
{ {
KToolInvocation::invokeHelp( "connectingtootherhosts", "ksysguard" ); KToolInvocation::self()->invokeHelp( "connectingtootherhosts", "ksysguard" );
} }
#include "moc_HostConnector.cpp" #include "moc_HostConnector.cpp"

View file

@ -57,7 +57,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "atoms.h" #include "atoms.h"
#include "options.h" #include "options.h"
#include "sm.h"
#include "utils.h" #include "utils.h"
#include "effects.h" #include "effects.h"
#include "workspace.h" #include "workspace.h"
@ -275,6 +274,17 @@ bool Application::setup()
return true; return true;
} }
bool Application::saveSession()
{
Workspace::self()->sessionSaveStarted();
RuleBook::self()->setUpdatesDisabled(true);
Workspace::self()->storeSession(kapp->sessionConfig());
kapp->sessionConfig()->sync();
RuleBook::self()->setUpdatesDisabled(false); // re-enable
Workspace::self()->sessionSaveDone();
return KApplication::saveSession();
}
void Application::lostSelection() void Application::lostSelection()
{ {
KCrash::setFlags(0); // too late to restart now KCrash::setFlags(0); // too late to restart now
@ -335,6 +345,7 @@ int main(int argc, char * argv[])
KCmdLineArgs::addCmdLineOptions(args); KCmdLineArgs::addCmdLineOptions(args);
KWin::Application a; KWin::Application a;
a.enableSessionManagement();
QDBusInterface plasma("org.kde.plasma-desktop", "/App", "local.PlasmaApp", QDBusConnection::sessionBus()); QDBusInterface plasma("org.kde.plasma-desktop", "/App", "local.PlasmaApp", QDBusConnection::sessionBus());
if (plasma.isValid()) { if (plasma.isValid()) {
plasma.call("suspendStartup", "kwin"); plasma.call("suspendStartup", "kwin");
@ -361,8 +372,6 @@ int main(int argc, char * argv[])
if (plasma.isValid()) { if (plasma.isValid()) {
plasma.call("resumeStartup", "kwin"); plasma.call("resumeStartup", "kwin");
} }
KWin::SessionManager weAreIndeed;
KWin::SessionSaveDoneHelper helper;
KGlobal::locale()->insertCatalog("kwin_effects"); KGlobal::locale()->insertCatalog("kwin_effects");
fcntl(XConnectionNumber(KWin::display()), F_SETFD, 1); fcntl(XConnectionNumber(KWin::display()), F_SETFD, 1);

View file

@ -42,7 +42,10 @@ protected:
bool x11EventFilter(XEvent*); bool x11EventFilter(XEvent*);
bool notify(QObject* o, QEvent* e); bool notify(QObject* o, QEvent* e);
private slots: private Q_SLOTS:
bool saveSession() final;
private Q_SLOTS:
void lostSelection(); void lostSelection();
private: private:

View file

@ -968,7 +968,7 @@ void RuleBook::edit(Client* c, bool whole_app)
args << "--wid" << QString::number(c->window()); args << "--wid" << QString::number(c->window());
if (whole_app) if (whole_app)
args << "--whole-app"; args << "--whole-app";
KToolInvocation::kdeinitExec("kwin_rules_dialog", args); KToolInvocation::self()->kdeinitExec("kwin_rules_dialog", args);
} }
void RuleBook::load() void RuleBook::load()

View file

@ -31,44 +31,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "workspace.h" #include "workspace.h"
#include "client.h" #include "client.h"
#include <QSocketNotifier> #include <QSocketNotifier>
#include <QSessionManager>
#include <kdebug.h> #include <kdebug.h>
namespace KWin namespace KWin
{ {
bool SessionManager::saveState(QSessionManager& sm)
{
// If the session manager is plasma-desktop, save stacking
// order, active window, active desktop etc. in phase 1,
// as plasma-desktop assures no interaction will be done
// before the WM finishes phase 1. Saving in phase 2 is
// too late, as possible user interaction may change some things.
// Phase2 is still needed though (ICCCM 5.2)
char* sm_vendor = SmcVendor(static_cast< SmcConn >(sm.handle()));
bool kde = qstrcmp(sm_vendor, "KDE") == 0;
free(sm_vendor);
if (!sm.isPhase2()) {
Workspace::self()->sessionSaveStarted();
if (kde) // save stacking order etc. before "save file?" etc. dialogs change it
Workspace::self()->storeSession(kapp->sessionConfig(), SMSavePhase0);
sm.release(); // Qt doesn't automatically release in this case (bug?)
sm.requestPhase2();
return true;
}
Workspace::self()->storeSession(kapp->sessionConfig(), kde ? SMSavePhase2 : SMSavePhase2Full);
kapp->sessionConfig()->sync();
return true;
}
// I bet this is broken, just like everywhere else in KDE
bool SessionManager::commitData(QSessionManager& sm)
{
if (!sm.isPhase2())
Workspace::self()->sessionSaveStarted();
return true;
}
// Workspace // Workspace
/*! /*!
@ -76,7 +43,7 @@ bool SessionManager::commitData(QSessionManager& sm)
\sa loadSessionInfo() \sa loadSessionInfo()
*/ */
void Workspace::storeSession(KConfig* config, SMSavePhase phase) void Workspace::storeSession(KConfig* config)
{ {
KConfigGroup cg(config, "Session"); KConfigGroup cg(config, "Session");
int count = 0; int count = 0;
@ -92,24 +59,11 @@ void Workspace::storeSession(KConfig* config, SMSavePhase phase)
count++; count++;
if (c->isActive()) if (c->isActive())
active_client = count; active_client = count;
if (phase == SMSavePhase2 || phase == SMSavePhase2Full)
storeClient(cg, count, c); storeClient(cg, count, c);
} }
if (phase == SMSavePhase0) {
// it would be much simpler to save these values to the config file,
// but both Qt and KDE treat phase1 and phase2 separately,
// which results in different sessionkey and different config file :(
session_active_client = active_client;
session_desktop = VirtualDesktopManager::self()->current();
} else if (phase == SMSavePhase2) {
cg.writeEntry("count", count);
cg.writeEntry("active", session_active_client);
cg.writeEntry("desktop", session_desktop);
} else { // SMSavePhase2Full
cg.writeEntry("count", count); cg.writeEntry("count", count);
cg.writeEntry("active", session_active_client); cg.writeEntry("active", session_active_client);
cg.writeEntry("desktop", VirtualDesktopManager::self()->current()); cg.writeEntry("desktop", VirtualDesktopManager::self()->current());
}
} }
void Workspace::storeClient(KConfigGroup &cg, int num, Client *c) void Workspace::storeClient(KConfigGroup &cg, int num, Client *c)
@ -149,32 +103,6 @@ void Workspace::storeClient(KConfigGroup &cg, int num, Client *c)
cg.writeEntry(QString("tabGroup") + n, static_cast<int>(reinterpret_cast<long>(c->tabGroup()))); cg.writeEntry(QString("tabGroup") + n, static_cast<int>(reinterpret_cast<long>(c->tabGroup())));
} }
void Workspace::storeSubSession(const QString &name, QSet<QByteArray> sessionIds)
{
//TODO clear it first
KConfigGroup cg(KGlobal::config(), QString("SubSession: ") + name);
int count = 0;
int active_client = -1;
foreach (Client *c, clients) {
QByteArray sessionId = c->sessionId();
QByteArray wmCommand = c->wmCommand();
if (sessionId.isEmpty())
if (wmCommand.isEmpty())
continue;
if (!sessionIds.contains(sessionId))
continue;
kDebug() << "storing" << sessionId;
count++;
if (c->isActive())
active_client = count;
storeClient(cg, count, c);
}
cg.writeEntry("count", count);
cg.writeEntry("active", active_client);
//cg.writeEntry( "desktop", currentDesktop());
}
/*! /*!
Loads the session information from the config file. Loads the session information from the config file.
@ -185,16 +113,11 @@ void Workspace::loadSessionInfo()
session.clear(); session.clear();
KConfigGroup cg(kapp->sessionConfig(), "Session"); KConfigGroup cg(kapp->sessionConfig(), "Session");
addSessionInfo(cg);
}
void Workspace::addSessionInfo(KConfigGroup &cg)
{
int count = cg.readEntry("count", 0); int count = cg.readEntry("count", 0);
int active_client = cg.readEntry("active", 0); int active_client = cg.readEntry("active", 0);
for (int i = 1; i <= count; i++) { for (int i = 1; i <= count; i++) {
QString n = QString::number(i); QString n = QString::number(i);
SessionInfo* info = new SessionInfo; SessionInfo* info = new SessionInfo();
session.append(info); session.append(info);
info->sessionId = cg.readEntry(QString("sessionId") + n, QString()).toLatin1(); info->sessionId = cg.readEntry(QString("sessionId") + n, QString()).toLatin1();
info->windowRole = cg.readEntry(QString("windowRole") + n, QString()).toLatin1(); info->windowRole = cg.readEntry(QString("windowRole") + n, QString()).toLatin1();
@ -226,12 +149,6 @@ void Workspace::addSessionInfo(KConfigGroup &cg)
} }
} }
void Workspace::loadSubSessionInfo(const QString &name)
{
KConfigGroup cg(KGlobal::config(), QString("SubSession: ") + name);
addSessionInfo(cg);
}
/*! /*!
Returns a SessionInfo for client \a c. The returned session Returns a SessionInfo for client \a c. The returned session
info is removed from the storage. It's up to the caller to delete it. info is removed from the storage. It's up to the caller to delete it.
@ -334,157 +251,6 @@ NET::WindowType Workspace::txtToWindowType(const char* txt)
return static_cast< NET::WindowType >(-2); // undefined return static_cast< NET::WindowType >(-2); // undefined
} }
// KWin's focus stealing prevention causes problems with user interaction
// during session save, as it prevents possible dialogs from getting focus.
// Therefore it's temporarily disabled during session saving. Start of
// session saving can be detected in SessionManager::saveState() above,
// but Qt doesn't have API for saying when session saved finished (either
// successfully, or was canceled). Therefore, create another connection
// to session manager, that will provide this information.
// Similarly the remember feature of window-specific settings should be disabled
// during KDE shutdown when windows may move e.g. because of Kicker going away
// (struts changing). When session saving starts, it can be cancelled, in which
// case the shutdown_cancelled callback is invoked, or it's a checkpoint that
// is immediatelly followed by save_complete, or finally it's a shutdown that
// is immediatelly followed by die callback. So getting save_yourself with shutdown
// set disables window-specific settings remembering, getting shutdown_cancelled
// re-enables, otherwise KWin will go away after die.
static void save_yourself(SmcConn conn_P, SmPointer ptr, int, Bool shutdown, int, Bool)
{
SessionSaveDoneHelper* session = reinterpret_cast< SessionSaveDoneHelper* >(ptr);
if (conn_P != session->connection())
return;
if (shutdown)
RuleBook::self()->setUpdatesDisabled(true);
SmcSaveYourselfDone(conn_P, True);
}
static void die(SmcConn conn_P, SmPointer ptr)
{
SessionSaveDoneHelper* session = reinterpret_cast< SessionSaveDoneHelper* >(ptr);
if (conn_P != session->connection())
return;
// session->saveDone(); we will quit anyway
session->close();
}
static void save_complete(SmcConn conn_P, SmPointer ptr)
{
SessionSaveDoneHelper* session = reinterpret_cast< SessionSaveDoneHelper* >(ptr);
if (conn_P != session->connection())
return;
session->saveDone();
}
static void shutdown_cancelled(SmcConn conn_P, SmPointer ptr)
{
SessionSaveDoneHelper* session = reinterpret_cast< SessionSaveDoneHelper* >(ptr);
if (conn_P != session->connection())
return;
RuleBook::self()->setUpdatesDisabled(false); // re-enable
// no need to differentiate between successful finish and cancel
session->saveDone();
}
void SessionSaveDoneHelper::saveDone()
{
Workspace::self()->sessionSaveDone();
}
SessionSaveDoneHelper::SessionSaveDoneHelper()
{
SmcCallbacks calls;
calls.save_yourself.callback = save_yourself;
calls.save_yourself.client_data = reinterpret_cast< SmPointer >(this);
calls.die.callback = die;
calls.die.client_data = reinterpret_cast< SmPointer >(this);
calls.save_complete.callback = save_complete;
calls.save_complete.client_data = reinterpret_cast< SmPointer >(this);
calls.shutdown_cancelled.callback = shutdown_cancelled;
calls.shutdown_cancelled.client_data = reinterpret_cast< SmPointer >(this);
char* id = NULL;
char err[ 11 ];
conn = SmcOpenConnection(NULL, 0, 1, 0,
SmcSaveYourselfProcMask | SmcDieProcMask | SmcSaveCompleteProcMask
| SmcShutdownCancelledProcMask, &calls, NULL, &id, 10, err);
if (id != NULL)
free(id);
if (conn == NULL)
return; // no SM
// set the required properties, mostly dummy values
SmPropValue propvalue[ 5 ];
SmProp props[ 5 ];
propvalue[ 0 ].length = sizeof(unsigned char);
unsigned char value0 = SmRestartNever; // so that this extra SM connection doesn't interfere
propvalue[ 0 ].value = &value0;
props[ 0 ].name = const_cast< char* >(SmRestartStyleHint);
props[ 0 ].type = const_cast< char* >(SmCARD8);
props[ 0 ].num_vals = 1;
props[ 0 ].vals = &propvalue[ 0 ];
QByteArray username = KUser(KUser::UseEffectiveUID).loginName().toLocal8Bit();
propvalue[ 1 ].length = username.size();
propvalue[ 1 ].value = (SmPointer)(username.isEmpty() ? "" : username.data());
props[ 1 ].name = const_cast< char* >(SmUserID);
props[ 1 ].type = const_cast< char* >(SmARRAY8);
props[ 1 ].num_vals = 1;
props[ 1 ].vals = &propvalue[ 1 ];
propvalue[ 2 ].length = 0;
propvalue[ 2 ].value = (SmPointer)("");
props[ 2 ].name = const_cast< char* >(SmRestartCommand);
props[ 2 ].type = const_cast< char* >(SmLISTofARRAY8);
props[ 2 ].num_vals = 1;
props[ 2 ].vals = &propvalue[ 2 ];
propvalue[ 3 ].length = strlen("kwinsmhelper");
propvalue[ 3 ].value = (SmPointer)"kwinsmhelper";
props[ 3 ].name = const_cast< char* >(SmProgram);
props[ 3 ].type = const_cast< char* >(SmARRAY8);
props[ 3 ].num_vals = 1;
props[ 3 ].vals = &propvalue[ 3 ];
propvalue[ 4 ].length = 0;
propvalue[ 4 ].value = (SmPointer)("");
props[ 4 ].name = const_cast< char* >(SmCloneCommand);
props[ 4 ].type = const_cast< char* >(SmLISTofARRAY8);
props[ 4 ].num_vals = 1;
props[ 4 ].vals = &propvalue[ 4 ];
SmProp* p[ 5 ] = { &props[ 0 ], &props[ 1 ], &props[ 2 ], &props[ 3 ], &props[ 4 ] };
SmcSetProperties(conn, 5, p);
notifier = new QSocketNotifier(IceConnectionNumber(SmcGetIceConnection(conn)),
QSocketNotifier::Read, this);
connect(notifier, SIGNAL(activated(int)), SLOT(processData()));
}
SessionSaveDoneHelper::~SessionSaveDoneHelper()
{
close();
}
void SessionSaveDoneHelper::close()
{
if (conn != NULL) {
delete notifier;
SmcCloseConnection(conn, 0, NULL);
}
conn = NULL;
}
void SessionSaveDoneHelper::processData()
{
if (conn != NULL)
IceProcessMessages(SmcGetIceConnection(conn), 0, 0);
}
void Workspace::sessionSaveDone()
{
session_saving = false;
//remove sessionInteract flag from all clients
foreach (Client * c, clients) {
c->setSessionInteract(false);
}
}
} // namespace } // namespace
#include "moc_sm.cpp" #include "moc_sm.cpp"

View file

@ -24,7 +24,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QDataStream> #include <QDataStream>
#include <kapplication.h> #include <kapplication.h>
#include <ksessionmanager.h>
#include <netwm_def.h> #include <netwm_def.h>
#include <QRect> #include <QRect>
@ -71,41 +70,6 @@ struct SessionInfo {
Client* tabGroupClient; // The first client created that has an identical identifier Client* tabGroupClient; // The first client created that has an identical identifier
}; };
enum SMSavePhase {
SMSavePhase0, // saving global state in "phase 0"
SMSavePhase2, // saving window state in phase 2
SMSavePhase2Full // complete saving in phase2, there was no phase 0
};
class SessionSaveDoneHelper
: public QObject
{
Q_OBJECT
public:
SessionSaveDoneHelper();
virtual ~SessionSaveDoneHelper();
SmcConn connection() const {
return conn;
}
void saveDone();
void close();
private slots:
void processData();
private:
QSocketNotifier* notifier;
SmcConn conn;
};
class SessionManager
: public KSessionManager
{
public:
virtual bool saveState(QSessionManager& sm);
virtual bool commitData(QSessionManager& sm);
};
} // namespace } // namespace
#endif #endif

View file

@ -223,7 +223,7 @@ void UserActionsMenu::configureWM()
{ {
QStringList args; QStringList args;
args << "--icon" << "preferences-system-windows" << configModules(); args << "--icon" << "preferences-system-windows" << configModules();
KToolInvocation::kdeinitExec("kcmshell4", args); KToolInvocation::self()->kdeinitExec("kcmshell4", args);
} }
void UserActionsMenu::init() void UserActionsMenu::init()

View file

@ -26,6 +26,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// kwin // kwin
#include <kdecoration.h> #include <kdecoration.h>
#include "sm.h" #include "sm.h"
#include "client.h"
#include "utils.h" #include "utils.h"
// Katie // Katie
#include <QKeySequence> #include <QKeySequence>
@ -225,10 +226,8 @@ public:
void performWindowOperation(Client* c, WindowOperation op); void performWindowOperation(Client* c, WindowOperation op);
void storeSession(KConfig* config, SMSavePhase phase); void storeSession(KConfig* config);
void storeClient(KConfigGroup &cg, int num, Client *c); void storeClient(KConfigGroup &cg, int num, Client *c);
void storeSubSession(const QString &name, QSet<QByteArray> sessionIds);
void loadSubSessionInfo(const QString &name);
SessionInfo* takeSessionInfo(Client*); SessionInfo* takeSessionInfo(Client*);
@ -453,7 +452,6 @@ private:
Client* active_popup_client; Client* active_popup_client;
void loadSessionInfo(); void loadSessionInfo();
void addSessionInfo(KConfigGroup &cg);
QList<SessionInfo*> session; QList<SessionInfo*> session;
static const char* windowTypeToTxt(NET::WindowType type); static const char* windowTypeToTxt(NET::WindowType type);
@ -610,6 +608,20 @@ inline const ToplevelList& Workspace::stackingOrder() const
return stacking_order; return stacking_order;
} }
inline void Workspace::sessionSaveStarted()
{
session_saving = true;
}
inline void Workspace::sessionSaveDone()
{
session_saving = false;
//remove sessionInteract flag from all clients
foreach (Client * c, clients) {
c->setSessionInteract(false);
}
}
inline void Workspace::setWasUserInteraction() inline void Workspace::setWasUserInteraction()
{ {
was_user_interaction = true; was_user_interaction = true;
@ -620,11 +632,6 @@ inline bool Workspace::wasUserInteraction() const
return was_user_interaction; return was_user_interaction;
} }
inline void Workspace::sessionSaveStarted()
{
session_saving = true;
}
inline bool Workspace::sessionSaving() const inline bool Workspace::sessionSaving() const
{ {
return session_saving; return session_saving;

View file

@ -383,7 +383,7 @@ void KonqOperations::asyncDrop( const KFileItem & destItem )
{ {
QString error; QString error;
const QStringList urlStrList = m_info->urls.toStringList(); const QStringList urlStrList = m_info->urls.toStringList();
if ( KToolInvocation::startServiceByDesktopPath( m_destUrl.path(), urlStrList, &error ) > 0 ) if ( KToolInvocation::self()->startServiceByDesktopPath( m_destUrl.path(), urlStrList, &error ) > 0 )
KMessageBox::error( parentWidget(), error ); KMessageBox::error( parentWidget(), error );
} }
else else

View file

@ -1806,7 +1806,7 @@ KBookmarkManager* LauncherApplet::bookmarkManager() const
void LauncherApplet::slotEditMenu() void LauncherApplet::slotEditMenu()
{ {
if (KToolInvocation::kdeinitExec("kmenuedit") == 0) { if (KToolInvocation::self()->kdeinitExec("kmenuedit") == 0) {
hidePopup(); hidePopup();
} else { } else {
showMessage(KIcon("dialog-error"), i18n("Failed to launch menu editor"), Plasma::MessageButton::ButtonOk); showMessage(KIcon("dialog-error"), i18n("Failed to launch menu editor"), Plasma::MessageButton::ButtonOk);

View file

@ -108,7 +108,7 @@ void BookmarksRunner::run(const Plasma::QueryMatch &action)
const QString term = action.data().toString(); const QString term = action.data().toString();
// transforms URLs like "kde.org" to "http://kde.org" // transforms URLs like "kde.org" to "http://kde.org"
const KUrl url = KUrl::fromUserInput(term); const KUrl url = KUrl::fromUserInput(term);
KToolInvocation::invokeBrowser(url.url()); KToolInvocation::self()->invokeBrowser(url.url());
} }
QMimeData* BookmarksRunner::mimeDataForMatch(const Plasma::QueryMatch &match) QMimeData* BookmarksRunner::mimeDataForMatch(const Plasma::QueryMatch &match)

View file

@ -64,7 +64,7 @@ void ShellRunner::run(const Plasma::QueryMatch &match)
} }
const QString command = match.data().toString(); const QString command = match.data().toString();
if (interminal) { if (interminal) {
KToolInvocation::invokeTerminal(command); KToolInvocation::self()->invokeTerminal(command);
} else { } else {
KRun::runCommand(command, nullptr); KRun::runCommand(command, nullptr);
} }

View file

@ -233,7 +233,7 @@ void SolidRunner::run(const Plasma::QueryMatch &match)
return; return;
} }
const QString actionexe = actioncommand.takeFirst(); const QString actionexe = actioncommand.takeFirst();
const int actionresult = KToolInvocation::kdeinitExec(actionexe, actioncommand); const int actionresult = KToolInvocation::self()->kdeinitExec(actionexe, actioncommand);
if (actionresult != 0) { if (actionresult != 0) {
kWarning() << "could not execute action for" << actionname << "in" << actionfilepath << actionresult; kWarning() << "could not execute action for" << actionname << "in" << actionfilepath << actionresult;
} }

View file

@ -106,7 +106,7 @@ void WebshortcutRunner::run(const Plasma::QueryMatch &match)
// kDebug() << location; // kDebug() << location;
if (!location.isEmpty()) { if (!location.isEmpty()) {
KToolInvocation::invokeBrowser(location); KToolInvocation::self()->invokeBrowser(location);
} }
} }

View file

@ -21,6 +21,9 @@ set(plasma_SRCS
set(plasmaapp_dbusXML dbus/org.kde.plasma.App.xml) set(plasmaapp_dbusXML dbus/org.kde.plasma.App.xml)
qt4_add_dbus_adaptor(plasma_SRCS ${plasmaapp_dbusXML} plasmaapp.h PlasmaApp) qt4_add_dbus_adaptor(plasma_SRCS ${plasmaapp_dbusXML} plasmaapp.h PlasmaApp)
set(kapplication_xml ${KDE4_DBUS_INTERFACES_INSTALL_DIR}/org.kde.KApplication.xml)
qt4_add_dbus_interface(plasma_SRCS ${kapplication_xml} kapplication_interface)
add_executable(plasma-desktop ${plasma_SRCS}) add_executable(plasma-desktop ${plasma_SRCS})
target_link_libraries(plasma-desktop target_link_libraries(plasma-desktop

View file

@ -1,8 +1,6 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node> <node>
<interface name="local.PlasmaApp"> <interface name="local.PlasmaApp">
<method name="quit">
</method>
<method name="createWaitingPanels"> <method name="createWaitingPanels">
</method> </method>
<method name="createWaitingDesktops"> <method name="createWaitingDesktops">
@ -10,16 +8,27 @@
<method name="supportInformation"> <method name="supportInformation">
<arg type="s" direction="out"/> <arg type="s" direction="out"/>
</method> </method>
<method name="saveClients">
</method>
<method name="restoreClients">
</method>
<method name="registerClient">
<arg name="client" type="s" direction="in"/>
</method>
<method name="unregisterClient">
<arg name="client" type="s" direction="in"/>
</method>
<method name="suspendStartup"> <method name="suspendStartup">
<arg type="s" direction="in"/> <arg name="app" type="s" direction="in"/>
</method> </method>
<method name="resumeStartup"> <method name="resumeStartup">
<arg type="s" direction="in"/> <arg name="app" type="s" direction="in"/>
</method> </method>
<method name="logout"> <method name="logout">
<arg type="i" direction="in"/> <arg name="confirm" type="i" direction="in"/>
<arg type="i" direction="in"/> <arg name="sdtype" type="i" direction="in"/>
</method>
<method name="wmChanged">
</method> </method>
<method name="wmChanged"/>
</interface> </interface>
</node> </node>

View file

@ -44,11 +44,13 @@ int main(int argc, char **argv)
ki18n("In memory of his contributions, 1937-1998."), ki18n("In memory of his contributions, 1937-1998."),
0, "http://en.wikipedia.org/wiki/John_Lions"); 0, "http://en.wikipedia.org/wiki/John_Lions");
// plasma-desktop is the session manager
::unsetenv("SESSION_MANAGER");
KCmdLineArgs::init(argc, argv, &aboutData); KCmdLineArgs::init(argc, argv, &aboutData);
PlasmaApp *app = PlasmaApp::self(); PlasmaApp *app = PlasmaApp::self();
QApplication::setWindowIcon(KIcon("plasma")); QApplication::setWindowIcon(KIcon("plasma"));
app->disableSessionManagement(); // autostarted
int rc = app->exec(); int rc = app->exec();
delete app; delete app;

View file

@ -27,6 +27,7 @@
#include <QTimer> #include <QTimer>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QTextStream> #include <QTextStream>
#include <QFileInfo>
#include <KAction> #include <KAction>
#include <KCrash> #include <KCrash>
@ -69,6 +70,8 @@
#include <X11/Xutil.h> #include <X11/Xutil.h>
#endif #endif
static const int s_phasedelay = 1000; // ms
static const int s_sessiondelay = 500; // ms
static const QString s_defaultwm = QString::fromLatin1("kwin"); static const QString s_defaultwm = QString::fromLatin1("kwin");
static const QStringList s_defaultwmcommands = QStringList() << s_defaultwm; static const QStringList s_defaultwmcommands = QStringList() << s_defaultwm;
@ -114,7 +117,9 @@ PlasmaApp::PlasmaApp()
m_wmproc(nullptr), m_wmproc(nullptr),
m_startupsuspend(0), m_startupsuspend(0),
m_dialogActive(false), m_dialogActive(false),
m_sdtype(KWorkSpace::ShutdownTypeNone) m_sdtype(KWorkSpace::ShutdownTypeNone),
m_waitingcount(0),
m_sessionManager(false)
{ {
kDebug() << "!!{} STARTUP TIME" << QTime().msecsTo(QTime::currentTime()) << "plasma app ctor start" << "(line:" << __LINE__ << ")"; kDebug() << "!!{} STARTUP TIME" << QTime().msecsTo(QTime::currentTime()) << "plasma app ctor start" << "(line:" << __LINE__ << ")";
@ -175,9 +180,6 @@ PlasmaApp::PlasmaApp()
QDBusConnection::sessionBus(), QDBusConnection::sessionBus(),
this this
); );
// TODO: m_klauncher->call("setLaunchEnv", "SESSION_MANAGER", "TODO");
m_kcminit = new QDBusInterface( m_kcminit = new QDBusInterface(
QLatin1String("org.kde.kcminit"), QLatin1String("org.kde.kcminit"),
QLatin1String("/kcminit"), QLatin1String("/kcminit"),
@ -185,11 +187,15 @@ PlasmaApp::PlasmaApp()
QDBusConnection::sessionBus(), QDBusConnection::sessionBus(),
this this
); );
const bool failsafe = (qgetenv("KDE_FAILSAFE").toInt() == 1);
if (!failsafe) {
m_sessionManager = true;
}
KGlobal::dirs()->addResourceType("windowmanagers", "data", "plasma/windowmanagers"); KGlobal::dirs()->addResourceType("windowmanagers", "data", "plasma/windowmanagers");
QStringList wmcommands; QStringList wmcommands;
if (qgetenv("KDE_FAILSAFE").toInt() != 1) { if (!failsafe) {
KConfig cfg("plasmarc", KConfig::NoGlobals); KConfig cfg("plasmarc", KConfig::NoGlobals);
KConfigGroup config(&cfg, "General"); KConfigGroup config(&cfg, "General");
const QString wmname = config.readEntry("windowManager", s_defaultwm); const QString wmname = config.readEntry("windowManager", s_defaultwm);
@ -203,12 +209,28 @@ PlasmaApp::PlasmaApp()
if (wmcommands.isEmpty()) { if (wmcommands.isEmpty()) {
wmcommands = s_defaultwmcommands; wmcommands = s_defaultwmcommands;
} }
const QString wmprog = wmcommands.takeFirst(); QString wmprog = wmcommands.takeFirst();
KConfigGroup sessiongroup(KGlobal::config(), "Session");
foreach (const QString &group, sessiongroup.groupList()) {
KConfigGroup clientgroup(&sessiongroup, group);
QStringList restartcommand = clientgroup.readEntry("restartCommand", QStringList());
if (restartcommand.size() < 1) {
kWarning() << "invalid restart command" << group;
continue;
}
QString program = restartcommand.takeFirst();
if (program == wmprog || QFileInfo(program).fileName() == QFileInfo(wmprog).fileName()) {
wmprog = program;
wmcommands = restartcommand;
kDebug() << "using session WM entry" << wmprog << wmcommands;
clientgroup.deleteGroup();
clientgroup.sync();
}
}
m_wmproc = new QProcess(this); m_wmproc = new QProcess(this);
m_wmproc->start(wmprog, wmcommands); m_wmproc->start(wmprog, wmcommands);
m_wmproc->waitForStarted(4000);
QTimer::singleShot(100, this, SLOT(nextPhase())); QTimer::singleShot(s_phasedelay, this, SLOT(nextPhase()));
} }
PlasmaApp::~PlasmaApp() PlasmaApp::~PlasmaApp()
@ -954,6 +976,110 @@ QString PlasmaApp::supportInformation() const
return streambuffer; return streambuffer;
} }
void PlasmaApp::saveClients()
{
if (!m_sessionManager || m_clients.size() < 1) {
doLogout();
return;
}
kDebug() << "initiating session save" << m_clients.size();
m_waitingcount = 0;
QMapIterator<QString,org::kde::KApplication*> iter(m_clients);
iter.toBack();
// window manager should be last to save its state first to restore so iteration is done
// backwards
while (iter.hasPrevious()) {
iter.previous();
kDebug() << "calling saveSession() for" << iter.key();
org::kde::KApplication* clientinterface = iter.value();
clientinterface->asyncCall("saveSession");
}
}
void PlasmaApp::restoreClients()
{
kDebug() << "restoring session";
KConfigGroup sessiongroup(KGlobal::config(), "Session");
foreach (const QString &group, sessiongroup.groupList()) {
KConfigGroup clientgroup(&sessiongroup, group);
QStringList restartcommand = clientgroup.readEntry("restartCommand", QStringList());
if (restartcommand.size() < 1) {
kWarning() << "invalid restart command" << group;
continue;
}
QString program = restartcommand.takeFirst();
kDebug() << "restoring client" << program << restartcommand;
KToolInvocation::self()->kdeinitExec(program, restartcommand);
}
sessiongroup.deleteGroup();
sessiongroup.sync();
}
void PlasmaApp::registerClient(const QString &client)
{
kDebug() << "adding session manager client" << client;
org::kde::KApplication* clientinterface = new org::kde::KApplication(
client, "/MainApplication",
QDBusConnection::sessionBus(),
this
);
connect(
clientinterface, SIGNAL(sessionSaved()),
this, SLOT(clientSaved())
);
connect(
clientinterface, SIGNAL(sessionSaveCanceled()),
this, SLOT(clientSaveCanceled())
);
m_clients.insert(client, clientinterface);
}
void PlasmaApp::unregisterClient(const QString &client)
{
if (!m_clients.contains(client)) {
return;
}
kDebug() << "removing session manager client" << client;
org::kde::KApplication* clientinterface = m_clients.take(client);
delete clientinterface;
}
void PlasmaApp::clientSaved()
{
kDebug() << "client saved its session";
m_waitingcount++;
if (m_waitingcount >= m_clients.size()) {
kDebug() << "saving session";
KConfigGroup sessiongroup(KGlobal::config(), "Session");
int clientcounter = 0;
QMapIterator<QString,org::kde::KApplication*> iter(m_clients);
while (iter.hasNext()) {
iter.next();
kDebug() << "getting restart command for" << iter.key();
org::kde::KApplication* clientinterface = iter.value();
const QStringList restartcommand = clientinterface->restartCommand();
if (restartcommand.isEmpty()) {
kDebug() << "not saving client state due to empty command";
continue;
}
kDebug() << "saving client state" << iter.key();
KConfigGroup clientgroup(&sessiongroup, QString::number(clientcounter));
clientgroup.writeEntry("restartCommand", restartcommand);
clientgroup.sync();
clientcounter++;
}
sessiongroup.sync();
kDebug() << "saving session done";
doLogout();
}
}
void PlasmaApp::clientSaveCanceled()
{
kDebug() << "client canceled session save";
m_waitingcount++;
}
void PlasmaApp::suspendStartup(const QString &app) void PlasmaApp::suspendStartup(const QString &app)
{ {
// TODO: timeout for suspending // TODO: timeout for suspending
@ -970,9 +1096,10 @@ void PlasmaApp::resumeStartup(const QString &app)
void PlasmaApp::logout(int confirm, int sdtype) void PlasmaApp::logout(int confirm, int sdtype)
{ {
// TODO: prevent logout while initializing // TODO: prevent logout while initializing
kDebug() << "logout" << confirm << sdtype;
m_sdtype = static_cast<KWorkSpace::ShutdownType>(sdtype); m_sdtype = static_cast<KWorkSpace::ShutdownType>(sdtype);
if (confirm == KWorkSpace::ShutdownConfirmNo) { if (confirm == KWorkSpace::ShutdownConfirmNo) {
QTimer::singleShot(500, this, SLOT(doLogout())); QTimer::singleShot(s_sessiondelay, this, SLOT(saveClients()));
return; return;
} }
if (m_dialogActive) { if (m_dialogActive) {
@ -984,7 +1111,7 @@ void PlasmaApp::logout(int confirm, int sdtype)
const bool choose = (m_sdtype == KWorkSpace::ShutdownTypeDefault); const bool choose = (m_sdtype == KWorkSpace::ShutdownTypeDefault);
const bool logoutConfirmed = KSMShutdownDlg::confirmShutdown(maysd, choose, m_sdtype); const bool logoutConfirmed = KSMShutdownDlg::confirmShutdown(maysd, choose, m_sdtype);
if (logoutConfirmed) { if (logoutConfirmed) {
QTimer::singleShot(500, this, SLOT(doLogout())); QTimer::singleShot(s_sessiondelay, this, SLOT(saveClients()));
} }
m_dialogActive = false; m_dialogActive = false;
} }
@ -996,28 +1123,36 @@ void PlasmaApp::wmChanged()
void PlasmaApp::captureDesktop() void PlasmaApp::captureDesktop()
{ {
KToolInvocation::kdeinitExec("ksnapshot", QStringList() << "--fullscreen"); KToolInvocation::self()->kdeinitExec("ksnapshot", QStringList() << "--fullscreen");
} }
void PlasmaApp::captureCurrentWindow() void PlasmaApp::captureCurrentWindow()
{ {
KToolInvocation::kdeinitExec("ksnapshot", QStringList() << "--current"); KToolInvocation::self()->kdeinitExec("ksnapshot", QStringList() << "--current");
} }
void PlasmaApp::cleanup() void PlasmaApp::cleanup()
{ {
if (m_klauncher) { if (m_klauncher) {
m_klauncher->call("cleanup"); QDBusPendingReply<void> reply = m_klauncher->asyncCall("cleanup");
m_klauncher->deleteLater(); kDebug() << "Waiting for klauncher cleanup to finish";
while (!reply.isFinished()) {
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}
delete m_klauncher;
m_klauncher = nullptr; m_klauncher = nullptr;
} }
if (m_wmproc) { if (m_wmproc) {
m_wmproc->kill(); m_wmproc->kill();
m_wmproc->waitForFinished(); m_wmproc->waitForFinished();
m_wmproc->deleteLater(); delete m_wmproc;
m_wmproc = nullptr; m_wmproc = nullptr;
} }
foreach (const QString &client, m_clients.keys()) {
unregisterClient(client);
}
} }
void PlasmaApp::nextPhase() void PlasmaApp::nextPhase()
@ -1031,23 +1166,30 @@ void PlasmaApp::nextPhase()
if (!sessionInterface->isServiceRegistered(kdedInterface)) { if (!sessionInterface->isServiceRegistered(kdedInterface)) {
sessionInterface->startService(kdedInterface); sessionInterface->startService(kdedInterface);
} }
m_klauncher->call("autoStart", int(0)); m_klauncher->asyncCall("autoStart", int(0));
m_kcminit->call("runPhase1"); m_kcminit->asyncCall("runPhase1");
QTimer::singleShot(s_phasedelay, this, SLOT(nextPhase()));
break; break;
} }
case 1: { case 1: {
m_klauncher->call("autoStart", int(1)); m_klauncher->asyncCall("autoStart", int(1));
m_kcminit->call("runPhase2"); m_kcminit->asyncCall("runPhase2");
QTimer::singleShot(s_phasedelay, this, SLOT(nextPhase()));
break; break;
} }
case 2: { case 2: {
m_klauncher->call("autoStart", int(2)); m_klauncher->asyncCall("autoStart", int(2));
if (m_sessionManager) {
restoreClients();
}
kDebug() << "startup done";
return; return;
} }
} }
m_phase++; m_phase++;
} } else {
QTimer::singleShot(100, this, SLOT(nextPhase())); QTimer::singleShot(100, this, SLOT(nextPhase()));
}
} }
void PlasmaApp::defaultLogout() void PlasmaApp::defaultLogout()

View file

@ -38,6 +38,7 @@
#include "desktoptracker.h" #include "desktoptracker.h"
#include "kworkspace/kworkspace.h" #include "kworkspace/kworkspace.h"
#include "kapplication_interface.h"
namespace Plasma namespace Plasma
{ {
@ -98,6 +99,10 @@ public Q_SLOTS:
QString supportInformation() const; QString supportInformation() const;
void saveClients();
void restoreClients();
void registerClient(const QString &client);
void unregisterClient(const QString &client);
void suspendStartup(const QString &app); void suspendStartup(const QString &app);
void resumeStartup(const QString &app); void resumeStartup(const QString &app);
void logout(int confirm, int sdtype); void logout(int confirm, int sdtype);
@ -138,6 +143,9 @@ private Q_SLOTS:
void haltWithoutConfirmation(); void haltWithoutConfirmation();
void rebootWithoutConfirmation(); void rebootWithoutConfirmation();
void doLogout(); void doLogout();
private Q_SLOTS:
void clientSaved();
void clientSaveCanceled();
private: private:
DesktopCorona *m_corona; DesktopCorona *m_corona;
@ -161,6 +169,9 @@ private:
int m_startupsuspend; int m_startupsuspend;
bool m_dialogActive; bool m_dialogActive;
KWorkSpace::ShutdownType m_sdtype; KWorkSpace::ShutdownType m_sdtype;
bool m_sessionManager;
int m_waitingcount;
QMap<QString,org::kde::KApplication*> m_clients;
}; };
#endif // multiple inclusion guard #endif // multiple inclusion guard

View file

@ -111,7 +111,7 @@ static void kExecuteAction(const KServiceAction &kserviceaction, const Solid::De
return; return;
} }
const QString actionexe = actioncommand.takeFirst(); const QString actionexe = actioncommand.takeFirst();
const int actionresult = KToolInvocation::kdeinitExec(actionexe, actioncommand); const int actionresult = KToolInvocation::self()->kdeinitExec(actionexe, actioncommand);
if (actionresult != 0) { if (actionresult != 0) {
kWarning() << "could not execute action for" << kserviceaction.name() << actionresult; kWarning() << "could not execute action for" << kserviceaction.name() << actionresult;
} }

View file

@ -314,7 +314,7 @@ void ModuleView::moduleHelp()
} }
QString moduleService = activeModule->fileName().replace(QLatin1String(".desktop"), QString()); QString moduleService = activeModule->fileName().replace(QLatin1String(".desktop"), QString());
KToolInvocation::invokeHelp(QString(), moduleService); KToolInvocation::self()->invokeHelp(QString(), moduleService);
} }
void ModuleView::activeModuleChanged(KPageWidgetItem * current, KPageWidgetItem * previous) void ModuleView::activeModuleChanged(KPageWidgetItem * current, KPageWidgetItem * previous)