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, the cursor needs to be moved to the center of the view if | |
92 // it approaches the border. |kMouseLockBorderPercentage| specifies the width of | |
93 // the border area, in percentage of the corresponding dimension. | |
94 const int kMouseLockBorderPercentage = 15; | |
95 | |
91 // A callback function for EnumThreadWindows to enumerate and dismiss | 96 // A callback function for EnumThreadWindows to enumerate and dismiss |
92 // any owned popop windows | 97 // any owned popop windows |
93 BOOL CALLBACK DismissOwnedPopups(HWND window, LPARAM arg) { | 98 BOOL CALLBACK DismissOwnedPopups(HWND window, LPARAM arg) { |
94 const HWND toplevel_hwnd = reinterpret_cast<HWND>(arg); | 99 const HWND toplevel_hwnd = reinterpret_cast<HWND>(arg); |
95 | 100 |
96 if (::IsWindowVisible(window)) { | 101 if (::IsWindowVisible(window)) { |
97 const HWND owner = ::GetWindow(window, GW_OWNER); | 102 const HWND owner = ::GetWindow(window, GW_OWNER); |
98 if (toplevel_hwnd == owner) { | 103 if (toplevel_hwnd == owner) { |
99 ::PostMessage(window, WM_CANCELMODE, 0, 0); | 104 ::PostMessage(window, WM_CANCELMODE, 0, 0); |
100 } | 105 } |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
327 close_on_deactivate_(false), | 332 close_on_deactivate_(false), |
328 being_destroyed_(false), | 333 being_destroyed_(false), |
329 tooltip_hwnd_(NULL), | 334 tooltip_hwnd_(NULL), |
330 tooltip_showing_(false), | 335 tooltip_showing_(false), |
331 weak_factory_(this), | 336 weak_factory_(this), |
332 parent_hwnd_(NULL), | 337 parent_hwnd_(NULL), |
333 is_loading_(false), | 338 is_loading_(false), |
334 overlay_color_(0), | 339 overlay_color_(0), |
335 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), | 340 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), |
336 is_fullscreen_(false), | 341 is_fullscreen_(false), |
342 ignore_move_to_center_message_(false), | |
337 ignore_mouse_movement_(true), | 343 ignore_mouse_movement_(true), |
338 composition_range_(ui::Range::InvalidRange()), | 344 composition_range_(ui::Range::InvalidRange()), |
339 ignore_next_lbutton_message_at_same_location(false), | 345 ignore_next_lbutton_message_at_same_location(false), |
340 last_pointer_down_location_(0), | 346 last_pointer_down_location_(0), |
341 touch_state_(this) { | 347 touch_state_(this) { |
342 render_widget_host_->SetView(this); | 348 render_widget_host_->SetView(this); |
343 registrar_.Add(this, | 349 registrar_.Add(this, |
344 content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, | 350 content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
345 content::NotificationService::AllBrowserContextsAndSources()); | 351 content::NotificationService::AllBrowserContextsAndSources()); |
346 } | 352 } |
(...skipping 1050 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1397 last_pointer_down_location_ = 0; | 1403 last_pointer_down_location_ = 0; |
1398 if (last_location == lparam) | 1404 if (last_location == lparam) |
1399 return 0; | 1405 return 0; |
1400 } | 1406 } |
1401 | 1407 |
1402 if (message == WM_MOUSELEAVE) | 1408 if (message == WM_MOUSELEAVE) |
1403 ignore_mouse_movement_ = true; | 1409 ignore_mouse_movement_ = true; |
1404 | 1410 |
1405 if (mouse_locked_) { | 1411 if (mouse_locked_) { |
1406 HandleLockedMouseEvent(message, wparam, lparam); | 1412 HandleLockedMouseEvent(message, wparam, lparam); |
1407 MoveCursorToCenter(); | 1413 MoveCursorToCenterIfNecessary(); |
1408 return 0; | 1414 return 0; |
1409 } | 1415 } |
1410 | 1416 |
1411 if (::IsWindow(tooltip_hwnd_)) { | 1417 if (::IsWindow(tooltip_hwnd_)) { |
1412 // Forward mouse events through to the tooltip window | 1418 // Forward mouse events through to the tooltip window |
1413 MSG msg; | 1419 MSG msg; |
1414 msg.hwnd = m_hWnd; | 1420 msg.hwnd = m_hWnd; |
1415 msg.message = message; | 1421 msg.message = message; |
1416 msg.wParam = wparam; | 1422 msg.wParam = wparam; |
1417 msg.lParam = lparam; | 1423 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 | 1891 // locked, no mouse message is relayed to the tooltip window, so we don't need |
1886 // to worry that it will reappear. | 1892 // to worry that it will reappear. |
1887 if (::IsWindow(tooltip_hwnd_) && tooltip_showing_) { | 1893 if (::IsWindow(tooltip_hwnd_) && tooltip_showing_) { |
1888 ::SendMessage(tooltip_hwnd_, TTM_POP, 0, 0); | 1894 ::SendMessage(tooltip_hwnd_, TTM_POP, 0, 0); |
1889 // Sending a TTM_POP message doesn't seem to actually hide the tooltip | 1895 // 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, | 1896 // window, although we will receive a TTN_POP notification. As a result, |
1891 // ShowWindow() is explicitly called to hide the window. | 1897 // ShowWindow() is explicitly called to hide the window. |
1892 ::ShowWindow(tooltip_hwnd_, SW_HIDE); | 1898 ::ShowWindow(tooltip_hwnd_, SW_HIDE); |
1893 } | 1899 } |
1894 | 1900 |
1895 // TODO(yzshen): Show an invisible cursor instead of using | 1901 // TODO(yzshen): ShowCursor(FALSE) causes SetCursorPos() to be ignored on |
1896 // ::ShowCursor(FALSE), so that MoveCursorToCenter() works with Remote | 1902 // Remote Desktop. |
1897 // Desktop. | |
1898 ::ShowCursor(FALSE); | 1903 ::ShowCursor(FALSE); |
1899 | 1904 |
1900 MoveCursorToCenter(); | 1905 last_locked_global_mouse_position_ = last_unlocked_global_mouse_position_; |
1906 MoveCursorToCenterIfNecessary(); | |
1901 | 1907 |
1902 CRect rect; | 1908 CRect rect; |
1903 GetWindowRect(&rect); | 1909 GetWindowRect(&rect); |
1904 ::ClipCursor(&rect); | 1910 ::ClipCursor(&rect); |
1905 | 1911 |
1906 return true; | 1912 return true; |
1907 } | 1913 } |
1908 | 1914 |
1909 void RenderWidgetHostViewWin::UnlockMouse() { | 1915 void RenderWidgetHostViewWin::UnlockMouse() { |
1910 if (!mouse_locked_) | 1916 if (!mouse_locked_) |
1911 return; | 1917 return; |
1912 | 1918 |
1913 mouse_locked_ = false; | 1919 mouse_locked_ = false; |
1914 | 1920 |
1915 ::ClipCursor(NULL); | 1921 ::ClipCursor(NULL); |
1916 ::SetCursorPos(last_global_mouse_position_.x(), | 1922 ::SetCursorPos(last_unlocked_global_mouse_position_.x(), |
1917 last_global_mouse_position_.y()); | 1923 last_unlocked_global_mouse_position_.y()); |
1918 ::ShowCursor(TRUE); | 1924 ::ShowCursor(TRUE); |
1919 | 1925 |
1920 if (render_widget_host_) | 1926 if (render_widget_host_) |
1921 render_widget_host_->LostMouseLock(); | 1927 render_widget_host_->LostMouseLock(); |
1922 } | 1928 } |
1923 | 1929 |
1924 void RenderWidgetHostViewWin::Observe( | 1930 void RenderWidgetHostViewWin::Observe( |
1925 int type, | 1931 int type, |
1926 const content::NotificationSource& source, | 1932 const content::NotificationSource& source, |
1927 const content::NotificationDetails& details) { | 1933 const content::NotificationDetails& details) { |
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2289 void RenderWidgetHostViewWin::ForwardMouseEventToRenderer(UINT message, | 2295 void RenderWidgetHostViewWin::ForwardMouseEventToRenderer(UINT message, |
2290 WPARAM wparam, | 2296 WPARAM wparam, |
2291 LPARAM lparam) { | 2297 LPARAM lparam) { |
2292 if (!render_widget_host_) | 2298 if (!render_widget_host_) |
2293 return; | 2299 return; |
2294 | 2300 |
2295 WebMouseEvent event( | 2301 WebMouseEvent event( |
2296 WebInputEventFactory::mouseEvent(m_hWnd, message, wparam, lparam)); | 2302 WebInputEventFactory::mouseEvent(m_hWnd, message, wparam, lparam)); |
2297 | 2303 |
2298 if (mouse_locked_) { | 2304 if (mouse_locked_) { |
2299 CPoint center = GetClientCenter(); | 2305 event.movementX = event.globalX - last_locked_global_mouse_position_.x(); |
2306 event.movementY = event.globalY - last_locked_global_mouse_position_.y(); | |
2307 last_locked_global_mouse_position_.SetPoint(event.globalX, event.globalY); | |
2300 | 2308 |
2301 event.movementX = event.windowX - center.x; | 2309 event.x = last_unlocked_mouse_position_.x(); |
2302 event.movementY = event.windowY - center.y; | 2310 event.y = last_unlocked_mouse_position_.y(); |
2303 event.x = last_mouse_position_.x(); | 2311 event.windowX = last_unlocked_mouse_position_.x(); |
2304 event.y = last_mouse_position_.y(); | 2312 event.windowY = last_unlocked_mouse_position_.y(); |
2305 event.windowX = last_mouse_position_.x(); | 2313 event.globalX = last_unlocked_global_mouse_position_.x(); |
2306 event.windowY = last_mouse_position_.y(); | 2314 event.globalY = last_unlocked_global_mouse_position_.y(); |
2307 event.globalX = last_global_mouse_position_.x(); | |
2308 event.globalY = last_global_mouse_position_.y(); | |
2309 } else { | 2315 } else { |
2310 if (ignore_mouse_movement_) { | 2316 if (ignore_mouse_movement_) { |
2311 ignore_mouse_movement_ = false; | 2317 ignore_mouse_movement_ = false; |
2312 event.movementX = 0; | 2318 event.movementX = 0; |
2313 event.movementY = 0; | 2319 event.movementY = 0; |
2314 } else { | 2320 } else { |
2315 event.movementX = event.globalX - last_global_mouse_position_.x(); | 2321 event.movementX = |
2316 event.movementY = event.globalY - last_global_mouse_position_.y(); | 2322 event.globalX - last_unlocked_global_mouse_position_.x(); |
2323 event.movementY = | |
2324 event.globalY - last_unlocked_global_mouse_position_.y(); | |
2317 } | 2325 } |
2318 | 2326 |
2319 last_mouse_position_.SetPoint(event.windowX, event.windowY); | 2327 last_unlocked_mouse_position_.SetPoint(event.windowX, event.windowY); |
2320 last_global_mouse_position_.SetPoint(event.globalX, event.globalY); | 2328 last_unlocked_global_mouse_position_.SetPoint(event.globalX, event.globalY); |
2321 } | 2329 } |
2322 | 2330 |
2323 // Send the event to the renderer before changing mouse capture, so that the | 2331 // Send the event to the renderer before changing mouse capture, so that the |
2324 // capturelost event arrives after mouseup. | 2332 // capturelost event arrives after mouseup. |
2325 render_widget_host_->ForwardMouseEvent(event); | 2333 render_widget_host_->ForwardMouseEvent(event); |
2326 | 2334 |
2327 switch (event.type) { | 2335 switch (event.type) { |
2328 case WebInputEvent::MouseMove: | 2336 case WebInputEvent::MouseMove: |
2329 TrackMouseLeave(true); | 2337 TrackMouseLeave(true); |
2330 break; | 2338 break; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2368 EnsureTooltip(); | 2376 EnsureTooltip(); |
2369 ShowWindow(IsActivatable() ? SW_SHOW : SW_SHOWNA); | 2377 ShowWindow(IsActivatable() ? SW_SHOW : SW_SHOWNA); |
2370 } | 2378 } |
2371 | 2379 |
2372 CPoint RenderWidgetHostViewWin::GetClientCenter() const { | 2380 CPoint RenderWidgetHostViewWin::GetClientCenter() const { |
2373 CRect rect; | 2381 CRect rect; |
2374 GetClientRect(&rect); | 2382 GetClientRect(&rect); |
2375 return rect.CenterPoint(); | 2383 return rect.CenterPoint(); |
2376 } | 2384 } |
2377 | 2385 |
2378 void RenderWidgetHostViewWin::MoveCursorToCenter() const { | 2386 void RenderWidgetHostViewWin::MoveCursorToCenterIfNecessary() { |
2379 CPoint center = GetClientCenter(); | 2387 DCHECK(mouse_locked_); |
2380 ClientToScreen(¢er); | 2388 |
2381 if (!::SetCursorPos(center.x, center.y)) | 2389 CRect rect; |
2382 LOG_GETLASTERROR(WARNING) << "Failed to set cursor position."; | 2390 GetWindowRect(&rect); |
2391 int border_x = rect.Width() * kMouseLockBorderPercentage / 100; | |
2392 int border_y = rect.Height() * kMouseLockBorderPercentage / 100; | |
2393 | |
2394 bool should_move = | |
2395 last_locked_global_mouse_position_.x() < rect.left + border_x || | |
2396 last_locked_global_mouse_position_.x() > rect.right - border_x || | |
2397 last_locked_global_mouse_position_.y() < rect.top + border_y || | |
2398 last_locked_global_mouse_position_.y() > rect.bottom - border_y; | |
2399 | |
2400 if (should_move) { | |
2401 ignore_move_to_center_message_ = true; | |
2402 CPoint center = rect.CenterPoint(); | |
2403 if (!::SetCursorPos(center.x, center.y)) | |
2404 LOG_GETLASTERROR(WARNING) << "Failed to set cursor position."; | |
2405 } | |
2383 } | 2406 } |
2384 | 2407 |
2385 void RenderWidgetHostViewWin::HandleLockedMouseEvent(UINT message, | 2408 void RenderWidgetHostViewWin::HandleLockedMouseEvent(UINT message, |
2386 WPARAM wparam, | 2409 WPARAM wparam, |
2387 LPARAM lparam) { | 2410 LPARAM lparam) { |
2388 DCHECK(mouse_locked_); | 2411 DCHECK(mouse_locked_); |
2389 | 2412 |
2390 if (message == WM_MOUSEMOVE) { | 2413 if (message == WM_MOUSEMOVE && ignore_move_to_center_message_) { |
2391 CPoint center = GetClientCenter(); | 2414 CPoint center = GetClientCenter(); |
2392 // Ignore WM_MOUSEMOVE messages generated by MoveCursorToCenter(). | 2415 // Ignore WM_MOUSEMOVE messages generated by |
2393 if (LOWORD(lparam) == center.x && HIWORD(lparam) == center.y) | 2416 // MoveCursorToCenterIfNecessary(). |
2417 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
| |
2418 ignore_move_to_center_message_ = false; | |
2419 ClientToScreen(¢er); | |
2420 last_locked_global_mouse_position_.SetPoint(center.x, center.y); | |
2394 return; | 2421 return; |
2422 } | |
2395 } | 2423 } |
2396 | 2424 |
2397 ForwardMouseEventToRenderer(message, wparam, lparam); | 2425 ForwardMouseEventToRenderer(message, wparam, lparam); |
2398 } | 2426 } |
2399 | 2427 |
2400 LRESULT RenderWidgetHostViewWin::OnDocumentFeed(RECONVERTSTRING* reconv) { | 2428 LRESULT RenderWidgetHostViewWin::OnDocumentFeed(RECONVERTSTRING* reconv) { |
2401 size_t target_offset; | 2429 size_t target_offset; |
2402 size_t target_length; | 2430 size_t target_length; |
2403 bool has_composition; | 2431 bool has_composition; |
2404 if (!composition_range_.is_empty()) { | 2432 if (!composition_range_.is_empty()) { |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2480 | 2508 |
2481 size_t offset = selection_range_.GetMin() - selection_text_offset_; | 2509 size_t offset = selection_range_.GetMin() - selection_text_offset_; |
2482 memcpy(reinterpret_cast<char*>(reconv) + sizeof(RECONVERTSTRING), | 2510 memcpy(reinterpret_cast<char*>(reconv) + sizeof(RECONVERTSTRING), |
2483 selection_text_.c_str() + offset, len * sizeof(WCHAR)); | 2511 selection_text_.c_str() + offset, len * sizeof(WCHAR)); |
2484 | 2512 |
2485 // According to Microsft API document, IMR_RECONVERTSTRING and | 2513 // According to Microsft API document, IMR_RECONVERTSTRING and |
2486 // IMR_DOCUMENTFEED should return reconv, but some applications return | 2514 // IMR_DOCUMENTFEED should return reconv, but some applications return |
2487 // need_size. | 2515 // need_size. |
2488 return reinterpret_cast<LRESULT>(reconv); | 2516 return reinterpret_cast<LRESULT>(reconv); |
2489 } | 2517 } |
OLD | NEW |