Magellan Linux

Annotation of /trunk/qt/patches/0002-dnd_active_window_fix.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 153 - (hide annotations) (download)
Tue May 8 20:52:56 2007 UTC (17 years, 1 month ago) by niro
File size: 7289 byte(s)
-import

1 niro 153 qt-bugs@ issue : 25122
2     applied: no
3     author: Lubos Lunak <l.lunak@kde.org>
4    
5     Hello,
6    
7     for example: Open Konqueror window, showing some files. Start dragging one
8     desktop icon. If you press/release Ctrl, there'll be a '+' attached to the
9     icon, showing the DND operation. Now, while still doing DND, make the
10     Konqueror window active (Alt+Tab with KDE-3.1.2+, hover over its taskbar
11     entry, Ctrl+Fn to switch to a different virtual desktop, etc.). As soon as
12     the app performing DND is not the active application, and the mouse is not
13     moving, pressing/releasing Ctrl doesn't do anything, the state only updates
14     when the mouse is moved.
15    
16     This is caused by the fact that Qt has only pointer grab when doing DND, but
17     doesn't have keyboard grab. I actually consider this a good thing, because
18     the only keys important for DND are modifiers, and they come together with
19     pointer events, and not having keyboard grab allows using keyboard shortcuts
20     like Alt+Tab while DND. However, when the mouse is not moved, and only a
21     modifier key is pressed/released, the app won't get any mouse event, and
22     won't also get the keyboard event.
23    
24     The attached patch changes Qt to explicitly check the modifiers state using
25     XQueryPointer() if there's wasn't recently any mouse/keyboard event, which
26     ensures the state is updated even in the situation described above.
27    
28     --- src/kernel/qapplication_x11.cpp.sav 2003-06-21 12:31:35.000000000 +0200
29     +++ src/kernel/qapplication_x11.cpp 2003-06-21 12:35:44.000000000 +0200
30     @@ -4053,7 +4053,7 @@ void QApplication::closePopup( QWidget *
31     // Keyboard event translation
32     //
33    
34     -static int translateButtonState( int s )
35     +int qt_x11_translateButtonState( int s )
36     {
37     int bst = 0;
38     if ( s & Button1Mask )
39     @@ -4119,7 +4119,7 @@ bool QETWidget::translateMouseEvent( con
40     pos.ry() = lastMotion.y;
41     globalPos.rx() = lastMotion.x_root;
42     globalPos.ry() = lastMotion.y_root;
43     - state = translateButtonState( lastMotion.state );
44     + state = qt_x11_translateButtonState( lastMotion.state );
45     if ( qt_button_down && (state & (LeftButton |
46     MidButton |
47     RightButton ) ) == 0 )
48     @@ -4143,7 +4143,7 @@ bool QETWidget::translateMouseEvent( con
49     pos.ry() = xevent->xcrossing.y;
50     globalPos.rx() = xevent->xcrossing.x_root;
51     globalPos.ry() = xevent->xcrossing.y_root;
52     - state = translateButtonState( xevent->xcrossing.state );
53     + state = qt_x11_translateButtonState( xevent->xcrossing.state );
54     if ( qt_button_down && (state & (LeftButton |
55     MidButton |
56     RightButton ) ) == 0 )
57     @@ -4155,7 +4155,7 @@ bool QETWidget::translateMouseEvent( con
58     pos.ry() = event->xbutton.y;
59     globalPos.rx() = event->xbutton.x_root;
60     globalPos.ry() = event->xbutton.y_root;
61     - state = translateButtonState( event->xbutton.state );
62     + state = qt_x11_translateButtonState( event->xbutton.state );
63     switch ( event->xbutton.button ) {
64     case Button1: button = LeftButton; break;
65     case Button2: button = MidButton; break;
66     @@ -4950,7 +4950,7 @@ bool QETWidget::translateKeyEventInterna
67     XKeyEvent xkeyevent = event->xkey;
68    
69     // save the modifier state, we will use the keystate uint later by passing
70     - // it to translateButtonState
71     + // it to qt_x11_translateButtonState
72     uint keystate = event->xkey.state;
73     // remove the modifiers where mode_switch exists... HPUX machines seem
74     // to have alt *AND* mode_switch both in Mod1Mask, which causes
75     @@ -5064,7 +5064,7 @@ bool QETWidget::translateKeyEventInterna
76     }
77     #endif // !QT_NO_XIM
78    
79     - state = translateButtonState( keystate );
80     + state = qt_x11_translateButtonState( keystate );
81    
82     static int directionKeyEvent = 0;
83     if ( qt_use_rtl_extensions && type == QEvent::KeyRelease ) {
84     --- src/kernel/qdnd_x11.cpp.sav 2003-06-30 15:26:42.000000000 +0200
85     +++ src/kernel/qdnd_x11.cpp 2003-06-30 15:32:23.000000000 +0200
86     @@ -114,6 +114,8 @@ Atom qt_xdnd_finished;
87     Atom qt_xdnd_type_list;
88     const int qt_xdnd_version = 4;
89    
90     +extern int qt_x11_translateButtonState( int s );
91     +
92     // Actions
93     //
94     // The Xdnd spec allows for user-defined actions. This could be implemented
95     @@ -198,6 +200,8 @@ static Atom qt_xdnd_source_current_time;
96     static int qt_xdnd_current_screen = -1;
97     // state of dragging... true if dragging, false if not
98     bool qt_xdnd_dragging = FALSE;
99     +// need to check state of keyboard modifiers
100     +static bool need_modifiers_check = FALSE;
101    
102     // dict of payload data, sorted by type atom
103     static QIntDict<QByteArray> * qt_xdnd_target_data = 0;
104     @@ -879,8 +883,20 @@ void qt_handle_xdnd_finished( QWidget *,
105    
106     void QDragManager::timerEvent( QTimerEvent* e )
107     {
108     - if ( e->timerId() == heartbeat && qt_xdnd_source_sameanswer.isNull() )
109     - move( QCursor::pos() );
110     + if ( e->timerId() == heartbeat ) {
111     + if( need_modifiers_check ) {
112     + Window root, child;
113     + int root_x, root_y, win_x, win_y;
114     + unsigned int mask;
115     + XQueryPointer( qt_xdisplay(), qt_xrootwin( qt_xdnd_current_screen ),
116     + &root, &child, &root_x, &root_y, &win_x, &win_y, &mask );
117     + if( updateMode( (ButtonState)qt_x11_translateButtonState( mask )))
118     + qt_xdnd_source_sameanswer = QRect(); // force move
119     + }
120     + need_modifiers_check = TRUE;
121     + if( qt_xdnd_source_sameanswer.isNull() )
122     + move( QCursor::pos() );
123     + }
124     }
125    
126     static bool qt_xdnd_was_move = false;
127     @@ -948,6 +964,7 @@ bool QDragManager::eventFilter( QObject
128     updateMode(me->stateAfter());
129     move( me->globalPos() );
130     }
131     + need_modifiers_check = FALSE;
132     return TRUE;
133     } else if ( e->type() == QEvent::MouseButtonRelease ) {
134     qApp->removeEventFilter( this );
135     @@ -986,9 +1003,11 @@ bool QDragManager::eventFilter( QObject
136     beingCancelled = FALSE;
137     qApp->exit_loop();
138     } else {
139     - updateMode(ke->stateAfter());
140     - qt_xdnd_source_sameanswer = QRect(); // force move
141     - move( QCursor::pos() );
142     + if( updateMode(ke->stateAfter())) {
143     + qt_xdnd_source_sameanswer = QRect(); // force move
144     + move( QCursor::pos() );
145     + }
146     + need_modifiers_check = FALSE;
147     }
148     return TRUE; // Eat all key events
149     }
150     @@ -1014,10 +1033,10 @@ bool QDragManager::eventFilter( QObject
151    
152    
153     static Qt::ButtonState oldstate;
154     -void QDragManager::updateMode( ButtonState newstate )
155     +bool QDragManager::updateMode( ButtonState newstate )
156     {
157     if ( newstate == oldstate )
158     - return;
159     + return false;
160     const int both = ShiftButton|ControlButton;
161     if ( (newstate & both) == both ) {
162     global_requested_action = QDropEvent::Link;
163     @@ -1041,6 +1060,7 @@ void QDragManager::updateMode( ButtonSta
164     }
165     }
166     oldstate = newstate;
167     + return true;
168     }
169    
170    
171     @@ -1707,6 +1727,7 @@ bool QDragManager::drag( QDragObject * o
172     qt_xdnd_source_sameanswer = QRect();
173     move(QCursor::pos());
174     heartbeat = startTimer(200);
175     + need_modifiers_check = FALSE;
176    
177     #ifndef QT_NO_CURSOR
178     qApp->setOverrideCursor( arrowCursor );
179     --- src/kernel/qdragobject.h.sav 2003-05-19 22:34:43.000000000 +0200
180     +++ src/kernel/qdragobject.h 2001-01-01 01:01:00.000000000 +0100
181     @@ -248,7 +248,7 @@ private:
182    
183     private:
184     QDragObject * object;
185     - void updateMode( ButtonState newstate );
186     + bool updateMode( ButtonState newstate );
187     void updateCursor();
188    
189     QWidget * dragSource;