Development/Tutorials/Session Management: Difference between revisions

From KDE TechBase
No edit summary
(The page was moved again)
 
(16 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/


==关于KDE和X11会话管理==
[[Category:MovedDevelop]]
 
Since KDE 1.0, the legacy X11R4 and ICCCM session management protocols
are supported. 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 KDE 2.0, also the standard X11R6 session management protocol XSMP
is supported and used. 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.
 
==更多阅读==
 
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.
 
===在main()函数添加会话管理===
 
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.
 
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() ) {
  kRestoreMainWindows< 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("MyWindow#");
  window->show();
}
return app.exec();
</code>
 
[http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/kmainwindow_8h.html#88ce427e39f425eefa5a94d746eb2bed kRestoreMainWindows<>()] will create (on the heap) as many instances of your main windows as have existed in the last session and call [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKMainWindow.html#46e01bd1aa6d488f1be2a5010030efb2 KMainWindow::restore()] with the correct arguments. Note that also QWidget::show() is called implicitly.
 
About setObjectName("MyWindow#"): For session management and window management to work properly, all main windows in the application should have a different name. If you don't do it, KMainWindow will create a unique name, but it's recommended to explicitly pass a window name that will also describe the type of the window. If there can be several windows of the same type, append '#' (hash) to the name, and KMainWindow will replace it with numbers to make the names unique. For example, for a mail client which has one main window showing the mails and folders, and which can also have one or more windows for composing mails, the name for the folders window should be e.g. "mainwindow" and for the composer windows "composer#".
 
With this you can easily restore all toplevel windows of your application.
 
It is also possible to restore different types of toplevel windows (each
derived from [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKMainWindow.html KMainWindow], of course) within one application. Imagine you have three classes of main windows: childMW1, childMW2 and childMW3:
 
<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, the [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/kmainwindow_8h.html#88ce427e39f425eefa5a94d746eb2bed kRestoreMainWindows<>()] template functions are provided for up to three template arguments.
 
==附录: KDE会话管理架构==
 
KDE的会话管理服务器叫做'''ksmserver''',他是'''kdebase'''的一部分。服务进程与KDE的窗口管理服务进程'''kwin'''进行交互,保存和恢复窗口信息,进行遗留的会话管理。 要启用会话管理, '''ksmserver'''必须X登陆过程的最后一个进程。这个会在'''startkde'''脚本的末尾体现.
 
 
''初始作者:'' [mailto:[email protected] Matthias Ettrich]
 
[[Category:Programming]]
[[Category:Tutorial]]
[[Category:FAQs]]

Latest revision as of 14:11, 18 July 2023

This tutorial was updated and moved to https://develop.kde.org/docs/features/session-managment/