Changeset View
Changeset View
Standalone View
Standalone View
sm.cpp
Show First 20 Lines • Show All 75 Lines • ▼ Show 20 Line(s) | 75 | { | |||
---|---|---|---|---|---|
76 | for (int i = NET::Unknown; | 76 | for (int i = NET::Unknown; | ||
77 | i <= NET::Splash; | 77 | i <= NET::Splash; | ||
78 | ++i) | 78 | ++i) | ||
79 | if (qstrcmp(txt, window_type_names[ i + 1 ]) == 0) // +1 | 79 | if (qstrcmp(txt, window_type_names[ i + 1 ]) == 0) // +1 | ||
80 | return static_cast< NET::WindowType >(i); | 80 | return static_cast< NET::WindowType >(i); | ||
81 | return static_cast< NET::WindowType >(-2); // undefined | 81 | return static_cast< NET::WindowType >(-2); // undefined | ||
82 | } | 82 | } | ||
83 | 83 | | |||
84 | void Workspace::saveState(QSessionManager &sm) | | |||
85 | { | | |||
86 | bool sessionManagerIsKSMServer = QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.ksmserver").value(); | | |||
87 | | ||||
88 | // If the session manager is ksmserver, save stacking | | |||
89 | // order, active window, active desktop etc. in phase 1, | | |||
90 | // as ksmserver assures no interaction will be done | | |||
91 | // before the WM finishes phase 1. Saving in phase 2 is | | |||
92 | // too late, as possible user interaction may change some things. | | |||
93 | // Phase2 is still needed though (ICCCM 5.2) | | |||
94 | KConfig *config = sessionConfig(sm.sessionId(), sm.sessionKey()); | | |||
95 | if (!sm.isPhase2()) { | | |||
96 | KConfigGroup cg(config, "Session"); | | |||
97 | cg.writeEntry("AllowsInteraction", sm.allowsInteraction()); | | |||
98 | if (sessionManagerIsKSMServer) // save stacking order etc. before "save file?" etc. dialogs change it | | |||
99 | storeSession(config, SMSavePhase0); | | |||
100 | config->markAsClean(); // don't write Phase #1 data to disk | | |||
101 | sm.release(); // Qt doesn't automatically release in this case (bug?) | | |||
102 | sm.requestPhase2(); | | |||
103 | return; | | |||
104 | } | | |||
105 | storeSession(config, sessionManagerIsKSMServer ? SMSavePhase2 : SMSavePhase2Full); | | |||
106 | config->sync(); | | |||
107 | | ||||
108 | // inform the smserver on how to clean-up after us | | |||
109 | const QString localFilePath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QLatin1Char('/') + config->name(); | | |||
110 | if (QFile::exists(localFilePath)) { // expectable for the sync | | |||
111 | sm.setDiscardCommand(QStringList() << QStringLiteral("rm") << localFilePath); | | |||
112 | } | | |||
113 | } | | |||
114 | | ||||
115 | // Workspace | | |||
116 | | ||||
117 | /** | 84 | /** | ||
118 | * Stores the current session in the config file | 85 | * Stores the current session in the config file | ||
119 | * | 86 | * | ||
120 | * @see loadSessionInfo | 87 | * @see loadSessionInfo | ||
121 | */ | 88 | */ | ||
122 | void Workspace::storeSession(KConfig* config, SMSavePhase phase) | 89 | void Workspace::storeSession(const QString &sessionName, SMSavePhase phase) | ||
123 | { | 90 | { | ||
91 | qCDebug(KWIN_CORE) << "storing session" << sessionName << "in phase" << phase; | ||||
92 | KConfig *config = sessionConfig(sessionName, QString()); | ||||
93 | | ||||
124 | KConfigGroup cg(config, "Session"); | 94 | KConfigGroup cg(config, "Session"); | ||
125 | int count = 0; | 95 | int count = 0; | ||
126 | int active_client = -1; | 96 | int active_client = -1; | ||
127 | 97 | | |||
128 | for (auto it = clients.begin(); it != clients.end(); ++it) { | 98 | for (auto it = clients.begin(); it != clients.end(); ++it) { | ||
129 | X11Client *c = (*it); | 99 | X11Client *c = (*it); | ||
130 | if (c->windowType() > NET::Splash) { | 100 | if (c->windowType() > NET::Splash) { | ||
131 | //window types outside this are not tooltips/menus/OSDs | 101 | //window types outside this are not tooltips/menus/OSDs | ||
Show All 23 Lines | 124 | } else if (phase == SMSavePhase2) { | |||
155 | cg.writeEntry("count", count); | 125 | cg.writeEntry("count", count); | ||
156 | cg.writeEntry("active", session_active_client); | 126 | cg.writeEntry("active", session_active_client); | ||
157 | cg.writeEntry("desktop", session_desktop); | 127 | cg.writeEntry("desktop", session_desktop); | ||
158 | } else { // SMSavePhase2Full | 128 | } else { // SMSavePhase2Full | ||
159 | cg.writeEntry("count", count); | 129 | cg.writeEntry("count", count); | ||
160 | cg.writeEntry("active", session_active_client); | 130 | cg.writeEntry("active", session_active_client); | ||
161 | cg.writeEntry("desktop", VirtualDesktopManager::self()->current()); | 131 | cg.writeEntry("desktop", VirtualDesktopManager::self()->current()); | ||
162 | } | 132 | } | ||
133 | config->sync(); // it previously did some "revert to defaults" stuff for phase1 I think | ||||
163 | } | 134 | } | ||
164 | 135 | | |||
165 | void Workspace::storeClient(KConfigGroup &cg, int num, X11Client *c) | 136 | void Workspace::storeClient(KConfigGroup &cg, int num, X11Client *c) | ||
166 | { | 137 | { | ||
167 | c->setSessionActivityOverride(false); //make sure we get the real values | 138 | c->setSessionActivityOverride(false); //make sure we get the real values | ||
168 | QString n = QString::number(num); | 139 | QString n = QString::number(num); | ||
169 | cg.writeEntry(QLatin1String("sessionId") + n, c->sessionId().constData()); | 140 | cg.writeEntry(QLatin1String("sessionId") + n, c->sessionId().constData()); | ||
170 | cg.writeEntry(QLatin1String("windowRole") + n, c->windowRole().constData()); | 141 | cg.writeEntry(QLatin1String("windowRole") + n, c->windowRole().constData()); | ||
▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Line(s) | 173 | { | |||
230 | //cg.writeEntry( "desktop", currentDesktop()); | 201 | //cg.writeEntry( "desktop", currentDesktop()); | ||
231 | } | 202 | } | ||
232 | 203 | | |||
233 | /** | 204 | /** | ||
234 | * Loads the session information from the config file. | 205 | * Loads the session information from the config file. | ||
235 | * | 206 | * | ||
236 | * @see storeSession | 207 | * @see storeSession | ||
237 | */ | 208 | */ | ||
238 | void Workspace::loadSessionInfo(const QString &key) | 209 | void Workspace::loadSessionInfo(const QString &sessionName) | ||
239 | { | 210 | { | ||
240 | // NOTICE: qApp->sessionKey() is outdated when this gets invoked | | |||
241 | // the key parameter is cached from the application constructor. | | |||
242 | session.clear(); | 211 | session.clear(); | ||
243 | KConfigGroup cg(sessionConfig(qApp->sessionId(), key), "Session"); | 212 | KConfigGroup cg(sessionConfig(sessionName, QString()), "Session"); | ||
244 | addSessionInfo(cg); | 213 | addSessionInfo(cg); | ||
245 | } | 214 | } | ||
246 | 215 | | |||
247 | void Workspace::addSessionInfo(KConfigGroup &cg) | 216 | void Workspace::addSessionInfo(KConfigGroup &cg) | ||
248 | { | 217 | { | ||
249 | m_initialDesktop = cg.readEntry("desktop", 1); | 218 | m_initialDesktop = cg.readEntry("desktop", 1); | ||
250 | int count = cg.readEntry("count", 0); | 219 | int count = cg.readEntry("count", 0); | ||
251 | int active_client = cg.readEntry("active", 0); | 220 | int active_client = cg.readEntry("active", 0); | ||
▲ Show 20 Lines • Show All 128 Lines • ▼ Show 20 Line(s) | 344 | { | |||
380 | case 1: | 349 | case 1: | ||
381 | setState(SessionState::Quitting); | 350 | setState(SessionState::Quitting); | ||
382 | break; | 351 | break; | ||
383 | default: | 352 | default: | ||
384 | setState(SessionState::Normal); | 353 | setState(SessionState::Normal); | ||
385 | } | 354 | } | ||
386 | } | 355 | } | ||
387 | 356 | | |||
357 | // TODO should we rethink this now that we have dedicated start end end save methods? | ||||
apol: Care to elaborate? what do you have in mind here?
Feels like it could end up being one of… | |||||
Ack, I rarely see a TODO and act upon it in any meaningful way. IMHO it's not a problem as-is. One is a request for kwin to perform an action, the other is a property of the state the whole session should be in. It allows us to be more explicit that we're shutting down or whatever which could outlive session management operations and to separate ksmserver specific code further. davidedmundson: Ack, I rarely see a TODO and act upon it in any meaningful way.
IMHO it's not a problem as-is. | |||||
388 | void SessionManager::setState(SessionState state) | 358 | void SessionManager::setState(SessionState state) | ||
389 | { | 359 | { | ||
390 | if (state == m_sessionState) { | 360 | if (state == m_sessionState) { | ||
391 | return; | 361 | return; | ||
392 | } | 362 | } | ||
393 | // If we're starting to save a session | 363 | // If we're starting to save a session | ||
394 | if (state == SessionState::Saving) { | 364 | if (state == SessionState::Saving) { | ||
395 | RuleBook::self()->setUpdatesDisabled(true); | 365 | RuleBook::self()->setUpdatesDisabled(true); | ||
396 | } | 366 | } | ||
397 | // If we're ending a save session due to either completion or cancellation | 367 | // If we're ending a save session due to either completion or cancellation | ||
398 | if (m_sessionState == SessionState::Saving) { | 368 | if (m_sessionState == SessionState::Saving) { | ||
399 | RuleBook::self()->setUpdatesDisabled(false); | 369 | RuleBook::self()->setUpdatesDisabled(false); | ||
400 | Workspace::self()->forEachClient([](X11Client *client) { | 370 | Workspace::self()->forEachClient([](X11Client *client) { | ||
401 | client->setSessionActivityOverride(false); | 371 | client->setSessionActivityOverride(false); | ||
402 | }); | 372 | }); | ||
403 | } | 373 | } | ||
404 | m_sessionState = state; | 374 | m_sessionState = state; | ||
405 | emit stateChanged(); | 375 | emit stateChanged(); | ||
406 | } | 376 | } | ||
407 | 377 | | |||
378 | void SessionManager::loadSession(const QString &name) | ||||
379 | { | ||||
380 | emit loadSessionRequested(name); | ||||
381 | } | ||||
382 | | ||||
383 | void SessionManager::aboutToSaveSession(const QString &name) | ||||
384 | { | ||||
385 | emit prepareSessionSaveRequested(name); | ||||
386 | } | ||||
387 | | ||||
388 | void SessionManager::finishSaveSession(const QString &name) | ||||
389 | { | ||||
390 | emit finishSessionSaveRequested(name); | ||||
391 | } | ||||
392 | | ||||
408 | } // namespace | 393 | } // namespace | ||
409 | 394 | |
Care to elaborate? what do you have in mind here?
Feels like it could end up being one of these TODO that stay forever