Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(101)

Unified Diff: content/browser/renderer_host/render_widget_host_view_win.cc

Issue 8791001: Fix mouse lock perf issue on Windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/browser/renderer_host/render_widget_host_view_win.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..3a7bfa994d86237f5c159653bb46a43c683b904b 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) {
@@ -334,6 +339,7 @@ RenderWidgetHostViewWin::RenderWidgetHostViewWin(RenderWidgetHost* widget)
overlay_color_(0),
text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
is_fullscreen_(false),
+ ignore_move_to_center_message_(false),
ignore_mouse_movement_(true),
composition_range_(ui::Range::InvalidRange()),
ignore_next_lbutton_message_at_same_location(false),
@@ -1404,7 +1410,7 @@ LRESULT RenderWidgetHostViewWin::OnMouseEvent(UINT message, WPARAM wparam,
if (mouse_locked_) {
HandleLockedMouseEvent(message, wparam, lparam);
- MoveCursorToCenter();
+ MoveCursorToCenterIfNecessary();
return 0;
}
@@ -1892,12 +1898,12 @@ 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();
+ last_locked_global_mouse_position_ = last_unlocked_global_mouse_position_;
+ 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_unlocked_global_mouse_position_.x(),
+ last_unlocked_global_mouse_position_.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_locked_global_mouse_position_.x();
+ event.movementY = event.globalY - last_locked_global_mouse_position_.y();
+ last_locked_global_mouse_position_.SetPoint(event.globalX, event.globalY);
+
+ event.x = last_unlocked_mouse_position_.x();
+ event.y = last_unlocked_mouse_position_.y();
+ event.windowX = last_unlocked_mouse_position_.x();
+ event.windowY = last_unlocked_mouse_position_.y();
+ event.globalX = last_unlocked_global_mouse_position_.x();
+ event.globalY = last_unlocked_global_mouse_position_.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_unlocked_global_mouse_position_.x();
+ event.movementY =
+ event.globalY - last_unlocked_global_mouse_position_.y();
}
- last_mouse_position_.SetPoint(event.windowX, event.windowY);
- last_global_mouse_position_.SetPoint(event.globalX, event.globalY);
+ last_unlocked_mouse_position_.SetPoint(event.windowX, event.windowY);
+ last_unlocked_global_mouse_position_.SetPoint(event.globalX, event.globalY);
}
// Send the event to the renderer before changing mouse capture, so that the
@@ -2375,11 +2383,26 @@ CPoint RenderWidgetHostViewWin::GetClientCenter() const {
return rect.CenterPoint();
}
-void RenderWidgetHostViewWin::MoveCursorToCenter() const {
- CPoint center = GetClientCenter();
- ClientToScreen(&center);
- 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_locked_global_mouse_position_.x() < rect.left + border_x ||
+ last_locked_global_mouse_position_.x() > rect.right - border_x ||
+ last_locked_global_mouse_position_.y() < rect.top + border_y ||
+ last_locked_global_mouse_position_.y() > rect.bottom - border_y;
+
+ if (should_move) {
+ ignore_move_to_center_message_ = true;
+ CPoint center = rect.CenterPoint();
+ if (!::SetCursorPos(center.x, center.y))
+ LOG_GETLASTERROR(WARNING) << "Failed to set cursor position.";
+ }
}
void RenderWidgetHostViewWin::HandleLockedMouseEvent(UINT message,
@@ -2387,11 +2410,16 @@ void RenderWidgetHostViewWin::HandleLockedMouseEvent(UINT message,
LPARAM lparam) {
DCHECK(mouse_locked_);
- if (message == WM_MOUSEMOVE) {
+ if (message == WM_MOUSEMOVE && ignore_move_to_center_message_) {
CPoint center = GetClientCenter();
- // Ignore WM_MOUSEMOVE messages generated by MoveCursorToCenter().
- if (LOWORD(lparam) == center.x && HIWORD(lparam) == center.y)
+ // Ignore WM_MOUSEMOVE messages generated by
+ // MoveCursorToCenterIfNecessary().
+ if (LOWORD(lparam) == center.x && HIWORD(lparam) == center.y) {
scheib 2011/12/03 04:13:01 Perhaps I'm being paranoid, but: consider caching
yzshen1 2011/12/05 01:16:42 I have also considered this scenario. But it won't
+ ignore_move_to_center_message_ = false;
+ ClientToScreen(&center);
+ last_locked_global_mouse_position_.SetPoint(center.x, center.y);
return;
+ }
}
ForwardMouseEventToRenderer(message, wparam, lparam);
« no previous file with comments | « content/browser/renderer_host/render_widget_host_view_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698