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.