Contents of /trunk/qt/patches/0001-dnd_optimization.patch
Parent Directory | Revision Log
Revision 153 -
(show 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 | 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; |