Move session management to SessionManagement class

Right now Workspace and SessionManagement were entangled with
SessionManager being a dumb class that just signalled to Workspace to do
the work.

The code, however, lived in sm.cpp despite being part of workspace.

This commit is an initial cleanup to strip some X11 specific features
from Workspace and move towards having the right code in the right
files. It should hopefully help get us in the right direction we get
some wayland session management.

Behaviour should be unchanged.
This commit is contained in:
David Edmundson 2022-04-04 23:53:48 +01:00
parent 9de79c62c7
commit 6d33612967
7 changed files with 65 additions and 48 deletions

View file

@ -120,7 +120,7 @@ bool Activities::start(const QString &id)
return false; // bogus id
}
ws->loadSubSessionInfo(id);
ws->sessionManager()->loadSubSessionInfo(id);
QDBusInterface ksmserver("org.kde.ksmserver", "/KSMServer", "org.kde.KSMServerInterface");
if (ksmserver.isValid()) {
@ -186,7 +186,7 @@ void Activities::reallyStop(const QString &id)
}
}
ws->storeSubSession(id, saveSessionIds);
ws->sessionManager()->storeSubSession(id, saveSessionIds);
QStringList saveAndClose;
QStringList saveOnly;

View file

@ -638,6 +638,11 @@ QList<Toplevel *> Workspace::xStackingOrder() const
return x_stacking;
}
QList<Toplevel *> Workspace::unconstrainedStackingOrder() const
{
return unconstrained_stacking_order;
}
void Workspace::updateXStackingOrder()
{
// use our own stacking order, not the X one, as they may differ

View file

@ -79,7 +79,7 @@ static NET::WindowType txtToWindowType(const char *txt)
*
* @see loadSessionInfo
*/
void Workspace::storeSession(const QString &sessionName, SMSavePhase phase)
void SessionManager::storeSession(const QString &sessionName, SMSavePhase phase)
{
qCDebug(KWIN_CORE) << "storing session" << sessionName << "in phase" << phase;
KConfig *config = sessionConfig(sessionName, QString());
@ -88,7 +88,8 @@ void Workspace::storeSession(const QString &sessionName, SMSavePhase phase)
int count = 0;
int active_client = -1;
for (auto it = m_x11Clients.begin(); it != m_x11Clients.end(); ++it) {
const QList<X11Client *> x11Clients = workspace()->clientList();
for (auto it = x11Clients.begin(); it != x11Clients.end(); ++it) {
X11Client *c = (*it);
if (c->windowType() > NET::Splash) {
// window types outside this are not tooltips/menus/OSDs
@ -130,7 +131,7 @@ void Workspace::storeSession(const QString &sessionName, SMSavePhase phase)
config->sync(); // it previously did some "revert to defaults" stuff for phase1 I think
}
void Workspace::storeClient(KConfigGroup &cg, int num, X11Client *c)
void SessionManager::storeClient(KConfigGroup &cg, int num, X11Client *c)
{
c->setSessionActivityOverride(false); // make sure we get the real values
QString n = QString::number(num);
@ -162,17 +163,19 @@ void Workspace::storeClient(KConfigGroup &cg, int num, X11Client *c)
cg.writeEntry(QLatin1String("userNoBorder") + n, c->userNoBorder());
cg.writeEntry(QLatin1String("windowType") + n, windowTypeToTxt(c->windowType()));
cg.writeEntry(QLatin1String("shortcut") + n, c->shortcut().toString());
cg.writeEntry(QLatin1String("stackingOrder") + n, unconstrained_stacking_order.indexOf(c));
cg.writeEntry(QLatin1String("stackingOrder") + n, workspace()->unconstrainedStackingOrder().indexOf(c));
cg.writeEntry(QLatin1String("activities") + n, c->activities());
}
void Workspace::storeSubSession(const QString &name, QSet<QByteArray> sessionIds)
void SessionManager::storeSubSession(const QString &name, QSet<QByteArray> sessionIds)
{
// TODO clear it first
KConfigGroup cg(KSharedConfig::openConfig(), QLatin1String("SubSession: ") + name);
int count = 0;
int active_client = -1;
for (auto it = m_x11Clients.begin(); it != m_x11Clients.end(); ++it) {
const QList<X11Client *> x11Clients = workspace()->clientList();
for (auto it = x11Clients.begin(); it != x11Clients.end(); ++it) {
X11Client *c = (*it);
if (c->windowType() > NET::Splash) {
continue;
@ -207,16 +210,17 @@ void Workspace::storeSubSession(const QString &name, QSet<QByteArray> sessionIds
*
* @see storeSession
*/
void Workspace::loadSessionInfo(const QString &sessionName)
void SessionManager::loadSession(const QString &sessionName)
{
session.clear();
KConfigGroup cg(sessionConfig(sessionName, QString()), "Session");
Q_EMIT loadSessionRequested(sessionName);
addSessionInfo(cg);
}
void Workspace::addSessionInfo(KConfigGroup &cg)
void SessionManager::addSessionInfo(KConfigGroup &cg)
{
m_initialDesktop = cg.readEntry("desktop", 1);
workspace()->setInitialDesktop(cg.readEntry("desktop", 1));
int count = cg.readEntry("count", 0);
int active_client = cg.readEntry("active", 0);
for (int i = 1; i <= count; i++) {
@ -252,7 +256,7 @@ void Workspace::addSessionInfo(KConfigGroup &cg)
}
}
void Workspace::loadSubSessionInfo(const QString &name)
void SessionManager::loadSubSessionInfo(const QString &name)
{
KConfigGroup cg(KSharedConfig::openConfig(), QLatin1String("SubSession: ") + name);
addSessionInfo(cg);
@ -276,7 +280,7 @@ static bool sessionInfoWindowTypeMatch(X11Client *c, SessionInfo *info)
*
* May return 0 if there's no session info for the client.
*/
SessionInfo *Workspace::takeSessionInfo(X11Client *c)
SessionInfo *SessionManager::takeSessionInfo(X11Client *c)
{
SessionInfo *realInfo = nullptr;
QByteArray sessionId = c->sessionId();
@ -336,6 +340,7 @@ SessionManager::SessionManager(QObject *parent)
SessionManager::~SessionManager()
{
qDeleteAll(session);
}
SessionState SessionManager::state() const
@ -378,19 +383,16 @@ void SessionManager::setState(SessionState state)
Q_EMIT stateChanged();
}
void SessionManager::loadSession(const QString &name)
{
Q_EMIT loadSessionRequested(name);
}
void SessionManager::aboutToSaveSession(const QString &name)
{
Q_EMIT prepareSessionSaveRequested(name);
storeSession(name, SMSavePhase0);
}
void SessionManager::finishSaveSession(const QString &name)
{
Q_EMIT finishSessionSaveRequested(name);
storeSession(name, SMSavePhase2);
}
void SessionManager::quit()

View file

@ -14,6 +14,9 @@
#include <QDataStream>
#include <QRect>
#include <QStringList>
#include <KConfigGroup>
#include <kwinglobals.h>
#include <netwm_def.h>
@ -21,16 +24,28 @@ namespace KWin
{
class X11Client;
struct SessionInfo;
class SessionManager : public QObject
{
Q_OBJECT
public:
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
};
SessionManager(QObject *parent);
~SessionManager() override;
SessionState state() const;
void loadSubSessionInfo(const QString &name);
void storeSubSession(const QString &name, QSet<QByteArray> sessionIds);
SessionInfo *takeSessionInfo(X11Client *);
Q_SIGNALS:
void stateChanged();
@ -47,7 +62,18 @@ public Q_SLOTS: // DBus API
private:
void setState(SessionState state);
void storeSession(const QString &sessionName, SMSavePhase phase);
void storeClient(KConfigGroup &cg, int num, X11Client *c);
void loadSessionInfo(const QString &sessionName);
void addSessionInfo(KConfigGroup &cg);
SessionState m_sessionState = SessionState::Normal;
int session_active_client;
int session_desktop;
QList<SessionInfo *> session;
};
struct SessionInfo
@ -83,12 +109,6 @@ struct SessionInfo
QStringList activities;
};
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
};
} // namespace
#endif

View file

@ -186,15 +186,6 @@ Workspace::Workspace()
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);
@ -513,7 +504,6 @@ Workspace::~Workspace()
delete Placement::self();
delete client_keys_dialog;
qDeleteAll(session);
_self = nullptr;
}
@ -1952,6 +1942,11 @@ void Workspace::removeInternalClient(InternalClient *client)
Q_EMIT internalClientRemoved(client);
}
void Workspace::setInitialDesktop(int desktop)
{
m_initialDesktop = desktop;
}
Group *Workspace::findGroup(xcb_window_t leader) const
{
Q_ASSERT(leader != XCB_WINDOW_NONE);

View file

@ -285,6 +285,7 @@ public:
*/
const QList<Toplevel *> &stackingOrder() const;
QList<Toplevel *> xStackingOrder() const;
QList<Toplevel *> unconstrainedStackingOrder() const;
QList<X11Client *> ensureStackingOrder(const QList<X11Client *> &clients) const;
QList<AbstractClient *> ensureStackingOrder(const QList<AbstractClient *> &clients) const;
@ -321,11 +322,6 @@ public:
void updateOnAllDesktopsOfTransients(AbstractClient *);
void checkTransients(xcb_window_t w);
void storeSession(const QString &sessionName, SMSavePhase phase);
void storeClient(KConfigGroup &cg, int num, X11Client *c);
void storeSubSession(const QString &name, QSet<QByteArray> sessionIds);
void loadSubSessionInfo(const QString &name);
SessionInfo *takeSessionInfo(X11Client *);
// D-Bus interface
@ -350,6 +346,7 @@ public:
void addGroup(Group *group);
void removeGroup(Group *group);
Group *findClientLeaderGroup(const X11Client *c) const;
int unconstainedStackingOrderIndex(const X11Client *c) const;
void removeUnmanaged(Unmanaged *); // Only called from Unmanaged::release()
void removeDeleted(Deleted *);
@ -432,6 +429,12 @@ public:
*/
void removeInternalClient(InternalClient *client);
/**
* @internal
* Used by session management
*/
void setInitialDesktop(int desktop);
public Q_SLOTS:
void performWindowOperation(KWin::AbstractClient *c, Options::WindowOperation op);
// Keybindings
@ -612,11 +615,6 @@ private:
AbstractClient *active_popup_client;
int m_initialDesktop;
void loadSessionInfo(const QString &sessionName);
void addSessionInfo(KConfigGroup &cg);
QList<SessionInfo *> session;
void updateXStackingOrder();
void updateTabbox();
@ -653,9 +651,6 @@ private:
bool was_user_interaction;
QScopedPointer<X11EventFilter> m_wasUserInteractionFilter;
int session_active_client;
int session_desktop;
int block_focus;
/**

View file

@ -483,7 +483,7 @@ bool X11Client::manage(xcb_window_t w, bool isMapped)
updateInputWindow();
updateLayer();
SessionInfo *session = workspace()->takeSessionInfo(this);
SessionInfo *session = workspace()->sessionManager()->takeSessionInfo(this);
if (session) {
init_minimize = session->minimized;
noborder = session->noBorder;