зеркало из https://github.com/mozilla/gecko-dev.git
Bug 672175 part.13 Compute cursor position at WM_MOUSEWHEEL and WM_MOUSEHWHEEL in MouseScrollHandler r=jimm
This commit is contained in:
Родитель
7c0c3c99dc
Коммит
abc50845c2
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче