Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qsessionmanager.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#include <qsessionmanager.h>
6#include <qguiapplication.h>
7#include <qpa/qplatformsessionmanager.h>
8#include <qpa/qplatformintegration.h>
9
10#include <private/qobject_p.h>
11#include <private/qguiapplication_p.h>
12#include <private/qsessionmanager_p.h>
13
14#ifndef QT_NO_SESSIONMANAGER
15
17
18/*!
19 \class QSessionManager
20 \brief The QSessionManager class provides access to the session manager.
21
22 \inmodule QtGui
23
24 A session manager in a desktop environment (in which Qt GUI applications
25 live) keeps track of a session, which is a group of running applications,
26 each of which has a particular state. The state of an application contains
27 (most notably) the documents the application has open and the position and
28 size of its windows.
29
30 The session manager is used to save the session, e.g., when the machine is
31 shut down, and to restore a session, e.g., when the machine is started up.
32 We recommend that you use QSettings to save an application's settings,
33 for example, window positions, recently used files, etc. When the
34 application is restarted by the session manager, you can restore the
35 settings.
36
37 QSessionManager provides an interface between the application and the
38 platform's session manager. In Qt, session management requests for action
39 are handled by the two signals QGuiApplication::commitDataRequest() and
40 QGuiApplication::saveStateRequest(). Both provide a reference to a
41 QSessionManager object as argument. The session manager can only be
42 accessed in slots invoked by these signals.
43
44 No user interaction is possible \e unless the application gets explicit
45 permission from the session manager. You ask for permission by calling
46 allowsInteraction() or, if it is really urgent, allowsErrorInteraction().
47 Qt does not enforce this, but the session manager may.
48
49 You can try to abort the shutdown process by calling cancel().
50
51 For sophisticated session managers provided on Unix/X11, QSessionManager
52 offers further possibilities to fine-tune an application's session
53 management behavior: setRestartCommand(), setDiscardCommand(),
54 setRestartHint(), setProperty(), requestPhase2(). See the respective
55 function descriptions for further details.
56
57 \sa QGuiApplication, {Session Management}
58*/
59
60
61/*! \enum QSessionManager::RestartHint
62
63 This enum type defines the circumstances under which this application wants
64 to be restarted by the session manager. The current values are:
65
66 \value RestartIfRunning If the application is still running when the
67 session is shut down, it wants to be restarted
68 at the start of the next session.
69
70 \value RestartAnyway The application wants to be started at the
71 start of the next session, no matter what.
72 (This is useful for utilities that run just
73 after startup and then quit.)
74
75 \value RestartImmediately The application wants to be started immediately
76 whenever it is not running.
77
78 \value RestartNever The application does not want to be restarted
79 automatically.
80
81 The default hint is \c RestartIfRunning.
82*/
83
84QSessionManagerPrivate::QSessionManagerPrivate(const QString &id,
85 const QString &key)
86 : QObjectPrivate()
87{
88 if (qApp->testAttribute(Qt::AA_DisableSessionManager)) {
89 platformSessionManager = new QPlatformSessionManager(id, key);
90 } else {
91 platformSessionManager = QGuiApplicationPrivate::platformIntegration()->createPlatformSessionManager(id, key);
92 }
93 Q_ASSERT_X(platformSessionManager, "Platform session management",
94 "No platform session management, should use the default implementation");
95}
96
97QSessionManagerPrivate::~QSessionManagerPrivate()
98{
99 delete platformSessionManager;
100 platformSessionManager = nullptr;
101}
102
103QSessionManager::QSessionManager(QGuiApplication *app, QString &id, QString &key)
104 : QObject(*(new QSessionManagerPrivate(id, key)), app)
105{
106}
107
108QSessionManager::~QSessionManager()
109{
110}
111
112/*!
113 Returns the identifier of the current session.
114
115 If the application has been restored from an earlier session, this
116 identifier is the same as it was in the earlier session.
117
118 \sa sessionKey(), QGuiApplication::sessionId()
119*/
120QString QSessionManager::sessionId() const
121{
122 Q_D(const QSessionManager);
123 return d->platformSessionManager->sessionId();
124}
125
126/*!
127 \fn QString QSessionManager::sessionKey() const
128
129 Returns the session key in the current session.
130
131 If the application has been restored from an earlier session, this key is
132 the same as it was when the previous session ended.
133
134 The session key changes with every call of commitData() or saveState().
135
136 \sa sessionId(), QGuiApplication::sessionKey()
137*/
138QString QSessionManager::sessionKey() const
139{
140 Q_D(const QSessionManager);
141 return d->platformSessionManager->sessionKey();
142}
143
144
145/*!
146 Asks the session manager for permission to interact with the user. Returns
147 true if interaction is permitted; otherwise returns \c false.
148
149 The rationale behind this mechanism is to make it possible to synchronize
150 user interaction during a shutdown. Advanced session managers may ask all
151 applications simultaneously to commit their data, resulting in a much
152 faster shutdown.
153
154 When the interaction is completed we strongly recommend releasing the user
155 interaction semaphore with a call to release(). This way, other
156 applications may get the chance to interact with the user while your
157 application is still busy saving data. (The semaphore is implicitly
158 released when the application exits.)
159
160 If the user decides to cancel the shutdown process during the interaction
161 phase, you must tell the session manager that this has happened by calling
162 cancel().
163
164 Here's an example of how an application's QGuiApplication::commitDataRequest()
165 might be implemented:
166
167 \snippet code/src_gui_kernel_qguiapplication.cpp 1
168
169 If an error occurred within the application while saving its data, you may
170 want to try allowsErrorInteraction() instead.
171
172 \sa QGuiApplication::commitDataRequest(), release(), cancel()
173*/
174bool QSessionManager::allowsInteraction()
175{
176 Q_D(QSessionManager);
177 return d->platformSessionManager->allowsInteraction();
178}
179
180/*!
181 Returns \c true if error interaction is permitted; otherwise returns \c false.
182
183 This is similar to allowsInteraction(), but also enables the application to
184 tell the user about any errors that occur. Session managers may give error
185 interaction requests higher priority, which means that it is more likely
186 that an error interaction is permitted. However, you are still not
187 guaranteed that the session manager will allow interaction.
188
189 \sa allowsInteraction(), release(), cancel()
190*/
191bool QSessionManager::allowsErrorInteraction()
192{
193 Q_D(QSessionManager);
194 return d->platformSessionManager->allowsErrorInteraction();
195}
196
197/*!
198 Releases the session manager's interaction semaphore after an interaction
199 phase.
200
201 \sa allowsInteraction(), allowsErrorInteraction()
202*/
203void QSessionManager::release()
204{
205 Q_D(QSessionManager);
206 d->platformSessionManager->release();
207}
208
209/*!
210 Tells the session manager to cancel the shutdown process. Applications
211 should not call this function without asking the user first.
212
213 \sa allowsInteraction(), allowsErrorInteraction()
214*/
215void QSessionManager::cancel()
216{
217 Q_D(QSessionManager);
218 d->platformSessionManager->cancel();
219}
220
221/*!
222 Sets the application's restart hint to \a hint. On application startup, the
223 hint is set to \c RestartIfRunning.
224
225 \note These flags are only hints, a session manager may or may not respect
226 them.
227
228 We recommend setting the restart hint in QGuiApplication::saveStateRequest()
229 because most session managers perform a checkpoint shortly after an
230 application's
231 startup.
232
233 \sa restartHint()
234*/
235void QSessionManager::setRestartHint(QSessionManager::RestartHint hint)
236{
237 Q_D(QSessionManager);
238 d->platformSessionManager->setRestartHint(hint);
239}
240
241/*!
242 \fn QSessionManager::RestartHint QSessionManager::restartHint() const
243
244 Returns the application's current restart hint. The default is
245 \c RestartIfRunning.
246
247 \sa setRestartHint()
248*/
249QSessionManager::RestartHint QSessionManager::restartHint() const
250{
251 Q_D(const QSessionManager);
252 return d->platformSessionManager->restartHint();
253}
254
255/*!
256 If the session manager is capable of restoring sessions it will execute
257 \a command in order to restore the application. The command defaults to
258
259 \snippet code/src_gui_kernel_qguiapplication.cpp 2
260
261 The \c -session option is mandatory; otherwise QGuiApplication cannot
262 tell whether it has been restored or what the current session identifier
263 is.
264 See QGuiApplication::isSessionRestored() and
265 QGuiApplication::sessionId() for details.
266
267 If your application is very simple, it may be possible to store the entire
268 application state in additional command line options. This is usually a
269 very bad idea because command lines are often limited to a few hundred
270 bytes. Instead, use QSettings, temporary files, or a database for this
271 purpose. By marking the data with the unique sessionId(), you will be able
272 to restore the application in a future session.
273
274 \sa restartCommand(), setDiscardCommand(), setRestartHint()
275*/
276void QSessionManager::setRestartCommand(const QStringList &command)
277{
278 Q_D(QSessionManager);
279 d->platformSessionManager->setRestartCommand(command);
280}
281
282/*!
283 Returns the currently set restart command.
284
285 \sa setRestartCommand(), restartHint()
286*/
287QStringList QSessionManager::restartCommand() const
288{
289 Q_D(const QSessionManager);
290 return d->platformSessionManager->restartCommand();
291}
292
293/*!
294 Sets the discard command to the given \a command.
295
296 \sa discardCommand(), setRestartCommand()
297*/
298void QSessionManager::setDiscardCommand(const QStringList &command)
299{
300 Q_D(QSessionManager);
301 d->platformSessionManager->setDiscardCommand(command);
302}
303
304/*!
305 Returns the currently set discard command.
306
307 \sa setDiscardCommand(), restartCommand(), setRestartCommand()
308*/
309QStringList QSessionManager::discardCommand() const
310{
311 Q_D(const QSessionManager);
312 return d->platformSessionManager->discardCommand();
313}
314
315/*!
316 \overload
317
318 Low-level write access to the application's identification and state
319 records are kept in the session manager.
320
321 The property called \a name has its value set to the string \a value.
322*/
323void QSessionManager::setManagerProperty(const QString &name,
324 const QString &value)
325{
326 Q_D(QSessionManager);
327 d->platformSessionManager->setManagerProperty(name, value);
328}
329
330/*!
331 Low-level write access to the application's identification and state record
332 are kept in the session manager.
333
334 The property called \a name has its value set to the string list \a value.
335*/
336void QSessionManager::setManagerProperty(const QString &name,
337 const QStringList &value)
338{
339 Q_D(QSessionManager);
340 d->platformSessionManager->setManagerProperty(name, value);
341}
342
343/*!
344 Returns \c true if the session manager is currently performing a second
345 session management phase; otherwise returns \c false.
346
347 \sa requestPhase2()
348*/
349bool QSessionManager::isPhase2() const
350{
351 Q_D(const QSessionManager);
352 return d->platformSessionManager->isPhase2();
353}
354
355/*!
356 Requests a second session management phase for the application. The
357 application may then return immediately from the
358 QGuiApplication::commitDataRequest() or QApplication::saveStateRequest()
359 function, and they will be called again once most or all other
360 applications have finished their session management.
361
362 The two phases are useful for applications such as the X11 window manager
363 that need to store information about another application's windows and
364 therefore have to wait until these applications have completed their
365 respective session management tasks.
366
367 \note If another application has requested a second phase it may get called
368 before, simultaneously with, or after your application's second phase.
369
370 \sa isPhase2()
371*/
372void QSessionManager::requestPhase2()
373{
374 Q_D(QSessionManager);
375 d->platformSessionManager->requestPhase2();
376}
377
378QT_END_NAMESPACE
379
380#include "moc_qsessionmanager.cpp"
381
382#endif // QT_NO_SESSIONMANAGER
Combined button and popup list for selecting options.
#define qApp