Index: content/browser/renderer_host/render_widget_host_view_win.cc |
diff --git a/content/browser/renderer_host/render_widget_host_view_win.cc b/content/browser/renderer_host/render_widget_host_view_win.cc |
index be206c3eb4fc80f1fbb830c9c9444f9d7626a5a0..8b39cb1cd0ed869568f0559fdc2b27121c68e77c 100644 |
--- a/content/browser/renderer_host/render_widget_host_view_win.cc |
+++ b/content/browser/renderer_host/render_widget_host_view_win.cc |
@@ -88,6 +88,11 @@ const int kIdCustom = 1; |
// process a grace period to stop referencing it. |
const int kDestroyCompositorHostWindowDelay = 10000; |
+// In mouse lock mode, the cursor needs to be moved to the center of the view if |
+// it approaches the border. |kMouseLockBorderPercentage| specifies the width of |
+// the border area, in percentage of the corresponding dimension. |
+const int kMouseLockBorderPercentage = 15; |
+ |
// A callback function for EnumThreadWindows to enumerate and dismiss |
// any owned popop windows |
BOOL CALLBACK DismissOwnedPopups(HWND window, LPARAM arg) { |
@@ -1404,7 +1409,7 @@ LRESULT RenderWidgetHostViewWin::OnMouseEvent(UINT message, WPARAM wparam, |
if (mouse_locked_) { |
HandleLockedMouseEvent(message, wparam, lparam); |
- MoveCursorToCenter(); |
+ MoveCursorToCenterIfNecessary(); |
return 0; |
} |
@@ -1892,12 +1897,13 @@ bool RenderWidgetHostViewWin::LockMouse() { |
::ShowWindow(tooltip_hwnd_, SW_HIDE); |
} |
- // TODO(yzshen): Show an invisible cursor instead of using |
- // ::ShowCursor(FALSE), so that MoveCursorToCenter() works with Remote |
- // Desktop. |
+ // TODO(yzshen): ShowCursor(FALSE) causes SetCursorPos() to be ignored on |
+ // Remote Desktop. |
::ShowCursor(FALSE); |
- MoveCursorToCenter(); |
+ move_to_center_request_.pending = false; |
+ last_mouse_position_.locked_global = last_mouse_position_.unlocked_global; |
+ MoveCursorToCenterIfNecessary(); |
CRect rect; |
GetWindowRect(&rect); |
@@ -1913,8 +1919,8 @@ void RenderWidgetHostViewWin::UnlockMouse() { |
mouse_locked_ = false; |
::ClipCursor(NULL); |
- ::SetCursorPos(last_global_mouse_position_.x(), |
- last_global_mouse_position_.y()); |
+ ::SetCursorPos(last_mouse_position_.unlocked_global.x(), |
+ last_mouse_position_.unlocked_global.y()); |
::ShowCursor(TRUE); |
if (render_widget_host_) |
@@ -2296,28 +2302,30 @@ void RenderWidgetHostViewWin::ForwardMouseEventToRenderer(UINT message, |
WebInputEventFactory::mouseEvent(m_hWnd, message, wparam, lparam)); |
if (mouse_locked_) { |
- CPoint center = GetClientCenter(); |
- |
- event.movementX = event.windowX - center.x; |
- event.movementY = event.windowY - center.y; |
- event.x = last_mouse_position_.x(); |
- event.y = last_mouse_position_.y(); |
- event.windowX = last_mouse_position_.x(); |
- event.windowY = last_mouse_position_.y(); |
- event.globalX = last_global_mouse_position_.x(); |
- event.globalY = last_global_mouse_position_.y(); |
+ event.movementX = event.globalX - last_mouse_position_.locked_global.x(); |
+ event.movementY = event.globalY - last_mouse_position_.locked_global.y(); |
+ last_mouse_position_.locked_global.SetPoint(event.globalX, event.globalY); |
+ |
+ event.x = last_mouse_position_.unlocked.x(); |
+ event.y = last_mouse_position_.unlocked.y(); |
+ event.windowX = last_mouse_position_.unlocked.x(); |
+ event.windowY = last_mouse_position_.unlocked.y(); |
+ event.globalX = last_mouse_position_.unlocked_global.x(); |
+ event.globalY = last_mouse_position_.unlocked_global.y(); |
} else { |
if (ignore_mouse_movement_) { |
ignore_mouse_movement_ = false; |
event.movementX = 0; |
event.movementY = 0; |
} else { |
- event.movementX = event.globalX - last_global_mouse_position_.x(); |
- event.movementY = event.globalY - last_global_mouse_position_.y(); |
+ event.movementX = |
+ event.globalX - last_mouse_position_.unlocked_global.x(); |
+ event.movementY = |
+ event.globalY - last_mouse_position_.unlocked_global.y(); |
} |
- last_mouse_position_.SetPoint(event.windowX, event.windowY); |
- last_global_mouse_position_.SetPoint(event.globalX, event.globalY); |
+ last_mouse_position_.unlocked.SetPoint(event.windowX, event.windowY); |
+ last_mouse_position_.unlocked_global.SetPoint(event.globalX, event.globalY); |
} |
// Send the event to the renderer before changing mouse capture, so that the |
@@ -2375,11 +2383,28 @@ CPoint RenderWidgetHostViewWin::GetClientCenter() const { |
return rect.CenterPoint(); |
} |
-void RenderWidgetHostViewWin::MoveCursorToCenter() const { |
- CPoint center = GetClientCenter(); |
- ClientToScreen(¢er); |
- if (!::SetCursorPos(center.x, center.y)) |
- LOG_GETLASTERROR(WARNING) << "Failed to set cursor position."; |
+void RenderWidgetHostViewWin::MoveCursorToCenterIfNecessary() { |
+ DCHECK(mouse_locked_); |
+ |
+ CRect rect; |
+ GetWindowRect(&rect); |
+ int border_x = rect.Width() * kMouseLockBorderPercentage / 100; |
+ int border_y = rect.Height() * kMouseLockBorderPercentage / 100; |
+ |
+ bool should_move = |
+ last_mouse_position_.locked_global.x() < rect.left + border_x || |
+ last_mouse_position_.locked_global.x() > rect.right - border_x || |
+ last_mouse_position_.locked_global.y() < rect.top + border_y || |
+ last_mouse_position_.locked_global.y() > rect.bottom - border_y; |
+ |
+ if (should_move) { |
+ move_to_center_request_.pending = true; |
+ move_to_center_request_.target = rect.CenterPoint(); |
+ if (!::SetCursorPos(move_to_center_request_.target.x(), |
+ move_to_center_request_.target.y())) { |
+ LOG_GETLASTERROR(WARNING) << "Failed to set cursor position."; |
+ } |
+ } |
} |
void RenderWidgetHostViewWin::HandleLockedMouseEvent(UINT message, |
@@ -2387,11 +2412,17 @@ void RenderWidgetHostViewWin::HandleLockedMouseEvent(UINT message, |
LPARAM lparam) { |
DCHECK(mouse_locked_); |
- if (message == WM_MOUSEMOVE) { |
- CPoint center = GetClientCenter(); |
- // Ignore WM_MOUSEMOVE messages generated by MoveCursorToCenter(). |
- if (LOWORD(lparam) == center.x && HIWORD(lparam) == center.y) |
+ if (message == WM_MOUSEMOVE && move_to_center_request_.pending) { |
+ // Ignore WM_MOUSEMOVE messages generated by |
+ // MoveCursorToCenterIfNecessary(). |
+ CPoint center(LOWORD(lparam), HIWORD(lparam)); |
+ ClientToScreen(¢er); |
+ if (move_to_center_request_.target.x() == center.x && |
scheib
2011/12/05 19:38:29
;X Am I confused, or should this test be something
yzshen1
2011/12/05 20:05:35
Sorry. I didn't change the variable name, which ca
|
+ move_to_center_request_.target.y() == center.y) { |
+ move_to_center_request_.pending = false; |
+ last_mouse_position_.locked_global = move_to_center_request_.target; |
return; |
+ } |
} |
ForwardMouseEventToRenderer(message, wparam, lparam); |