]>
Commit | Line | Data |
---|---|---|
c37e4a41 AM |
1 | commit 1095252559a937efcaaf012d8dfbb4e13c4fd6b5 |
2 | Author: John Stanley <jpsinthemix@verizon.net> | |
3 | Date: Tue Jan 17 20:04:59 2012 -0500 | |
4 | ||
5 | Pass events to installed event dispatcher event filters before passing them to x11ProcessEvent() | |
6 | ||
7 | Change-Id: If551c732b520b0105a3d4578db1b039c1b5d49fd | |
8 | ||
9 | Pass events to eventFilter first | |
10 | ||
11 | Change-Id: If551c732b520b0105a3d4578db1b039c1b5d49fd | |
12 | Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com> | |
13 | ||
14 | diff --git a/src/gui/kernel/qclipboard_x11.cpp b/src/gui/kernel/qclipboard_x11.cpp | |
15 | index 803b1ba..72110ed 100644 | |
16 | --- a/src/gui/kernel/qclipboard_x11.cpp | |
17 | +++ b/src/gui/kernel/qclipboard_x11.cpp | |
18 | @@ -579,7 +579,10 @@ bool QX11Data::clipboardWaitForEvent(Window win, int type, XEvent *event, int ti | |
19 | ||
20 | // process other clipboard events, since someone is probably requesting data from us | |
21 | XEvent e; | |
22 | - if (XCheckIfEvent(X11->display, &e, checkForClipboardEvents, 0)) | |
23 | + // Pass the event through the event dispatcher filter so that applications | |
24 | + // which install an event filter on the dispatcher get to handle it first. | |
25 | + if (XCheckIfEvent(X11->display, &e, checkForClipboardEvents, 0) && | |
26 | + !QAbstractEventDispatcher::instance()->filterEvent(&e)) | |
27 | qApp->x11ProcessEvent(&e); | |
28 | ||
29 | now.start(); | |
30 | diff --git a/src/gui/kernel/qdnd_x11.cpp b/src/gui/kernel/qdnd_x11.cpp | |
31 | index 2b14743..d2050d1 100644 | |
32 | --- a/src/gui/kernel/qdnd_x11.cpp | |
33 | +++ b/src/gui/kernel/qdnd_x11.cpp | |
34 | @@ -42,6 +42,7 @@ | |
35 | #include "qplatformdefs.h" | |
36 | ||
37 | #include "qapplication.h" | |
38 | +#include "qabstracteventdispatcher.h" | |
39 | ||
40 | #ifndef QT_NO_DRAGANDDROP | |
41 | ||
42 | @@ -1967,7 +1968,10 @@ Qt::DropAction QDragManager::drag(QDrag * o) | |
43 | timer.start(); | |
44 | do { | |
45 | XEvent event; | |
46 | - if (XCheckTypedEvent(X11->display, ClientMessage, &event)) | |
47 | + // Pass the event through the event dispatcher filter so that applications | |
48 | + // which install an event filter on the dispatcher get to handle it first. | |
49 | + if (XCheckTypedEvent(X11->display, ClientMessage, &event) && | |
50 | + !QAbstractEventDispatcher::instance()->filterEvent(&event)) | |
51 | qApp->x11ProcessEvent(&event); | |
52 | ||
53 | // sleep 50 ms, so we don't use up CPU cycles all the time. | |
54 | diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp | |
55 | index 4cdd6e7..3cff3ee 100644 | |
56 | --- a/src/gui/kernel/qwidget_x11.cpp | |
57 | +++ b/src/gui/kernel/qwidget_x11.cpp | |
58 | @@ -44,6 +44,7 @@ | |
59 | #include "qdesktopwidget.h" | |
60 | #include "qapplication.h" | |
61 | #include "qapplication_p.h" | |
62 | +#include "qabstracteventdispatcher.h" | |
63 | #include "qnamespace.h" | |
64 | #include "qpainter.h" | |
65 | #include "qbitmap.h" | |
66 | @@ -376,17 +377,21 @@ void qt_x11_wait_for_window_manager(QWidget *w, bool sendPostedEvents) | |
67 | do { | |
68 | if (XEventsQueued(X11->display, QueuedAlready)) { | |
69 | XNextEvent(X11->display, &ev); | |
70 | - qApp->x11ProcessEvent(&ev); | |
71 | - | |
72 | - switch (state) { | |
73 | - case Initial: | |
74 | - if (ev.type == MapNotify && ev.xany.window == winid) | |
75 | - state = Mapped; | |
76 | - break; | |
77 | - case Mapped: | |
78 | - if (ev.type == Expose && ev.xany.window == winid) | |
79 | - return; | |
80 | - break; | |
81 | + // Pass the event through the event dispatcher filter so that applications | |
82 | + // which install an event filter on the dispatcher get to handle it first. | |
83 | + if (!QAbstractEventDispatcher::instance()->filterEvent(&ev)) { | |
84 | + qApp->x11ProcessEvent(&ev); | |
85 | + | |
86 | + switch (state) { | |
87 | + case Initial: | |
88 | + if (ev.type == MapNotify && ev.xany.window == winid) | |
89 | + state = Mapped; | |
90 | + break; | |
91 | + case Mapped: | |
92 | + if (ev.type == Expose && ev.xany.window == winid) | |
93 | + return; | |
94 | + break; | |
95 | + } | |
96 | } | |
97 | } else { | |
98 | if (!XEventsQueued(X11->display, QueuedAfterFlush)) | |
99 | commit 69ada23a75bb51b4efc90c6128cce22d5ee6a779 | |
100 | Author: John Stanley <jpsinthemix@verizon.net> | |
101 | Date: Tue Jan 17 20:04:55 2012 -0500 | |
102 | ||
103 | When doing mouse move compression, pass non-MotionNotify events to installed event dispatcher event filters | |
104 | ||
105 | Change-Id: Ia71f23458b9a6bc728f3e05592f530e317ae453c | |
106 | Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com> | |
107 | ||
108 | diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp | |
109 | index 256db7d..4d642a9 100644 | |
110 | --- a/src/gui/kernel/qapplication_x11.cpp | |
111 | +++ b/src/gui/kernel/qapplication_x11.cpp | |
112 | @@ -4234,7 +4234,10 @@ bool QETWidget::translateMouseEvent(const XEvent *event) | |
113 | && (nextEvent.xclient.message_type == ATOM(_QT_SCROLL_DONE) || | |
114 | (nextEvent.xclient.message_type == ATOM(WM_PROTOCOLS) && | |
115 | (Atom)nextEvent.xclient.data.l[0] == ATOM(_NET_WM_SYNC_REQUEST))))) { | |
116 | - qApp->x11ProcessEvent(&nextEvent); | |
117 | + // Pass the event through the event dispatcher filter so that applications | |
118 | + // which install an event filter on the dispatcher get to handle it first. | |
119 | + if (!QAbstractEventDispatcher::instance()->filterEvent(&nextEvent)) | |
120 | + qApp->x11ProcessEvent(&nextEvent); | |
121 | continue; | |
122 | } else if (nextEvent.type != MotionNotify || | |
123 | nextEvent.xmotion.window != event->xmotion.window || | |
124 | commit 6bab6fccd2d8ee8e83e968864d729c1bbee39a66 | |
125 | Author: John Stanley <jpsinthemix@verizon.net> | |
126 | Date: Mon Jan 30 07:27:49 2012 -0500 | |
127 | ||
128 | Raise loopLevel for deleteLater in event filters | |
129 | ||
130 | Change-Id: I163f510f6e99d86a35cc78965fa383e7f4618f42 | |
131 | Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com> | |
132 | ||
133 | diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp | |
134 | index 3f73e61..3b0a258 100644 | |
135 | --- a/src/corelib/kernel/qabstracteventdispatcher.cpp | |
136 | +++ b/src/corelib/kernel/qabstracteventdispatcher.cpp | |
137 | @@ -532,8 +532,12 @@ QAbstractEventDispatcher::EventFilter QAbstractEventDispatcher::setEventFilter(E | |
138 | bool QAbstractEventDispatcher::filterEvent(void *message) | |
139 | { | |
140 | Q_D(QAbstractEventDispatcher); | |
141 | - if (d->event_filter) | |
142 | + if (d->event_filter) { | |
143 | + // Raise the loopLevel so that deleteLater() calls in or triggered | |
144 | + // by event_filter() will be processed from the main event loop. | |
145 | + QScopedLoopLevelCounter loopLevelCounter(d->threadData); | |
146 | return d->event_filter(message); | |
147 | + } | |
148 | return false; | |
149 | } | |
150 | ||
151 | diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h | |
152 | index 9b71d02..bb90de7 100644 | |
153 | --- a/src/corelib/thread/qthread_p.h | |
154 | +++ b/src/corelib/thread/qthread_p.h | |
155 | @@ -238,6 +238,17 @@ public: | |
156 | # endif | |
157 | }; | |
158 | ||
159 | +class QScopedLoopLevelCounter | |
160 | +{ | |
161 | + QThreadData *threadData; | |
162 | +public: | |
163 | + inline QScopedLoopLevelCounter(QThreadData *threadData) | |
164 | + : threadData(threadData) | |
165 | + { ++threadData->loopLevel; } | |
166 | + inline ~QScopedLoopLevelCounter() | |
167 | + { --threadData->loopLevel; } | |
168 | +}; | |
169 | + | |
170 | // thread wrapper for the main() thread | |
171 | class QAdoptedThread : public QThread | |
172 | { | |
173 | diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h | |
174 | index 9acf2c8..31d0b75 100644 | |
175 | --- a/src/gui/kernel/qapplication_p.h | |
176 | +++ b/src/gui/kernel/qapplication_p.h | |
177 | @@ -277,17 +277,6 @@ typedef struct tagGESTURECONFIG | |
178 | ||
179 | #endif // Q_WS_WIN | |
180 | ||
181 | -class QScopedLoopLevelCounter | |
182 | -{ | |
183 | - QThreadData *threadData; | |
184 | -public: | |
185 | - QScopedLoopLevelCounter(QThreadData *threadData) | |
186 | - : threadData(threadData) | |
187 | - { ++threadData->loopLevel; } | |
188 | - ~QScopedLoopLevelCounter() | |
189 | - { --threadData->loopLevel; } | |
190 | -}; | |
191 | - | |
192 | typedef QHash<QByteArray, QFont> FontHash; | |
193 | FontHash *qt_app_fonts_hash(); | |
194 | ||
195 | commit 26f1ca8681db995e82c0f4c0fa9363c842520700 | |
196 | Author: Shane Kearns <shane.kearns@accenture.com> | |
197 | Date: Mon Dec 19 15:10:45 2011 +0000 | |
198 | ||
199 | Handle plain socket write errors in SSL | |
200 | ||
201 | When an ssl socket is closed during connecting, and it is using a proxy | |
202 | then it is possible for the plain socket to be in pending close state | |
203 | when transmit() is called. | |
204 | As errors were not handled, this caused the socket (and https request) | |
205 | to "hang". | |
206 | It now propagates the error from plain socket. | |
207 | ||
208 | Change-Id: I6fb86815a2a63e197cea582f4b153e487543477c | |
209 | Reviewed-by: Peter Hartmann <peter.hartmann@nokia.com> | |
210 | Reviewed-by: Richard J. Moore <rich@kde.org> | |
211 | Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> | |
212 | (cherry picked from commit 2cc78885b0b7d08f965998d156945a077e56c1d8) | |
213 | ||
214 | diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp | |
215 | index 872b19c..900bfdb 100644 | |
216 | --- a/src/network/ssl/qsslsocket_openssl.cpp | |
217 | +++ b/src/network/ssl/qsslsocket_openssl.cpp | |
218 | @@ -1044,10 +1044,17 @@ void QSslSocketBackendPrivate::transmit() | |
219 | int encryptedBytesRead = q_BIO_read(writeBio, data.data(), pendingBytes); | |
220 | ||
221 | // Write encrypted data from the buffer to the socket. | |
222 | - plainSocket->write(data.constData(), encryptedBytesRead); | |
223 | + qint64 actualWritten = plainSocket->write(data.constData(), encryptedBytesRead); | |
224 | #ifdef QSSLSOCKET_DEBUG | |
225 | - qDebug() << "QSslSocketBackendPrivate::transmit: wrote" << encryptedBytesRead << "encrypted bytes to the socket"; | |
226 | + qDebug() << "QSslSocketBackendPrivate::transmit: wrote" << encryptedBytesRead << "encrypted bytes to the socket" << actualWritten << "actual."; | |
227 | #endif | |
228 | + if (actualWritten < 0) { | |
229 | + //plain socket write fails if it was in the pending close state. | |
230 | + q->setErrorString(plainSocket->errorString()); | |
231 | + q->setSocketError(plainSocket->error()); | |
232 | + emit q->error(plainSocket->error()); | |
233 | + return; | |
234 | + } | |
235 | transmitting = true; | |
236 | } | |
237 | ||
238 | commit 33179842341fcf7d42e74f62a600470aed6b08a1 | |
239 | Author: Shane Kearns <ext-shane.2.kearns@nokia.com> | |
240 | Date: Mon Jan 30 15:52:27 2012 +0000 | |
241 | ||
242 | Prevent data loss when an ssl socket is closed by remote | |
243 | ||
244 | SSL context was destroyed on disconnect. This makes it impossible to | |
245 | decrypt buffered encrypted data. So if there is encrypted data in the | |
246 | receive buffers, then don't destroy the ssl context until the socket is | |
247 | destroyed. | |
248 | ||
249 | Task-Number: QTBUG-23607 | |
250 | Change-Id: I16a7b4fa006647ec73049c90cdbc72686696850f | |
251 | Reviewed-by: Jonas Gastal <jgastal@profusion.mobi> | |
252 | Reviewed-by: Richard J. Moore <rich@kde.org> | |
253 | (cherry picked from commit c5aba0ac17ae6ed8f3847bd30325acdbd1ecaa80) | |
254 | ||
255 | diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp | |
256 | index 25d1d9e..5b1cd1b 100644 | |
257 | --- a/src/network/ssl/qsslsocket_openssl.cpp | |
258 | +++ b/src/network/ssl/qsslsocket_openssl.cpp | |
259 | @@ -183,6 +183,7 @@ QSslSocketBackendPrivate::QSslSocketBackendPrivate() | |
260 | ||
261 | QSslSocketBackendPrivate::~QSslSocketBackendPrivate() | |
262 | { | |
263 | + destroySslContext(); | |
264 | } | |
265 | ||
266 | QSslCipher QSslSocketBackendPrivate::QSslCipher_from_SSL_CIPHER(SSL_CIPHER *cipher) | |
267 | @@ -483,6 +484,22 @@ init_context: | |
268 | return true; | |
269 | } | |
270 | ||
271 | +void QSslSocketBackendPrivate::destroySslContext() | |
272 | +{ | |
273 | + if (ssl) { | |
274 | + q_SSL_free(ssl); | |
275 | + ssl = 0; | |
276 | + } | |
277 | + if (ctx) { | |
278 | + q_SSL_CTX_free(ctx); | |
279 | + ctx = 0; | |
280 | + } | |
281 | + if (pkey) { | |
282 | + q_EVP_PKEY_free(pkey); | |
283 | + pkey = 0; | |
284 | + } | |
285 | +} | |
286 | + | |
287 | /*! | |
288 | \internal | |
289 | */ | |
290 | @@ -1403,19 +1420,10 @@ void QSslSocketBackendPrivate::disconnectFromHost() | |
291 | ||
292 | void QSslSocketBackendPrivate::disconnected() | |
293 | { | |
294 | - if (ssl) { | |
295 | - q_SSL_free(ssl); | |
296 | - ssl = 0; | |
297 | - } | |
298 | - if (ctx) { | |
299 | - q_SSL_CTX_free(ctx); | |
300 | - ctx = 0; | |
301 | - } | |
302 | - if (pkey) { | |
303 | - q_EVP_PKEY_free(pkey); | |
304 | - pkey = 0; | |
305 | - } | |
306 | - | |
307 | + if (plainSocket->bytesAvailable() <= 0) | |
308 | + destroySslContext(); | |
309 | + //if there is still buffered data in the plain socket, don't destroy the ssl context yet. | |
310 | + //it will be destroyed when the socket is deleted. | |
311 | } | |
312 | ||
313 | QSslCipher QSslSocketBackendPrivate::sessionCipher() const | |
314 | diff --git a/src/network/ssl/qsslsocket_openssl_p.h b/src/network/ssl/qsslsocket_openssl_p.h | |
315 | index bad2c9c..2940480 100644 | |
316 | --- a/src/network/ssl/qsslsocket_openssl_p.h | |
317 | +++ b/src/network/ssl/qsslsocket_openssl_p.h | |
318 | @@ -99,6 +99,7 @@ public: | |
319 | ||
320 | // SSL context | |
321 | bool initSslContext(); | |
322 | + void destroySslContext(); | |
323 | SSL *ssl; | |
324 | SSL_CTX *ctx; | |
325 | EVP_PKEY *pkey; | |
326 | commit 6a91b3bcdf1b5e491aa8531579c4e62fcc794d6e | |
327 | Author: Albert Astals Cid <aacid@kde.org> | |
328 | Date: Tue Jan 10 16:00:48 2012 +0100 | |
329 | ||
330 | Check for the clipboard manager when looping due to app quiting | |
331 | ||
332 | One can be extremely unlucky and on session logout get this: | |
333 | * All apps are going down | |
334 | * A Qt app checks if the clipboard manager is there to yield its clipboard contents | |
335 | * The clipboard manager is still there | |
336 | * Then just after that check, the clipboard manager finishes because of the session end | |
337 | * This means the Qt app will loop for 5 seconds trying to yield its clipboard contents | |
338 | to a clipboard manager that is not there anymore | |
339 | This is a backport of 689c4009fb9be348f9137a9092b068e056a3d8b3 in the qtbase (Qt 5.0) repo | |
340 | ||
341 | Change-Id: I8ab1f460aa5936c03f1afc1b6ff18824f1d6cbc1 | |
342 | Reviewed-by: Lars Knoll <lars.knoll@nokia.com> | |
343 | ||
344 | diff --git a/src/gui/kernel/qclipboard_x11.cpp b/src/gui/kernel/qclipboard_x11.cpp | |
345 | index 7990f5d..803b1ba 100644 | |
346 | --- a/src/gui/kernel/qclipboard_x11.cpp | |
347 | +++ b/src/gui/kernel/qclipboard_x11.cpp | |
348 | @@ -515,7 +515,7 @@ static Bool checkForClipboardEvents(Display *, XEvent *e, XPointer) | |
349 | || e->xselectionclear.selection == ATOM(CLIPBOARD)))); | |
350 | } | |
351 | ||
352 | -bool QX11Data::clipboardWaitForEvent(Window win, int type, XEvent *event, int timeout) | |
353 | +bool QX11Data::clipboardWaitForEvent(Window win, int type, XEvent *event, int timeout, bool checkManager) | |
354 | { | |
355 | QElapsedTimer started; | |
356 | started.start(); | |
357 | @@ -544,6 +544,9 @@ bool QX11Data::clipboardWaitForEvent(Window win, int type, XEvent *event, int ti | |
358 | return true; | |
359 | } | |
360 | ||
361 | + if (checkManager && XGetSelectionOwner(X11->display, ATOM(CLIPBOARD_MANAGER)) == XNone) | |
362 | + return false; | |
363 | + | |
364 | XSync(X11->display, false); | |
365 | usleep(50000); | |
366 | ||
367 | @@ -571,6 +574,9 @@ bool QX11Data::clipboardWaitForEvent(Window win, int type, XEvent *event, int ti | |
368 | if (XCheckTypedWindowEvent(X11->display,win,type,event)) | |
369 | return true; | |
370 | ||
371 | + if (checkManager && XGetSelectionOwner(X11->display, ATOM(CLIPBOARD_MANAGER)) == XNone) | |
372 | + return false; | |
373 | + | |
374 | // process other clipboard events, since someone is probably requesting data from us | |
375 | XEvent e; | |
376 | if (XCheckIfEvent(X11->display, &e, checkForClipboardEvents, 0)) | |
377 | @@ -933,7 +939,7 @@ bool QClipboard::event(QEvent *e) | |
378 | ||
379 | XEvent event; | |
380 | // waiting until the clipboard manager fetches the content. | |
381 | - if (!X11->clipboardWaitForEvent(ownerId, SelectionNotify, &event, 10000)) { | |
382 | + if (!X11->clipboardWaitForEvent(ownerId, SelectionNotify, &event, 10000, true)) { | |
383 | qWarning("QClipboard: Unable to receive an event from the " | |
384 | "clipboard manager in a reasonable time"); | |
385 | } | |
386 | diff --git a/src/gui/kernel/qt_x11_p.h b/src/gui/kernel/qt_x11_p.h | |
387 | index bdca019..ed7c146 100644 | |
388 | --- a/src/gui/kernel/qt_x11_p.h | |
389 | +++ b/src/gui/kernel/qt_x11_p.h | |
390 | @@ -350,7 +350,7 @@ struct QX11Data | |
391 | Window findClientWindow(Window, Atom, bool); | |
392 | ||
393 | // from qclipboard_x11.cpp | |
394 | - bool clipboardWaitForEvent(Window win, int type, XEvent *event, int timeout); | |
395 | + bool clipboardWaitForEvent(Window win, int type, XEvent *event, int timeout, bool checkManager = false); | |
396 | bool clipboardReadProperty(Window win, Atom property, bool deleteProperty, | |
397 | QByteArray *buffer, int *size, Atom *type, int *format); | |
398 | QByteArray clipboardReadIncrementalProperty(Window win, Atom property, int nbytes, bool nullterm); |