Changeset 78


Ignore:
Timestamp:
Apr 2, 2006, 4:11:09 PM (19 years ago)
Author:
dmik
Message:

Moved the QApplication::commitData() call to WM_SAVEAPPLICATION, to protect against WinShutdownSystem() killing the app if its parent is a VIO app that is waiting for child termoination, and to support canceling the Extended XWorkplace procedure gracefully (requires an XWP patch that is not accepted by the maintainers thoug).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel/qapplication_pm.cpp

    r77 r78  
    241241static bool     sm_cancel            = FALSE;
    242242static bool     sm_gracefulShutdown  = FALSE;
    243 bool            qt_about_to_destroy_wnd = FALSE;
     243static bool     sm_quitSkipped       = FALSE;
     244bool qt_about_to_destroy_wnd     = FALSE;
    244245
    245246//#define DEBUG_SESSIONMANAGER
     
    10341035#if !defined (QT_NO_SESSIONMANAGER)
    10351036        case WM_SAVEAPPLICATION: {
    1036 #if defined (DEBUG_SESSIONMANAGER)               
     1037#if defined (DEBUG_SESSIONMANAGER)
    10371038            qDebug( "WM_SAVEAPPLICATION: sm_gracefulShutdown=%d "
    1038                     "qt_about_to_destroy_wnd=%d",
    1039                     sm_gracefulShutdown, qt_about_to_destroy_wnd );
    1040 #endif           
     1039                    "qt_about_to_destroy_wnd=%d (mp1=%p mp2=%p)",
     1040                    sm_gracefulShutdown, qt_about_to_destroy_wnd,
     1041                    mp1, mp2 );
     1042#endif
    10411043            // PM seems to post this message to all top-level windows on system
    10421044            // shutdown, so react only to the first one. Also, this message is
    10431045            // always sent by WinDestroyWindow(), where it must be also ignored.
    1044             if ( !sm_gracefulShutdown && !qt_about_to_destroy_wnd ) {
     1046            if ( !qt_about_to_destroy_wnd && !sm_smActive &&
     1047                 !sm_gracefulShutdown ) {
     1048                sm_smActive = TRUE;
    10451049                sm_gracefulShutdown = TRUE;
     1050                sm_blockUserInput = TRUE; // prevent user-interaction outside interaction windows
     1051                sm_cancel = FALSE;
     1052                sm_quitSkipped = FALSE;
     1053                if ( qt_session_manager_self )
     1054                    qApp->commitData( *qt_session_manager_self );
     1055                sm_smActive = FALSE; // session management has been finished
     1056                if ( sm_cancel ) {
     1057                    // Here we try to cancel the Extended XWorkplace shutdown.
     1058                    // If it's XWorkplace who sent us WM_SAVEAPPLICATION, then
     1059                    // it probably passed us non-NULL parameters, so that
     1060                    // mp1 = it's window handle and mp2 = WM_COMMAND code to
     1061                    // cancel the shutdown procedure.
     1062                    HWND shutdownHwnd = HWNDFROMMP(mp1);
     1063                    if ( WinIsWindow( 0, shutdownHwnd ) ) {
     1064                        WinPostMsg( shutdownHwnd, WM_COMMAND, mp2, 0 );
     1065                        // Ensure we will get WM_QUIT anyway, even if xwp was
     1066                        // not that fast to post it yet (we need it to correctly
     1067                        // finish the graceful shutdown procedure)
     1068                        sm_quitSkipped = TRUE;
     1069                    }
     1070                }
     1071                // repost WM_QUIT to ourselves because we might have ignored
     1072                // it in qt_app_canQuit(), so will not get one anymore
     1073                if ( sm_quitSkipped )
     1074                    WinPostMsg( hwnd, WM_QUIT, 0, 0 );
    10461075            }
    10471076            // PMREF recommends to pass it to WinDefWindowProc()
     
    10501079        }
    10511080#endif
    1052        
     1081
    10531082/// @todo (dmik) later
    10541083//    case WM_SETTINGCHANGE:
     
    14341463#if 0
    14351464            qDebug( "WM_ACTIVATE: [%s] %d", widget->name(), SHORT1FROMMP(mp1) );
    1436 #endif           
     1465#endif
    14371466            qApp->pmFocus( widget, SHORT1FROMMP(mp1) );
    14381467            break;
    14391468
    14401469        case WM_SETFOCUS:
    1441 #if 0           
     1470#if 0
    14421471            qDebug( "WM_SETFOCUS: [%s] %s [%s]", widget->name(),
    14431472                    SHORT1FROMMP(mp2) ? "<=" : "=>",
    14441473                    QWidget::find( (HWND)mp1 ) ? QWidget::find( (HWND)mp1 )->name()
    14451474                                               : "{foreign}" );
    1446 #endif           
     1475#endif
    14471476            result = FALSE;
    14481477            if ( !SHORT1FROMMP(mp2) ) {
     
    22782307            SHORT1FROMMP(qmsg.mp2), SHORT2FROMMP(qmsg.mp2) );
    22792308#endif
    2280    
     2309
    22812310    static QPoint pos;                          // window pos (y flipped)
    22822311    static POINTL gpos = { -1, -1 };            // global pos (y flipped)
     
    22882317    // candidate for a double click event
    22892318    static HWND dblClickCandidateWin = 0;
    2290    
     2319
    22912320    if ( sm_blockUserInput ) //block user interaction during session management
    22922321        return TRUE;
     
    23642393        dblClickCandidateWin = 0;
    23652394    }
    2366    
     2395
    23672396    if ( type == QEvent::ContextMenu ) {
    23682397        QPoint g = QPoint( qmsg.ptl.x, qmsg.ptl.y );
     
    24072436        // otherwise the specified window gets it unless it is already under the
    24082437        // pointer. We use this info to check whether the window can be a double
    2409         // click candidate (see above). 
     2438        // click candidate (see above).
    24102439        if ( qmsg.ptl.x == gpos.x && qmsg.ptl.y == gpos.y ) {
    24112440            if ( dblClickCandidateWin != qmsg.hwnd )
     
    25472576        QMouseEvent e( type, pos, QPoint(gpos.x,gpos.y), button, state );
    25482577        QApplication::sendSpontaneousEvent( widget, &e );
    2549        
     2578
    25502579        if ( type != QEvent::MouseMove )
    25512580            pos.rx() = pos.ry() = -9999;        // init for move compression
     
    31153144bool QETWidget::translatePaintEvent( const QMSG & )
    31163145{
    3117     HPS displayPS = qt_display_ps(); 
    3118    
     3146    HPS displayPS = qt_display_ps();
     3147
    31193148#if !defined (QT_PM_NO_WIDGETMASK)
    31203149    // Since we don't use WS_CLIPSIBLINGS and WS_CLIPCHILDREN bits (see
     
    31233152    validateObstacles();
    31243153#endif
    3125    
     3154
    31263155    HRGN hrgn = GpiCreateRegion( displayPS, 0, NULL );
    31273156    LONG rc = WinQueryUpdateRegion( winId(), hrgn );
     
    31613190    }
    31623191#endif
    3163    
     3192
    31643193    // flip y coordinate
    31653194    rcl.yBottom = height() - (rcl.yBottom + rcl.yTop);
     
    32523281            // need to move a non top-level window of a foreign process?).
    32533282            Q_ASSERT( isTopLevel() );
    3254 #endif   
     3283#endif
    32553284            if ( isVisible() ) {
    32563285                QResizeEvent e( newSize, oldSize );
     
    34303459bool qt_app_canQuit()
    34313460{
    3432 #if defined (DEBUG_SESSIONMANAGER)               
     3461#if defined (DEBUG_SESSIONMANAGER)
    34333462    qDebug( "qt_app_canQuit(): sm_smActive=%d qt_about_to_destroy_wnd=%d "
    34343463            "sm_gracefulShutdown=%d sm_cancel=%d",
    34353464            sm_smActive, qt_about_to_destroy_wnd,
    3436             sm_gracefulShutdown, sm_cancel );               
     3465            sm_gracefulShutdown, sm_cancel );
    34373466#endif
    34383467
     
    34433472    // progress. Ignore them.
    34443473    if ( !sm_smActive ) {
    3445         sm_smActive = TRUE;
    3446         sm_blockUserInput = TRUE; // prevent user-interaction outside interaction windows
    3447         sm_cancel = FALSE;
    3448         if ( qt_session_manager_self )
    3449             qApp->commitData( *qt_session_manager_self );
    3450         sm_smActive = FALSE;
    3451         sm_gracefulShutdown = FALSE;
    3452         answer = !sm_cancel;
    3453     }
    3454    
    3455 #if defined (DEBUG_SESSIONMANAGER)               
     3474        if ( sm_gracefulShutdown ) {
     3475            // this is WM_QUIT after WM_SAVEAPPLICATION (either posted by the OS
     3476            // or by ourselves), confirm the quit depending on what the user wants
     3477            sm_quitSkipped = FALSE;
     3478            answer = !sm_cancel;
     3479            if ( sm_cancel ) {
     3480                // the shutdown has been canceled, reset the flag to let the
     3481                // graceful shutdown happen again later
     3482                sm_gracefulShutdown = FALSE;
     3483            }
     3484        } else {
     3485            // sm_gracefulShutdown is FALSE, so allowsInteraction() and friends
     3486            // will return FALSE during commitData() (assuming that WM_QUIT w/o
     3487            // WM_SAVEAPPLICATION is an emergency termination)
     3488            sm_smActive = TRUE;
     3489            sm_blockUserInput = TRUE; // prevent user-interaction outside interaction windows
     3490            sm_cancel = FALSE;
     3491            if ( qt_session_manager_self )
     3492                qApp->commitData( *qt_session_manager_self );
     3493            sm_smActive = FALSE;
     3494            answer = TRUE; // ignore sm_cancel
     3495        }
     3496    } else {
     3497        // if this is a WM_QUIT received during WM_SAVEAPPLICATION handling,
     3498        // remember we've skipped (refused) it
     3499        if ( sm_gracefulShutdown )
     3500            sm_quitSkipped = TRUE;
     3501    }
     3502
     3503#if defined (DEBUG_SESSIONMANAGER)
    34563504    qDebug( "qt_app_canQuit(): answer=%ld", answer );
    34573505#endif
Note: See TracChangeset for help on using the changeset viewer.