Coverage Report

Created: 2026-09-14 07:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtbase/src/gui/kernel/qsessionmanager.cpp
Line
Count
Source
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
16
QT_BEGIN_NAMESPACE
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
84
QSessionManagerPrivate::QSessionManagerPrivate(const QString &id,
85
                                               const QString &key)
86
0
    : QObjectPrivate()
87
0
{
88
0
    if (qApp->testAttribute(Qt::AA_DisableSessionManager)) {
89
0
        platformSessionManager = new QPlatformSessionManager(id, key);
90
0
    } else {
91
0
        platformSessionManager = QGuiApplicationPrivate::platformIntegration()->createPlatformSessionManager(id, key);
92
0
    }
93
0
    Q_ASSERT_X(platformSessionManager, "Platform session management",
94
0
               "No platform session management, should use the default implementation");
95
0
}
96
97
QSessionManagerPrivate::~QSessionManagerPrivate()
98
0
{
99
0
    delete platformSessionManager;
100
0
    platformSessionManager = nullptr;
101
0
}
102
103
QSessionManager::QSessionManager(QGuiApplication *app, QString &id, QString &key)
104
0
    : QObject(*(new QSessionManagerPrivate(id, key)), app)
105
0
{
106
0
}
107
108
QSessionManager::~QSessionManager()
109
0
{
110
0
}
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
*/
120
QString QSessionManager::sessionId() const
121
0
{
122
0
    Q_D(const QSessionManager);
123
0
    return d->platformSessionManager->sessionId();
124
0
}
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
*/
138
QString QSessionManager::sessionKey() const
139
0
{
140
0
    Q_D(const QSessionManager);
141
0
    return d->platformSessionManager->sessionKey();
142
0
}
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
*/
174
bool QSessionManager::allowsInteraction()
175
0
{
176
0
    Q_D(QSessionManager);
177
0
    return d->platformSessionManager->allowsInteraction();
178
0
}
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
*/
191
bool QSessionManager::allowsErrorInteraction()
192
0
{
193
0
    Q_D(QSessionManager);
194
0
    return d->platformSessionManager->allowsErrorInteraction();
195
0
}
196
197
/*!
198
    Releases the session manager's interaction semaphore after an interaction
199
    phase.
200
201
    \sa allowsInteraction(), allowsErrorInteraction()
202
*/
203
void QSessionManager::release()
204
0
{
205
0
    Q_D(QSessionManager);
206
0
    d->platformSessionManager->release();
207
0
}
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
*/
215
void QSessionManager::cancel()
216
0
{
217
0
    Q_D(QSessionManager);
218
0
    d->platformSessionManager->cancel();
219
0
}
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
*/
235
void QSessionManager::setRestartHint(QSessionManager::RestartHint hint)
236
0
{
237
0
    Q_D(QSessionManager);
238
0
    d->platformSessionManager->setRestartHint(hint);
239
0
}
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
*/
249
QSessionManager::RestartHint QSessionManager::restartHint() const
250
0
{
251
0
    Q_D(const QSessionManager);
252
0
    return d->platformSessionManager->restartHint();
253
0
}
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
*/
276
void QSessionManager::setRestartCommand(const QStringList &command)
277
0
{
278
0
    Q_D(QSessionManager);
279
0
    d->platformSessionManager->setRestartCommand(command);
280
0
}
281
282
/*!
283
    Returns the currently set restart command.
284
285
    \sa setRestartCommand(), restartHint()
286
*/
287
QStringList QSessionManager::restartCommand() const
288
0
{
289
0
    Q_D(const QSessionManager);
290
0
    return d->platformSessionManager->restartCommand();
291
0
}
292
293
/*!
294
    Sets the discard command to the given \a command.
295
296
    \sa discardCommand(), setRestartCommand()
297
*/
298
void QSessionManager::setDiscardCommand(const QStringList &command)
299
0
{
300
0
    Q_D(QSessionManager);
301
0
    d->platformSessionManager->setDiscardCommand(command);
302
0
}
303
304
/*!
305
    Returns the currently set discard command.
306
307
    \sa setDiscardCommand(), restartCommand(), setRestartCommand()
308
*/
309
QStringList QSessionManager::discardCommand() const
310
0
{
311
0
    Q_D(const QSessionManager);
312
0
    return d->platformSessionManager->discardCommand();
313
0
}
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
*/
323
void QSessionManager::setManagerProperty(const QString &name,
324
                                         const QString &value)
325
0
{
326
0
    Q_D(QSessionManager);
327
0
    d->platformSessionManager->setManagerProperty(name, value);
328
0
}
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
*/
336
void QSessionManager::setManagerProperty(const QString &name,
337
                                         const QStringList &value)
338
0
{
339
0
    Q_D(QSessionManager);
340
0
    d->platformSessionManager->setManagerProperty(name, value);
341
0
}
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
*/
349
bool QSessionManager::isPhase2() const
350
0
{
351
0
    Q_D(const QSessionManager);
352
0
    return d->platformSessionManager->isPhase2();
353
0
}
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
*/
372
void QSessionManager::requestPhase2()
373
0
{
374
    Q_D(QSessionManager);
375
0
    d->platformSessionManager->requestPhase2();
376
0
}
377
378
QT_END_NAMESPACE
379
380
#include "moc_qsessionmanager.cpp"
381
382
#endif // QT_NO_SESSIONMANAGER