| 1 | /**************************************************************************** | 
|---|
| 2 | ** | 
|---|
| 3 | ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). | 
|---|
| 4 | ** Contact: Qt Software Information (qt-info@nokia.com) | 
|---|
| 5 | ** | 
|---|
| 6 | ** This file is part of the documentation of the Qt Toolkit. | 
|---|
| 7 | ** | 
|---|
| 8 | ** $QT_BEGIN_LICENSE:LGPL$ | 
|---|
| 9 | ** Commercial Usage | 
|---|
| 10 | ** Licensees holding valid Qt Commercial licenses may use this file in | 
|---|
| 11 | ** accordance with the Qt Commercial License Agreement provided with the | 
|---|
| 12 | ** Software or, alternatively, in accordance with the terms contained in | 
|---|
| 13 | ** a written agreement between you and Nokia. | 
|---|
| 14 | ** | 
|---|
| 15 | ** GNU Lesser General Public License Usage | 
|---|
| 16 | ** Alternatively, this file may be used under the terms of the GNU Lesser | 
|---|
| 17 | ** General Public License version 2.1 as published by the Free Software | 
|---|
| 18 | ** Foundation and appearing in the file LICENSE.LGPL included in the | 
|---|
| 19 | ** packaging of this file.  Please review the following information to | 
|---|
| 20 | ** ensure the GNU Lesser General Public License version 2.1 requirements | 
|---|
| 21 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. | 
|---|
| 22 | ** | 
|---|
| 23 | ** In addition, as a special exception, Nokia gives you certain | 
|---|
| 24 | ** additional rights. These rights are described in the Nokia Qt LGPL | 
|---|
| 25 | ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this | 
|---|
| 26 | ** package. | 
|---|
| 27 | ** | 
|---|
| 28 | ** GNU General Public License Usage | 
|---|
| 29 | ** Alternatively, this file may be used under the terms of the GNU | 
|---|
| 30 | ** General Public License version 3.0 as published by the Free Software | 
|---|
| 31 | ** Foundation and appearing in the file LICENSE.GPL included in the | 
|---|
| 32 | ** packaging of this file.  Please review the following information to | 
|---|
| 33 | ** ensure the GNU General Public License version 3.0 requirements will be | 
|---|
| 34 | ** met: http://www.gnu.org/copyleft/gpl.html. | 
|---|
| 35 | ** | 
|---|
| 36 | ** If you are unsure which license is appropriate for your use, please | 
|---|
| 37 | ** contact the sales department at qt-sales@nokia.com. | 
|---|
| 38 | ** $QT_END_LICENSE$ | 
|---|
| 39 | ** | 
|---|
| 40 | ****************************************************************************/ | 
|---|
| 41 |  | 
|---|
| 42 | /*! | 
|---|
| 43 | \page session.html | 
|---|
| 44 | \title Session Management | 
|---|
| 45 | \ingroup gui-programming | 
|---|
| 46 |  | 
|---|
| 47 | A \e session is a group of running applications, each of which has a | 
|---|
| 48 | particular state. The session is controlled by a service called the \e | 
|---|
| 49 | session \e manager. The applications participating in the session are | 
|---|
| 50 | called \e{session clients}. | 
|---|
| 51 |  | 
|---|
| 52 | The session manager issues commands to its clients on behalf of the | 
|---|
| 53 | user. These commands may cause clients to commit unsaved changes (for | 
|---|
| 54 | example by saving open files), to preserve their state for future | 
|---|
| 55 | sessions, or to terminate gracefully. The set of these operations is | 
|---|
| 56 | called \e session \e management. | 
|---|
| 57 |  | 
|---|
| 58 | In the common case, a session consists of all applications that a | 
|---|
| 59 | user runs on their desktop at a time. Under Unix/X11, however, a | 
|---|
| 60 | session may include applications running on different computers and | 
|---|
| 61 | may span multiple displays. | 
|---|
| 62 |  | 
|---|
| 63 | \section1 Shutting a Session Down | 
|---|
| 64 |  | 
|---|
| 65 | A session is shut down by the session manager, usually on behalf of | 
|---|
| 66 | the user when they want to log out. A system might also perform an | 
|---|
| 67 | automatic shutdown in an emergency situation, for example, if power is | 
|---|
| 68 | about to be lost. Clearly there is a significant difference between | 
|---|
| 69 | these types of shutdown. During the first, the user may want to | 
|---|
| 70 | interact with the application, specifying exactly which files should | 
|---|
| 71 | be saved and which should be discarded. In the latter case, there's no | 
|---|
| 72 | time for interaction. There may not even be a user sitting in front of | 
|---|
| 73 | the machine! | 
|---|
| 74 |  | 
|---|
| 75 |  | 
|---|
| 76 | \section1 Protocols and Support on Different Platforms | 
|---|
| 77 |  | 
|---|
| 78 | On Mac OS X, and Microsoft Windows versions prior to Windows 2000, | 
|---|
| 79 | there is nothing like complete session management for applications | 
|---|
| 80 | yet, i.e. no restoring of previous sessions. (Windows 2000 and XP | 
|---|
| 81 | provide "hibernation" where the entire memory is saved to disk and | 
|---|
| 82 | restored when the machine is restarted.) They do support graceful | 
|---|
| 83 | logouts where applications have the opportunity to cancel the process | 
|---|
| 84 | after getting confirmation from the user. This is the functionality | 
|---|
| 85 | that corresponds to the QApplication::commitData() method. | 
|---|
| 86 |  | 
|---|
| 87 | X11 has supported complete session management since X11R6. | 
|---|
| 88 |  | 
|---|
| 89 | \section1 Getting Session Management to Work with Qt | 
|---|
| 90 |  | 
|---|
| 91 | Start by reimplementing QApplication::commitData() to | 
|---|
| 92 | enable your application to take part in the graceful logout process. If | 
|---|
| 93 | you are only targeting the Microsoft Windows platform, this is all you can | 
|---|
| 94 | and must provide. Ideally, your application should provide a shutdown | 
|---|
| 95 | dialog similar to the following: | 
|---|
| 96 |  | 
|---|
| 97 | \img session.png A typical dialog on shutdown | 
|---|
| 98 |  | 
|---|
| 99 | Example code for this dialog can be found in the documentation of | 
|---|
| 100 | QSessionManager::allowsInteraction(). | 
|---|
| 101 |  | 
|---|
| 102 | For complete session management (only supported on X11R6 at present), | 
|---|
| 103 | you must also take care of saving the application's state, and | 
|---|
| 104 | potentially of restoring the state in the next life cycle of the | 
|---|
| 105 | session. This saving is done by reimplementing | 
|---|
| 106 | QApplication::saveState(). All state data you are saving in this | 
|---|
| 107 | function, should be marked with the session identifier | 
|---|
| 108 | QApplication::sessionId(). This application specific identifier is | 
|---|
| 109 | globally unique, so no clashes will occur. (See QSessionManager for | 
|---|
| 110 | information on saving/restoring the state of a particular Qt | 
|---|
| 111 | application.) | 
|---|
| 112 |  | 
|---|
| 113 | Restoration is usually done in the application's main() | 
|---|
| 114 | function. Check if QApplication::isSessionRestored() is \c true. If | 
|---|
| 115 | that's the case, use the session identifier | 
|---|
| 116 | QApplication::sessionId() again to access your state data and restore | 
|---|
| 117 | the state of the application. | 
|---|
| 118 |  | 
|---|
| 119 | \bold{Important:} In order to allow the window manager to | 
|---|
| 120 | restore window attributes such as stacking order or geometry | 
|---|
| 121 | information, you must identify your top level widgets with | 
|---|
| 122 | unique application-wide object names (see QObject::setObjectName()). When | 
|---|
| 123 | restoring the application, you must ensure that all restored | 
|---|
| 124 | top level widgets are given the same unique names they had before. | 
|---|
| 125 |  | 
|---|
| 126 | \section1 Testing and Debugging Session Management | 
|---|
| 127 |  | 
|---|
| 128 | Session management support on Mac OS X and Windows is fairly limited | 
|---|
| 129 | due to the lack of this functionality in the operating system | 
|---|
| 130 | itself. Simply shut the session down and verify that your application | 
|---|
| 131 | behaves as expected. It may be useful to launch another application, | 
|---|
| 132 | usually the integrated development environment, before starting your | 
|---|
| 133 | application. This other application will get the shutdown message | 
|---|
| 134 | afterwards, thus permitting you to cancel the shutdown. Otherwise you | 
|---|
| 135 | would have to log in again after each test run, which is not a problem | 
|---|
| 136 | per se, but is time consuming. | 
|---|
| 137 |  | 
|---|
| 138 | On Unix you can either use a desktop environment that supports | 
|---|
| 139 | standard X11R6 session management or, the recommended method, use the | 
|---|
| 140 | session manager reference implementation provided by the X Consortium. | 
|---|
| 141 | This sample manager is called \c xsm and is part of a standard X11R6 | 
|---|
| 142 | installation. As always with X11, a useful and informative manual page | 
|---|
| 143 | is provided. Using \c xsm is straightforward (apart from the clumsy | 
|---|
| 144 | Athena-based user interface). Here's a simple approach: | 
|---|
| 145 |  | 
|---|
| 146 | \list | 
|---|
| 147 | \i Run X11R6. | 
|---|
| 148 | \i Create a dot file \c .xsmstartup in your home directory which | 
|---|
| 149 | contains the single line | 
|---|
| 150 | \snippet doc/src/snippets/code/doc_src_session.qdoc 0 | 
|---|
| 151 | This tells \c xsm that the default/failsafe session is just an xterm | 
|---|
| 152 | and nothing else. Otherwise \c xsm would try to invoke lots of | 
|---|
| 153 | clients including the windowmanager \c twm, which isn't very helpful. | 
|---|
| 154 | \i Now launch \c xsm from another terminal window. Both a session | 
|---|
| 155 | manager window and the xterm will appear. The xterm has a nice | 
|---|
| 156 | property that sets it apart from all the other shells you are | 
|---|
| 157 | currently running: within its shell, the \c SESSION_MANAGER | 
|---|
| 158 | environment variable points to the session manager you just started. | 
|---|
| 159 | \i Launch your application from the new xterm window. It will connect | 
|---|
| 160 | itself automatically to the session manager. You can check with the \e | 
|---|
| 161 | ClientList push button whether the connect was successful. | 
|---|
| 162 |  | 
|---|
| 163 | \bold{Note:} Never keep the \e ClientList open when you | 
|---|
| 164 | start or end session managed clients! Otherwise \c xsm is likely to | 
|---|
| 165 | crash. | 
|---|
| 166 | \i Use the session manager's \e Checkpoint and \e Shutdown buttons | 
|---|
| 167 | with different settings and see how your application behaves. The save | 
|---|
| 168 | type \e local means that the clients should save their state. It | 
|---|
| 169 | corresponds to the QApplication::saveState() function. The \e | 
|---|
| 170 | global save type asks applications to save their unsaved changes in | 
|---|
| 171 | permanent, globally accessible storage. It invokes | 
|---|
| 172 | QApplication::commitData(). | 
|---|
| 173 | \i Whenever something crashes, blame \c xsm and not Qt. \c xsm is far | 
|---|
| 174 | from being a usable session manager on a user's desktop. It is, | 
|---|
| 175 | however, stable and useful enough to serve as testing environment. | 
|---|
| 176 | \endlist | 
|---|
| 177 | */ | 
|---|