--- src/kernel/qapplication_x11.cpp +++ src/kernel/qapplication_x11.cpp @@ -3972,7 +3972,7 @@ // Keyboard event translation // -static int translateButtonState( int s ) +int qt_x11_translateButtonState( int s ) { int bst = 0; if ( s & Button1Mask ) @@ -4038,7 +4038,7 @@ pos.ry() = lastMotion.y; globalPos.rx() = lastMotion.x_root; globalPos.ry() = lastMotion.y_root; - state = translateButtonState( lastMotion.state ); + state = qt_x11_translateButtonState( lastMotion.state ); if ( qt_button_down && (state & (LeftButton | MidButton | RightButton ) ) == 0 ) @@ -4062,7 +4062,7 @@ pos.ry() = xevent->xcrossing.y; globalPos.rx() = xevent->xcrossing.x_root; globalPos.ry() = xevent->xcrossing.y_root; - state = translateButtonState( xevent->xcrossing.state ); + state = qt_x11_translateButtonState( xevent->xcrossing.state ); if ( qt_button_down && (state & (LeftButton | MidButton | RightButton ) ) == 0 ) @@ -4074,7 +4074,7 @@ pos.ry() = event->xbutton.y; globalPos.rx() = event->xbutton.x_root; globalPos.ry() = event->xbutton.y_root; - state = translateButtonState( event->xbutton.state ); + state = qt_x11_translateButtonState( event->xbutton.state ); switch ( event->xbutton.button ) { case Button1: button = LeftButton; break; case Button2: button = MidButton; break; @@ -5020,7 +5020,7 @@ XKeyEvent xkeyevent = event->xkey; // save the modifier state, we will use the keystate uint later by passing - // it to translateButtonState + // it to qt_x11_translateButtonState uint keystate = event->xkey.state; // remove the modifiers where mode_switch exists... HPUX machines seem // to have alt *AND* mode_switch both in Mod1Mask, which causes @@ -5134,7 +5134,7 @@ } #endif // !QT_NO_XIM - state = translateButtonState( keystate ); + state = qt_x11_translateButtonState( keystate ); static int directionKeyEvent = 0; if ( qt_use_rtl_extensions && type == QEvent::KeyRelease ) { --- src/kernel/qdnd_x11.cpp +++ src/kernel/qdnd_x11.cpp @@ -115,6 +115,8 @@ Atom qt_xdnd_type_list; const int qt_xdnd_version = 4; +extern int qt_x11_translateButtonState( int s ); + // Actions // // The Xdnd spec allows for user-defined actions. This could be implemented @@ -199,6 +201,8 @@ static int qt_xdnd_current_screen = -1; // state of dragging... true if dragging, false if not bool qt_xdnd_dragging = FALSE; +// need to check state of keyboard modifiers +static bool need_modifiers_check = FALSE; // dict of payload data, sorted by type atom static QIntDict * qt_xdnd_target_data = 0; @@ -887,8 +891,20 @@ void QDragManager::timerEvent( QTimerEvent* e ) { - if ( e->timerId() == heartbeat && qt_xdnd_source_sameanswer.isNull() ) - move( QCursor::pos() ); + if ( e->timerId() == heartbeat ) { + if( need_modifiers_check ) { + Window root, child; + int root_x, root_y, win_x, win_y; + unsigned int mask; + XQueryPointer( qt_xdisplay(), qt_xrootwin( qt_xdnd_current_screen ), + &root, &child, &root_x, &root_y, &win_x, &win_y, &mask ); + if( updateMode( (ButtonState)qt_x11_translateButtonState( mask ))) + qt_xdnd_source_sameanswer = QRect(); // force move + } + need_modifiers_check = TRUE; + if( qt_xdnd_source_sameanswer.isNull() ) + move( QCursor::pos() ); + } } static bool qt_xdnd_was_move = false; @@ -956,6 +972,7 @@ updateMode(me->stateAfter()); move( me->globalPos() ); } + need_modifiers_check = FALSE; return TRUE; } else if ( e->type() == QEvent::MouseButtonRelease ) { qApp->removeEventFilter( this ); @@ -994,9 +1011,11 @@ beingCancelled = FALSE; qApp->exit_loop(); } else { - updateMode(ke->stateAfter()); - qt_xdnd_source_sameanswer = QRect(); // force move - move( QCursor::pos() ); + if( updateMode(ke->stateAfter())) { + qt_xdnd_source_sameanswer = QRect(); // force move + move( QCursor::pos() ); + } + need_modifiers_check = FALSE; } return TRUE; // Eat all key events } @@ -1023,10 +1042,10 @@ static Qt::ButtonState oldstate; -void QDragManager::updateMode( ButtonState newstate ) +bool QDragManager::updateMode( ButtonState newstate ) { if ( newstate == oldstate ) - return; + return false; const int both = ShiftButton|ControlButton; if ( (newstate & both) == both ) { global_requested_action = QDropEvent::Link; @@ -1050,6 +1069,7 @@ } } oldstate = newstate; + return true; } @@ -1754,6 +1774,7 @@ qt_xdnd_source_sameanswer = QRect(); move(QCursor::pos()); heartbeat = startTimer(200); + need_modifiers_check = FALSE; #ifndef QT_NO_CURSOR qApp->setOverrideCursor( arrowCursor ); --- src/kernel/qdragobject.h +++ src/kernel/qdragobject.h @@ -249,7 +249,7 @@ private: QDragObject * object; - void updateMode( ButtonState newstate ); + bool updateMode( ButtonState newstate ); void updateCursor(); #if defined(Q_WS_X11) void createCursors();