From df27194993b910dad8c8b0e95cd8a7226d2e77d5 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Sat, 15 Oct 2011 00:38:23 +0000 Subject: [PATCH] [Win32k] - Properly set the timer event id's to match tests and add one more bit for track. - Restore TME user API (now in mouse.c) and Hover Timer, these are not the Droids you are looking for. - Restore TME cancellation point in co_MsqInsertMouseMessage and duplicate the the same in co_IntProcessMouseMessage. First thing, pDesk->spwndTrack is never NULL. The Theme TME patch code was setting the wrong QS bit and sending to the wrong queue instead of the pDesk->spwndTrack queue. Surprising this was working at all. - Tested with Themes, passes wine test_TrackMouseEvent and fixes bug (6257 <-- !). Notes: It's all in the sequencing. Locate cancellation points, tracking mouse moves and set the hit test and track window. When the window message queue does not match the current thread, check it again and restore the mouse hover window if it is the same window as the track window and the hover bit set. Track cancellation points and clear the bits at the same time. Not when in WM_MOUSEMOVE. Guess when posting or sending to another thread? co_MsqInsertMouseMessage? svn path=/trunk/; revision=54142 --- .../subsystems/win32/win32k/include/desktop.h | 2 +- .../subsystems/win32/win32k/include/timer.h | 10 +-- .../subsystems/win32/win32k/ntuser/mouse.c | 14 +++- .../subsystems/win32/win32k/ntuser/msgqueue.c | 79 ++++++------------- .../subsystems/win32/win32k/ntuser/timer.c | 8 -- 5 files changed, 42 insertions(+), 71 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/desktop.h b/reactos/subsystems/win32/win32k/include/desktop.h index c7afe5a32cd..573a98abf08 100644 --- a/reactos/subsystems/win32/win32k/include/desktop.h +++ b/reactos/subsystems/win32/win32k/include/desktop.h @@ -34,11 +34,11 @@ typedef struct _DESKTOP // Desktop flags #define DF_TME_HOVER 0x00000400 #define DF_TME_LEAVE 0x00000800 +#define DF_HOTTRACK 0x00004000 #define DF_DESTROYED 0x00008000 #define DF_DESKWNDDESTROYED 0x00010000 #define DF_DYING 0x00020000 - extern PDESKTOP InputDesktop; extern HDESK InputDesktopHandle; extern PCLS DesktopWindowClass; diff --git a/reactos/subsystems/win32/win32k/include/timer.h b/reactos/subsystems/win32/win32k/include/timer.h index 3b9bd030412..fd4b2657e64 100644 --- a/reactos/subsystems/win32/win32k/include/timer.h +++ b/reactos/subsystems/win32/win32k/include/timer.h @@ -24,11 +24,11 @@ typedef struct _TIMER #define TMRF_WAITING 0x0020 #define TMRF_TIFROMWND 0x0040 -#define ID_EVENT_SYSTIMER_MOUSEHOVER (-6) -#define ID_EVENT_SYSTIMER_FLASHWIN (-8) -#define ID_EVENT_SYSTIMER_TRACKWIN (-9) -#define ID_EVENT_SYSTIMER_ANIMATEDFADE (-10) -#define ID_EVENT_SYSTIMER_INVALIDATEDCES (-11) +#define ID_EVENT_SYSTIMER_MOUSEHOVER ID_TME_TIMER +#define ID_EVENT_SYSTIMER_FLASHWIN (0xFFF8) +#define ID_EVENT_SYSTIMER_TRACKWIN (0xFFF7) +#define ID_EVENT_SYSTIMER_ANIMATEDFADE (0xFFF6) +#define ID_EVENT_SYSTIMER_INVALIDATEDCES (0xFFF5) extern PKTIMER MasterTimer; diff --git a/reactos/subsystems/win32/win32k/ntuser/mouse.c b/reactos/subsystems/win32/win32k/ntuser/mouse.c index d77f6650237..8b81f3a08aa 100644 --- a/reactos/subsystems/win32/win32k/ntuser/mouse.c +++ b/reactos/subsystems/win32/win32k/ntuser/mouse.c @@ -334,6 +334,19 @@ IntTrackMouseEvent( if (!(pWnd = UserGetWindowObject(lpEventTrack->hwndTrack))) return FALSE; + if ( pDesk->spwndTrack != pWnd || + (pDesk->htEx != HTCLIENT) ^ !!(lpEventTrack->dwFlags & TME_NONCLIENT) ) + { + if ( lpEventTrack->dwFlags & TME_LEAVE && !(lpEventTrack->dwFlags & TME_CANCEL) ) + { + UserPostMessage( lpEventTrack->hwndTrack, + lpEventTrack->dwFlags & TME_NONCLIENT ? WM_NCMOUSELEAVE : WM_MOUSELEAVE, + 0, 0); + } + TRACE("IntTrackMouseEvent spwndTrack 0x%x pwnd 0x%x\n", pDesk->spwndTrack, pWnd); + return TRUE; + } + /* Tracking spwndTrack same as pWnd */ if (lpEventTrack->dwFlags & TME_CANCEL) // Canceled mode. { @@ -351,7 +364,6 @@ IntTrackMouseEvent( } else // Not Canceled. { - pDesk->spwndTrack = pWnd; if (lpEventTrack->dwFlags & TME_LEAVE) pDesk->dwDTFlags |= DF_TME_LEAVE; diff --git a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c index eedcad3ebf8..a5123922a19 100644 --- a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c +++ b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c @@ -536,34 +536,22 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook if (pwnd) { /* If we a re tracking the mouse and it moves to another top level window */ - if(pDesk->spwndTrack && - UserGetAncestor(pDesk->spwndTrack, GA_ROOT) != pwnd) + PWND pwndTrack = IntChildrenWindowFromPoint(pwnd, Msg->pt.x, Msg->pt.y); + + if ( pDesk->spwndTrack != pwndTrack && pDesk->dwDTFlags & (DF_TME_LEAVE|DF_TME_HOVER) ) { - /* Generate a WM_MOUSELEAVE message */ - if ( pDesk->dwDTFlags & DF_TME_LEAVE ) - { - MSG msgMouseLeave; + if ( pDesk->dwDTFlags & DF_TME_LEAVE ) + UserPostMessage( UserHMGetHandle(pDesk->spwndTrack), + (pDesk->htEx != HTCLIENT) ? WM_NCMOUSELEAVE : WM_MOUSELEAVE, + 0, 0); - TRACE("co_MsqInsertMouseMessage: generating WM_MOUSELEAVE\n"); + if ( pDesk->dwDTFlags & DF_TME_HOVER ) + IntKillTimer(UserHMGetHandle(pDesk->spwndTrack), ID_EVENT_SYSTIMER_MOUSEHOVER, TRUE); - msgMouseLeave.hwnd = UserHMGetHandle(pDesk->spwndTrack); - msgMouseLeave.message = WM_MOUSELEAVE; - msgMouseLeave.pt = Msg->pt; - msgMouseLeave.time = Msg->time; - msgMouseLeave.lParam = msgMouseLeave.wParam = 0; - - MsqPostMessage(pwnd->head.pti->MessageQueue, Msg, TRUE, QS_MOUSE); - } - - /* Stop tracking */ - if ( pDesk->dwDTFlags & DF_TME_HOVER ) - { - IntKillTimer(pDesk->spwndTrack, ID_EVENT_SYSTIMER_MOUSEHOVER, TRUE); - } - - pDesk->spwndTrack = NULL; - pDesk->htEx = 0; + pDesk->dwDTFlags &= ~(DF_TME_LEAVE|DF_TME_HOVER); } + pDesk->spwndTrack = pwndTrack; + pDesk->htEx = GetNCHitEx(pDesk->spwndTrack, Msg->pt); } hdcScreen = IntGetScreenDC(); @@ -1306,42 +1294,21 @@ BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, UINT first, UINT } /* If we a re tracking the mouse and it moves to another window */ - if(pDesk->spwndTrack && - pDesk->spwndTrack != pwndMsg && - msg->message != WM_MOUSELEAVE) + if ( pDesk->spwndTrack != pwndMsg && pDesk->dwDTFlags & (DF_TME_LEAVE|DF_TME_HOVER) && + msg->message != WM_MOUSELEAVE ) { - /* Generate a WM_MOUSELEAVE message */ - if ( pDesk->dwDTFlags & DF_TME_LEAVE ) - { - MSG msgMouseLeave; + if ( pDesk->dwDTFlags & DF_TME_LEAVE ) + UserPostMessage( UserHMGetHandle(pDesk->spwndTrack), + (pDesk->htEx != HTCLIENT) ? WM_NCMOUSELEAVE : WM_MOUSELEAVE, + 0, 0); - TRACE("co_IntProcessMouseMessage: generating WM_MOUSELEAVE\n"); + if ( pDesk->dwDTFlags & DF_TME_HOVER ) + IntKillTimer(UserHMGetHandle(pDesk->spwndTrack), ID_EVENT_SYSTIMER_MOUSEHOVER, TRUE); - msgMouseLeave.hwnd = UserHMGetHandle(pDesk->spwndTrack); - msgMouseLeave.message = WM_MOUSELEAVE; - msgMouseLeave.pt = msg->pt; - msgMouseLeave.time = msg->time; - msgMouseLeave.lParam = msgMouseLeave.wParam = 0; + pDesk->dwDTFlags &= ~(DF_TME_LEAVE|DF_TME_HOVER); - MsqPostMessage(pwndMsg->head.pti->MessageQueue, - &msgMouseLeave, - TRUE, - QS_MOUSE); - } - - /* Stop tracking */ - if ( pDesk->dwDTFlags & DF_TME_HOVER ) - { - IntKillTimer(pDesk->spwndTrack, ID_EVENT_SYSTIMER_MOUSEHOVER, TRUE); - } - - pDesk->spwndTrack = NULL; - pDesk->htEx = 0; - } - - if(pDesk->spwndTrack) - { - pDesk->htEx = hittest; + pDesk->spwndTrack = pwndMsg; + pDesk->htEx = hittest; } msg->hwnd = UserHMGetHandle(pwndMsg); diff --git a/reactos/subsystems/win32/win32k/ntuser/timer.c b/reactos/subsystems/win32/win32k/ntuser/timer.c index acbdc8e9167..d2074f76df9 100644 --- a/reactos/subsystems/win32/win32k/ntuser/timer.c +++ b/reactos/subsystems/win32/win32k/ntuser/timer.c @@ -345,14 +345,6 @@ SystemTimerProc(HWND hwnd, pDesk->dwDTFlags &= ~DF_TME_HOVER; break; // Kill this timer. } - else - { - RECTL_vSetRect(&pDesk->rcMouseHover, - Point.x - gspv.iMouseHoverWidth / 2, - Point.y - gspv.iMouseHoverHeight / 2, - Point.x + gspv.iMouseHoverWidth / 2, - Point.y + gspv.iMouseHoverHeight / 2); - } } } return; // Not this window so just return.