From 692cd5a0bb0882d7f1c9f0bb79a98ae4f22a6c2b Mon Sep 17 00:00:00 2001 From: James Tabor Date: Fri, 21 Nov 2014 03:15:27 +0000 Subject: [PATCH] [NtUser] - Synchronize mouse messages. Best way to do this, just post the move message while it occurs and just update it with recurrent information. The other way was to check time stamps and that was a hackish headache. Then the scorn and reticule would erupt. So it was easier to just post to the queue, update and if a mouse down up was captured than it would be in the order as it was received. - See CORE-8779 #resolve, CORE-8394, CORE-7797, CORE-7447. svn path=/trunk/; revision=65440 --- reactos/win32ss/user/ntuser/message.c | 11 --- reactos/win32ss/user/ntuser/msgqueue.c | 130 ++++++++----------------- reactos/win32ss/user/ntuser/msgqueue.h | 9 -- reactos/win32ss/user/ntuser/timer.c | 2 +- 4 files changed, 40 insertions(+), 112 deletions(-) diff --git a/reactos/win32ss/user/ntuser/message.c b/reactos/win32ss/user/ntuser/message.c index c7786b4939b..e705a8ffa7a 100644 --- a/reactos/win32ss/user/ntuser/message.c +++ b/reactos/win32ss/user/ntuser/message.c @@ -858,17 +858,6 @@ co_IntPeekMessage( PMSG Msg, return TRUE; } - if ((ProcessMask & QS_MOUSE) && - co_MsqPeekMouseMove( pti, - RemoveMessages, - Window, - MsgFilterMin, - MsgFilterMax, - Msg )) - { - return TRUE; - } - /* Check for hardware events. */ if ((ProcessMask & QS_INPUT) && co_MsqPeekHardwareMessage( pti, diff --git a/reactos/win32ss/user/ntuser/msgqueue.c b/reactos/win32ss/user/ntuser/msgqueue.c index e82ca127a15..7550aa31adc 100644 --- a/reactos/win32ss/user/ntuser/msgqueue.c +++ b/reactos/win32ss/user/ntuser/msgqueue.c @@ -37,44 +37,6 @@ MsqInitializeImpl(VOID) return(STATUS_SUCCESS); } -PWND FASTCALL -IntChildrenWindowFromPoint(PWND pWndTop, INT x, INT y) -{ - PWND pWnd, pWndChild; - - if ( !pWndTop ) - { - pWndTop = UserGetDesktopWindow(); - if ( !pWndTop ) return NULL; - } - - if (!(pWndTop->style & WS_VISIBLE)) return NULL; - if ((pWndTop->style & WS_DISABLED)) return NULL; - if (!IntPtInWindow(pWndTop, x, y)) return NULL; - - if (RECTL_bPointInRect(&pWndTop->rcClient, x, y)) - { - for (pWnd = pWndTop->spwndChild; - pWnd != NULL; - pWnd = pWnd->spwndNext) - { - if (pWnd->state2 & WNDS2_INDESTROY || pWnd->state & WNDS_DESTROYED ) - { - TRACE("The Window is in DESTROY!\n"); - continue; - } - - pWndChild = IntChildrenWindowFromPoint(pWnd, x, y); - - if (pWndChild) - { - return pWndChild; - } - } - } - return pWndTop; -} - PWND FASTCALL IntTopLevelWindowFromPoint(INT x, INT y) { @@ -446,9 +408,16 @@ ClearMsgBitsMask(PTHREADINFO pti, UINT MessageBits) } if (MessageBits & QS_MOUSEMOVE) // ReactOS hard coded. { // Account for tracking mouse moves.. - if (--pti->nCntsQBits[QSRosMouseMove] == 0) ClrMask |= QS_MOUSEMOVE; + if (pti->nCntsQBits[QSRosMouseMove]) + { + pti->nCntsQBits[QSRosMouseMove] = 0; // Throttle down count. Up to > 3:1 entries are ignored. + } // Handle mouse move bits here. - if (Queue->MouseMoved) ClrMask |= QS_MOUSEMOVE; + if (Queue->MouseMoved) + { + ClrMask |= QS_MOUSEMOVE; + Queue->MouseMoved = FALSE; + } } if (MessageBits & QS_MOUSEBUTTON) { @@ -502,12 +471,34 @@ MsqDecPaintCountQueue(PTHREADINFO pti) ClearMsgBitsMask(pti, QS_PAINT); } +/* + Post Mouse Move. + */ VOID FASTCALL MsqPostMouseMove(PTHREADINFO pti, MSG* Msg) { - pti->MessageQueue->MouseMoveMsg = *Msg; - pti->MessageQueue->MouseMoved = TRUE; - MsqWakeQueue(pti, QS_MOUSEMOVE, TRUE); + PUSER_MESSAGE Message; + PLIST_ENTRY ListHead; + PUSER_MESSAGE_QUEUE MessageQueue = pti->MessageQueue; + + ListHead = &MessageQueue->HardwareMessagesListHead; + + MessageQueue->MouseMoved = TRUE; + + if (!IsListEmpty(ListHead->Flink)) + { // Look at the end of the list, + Message = CONTAINING_RECORD(ListHead->Blink, USER_MESSAGE, ListEntry); + // If the mouse move message is existing, + if (Message->Msg.message == WM_MOUSEMOVE) + { + TRACE("Post Old MM Message in Q\n"); + Message->Msg = *Msg; // Overwrite the message with updated data! + MsqWakeQueue(pti, QS_MOUSEMOVE, TRUE); + return; + } + } + TRACE("Post New MM Message to Q\n"); + MsqPostMessage(pti, Msg, TRUE, QS_MOUSEMOVE, 0); } VOID FASTCALL @@ -581,14 +572,15 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook { pti = pwnd->head.pti; MessageQueue = pti->MessageQueue; - // MessageQueue->ptiMouse = pti; - if ( pti->TIF_flags & TIF_INCLEANUP || MessageQueue->QF_flags & QF_INDESTROY) + if (MessageQueue->QF_flags & QF_INDESTROY) { - ERR("Mouse is over the Window Thread is Dead!\n"); + ERR("Mouse is over a Window with a Dead Message Queue!\n"); return; } + MessageQueue->ptiMouse = pti; + if (Msg->message == WM_MOUSEMOVE) { /* Check if cursor should be visible */ @@ -642,6 +634,7 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook { // ERR("ptiLastInput is set\n"); // ptiLastInput = pti; // Once this is set during Reboot or Shutdown, this prevents the exit window having foreground. + // Find all the Move Mouse calls and fix mouse set active focus issues...... } TRACE("Posting mouse message to hwnd=%p!\n", UserHMGetHandle(pwnd)); MsqPostMessage(pti, Msg, TRUE, QS_MOUSEBUTTON, 0); @@ -1677,51 +1670,6 @@ BOOL co_IntProcessHardwareMessage(MSG* Msg, BOOL* RemoveMessages, UINT first, UI return TRUE; } -BOOL APIENTRY -co_MsqPeekMouseMove(IN PTHREADINFO pti, - IN BOOL Remove, - IN PWND Window, - IN UINT MsgFilterLow, - IN UINT MsgFilterHigh, - OUT MSG* pMsg) -{ - BOOL AcceptMessage; - MSG msg; - PUSER_MESSAGE_QUEUE MessageQueue = pti->MessageQueue; - - if(!(MessageQueue->MouseMoved)) - return FALSE; - - if (!MessageQueue->ptiSysLock) - { - MessageQueue->ptiSysLock = pti; - pti->pcti->CTI_flags |= CTI_THREADSYSLOCK; - } - - if (MessageQueue->ptiSysLock != pti) - { - ERR("MsqPeekMouseMove: Thread Q is locked to another pti!\n"); - return FALSE; - } - - msg = MessageQueue->MouseMoveMsg; - - AcceptMessage = co_IntProcessMouseMessage(&msg, &Remove, MsgFilterLow, MsgFilterHigh); - - if(AcceptMessage) - *pMsg = msg; - - if(Remove) - { - ClearMsgBitsMask(pti, QS_MOUSEMOVE); - MessageQueue->MouseMoved = FALSE; - } - - MessageQueue->ptiSysLock = NULL; - pti->pcti->CTI_flags &= ~CTI_THREADSYSLOCK; - return AcceptMessage; -} - /* check whether a message filter contains at least one potential hardware message */ static INT FASTCALL filter_contains_hw_range( UINT first, UINT last ) diff --git a/reactos/win32ss/user/ntuser/msgqueue.h b/reactos/win32ss/user/ntuser/msgqueue.h index e2882f84cbc..61f52279e3d 100644 --- a/reactos/win32ss/user/ntuser/msgqueue.h +++ b/reactos/win32ss/user/ntuser/msgqueue.h @@ -54,8 +54,6 @@ typedef struct _USER_MESSAGE_QUEUE /* True if a WM_MOUSEMOVE is pending */ BOOLEAN MouseMoved; /* Current WM_MOUSEMOVE message */ - MSG MouseMoveMsg; - /* Last click message for translating double clicks */ MSG msgDblClk; /* Current capture window for this queue. */ PWND spwndCapture; @@ -142,13 +140,6 @@ co_MsqPeekHardwareMessage(IN PTHREADINFO pti, IN UINT MsgFilterHigh, IN UINT QSflags, OUT MSG* pMsg); -BOOL APIENTRY -co_MsqPeekMouseMove(IN PTHREADINFO pti, - IN BOOL Remove, - IN PWND Window, - IN UINT MsgFilterLow, - IN UINT MsgFilterHigh, - OUT MSG* pMsg); BOOLEAN FASTCALL MsqInitializeMessageQueue(PTHREADINFO, PUSER_MESSAGE_QUEUE); PUSER_MESSAGE_QUEUE FASTCALL MsqCreateMessageQueue(PTHREADINFO); VOID FASTCALL MsqCleanupThreadMsgs(PTHREADINFO); diff --git a/reactos/win32ss/user/ntuser/timer.c b/reactos/win32ss/user/ntuser/timer.c index 3cbf14e576e..f3355a5095c 100644 --- a/reactos/win32ss/user/ntuser/timer.c +++ b/reactos/win32ss/user/ntuser/timer.c @@ -315,7 +315,7 @@ SystemTimerProc(HWND hwnd, if ( pDesk->dwDTFlags & DF_TME_HOVER && pWnd == pDesk->spwndTrack ) { - Point = pWnd->head.pti->MessageQueue->MouseMoveMsg.pt; + Point = gpsi->ptCursor; if ( RECTL_bPointInRect(&pDesk->rcMouseHover, Point.x, Point.y) ) { if (pDesk->htEx == HTCLIENT) // In a client area.