diff --git a/main.h b/main.h
--- a/main.h
+++ b/main.h
@@ -238,7 +238,6 @@
}
protected:
- QString m_originalSessionKey;
static int crashes;
private Q_SLOTS:
diff --git a/main.cpp b/main.cpp
--- a/main.cpp
+++ b/main.cpp
@@ -276,7 +276,7 @@
// critical startup section where x errors cause kwin to abort.
// create workspace.
- (void) new Workspace(m_originalSessionKey);
+ (void) new Workspace();
emit workspaceCreated();
}
diff --git a/main_x11.cpp b/main_x11.cpp
--- a/main_x11.cpp
+++ b/main_x11.cpp
@@ -216,11 +216,6 @@
Application::setX11ScreenNumber(QX11Info::appScreen());
}
- // QSessionManager for some reason triggers a very early commitDataRequest
- // and updates the key - before we create the workspace and load the session
- // data -> store and pass to the workspace constructor
- m_originalSessionKey = sessionKey();
-
owner.reset(new KWinSelectionOwner(Application::x11ScreenNumber()));
connect(owner.data(), &KSelectionOwner::failedToClaimOwnership, []{
fputs(i18n("kwin: unable to claim manager selection, another wm running? (try using --replace)\n").toLocal8Bit().constData(), stderr);
@@ -420,6 +415,8 @@
qunsetenv("QT_DEVICE_PIXEL_RATIO");
qunsetenv("QT_SCALE_FACTOR");
QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling);
+ // KSMServer talks to us directly on DBus.
+ QCoreApplication::setAttribute(Qt::AA_DisableSessionManager);
KWin::ApplicationX11 a(argc, argv);
a.setupTranslator();
diff --git a/org.kde.KWin.Session.xml b/org.kde.KWin.Session.xml
--- a/org.kde.KWin.Session.xml
+++ b/org.kde.KWin.Session.xml
@@ -10,6 +10,15 @@
-->
+
+
+
+
+
+
+
+
+
diff --git a/sm.h b/sm.h
--- a/sm.h
+++ b/sm.h
@@ -45,8 +45,15 @@
Q_SIGNALS:
void stateChanged();
+ void loadSessionRequested(const QString &name);
+ void prepareSessionSaveRequested(const QString &name);
+ void finishSessionSaveRequested(const QString &name);
+
public Q_SLOTS: // DBus API
void setState(uint state);
+ void loadSession(const QString &name);
+ void aboutToSaveSession(const QString &name);
+ void finishSaveSession(const QString &name);
private:
void setState(SessionState state);
diff --git a/sm.cpp b/sm.cpp
--- a/sm.cpp
+++ b/sm.cpp
@@ -81,46 +81,16 @@
return static_cast< NET::WindowType >(-2); // undefined
}
-void Workspace::saveState(QSessionManager &sm)
-{
- bool sessionManagerIsKSMServer = QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.ksmserver").value();
-
- // If the session manager is ksmserver, save stacking
- // order, active window, active desktop etc. in phase 1,
- // as ksmserver 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)
- KConfig *config = sessionConfig(sm.sessionId(), sm.sessionKey());
- if (!sm.isPhase2()) {
- KConfigGroup cg(config, "Session");
- cg.writeEntry("AllowsInteraction", sm.allowsInteraction());
- if (sessionManagerIsKSMServer) // save stacking order etc. before "save file?" etc. dialogs change it
- storeSession(config, SMSavePhase0);
- config->markAsClean(); // don't write Phase #1 data to disk
- sm.release(); // Qt doesn't automatically release in this case (bug?)
- sm.requestPhase2();
- return;
- }
- storeSession(config, sessionManagerIsKSMServer ? SMSavePhase2 : SMSavePhase2Full);
- config->sync();
-
- // inform the smserver on how to clean-up after us
- const QString localFilePath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QLatin1Char('/') + config->name();
- if (QFile::exists(localFilePath)) { // expectable for the sync
- sm.setDiscardCommand(QStringList() << QStringLiteral("rm") << localFilePath);
- }
-}
-
-// Workspace
-
/**
* Stores the current session in the config file
*
* @see loadSessionInfo
*/
-void Workspace::storeSession(KConfig* config, SMSavePhase phase)
+void Workspace::storeSession(const QString &sessionName, SMSavePhase phase)
{
+ qCDebug(KWIN_CORE) << "storing session" << sessionName << "in phase" << phase;
+ KConfig *config = sessionConfig(sessionName, QString());
+
KConfigGroup cg(config, "Session");
int count = 0;
int active_client = -1;
@@ -160,6 +130,7 @@
cg.writeEntry("active", session_active_client);
cg.writeEntry("desktop", VirtualDesktopManager::self()->current());
}
+ config->sync(); // it previously did some "revert to defaults" stuff for phase1 I think
}
void Workspace::storeClient(KConfigGroup &cg, int num, X11Client *c)
@@ -235,12 +206,10 @@
*
* @see storeSession
*/
-void Workspace::loadSessionInfo(const QString &key)
+void Workspace::loadSessionInfo(const QString &sessionName)
{
- // NOTICE: qApp->sessionKey() is outdated when this gets invoked
- // the key parameter is cached from the application constructor.
session.clear();
- KConfigGroup cg(sessionConfig(qApp->sessionId(), key), "Session");
+ KConfigGroup cg(sessionConfig(sessionName, QString()), "Session");
addSessionInfo(cg);
}
@@ -385,6 +354,7 @@
}
}
+// TODO should we rethink this now that we have dedicated start end end save methods?
void SessionManager::setState(SessionState state)
{
if (state == m_sessionState) {
@@ -405,5 +375,20 @@
emit stateChanged();
}
+void SessionManager::loadSession(const QString &name)
+{
+ emit loadSessionRequested(name);
+}
+
+void SessionManager::aboutToSaveSession(const QString &name)
+{
+ emit prepareSessionSaveRequested(name);
+}
+
+void SessionManager::finishSaveSession(const QString &name)
+{
+ emit finishSessionSaveRequested(name);
+}
+
} // namespace
diff --git a/workspace.h b/workspace.h
--- a/workspace.h
+++ b/workspace.h
@@ -69,7 +69,7 @@
{
Q_OBJECT
public:
- explicit Workspace(const QString &sessionKey = QString());
+ explicit Workspace();
~Workspace() override;
static Workspace* self() {
@@ -309,7 +309,7 @@
void updateOnAllDesktopsOfTransients(AbstractClient*);
void checkTransients(xcb_window_t w);
- void storeSession(KConfig* config, SMSavePhase phase);
+ void storeSession(const QString &sessionName, SMSavePhase phase);
void storeClient(KConfigGroup &cg, int num, X11Client *c);
void storeSubSession(const QString &name, QSet sessionIds);
void loadSubSessionInfo(const QString &name);
@@ -494,9 +494,6 @@
void slotDesktopCountChanged(uint previousCount, uint newCount);
void slotCurrentDesktopChanged(uint oldDesktop, uint newDesktop);
- // session management
- void saveState(QSessionManager &sm);
-
Q_SIGNALS:
/**
* Emitted after the Workspace has setup the complete initialization process.
@@ -581,7 +578,7 @@
AbstractClient* active_popup_client;
int m_initialDesktop;
- void loadSessionInfo(const QString &key);
+ void loadSessionInfo(const QString &sessionName);
void addSessionInfo(KConfigGroup &cg);
QList session;
diff --git a/workspace.cpp b/workspace.cpp
--- a/workspace.cpp
+++ b/workspace.cpp
@@ -102,7 +102,7 @@
Workspace* Workspace::_self = nullptr;
-Workspace::Workspace(const QString &sessionKey)
+Workspace::Workspace()
: QObject(nullptr)
, m_compositor(nullptr)
// Unsorted
@@ -153,10 +153,6 @@
delayFocusTimer = nullptr;
- if (!sessionKey.isEmpty())
- loadSessionInfo(sessionKey);
- connect(qApp, &QGuiApplication::saveStateRequest, this, &Workspace::saveState);
-
RuleBook::create(this)->load();
kwinApp()->createScreens();
@@ -187,6 +183,15 @@
decorationBridge->init();
connect(this, &Workspace::configChanged, decorationBridge, &Decoration::DecorationBridge::reconfigure);
+ connect(m_sessionManager, &SessionManager::loadSessionRequested, this, &Workspace::loadSessionInfo);
+
+ connect(m_sessionManager, &SessionManager::prepareSessionSaveRequested, this, [this](const QString &name) {
+ storeSession(name, SMSavePhase0);
+ });
+ connect(m_sessionManager, &SessionManager::finishSessionSaveRequested, this, [this](const QString &name) {
+ storeSession(name, SMSavePhase2);
+ });
+
new DBusInterface(this);
Outline::create(this);