|
|
(19 intermediate revisions by 6 users not shown) |
Line 1: |
Line 1: |
| {{Template:I18n/Language Navigation Bar|Development/Tutorials/Session Management}}
| | This tutorial was updated and moved to https://develop.kde.org/docs/features/session-managment/ |
|
| |
|
| ==About KDE and X11 session management==
| | [[Category:MovedDevelop]] |
| | |
| KDE supports the legacy X11R4 and ICCCM session
| |
| management protocols. Legacy applications that define the <tt>WM_COMMAND</tt>
| |
| property or support the <tt>WM_SAVE_YOURSELF</tt> protocol will be restarted
| |
| with the specified command. The window geometries will be restored on a best
| |
| effort basis.
| |
| | |
| Since version 2.0, KDE also supports and uses the standard X11R6
| |
| session management protocol XSMP. The official documentation of the
| |
| standard can be download from the X Consortium's FTP server
| |
| [http://stuff.mit.edu/afs/sipb/contrib/doc/X11/hardcopy/SM/xsmp.PS.gz ftp.x.org]. Unlike these legacy protocols, the new X11R6
| |
| session management gives a chance to save application
| |
| dependent settings when you log out. A text
| |
| editor, for instance, would save the names of the loaded files and would
| |
| reload them when you log in again. Another major advantage of the new
| |
| protocol is the support for a clean and safe logout procedure even if the
| |
| users decides not to restore the session next time. The protocol gives
| |
| applications the possibility to interact with the user in case they are in
| |
| danger to lose some data, and to cancel the shutdown process if necessary.
| |
| | |
| ==Further Reading==
| |
| | |
| An introductive overview of session management functionality and
| |
| the Qt API for it is available from [http://doc.trolltech.com/4.4/session.html doc.trolltech.com].
| |
| | |
| In KDE, the classes [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKApplication.html KApplication]
| |
| and [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKMainWindow.html KMainWindow]
| |
| hide all the ugly details from the programmer. Basically, a
| |
| [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKApplication.html KApplication] manages a
| |
| [http://api.kde.org/4.x-api/kdelibs-apidocs/kdecore/html/classKConfig.html KConfig] configuration object
| |
| [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKApplication.html#8f88369c240d6d90a04d29b2761989d9 sessionConfig()]
| |
| for you, that your application can utilize to store session specific data.
| |
| | |
| Please read the respective class documentation, especially the one of
| |
| [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKMainWindow.html KMainWindow], for a detailed interface description. With the advanced
| |
| functionality in [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKMainWindow.html KMainWindow], it's really just a matter of a few lines to get even a multi-window application to retains its state between
| |
| different user sessions.
| |
| | |
| ==Implementing session management in your application==
| |
| | |
| Here's just a brief overview how things are done. Again, see the
| |
| respective class documentation for details.
| |
| | |
| Implementing session management in KDE is easy. If your main window inherits from [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKMainWindow.html KMainWindow], you have just 2 things to do:
| |
| * Reimplement some virtual functions of [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKMainWindow.html KMainWindow].
| |
| * Add session management support to your main() function.
| |
| That's all.
| |
| | |
| ===Reimplement some virtual functions of KMainWindow===
| |
| | |
| [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKMainWindow.html KMainWindow] will save its position, geometry and positions of toolbars and menubar on logout.
| |
| * To warn the user that the application or some windows have unsaved data on close or logout (for example: show a dialog with the buttons "Save changes" and "Discard changes"), reimplement [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKMainWindow.html#f8c5708414be62f259114b0453ef8432 queryClose()].
| |
| * To save additional data, reimplement [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKMainWindow.html#4c7a6c395eec0bb245cd9ad6c884f897 saveProperties()]. (For a text editor, that would be the loaded files, for example.) Note that no user interaction is allowed in this function! For example, you may not display any dialog!
| |
| * To read the additional data again on next login, reimplement [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKMainWindow.html#c8d0d64ed5b309ba1da410423120d0a6 readProperties()].
| |
| These functions are called automatically by [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKMainWindow.html KMainWindow] respectively by the session manager. Note that it is not determined if [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKMainWindow.html#4c7a6c395eec0bb245cd9ad6c884f897 saveProperties()] is called before or after [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKMainWindow.html#f8c5708414be62f259114b0453ef8432 queryClose()]! Please read documentation of the respective functions before reimplementing them.
| |
| | |
| To save your application-wide properties (data that is only needed once per application, and not for each main window) reimplement [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKMainWindow.html#cf811d77a3acdcf2b61f8826429615a7 saveGlobalProperties()] and it's counterpart [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKMainWindow.html#2d4da4f305f00e8a5c94f5b978334231 readGlobalProperties]. Normally, you don't need these functions.
| |
| | |
| ===Add session management support to your main() function===
| |
| | |
| While [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKMainWindow.html#4c7a6c395eec0bb245cd9ad6c884f897 KMainWindow::saveProperties()] and [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKMainWindow.html#f8c5708414be62f259114b0453ef8432 KMainWindow::queryClose()] will work out of the box, [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKMainWindow.html#c8d0d64ed5b309ba1da410423120d0a6 KMainWindow::readProperties()] will not. You have to add some code to your main() function to implement session restoring.
| |
| | |
| ====For one kind of toplevel widget====
| |
| | |
| If your client has only one kind of toplevel widgets (which should be pretty usual) then you should use the RESTORE-macro.
| |
| | |
| Imagine you have an
| |
| application with a main window MyWindow inherited from
| |
| [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKMainWindow.html KMainWindow] (or from
| |
| [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKXmlGuiWindow.html KXmlGuiWindow], which inherits from
| |
| [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKMainWindow.html KMainWindow]). In your main() function, you would then create/restore the
| |
| application windows with something like:
| |
| | |
| <code cppqt>
| |
| KApplication app;
| |
| if ( app.isSessionRestored() ) {
| |
| RESTORE( MyWindow )
| |
| } else {
| |
| // create default application as usual
| |
| // for example:
| |
| MyWindow* window = new MyWindow();
| |
| // # will be replaced with numbers that are guaranteed
| |
| // to be unique in the application:
| |
| window->setObjectName("MainWindow#");
| |
| window->show();
| |
| }
| |
| return app.exec();
| |
| </code>
| |
| | |
| RESTORE will create as many instances of MyWindow as have existed in the last session. Note that QWidget::show() is called.
| |
| | |
| With this you can easily restore all toplevel windows of your application.
| |
| | |
| ====For several kinds of toplevel widgets====
| |
| | |
| It is also possible to
| |
| restore different types of toplevel windows within one application. In
| |
| that case, the RESTORE macro is too primitive. If you have more than one
| |
| kind of toplevel widget (each derived from [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKMainWindow.html KMainWindow], of course), you
| |
| can use the templated [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/kmainwindow_8h.html#88ce427e39f425eefa5a94d746eb2bed kRestoreMainWindows()] global functions:
| |
| | |
| <code cppqt>
| |
| KApplication app;
| |
| if ( app.isSessionRestored() ) {
| |
| kRestoreMainWindows< childMW1, childMW2, childMW3 >();
| |
| } else {
| |
| // create default application as usual
| |
| // for example:
| |
| childMW1* window1 = new childMW1();
| |
| childMW2* window2 = new childMW2();
| |
| childMW3* window3 = new childMW3();
| |
| // # will be replaced with numbers that are guaranteed
| |
| // to be unique in the application:
| |
| window1->setObjectName("type1mainWindow#");
| |
| window2->setObjectName("type2mainWindow#");
| |
| window3->setObjectName("type3mainWindow#");
| |
| window1->show();
| |
| window2->show();
| |
| window3->show();
| |
| }
| |
| return app.exec();
| |
| </code>
| |
| | |
| Currently, these functions are provided for up to three template arguments.
| |
| | |
| ===Internals===
| |
| | |
| These macros and template functions make use of [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKMainWindow.html#46e01bd1aa6d488f1be2a5010030efb2 KMainWindow::restore()] to restore the session.
| |
| | |
| ==Appendix: Architecture of the KDE session manager==
| |
| | |
| The session management server in KDE is called '''ksmserver''' and it is
| |
| part of the '''kdebase''' package. The server interacts with the KDE window
| |
| manager '''kwin''' to save and restore the window geometries and to perform
| |
| legacy session management. To make session management work, '''ksmserver'''
| |
| has to be started as last process of the X login procedure. This happens
| |
| automatically at the end of the '''startkde''' script.
| |
| | |
| | |
| | |
| | |
| [[Category:Programming]]
| |
| [[Category:Tutorial]]
| |
| [[Category:FAQs]] | |