diff options
Diffstat (limited to 'src/gui/kernel/qguiapplication.cpp')
-rw-r--r-- | src/gui/kernel/qguiapplication.cpp | 216 |
1 files changed, 214 insertions, 2 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 2beddd2cd6..e6aece0ad9 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -62,6 +62,7 @@ #include <QtDebug> #include <qpalette.h> #include <qscreen.h> +#include "qsessionmanager.h" #include <private/qscreen_p.h> #include <private/qdrawhelper_p.h> @@ -211,8 +212,9 @@ static inline void clearFontUnlocked() QGuiApplication contains the main event loop, where all events from the window system and other sources are processed and dispatched. It also handles the - application's initialization and finalization. In addition, QGuiApplication handles - most of the system-wide and application-wide settings. + application's initialization and finalization, and provides session management. + In addition, QGuiApplication handles most of the system-wide and application-wide + settings. For any GUI application using Qt, there is precisely \b one QGuiApplication object no matter whether the application has 0, 1, 2 or more windows at @@ -251,6 +253,14 @@ static inline void clearFontUnlocked() \li It manages the application's mouse cursor handling, see setOverrideCursor() + + \li It provides support for sophisticated \l{Session Management} + {session management}. This makes it possible for applications + to terminate gracefully when the user logs out, to cancel a + shutdown process if termination isn't possible and even to + preserve the entire application's state for a future session. + See isSessionRestored(), sessionId() and commitDataRequest() and + saveStateRequest() for details. \endlist Since the QGuiApplication object does so much initialization, it \e{must} be @@ -301,6 +311,13 @@ static inline void clearFontUnlocked() restoreOverrideCursor(). \row + \li Session management + \li isSessionRestored(), + sessionId(), + commitDataRequest(), + saveStateRequest(). + + \row \li Miscellaneous \li startingUp(), closingDown(), @@ -335,6 +352,8 @@ static inline void clearFontUnlocked() \li -qmljsdebugger=, activates the QML/JS debugger with a specified port. The value must be of format port:1234[,block], where block is optional and will make the application wait until a debugger connects to it. + \li -session \e session, restores the application from an earlier + \l{Session Management}{session}. \endlist \sa arguments() @@ -374,6 +393,11 @@ QGuiApplication::~QGuiApplication() QGuiApplicationPrivate::qt_clipboard = 0; #endif +#ifndef QT_NO_SESSIONMANAGER + delete d->session_manager; + d->session_manager = 0; +#endif //QT_NO_SESSIONMANAGER + clearPalette(); #ifndef QT_NO_CURSOR @@ -394,6 +418,10 @@ QGuiApplicationPrivate::QGuiApplicationPrivate(int &argc, char **argv, int flags { self = this; application_type = QCoreApplicationPrivate::Gui; +#ifndef QT_NO_SESSIONMANAGER + is_session_restored = false; + is_saving_session = false; +#endif } /*! @@ -911,6 +939,19 @@ void QGuiApplicationPrivate::init() QGuiApplicationPrivate::noGrab = true; } else if (arg == "-dograb") { doGrabUnderDebugger = true; +#ifndef QT_NO_SESSIONMANAGER + } else if (arg == "-session" && i < argc-1) { + ++i; + if (argv[i] && *argv[i]) { + session_id = QString::fromLatin1(argv[i]); + int p = session_id.indexOf(QLatin1Char('_')); + if (p >= 0) { + session_key = session_id.mid(p +1); + session_id = session_id.left(p); + } + is_session_restored = true; + } +#endif } else { argv[j++] = argv[i]; } @@ -957,6 +998,14 @@ void QGuiApplicationPrivate::init() is_app_running = true; init_plugins(pluginList); QWindowSystemInterface::flushWindowSystemEvents(); + + Q_Q(QGuiApplication); + +#ifndef QT_NO_SESSIONMANAGER + // connect to the session manager + session_manager = new QSessionManager(q, session_id, session_key); +#endif + } extern void qt_cleanupFontDatabase(); @@ -2316,6 +2365,169 @@ bool QGuiApplicationPrivate::shouldQuit() } /*! + \since 4.2 + \fn void QGuiApplication::commitDataRequest(QSessionManager &manager) + + This signal deals with \l{Session Management}{session management}. It is + emitted when the QSessionManager wants the application to commit all its + data. + + Usually this means saving all open files, after getting permission from + the user. Furthermore you may want to provide a means by which the user + can cancel the shutdown. + + You should not exit the application within this signal. Instead, + the session manager may or may not do this afterwards, depending on the + context. + + \warning Within this signal, no user interaction is possible, \e + unless you ask the \a manager for explicit permission. See + QSessionManager::allowsInteraction() and + QSessionManager::allowsErrorInteraction() for details and example + usage. + + \note You should use Qt::DirectConnection when connecting to this signal. + + \sa isSessionRestored(), sessionId(), saveStateRequest(), {Session Management} +*/ + +/*! + \since 4.2 + \fn void QGuiApplication::saveStateRequest(QSessionManager &manager) + + This signal deals with \l{Session Management}{session management}. It is + invoked when the \l{QSessionManager}{session manager} wants the application + to preserve its state for a future session. + + For example, a text editor would create a temporary file that includes the + current contents of its edit buffers, the location of the cursor and other + aspects of the current editing session. + + You should never exit the application within this signal. Instead, the + session manager may or may not do this afterwards, depending on the + context. Futhermore, most session managers will very likely request a saved + state immediately after the application has been started. This permits the + session manager to learn about the application's restart policy. + + \warning Within this signal, no user interaction is possible, \e + unless you ask the \a manager for explicit permission. See + QSessionManager::allowsInteraction() and + QSessionManager::allowsErrorInteraction() for details. + + \note You should use Qt::DirectConnection when connecting to this signal. + + \sa isSessionRestored(), sessionId(), commitDataRequest(), {Session Management} +*/ + +/*! + \fn bool QGuiApplication::isSessionRestored() const + + Returns true if the application has been restored from an earlier + \l{Session Management}{session}; otherwise returns false. + + \sa sessionId(), commitDataRequest(), saveStateRequest() +*/ + +/*! + \since 5.0 + \fn bool QGuiApplication::isSavingSession() const + + Returns true if the application is currently saving the + \l{Session Management}{session}; otherwise returns false. + + This is true when commitDataRequest() and saveStateRequest() are emitted, + but also when the windows are closed afterwards by session management. + + \sa sessionId(), commitDataRequest(), saveStateRequest() +*/ + +/*! + \fn QString QGuiApplication::sessionId() const + + Returns the current \l{Session Management}{session's} identifier. + + If the application has been restored from an earlier session, this + identifier is the same as it was in that previous session. The session + identifier is guaranteed to be unique both for different applications + and for different instances of the same application. + + \sa isSessionRestored(), sessionKey(), commitDataRequest(), saveStateRequest() +*/ + +/*! + \fn QString QGuiApplication::sessionKey() const + + Returns the session key in the current \l{Session Management}{session}. + + If the application has been restored from an earlier session, this key is + the same as it was when the previous session ended. + + The session key changes every time the session is saved. If the shutdown process + is cancelled, another session key will be used when shutting down again. + + \sa isSessionRestored(), sessionId(), commitDataRequest(), saveStateRequest() +*/ +#ifndef QT_NO_SESSIONMANAGER +bool QGuiApplication::isSessionRestored() const +{ + Q_D(const QGuiApplication); + return d->is_session_restored; +} + +QString QGuiApplication::sessionId() const +{ + Q_D(const QGuiApplication); + return d->session_id; +} + +QString QGuiApplication::sessionKey() const +{ + Q_D(const QGuiApplication); + return d->session_key; +} + +bool QGuiApplication::isSavingSession() const +{ + Q_D(const QGuiApplication); + return d->is_saving_session; +} + +void QGuiApplicationPrivate::commitData(QSessionManager& manager) +{ + Q_Q(QGuiApplication); + is_saving_session = true; + emit q->commitDataRequest(manager); + if (manager.allowsInteraction()) { + QWindowList done; + QWindowList list = QGuiApplication::topLevelWindows(); + bool cancelled = false; + for (int i = 0; !cancelled && i < list.size(); ++i) { + QWindow* w = list.at(i); + if (w->isVisible() && !done.contains(w)) { + cancelled = !w->close(); + if (!cancelled) + done.append(w); + list = QGuiApplication::topLevelWindows(); + i = -1; + } + } + if (cancelled) + manager.cancel(); + } + is_saving_session = false; +} + + +void QGuiApplicationPrivate::saveState(QSessionManager &manager) +{ + Q_Q(QGuiApplication); + is_saving_session = true; + emit q->saveStateRequest(manager); + is_saving_session = false; +} +#endif //QT_NO_SESSIONMANAGER + +/*! \property QGuiApplication::layoutDirection \brief the default layout direction for this application |