8#include <private/qsystemlibrary_p.h>
17#include <private/qthread_p.h>
21#ifndef TIME_KILL_SYNCHRONOUS
22# define TIME_KILL_SYNCHRONOUS 0x0100
26# define QS_RAWINPUT 0x0400
30# define WM_TOUCH 0x0240
34# define WM_GESTURE 0x0119
36#ifndef WM_GESTURENOTIFY
37# define WM_GESTURENOTIFY 0x011A
53#if !defined(DWORD_PTR) && !defined(Q_OS_WIN64)
54#define DWORD_PTR DWORD
61 using namespace std::chrono;
62 auto t = duration_cast<milliseconds>(steady_clock::now().time_since_epoch());
118 switch (WSAGETSELECTEVENT(lp)) {
136 QSNDict *sn_vec[4] = { &
d->sn_read, &
d->sn_write, &
d->sn_except, &
d->sn_read };
141 d->postActivateSocketNotifiers();
147 d->doWsaAsyncSelect(sn->
fd, 0);
150 d->postActivateSocketNotifiers();
154 const long eventCode = WSAGETSELECTEVENT(lp);
155 if ((sd.
mask & eventCode) != eventCode) {
156 sd.
mask |= eventCode;
171 if (!PeekMessage(&msg,
d->internalHwnd,
173 &&
d->queuedSocketEvents.isEmpty()) {
179 d->doWsaAsyncSelect(
it.key(), sd.
event);
186 d->activateNotifiersPosted =
false;
192 if (wp ==
d->sendPostedEventsTimerId)
193 q->sendPostedEvents();
195 d->sendTimerEvent(wp);
204 static const UINT
mask = QS_ALLEVENTS;
205 if (HIWORD(GetQueueStatus(
mask)) == 0)
206 q->sendPostedEvents();
208 d->startPostedEventsTimer();
212 return DefWindowProc(hwnd,
message, wp, lp);
222 USER_TIMER_MINIMUM, NULL);
252 wc.hInstance = GetModuleHandle(0);
255 wc.hbrBackground = 0;
256 wc.lpszMenuName = NULL;
258 atom = RegisterClass(&wc);
269 UnregisterClass(
className, GetModuleHandle(0));
281 HWND wnd = CreateWindow(
ctx->className,
291 qErrnoWarning(
"CreateWindow() for QEventDispatcherWin32 internal window failed");
295 SetWindowLongPtr(wnd, GWLP_USERDATA,
reinterpret_cast<LONG_PTR
>(eventDispatcher));
302 uint interval =
t->interval;
303 ULONG tolerance = TIMERV_DEFAULT_COALESCING;
304 switch (
t->timerType) {
315 if (interval >= 20000) {
317 }
else if (interval <= 20) {
322 tolerance = interval / 20;
333 interval = (interval + 500) / 1000 * 1000;
338 t->interval = interval;
351 uint interval =
t->interval;
352 if (interval == 0u) {
356 }
else if (tolerance == TIMERV_DEFAULT_COALESCING) {
366 ok = SetCoalescableTimer(
internalHwnd,
t->timerId, interval,
nullptr, tolerance);
372 qErrnoWarning(
"QEventDispatcherWin32::registerTimer: Failed to create a timer");
377 if (
t->interval == 0) {
378 QCoreApplicationPrivate::removePostedTimerEvent(
t->dispatcher,
t->timerId);
379 }
else if (
t->fastTimerId != 0) {
380 timeKillEvent(
t->fastTimerId);
381 QCoreApplicationPrivate::removePostedTimerEvent(
t->dispatcher,
t->timerId);
386 if (!
t->inTimerEvent)
393 if (
t && !
t->inTimerEvent) {
404 if (
t->timerId == -1) {
407 t->inTimerEvent =
false;
450#ifndef QT_NO_GESTURES
464 const bool wasInterrupted =
d->interrupt.fetchAndStoreRelaxed(
false);
474 auto threadData =
d->threadData.loadRelaxed();
479 while (!
d->interrupt.loadRelaxed()) {
484 msg =
d->queuedUserInputEvents.takeFirst();
487 msg =
d->queuedSocketEvents.takeFirst();
488 }
else if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
492 d->queuedUserInputEvents.append(msg);
498 d->queuedSocketEvents.append(msg);
501 }
else if (MsgWaitForMultipleObjectsEx(0, NULL, 0, QS_ALLINPUT, MWMO_ALERTABLE)
511 d->startPostedEventsTimer();
516 if (msg.message == WM_TIMER) {
518 if (
d->internalHwnd == msg.hwnd && msg.wParam ==
d->sendPostedEventsTimerId)
523 for (
int i = 0; !found &&
i < processedTimers.
count(); ++
i) {
525 found = (processed.wParam == msg.wParam && processed.hwnd == msg.hwnd && processed.lParam == msg.lParam);
529 processedTimers.
append(msg);
530 }
else if (msg.message == WM_QUIT) {
537 TranslateMessage(&msg);
538 DispatchMessage(&msg);
545 && !
d->interrupt.loadRelaxed()
547 && threadData->canWaitLocked());
550 MsgWaitForMultipleObjectsEx(0, NULL, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE | MWMO_INPUTAVAILABLE);
565 qWarning(
"QEventDispatcherWin32::registerSocketNotifier: invalid socket identifier");
569 qWarning(
"QEventDispatcherWin32: socket notifiers cannot be enabled from another thread");
575 QSNDict *sn_vec[3] = { &
d->sn_read, &
d->sn_write, &
d->sn_except };
582 const char *
t[] = {
"Read",
"Write",
"Exception" };
584 qWarning(
"QSocketNotifier: Multiple socket notifiers for "
585 "same socket %d and type %s", sockfd,
t[
type]);
594 if (
d->sn_read.contains(sockfd))
595 event |= FD_READ | FD_CLOSE | FD_ACCEPT;
596 if (
d->sn_write.contains(sockfd))
597 event |= FD_WRITE | FD_CONNECT;
598 if (
d->sn_except.contains(sockfd))
602 if (
it !=
d->active_fd.end()) {
605 d->doWsaAsyncSelect(sockfd, 0);
618 d->active_fd.insert(sockfd,
QSockFd(
event, FD_READ | FD_CLOSE | FD_ACCEPT | FD_WRITE
619 | FD_CONNECT | FD_OOB));
622 d->postActivateSocketNotifiers();
631 qWarning(
"QEventDispatcherWin32::unregisterSocketNotifier: invalid socket identifier");
635 qWarning(
"QEventDispatcherWin32: socket notifiers cannot be disabled from another thread");
650 if (
it !=
d->active_fd.end()) {
653 d->doWsaAsyncSelect(sockfd, 0);
654 const long event[3] = { FD_READ | FD_CLOSE | FD_ACCEPT, FD_WRITE | FD_CONNECT, FD_OOB };
657 d->active_fd.erase(
it);
660 d->postActivateSocketNotifiers();
664 QSNDict *sn_vec[3] = { &
d->sn_read, &
d->sn_write, &
d->sn_except };
677 if (timerId < 1 || interval < 0 || !
object) {
678 qWarning(
"QEventDispatcherWin32::registerTimer: invalid arguments");
682 qWarning(
"QEventDispatcherWin32::registerTimer: timers cannot be started from another thread");
696 t->timerId = timerId;
697 t->interval = interval;
698 t->timerType = timerType;
700 t->inTimerEvent =
false;
705 d->timerDict.insert(
t->timerId,
t);
712 qWarning(
"QEventDispatcherWin32::unregisterTimer: invalid argument");
716 qWarning(
"QEventDispatcherWin32::unregisterTimer: timers cannot be stopped from another thread");
727 d->unregisterTimer(
t);
735 qWarning(
"QEventDispatcherWin32::unregisterTimers: invalid argument");
739 qWarning(
"QEventDispatcherWin32::unregisterTimers: timers cannot be stopped from another thread");
745 if (
d->timerDict.isEmpty())
748 auto it =
d->timerDict.begin();
749 while (
it !=
d->timerDict.end()) {
752 if (
t->obj ==
object) {
753 it =
d->timerDict.erase(
it);
754 d->unregisterTimer(
t);
767 qWarning(
"QEventDispatcherWin32:registeredTimers: invalid argument");
776 if (
t->obj ==
object)
786 qWarning(
"QEventDispatcherWin32::remainingTime: invalid argument");
802 qWarning(
"QEventDispatcherWin32::remainingTime: timer id %d not found", timerId);
811 if (
d->wakeUps.testAndSetRelaxed(0, 1)) {
814 qErrnoWarning(
"QEventDispatcherWin32::wakeUp: Failed to post a message");
821 d->interrupt.storeRelaxed(
true);
833 while (!
d->sn_read.isEmpty())
835 while (!
d->sn_write.isEmpty())
837 while (!
d->sn_except.isEmpty())
843 d->unregisterTimer(
t);
844 d->timerDict.clear();
846 d->closingDown =
true;
848 if (
d->sendPostedEventsTimerId != 0)
849 KillTimer(
d->internalHwnd,
d->sendPostedEventsTimerId);
850 d->sendPostedEventsTimerId = 0;
861 t->inTimerEvent =
true;
867 if (
t->timerId == -1) {
870 if (
t->interval == 0 &&
t->inTimerEvent) {
875 t->inTimerEvent =
false;
881 d->sendTimerEvent(
static_cast<const QTimerEvent*
>(
e)->timerId());
893 if (
d->sendPostedEventsTimerId != 0)
894 KillTimer(
d->internalHwnd,
d->sendPostedEventsTimerId);
895 d->sendPostedEventsTimerId = 0;
898 d->wakeUps.storeRelaxed(0);
905 return d_func()->internalHwnd;
910#include "moc_qeventdispatcher_win_p.cpp"
DarwinBluetooth::LECBManagerNotifier * notifier
static QAbstractEventDispatcher * instance(QThread *thread=nullptr)
Returns a pointer to the event dispatcher object for the specified thread.
void aboutToBlock()
This signal is emitted before the event loop calls a function that could block.
bool filterNativeEvent(const QByteArray &eventType, void *message, qintptr *result)
Sends message through the event filters that were set by installNativeEventFilter().
void awake()
This signal is emitted after the event loop returns from a function that could block.
void storeRelaxed(T newValue) noexcept
static void sendPostedEvents(QObject *receiver, int event_type, QThreadData *data)
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
static void quit()
\threadsafe
static QCoreApplication * instance() noexcept
Returns a pointer to the application's QCoreApplication (or QGuiApplication/QApplication) instance.
static bool closingDown()
Returns true if the application objects are being destroyed; otherwise returns false.
static void postEvent(QObject *receiver, QEvent *event, int priority=Qt::NormalEventPriority)
void doWsaAsyncSelect(int socket, long event)
bool activateNotifiersPosted
void sendTimerEvent(int timerId)
~QEventDispatcherWin32Private()
void registerTimer(WinTimerInfo *t)
UINT_PTR sendPostedEventsTimerId
void postActivateSocketNotifiers()
void unregisterTimer(WinTimerInfo *t)
void startPostedEventsTimer()
QEventDispatcherWin32Private()
void interrupt() override
Interrupts event dispatching.
void closingDown() override
bool QT_ENSURE_STACK_ALIGNED_FOR_SSE processEvents(QEventLoop::ProcessEventsFlags flags) override
Processes pending events that match flags until there are no more events to process.
virtual void sendPostedEvents()
bool unregisterTimer(int timerId) override
Unregisters the timer with the given timerId.
void startingUp() override
QList< TimerInfo > registeredTimers(QObject *object) const override
Returns a list of registered timers for object.
QEventDispatcherWin32(QObject *parent=nullptr)
bool unregisterTimers(QObject *object) override
Unregisters all the timers associated with the given object.
void wakeUp() override
\threadsafe
int remainingTime(int timerId) override
Returns the remaining time in milliseconds with the given timerId.
void doUnregisterSocketNotifier(QSocketNotifier *notifier)
void registerTimer(int timerId, qint64 interval, Qt::TimerType timerType, QObject *object) override
Register a timer with the specified timerId, interval, and timerType for the given object.
void registerSocketNotifier(QSocketNotifier *notifier) override
Registers notifier with the event loop.
void unregisterSocketNotifier(QSocketNotifier *notifier) override
Unregisters notifier from the event dispatcher.
bool event(QEvent *e) override
This virtual function receives events to an object and should return true if the event e was recogniz...
bool remove(const Key &key)
Removes the item that has the key from the hash.
bool contains(const Key &key) const noexcept
Returns true if the hash contains an item with the key; otherwise returns false.
T value(const Key &key) const noexcept
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
virtual bool event(QEvent *event)
This virtual function receives events to an object and should return true if the event e was recogniz...
QThread * thread() const
Returns the thread in which the object lives.
\macro QT_RESTRICTED_CAST_FROM_ASCII
qsizetype toWCharArray(wchar_t *array) const
qsizetype size() const
Returns the number of characters in this string.
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
static QThread * currentThread()
int timerId() const
Returns the unique timer identifier, which is the same identifier as returned from QObject::startTime...
const T * constData() const
QSet< QString >::iterator it
void qErrnoWarning(const char *msg,...)
Combined button and popup list for selecting options.
#define QByteArrayLiteral(str)
static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatcher)
LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
static quint64 qt_msectime()
#define TIME_KILL_SYNCHRONOUS
@ SendPostedEventsTimerId
void WINAPI QT_WIN_CALLBACK qt_fast_timer_proc(uint timerId, uint, DWORD_PTR user, DWORD_PTR, DWORD_PTR)
@ WM_QT_ACTIVATENOTIFIERS
static bool isUserInputMessage(UINT message)
static ULONG calculateNextTimeout(WinTimerInfo *t, quint64 currentTime)
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
GLuint GLsizei const GLchar * message
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLdouble GLdouble GLdouble GLdouble q
#define qUtf16Printable(string)
#define QStringLiteral(str)
unsigned long long quint64
static double currentTime()
const char className[16]
[1]
~QWindowsMessageWindowClassContext()
QWindowsMessageWindowClassContext()
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent