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

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

Issue 7863003: Mouse lock implementation, including the renderer side and the Windows version of the browser side. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 3 months 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
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 22d4f49432b802fd67d3f1ffbf826279730c28a6..855aa5d9ffc5ee5d4b5fb05de882b0b18a6d8254 100644
--- a/content/browser/renderer_host/render_widget_host_view_win.cc
+++ b/content/browser/renderer_host/render_widget_host_view_win.cc
@@ -243,7 +243,12 @@ RenderWidgetHostViewWin::RenderWidgetHostViewWin(RenderWidgetHost* widget)
is_loading_(false),
overlay_color_(0),
text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
- is_fullscreen_(false) {
+ is_fullscreen_(false),
+ last_x_(0),
+ last_y_(0),
+ last_global_x_(0),
+ last_global_y_(0),
+ ignore_mouse_movement_(true) {
render_widget_host_->SetView(this);
registrar_.Add(this,
content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
@@ -251,6 +256,7 @@ RenderWidgetHostViewWin::RenderWidgetHostViewWin(RenderWidgetHost* widget)
}
RenderWidgetHostViewWin::~RenderWidgetHostViewWin() {
+ UnlockMouse();
ResetTooltip();
}
@@ -1229,6 +1235,16 @@ LRESULT RenderWidgetHostViewWin::OnMouseEvent(UINT message, WPARAM wparam,
LPARAM lparam, BOOL& handled) {
handled = TRUE;
+ if (message == WM_MOUSELEAVE)
+ ignore_mouse_movement_ = true;
+
+ if (mouse_locked_) {
+ HandleLockedMouseEvent(message, wparam, lparam);
+ MoveCursorToCenter();
+ return 0;
+ }
+
+ // TODO(yzshen): is this correct? Nothing goes to the tool tip window?
if (::IsWindow(tooltip_hwnd_)) {
// Forward mouse events through to the tooltip window
MSG msg;
@@ -1292,10 +1308,12 @@ LRESULT RenderWidgetHostViewWin::OnKeyEvent(UINT message, WPARAM wparam,
handled = TRUE;
// Force fullscreen windows to close on Escape.
- if (is_fullscreen_ && (message == WM_KEYDOWN || message == WM_KEYUP) &&
- wparam == VK_ESCAPE) {
- SendMessage(WM_CANCELMODE);
- return 0;
+ if ((message == WM_KEYDOWN || message == WM_KEYUP) && wparam == VK_ESCAPE) {
+ if (mouse_locked_)
+ UnlockMouse();
+ if (is_fullscreen_)
+ SendMessage(WM_CANCELMODE);
+ return 0;
}
// If we are a pop-up, forward tab related messages to our parent HWND, so
@@ -1480,6 +1498,45 @@ void RenderWidgetHostViewWin::OnAccessibilityNotifications(
browser_accessibility_manager_->OnAccessibilityNotifications(params);
}
+bool RenderWidgetHostViewWin::LockMouse() {
+ if (mouse_locked_)
+ return true;
+
+ mouse_locked_ = true;
+ // TODO(yzshen): (1) Make sure it works with the current_cursor_.
+ // (2) if not confined successful, we can tell once we receive
+ // mouse leave message, does that help?
+ // (3) ResetTooltip / EnsureTooltip, and make sure they work
+ // consistently with other part of the code.
+
+ // TODO(yzshen): Show an invisible cursor instead of using
+ // ::ShowCursor(FALSE), so that MoveCursorToCenter() works with Remote
+ // Desktop.
+ ::ShowCursor(FALSE);
+
+ MoveCursorToCenter();
+
+ CRect rect;
+ GetWindowRect(&rect);
+ ::ClipCursor(&rect);
+
+ return true;
+}
+
+void RenderWidgetHostViewWin::UnlockMouse() {
+ if (!mouse_locked_)
+ return;
+
+ mouse_locked_ = false;
+
+ ::ClipCursor(NULL);
+ ::SetCursorPos(last_global_x_, last_global_y_);
+ ::ShowCursor(TRUE);
+
+ if (render_widget_host_)
+ render_widget_host_->LostMouseLock();
+}
+
void RenderWidgetHostViewWin::Observe(int type,
const NotificationSource& source,
const NotificationDetails& details) {
@@ -1800,6 +1857,33 @@ void RenderWidgetHostViewWin::ForwardMouseEventToRenderer(UINT message,
WebMouseEvent event(
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_x_;
+ event.y = last_y_;
+ event.windowX = last_x_;
+ event.windowY = last_y_;
+ event.globalX = last_global_x_;
+ event.globalY = last_global_y_;
+ } else {
+ if (ignore_mouse_movement_) {
+ ignore_mouse_movement_ = false;
+ event.movementX = 0;
+ event.movementY = 0;
+ } else {
+ event.movementX = event.globalX - last_global_x_;
+ event.movementY = event.globalY - last_global_y_;
+ }
+
+ last_x_ = event.windowX;
+ last_y_ = event.windowY;
+ last_global_x_ = event.globalX;
+ last_global_y_ = event.globalY;
+ }
+
// Send the event to the renderer before changing mouse capture, so that the
// capturelost event arrives after mouseup.
render_widget_host_->ForwardMouseEvent(event);
@@ -1827,6 +1911,7 @@ void RenderWidgetHostViewWin::ForwardMouseEventToRenderer(UINT message,
// WM_LBUTTONDOWN.
SetFocus();
}
+
}
void RenderWidgetHostViewWin::ShutdownHost() {
@@ -1848,3 +1933,32 @@ void RenderWidgetHostViewWin::DoPopupOrFullscreenInit(HWND parent_hwnd,
EnsureTooltip();
ShowWindow(IsActivatable() ? SW_SHOW : SW_SHOWNA);
}
+
+CPoint RenderWidgetHostViewWin::GetClientCenter() const {
+ CRect rect;
+ GetClientRect(&rect);
+ 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::HandleLockedMouseEvent(UINT message,
+ WPARAM wparam,
+ 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)
+ return;
+ }
+
+ ForwardMouseEventToRenderer(message, wparam, lparam);
+}
+

Powered by Google App Engine
This is Rietveld 408576698