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

Side by Side Diff: content/browser/renderer_host/render_widget_host_view_win.cc

Issue 8791001: Fix mouse lock perf issue on Windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 9 years 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
« no previous file with comments | « content/browser/renderer_host/render_widget_host_view_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #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
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
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
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
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
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
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(&center); 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(&center);
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
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 }
OLDNEW
« no previous file with comments | « content/browser/renderer_host/render_widget_host_view_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698