Changeset 52


Ignore:
Timestamp:
Jan 15, 2006, 10:51:59 PM (20 years ago)
Author:
dmik
Message:

Fixed [PM misbehavior]: MouseButtonDblClick messages were delivered to a widget even if it didn't receive the preceeding MouseButtonRelease; as a result, QWorkplace and QTitleBar sysmenu handlers didn't allow to click an MDI widget using a double click on a sysmenu icon.

File:
1 edited

Legend:

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

    r8 r52  
    11861186        if ( qApp->activePopupWidget() != 0 ) { // in popup mode
    11871187            QWidget* w = QApplication::widgetAt( qmsg.ptl.x, qmsg.ptl.y, TRUE );
    1188             if ( w )
     1188            if ( w ) {
     1189                POINTL ptl = { SHORT1FROMMP(qmsg.mp1), SHORT2FROMMP(qmsg.mp1) };
     1190                WinMapWindowPoints( qmsg.hwnd, w->winId(), &ptl, 1 );
     1191                qmsg.mp1 = MPFROM2SHORT( ptl.x, ptl.y );
    11891192                widget = (QETWidget*)w;
     1193            }
    11901194        }
    11911195        result = widget->translateMouseEvent( qmsg );
     
    24542458bool QETWidget::translateMouseEvent( const QMSG &qmsg )
    24552459{
     2460#if 0
     2461    static const char *msgNames[] = { // 11 items
     2462        "WM_MOUSEMOVE",
     2463        "WM_BUTTON1DOWN", "WM_BUTTON1UP", "WM_BUTTON1DBLCLK",
     2464        "WM_BUTTON2DOWN", "WM_BUTTON2UP", "WM_BUTTON2DBLCLK",
     2465        "WM_BUTTON3DOWN", "WM_BUTTON3UP", "WM_BUTTON3DBLCLK",
     2466        "WM_???"
     2467    };
     2468    int msgIdx = qmsg.msg - WM_MOUSEMOVE;
     2469    if (msgIdx < 0 || msgIdx > 9)
     2470        msgIdx = 10;
     2471    qDebug( "%s (%04lX): [%08lX/%p:%s/%s] %04hd,%04hd hit=%04hX fl=%04hX",
     2472            msgNames[msgIdx], qmsg.msg, qmsg.hwnd, this, name(), className(),
     2473            SHORT1FROMMP(qmsg.mp1), SHORT2FROMMP(qmsg.mp1),
     2474            SHORT1FROMMP(qmsg.mp2), SHORT2FROMMP(qmsg.mp2) );
     2475#endif
     2476   
    24562477    static QPoint pos;                          // window pos (y flipped)
    24572478    static POINTL gpos = { -1, -1 };            // global pos (y flipped)
     
    24612482    int    i;
    24622483
     2484    // candidate for a double click event
     2485    static HWND dblClickCandidateWin = 0;
     2486   
    24632487//@@TODO (dmik): later
    24642488//    if ( sm_blockUserInput ) //block user interaction during session management
     
    25152539    state  = translateButtonState( SHORT2FROMMP(qmsg.mp2), type, button ); // button state
    25162540
     2541    // It seems, that PM remembers only the WM_BUTTONxDOWN message (instead of
     2542    // the WM_BUTTONxDOWN + WM_BUTTONxUP pair) to detect whether the next button
     2543    // press should be converted to WM_BUTTONxDBLCLK or not. As a result, the
     2544    // window gets WM_BUTTONxDBLCLK even if it didn't receive the preceeding
     2545    // WM_BUTTONxUP (this happens if we issue WinSetCapture() on the first
     2546    // WM_BUTTONxDOWN), which is obviously wrong and makes problems for QWorkspace
     2547    // and QTitleBar system menu handlers that don't expect a double click after
     2548    // they opened a popup menu. dblClickCandidateWin is reset to 0 (see a ***
     2549    // remmark below) when WinSetCapture is issued that directs messages
     2550    // to a window other than one received the first WM_BUTTONxDOWN,
     2551    // so we can fix it here.  Note that if there is more than one popup window,
     2552    // WinSetCapture is issued only for the first of them, so this code doesn't
     2553    // prevent MouseButtonDblClick from being delivered to a popup when another
     2554    // popup gets closed on the first WM_BUTTONxDOWN (Qt/Win32 behaves in the
     2555    // same way, so it's left for compatibility).
     2556    if ( type == QEvent::MouseButtonPress ) {
     2557        dblClickCandidateWin = qmsg.hwnd;
     2558    } else if ( type == QEvent::MouseButtonDblClick ) {
     2559        if ( dblClickCandidateWin != qmsg.hwnd )
     2560            type = QEvent::MouseButtonPress;
     2561        dblClickCandidateWin = 0;
     2562    }
     2563   
    25172564    if ( type == QEvent::ContextMenu ) {
    25182565        QPoint g = QPoint( qmsg.ptl.x, qmsg.ptl.y );
     
    25512598        }
    25522599
    2553         // PM sends WM_MOUSEMOVE on every WM_BUTTONxDOWN/WM_BUTTONxUP even if
    2554         // the pointer hasn't actually changed its position, to give us a chance
    2555         // to update the pointer shape. Here we already did it, but there's no
    2556         // need to send the duplicate mouse move events across Qt.
    2557         if ( qmsg.ptl.x == gpos.x && qmsg.ptl.y == gpos.y )
     2600        // *** PM posts a dummy WM_MOUSEMOVE message (with the same, uncahnged
     2601        // pointer coordinates) after every WinSetCapture that actually changes
     2602        // the capture target. I.e., if the argument of WinSetCapture is
     2603        // NULLHANDLE, a window under the mouse pointer gets this message,
     2604        // otherwise the specified window gets it unless it is already under the
     2605        // pointer. We use this info to check whether the window can be a double
     2606        // click candidate (see above).
     2607        if ( qmsg.ptl.x == gpos.x && qmsg.ptl.y == gpos.y ) {
     2608            if ( dblClickCandidateWin != qmsg.hwnd )
     2609                dblClickCandidateWin = 0;
    25582610            return TRUE;
     2611        }
    25592612
    25602613        gpos = qmsg.ptl;
     
    26412694                popupButtonFocus = 0;
    26422695            }
    2643         } else if ( popupChild ){
     2696        } else if ( popupChild ) {
    26442697            QMouseEvent e( type,
    26452698                popupChild->mapFromGlobal(QPoint(gpos.x,gpos.y)),
     
    26482701        } else {
    26492702            QMouseEvent e( type, pos, QPoint(gpos.x,gpos.y), button, state );
    2650             QApplication::sendSpontaneousEvent( popupChild ? popupChild : popup, &e );
     2703            QApplication::sendSpontaneousEvent( popup, &e );
    26512704        }
    26522705
     
    26592712            // the popup dissappeared. Replay the event
    26602713            QWidget* w = QApplication::widgetAt( gpos.x, gpos.y, TRUE );
    2661             if (w && !qt_blocked_modal( w ) ) {
    2662 //@@TODO (dmik): do we need this? guess not
    2663 //              if ( QWidget::mouseGrabber() == 0 )
    2664 //                  setAutoCapture( w->winId() );
    2665 
     2714            if ( w && !qt_blocked_modal( w ) ) {
    26662715                QPoint wpos = w->mapFromGlobal(QPoint(gpos.x, gpos.y));
    26672716                // flip y coordinate
    26682717                wpos.ry() = w->height() - (wpos.y() + 1);
    2669                 MPARAM mp1 = MPFROM2SHORT( wpos.x(), wpos.y() );
    2670                 WinPostMsg( w->winId(), qmsg.msg, mp1, qmsg.mp2 );
     2718                QMSG newQmsg = qmsg;
     2719                newQmsg.hwnd = w->winId();
     2720                newQmsg.mp1 = MPFROM2SHORT( wpos.x(), wpos.y() );
     2721                ((QETWidget *) w)->translateMouseEvent( newQmsg );
    26712722            }
    26722723        }
     
    26932744        QMouseEvent e( type, pos, QPoint(gpos.x,gpos.y), button, state );
    26942745        QApplication::sendSpontaneousEvent( widget, &e );
    2695 //@@TODO (dmik): remove, context menu events are sent through WM_CONTEXTMENU
    2696 //      if ( type == QEvent::MouseButtonRelease && button == RightButton ) {
    2697 //          QContextMenuEvent e2( QContextMenuEvent::Mouse, pos, QPoint(gpos.x,gpos.y), state );
    2698 //          QApplication::sendSpontaneousEvent( widget, &e2 );
    2699 //      }
    2700 
     2746       
    27012747        if ( type != QEvent::MouseMove )
    27022748            pos.rx() = pos.ry() = -9999;        // init for move compression
Note: See TracChangeset for help on using the changeset viewer.