OLD | NEW |
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 Loading... |
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 last_x_(0), |
| 248 last_y_(0), |
| 249 last_global_x_(0), |
| 250 last_global_y_(0), |
| 251 ignore_mouse_movement_(true) { |
247 render_widget_host_->SetView(this); | 252 render_widget_host_->SetView(this); |
248 registrar_.Add(this, | 253 registrar_.Add(this, |
249 content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, | 254 content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
250 NotificationService::AllSources()); | 255 NotificationService::AllSources()); |
251 } | 256 } |
252 | 257 |
253 RenderWidgetHostViewWin::~RenderWidgetHostViewWin() { | 258 RenderWidgetHostViewWin::~RenderWidgetHostViewWin() { |
| 259 UnlockMouse(); |
254 ResetTooltip(); | 260 ResetTooltip(); |
255 } | 261 } |
256 | 262 |
257 void RenderWidgetHostViewWin::CreateWnd(HWND parent) { | 263 void RenderWidgetHostViewWin::CreateWnd(HWND parent) { |
258 Create(parent); // ATL function to create the window. | 264 Create(parent); // ATL function to create the window. |
259 } | 265 } |
260 | 266 |
261 /////////////////////////////////////////////////////////////////////////////// | 267 /////////////////////////////////////////////////////////////////////////////// |
262 // RenderWidgetHostViewWin, RenderWidgetHostView implementation: | 268 // RenderWidgetHostViewWin, RenderWidgetHostView implementation: |
263 | 269 |
(...skipping 958 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1222 ime_input_.DestroyImeWindow(m_hWnd); | 1228 ime_input_.DestroyImeWindow(m_hWnd); |
1223 // Let WTL call ::DefWindowProc() and release its resources. | 1229 // Let WTL call ::DefWindowProc() and release its resources. |
1224 handled = FALSE; | 1230 handled = FALSE; |
1225 return 0; | 1231 return 0; |
1226 } | 1232 } |
1227 | 1233 |
1228 LRESULT RenderWidgetHostViewWin::OnMouseEvent(UINT message, WPARAM wparam, | 1234 LRESULT RenderWidgetHostViewWin::OnMouseEvent(UINT message, WPARAM wparam, |
1229 LPARAM lparam, BOOL& handled) { | 1235 LPARAM lparam, BOOL& handled) { |
1230 handled = TRUE; | 1236 handled = TRUE; |
1231 | 1237 |
| 1238 if (message == WM_MOUSELEAVE) |
| 1239 ignore_mouse_movement_ = true; |
| 1240 |
| 1241 if (mouse_locked_) { |
| 1242 HandleLockedMouseEvent(message, wparam, lparam); |
| 1243 MoveCursorToCenter(); |
| 1244 return 0; |
| 1245 } |
| 1246 |
| 1247 // TODO(yzshen): is this correct? Nothing goes to the tool tip window? |
1232 if (::IsWindow(tooltip_hwnd_)) { | 1248 if (::IsWindow(tooltip_hwnd_)) { |
1233 // Forward mouse events through to the tooltip window | 1249 // Forward mouse events through to the tooltip window |
1234 MSG msg; | 1250 MSG msg; |
1235 msg.hwnd = m_hWnd; | 1251 msg.hwnd = m_hWnd; |
1236 msg.message = message; | 1252 msg.message = message; |
1237 msg.wParam = wparam; | 1253 msg.wParam = wparam; |
1238 msg.lParam = lparam; | 1254 msg.lParam = lparam; |
1239 SendMessage(tooltip_hwnd_, TTM_RELAYEVENT, NULL, | 1255 SendMessage(tooltip_hwnd_, TTM_RELAYEVENT, NULL, |
1240 reinterpret_cast<LPARAM>(&msg)); | 1256 reinterpret_cast<LPARAM>(&msg)); |
1241 } | 1257 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1285 | 1301 |
1286 ForwardMouseEventToRenderer(message, wparam, lparam); | 1302 ForwardMouseEventToRenderer(message, wparam, lparam); |
1287 return 0; | 1303 return 0; |
1288 } | 1304 } |
1289 | 1305 |
1290 LRESULT RenderWidgetHostViewWin::OnKeyEvent(UINT message, WPARAM wparam, | 1306 LRESULT RenderWidgetHostViewWin::OnKeyEvent(UINT message, WPARAM wparam, |
1291 LPARAM lparam, BOOL& handled) { | 1307 LPARAM lparam, BOOL& handled) { |
1292 handled = TRUE; | 1308 handled = TRUE; |
1293 | 1309 |
1294 // Force fullscreen windows to close on Escape. | 1310 // Force fullscreen windows to close on Escape. |
1295 if (is_fullscreen_ && (message == WM_KEYDOWN || message == WM_KEYUP) && | 1311 if ((message == WM_KEYDOWN || message == WM_KEYUP) && wparam == VK_ESCAPE) { |
1296 wparam == VK_ESCAPE) { | 1312 if (mouse_locked_) |
1297 SendMessage(WM_CANCELMODE); | 1313 UnlockMouse(); |
1298 return 0; | 1314 if (is_fullscreen_) |
| 1315 SendMessage(WM_CANCELMODE); |
| 1316 return 0; |
1299 } | 1317 } |
1300 | 1318 |
1301 // If we are a pop-up, forward tab related messages to our parent HWND, so | 1319 // If we are a pop-up, forward tab related messages to our parent HWND, so |
1302 // that we are dismissed appropriately and so that the focus advance in our | 1320 // that we are dismissed appropriately and so that the focus advance in our |
1303 // parent. | 1321 // parent. |
1304 // TODO(jcampan): http://b/issue?id=1192881 Could be abstracted in the | 1322 // TODO(jcampan): http://b/issue?id=1192881 Could be abstracted in the |
1305 // FocusManager. | 1323 // FocusManager. |
1306 if (close_on_deactivate_ && | 1324 if (close_on_deactivate_ && |
1307 (((message == WM_KEYDOWN || message == WM_KEYUP) && (wparam == VK_TAB)) || | 1325 (((message == WM_KEYDOWN || message == WM_KEYUP) && (wparam == VK_TAB)) || |
1308 (message == WM_CHAR && wparam == L'\t'))) { | 1326 (message == WM_CHAR && wparam == L'\t'))) { |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1473 void RenderWidgetHostViewWin::OnAccessibilityNotifications( | 1491 void RenderWidgetHostViewWin::OnAccessibilityNotifications( |
1474 const std::vector<ViewHostMsg_AccessibilityNotification_Params>& params) { | 1492 const std::vector<ViewHostMsg_AccessibilityNotification_Params>& params) { |
1475 if (!browser_accessibility_manager_.get()) { | 1493 if (!browser_accessibility_manager_.get()) { |
1476 browser_accessibility_manager_.reset( | 1494 browser_accessibility_manager_.reset( |
1477 BrowserAccessibilityManager::CreateEmptyDocument( | 1495 BrowserAccessibilityManager::CreateEmptyDocument( |
1478 m_hWnd, static_cast<WebAccessibility::State>(0), this)); | 1496 m_hWnd, static_cast<WebAccessibility::State>(0), this)); |
1479 } | 1497 } |
1480 browser_accessibility_manager_->OnAccessibilityNotifications(params); | 1498 browser_accessibility_manager_->OnAccessibilityNotifications(params); |
1481 } | 1499 } |
1482 | 1500 |
| 1501 bool RenderWidgetHostViewWin::LockMouse() { |
| 1502 if (mouse_locked_) |
| 1503 return true; |
| 1504 |
| 1505 mouse_locked_ = true; |
| 1506 // TODO(yzshen): (1) Make sure it works with the current_cursor_. |
| 1507 // (2) if not confined successful, we can tell once we receive |
| 1508 // mouse leave message, does that help? |
| 1509 // (3) ResetTooltip / EnsureTooltip, and make sure they work |
| 1510 // consistently with other part of the code. |
| 1511 |
| 1512 // TODO(yzshen): Show an invisible cursor instead of using |
| 1513 // ::ShowCursor(FALSE), so that MoveCursorToCenter() works with Remote |
| 1514 // Desktop. |
| 1515 ::ShowCursor(FALSE); |
| 1516 |
| 1517 MoveCursorToCenter(); |
| 1518 |
| 1519 CRect rect; |
| 1520 GetWindowRect(&rect); |
| 1521 ::ClipCursor(&rect); |
| 1522 |
| 1523 return true; |
| 1524 } |
| 1525 |
| 1526 void RenderWidgetHostViewWin::UnlockMouse() { |
| 1527 if (!mouse_locked_) |
| 1528 return; |
| 1529 |
| 1530 mouse_locked_ = false; |
| 1531 |
| 1532 ::ClipCursor(NULL); |
| 1533 ::SetCursorPos(last_global_x_, last_global_y_); |
| 1534 ::ShowCursor(TRUE); |
| 1535 |
| 1536 if (render_widget_host_) |
| 1537 render_widget_host_->LostMouseLock(); |
| 1538 } |
| 1539 |
1483 void RenderWidgetHostViewWin::Observe(int type, | 1540 void RenderWidgetHostViewWin::Observe(int type, |
1484 const NotificationSource& source, | 1541 const NotificationSource& source, |
1485 const NotificationDetails& details) { | 1542 const NotificationDetails& details) { |
1486 DCHECK(type == content::NOTIFICATION_RENDERER_PROCESS_TERMINATED); | 1543 DCHECK(type == content::NOTIFICATION_RENDERER_PROCESS_TERMINATED); |
1487 | 1544 |
1488 // Get the RenderProcessHost that posted this notification, and exit | 1545 // Get the RenderProcessHost that posted this notification, and exit |
1489 // if it's not the one associated with this host view. | 1546 // if it's not the one associated with this host view. |
1490 RenderProcessHost* render_process_host = | 1547 RenderProcessHost* render_process_host = |
1491 Source<RenderProcessHost>(source).ptr(); | 1548 Source<RenderProcessHost>(source).ptr(); |
1492 DCHECK(render_process_host); | 1549 DCHECK(render_process_host); |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1793 | 1850 |
1794 void RenderWidgetHostViewWin::ForwardMouseEventToRenderer(UINT message, | 1851 void RenderWidgetHostViewWin::ForwardMouseEventToRenderer(UINT message, |
1795 WPARAM wparam, | 1852 WPARAM wparam, |
1796 LPARAM lparam) { | 1853 LPARAM lparam) { |
1797 if (!render_widget_host_) | 1854 if (!render_widget_host_) |
1798 return; | 1855 return; |
1799 | 1856 |
1800 WebMouseEvent event( | 1857 WebMouseEvent event( |
1801 WebInputEventFactory::mouseEvent(m_hWnd, message, wparam, lparam)); | 1858 WebInputEventFactory::mouseEvent(m_hWnd, message, wparam, lparam)); |
1802 | 1859 |
| 1860 if (mouse_locked_) { |
| 1861 CPoint center = GetClientCenter(); |
| 1862 |
| 1863 event.movementX = event.windowX - center.x; |
| 1864 event.movementY = event.windowY - center.y; |
| 1865 event.x = last_x_; |
| 1866 event.y = last_y_; |
| 1867 event.windowX = last_x_; |
| 1868 event.windowY = last_y_; |
| 1869 event.globalX = last_global_x_; |
| 1870 event.globalY = last_global_y_; |
| 1871 } else { |
| 1872 if (ignore_mouse_movement_) { |
| 1873 ignore_mouse_movement_ = false; |
| 1874 event.movementX = 0; |
| 1875 event.movementY = 0; |
| 1876 } else { |
| 1877 event.movementX = event.globalX - last_global_x_; |
| 1878 event.movementY = event.globalY - last_global_y_; |
| 1879 } |
| 1880 |
| 1881 last_x_ = event.windowX; |
| 1882 last_y_ = event.windowY; |
| 1883 last_global_x_ = event.globalX; |
| 1884 last_global_y_ = event.globalY; |
| 1885 } |
| 1886 |
1803 // 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 |
1804 // capturelost event arrives after mouseup. | 1888 // capturelost event arrives after mouseup. |
1805 render_widget_host_->ForwardMouseEvent(event); | 1889 render_widget_host_->ForwardMouseEvent(event); |
1806 | 1890 |
1807 switch (event.type) { | 1891 switch (event.type) { |
1808 case WebInputEvent::MouseMove: | 1892 case WebInputEvent::MouseMove: |
1809 TrackMouseLeave(true); | 1893 TrackMouseLeave(true); |
1810 break; | 1894 break; |
1811 case WebInputEvent::MouseLeave: | 1895 case WebInputEvent::MouseLeave: |
1812 TrackMouseLeave(false); | 1896 TrackMouseLeave(false); |
1813 break; | 1897 break; |
1814 case WebInputEvent::MouseDown: | 1898 case WebInputEvent::MouseDown: |
1815 SetCapture(); | 1899 SetCapture(); |
1816 break; | 1900 break; |
1817 case WebInputEvent::MouseUp: | 1901 case WebInputEvent::MouseUp: |
1818 if (GetCapture() == m_hWnd) | 1902 if (GetCapture() == m_hWnd) |
1819 ReleaseCapture(); | 1903 ReleaseCapture(); |
1820 break; | 1904 break; |
1821 } | 1905 } |
1822 | 1906 |
1823 if (IsActivatable() && event.type == WebInputEvent::MouseDown) { | 1907 if (IsActivatable() && event.type == WebInputEvent::MouseDown) { |
1824 // This is a temporary workaround for bug 765011 to get focus when the | 1908 // This is a temporary workaround for bug 765011 to get focus when the |
1825 // mouse is clicked. This happens after the mouse down event is sent to | 1909 // mouse is clicked. This happens after the mouse down event is sent to |
1826 // the renderer because normally Windows does a WM_SETFOCUS after | 1910 // the renderer because normally Windows does a WM_SETFOCUS after |
1827 // WM_LBUTTONDOWN. | 1911 // WM_LBUTTONDOWN. |
1828 SetFocus(); | 1912 SetFocus(); |
1829 } | 1913 } |
| 1914 |
1830 } | 1915 } |
1831 | 1916 |
1832 void RenderWidgetHostViewWin::ShutdownHost() { | 1917 void RenderWidgetHostViewWin::ShutdownHost() { |
1833 shutdown_factory_.RevokeAll(); | 1918 shutdown_factory_.RevokeAll(); |
1834 if (render_widget_host_) | 1919 if (render_widget_host_) |
1835 render_widget_host_->Shutdown(); | 1920 render_widget_host_->Shutdown(); |
1836 // Do not touch any members at this point, |this| has been deleted. | 1921 // Do not touch any members at this point, |this| has been deleted. |
1837 } | 1922 } |
1838 | 1923 |
1839 void RenderWidgetHostViewWin::DoPopupOrFullscreenInit(HWND parent_hwnd, | 1924 void RenderWidgetHostViewWin::DoPopupOrFullscreenInit(HWND parent_hwnd, |
1840 const gfx::Rect& pos, | 1925 const gfx::Rect& pos, |
1841 DWORD ex_style) { | 1926 DWORD ex_style) { |
1842 parent_hwnd_ = parent_hwnd; | 1927 parent_hwnd_ = parent_hwnd; |
1843 Create(parent_hwnd_, NULL, NULL, WS_POPUP, ex_style); | 1928 Create(parent_hwnd_, NULL, NULL, WS_POPUP, ex_style); |
1844 MoveWindow(pos.x(), pos.y(), pos.width(), pos.height(), TRUE); | 1929 MoveWindow(pos.x(), pos.y(), pos.width(), pos.height(), TRUE); |
1845 // To show tooltip on popup window.(e.g. title in <select>) | 1930 // To show tooltip on popup window.(e.g. title in <select>) |
1846 // Popups default to showing, which means |DidBecomeSelected()| isn't invoked. | 1931 // Popups default to showing, which means |DidBecomeSelected()| isn't invoked. |
1847 // Ensure the tooltip is created otherwise tooltips are never shown. | 1932 // Ensure the tooltip is created otherwise tooltips are never shown. |
1848 EnsureTooltip(); | 1933 EnsureTooltip(); |
1849 ShowWindow(IsActivatable() ? SW_SHOW : SW_SHOWNA); | 1934 ShowWindow(IsActivatable() ? SW_SHOW : SW_SHOWNA); |
1850 } | 1935 } |
| 1936 |
| 1937 CPoint RenderWidgetHostViewWin::GetClientCenter() const { |
| 1938 CRect rect; |
| 1939 GetClientRect(&rect); |
| 1940 return rect.CenterPoint(); |
| 1941 } |
| 1942 |
| 1943 void RenderWidgetHostViewWin::MoveCursorToCenter() const { |
| 1944 CPoint center = GetClientCenter(); |
| 1945 ClientToScreen(¢er); |
| 1946 if (!::SetCursorPos(center.x, center.y)) |
| 1947 LOG_GETLASTERROR(WARNING) << "Failed to set cursor position."; |
| 1948 } |
| 1949 |
| 1950 void RenderWidgetHostViewWin::HandleLockedMouseEvent(UINT message, |
| 1951 WPARAM wparam, |
| 1952 LPARAM lparam) { |
| 1953 DCHECK(mouse_locked_); |
| 1954 |
| 1955 if (message == WM_MOUSEMOVE) { |
| 1956 CPoint center = GetClientCenter(); |
| 1957 // Ignore WM_MOUSEMOVE messages generated by MoveCursorToCenter(). |
| 1958 if (LOWORD(lparam) == center.x && HIWORD(lparam) == center.y) |
| 1959 return; |
| 1960 } |
| 1961 |
| 1962 ForwardMouseEventToRenderer(message, wparam, lparam); |
| 1963 } |
| 1964 |
OLD | NEW |