Opened 19 years ago

Closed 19 years ago

Last modified 18 years ago

#15 closed enhancement (fixed)

Implement the QSessionManager class

Reported by: dmik Owned by: dmik
Priority: normal Milestone: qt-os2-3.3.1-rc07
Component: kernel Version:
Severity: normal Keywords: session manager management
Cc:

Description

We need to implement the QSessionManager class, because it is used by many Qt applications for Linux. Since (at least as far as I know) OS/2 doesn't provide much control over the session management (in particular, an application cannot determine whether it is automatically openend by WPS because of RESTARTOBJECTS=YES/AUTOSTART=PROGRAMS,.. in config.sys or is just normally started by the user), we'll provide a limited QSessionManager implementation similarly to Qt/Win32 and Qt/Mac (see http://doc.trolltech.com/3.3/session.html).

Change History (3)

comment:1 by dmik, 19 years ago

Status: newassigned

comment:2 by dmik, 19 years ago

Resolution: fixed
Status: assignedclosed

The OS/2 version of the QSessionManager class has been implemented, so QT_NO_SESSIONMANAGER is no more defined by default. The session management works as follows:

After a WM_SAVEAPPLICATION message is received by a Qt application (that normally indicates the system shutdown procedure has been initiated), receiving a WM_QUIT message will cause the QApplication::commitData() method to be called. Calling QSessionManager::allowsInteraction() or QSessionManager::allowsErrorInteraction() from this method will return TRUE, and calling QSessionManager::cancel() will cancel the shutdown process.

However, when a WM_QUIT message is received by the application without first receiving WM_SAVEAPPLICATION, it is assumed to be an emergency exit. QApplication::commitData() will still be called, but both QSessionManager::allowsInteraction() and QSessionManager::allowsErrorInteraction() will return FALSE and QSessionManager::cancel() will have no effect. The application will terminate once QApplication::commitData() returns.

I've successfully tested the session management both with the standard PM shutdown procedure (i.e. a WinShutdownSystem() call) and with the extended shutdown provided both by the eStyler Lite (that actually seems to use WinShutdownSystem() as well) and by XWorkplace. In case of XWorkplace, it is not actually possible to cancel the shutdown -- the shutdown progress window will still be waiting for the app to terminate (I will check the XWorkplace sources later to see what can be done).

Regarding WinShutdownSystem(), there is one important note related to the parent-child relationship between processes. If a VIO application has started a child PM process in EXEC_SYNC mode (i.e. it is waiting for the child to terminate), WinShutdownSystem() will kill both the parent and the child soon after the child has returned from WM_SAVEAPPLICATION processing, without posting it a WM_QUIT message and waiting until it destroys its message queue. On practice, this means that the child, if it's a Qt application, will not have the opportunity to save its data or to cancel the shutdown procedure. A possible solution is to always start a Qt child in a separate session (i.e., using the start command or the DosStartSession() API call). The other approach could be to call QApplication::commitData() from WM_SAVEAPPLICATION with the user interaction disabled, but I don't know how to determine that we are being shut down by WinShutdownSystem(). Probably, it's better just to call it from there but with the user interaction enabled. Should not make any harm to other use cases, except that even if the user requests to cancel the shutdown from the dialog box, this request will be ignored. Need to think more of it.

comment:3 by dmik, 19 years ago

Just a postnote. I've tested the approach of calling QApplication::commitData() from WM_SAVEAPPLICATION with the user interaction enabled to protect against WinCancelShutdown() killing us if we're a child of a VIO parent waiting for us, and it appears to work just fine, so I've committed the change. When such a relationship takes place, the QSessionManager::cancel() call has no effect of course, but since we are not actually killed until we return from WM_SAVEAPPLICATION, the application can at least save its sensitive data.

Besides this, I've also tried to add the support of canceling the Extended XWorkplace shutdown when QSessionManager::cancel() gets called. It required a very simple patch to the xwp sources (since I haven't found that this functionality is already there), but works really nice (i.e. the extended shutdown progress window is dissmissed as if the user has pressed the Cancel Shutdown button). So, although the patch is not officially accepted by xwp maintainers, I've already committed this feature. Here is the patch I'm talking about:

Index: shutdown.c
===================================================================
RCS file: /netlabs.cvs/xworkplace/src/startshut/shutdown.c,v
retrieving revision 1.108
diff -u -r1.108 shutdown.c
--- shutdown.c	2006/04/01 15:57:17	1.108
+++ shutdown.c	2006/04/02 14:28:50
@@ -2897,7 +2897,8 @@
 
             WinPostMsg(pItem->swctl.hwnd,
                        WM_SAVEAPPLICATION,
-                       MPNULL, MPNULL);
+                       MPFROMHWND(pShutdownData->SDConsts.hwndMain),
+                       MPFROM2SHORT(ID_SDDI_CANCELSHUTDOWN, 0));
 
             doshWriteLogEntry(pShutdownData->ShutdownLogFile,
                    "      Posting WM_QUIT to hwnd 0x%lX",
Note: See TracTickets for help on using tickets.