Bug 672175 part.13 Compute cursor position at WM_MOUSEWHEEL and WM_MOUSEHWHEEL in MouseScrollHandler r=jimm

This commit is contained in:
Masayuki Nakano 2012-03-06 12:20:29 +09:00
Родитель 7c0c3c99dc
Коммит abc50845c2
3 изменённых файлов: 99 добавлений и 31 удалений

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

@ -65,6 +65,8 @@ bool MouseScrollHandler::Device::Elantech::sUseSwipeHack = false;
bool MouseScrollHandler::Device::Elantech::sUsePinchHack = false;
DWORD MouseScrollHandler::Device::Elantech::sZoomUntil = 0;
bool MouseScrollHandler::Device::SetPoint::sMightBeUsing = false;
// The duration until timeout of events transaction. The value is 1.5 sec,
// it's just a magic number, it was suggested by Logitech's engineer, see
// bug 605648 comment 90.
@ -197,6 +199,26 @@ MouseScrollHandler::GetModifierKeyState(UINT aMessage)
return result;
}
POINT
MouseScrollHandler::ComputeMessagePos(UINT aMessage,
WPARAM aWParam,
LPARAM aLParam)
{
POINT point;
if (Device::SetPoint::IsGetMessagePosResponseValid(aMessage,
aWParam, aLParam)) {
PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
("MouseScroll::ComputeMessagePos: Using ::GetCursorPos()"));
::GetCursorPos(&point);
} else {
DWORD dwPoints = ::GetMessagePos();
point.x = GET_X_LPARAM(dwPoints);
point.y = GET_Y_LPARAM(dwPoints);
}
return point;
}
MouseScrollHandler::ScrollTargetInfo
MouseScrollHandler::GetScrollTargetInfo(
nsWindow* aWindow,
@ -1151,5 +1173,51 @@ MouseScrollHandler::Device::UltraNav::IsObsoleteDriverInstalled()
return majorVersion < 15 || majorVersion == 15 && minorVersion == 0;
}
/******************************************************************************
*
* Device::SetPoint
*
******************************************************************************/
/* static */
bool
MouseScrollHandler::Device::SetPoint::IsGetMessagePosResponseValid(
UINT aMessage,
WPARAM aWParam,
LPARAM aLParam)
{
if (aMessage != WM_MOUSEHWHEEL) {
return false;
}
DWORD messagePos = ::GetMessagePos();
// XXX We should check whether SetPoint is installed or not by registry.
// SetPoint, Logitech (Logicool) mouse driver, (confirmed with 4.82.11 and
// MX-1100) always sets 0 to the lParam of WM_MOUSEHWHEEL. The driver SENDs
// one message at first time, this time, ::GetMessagePos() works fine.
// Then, we will return 0 (0 means we process it) to the message. Then, the
// driver will POST the same messages continuously during the wheel tilted.
// But ::GetMessagePos() API always returns (0, 0) for them, even if the
// actual mouse cursor isn't 0,0. Therefore, we cannot trust the result of
// ::GetMessagePos API if the sender is SetPoint.
if (!sMightBeUsing && !aLParam && (DWORD)aLParam != messagePos &&
::InSendMessage()) {
sMightBeUsing = true;
PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
("MouseScroll::Device::SetPoint::IsGetMessagePosResponseValid(): "
"Might using SetPoint"));
} else if (sMightBeUsing && aLParam != 0 && ::InSendMessage()) {
// The user has changed the mouse from Logitech's to another one (e.g.,
// the user has changed to the touchpad of the notebook.
sMightBeUsing = false;
PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
("MouseScroll::Device::SetPoint::IsGetMessagePosResponseValid(): "
"Might stop using SetPoint"));
}
return (sMightBeUsing && !aLParam && !messagePos);
}
} // namespace widget
} // namespace mozilla

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

@ -35,6 +35,21 @@ public:
LRESULT *aRetValue,
bool &aEatMessage);
/**
* ComputeMessagePos() computes the cursor position when the message was
* added to the queue.
*
* @param aMessage Handling message.
* @param aWParam Handling message's wParam.
* @param aLParam Handling message's lParam.
* @return Mouse cursor position when the message is added to
* the queue or current cursor position if the result of
* ::GetMessagePos() is broken.
*/
POINT ComputeMessagePos(UINT aMessage,
WPARAM aWParam,
LPARAM aLParam);
private:
MouseScrollHandler();
~MouseScrollHandler();
@ -367,6 +382,20 @@ public:
static bool IsObsoleteDriverInstalled();
}; // class UltraNav
class SetPoint {
public:
/**
* SetPoint, Logitech's mouse driver, may report wrong cursor position
* for WM_MOUSEHWHEEL message. See comment in the implementation for
* the detail.
*/
static bool IsGetMessagePosResponseValid(UINT aMessage,
WPARAM aWParam,
LPARAM aLParam);
private:
static bool sMightBeUsing;
};
static void Init();
static bool IsFakeScrollableWindowNeeded()

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

@ -7042,37 +7042,8 @@ nsWindow::OnMouseWheel(UINT aMsg, WPARAM aWParam, LPARAM aLParam,
{
*aRetValue = (aMsg != WM_MOUSEHWHEEL) ? TRUE : FALSE;
POINT point;
DWORD dwPoints = ::GetMessagePos();
point.x = GET_X_LPARAM(dwPoints);
point.y = GET_Y_LPARAM(dwPoints);
static bool sMayBeUsingLogitechMouse = false;
if (aMsg == WM_MOUSEHWHEEL) {
// Logitech (Logicool) mouse driver (confirmed with 4.82.11 and MX-1100)
// always sets 0 to the lParam of WM_MOUSEHWHEEL. The driver SENDs one
// message at first time, this time, ::GetMessagePos works fine.
// Then, we will return 0 (0 means we process it) to the message. Then, the
// driver will POST the same messages continuously during the wheel tilted.
// But ::GetMessagePos API always returns (0, 0), even if the actual mouse
// cursor isn't 0,0. Therefore, we cannot trust the result of
// ::GetMessagePos API if the sender is the driver.
if (!sMayBeUsingLogitechMouse && aLParam == 0 && (DWORD)aLParam != dwPoints &&
::InSendMessage()) {
sMayBeUsingLogitechMouse = true;
} else if (sMayBeUsingLogitechMouse && aLParam != 0 && ::InSendMessage()) {
// The user has changed the mouse from Logitech's to another one (e.g.,
// the user has changed to the touchpad of the notebook.
sMayBeUsingLogitechMouse = false;
}
// If the WM_MOUSEHWHEEL comes from Logitech's mouse driver, and the
// ::GetMessagePos isn't correct, probably, we should use ::GetCursorPos
// instead.
if (sMayBeUsingLogitechMouse && aLParam == 0 && dwPoints == 0) {
::GetCursorPos(&point);
}
}
MouseScrollHandler* handler = MouseScrollHandler::GetInstance();
POINT point = handler->ComputeMessagePos(aMsg, aWParam, aLParam);
HWND underCursorWnd = ::WindowFromPoint(point);
if (!underCursorWnd) {
return;