summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
authorAlex Trotsenko <alex1973tr@gmail.com>2015-12-05 23:55:17 +0200
committerAlex Trotsenko <alex1973tr@gmail.com>2016-01-05 13:05:35 +0000
commit02f70004c266f4c35f098f49cfb3ca0284e28cac (patch)
tree7aa683c0716aa64860e4d7f5d9c63bc5ae65b4b8 /src/corelib/kernel
parente0a5f661e52fd09611f406ae82128b6ef81fe90e (diff)
Allow socket events processing with a foreign event loop on Windows
While a native dialog is open, the application message queue is handled by the native event loop which is external to Qt. In this case, QEventDispatcherWin32::processEvents() does not run and socket notifiers will not be activated. So, this patch moves the notifier activation code into the window procedure, which enables socket event processing with native dialogs. Task-number: QTBUG-49782 Task-number: QTBUG-48901 Change-Id: Icbdd96b2e80c50b73505f4fe74957575b83d6cf1 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> Reviewed-by: Kai Koehne <kai.koehne@theqtcompany.com> Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp44
-rw-r--r--src/corelib/kernel/qeventdispatcher_win_p.h2
2 files changed, 33 insertions, 13 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index 695eb3d5d0..812494372d 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -79,6 +79,7 @@ extern uint qGlobalPostedEventsCount();
enum {
WM_QT_SOCKETNOTIFIER = WM_USER,
WM_QT_SENDPOSTEDEVENTS = WM_USER + 1,
+ WM_QT_ACTIVATENOTIFIERS = WM_USER + 2,
SendPostedEventsWindowsTimerId = ~1u
};
@@ -309,7 +310,7 @@ static void resolveTimerAPI()
QEventDispatcherWin32Private::QEventDispatcherWin32Private()
: threadId(GetCurrentThreadId()), interrupt(false), closingDown(false), internalHwnd(0),
getMessageHook(0), serialNumber(0), lastSerialNumber(0), sendPostedEventsWindowsTimerId(0),
- wakeUps(0)
+ wakeUps(0), activateNotifiersPosted(false)
{
resolveTimerAPI();
}
@@ -393,6 +394,7 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA
if (sn) {
d->doWsaAsyncSelect(sn->fd, 0);
d->active_fd[sn->fd].selected = false;
+ d->postActivateSocketNotifiers();
if (type < 3) {
QEvent event(QEvent::SockAct);
QCoreApplication::sendEvent(sn->obj, &event);
@@ -403,6 +405,20 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA
}
}
return 0;
+ } else if (message == WM_QT_ACTIVATENOTIFIERS) {
+ Q_ASSERT(d != 0);
+
+ // register all socket notifiers
+ for (QSFDict::iterator it = d->active_fd.begin(), end = d->active_fd.end();
+ it != end; ++it) {
+ QSockFd &sd = it.value();
+ if (!sd.selected) {
+ d->doWsaAsyncSelect(it.key(), sd.event);
+ sd.selected = true;
+ }
+ }
+ d->activateNotifiersPosted = false;
+ return 0;
} else if (message == WM_QT_SENDPOSTEDEVENTS
// we also use a Windows timer to send posted events when the message queue is full
|| (message == WM_TIMER
@@ -643,6 +659,12 @@ void QEventDispatcherWin32Private::doWsaAsyncSelect(int socket, long event)
WSAAsyncSelect(socket, internalHwnd, event ? int(WM_QT_SOCKETNOTIFIER) : 0, event);
}
+void QEventDispatcherWin32Private::postActivateSocketNotifiers()
+{
+ if (!activateNotifiersPosted)
+ activateNotifiersPosted = PostMessage(internalHwnd, WM_QT_ACTIVATENOTIFIERS, 0, 0);
+}
+
void QEventDispatcherWin32::createInternalHwnd()
{
Q_D(QEventDispatcherWin32);
@@ -761,16 +783,6 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
d->queuedSocketEvents.append(msg);
continue;
}
- } else if (!(flags & QEventLoop::ExcludeSocketNotifiers)) {
- // register all socket notifiers
- for (QSFDict::iterator it = d->active_fd.begin(), end = d->active_fd.end();
- it != end; ++it) {
- QSockFd &sd = it.value();
- if (!sd.selected) {
- d->doWsaAsyncSelect(it.key(), sd.event);
- sd.selected = true;
- }
- }
}
}
if (!haveMessage) {
@@ -891,6 +903,8 @@ void QEventDispatcherWin32::registerSocketNotifier(QSocketNotifier *notifier)
"same socket %d and type %s", sockfd, t[type]);
}
+ createInternalHwnd();
+
QSockNot *sn = new QSockNot;
sn->obj = notifier;
sn->fd = sockfd;
@@ -915,6 +929,8 @@ void QEventDispatcherWin32::registerSocketNotifier(QSocketNotifier *notifier)
} else {
d->active_fd.insert(sockfd, QSockFd(event));
}
+
+ d->postActivateSocketNotifiers();
}
void QEventDispatcherWin32::unregisterSocketNotifier(QSocketNotifier *notifier)
@@ -940,10 +956,12 @@ void QEventDispatcherWin32::unregisterSocketNotifier(QSocketNotifier *notifier)
d->doWsaAsyncSelect(sockfd, 0);
const long event[3] = { FD_READ | FD_CLOSE | FD_ACCEPT, FD_WRITE | FD_CONNECT, FD_OOB };
sd.event ^= event[type];
- if (sd.event == 0)
+ if (sd.event == 0) {
d->active_fd.erase(it);
- else
+ } else if (sd.selected) {
sd.selected = false;
+ d->postActivateSocketNotifiers();
+ }
}
QSNDict *sn_vec[3] = { &d->sn_read, &d->sn_write, &d->sn_except };
diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h
index 8578110ee4..9a53e06730 100644
--- a/src/corelib/kernel/qeventdispatcher_win_p.h
+++ b/src/corelib/kernel/qeventdispatcher_win_p.h
@@ -178,7 +178,9 @@ public:
QSNDict sn_write;
QSNDict sn_except;
QSFDict active_fd;
+ bool activateNotifiersPosted;
void doWsaAsyncSelect(int socket, long event);
+ void postActivateSocketNotifiers();
QList<QWinEventNotifier *> winEventNotifierList;
void activateEventNotifier(QWinEventNotifier * wen);