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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Need a few defines from Win 7 headers for WM_GESTURE and 5 // Need a few defines from Win 7 headers for WM_GESTURE and
6 // ChangeWindowMessageFilterEx. 6 // ChangeWindowMessageFilterEx.
7 // TODO(jschuh): See crbug.com/92941 for longterm fix. 7 // TODO(jschuh): See crbug.com/92941 for longterm fix.
8 #include <windows.h> 8 #include <windows.h>
9 #if(WINVER < 0x0601) 9 #if(WINVER < 0x0601)
10 typedef struct tagCHANGEFILTERSTRUCT { 10 typedef struct tagCHANGEFILTERSTRUCT {
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 about_to_validate_and_paint_(false), 236 about_to_validate_and_paint_(false),
237 close_on_deactivate_(false), 237 close_on_deactivate_(false),
238 being_destroyed_(false), 238 being_destroyed_(false),
239 tooltip_hwnd_(NULL), 239 tooltip_hwnd_(NULL),
240 tooltip_showing_(false), 240 tooltip_showing_(false),
241 shutdown_factory_(this), 241 shutdown_factory_(this),
242 parent_hwnd_(NULL), 242 parent_hwnd_(NULL),
243 is_loading_(false), 243 is_loading_(false),
244 overlay_color_(0), 244 overlay_color_(0),
245 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), 245 text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
246 is_fullscreen_(false) { 246 is_fullscreen_(false),
247 ignore_mouse_movement_(true) {
247 render_widget_host_->SetView(this); 248 render_widget_host_->SetView(this);
248 registrar_.Add(this, 249 registrar_.Add(this,
249 content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, 250 content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
250 NotificationService::AllSources()); 251 NotificationService::AllSources());
251 } 252 }
252 253
253 RenderWidgetHostViewWin::~RenderWidgetHostViewWin() { 254 RenderWidgetHostViewWin::~RenderWidgetHostViewWin() {
255 UnlockMouse();
254 ResetTooltip(); 256 ResetTooltip();
255 } 257 }
256 258
257 void RenderWidgetHostViewWin::CreateWnd(HWND parent) { 259 void RenderWidgetHostViewWin::CreateWnd(HWND parent) {
258 Create(parent); // ATL function to create the window. 260 Create(parent); // ATL function to create the window.
259 } 261 }
260 262
261 /////////////////////////////////////////////////////////////////////////////// 263 ///////////////////////////////////////////////////////////////////////////////
262 // RenderWidgetHostViewWin, RenderWidgetHostView implementation: 264 // RenderWidgetHostViewWin, RenderWidgetHostView implementation:
263 265
(...skipping 830 matching lines...) Expand 10 before | Expand all | Expand 10 after
1094 1096
1095 switch (header->code) { 1097 switch (header->code) {
1096 case TTN_GETDISPINFO: { 1098 case TTN_GETDISPINFO: {
1097 NMTTDISPINFOW* tooltip_info = reinterpret_cast<NMTTDISPINFOW*>(header); 1099 NMTTDISPINFOW* tooltip_info = reinterpret_cast<NMTTDISPINFOW*>(header);
1098 tooltip_info->szText[0] = L'\0'; 1100 tooltip_info->szText[0] = L'\0';
1099 tooltip_info->lpszText = const_cast<WCHAR*>(tooltip_text_.c_str()); 1101 tooltip_info->lpszText = const_cast<WCHAR*>(tooltip_text_.c_str());
1100 ::SendMessage( 1102 ::SendMessage(
1101 tooltip_hwnd_, TTM_SETMAXTIPWIDTH, 0, kTooltipMaxWidthPixels); 1103 tooltip_hwnd_, TTM_SETMAXTIPWIDTH, 0, kTooltipMaxWidthPixels);
1102 SetMsgHandled(TRUE); 1104 SetMsgHandled(TRUE);
1103 break; 1105 break;
1104 } 1106 }
1105 case TTN_POP: 1107 case TTN_POP:
1106 tooltip_showing_ = false; 1108 tooltip_showing_ = false;
1107 SetMsgHandled(TRUE); 1109 SetMsgHandled(TRUE);
1108 break; 1110 break;
1109 case TTN_SHOW: 1111 case TTN_SHOW:
1112 // Tooltip shouldn't be shown when the mouse is locked.
1113 DCHECK(!mouse_locked_);
1110 tooltip_showing_ = true; 1114 tooltip_showing_ = true;
1111 SetMsgHandled(TRUE); 1115 SetMsgHandled(TRUE);
1112 break; 1116 break;
1113 } 1117 }
1114 return 0; 1118 return 0;
1115 } 1119 }
1116 1120
1117 LRESULT RenderWidgetHostViewWin::OnImeSetContext( 1121 LRESULT RenderWidgetHostViewWin::OnImeSetContext(
1118 UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled) { 1122 UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled) {
1119 if (!render_widget_host_) 1123 if (!render_widget_host_)
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1220 ime_input_.DestroyImeWindow(m_hWnd); 1224 ime_input_.DestroyImeWindow(m_hWnd);
1221 // Let WTL call ::DefWindowProc() and release its resources. 1225 // Let WTL call ::DefWindowProc() and release its resources.
1222 handled = FALSE; 1226 handled = FALSE;
1223 return 0; 1227 return 0;
1224 } 1228 }
1225 1229
1226 LRESULT RenderWidgetHostViewWin::OnMouseEvent(UINT message, WPARAM wparam, 1230 LRESULT RenderWidgetHostViewWin::OnMouseEvent(UINT message, WPARAM wparam,
1227 LPARAM lparam, BOOL& handled) { 1231 LPARAM lparam, BOOL& handled) {
1228 handled = TRUE; 1232 handled = TRUE;
1229 1233
1234 if (message == WM_MOUSELEAVE)
1235 ignore_mouse_movement_ = true;
1236
1237 if (mouse_locked_) {
1238 HandleLockedMouseEvent(message, wparam, lparam);
1239 MoveCursorToCenter();
1240 return 0;
1241 }
1242
1230 if (::IsWindow(tooltip_hwnd_)) { 1243 if (::IsWindow(tooltip_hwnd_)) {
1231 // Forward mouse events through to the tooltip window 1244 // Forward mouse events through to the tooltip window
1232 MSG msg; 1245 MSG msg;
1233 msg.hwnd = m_hWnd; 1246 msg.hwnd = m_hWnd;
1234 msg.message = message; 1247 msg.message = message;
1235 msg.wParam = wparam; 1248 msg.wParam = wparam;
1236 msg.lParam = lparam; 1249 msg.lParam = lparam;
1237 SendMessage(tooltip_hwnd_, TTM_RELAYEVENT, NULL, 1250 SendMessage(tooltip_hwnd_, TTM_RELAYEVENT, NULL,
1238 reinterpret_cast<LPARAM>(&msg)); 1251 reinterpret_cast<LPARAM>(&msg));
1239 } 1252 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1283 1296
1284 ForwardMouseEventToRenderer(message, wparam, lparam); 1297 ForwardMouseEventToRenderer(message, wparam, lparam);
1285 return 0; 1298 return 0;
1286 } 1299 }
1287 1300
1288 LRESULT RenderWidgetHostViewWin::OnKeyEvent(UINT message, WPARAM wparam, 1301 LRESULT RenderWidgetHostViewWin::OnKeyEvent(UINT message, WPARAM wparam,
1289 LPARAM lparam, BOOL& handled) { 1302 LPARAM lparam, BOOL& handled) {
1290 handled = TRUE; 1303 handled = TRUE;
1291 1304
1292 // Force fullscreen windows to close on Escape. 1305 // Force fullscreen windows to close on Escape.
1293 if (is_fullscreen_ && (message == WM_KEYDOWN || message == WM_KEYUP) && 1306 if ((message == WM_KEYDOWN || message == WM_KEYUP) && wparam == VK_ESCAPE) {
1294 wparam == VK_ESCAPE) { 1307 if (mouse_locked_)
1295 SendMessage(WM_CANCELMODE); 1308 UnlockMouse();
1296 return 0; 1309 if (is_fullscreen_)
1310 SendMessage(WM_CANCELMODE);
1311 return 0;
1297 } 1312 }
1298 1313
1299 // If we are a pop-up, forward tab related messages to our parent HWND, so 1314 // If we are a pop-up, forward tab related messages to our parent HWND, so
1300 // that we are dismissed appropriately and so that the focus advance in our 1315 // that we are dismissed appropriately and so that the focus advance in our
1301 // parent. 1316 // parent.
1302 // TODO(jcampan): http://b/issue?id=1192881 Could be abstracted in the 1317 // TODO(jcampan): http://b/issue?id=1192881 Could be abstracted in the
1303 // FocusManager. 1318 // FocusManager.
1304 if (close_on_deactivate_ && 1319 if (close_on_deactivate_ &&
1305 (((message == WM_KEYDOWN || message == WM_KEYUP) && (wparam == VK_TAB)) || 1320 (((message == WM_KEYDOWN || message == WM_KEYUP) && (wparam == VK_TAB)) ||
1306 (message == WM_CHAR && wparam == L'\t'))) { 1321 (message == WM_CHAR && wparam == L'\t'))) {
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1471 void RenderWidgetHostViewWin::OnAccessibilityNotifications( 1486 void RenderWidgetHostViewWin::OnAccessibilityNotifications(
1472 const std::vector<ViewHostMsg_AccessibilityNotification_Params>& params) { 1487 const std::vector<ViewHostMsg_AccessibilityNotification_Params>& params) {
1473 if (!browser_accessibility_manager_.get()) { 1488 if (!browser_accessibility_manager_.get()) {
1474 browser_accessibility_manager_.reset( 1489 browser_accessibility_manager_.reset(
1475 BrowserAccessibilityManager::CreateEmptyDocument( 1490 BrowserAccessibilityManager::CreateEmptyDocument(
1476 m_hWnd, static_cast<WebAccessibility::State>(0), this)); 1491 m_hWnd, static_cast<WebAccessibility::State>(0), this));
1477 } 1492 }
1478 browser_accessibility_manager_->OnAccessibilityNotifications(params); 1493 browser_accessibility_manager_->OnAccessibilityNotifications(params);
1479 } 1494 }
1480 1495
1496 bool RenderWidgetHostViewWin::LockMouse() {
1497 if (mouse_locked_)
1498 return true;
1499
1500 mouse_locked_ = true;
1501
1502 // Hide the tooltip window if it is currently visible. When the mouse is
1503 // locked, no mouse message is relayed to the tooltip window, so we don't need
1504 // to worry that it will reappear.
1505 if (::IsWindow(tooltip_hwnd_) && tooltip_showing_) {
1506 ::SendMessage(tooltip_hwnd_, TTM_POP, 0, 0);
1507 // Sending a TTM_POP message doesn't seem to actually hide the tooltip
1508 // window, although we will receive a TTN_POP notification. As a result,
1509 // ShowWindow() is explicitly called to hide the window.
1510 ::ShowWindow(tooltip_hwnd_, SW_HIDE);
1511 }
1512
1513 // TODO(yzshen): Show an invisible cursor instead of using
1514 // ::ShowCursor(FALSE), so that MoveCursorToCenter() works with Remote
1515 // Desktop.
1516 ::ShowCursor(FALSE);
1517
1518 MoveCursorToCenter();
1519
1520 CRect rect;
1521 GetWindowRect(&rect);
1522 ::ClipCursor(&rect);
1523
1524 return true;
1525 }
1526
1527 void RenderWidgetHostViewWin::UnlockMouse() {
1528 if (!mouse_locked_)
1529 return;
1530
1531 mouse_locked_ = false;
1532
1533 ::ClipCursor(NULL);
1534 ::SetCursorPos(last_global_mouse_position_.x(),
1535 last_global_mouse_position_.y());
1536 ::ShowCursor(TRUE);
1537
1538 if (render_widget_host_)
1539 render_widget_host_->LostMouseLock();
1540 }
1541
1481 void RenderWidgetHostViewWin::Observe(int type, 1542 void RenderWidgetHostViewWin::Observe(int type,
1482 const NotificationSource& source, 1543 const NotificationSource& source,
1483 const NotificationDetails& details) { 1544 const NotificationDetails& details) {
1484 DCHECK(type == content::NOTIFICATION_RENDERER_PROCESS_TERMINATED); 1545 DCHECK(type == content::NOTIFICATION_RENDERER_PROCESS_TERMINATED);
1485 1546
1486 // Get the RenderProcessHost that posted this notification, and exit 1547 // Get the RenderProcessHost that posted this notification, and exit
1487 // if it's not the one associated with this host view. 1548 // if it's not the one associated with this host view.
1488 RenderProcessHost* render_process_host = 1549 RenderProcessHost* render_process_host =
1489 Source<RenderProcessHost>(source).ptr(); 1550 Source<RenderProcessHost>(source).ptr();
1490 DCHECK(render_process_host); 1551 DCHECK(render_process_host);
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
1791 1852
1792 void RenderWidgetHostViewWin::ForwardMouseEventToRenderer(UINT message, 1853 void RenderWidgetHostViewWin::ForwardMouseEventToRenderer(UINT message,
1793 WPARAM wparam, 1854 WPARAM wparam,
1794 LPARAM lparam) { 1855 LPARAM lparam) {
1795 if (!render_widget_host_) 1856 if (!render_widget_host_)
1796 return; 1857 return;
1797 1858
1798 WebMouseEvent event( 1859 WebMouseEvent event(
1799 WebInputEventFactory::mouseEvent(m_hWnd, message, wparam, lparam)); 1860 WebInputEventFactory::mouseEvent(m_hWnd, message, wparam, lparam));
1800 1861
1862 if (mouse_locked_) {
1863 CPoint center = GetClientCenter();
1864
1865 event.movementX = event.windowX - center.x;
1866 event.movementY = event.windowY - center.y;
1867 event.x = last_mouse_position_.x();
1868 event.y = last_mouse_position_.y();
1869 event.windowX = last_mouse_position_.x();
1870 event.windowY = last_mouse_position_.y();
1871 event.globalX = last_global_mouse_position_.x();
1872 event.globalY = last_global_mouse_position_.y();
1873 } else {
1874 if (ignore_mouse_movement_) {
1875 ignore_mouse_movement_ = false;
1876 event.movementX = 0;
1877 event.movementY = 0;
1878 } else {
1879 event.movementX = event.globalX - last_global_mouse_position_.x();
1880 event.movementY = event.globalY - last_global_mouse_position_.y();
1881 }
1882
1883 last_mouse_position_.SetPoint(event.windowX, event.windowY);
1884 last_global_mouse_position_.SetPoint(event.globalX, event.globalY);
1885 }
1886
1801 // Send the event to the renderer before changing mouse capture, so that the 1887 // Send the event to the renderer before changing mouse capture, so that the
1802 // capturelost event arrives after mouseup. 1888 // capturelost event arrives after mouseup.
1803 render_widget_host_->ForwardMouseEvent(event); 1889 render_widget_host_->ForwardMouseEvent(event);
1804 1890
1805 switch (event.type) { 1891 switch (event.type) {
1806 case WebInputEvent::MouseMove: 1892 case WebInputEvent::MouseMove:
1807 TrackMouseLeave(true); 1893 TrackMouseLeave(true);
1808 break; 1894 break;
1809 case WebInputEvent::MouseLeave: 1895 case WebInputEvent::MouseLeave:
1810 TrackMouseLeave(false); 1896 TrackMouseLeave(false);
(...skipping 28 matching lines...) Expand all
1839 DWORD ex_style) { 1925 DWORD ex_style) {
1840 parent_hwnd_ = parent_hwnd; 1926 parent_hwnd_ = parent_hwnd;
1841 Create(parent_hwnd_, NULL, NULL, WS_POPUP, ex_style); 1927 Create(parent_hwnd_, NULL, NULL, WS_POPUP, ex_style);
1842 MoveWindow(pos.x(), pos.y(), pos.width(), pos.height(), TRUE); 1928 MoveWindow(pos.x(), pos.y(), pos.width(), pos.height(), TRUE);
1843 // To show tooltip on popup window.(e.g. title in <select>) 1929 // To show tooltip on popup window.(e.g. title in <select>)
1844 // Popups default to showing, which means |DidBecomeSelected()| isn't invoked. 1930 // Popups default to showing, which means |DidBecomeSelected()| isn't invoked.
1845 // Ensure the tooltip is created otherwise tooltips are never shown. 1931 // Ensure the tooltip is created otherwise tooltips are never shown.
1846 EnsureTooltip(); 1932 EnsureTooltip();
1847 ShowWindow(IsActivatable() ? SW_SHOW : SW_SHOWNA); 1933 ShowWindow(IsActivatable() ? SW_SHOW : SW_SHOWNA);
1848 } 1934 }
1935
1936 CPoint RenderWidgetHostViewWin::GetClientCenter() const {
1937 CRect rect;
1938 GetClientRect(&rect);
1939 return rect.CenterPoint();
1940 }
1941
1942 void RenderWidgetHostViewWin::MoveCursorToCenter() const {
1943 CPoint center = GetClientCenter();
1944 ClientToScreen(&center);
1945 if (!::SetCursorPos(center.x, center.y))
1946 LOG_GETLASTERROR(WARNING) << "Failed to set cursor position.";
1947 }
1948
1949 void RenderWidgetHostViewWin::HandleLockedMouseEvent(UINT message,
1950 WPARAM wparam,
1951 LPARAM lparam) {
1952 DCHECK(mouse_locked_);
1953
1954 if (message == WM_MOUSEMOVE) {
1955 CPoint center = GetClientCenter();
1956 // Ignore WM_MOUSEMOVE messages generated by MoveCursorToCenter().
1957 if (LOWORD(lparam) == center.x && HIWORD(lparam) == center.y)
1958 return;
1959 }
1960
1961 ForwardMouseEventToRenderer(message, wparam, lparam);
1962 }
1963
OLDNEW
« no previous file with comments | « content/browser/renderer_host/render_widget_host_view_win.h ('k') | content/browser/renderer_host/test_render_view_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698