| 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 #include "content/browser/renderer_host/render_widget_host_view_win.h" | 5 #include "content/browser/renderer_host/render_widget_host_view_win.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 const int kMaxTooltipLength = 1024; | 81 const int kMaxTooltipLength = 1024; |
| 82 | 82 |
| 83 // A custom MSAA object id used to determine if a screen reader is actively | 83 // A custom MSAA object id used to determine if a screen reader is actively |
| 84 // listening for MSAA events. | 84 // listening for MSAA events. |
| 85 const int kIdCustom = 1; | 85 const int kIdCustom = 1; |
| 86 | 86 |
| 87 // The delay before the compositor host window is destroyed. This gives the GPU | 87 // The delay before the compositor host window is destroyed. This gives the GPU |
| 88 // process a grace period to stop referencing it. | 88 // process a grace period to stop referencing it. |
| 89 const int kDestroyCompositorHostWindowDelay = 10000; | 89 const int kDestroyCompositorHostWindowDelay = 10000; |
| 90 | 90 |
| 91 // In mouse lock mode, we need to prevent the (invisible) cursor from hitting |
| 92 // the border of the view, in order to get valid movement information. However, |
| 93 // forcing the cursor back to the center of the view after each mouse move |
| 94 // doesn't work well. It reduces the frequency of useful WM_MOUSEMOVE messages |
| 95 // significantly. Therefore, we move the cursor to the center of the view only |
| 96 // if it approaches the border. |kMouseLockBorderPercentage| specifies the width |
| 97 // of the border area, in percentage of the corresponding dimension. |
| 98 const int kMouseLockBorderPercentage = 15; |
| 99 |
| 91 // A callback function for EnumThreadWindows to enumerate and dismiss | 100 // A callback function for EnumThreadWindows to enumerate and dismiss |
| 92 // any owned popop windows | 101 // any owned popup windows. |
| 93 BOOL CALLBACK DismissOwnedPopups(HWND window, LPARAM arg) { | 102 BOOL CALLBACK DismissOwnedPopups(HWND window, LPARAM arg) { |
| 94 const HWND toplevel_hwnd = reinterpret_cast<HWND>(arg); | 103 const HWND toplevel_hwnd = reinterpret_cast<HWND>(arg); |
| 95 | 104 |
| 96 if (::IsWindowVisible(window)) { | 105 if (::IsWindowVisible(window)) { |
| 97 const HWND owner = ::GetWindow(window, GW_OWNER); | 106 const HWND owner = ::GetWindow(window, GW_OWNER); |
| 98 if (toplevel_hwnd == owner) { | 107 if (toplevel_hwnd == owner) { |
| 99 ::PostMessage(window, WM_CANCELMODE, 0, 0); | 108 ::PostMessage(window, WM_CANCELMODE, 0, 0); |
| 100 } | 109 } |
| 101 } | 110 } |
| 102 | 111 |
| (...skipping 1294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1397 last_pointer_down_location_ = 0; | 1406 last_pointer_down_location_ = 0; |
| 1398 if (last_location == lparam) | 1407 if (last_location == lparam) |
| 1399 return 0; | 1408 return 0; |
| 1400 } | 1409 } |
| 1401 | 1410 |
| 1402 if (message == WM_MOUSELEAVE) | 1411 if (message == WM_MOUSELEAVE) |
| 1403 ignore_mouse_movement_ = true; | 1412 ignore_mouse_movement_ = true; |
| 1404 | 1413 |
| 1405 if (mouse_locked_) { | 1414 if (mouse_locked_) { |
| 1406 HandleLockedMouseEvent(message, wparam, lparam); | 1415 HandleLockedMouseEvent(message, wparam, lparam); |
| 1407 MoveCursorToCenter(); | 1416 MoveCursorToCenterIfNecessary(); |
| 1408 return 0; | 1417 return 0; |
| 1409 } | 1418 } |
| 1410 | 1419 |
| 1411 if (::IsWindow(tooltip_hwnd_)) { | 1420 if (::IsWindow(tooltip_hwnd_)) { |
| 1412 // Forward mouse events through to the tooltip window | 1421 // Forward mouse events through to the tooltip window |
| 1413 MSG msg; | 1422 MSG msg; |
| 1414 msg.hwnd = m_hWnd; | 1423 msg.hwnd = m_hWnd; |
| 1415 msg.message = message; | 1424 msg.message = message; |
| 1416 msg.wParam = wparam; | 1425 msg.wParam = wparam; |
| 1417 msg.lParam = lparam; | 1426 msg.lParam = lparam; |
| (...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1885 // locked, no mouse message is relayed to the tooltip window, so we don't need | 1894 // locked, no mouse message is relayed to the tooltip window, so we don't need |
| 1886 // to worry that it will reappear. | 1895 // to worry that it will reappear. |
| 1887 if (::IsWindow(tooltip_hwnd_) && tooltip_showing_) { | 1896 if (::IsWindow(tooltip_hwnd_) && tooltip_showing_) { |
| 1888 ::SendMessage(tooltip_hwnd_, TTM_POP, 0, 0); | 1897 ::SendMessage(tooltip_hwnd_, TTM_POP, 0, 0); |
| 1889 // Sending a TTM_POP message doesn't seem to actually hide the tooltip | 1898 // Sending a TTM_POP message doesn't seem to actually hide the tooltip |
| 1890 // window, although we will receive a TTN_POP notification. As a result, | 1899 // window, although we will receive a TTN_POP notification. As a result, |
| 1891 // ShowWindow() is explicitly called to hide the window. | 1900 // ShowWindow() is explicitly called to hide the window. |
| 1892 ::ShowWindow(tooltip_hwnd_, SW_HIDE); | 1901 ::ShowWindow(tooltip_hwnd_, SW_HIDE); |
| 1893 } | 1902 } |
| 1894 | 1903 |
| 1895 // TODO(yzshen): Show an invisible cursor instead of using | 1904 // TODO(yzshen): ShowCursor(FALSE) causes SetCursorPos() to be ignored on |
| 1896 // ::ShowCursor(FALSE), so that MoveCursorToCenter() works with Remote | 1905 // Remote Desktop. |
| 1897 // Desktop. | |
| 1898 ::ShowCursor(FALSE); | 1906 ::ShowCursor(FALSE); |
| 1899 | 1907 |
| 1900 MoveCursorToCenter(); | 1908 move_to_center_request_.pending = false; |
| 1909 last_mouse_position_.locked_global = last_mouse_position_.unlocked_global; |
| 1910 MoveCursorToCenterIfNecessary(); |
| 1901 | 1911 |
| 1902 CRect rect; | 1912 CRect rect; |
| 1903 GetWindowRect(&rect); | 1913 GetWindowRect(&rect); |
| 1904 ::ClipCursor(&rect); | 1914 ::ClipCursor(&rect); |
| 1905 | 1915 |
| 1906 return true; | 1916 return true; |
| 1907 } | 1917 } |
| 1908 | 1918 |
| 1909 void RenderWidgetHostViewWin::UnlockMouse() { | 1919 void RenderWidgetHostViewWin::UnlockMouse() { |
| 1910 if (!mouse_locked_) | 1920 if (!mouse_locked_) |
| 1911 return; | 1921 return; |
| 1912 | 1922 |
| 1913 mouse_locked_ = false; | 1923 mouse_locked_ = false; |
| 1914 | 1924 |
| 1915 ::ClipCursor(NULL); | 1925 ::ClipCursor(NULL); |
| 1916 ::SetCursorPos(last_global_mouse_position_.x(), | 1926 ::SetCursorPos(last_mouse_position_.unlocked_global.x(), |
| 1917 last_global_mouse_position_.y()); | 1927 last_mouse_position_.unlocked_global.y()); |
| 1918 ::ShowCursor(TRUE); | 1928 ::ShowCursor(TRUE); |
| 1919 | 1929 |
| 1920 if (render_widget_host_) | 1930 if (render_widget_host_) |
| 1921 render_widget_host_->LostMouseLock(); | 1931 render_widget_host_->LostMouseLock(); |
| 1922 } | 1932 } |
| 1923 | 1933 |
| 1924 void RenderWidgetHostViewWin::Observe( | 1934 void RenderWidgetHostViewWin::Observe( |
| 1925 int type, | 1935 int type, |
| 1926 const content::NotificationSource& source, | 1936 const content::NotificationSource& source, |
| 1927 const content::NotificationDetails& details) { | 1937 const content::NotificationDetails& details) { |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2289 void RenderWidgetHostViewWin::ForwardMouseEventToRenderer(UINT message, | 2299 void RenderWidgetHostViewWin::ForwardMouseEventToRenderer(UINT message, |
| 2290 WPARAM wparam, | 2300 WPARAM wparam, |
| 2291 LPARAM lparam) { | 2301 LPARAM lparam) { |
| 2292 if (!render_widget_host_) | 2302 if (!render_widget_host_) |
| 2293 return; | 2303 return; |
| 2294 | 2304 |
| 2295 WebMouseEvent event( | 2305 WebMouseEvent event( |
| 2296 WebInputEventFactory::mouseEvent(m_hWnd, message, wparam, lparam)); | 2306 WebInputEventFactory::mouseEvent(m_hWnd, message, wparam, lparam)); |
| 2297 | 2307 |
| 2298 if (mouse_locked_) { | 2308 if (mouse_locked_) { |
| 2299 CPoint center = GetClientCenter(); | 2309 event.movementX = event.globalX - last_mouse_position_.locked_global.x(); |
| 2310 event.movementY = event.globalY - last_mouse_position_.locked_global.y(); |
| 2311 last_mouse_position_.locked_global.SetPoint(event.globalX, event.globalY); |
| 2300 | 2312 |
| 2301 event.movementX = event.windowX - center.x; | 2313 event.x = last_mouse_position_.unlocked.x(); |
| 2302 event.movementY = event.windowY - center.y; | 2314 event.y = last_mouse_position_.unlocked.y(); |
| 2303 event.x = last_mouse_position_.x(); | 2315 event.windowX = last_mouse_position_.unlocked.x(); |
| 2304 event.y = last_mouse_position_.y(); | 2316 event.windowY = last_mouse_position_.unlocked.y(); |
| 2305 event.windowX = last_mouse_position_.x(); | 2317 event.globalX = last_mouse_position_.unlocked_global.x(); |
| 2306 event.windowY = last_mouse_position_.y(); | 2318 event.globalY = last_mouse_position_.unlocked_global.y(); |
| 2307 event.globalX = last_global_mouse_position_.x(); | |
| 2308 event.globalY = last_global_mouse_position_.y(); | |
| 2309 } else { | 2319 } else { |
| 2310 if (ignore_mouse_movement_) { | 2320 if (ignore_mouse_movement_) { |
| 2311 ignore_mouse_movement_ = false; | 2321 ignore_mouse_movement_ = false; |
| 2312 event.movementX = 0; | 2322 event.movementX = 0; |
| 2313 event.movementY = 0; | 2323 event.movementY = 0; |
| 2314 } else { | 2324 } else { |
| 2315 event.movementX = event.globalX - last_global_mouse_position_.x(); | 2325 event.movementX = |
| 2316 event.movementY = event.globalY - last_global_mouse_position_.y(); | 2326 event.globalX - last_mouse_position_.unlocked_global.x(); |
| 2327 event.movementY = |
| 2328 event.globalY - last_mouse_position_.unlocked_global.y(); |
| 2317 } | 2329 } |
| 2318 | 2330 |
| 2319 last_mouse_position_.SetPoint(event.windowX, event.windowY); | 2331 last_mouse_position_.unlocked.SetPoint(event.windowX, event.windowY); |
| 2320 last_global_mouse_position_.SetPoint(event.globalX, event.globalY); | 2332 last_mouse_position_.unlocked_global.SetPoint(event.globalX, event.globalY); |
| 2321 } | 2333 } |
| 2322 | 2334 |
| 2323 // Send the event to the renderer before changing mouse capture, so that the | 2335 // Send the event to the renderer before changing mouse capture, so that the |
| 2324 // capturelost event arrives after mouseup. | 2336 // capturelost event arrives after mouseup. |
| 2325 render_widget_host_->ForwardMouseEvent(event); | 2337 render_widget_host_->ForwardMouseEvent(event); |
| 2326 | 2338 |
| 2327 switch (event.type) { | 2339 switch (event.type) { |
| 2328 case WebInputEvent::MouseMove: | 2340 case WebInputEvent::MouseMove: |
| 2329 TrackMouseLeave(true); | 2341 TrackMouseLeave(true); |
| 2330 break; | 2342 break; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2368 EnsureTooltip(); | 2380 EnsureTooltip(); |
| 2369 ShowWindow(IsActivatable() ? SW_SHOW : SW_SHOWNA); | 2381 ShowWindow(IsActivatable() ? SW_SHOW : SW_SHOWNA); |
| 2370 } | 2382 } |
| 2371 | 2383 |
| 2372 CPoint RenderWidgetHostViewWin::GetClientCenter() const { | 2384 CPoint RenderWidgetHostViewWin::GetClientCenter() const { |
| 2373 CRect rect; | 2385 CRect rect; |
| 2374 GetClientRect(&rect); | 2386 GetClientRect(&rect); |
| 2375 return rect.CenterPoint(); | 2387 return rect.CenterPoint(); |
| 2376 } | 2388 } |
| 2377 | 2389 |
| 2378 void RenderWidgetHostViewWin::MoveCursorToCenter() const { | 2390 void RenderWidgetHostViewWin::MoveCursorToCenterIfNecessary() { |
| 2379 CPoint center = GetClientCenter(); | 2391 DCHECK(mouse_locked_); |
| 2380 ClientToScreen(¢er); | 2392 |
| 2381 if (!::SetCursorPos(center.x, center.y)) | 2393 CRect rect; |
| 2382 LOG_GETLASTERROR(WARNING) << "Failed to set cursor position."; | 2394 GetWindowRect(&rect); |
| 2395 int border_x = rect.Width() * kMouseLockBorderPercentage / 100; |
| 2396 int border_y = rect.Height() * kMouseLockBorderPercentage / 100; |
| 2397 |
| 2398 bool should_move = |
| 2399 last_mouse_position_.locked_global.x() < rect.left + border_x || |
| 2400 last_mouse_position_.locked_global.x() > rect.right - border_x || |
| 2401 last_mouse_position_.locked_global.y() < rect.top + border_y || |
| 2402 last_mouse_position_.locked_global.y() > rect.bottom - border_y; |
| 2403 |
| 2404 if (should_move) { |
| 2405 move_to_center_request_.pending = true; |
| 2406 move_to_center_request_.target = rect.CenterPoint(); |
| 2407 if (!::SetCursorPos(move_to_center_request_.target.x(), |
| 2408 move_to_center_request_.target.y())) { |
| 2409 LOG_GETLASTERROR(WARNING) << "Failed to set cursor position."; |
| 2410 } |
| 2411 } |
| 2383 } | 2412 } |
| 2384 | 2413 |
| 2385 void RenderWidgetHostViewWin::HandleLockedMouseEvent(UINT message, | 2414 void RenderWidgetHostViewWin::HandleLockedMouseEvent(UINT message, |
| 2386 WPARAM wparam, | 2415 WPARAM wparam, |
| 2387 LPARAM lparam) { | 2416 LPARAM lparam) { |
| 2388 DCHECK(mouse_locked_); | 2417 DCHECK(mouse_locked_); |
| 2389 | 2418 |
| 2390 if (message == WM_MOUSEMOVE) { | 2419 if (message == WM_MOUSEMOVE && move_to_center_request_.pending) { |
| 2391 CPoint center = GetClientCenter(); | 2420 // Ignore WM_MOUSEMOVE messages generated by |
| 2392 // Ignore WM_MOUSEMOVE messages generated by MoveCursorToCenter(). | 2421 // MoveCursorToCenterIfNecessary(). |
| 2393 if (LOWORD(lparam) == center.x && HIWORD(lparam) == center.y) | 2422 CPoint current_position(LOWORD(lparam), HIWORD(lparam)); |
| 2423 ClientToScreen(¤t_position); |
| 2424 if (move_to_center_request_.target.x() == current_position.x && |
| 2425 move_to_center_request_.target.y() == current_position.y) { |
| 2426 move_to_center_request_.pending = false; |
| 2427 last_mouse_position_.locked_global = move_to_center_request_.target; |
| 2394 return; | 2428 return; |
| 2429 } |
| 2395 } | 2430 } |
| 2396 | 2431 |
| 2397 ForwardMouseEventToRenderer(message, wparam, lparam); | 2432 ForwardMouseEventToRenderer(message, wparam, lparam); |
| 2398 } | 2433 } |
| 2399 | 2434 |
| 2400 LRESULT RenderWidgetHostViewWin::OnDocumentFeed(RECONVERTSTRING* reconv) { | 2435 LRESULT RenderWidgetHostViewWin::OnDocumentFeed(RECONVERTSTRING* reconv) { |
| 2401 size_t target_offset; | 2436 size_t target_offset; |
| 2402 size_t target_length; | 2437 size_t target_length; |
| 2403 bool has_composition; | 2438 bool has_composition; |
| 2404 if (!composition_range_.is_empty()) { | 2439 if (!composition_range_.is_empty()) { |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2480 | 2515 |
| 2481 size_t offset = selection_range_.GetMin() - selection_text_offset_; | 2516 size_t offset = selection_range_.GetMin() - selection_text_offset_; |
| 2482 memcpy(reinterpret_cast<char*>(reconv) + sizeof(RECONVERTSTRING), | 2517 memcpy(reinterpret_cast<char*>(reconv) + sizeof(RECONVERTSTRING), |
| 2483 selection_text_.c_str() + offset, len * sizeof(WCHAR)); | 2518 selection_text_.c_str() + offset, len * sizeof(WCHAR)); |
| 2484 | 2519 |
| 2485 // According to Microsft API document, IMR_RECONVERTSTRING and | 2520 // According to Microsft API document, IMR_RECONVERTSTRING and |
| 2486 // IMR_DOCUMENTFEED should return reconv, but some applications return | 2521 // IMR_DOCUMENTFEED should return reconv, but some applications return |
| 2487 // need_size. | 2522 // need_size. |
| 2488 return reinterpret_cast<LRESULT>(reconv); | 2523 return reinterpret_cast<LRESULT>(reconv); |
| 2489 } | 2524 } |
| OLD | NEW |