From fb686dc3c1682ef2a919f413eb83106cd198e318 Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Tue, 7 May 2024 10:46:00 +0300 Subject: [PATCH] plasma: implement session manager comes along with plenty of other changes Signed-off-by: Ivailo Monev --- dolphin/src/dolphinmainwindow.cpp | 2 +- dolphin/src/main.cpp | 1 + kate/addons/kate/mailfiles/katemailfiles.cpp | 13 +- .../plasma/session/katesessionapplet.cpp | 2 +- kate/part/variableeditor/katehelpbutton.cpp | 2 +- kate/part/view/kateviewhelpers.cpp | 5 +- kate/src/app/katemain.cpp | 3 +- kate/src/app/katemainwindow.cpp | 2 +- kcontrol/access/kcmaccess.cpp | 4 +- kcontrol/input/main.cpp | 4 +- kcontrol/input/mouse.cpp | 2 +- kcontrol/input/xcursor/themepage.cpp | 2 +- kcontrol/krdb/main.cpp | 2 +- kcontrol/randr/module/randrmonitor.cpp | 4 +- kcrash/kded/kded_kcrash.cpp | 6 +- kdontchangethehostname/khostname.cpp | 2 +- kinfocenter/infocenter.cpp | 2 +- knetattach/knetattach.cpp | 2 +- konsole/src/SessionController.cpp | 2 +- konsole/src/main.cpp | 1 + kstart/kstart.cpp | 2 +- ksysguard/gui/HostConnector.cpp | 2 +- kwin/main.cpp | 15 +- kwin/main.h | 5 +- kwin/rules.cpp | 2 +- kwin/sm.cpp | 246 +----------------- kwin/sm.h | 36 --- kwin/useractions.cpp | 2 +- kwin/workspace.h | 25 +- libs/konq/konq_operations.cpp | 2 +- plasma/applets/launcher/launcher.cpp | 2 +- plasma/runners/bookmarks/bookmarksrunner.cpp | 2 +- plasma/runners/shell/shellrunner.cpp | 2 +- plasma/runners/solid/solidrunner.cpp | 2 +- .../webshortcuts/webshortcutrunner.cpp | 2 +- plasma/shells/plasma-desktop/CMakeLists.txt | 3 + .../dbus/org.kde.plasma.App.xml | 23 +- plasma/shells/plasma-desktop/main.cpp | 4 +- plasma/shells/plasma-desktop/plasmaapp.cpp | 186 +++++++++++-- plasma/shells/plasma-desktop/plasmaapp.h | 11 + soliduiserver/soliduiserver_common.h | 2 +- systemsettings/core/ModuleView.cpp | 2 +- 42 files changed, 281 insertions(+), 360 deletions(-) diff --git a/dolphin/src/dolphinmainwindow.cpp b/dolphin/src/dolphinmainwindow.cpp index db2acdd3..cbb3d6a1 100644 --- a/dolphin/src/dolphinmainwindow.cpp +++ b/dolphin/src/dolphinmainwindow.cpp @@ -836,7 +836,7 @@ void DolphinMainWindow::openTerminal() dir = url.toLocalFile(); } - KToolInvocation::invokeTerminal(QString(), dir); + KToolInvocation::self()->invokeTerminal(QString(), dir); } void DolphinMainWindow::editSettings() diff --git a/dolphin/src/main.cpp b/dolphin/src/main.cpp index cd4e7284..5fbb9c07 100644 --- a/dolphin/src/main.cpp +++ b/dolphin/src/main.cpp @@ -86,6 +86,7 @@ int main(int argc, char **argv) { DolphinApplication app; + app.enableSessionManagement(); if (app.isSessionRestored()) { app.restoreSession(); } diff --git a/kate/addons/kate/mailfiles/katemailfiles.cpp b/kate/addons/kate/mailfiles/katemailfiles.cpp index 6e699e4d..7edd3231 100644 --- a/kate/addons/kate/mailfiles/katemailfiles.cpp +++ b/kate/addons/kate/mailfiles/katemailfiles.cpp @@ -135,12 +135,13 @@ void KateMailFilesPluginView::slotMail() } // check selected docs done if ( ! urls.count() ) return; - KToolInvocation::invokeMailer( QString(), // to - QString(), // cc - QString(), // subject - QString(), // body - urls // urls to atthatch - ); + KToolInvocation::self()->invokeMailer( + QString(), // to + QString(), // cc + QString(), // subject + QString(), // body + urls // urls to atthatch + ); } // kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/kate/addons/plasma/session/katesessionapplet.cpp b/kate/addons/plasma/session/katesessionapplet.cpp index 17dcab82..cbfcbddf 100644 --- a/kate/addons/plasma/session/katesessionapplet.cpp +++ b/kate/addons/plasma/session/katesessionapplet.cpp @@ -202,7 +202,7 @@ void KateSessionApplet::slotOnItemClicked(const QModelIndex &index) else if ( id > 2 ) args <<"-n"<< "--start"<kdeinitExec("kate", args); } void KateSessionApplet::createConfigurationInterface(KConfigDialog *parent) diff --git a/kate/part/variableeditor/katehelpbutton.cpp b/kate/part/variableeditor/katehelpbutton.cpp index d61d4b4a..512a0441 100644 --- a/kate/part/variableeditor/katehelpbutton.cpp +++ b/kate/part/variableeditor/katehelpbutton.cpp @@ -53,7 +53,7 @@ void KateHelpButton::setIconState(IconState state) void KateHelpButton::invokeHelp() { - KToolInvocation::invokeHelp(m_section, "kate"); + KToolInvocation::self()->invokeHelp(m_section, "kate"); } void KateHelpButton::setSection(const QString& section) diff --git a/kate/part/view/kateviewhelpers.cpp b/kate/part/view/kateviewhelpers.cpp index 4cd908f8..9717a25c 100644 --- a/kate/part/view/kateviewhelpers.cpp +++ b/kate/part/view/kateviewhelpers.cpp @@ -805,8 +805,9 @@ KateCommandLineBar::KateCommandLineBar (KateView *view, QWidget *parent) setFocusProxy (m_lineEdit); } -void KateCommandLineBar::showHelpPage() { - KToolInvocation::invokeHelp("advanced-editing-tools-commandline","kate"); +void KateCommandLineBar::showHelpPage() +{ + KToolInvocation::self()->invokeHelp("advanced-editing-tools-commandline","kate"); } KateCommandLineBar::~KateCommandLineBar() diff --git a/kate/src/app/katemain.cpp b/kate/src/app/katemain.cpp index acda9ea0..ab81b23e 100644 --- a/kate/src/app/katemain.cpp +++ b/kate/src/app/katemain.cpp @@ -365,7 +365,7 @@ int main( int argc, char **argv ) } #ifdef Q_WS_X11 - // make the world happy, we are started, kind of... + // make the world happy, it are started, kind of... KStartupInfo::appStarted (); #endif @@ -377,6 +377,7 @@ int main( int argc, char **argv ) KateApp app (args); if (app.shouldExit()) return 0; + app.enableSessionManagement(); // execute ourself ;) return app.exec(); } diff --git a/kate/src/app/katemainwindow.cpp b/kate/src/app/katemainwindow.cpp index 8a93c767..c5a35ab6 100644 --- a/kate/src/app/katemainwindow.cpp +++ b/kate/src/app/katemainwindow.cpp @@ -825,7 +825,7 @@ void KateMainWindow::slotOpenWithMenuAction(QAction* a) void KateMainWindow::pluginHelp() { - KToolInvocation::invokeHelp (QString(), "kate-plugins"); + KToolInvocation::self()->invokeHelp (QString(), "kate-plugins"); } void KateMainWindow::aboutEditor() diff --git a/kcontrol/access/kcmaccess.cpp b/kcontrol/access/kcmaccess.cpp index 91fa631d..4e506a6a 100644 --- a/kcontrol/access/kcmaccess.cpp +++ b/kcontrol/access/kcmaccess.cpp @@ -672,7 +672,7 @@ void KAccessConfig::save() // make kaccess reread the configuration // 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 - KToolInvocation::startServiceByDesktopName("kaccess"); + KToolInvocation::self()->startServiceByDesktopName("kaccess"); emit changed(false); } @@ -774,7 +774,7 @@ extern "C" Q_DECL_EXPORT void kcminit_access() { KConfig config("kaccessrc", KConfig::NoGlobals); - KToolInvocation::startServiceByDesktopName("kaccess"); + KToolInvocation::self()->startServiceByDesktopName("kaccess"); } } diff --git a/kcontrol/input/main.cpp b/kcontrol/input/main.cpp index 42f01dfb..4f71b741 100644 --- a/kcontrol/input/main.cpp +++ b/kcontrol/input/main.cpp @@ -68,9 +68,9 @@ extern "C" // Tell klauncher to set the XCURSOR_THEME and XCURSOR_SIZE environment // variables when launching applications. - KToolInvocation::setLaunchEnv("XCURSOR_THEME", theme); + KToolInvocation::self()->setLaunchEnv("XCURSOR_THEME", theme); if (!size.isEmpty()) { - KToolInvocation::setLaunchEnv("XCURSOR_SIZE", size); + KToolInvocation::self()->setLaunchEnv("XCURSOR_SIZE", size); } #endif delete config; diff --git a/kcontrol/input/mouse.cpp b/kcontrol/input/mouse.cpp index f343f043..3c244712 100644 --- a/kcontrol/input/mouse.cpp +++ b/kcontrol/input/mouse.cpp @@ -557,7 +557,7 @@ void MouseConfig::save() group.writeEntry("MKCurve", mk_curve->value()); // restart kaccess - KToolInvocation::startServiceByDesktopName("kaccess"); + KToolInvocation::self()->startServiceByDesktopName("kaccess"); emit changed(false); } diff --git a/kcontrol/input/xcursor/themepage.cpp b/kcontrol/input/xcursor/themepage.cpp index 75d94366..757b4dc6 100644 --- a/kcontrol/input/xcursor/themepage.cpp +++ b/kcontrol/input/xcursor/themepage.cpp @@ -256,7 +256,7 @@ bool ThemePage::applyTheme(const CursorTheme *theme, const int size) } // 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 runRdb(); diff --git a/kcontrol/krdb/main.cpp b/kcontrol/krdb/main.cpp index 2f4ef4c6..ed9799dd 100644 --- a/kcontrol/krdb/main.cpp +++ b/kcontrol/krdb/main.cpp @@ -92,7 +92,7 @@ static void applyGtkStyles(bool active, int version) // Pass env. var to klauncher. QString name = gtkEnvVar(version); QString value = list.join(":"); - KToolInvocation::setLaunchEnv(name, value); + KToolInvocation::self()->setLaunchEnv(name, value); } // ----------------------------------------------------------------------------- diff --git a/kcontrol/randr/module/randrmonitor.cpp b/kcontrol/randr/module/randrmonitor.cpp index 349666f2..3e98256c 100644 --- a/kcontrol/randr/module/randrmonitor.cpp +++ b/kcontrol/randr/module/randrmonitor.cpp @@ -162,7 +162,7 @@ void RandrMonitorModule::processX11Event( XEvent* e ) void RandrMonitorModule::showKcm() { - KToolInvocation::kdeinitExec("kcmshell4", QStringList() << "randr"); + KToolInvocation::self()->kdeinitExec("kcmshell4", QStringList() << "randr"); } void RandrMonitorModule::tryAutoConfig() @@ -244,7 +244,7 @@ void RandrMonitorModule::switchDisplay() return; } // no idea what to do here - KToolInvocation::kdeinitExec( "kcmshell4", QStringList() << "randr" ); + KToolInvocation::self()->kdeinitExec( "kcmshell4", QStringList() << "randr" ); } void RandrMonitorModule::resumedFromSuspend() diff --git a/kcrash/kded/kded_kcrash.cpp b/kcrash/kded/kded_kcrash.cpp index 0fe65c0c..294315ee 100644 --- a/kcrash/kded/kded_kcrash.cpp +++ b/kcrash/kded/kded_kcrash.cpp @@ -176,7 +176,7 @@ void KCrashModule::slotDirty(const QString &path) kcrashargs.append(kcrashdisplay); } 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(); knotification->close(); if (kcrashreporturl.startsWith(QLatin1String("mailto:"))) { - KToolInvocation::invokeMailer(kcrashreporturl, QString::fromLatin1("Crash report")); + KToolInvocation::self()->invokeMailer(kcrashreporturl, QString::fromLatin1("Crash report")); } else { - KToolInvocation::invokeBrowser(kcrashreporturl); + KToolInvocation::self()->invokeBrowser(kcrashreporturl); } } diff --git a/kdontchangethehostname/khostname.cpp b/kdontchangethehostname/khostname.cpp index 84f3257e..04d32402 100644 --- a/kdontchangethehostname/khostname.cpp +++ b/kdontchangethehostname/khostname.cpp @@ -167,7 +167,7 @@ void KHostName::changeSessionManager() return; } 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) diff --git a/kinfocenter/infocenter.cpp b/kinfocenter/infocenter.cpp index 13c7e2fd..68dcd8bc 100644 --- a/kinfocenter/infocenter.cpp +++ b/kinfocenter/infocenter.cpp @@ -233,7 +233,7 @@ void KInfoCenter::resetCondition() void KInfoCenter::helpClickedSlot() { - KToolInvocation::invokeHelp(QString(), m_contain->serviceName()); + KToolInvocation::self()->invokeHelp(QString(), m_contain->serviceName()); } void KInfoCenter::exportClickedSlot() diff --git a/knetattach/knetattach.cpp b/knetattach/knetattach.cpp index 0974e2da..f9d3958c 100644 --- a/knetattach/knetattach.cpp +++ b/knetattach/knetattach.cpp @@ -84,7 +84,7 @@ void KNetAttach::slotPageChanged(int) void KNetAttach::slotHelpClicked() { - KToolInvocation::invokeHelp(QString(), "knetattach"); + KToolInvocation::self()->invokeHelp(QString(), "knetattach"); } void KNetAttach::setInformationText(const QString &type) diff --git a/konsole/src/SessionController.cpp b/konsole/src/SessionController.cpp index c6298f9d..458de8cc 100644 --- a/konsole/src/SessionController.cpp +++ b/konsole/src/SessionController.cpp @@ -495,7 +495,7 @@ void SessionController::handleOpenWithAction() void SessionController::configureWebShortcuts() { - KToolInvocation::kdeinitExec("kcmshell4", QStringList() << "ebrowsing"); + KToolInvocation::self()->kdeinitExec("kcmshell4", QStringList() << "ebrowsing"); } void SessionController::sendSignal(QAction* action) diff --git a/konsole/src/main.cpp b/konsole/src/main.cpp index 9a9dd006..e77d5212 100644 --- a/konsole/src/main.cpp +++ b/konsole/src/main.cpp @@ -71,6 +71,7 @@ int main(int argc, char** argv) // create a new application instance Application app; + app.enableSessionManagement(); // make sure the d&d popup menu provided by libkonq get translated. KGlobal::locale()->insertCatalog("libkonq"); diff --git a/kstart/kstart.cpp b/kstart/kstart.cpp index 89acf74d..e5fa4dec 100644 --- a/kstart/kstart.cpp +++ b/kstart/kstart.cpp @@ -98,7 +98,7 @@ KStart::KStart() } } else { QString error; - if (KToolInvocation::startServiceByDesktopPath(exe, url, &error) != 0) { + if (KToolInvocation::self()->startServiceByDesktopPath(exe, url, &error) != 0) { kError() << error; } } diff --git a/ksysguard/gui/HostConnector.cpp b/ksysguard/gui/HostConnector.cpp index 69380abb..1f993236 100644 --- a/ksysguard/gui/HostConnector.cpp +++ b/ksysguard/gui/HostConnector.cpp @@ -224,7 +224,7 @@ bool HostConnector::useCustom() const void HostConnector::slotHelp() { - KToolInvocation::invokeHelp( "connectingtootherhosts", "ksysguard" ); + KToolInvocation::self()->invokeHelp( "connectingtootherhosts", "ksysguard" ); } #include "moc_HostConnector.cpp" diff --git a/kwin/main.cpp b/kwin/main.cpp index 497b1a6e..1b350de1 100644 --- a/kwin/main.cpp +++ b/kwin/main.cpp @@ -57,7 +57,6 @@ along with this program. If not, see . #include "atoms.h" #include "options.h" -#include "sm.h" #include "utils.h" #include "effects.h" #include "workspace.h" @@ -275,6 +274,17 @@ bool Application::setup() 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() { KCrash::setFlags(0); // too late to restart now @@ -335,6 +345,7 @@ int main(int argc, char * argv[]) KCmdLineArgs::addCmdLineOptions(args); KWin::Application a; + a.enableSessionManagement(); QDBusInterface plasma("org.kde.plasma-desktop", "/App", "local.PlasmaApp", QDBusConnection::sessionBus()); if (plasma.isValid()) { plasma.call("suspendStartup", "kwin"); @@ -361,8 +372,6 @@ int main(int argc, char * argv[]) if (plasma.isValid()) { plasma.call("resumeStartup", "kwin"); } - KWin::SessionManager weAreIndeed; - KWin::SessionSaveDoneHelper helper; KGlobal::locale()->insertCatalog("kwin_effects"); fcntl(XConnectionNumber(KWin::display()), F_SETFD, 1); diff --git a/kwin/main.h b/kwin/main.h index 4a18dedc..02449fdd 100644 --- a/kwin/main.h +++ b/kwin/main.h @@ -42,7 +42,10 @@ protected: bool x11EventFilter(XEvent*); bool notify(QObject* o, QEvent* e); -private slots: +private Q_SLOTS: + bool saveSession() final; + +private Q_SLOTS: void lostSelection(); private: diff --git a/kwin/rules.cpp b/kwin/rules.cpp index d651d5b7..da776abc 100644 --- a/kwin/rules.cpp +++ b/kwin/rules.cpp @@ -968,7 +968,7 @@ void RuleBook::edit(Client* c, bool whole_app) args << "--wid" << QString::number(c->window()); if (whole_app) args << "--whole-app"; - KToolInvocation::kdeinitExec("kwin_rules_dialog", args); + KToolInvocation::self()->kdeinitExec("kwin_rules_dialog", args); } void RuleBook::load() diff --git a/kwin/sm.cpp b/kwin/sm.cpp index 7a1d0553..ad423c63 100644 --- a/kwin/sm.cpp +++ b/kwin/sm.cpp @@ -31,44 +31,11 @@ along with this program. If not, see . #include "workspace.h" #include "client.h" #include -#include #include 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 /*! @@ -76,7 +43,7 @@ bool SessionManager::commitData(QSessionManager& sm) \sa loadSessionInfo() */ -void Workspace::storeSession(KConfig* config, SMSavePhase phase) +void Workspace::storeSession(KConfig* config) { KConfigGroup cg(config, "Session"); int count = 0; @@ -92,24 +59,11 @@ void Workspace::storeSession(KConfig* config, SMSavePhase phase) count++; if (c->isActive()) active_client = count; - if (phase == SMSavePhase2 || phase == SMSavePhase2Full) - 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("active", session_active_client); - cg.writeEntry("desktop", VirtualDesktopManager::self()->current()); + storeClient(cg, count, c); } + cg.writeEntry("count", count); + cg.writeEntry("active", session_active_client); + cg.writeEntry("desktop", VirtualDesktopManager::self()->current()); } 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(reinterpret_cast(c->tabGroup()))); } -void Workspace::storeSubSession(const QString &name, QSet 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. @@ -185,16 +113,11 @@ void Workspace::loadSessionInfo() session.clear(); KConfigGroup cg(kapp->sessionConfig(), "Session"); - addSessionInfo(cg); -} - -void Workspace::addSessionInfo(KConfigGroup &cg) -{ int count = cg.readEntry("count", 0); int active_client = cg.readEntry("active", 0); for (int i = 1; i <= count; i++) { QString n = QString::number(i); - SessionInfo* info = new SessionInfo; + SessionInfo* info = new SessionInfo(); session.append(info); info->sessionId = cg.readEntry(QString("sessionId") + 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 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 } - - - -// 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 #include "moc_sm.cpp" diff --git a/kwin/sm.h b/kwin/sm.h index f6399f92..6fdfc38e 100644 --- a/kwin/sm.h +++ b/kwin/sm.h @@ -24,7 +24,6 @@ along with this program. If not, see . #include #include -#include #include #include @@ -71,41 +70,6 @@ struct SessionInfo { 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 #endif diff --git a/kwin/useractions.cpp b/kwin/useractions.cpp index deaf6dcb..60636eba 100755 --- a/kwin/useractions.cpp +++ b/kwin/useractions.cpp @@ -223,7 +223,7 @@ void UserActionsMenu::configureWM() { QStringList args; args << "--icon" << "preferences-system-windows" << configModules(); - KToolInvocation::kdeinitExec("kcmshell4", args); + KToolInvocation::self()->kdeinitExec("kcmshell4", args); } void UserActionsMenu::init() diff --git a/kwin/workspace.h b/kwin/workspace.h index a3f6a702..e8388800 100644 --- a/kwin/workspace.h +++ b/kwin/workspace.h @@ -26,6 +26,7 @@ along with this program. If not, see . // kwin #include #include "sm.h" +#include "client.h" #include "utils.h" // Katie #include @@ -225,10 +226,8 @@ public: 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 storeSubSession(const QString &name, QSet sessionIds); - void loadSubSessionInfo(const QString &name); SessionInfo* takeSessionInfo(Client*); @@ -453,7 +452,6 @@ private: Client* active_popup_client; void loadSessionInfo(); - void addSessionInfo(KConfigGroup &cg); QList session; static const char* windowTypeToTxt(NET::WindowType type); @@ -610,6 +608,20 @@ inline const ToplevelList& Workspace::stackingOrder() const 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() { was_user_interaction = true; @@ -620,11 +632,6 @@ inline bool Workspace::wasUserInteraction() const return was_user_interaction; } -inline void Workspace::sessionSaveStarted() -{ - session_saving = true; -} - inline bool Workspace::sessionSaving() const { return session_saving; diff --git a/libs/konq/konq_operations.cpp b/libs/konq/konq_operations.cpp index 999aae21..5980d503 100644 --- a/libs/konq/konq_operations.cpp +++ b/libs/konq/konq_operations.cpp @@ -383,7 +383,7 @@ void KonqOperations::asyncDrop( const KFileItem & destItem ) { QString error; 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 ); } else diff --git a/plasma/applets/launcher/launcher.cpp b/plasma/applets/launcher/launcher.cpp index a33dd952..f7557fa8 100644 --- a/plasma/applets/launcher/launcher.cpp +++ b/plasma/applets/launcher/launcher.cpp @@ -1806,7 +1806,7 @@ KBookmarkManager* LauncherApplet::bookmarkManager() const void LauncherApplet::slotEditMenu() { - if (KToolInvocation::kdeinitExec("kmenuedit") == 0) { + if (KToolInvocation::self()->kdeinitExec("kmenuedit") == 0) { hidePopup(); } else { showMessage(KIcon("dialog-error"), i18n("Failed to launch menu editor"), Plasma::MessageButton::ButtonOk); diff --git a/plasma/runners/bookmarks/bookmarksrunner.cpp b/plasma/runners/bookmarks/bookmarksrunner.cpp index a154d4b6..55df36af 100644 --- a/plasma/runners/bookmarks/bookmarksrunner.cpp +++ b/plasma/runners/bookmarks/bookmarksrunner.cpp @@ -108,7 +108,7 @@ void BookmarksRunner::run(const Plasma::QueryMatch &action) const QString term = action.data().toString(); // transforms URLs like "kde.org" to "http://kde.org" const KUrl url = KUrl::fromUserInput(term); - KToolInvocation::invokeBrowser(url.url()); + KToolInvocation::self()->invokeBrowser(url.url()); } QMimeData* BookmarksRunner::mimeDataForMatch(const Plasma::QueryMatch &match) diff --git a/plasma/runners/shell/shellrunner.cpp b/plasma/runners/shell/shellrunner.cpp index d86700cf..34f26743 100644 --- a/plasma/runners/shell/shellrunner.cpp +++ b/plasma/runners/shell/shellrunner.cpp @@ -64,7 +64,7 @@ void ShellRunner::run(const Plasma::QueryMatch &match) } const QString command = match.data().toString(); if (interminal) { - KToolInvocation::invokeTerminal(command); + KToolInvocation::self()->invokeTerminal(command); } else { KRun::runCommand(command, nullptr); } diff --git a/plasma/runners/solid/solidrunner.cpp b/plasma/runners/solid/solidrunner.cpp index 0f55f613..b361878a 100644 --- a/plasma/runners/solid/solidrunner.cpp +++ b/plasma/runners/solid/solidrunner.cpp @@ -233,7 +233,7 @@ void SolidRunner::run(const Plasma::QueryMatch &match) return; } const QString actionexe = actioncommand.takeFirst(); - const int actionresult = KToolInvocation::kdeinitExec(actionexe, actioncommand); + const int actionresult = KToolInvocation::self()->kdeinitExec(actionexe, actioncommand); if (actionresult != 0) { kWarning() << "could not execute action for" << actionname << "in" << actionfilepath << actionresult; } diff --git a/plasma/runners/webshortcuts/webshortcutrunner.cpp b/plasma/runners/webshortcuts/webshortcutrunner.cpp index 13c05261..3e3cf62e 100644 --- a/plasma/runners/webshortcuts/webshortcutrunner.cpp +++ b/plasma/runners/webshortcuts/webshortcutrunner.cpp @@ -106,7 +106,7 @@ void WebshortcutRunner::run(const Plasma::QueryMatch &match) // kDebug() << location; if (!location.isEmpty()) { - KToolInvocation::invokeBrowser(location); + KToolInvocation::self()->invokeBrowser(location); } } diff --git a/plasma/shells/plasma-desktop/CMakeLists.txt b/plasma/shells/plasma-desktop/CMakeLists.txt index 93906d84..913d3df2 100644 --- a/plasma/shells/plasma-desktop/CMakeLists.txt +++ b/plasma/shells/plasma-desktop/CMakeLists.txt @@ -21,6 +21,9 @@ set(plasma_SRCS set(plasmaapp_dbusXML dbus/org.kde.plasma.App.xml) 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}) target_link_libraries(plasma-desktop diff --git a/plasma/shells/plasma-desktop/dbus/org.kde.plasma.App.xml b/plasma/shells/plasma-desktop/dbus/org.kde.plasma.App.xml index c9279865..44defa35 100644 --- a/plasma/shells/plasma-desktop/dbus/org.kde.plasma.App.xml +++ b/plasma/shells/plasma-desktop/dbus/org.kde.plasma.App.xml @@ -1,8 +1,6 @@ - - @@ -10,16 +8,27 @@ + + + + + + + + + + - + - + - - + + + + - diff --git a/plasma/shells/plasma-desktop/main.cpp b/plasma/shells/plasma-desktop/main.cpp index 5f6ded97..c9951b09 100644 --- a/plasma/shells/plasma-desktop/main.cpp +++ b/plasma/shells/plasma-desktop/main.cpp @@ -44,11 +44,13 @@ int main(int argc, char **argv) ki18n("In memory of his contributions, 1937-1998."), 0, "http://en.wikipedia.org/wiki/John_Lions"); + // plasma-desktop is the session manager + ::unsetenv("SESSION_MANAGER"); + KCmdLineArgs::init(argc, argv, &aboutData); PlasmaApp *app = PlasmaApp::self(); QApplication::setWindowIcon(KIcon("plasma")); - app->disableSessionManagement(); // autostarted int rc = app->exec(); delete app; diff --git a/plasma/shells/plasma-desktop/plasmaapp.cpp b/plasma/shells/plasma-desktop/plasmaapp.cpp index 4694d27d..81a89464 100644 --- a/plasma/shells/plasma-desktop/plasmaapp.cpp +++ b/plasma/shells/plasma-desktop/plasmaapp.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -69,6 +70,8 @@ #include #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 QStringList s_defaultwmcommands = QStringList() << s_defaultwm; @@ -114,7 +117,9 @@ PlasmaApp::PlasmaApp() m_wmproc(nullptr), m_startupsuspend(0), 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__ << ")"; @@ -174,10 +179,7 @@ PlasmaApp::PlasmaApp() QLatin1String("org.kde.KLauncher"), QDBusConnection::sessionBus(), this - ); - // TODO: m_klauncher->call("setLaunchEnv", "SESSION_MANAGER", "TODO"); - - + ); m_kcminit = new QDBusInterface( QLatin1String("org.kde.kcminit"), QLatin1String("/kcminit"), @@ -185,11 +187,15 @@ PlasmaApp::PlasmaApp() QDBusConnection::sessionBus(), this ); + const bool failsafe = (qgetenv("KDE_FAILSAFE").toInt() == 1); + if (!failsafe) { + m_sessionManager = true; + } KGlobal::dirs()->addResourceType("windowmanagers", "data", "plasma/windowmanagers"); QStringList wmcommands; - if (qgetenv("KDE_FAILSAFE").toInt() != 1) { + if (!failsafe) { KConfig cfg("plasmarc", KConfig::NoGlobals); KConfigGroup config(&cfg, "General"); const QString wmname = config.readEntry("windowManager", s_defaultwm); @@ -203,12 +209,28 @@ PlasmaApp::PlasmaApp() if (wmcommands.isEmpty()) { 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->start(wmprog, wmcommands); - m_wmproc->waitForStarted(4000); - QTimer::singleShot(100, this, SLOT(nextPhase())); + QTimer::singleShot(s_phasedelay, this, SLOT(nextPhase())); } PlasmaApp::~PlasmaApp() @@ -954,6 +976,110 @@ QString PlasmaApp::supportInformation() const 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 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 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) { // TODO: timeout for suspending @@ -970,9 +1096,10 @@ void PlasmaApp::resumeStartup(const QString &app) void PlasmaApp::logout(int confirm, int sdtype) { // TODO: prevent logout while initializing + kDebug() << "logout" << confirm << sdtype; m_sdtype = static_cast(sdtype); if (confirm == KWorkSpace::ShutdownConfirmNo) { - QTimer::singleShot(500, this, SLOT(doLogout())); + QTimer::singleShot(s_sessiondelay, this, SLOT(saveClients())); return; } if (m_dialogActive) { @@ -984,7 +1111,7 @@ void PlasmaApp::logout(int confirm, int sdtype) const bool choose = (m_sdtype == KWorkSpace::ShutdownTypeDefault); const bool logoutConfirmed = KSMShutdownDlg::confirmShutdown(maysd, choose, m_sdtype); if (logoutConfirmed) { - QTimer::singleShot(500, this, SLOT(doLogout())); + QTimer::singleShot(s_sessiondelay, this, SLOT(saveClients())); } m_dialogActive = false; } @@ -996,28 +1123,36 @@ void PlasmaApp::wmChanged() void PlasmaApp::captureDesktop() { - KToolInvocation::kdeinitExec("ksnapshot", QStringList() << "--fullscreen"); + KToolInvocation::self()->kdeinitExec("ksnapshot", QStringList() << "--fullscreen"); } void PlasmaApp::captureCurrentWindow() { - KToolInvocation::kdeinitExec("ksnapshot", QStringList() << "--current"); + KToolInvocation::self()->kdeinitExec("ksnapshot", QStringList() << "--current"); } void PlasmaApp::cleanup() { if (m_klauncher) { - m_klauncher->call("cleanup"); - m_klauncher->deleteLater(); + QDBusPendingReply reply = m_klauncher->asyncCall("cleanup"); + kDebug() << "Waiting for klauncher cleanup to finish"; + while (!reply.isFinished()) { + QCoreApplication::processEvents(QEventLoop::AllEvents, 100); + } + delete m_klauncher; m_klauncher = nullptr; } if (m_wmproc) { m_wmproc->kill(); m_wmproc->waitForFinished(); - m_wmproc->deleteLater(); + delete m_wmproc; m_wmproc = nullptr; } + + foreach (const QString &client, m_clients.keys()) { + unregisterClient(client); + } } void PlasmaApp::nextPhase() @@ -1031,23 +1166,30 @@ void PlasmaApp::nextPhase() if (!sessionInterface->isServiceRegistered(kdedInterface)) { sessionInterface->startService(kdedInterface); } - m_klauncher->call("autoStart", int(0)); - m_kcminit->call("runPhase1"); + m_klauncher->asyncCall("autoStart", int(0)); + m_kcminit->asyncCall("runPhase1"); + QTimer::singleShot(s_phasedelay, this, SLOT(nextPhase())); break; } case 1: { - m_klauncher->call("autoStart", int(1)); - m_kcminit->call("runPhase2"); + m_klauncher->asyncCall("autoStart", int(1)); + m_kcminit->asyncCall("runPhase2"); + QTimer::singleShot(s_phasedelay, this, SLOT(nextPhase())); break; } case 2: { - m_klauncher->call("autoStart", int(2)); + m_klauncher->asyncCall("autoStart", int(2)); + if (m_sessionManager) { + restoreClients(); + } + kDebug() << "startup done"; return; } } m_phase++; + } else { + QTimer::singleShot(100, this, SLOT(nextPhase())); } - QTimer::singleShot(100, this, SLOT(nextPhase())); } void PlasmaApp::defaultLogout() diff --git a/plasma/shells/plasma-desktop/plasmaapp.h b/plasma/shells/plasma-desktop/plasmaapp.h index 91865e81..f1b168bb 100644 --- a/plasma/shells/plasma-desktop/plasmaapp.h +++ b/plasma/shells/plasma-desktop/plasmaapp.h @@ -38,6 +38,7 @@ #include "desktoptracker.h" #include "kworkspace/kworkspace.h" +#include "kapplication_interface.h" namespace Plasma { @@ -98,6 +99,10 @@ public Q_SLOTS: QString supportInformation() const; + void saveClients(); + void restoreClients(); + void registerClient(const QString &client); + void unregisterClient(const QString &client); void suspendStartup(const QString &app); void resumeStartup(const QString &app); void logout(int confirm, int sdtype); @@ -138,6 +143,9 @@ private Q_SLOTS: void haltWithoutConfirmation(); void rebootWithoutConfirmation(); void doLogout(); +private Q_SLOTS: + void clientSaved(); + void clientSaveCanceled(); private: DesktopCorona *m_corona; @@ -161,6 +169,9 @@ private: int m_startupsuspend; bool m_dialogActive; KWorkSpace::ShutdownType m_sdtype; + bool m_sessionManager; + int m_waitingcount; + QMap m_clients; }; #endif // multiple inclusion guard diff --git a/soliduiserver/soliduiserver_common.h b/soliduiserver/soliduiserver_common.h index adf7fe7b..24182908 100644 --- a/soliduiserver/soliduiserver_common.h +++ b/soliduiserver/soliduiserver_common.h @@ -111,7 +111,7 @@ static void kExecuteAction(const KServiceAction &kserviceaction, const Solid::De return; } const QString actionexe = actioncommand.takeFirst(); - const int actionresult = KToolInvocation::kdeinitExec(actionexe, actioncommand); + const int actionresult = KToolInvocation::self()->kdeinitExec(actionexe, actioncommand); if (actionresult != 0) { kWarning() << "could not execute action for" << kserviceaction.name() << actionresult; } diff --git a/systemsettings/core/ModuleView.cpp b/systemsettings/core/ModuleView.cpp index 2a24ae16..96b9d4c5 100644 --- a/systemsettings/core/ModuleView.cpp +++ b/systemsettings/core/ModuleView.cpp @@ -314,7 +314,7 @@ void ModuleView::moduleHelp() } QString moduleService = activeModule->fileName().replace(QLatin1String(".desktop"), QString()); - KToolInvocation::invokeHelp(QString(), moduleService); + KToolInvocation::self()->invokeHelp(QString(), moduleService); } void ModuleView::activeModuleChanged(KPageWidgetItem * current, KPageWidgetItem * previous)