Annotation of /trunk/qt/patches/0001-dnd_optimization.patch
Parent Directory | Revision Log
Revision 153 -
(hide annotations)
(download)
Tue May 8 20:52:56 2007 UTC (17 years, 4 months ago) by niro
File size: 5623 byte(s)
Tue May 8 20:52:56 2007 UTC (17 years, 4 months ago) by niro
File size: 5623 byte(s)
-import
1 | niro | 153 | qt-bugs@ issue : 16115 |
2 | applied: no | ||
3 | author: Lubos Lunak <l.lunak@kde.org> | ||
4 | |||
5 | See http://lists.kde.org/?t=104388858900001&r=1&w=2 | ||
6 | |||
7 | |||
8 | --- src/kernel/qdnd_x11.cpp.sav 2003-02-05 16:09:45.000000000 +0100 | ||
9 | +++ src/kernel/qdnd_x11.cpp 2003-02-07 16:14:49.000000000 +0100 | ||
10 | @@ -49,13 +49,15 @@ | ||
11 | #include "qdragobject.h" | ||
12 | #include "qobjectlist.h" | ||
13 | #include "qcursor.h" | ||
14 | +#include "qbitmap.h" | ||
15 | +#include "qpainter.h" | ||
16 | |||
17 | #include "qt_x11_p.h" | ||
18 | |||
19 | // conflict resolution | ||
20 | |||
21 | -// unused, may be used again later: const int XKeyPress = KeyPress; | ||
22 | -// unused, may be used again later: const int XKeyRelease = KeyRelease; | ||
23 | +const int XKeyPress = KeyPress; | ||
24 | +const int XKeyRelease = KeyRelease; | ||
25 | #undef KeyPress | ||
26 | #undef KeyRelease | ||
27 | |||
28 | @@ -249,20 +251,47 @@ class QShapedPixmapWidget : public QWidg | ||
29 | public: | ||
30 | QShapedPixmapWidget(int screen = -1) : | ||
31 | QWidget(QApplication::desktop()->screen( screen ), | ||
32 | - 0, WStyle_Customize | WStyle_Tool | WStyle_NoBorder | WX11BypassWM ) | ||
33 | + 0, WStyle_Customize | WStyle_Tool | WStyle_NoBorder | WX11BypassWM ), oldpmser( 0 ), oldbmser( 0 ) | ||
34 | { | ||
35 | } | ||
36 | |||
37 | - void setPixmap(QPixmap pm) | ||
38 | + void setPixmap(QPixmap pm, QPoint hot) | ||
39 | { | ||
40 | - if ( pm.mask() ) { | ||
41 | + int bmser = pm.mask() ? pm.mask()->serialNumber() : 0; | ||
42 | + if( oldpmser == pm.serialNumber() && oldbmser == bmser | ||
43 | + && oldhot == hot ) | ||
44 | + return; | ||
45 | + oldpmser = pm.serialNumber(); | ||
46 | + oldbmser = bmser; | ||
47 | + oldhot = hot; | ||
48 | + bool hotspot_in = !(hot.x() < 0 || hot.y() < 0 || hot.x() >= pm.width() || hot.y() >= pm.height()); | ||
49 | +// if the pixmap has hotspot in its area, make a "hole" in it at that position | ||
50 | +// this will allow XTranslateCoordinates() to find directly the window below the cursor instead | ||
51 | +// of finding this pixmap, and therefore there won't be needed any (slow) search for the window | ||
52 | +// using findRealWindow() | ||
53 | + if( hotspot_in ) { | ||
54 | + QBitmap mask = pm.mask() ? *pm.mask() : QBitmap( pm.width(), pm.height()); | ||
55 | + if( !pm.mask()) | ||
56 | + mask.fill( Qt::color1 ); | ||
57 | + QPainter p( &mask ); | ||
58 | + p.setPen( Qt::color0 ); | ||
59 | + p.drawPoint( hot.x(), hot.y()); | ||
60 | + p.end(); | ||
61 | + pm.setMask( mask ); | ||
62 | + setMask( mask ); | ||
63 | + } else if ( pm.mask() ) { | ||
64 | setMask( *pm.mask() ); | ||
65 | } else { | ||
66 | clearMask(); | ||
67 | } | ||
68 | resize(pm.width(),pm.height()); | ||
69 | setErasePixmap(pm); | ||
70 | + erase(); | ||
71 | } | ||
72 | +private: | ||
73 | + int oldpmser; | ||
74 | + int oldbmser; | ||
75 | + QPoint oldhot; | ||
76 | }; | ||
77 | |||
78 | QShapedPixmapWidget * qt_xdnd_deco = 0; | ||
79 | @@ -859,6 +888,45 @@ void QDragManager::timerEvent( QTimerEve | ||
80 | move( QCursor::pos() ); | ||
81 | } | ||
82 | |||
83 | +static bool qt_xdnd_was_move = false; | ||
84 | +static bool qt_xdnd_found = false; | ||
85 | +// check whole incoming X queue for move events | ||
86 | +// checking whole queue is done by always returning False in the predicate | ||
87 | +// if there's another move event in the queue, and there's not a mouse button | ||
88 | +// or keyboard or ClientMessage event before it, the current move event | ||
89 | +// may be safely discarded | ||
90 | +// this helps avoiding being overloaded by being flooded from many events | ||
91 | +// from the XServer | ||
92 | +static | ||
93 | +Bool qt_xdnd_predicate( Display*, XEvent* ev, XPointer ) | ||
94 | +{ | ||
95 | + if( qt_xdnd_found ) | ||
96 | + return False; | ||
97 | + if( ev->type == MotionNotify ) | ||
98 | + { | ||
99 | + qt_xdnd_was_move = true; | ||
100 | + qt_xdnd_found = true; | ||
101 | + } | ||
102 | + if( ev->type == ButtonPress || ev->type == ButtonRelease | ||
103 | + || ev->type == XKeyPress || ev->type == XKeyRelease | ||
104 | + || ev->type == ClientMessage ) | ||
105 | + { | ||
106 | + qt_xdnd_was_move = false; | ||
107 | + qt_xdnd_found = true; | ||
108 | + } | ||
109 | + return False; | ||
110 | +} | ||
111 | + | ||
112 | +static | ||
113 | +bool qt_xdnd_another_movement() | ||
114 | +{ | ||
115 | + qt_xdnd_was_move = false; | ||
116 | + qt_xdnd_found = false; | ||
117 | + XEvent dummy; | ||
118 | + XCheckIfEvent( qt_xdisplay(), &dummy, qt_xdnd_predicate, NULL ); | ||
119 | + return qt_xdnd_was_move; | ||
120 | +} | ||
121 | + | ||
122 | bool QDragManager::eventFilter( QObject * o, QEvent * e) | ||
123 | { | ||
124 | if ( beingCancelled ) { | ||
125 | @@ -881,8 +949,10 @@ bool QDragManager::eventFilter( QObject | ||
126 | |||
127 | if ( e->type() == QEvent::MouseMove ) { | ||
128 | QMouseEvent* me = (QMouseEvent *)e; | ||
129 | - updateMode(me->stateAfter()); | ||
130 | - move( me->globalPos() ); | ||
131 | + if( !qt_xdnd_another_movement()) { | ||
132 | + updateMode(me->stateAfter()); | ||
133 | + move( me->globalPos() ); | ||
134 | + } | ||
135 | return TRUE; | ||
136 | } else if ( e->type() == QEvent::MouseButtonRelease ) { | ||
137 | qApp->removeEventFilter( this ); | ||
138 | @@ -1106,7 +1176,7 @@ void QDragManager::move( const QPoint & | ||
139 | delete qt_xdnd_deco; | ||
140 | qt_xdnd_deco = new QShapedPixmapWidget( screen ); | ||
141 | } | ||
142 | - updatePixmap(); | ||
143 | + updatePixmap( globalPos ); | ||
144 | |||
145 | if ( qt_xdnd_source_sameanswer.contains( globalPos ) && | ||
146 | qt_xdnd_source_sameanswer.isValid() ) { | ||
147 | @@ -1679,7 +1749,7 @@ bool QDragManager::drag( QDragObject * o | ||
148 | // qt_xdnd_source_object persists until we get an xdnd_finish message | ||
149 | } | ||
150 | |||
151 | -void QDragManager::updatePixmap() | ||
152 | +void QDragManager::updatePixmap( const QPoint& cursorPos ) | ||
153 | { | ||
154 | if ( qt_xdnd_deco ) { | ||
155 | QPixmap pm; | ||
156 | @@ -1694,9 +1764,8 @@ void QDragManager::updatePixmap() | ||
157 | defaultPm = new QPixmap(default_pm); | ||
158 | pm = *defaultPm; | ||
159 | } | ||
160 | - qt_xdnd_deco->setPixmap(pm); | ||
161 | - qt_xdnd_deco->move(QCursor::pos()-pm_hot); | ||
162 | - qt_xdnd_deco->repaint(FALSE); | ||
163 | + qt_xdnd_deco->setPixmap(pm, pm_hot); | ||
164 | + qt_xdnd_deco->move(cursorPos-pm_hot); | ||
165 | //if ( willDrop ) { | ||
166 | qt_xdnd_deco->show(); | ||
167 | //} else { | ||
168 | @@ -1705,4 +1774,9 @@ void QDragManager::updatePixmap() | ||
169 | } | ||
170 | } | ||
171 | |||
172 | +void QDragManager::updatePixmap() | ||
173 | +{ | ||
174 | + updatePixmap( QCursor::pos()); | ||
175 | +} | ||
176 | + | ||
177 | #endif // QT_NO_DRAGANDDROP | ||
178 | --- src/kernel/qdragobject.h.sav 2002-11-01 19:25:07.000000000 +0100 | ||
179 | +++ src/kernel/qdragobject.h 2001-01-01 01:01:00.000000000 +0100 | ||
180 | @@ -245,6 +245,7 @@ private: | ||
181 | void move( const QPoint & ); | ||
182 | void drop(); | ||
183 | void updatePixmap(); | ||
184 | + void updatePixmap( const QPoint& cursorPos ); | ||
185 | |||
186 | private: | ||
187 | QDragObject * object; |