Fix for bug 312566: Fix MouseTrailer and other mouse handling issues

r=dougt, roc
sr=roc
This commit is contained in:
emaijala%kolumbus.fi 2005-12-02 12:08:32 +00:00
Родитель 480f8e01d3
Коммит fbb091853f
4 изменённых файлов: 137 добавлений и 137 удалений

Просмотреть файл

@ -920,7 +920,7 @@ NS_METHOD NS_GetCurrentToolkit(nsIToolkit* *aResult)
// //
// //
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
MouseTrailer::MouseTrailer() : mHoldMouseWindow(nsnull), mCaptureWindow(nsnull), MouseTrailer::MouseTrailer() : mMouseTrailerWindow(nsnull), mCaptureWindow(nsnull),
mIsInCaptureMode(PR_FALSE), mIgnoreNextCycle(PR_FALSE) mIsInCaptureMode(PR_FALSE), mIgnoreNextCycle(PR_FALSE)
{ {
} }
@ -931,24 +931,33 @@ MouseTrailer::MouseTrailer() : mHoldMouseWindow(nsnull), mCaptureWindow(nsnull),
MouseTrailer::~MouseTrailer() MouseTrailer::~MouseTrailer()
{ {
DestroyTimer(); DestroyTimer();
NS_IF_RELEASE(mHoldMouseWindow);
NS_IF_RELEASE(mCaptureWindow);
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// //
// //
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
void MouseTrailer::SetMouseTrailerWindow(nsWindow * aNSWin) void MouseTrailer::SetMouseTrailerWindow(HWND aWnd)
{ {
nsWindow *topWin = aNSWin ? aNSWin->GetTopLevelWindow() : nsnull; if (mMouseTrailerWindow != aWnd && mTimer) {
if (mHoldMouseWindow != topWin && mTimer) {
// Make sure TimerProc is fired at least once for the old window // Make sure TimerProc is fired at least once for the old window
TimerProc(nsnull, nsnull); TimerProc(nsnull, nsnull);
} }
NS_IF_RELEASE(mHoldMouseWindow); mMouseTrailerWindow = aWnd;
mHoldMouseWindow = topWin;
CreateTimer(); CreateTimer();
} }
//-------------------------------------------------------------------------
//
//
//-------------------------------------------------------------------------
void MouseTrailer::SetCaptureWindow(HWND aWnd)
{
mCaptureWindow = aWnd;
if (mCaptureWindow) {
mIsInCaptureMode = PR_TRUE;
}
}
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// //
// //
@ -967,7 +976,6 @@ nsresult MouseTrailer::CreateTimer()
nsITimer::TYPE_REPEATING_SLACK); nsITimer::TYPE_REPEATING_SLACK);
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// //
// //
@ -979,18 +987,7 @@ void MouseTrailer::DestroyTimer()
mTimer = nsnull; mTimer = nsnull;
} }
} }
//-------------------------------------------------------------------------
//
//
//-------------------------------------------------------------------------
void MouseTrailer::SetCaptureWindow(nsWindow * aNSWin)
{
NS_IF_RELEASE(mCaptureWindow);
mCaptureWindow = aNSWin ? aNSWin->GetTopLevelWindow() : nsnull;
if (nsnull != mCaptureWindow) {
mIsInCaptureMode = PR_TRUE;
}
}
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// //
// //
@ -998,26 +995,26 @@ void MouseTrailer::SetCaptureWindow(nsWindow * aNSWin)
void MouseTrailer::TimerProc(nsITimer* aTimer, void* aClosure) void MouseTrailer::TimerProc(nsITimer* aTimer, void* aClosure)
{ {
// Check to see if we are in mouse capture mode, // Check to see if we are in mouse capture mode,
// Once capture ends we could still get back one more timer event // Once capture ends we could still get back one more timer event.
// Capture could end outside our window // Capture could end outside our window.
// Also, for some reason when the mouse is on the frame it thinks that // Also, for some reason when the mouse is on the frame it thinks that
// it is inside the window that is being captured. // it is inside the window that is being captured.
if (nsnull != mSingleton.mCaptureWindow) { if (mSingleton.mCaptureWindow) {
if (mSingleton.mCaptureWindow != mSingleton.mHoldMouseWindow) { if (mSingleton.mCaptureWindow != mSingleton.mMouseTrailerWindow) {
return; return;
} }
} else { } else {
if (mSingleton.mIsInCaptureMode) { if (mSingleton.mIsInCaptureMode) {
// The mHoldMouse could be bad from rolling over the frame, so clear // mMouseTrailerWindow could be bad from rolling over the frame, so clear
// it if we were capturing and now this is the first timer call back // it if we were capturing and now this is the first timer callback
// since we canceled the capture // since we canceled the capture
NS_IF_RELEASE(mSingleton.mHoldMouseWindow); mSingleton.mMouseTrailerWindow = nsnull;
mSingleton.mIsInCaptureMode = PR_FALSE; mSingleton.mIsInCaptureMode = PR_FALSE;
return; return;
} }
} }
if (mSingleton.mHoldMouseWindow && ::IsWindow(mSingleton.mHoldMouseWindow->GetWindowHandle())) { if (mSingleton.mMouseTrailerWindow && ::IsWindow(mSingleton.mMouseTrailerWindow)) {
if (mSingleton.mIgnoreNextCycle) { if (mSingleton.mIgnoreNextCycle) {
mSingleton.mIgnoreNextCycle = PR_FALSE; mSingleton.mIgnoreNextCycle = PR_FALSE;
} }
@ -1027,24 +1024,24 @@ void MouseTrailer::TimerProc(nsITimer* aTimer, void* aClosure)
mp.x = GET_X_LPARAM(pos); mp.x = GET_X_LPARAM(pos);
mp.y = GET_Y_LPARAM(pos); mp.y = GET_Y_LPARAM(pos);
// Need to get the top level wnd's here. Although mHoldMouseWindow is top level, HWND mouseWnd = WindowFromPoint(mp);
// the actual top level window handle might be something else if (mSingleton.mMouseTrailerWindow != mouseWnd) {
HWND mouseWnd = nsWindow::GetTopLevelHWND(::WindowFromPoint(mp), PR_TRUE); #ifndef WINCE
HWND holdWnd = nsWindow::GetTopLevelHWND(mSingleton.mHoldMouseWindow->GetWindowHandle(), PR_TRUE); // Notify someone that a mouse exit happened.
if (mouseWnd != holdWnd) { // This must be posted to the toplevel window. Otherwise event state
//notify someone that a mouse exit happened // manager might think the mouse is still within window bounds and
if (nsnull != mSingleton.mHoldMouseWindow) { // convert this to a move message.
mSingleton.mHoldMouseWindow->DispatchMouseEvent(NS_MOUSE_EXIT, NULL, NULL); PostMessage(mSingleton.mMouseTrailerWindow, WM_MOUSELEAVE, NULL, NULL);
} #endif
// we are out of this window and of any window, destroy timer // we are out of this window, destroy timer
mSingleton.DestroyTimer(); mSingleton.DestroyTimer();
NS_IF_RELEASE(mSingleton.mHoldMouseWindow); mSingleton.mMouseTrailerWindow = nsnull;
} }
} }
} else { } else {
mSingleton.DestroyTimer(); mSingleton.DestroyTimer();
NS_IF_RELEASE(mSingleton.mHoldMouseWindow); mSingleton.mMouseTrailerWindow = nsnull;
} }
} }

Просмотреть файл

@ -161,11 +161,11 @@ class MouseTrailer
public: public:
static MouseTrailer &GetSingleton() { return mSingleton; } static MouseTrailer &GetSingleton() { return mSingleton; }
nsWindow *GetMouseTrailerWindow() { return mHoldMouseWindow; } HWND GetMouseTrailerWindow() { return mMouseTrailerWindow; }
nsWindow *GetCaptureWindow() { return mCaptureWindow; } HWND GetCaptureWindow() { return mCaptureWindow; }
void SetMouseTrailerWindow(nsWindow * aNSWin); void SetMouseTrailerWindow(HWND aWnd);
void SetCaptureWindow(nsWindow * aNSWin); void SetCaptureWindow(HWND aWnd);
void IgnoreNextCycle() { mIgnoreNextCycle = PR_TRUE; } void IgnoreNextCycle() { mIgnoreNextCycle = PR_TRUE; }
void DestroyTimer(); void DestroyTimer();
~MouseTrailer(); ~MouseTrailer();
@ -180,15 +180,12 @@ private:
// Global nsToolkit Instance // Global nsToolkit Instance
static MouseTrailer mSingleton; static MouseTrailer mSingleton;
// information for mouse enter/exit events // Information for mouse enter/exit events
// last window HWND mMouseTrailerWindow;
nsWindow *mHoldMouseWindow; HWND mCaptureWindow;
nsWindow *mCaptureWindow;
PRBool mIsInCaptureMode; PRBool mIsInCaptureMode;
PRBool mIgnoreNextCycle; PRBool mIgnoreNextCycle;
// timer
nsCOMPtr<nsITimer> mTimer; nsCOMPtr<nsITimer> mTimer;
}; };
//------------------------------------------------------------------------- //-------------------------------------------------------------------------

Просмотреть файл

@ -914,9 +914,12 @@ nsWindow::~nsWindow()
gCurrentWindow = nsnull; gCurrentWindow = nsnull;
} }
if (MouseTrailer::GetSingleton().GetMouseTrailerWindow() == this) { if (MouseTrailer::GetSingleton().GetMouseTrailerWindow() == mWnd) {
MouseTrailer::GetSingleton().DestroyTimer(); MouseTrailer::GetSingleton().DestroyTimer();
} }
if (MouseTrailer::GetSingleton().GetCaptureWindow() == mWnd) {
MouseTrailer::GetSingleton().SetCaptureWindow(nsnull);
}
// If the widget was released without calling Destroy() then the native // If the widget was released without calling Destroy() then the native
// window still exists, and we need to destroy it // window still exists, and we need to destroy it
@ -956,7 +959,7 @@ nsWindow::~nsWindow()
NS_METHOD nsWindow::CaptureMouse(PRBool aCapture) NS_METHOD nsWindow::CaptureMouse(PRBool aCapture)
{ {
if (aCapture) { if (aCapture) {
MouseTrailer::GetSingleton().SetCaptureWindow(this); MouseTrailer::GetSingleton().SetCaptureWindow(mWnd);
::SetCapture(mWnd); ::SetCapture(mWnd);
} else { } else {
MouseTrailer::GetSingleton().SetCaptureWindow(NULL); MouseTrailer::GetSingleton().SetCaptureWindow(NULL);
@ -1026,6 +1029,24 @@ NS_METHOD nsWindow::ScreenToWidget(const nsRect& aOldRect, nsRect& aNewRect)
return NS_OK; return NS_OK;
} }
LPARAM nsWindow::lParamToScreen(LPARAM lParam)
{
POINT pt;
pt.x = GET_X_LPARAM(lParam);
pt.y = GET_Y_LPARAM(lParam);
::ClientToScreen(mWnd, &pt);
return MAKELPARAM(pt.x, pt.y);
}
LPARAM nsWindow::lParamToClient(LPARAM lParam)
{
POINT pt;
pt.x = GET_X_LPARAM(lParam);
pt.y = GET_Y_LPARAM(lParam);
::ScreenToClient(mWnd, &pt);
return MAKELPARAM(pt.x, pt.y);
}
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// //
// Convert nsEventStatus value to a windows boolean // Convert nsEventStatus value to a windows boolean
@ -3895,7 +3916,6 @@ EventMsgInfo gAllEvents[] = {
{"LB_INITSTORAGE", 0x01A8}, {"LB_INITSTORAGE", 0x01A8},
{"LB_ITEMFROMPOINT", 0x01A9}, {"LB_ITEMFROMPOINT", 0x01A9},
{"LB_MSGMAX", 0x01B0}, {"LB_MSGMAX", 0x01B0},
{"WM_MOUSEFIRST", 0x0200},
{"WM_MOUSEMOVE", 0x0200}, {"WM_MOUSEMOVE", 0x0200},
{"WM_LBUTTONDOWN", 0x0201}, {"WM_LBUTTONDOWN", 0x0201},
{"WM_LBUTTONUP", 0x0202}, {"WM_LBUTTONUP", 0x0202},
@ -3907,8 +3927,6 @@ EventMsgInfo gAllEvents[] = {
{"WM_MBUTTONUP", 0x0208}, {"WM_MBUTTONUP", 0x0208},
{"WM_MBUTTONDBLCLK", 0x0209}, {"WM_MBUTTONDBLCLK", 0x0209},
{"WM_MOUSEWHEEL", 0x020A}, {"WM_MOUSEWHEEL", 0x020A},
{"WM_MOUSELAST", 0x020A},
{"WM_MOUSELAST", 0x0209},
{"WM_PARENTNOTIFY", 0x0210}, {"WM_PARENTNOTIFY", 0x0210},
{"WM_ENTERMENULOOP", 0x0211}, {"WM_ENTERMENULOOP", 0x0211},
{"WM_EXITMENULOOP", 0x0212}, {"WM_EXITMENULOOP", 0x0212},
@ -3942,6 +3960,7 @@ EventMsgInfo gAllEvents[] = {
{"WM_IME_REQUEST", 0x0288}, {"WM_IME_REQUEST", 0x0288},
{"WM_IME_KEYDOWN", 0x0290}, {"WM_IME_KEYDOWN", 0x0290},
{"WM_IME_KEYUP", 0x0291}, {"WM_IME_KEYUP", 0x0291},
{"WM_NCMOUSEHOVER", 0x02A0},
{"WM_MOUSEHOVER", 0x02A1}, {"WM_MOUSEHOVER", 0x02A1},
{"WM_MOUSELEAVE", 0x02A3}, {"WM_MOUSELEAVE", 0x02A3},
{"WM_CUT", 0x0300}, {"WM_CUT", 0x0300},
@ -4472,22 +4491,19 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
break; break;
case WM_MOUSEMOVE: case WM_MOUSEMOVE:
//RelayMouseEvent(msg,wParam, lParam); {
// Suppress dispatch of pending events // Suppress dispatch of pending events
// when mouse moves are generated by widget // when mouse moves are generated by widget
// creation instead of user input. // creation instead of user input.
{
POINT mp; POINT mp;
DWORD pos = ::GetMessagePos(); mp.x = GET_X_LPARAM(lParam);
mp.x = GET_X_LPARAM(pos); mp.y = GET_Y_LPARAM(lParam);
mp.y = GET_Y_LPARAM(pos);
PRBool userMovedMouse = PR_FALSE; PRBool userMovedMouse = PR_FALSE;
if ((gLastMouseMovePoint.x != mp.x) || (gLastMouseMovePoint.y != mp.y)) { if ((gLastMouseMovePoint.x != mp.x) || (gLastMouseMovePoint.y != mp.y)) {
userMovedMouse = PR_TRUE; userMovedMouse = PR_TRUE;
} }
result = DispatchMouseEvent(NS_MOUSE_MOVE, wParam); result = DispatchMouseEvent(NS_MOUSE_MOVE, wParam, lParam);
if (userMovedMouse) { if (userMovedMouse) {
DispatchPendingEvents(); DispatchPendingEvents();
} }
@ -4509,8 +4525,8 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
shrg.dwFlags = SHRG_RETURNCMD; shrg.dwFlags = SHRG_RETURNCMD;
if (SHRecognizeGesture(&shrg) == GN_CONTEXTMENU) if (SHRecognizeGesture(&shrg) == GN_CONTEXTMENU)
{ {
result = DispatchMouseEvent(NS_MOUSE_RIGHT_BUTTON_DOWN, wParam); result = DispatchMouseEvent(NS_MOUSE_RIGHT_BUTTON_DOWN, wParam, lParam);
result = DispatchMouseEvent(NS_MOUSE_RIGHT_BUTTON_UP, wParam); result = DispatchMouseEvent(NS_MOUSE_RIGHT_BUTTON_UP, wParam, lParam);
break; break;
} }
} }
@ -4518,28 +4534,55 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
// check whether IME window do mouse operation // check whether IME window do mouse operation
if (IMEMouseHandling(NS_MOUSE_LEFT_BUTTON_DOWN, IMEMOUSE_LDOWN, lParam)) if (IMEMouseHandling(NS_MOUSE_LEFT_BUTTON_DOWN, IMEMOUSE_LDOWN, lParam))
break; break;
result = DispatchMouseEvent(NS_MOUSE_LEFT_BUTTON_DOWN, wParam); result = DispatchMouseEvent(NS_MOUSE_LEFT_BUTTON_DOWN, wParam, lParam);
DispatchPendingEvents(); DispatchPendingEvents();
} }
break; break;
case WM_LBUTTONUP: case WM_LBUTTONUP:
//RelayMouseEvent(msg,wParam, lParam); //RelayMouseEvent(msg,wParam, lParam);
result = DispatchMouseEvent(NS_MOUSE_LEFT_BUTTON_UP, wParam); result = DispatchMouseEvent(NS_MOUSE_LEFT_BUTTON_UP, wParam, lParam);
DispatchPendingEvents(); DispatchPendingEvents();
break; break;
case WM_CANCELMODE:
CaptureMouse(PR_FALSE);
break;
#ifndef WINCE
case WM_MOUSELEAVE:
{
// We use MAXDWORD as the mouse position to make sure
// EventStateManager doesn't convert this EXIT message to
// a MOVE message (besides, WM_MOUSELEAVE doesn't have the position
// in lParam).
DispatchMouseEvent(NS_MOUSE_EXIT, wParam, MAXDWORD);
}
break;
#endif
case WM_CONTEXTMENU: case WM_CONTEXTMENU:
{ {
// if the context menu is brought up from the keyboard, |lParam| // if the context menu is brought up from the keyboard, |lParam|
// will be maxlong. Send a different event msg instead. // will be maxlong. Send a different event msg instead.
PRUint32 msg = (lParam == 0xFFFFFFFF) ? NS_CONTEXTMENU_KEY : NS_CONTEXTMENU; PRUint32 msg;
result = DispatchMouseEvent(msg, wParam); LPARAM pos;
if (lParam == 0xFFFFFFFF)
{
msg = NS_CONTEXTMENU_KEY;
pos = lParamToClient(GetMessagePos());
}
else
{
msg = NS_CONTEXTMENU;
pos = lParamToClient(lParam);
}
result = DispatchMouseEvent(msg, wParam, pos);
} }
break; break;
case WM_LBUTTONDBLCLK: case WM_LBUTTONDBLCLK:
result = DispatchMouseEvent(NS_MOUSE_LEFT_DOUBLECLICK, wParam); result = DispatchMouseEvent(NS_MOUSE_LEFT_DOUBLECLICK, wParam, lParam);
break; break;
case WM_MBUTTONDOWN: case WM_MBUTTONDOWN:
@ -4547,18 +4590,18 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
// check whether IME window do mouse operation // check whether IME window do mouse operation
if (IMEMouseHandling(NS_MOUSE_MIDDLE_BUTTON_DOWN, IMEMOUSE_MDOWN, lParam)) if (IMEMouseHandling(NS_MOUSE_MIDDLE_BUTTON_DOWN, IMEMOUSE_MDOWN, lParam))
break; break;
result = DispatchMouseEvent(NS_MOUSE_MIDDLE_BUTTON_DOWN, wParam); result = DispatchMouseEvent(NS_MOUSE_MIDDLE_BUTTON_DOWN, wParam, lParam);
DispatchPendingEvents(); DispatchPendingEvents();
} }
break; break;
case WM_MBUTTONUP: case WM_MBUTTONUP:
result = DispatchMouseEvent(NS_MOUSE_MIDDLE_BUTTON_UP, wParam); result = DispatchMouseEvent(NS_MOUSE_MIDDLE_BUTTON_UP, wParam, lParam);
DispatchPendingEvents(); DispatchPendingEvents();
break; break;
case WM_MBUTTONDBLCLK: case WM_MBUTTONDBLCLK:
result = DispatchMouseEvent(NS_MOUSE_MIDDLE_BUTTON_DOWN, wParam); result = DispatchMouseEvent(NS_MOUSE_MIDDLE_BUTTON_DOWN, wParam, lParam);
break; break;
case WM_RBUTTONDOWN: case WM_RBUTTONDOWN:
@ -4566,18 +4609,18 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
// check whether IME window do mouse operation // check whether IME window do mouse operation
if (IMEMouseHandling(NS_MOUSE_RIGHT_BUTTON_DOWN, IMEMOUSE_RDOWN, lParam)) if (IMEMouseHandling(NS_MOUSE_RIGHT_BUTTON_DOWN, IMEMOUSE_RDOWN, lParam))
break; break;
result = DispatchMouseEvent(NS_MOUSE_RIGHT_BUTTON_DOWN, wParam); result = DispatchMouseEvent(NS_MOUSE_RIGHT_BUTTON_DOWN, wParam, lParam);
DispatchPendingEvents(); DispatchPendingEvents();
} }
break; break;
case WM_RBUTTONUP: case WM_RBUTTONUP:
result = DispatchMouseEvent(NS_MOUSE_RIGHT_BUTTON_UP, wParam); result = DispatchMouseEvent(NS_MOUSE_RIGHT_BUTTON_UP, wParam, lParam);
DispatchPendingEvents(); DispatchPendingEvents();
break; break;
case WM_RBUTTONDBLCLK: case WM_RBUTTONDBLCLK:
result = DispatchMouseEvent(NS_MOUSE_RIGHT_DOUBLECLICK, wParam); result = DispatchMouseEvent(NS_MOUSE_RIGHT_DOUBLECLICK, wParam, lParam);
break; break;
case WM_APPCOMMAND: case WM_APPCOMMAND:
@ -5798,7 +5841,7 @@ PRBool nsWindow::OnResize(nsRect &aWindowRect)
// Deal with all sort of mouse event // Deal with all sort of mouse event
// //
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
PRBool nsWindow::DispatchMouseEvent(PRUint32 aEventType, WPARAM wParam, nsPoint* aPoint) PRBool nsWindow::DispatchMouseEvent(PRUint32 aEventType, WPARAM wParam, LPARAM lParam)
{ {
PRBool result = PR_FALSE; PRBool result = PR_FALSE;
@ -5806,12 +5849,16 @@ PRBool nsWindow::DispatchMouseEvent(PRUint32 aEventType, WPARAM wParam, nsPoint*
return result; return result;
} }
nsPoint eventPoint;
eventPoint.x = GET_X_LPARAM(lParam);
eventPoint.y = GET_Y_LPARAM(lParam);
nsMouseEvent event(PR_TRUE, aEventType, this, nsMouseEvent::eReal); nsMouseEvent event(PR_TRUE, aEventType, this, nsMouseEvent::eReal);
if (aEventType == NS_CONTEXTMENU_KEY) { if (aEventType == NS_CONTEXTMENU_KEY) {
nsPoint zero(0, 0); nsPoint zero(0, 0);
InitEvent(event, &zero); InitEvent(event, &zero);
} else { } else {
InitEvent(event, aPoint); InitEvent(event, &eventPoint);
} }
event.isShift = IS_VK_DOWN(NS_VK_SHIFT); event.isShift = IS_VK_DOWN(NS_VK_SHIFT);
@ -5822,9 +5869,8 @@ PRBool nsWindow::DispatchMouseEvent(PRUint32 aEventType, WPARAM wParam, nsPoint*
//Dblclicks are used to set the click count, then changed to mousedowns //Dblclicks are used to set the click count, then changed to mousedowns
LONG curMsgTime = ::GetMessageTime(); LONG curMsgTime = ::GetMessageTime();
POINT mp; POINT mp;
DWORD pos = ::GetMessagePos(); mp.x = eventPoint.x;
mp.x = GET_X_LPARAM(pos); mp.y = eventPoint.y;
mp.y = GET_Y_LPARAM(pos);
PRBool insideMovementThreshold = (abs(gLastMousePoint.x - mp.x) < (short)::GetSystemMetrics(SM_CXDOUBLECLK)) && PRBool insideMovementThreshold = (abs(gLastMousePoint.x - mp.x) < (short)::GetSystemMetrics(SM_CXDOUBLECLK)) &&
(abs(gLastMousePoint.y - mp.y) < (short)::GetSystemMetrics(SM_CYDOUBLECLK)); (abs(gLastMousePoint.y - mp.y) < (short)::GetSystemMetrics(SM_CYDOUBLECLK));
@ -5879,9 +5925,8 @@ PRBool nsWindow::DispatchMouseEvent(PRUint32 aEventType, WPARAM wParam, nsPoint*
else if (aEventType == NS_MOUSE_LEFT_BUTTON_UP || aEventType == NS_MOUSE_MIDDLE_BUTTON_UP || else if (aEventType == NS_MOUSE_LEFT_BUTTON_UP || aEventType == NS_MOUSE_MIDDLE_BUTTON_UP ||
aEventType == NS_MOUSE_RIGHT_BUTTON_UP) { aEventType == NS_MOUSE_RIGHT_BUTTON_UP) {
// remember when this happened for the next mouse down // remember when this happened for the next mouse down
DWORD pos = ::GetMessagePos(); gLastMousePoint.x = eventPoint.x;
gLastMousePoint.x = GET_X_LPARAM(pos); gLastMousePoint.y = eventPoint.y;
gLastMousePoint.y = GET_Y_LPARAM(pos);
gLastMouseButton = eventButton; gLastMouseButton = eventButton;
} }
else if (aEventType == NS_MOUSE_LEFT_BUTTON_DOWN || aEventType == NS_MOUSE_MIDDLE_BUTTON_DOWN || else if (aEventType == NS_MOUSE_LEFT_BUTTON_DOWN || aEventType == NS_MOUSE_MIDDLE_BUTTON_DOWN ||
@ -5913,7 +5958,7 @@ PRBool nsWindow::DispatchMouseEvent(PRUint32 aEventType, WPARAM wParam, nsPoint*
nsPluginEvent pluginEvent; nsPluginEvent pluginEvent;
switch (aEventType)//~~~ switch (aEventType)
{ {
case NS_MOUSE_LEFT_BUTTON_DOWN: case NS_MOUSE_LEFT_BUTTON_DOWN:
pluginEvent.event = WM_LBUTTONDOWN; pluginEvent.event = WM_LBUTTONDOWN;
@ -5946,11 +5991,12 @@ PRBool nsWindow::DispatchMouseEvent(PRUint32 aEventType, WPARAM wParam, nsPoint*
pluginEvent.event = WM_MOUSEMOVE; pluginEvent.event = WM_MOUSEMOVE;
break; break;
default: default:
pluginEvent.event = WM_NULL;
break; break;
} }
pluginEvent.wParam = wParam; // plugins NEED raw OS event flags! pluginEvent.wParam = wParam; // plugins NEED raw OS event flags!
pluginEvent.lParam = MAKELONG(event.refPoint.x, event.refPoint.y); pluginEvent.lParam = lParam;
event.nativeMsg = (void *)&pluginEvent; event.nativeMsg = (void *)&pluginEvent;
@ -5959,49 +6005,9 @@ PRBool nsWindow::DispatchMouseEvent(PRUint32 aEventType, WPARAM wParam, nsPoint*
result = DispatchWindowEvent(&event); result = DispatchWindowEvent(&event);
if (aEventType == NS_MOUSE_MOVE) { if (aEventType == NS_MOUSE_MOVE) {
// if we are not in mouse capture mode (mouse down and hold)
// then use "this" window
// if we are in mouse capture, then all events are being directed
// back to the nsWindow doing the capture. So therefore, the detection
// of whether we are in a new nsWindow is wrong. Meaning this MOUSE_MOVE
// event hold the captured windows pointer not the one the mouse is over.
//
// So we use "WindowFromPoint" to find what window we are over and
// set that window into the mouse trailer timer.
if (!mIsInMouseCapture) { if (!mIsInMouseCapture) {
MouseTrailer::GetSingleton().SetMouseTrailerWindow(this); MouseTrailer::GetSingleton().SetMouseTrailerWindow(mWnd);
} else {
POINT mp;
DWORD pos = ::GetMessagePos();
mp.x = GET_X_LPARAM(pos);
mp.y = GET_Y_LPARAM(pos);
// OK, now find out if we are still inside
// the captured native window
nsWindow * someWindow = nsnull;
HWND hWnd = ::WindowFromPoint(mp);
if (hWnd != NULL) {
POINT cpos = mp;
::ScreenToClient(hWnd, &cpos);
RECT r;
VERIFY(::GetClientRect(hWnd, &r));
if (cpos.x >= r.left && cpos.x <= r.right &&
cpos.y >= r.top && cpos.y <= r.bottom) {
// yes we are so we should be able to get a valid window
// although, strangley enough when we are on the frame part of the
// window we get right here when in capture mode
// but this window won't match the capture mode window so
// we are ok
someWindow = GetNSWindowPtr(hWnd);
} }
}
// only set the window into the mouse trailer if we have a good window
if (nsnull != someWindow) {
MouseTrailer::GetSingleton().SetMouseTrailerWindow(someWindow);
}
}
nsRect rect; nsRect rect;
GetBounds(rect); GetBounds(rect);
rect.x = 0; rect.x = 0;
@ -6011,11 +6017,13 @@ PRBool nsWindow::DispatchMouseEvent(PRUint32 aEventType, WPARAM wParam, nsPoint*
if (gCurrentWindow == NULL || gCurrentWindow != this) { if (gCurrentWindow == NULL || gCurrentWindow != this) {
if ((nsnull != gCurrentWindow) && (!gCurrentWindow->mIsDestroying)) { if ((nsnull != gCurrentWindow) && (!gCurrentWindow->mIsDestroying)) {
MouseTrailer::GetSingleton().IgnoreNextCycle(); MouseTrailer::GetSingleton().IgnoreNextCycle();
gCurrentWindow->DispatchMouseEvent(NS_MOUSE_EXIT, wParam); LPARAM pos = gCurrentWindow->lParamToClient(lParamToScreen(lParam));
gCurrentWindow->DispatchMouseEvent(NS_MOUSE_EXIT, wParam, pos);
} }
gCurrentWindow = this; gCurrentWindow = this;
if (!mIsDestroying) { if (!mIsDestroying) {
gCurrentWindow->DispatchMouseEvent(NS_MOUSE_ENTER, wParam); LPARAM pos = gCurrentWindow->lParamToClient(lParamToScreen(lParam));
gCurrentWindow->DispatchMouseEvent(NS_MOUSE_ENTER, wParam, pos);
} }
} }
} }
@ -6043,10 +6051,6 @@ PRBool nsWindow::DispatchMouseEvent(PRUint32 aEventType, WPARAM wParam, nsPoint*
if (gCurrentWindow == NULL || gCurrentWindow != this) { if (gCurrentWindow == NULL || gCurrentWindow != this) {
gCurrentWindow = this; gCurrentWindow = this;
} }
} else {
#ifdef DEBUG
//printf("Mouse exit");
#endif
} }
} }
break; break;
@ -6180,7 +6184,7 @@ HBRUSH nsWindow::OnControlColor()
// Deal with all sort of mouse event // Deal with all sort of mouse event
// //
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
PRBool ChildWindow::DispatchMouseEvent(PRUint32 aEventType, WPARAM wParam, nsPoint* aPoint) PRBool ChildWindow::DispatchMouseEvent(PRUint32 aEventType, WPARAM wParam, LPARAM lParam)
{ {
PRBool result = PR_FALSE; PRBool result = PR_FALSE;
@ -6206,7 +6210,7 @@ PRBool ChildWindow::DispatchMouseEvent(PRUint32 aEventType, WPARAM wParam, nsPoi
} // switch } // switch
return nsWindow::DispatchMouseEvent(aEventType, wParam, aPoint); return nsWindow::DispatchMouseEvent(aEventType, wParam, lParam);
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------

Просмотреть файл

@ -235,7 +235,7 @@ public:
HWND GetWindowHandle() { return mWnd; } HWND GetWindowHandle() { return mWnd; }
WNDPROC GetPrevWindowProc() { return mPrevWndProc; } WNDPROC GetPrevWindowProc() { return mPrevWndProc; }
virtual PRBool DispatchMouseEvent(PRUint32 aEventType, WPARAM wParam = NULL, nsPoint* aPoint = nsnull); virtual PRBool DispatchMouseEvent(PRUint32 aEventType, WPARAM wParam, LPARAM lParam);
#ifdef ACCESSIBILITY #ifdef ACCESSIBILITY
virtual PRBool DispatchAccessibleEvent(PRUint32 aEventType, nsIAccessible** aAccessible, nsPoint* aPoint = nsnull); virtual PRBool DispatchAccessibleEvent(PRUint32 aEventType, nsIAccessible** aAccessible, nsPoint* aPoint = nsnull);
nsIAccessible* GetRootAccessible(); nsIAccessible* GetRootAccessible();
@ -345,6 +345,8 @@ protected:
void ConstrainZLevel(HWND *aAfter); void ConstrainZLevel(HWND *aAfter);
LPARAM lParamToScreen(LPARAM lParam);
LPARAM lParamToClient(LPARAM lParam);
private: private:
@ -552,7 +554,7 @@ class ChildWindow : public nsWindow {
public: public:
ChildWindow() {} ChildWindow() {}
PRBool DispatchMouseEvent(PRUint32 aEventType, WPARAM wParam = NULL, nsPoint* aPoint = nsnull); PRBool DispatchMouseEvent(PRUint32 aEventType, WPARAM wParam, LPARAM lParam);
protected: protected:
virtual DWORD WindowStyle(); virtual DWORD WindowStyle();