| 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 "chrome/browser/renderer_host/render_widget_host_view_win.h" | 5 #include "chrome/browser/renderer_host/render_widget_host_view_win.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/i18n/rtl.h" | 10 #include "base/i18n/rtl.h" |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 // Tooltips will wrap after this width. Yes, wrap. Imagine that! | 73 // Tooltips will wrap after this width. Yes, wrap. Imagine that! |
| 74 const int kTooltipMaxWidthPixels = 300; | 74 const int kTooltipMaxWidthPixels = 300; |
| 75 | 75 |
| 76 // Maximum number of characters we allow in a tooltip. | 76 // Maximum number of characters we allow in a tooltip. |
| 77 const int kMaxTooltipLength = 1024; | 77 const int kMaxTooltipLength = 1024; |
| 78 | 78 |
| 79 // A custom MSAA object id used to determine if a screen reader is actively | 79 // A custom MSAA object id used to determine if a screen reader is actively |
| 80 // listening for MSAA events. | 80 // listening for MSAA events. |
| 81 const int kIdCustom = 1; | 81 const int kIdCustom = 1; |
| 82 | 82 |
| 83 // The delay before the compositor host window is destroyed. This gives the GPU |
| 84 // process a grace period to stop referencing it. |
| 85 const int kDestroyCompositorHostWindowDelay = 10000; |
| 86 |
| 83 const char* const kRenderWidgetHostViewKey = "__RENDER_WIDGET_HOST_VIEW__"; | 87 const char* const kRenderWidgetHostViewKey = "__RENDER_WIDGET_HOST_VIEW__"; |
| 84 | 88 |
| 85 // A callback function for EnumThreadWindows to enumerate and dismiss | 89 // A callback function for EnumThreadWindows to enumerate and dismiss |
| 86 // any owned popop windows | 90 // any owned popop windows |
| 87 BOOL CALLBACK DismissOwnedPopups(HWND window, LPARAM arg) { | 91 BOOL CALLBACK DismissOwnedPopups(HWND window, LPARAM arg) { |
| 88 const HWND toplevel_hwnd = reinterpret_cast<HWND>(arg); | 92 const HWND toplevel_hwnd = reinterpret_cast<HWND>(arg); |
| 89 | 93 |
| 90 if (::IsWindowVisible(window)) { | 94 if (::IsWindowVisible(window)) { |
| 91 const HWND owner = ::GetWindow(window, GW_OWNER); | 95 const HWND owner = ::GetWindow(window, GW_OWNER); |
| 92 if (toplevel_hwnd == owner) { | 96 if (toplevel_hwnd == owner) { |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 UINT swp_flags = SWP_NOSENDCHANGING | SWP_NOOWNERZORDER | SWP_NOCOPYBITS | | 316 UINT swp_flags = SWP_NOSENDCHANGING | SWP_NOOWNERZORDER | SWP_NOCOPYBITS | |
| 313 SWP_NOZORDER | SWP_NOACTIVATE | SWP_DEFERERASE; | 317 SWP_NOZORDER | SWP_NOACTIVATE | SWP_DEFERERASE; |
| 314 | 318 |
| 315 // If the style is not popup, you have to convert the point to client | 319 // If the style is not popup, you have to convert the point to client |
| 316 // coordinate. | 320 // coordinate. |
| 317 POINT point = { rect.x(), rect.y() }; | 321 POINT point = { rect.x(), rect.y() }; |
| 318 if (GetStyle() & WS_CHILD) | 322 if (GetStyle() & WS_CHILD) |
| 319 ScreenToClient(&point); | 323 ScreenToClient(&point); |
| 320 | 324 |
| 321 SetWindowPos(NULL, point.x, point.y, rect.width(), rect.height(), swp_flags); | 325 SetWindowPos(NULL, point.x, point.y, rect.width(), rect.height(), swp_flags); |
| 322 if (compositor_host_window_) { | |
| 323 ::SetWindowPos(compositor_host_window_, NULL, point.x, point.y, | |
| 324 rect.width(), rect.height(), | |
| 325 SWP_NOSENDCHANGING | SWP_NOCOPYBITS | SWP_NOZORDER | SWP_NOACTIVATE); | |
| 326 } | |
| 327 render_widget_host_->WasResized(); | 326 render_widget_host_->WasResized(); |
| 328 EnsureTooltip(); | 327 EnsureTooltip(); |
| 329 } | 328 } |
| 330 | 329 |
| 331 gfx::NativeView RenderWidgetHostViewWin::GetNativeView() { | 330 gfx::NativeView RenderWidgetHostViewWin::GetNativeView() { |
| 332 return m_hWnd; | 331 return m_hWnd; |
| 333 } | 332 } |
| 334 | 333 |
| 335 void RenderWidgetHostViewWin::MovePluginWindows( | 334 void RenderWidgetHostViewWin::MovePluginWindows( |
| 336 const std::vector<WebPluginGeometry>& plugin_window_moves) { | 335 const std::vector<WebPluginGeometry>& plugin_window_moves) { |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 static BOOL CALLBACK AddChildWindowToVector(HWND hwnd, LPARAM lparam) { | 454 static BOOL CALLBACK AddChildWindowToVector(HWND hwnd, LPARAM lparam) { |
| 456 std::vector<HWND>* vector = reinterpret_cast<std::vector<HWND>*>(lparam); | 455 std::vector<HWND>* vector = reinterpret_cast<std::vector<HWND>*>(lparam); |
| 457 vector->push_back(hwnd); | 456 vector->push_back(hwnd); |
| 458 return TRUE; | 457 return TRUE; |
| 459 } | 458 } |
| 460 | 459 |
| 461 void RenderWidgetHostViewWin::CleanupCompositorWindow() { | 460 void RenderWidgetHostViewWin::CleanupCompositorWindow() { |
| 462 if (!compositor_host_window_) | 461 if (!compositor_host_window_) |
| 463 return; | 462 return; |
| 464 | 463 |
| 465 std::vector<HWND> all_child_windows; | 464 // Hide the compositor and parent it to the desktop rather than destroying |
| 466 ::EnumChildWindows(compositor_host_window_, AddChildWindowToVector, | 465 // it immediately. The GPU process has a grace period to stop accessing the |
| 467 reinterpret_cast<LPARAM>(&all_child_windows)); | 466 // window. TODO(apatrick): the GPU process should acknowledge that it has |
| 468 if (all_child_windows.size()) { | 467 // finished with the window handle and the browser process should destroy it |
| 469 DCHECK(all_child_windows.size() == 1); | 468 // at that point. |
| 470 ::ShowWindow(all_child_windows[0], SW_HIDE); | 469 ::ShowWindow(compositor_host_window_, SW_HIDE); |
| 471 ::SetParent(all_child_windows[0], NULL); | 470 ::SetParent(compositor_host_window_, NULL); |
| 472 } | 471 |
| 472 BrowserThread::PostDelayedTask( |
| 473 BrowserThread::UI, |
| 474 FROM_HERE, |
| 475 NewRunnableFunction(::DestroyWindow, compositor_host_window_), |
| 476 kDestroyCompositorHostWindowDelay); |
| 477 |
| 473 compositor_host_window_ = NULL; | 478 compositor_host_window_ = NULL; |
| 474 } | 479 } |
| 475 | 480 |
| 476 bool RenderWidgetHostViewWin::IsActivatable() const { | 481 bool RenderWidgetHostViewWin::IsActivatable() const { |
| 477 // Popups should not be activated. | 482 // Popups should not be activated. |
| 478 return popup_type_ == WebKit::WebPopupTypeNone; | 483 return popup_type_ == WebKit::WebPopupTypeNone; |
| 479 } | 484 } |
| 480 | 485 |
| 481 void RenderWidgetHostViewWin::Focus() { | 486 void RenderWidgetHostViewWin::Focus() { |
| 482 if (IsWindow()) | 487 if (IsWindow()) |
| (...skipping 976 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1459 if (!render_widget_host_ || | 1464 if (!render_widget_host_ || |
| 1460 render_process_host != render_widget_host_->process()) | 1465 render_process_host != render_widget_host_->process()) |
| 1461 return; | 1466 return; |
| 1462 | 1467 |
| 1463 // If it was our RenderProcessHost that posted the notification, | 1468 // If it was our RenderProcessHost that posted the notification, |
| 1464 // clear the BrowserAccessibilityManager, because the renderer is | 1469 // clear the BrowserAccessibilityManager, because the renderer is |
| 1465 // dead and any accessibility information we have is now stale. | 1470 // dead and any accessibility information we have is now stale. |
| 1466 browser_accessibility_manager_.reset(NULL); | 1471 browser_accessibility_manager_.reset(NULL); |
| 1467 } | 1472 } |
| 1468 | 1473 |
| 1469 // Looks through the children windows of the CompositorHostWindow. If the | |
| 1470 // compositor child window is found, its size is checked against the host | |
| 1471 // window's size. If the child is smaller in either dimensions, we fill | |
| 1472 // the host window with white to avoid unseemly cracks. | |
| 1473 static void PaintCompositorHostWindow(HWND hWnd) { | 1474 static void PaintCompositorHostWindow(HWND hWnd) { |
| 1474 PAINTSTRUCT paint; | 1475 PAINTSTRUCT paint; |
| 1475 BeginPaint(hWnd, &paint); | 1476 BeginPaint(hWnd, &paint); |
| 1476 | 1477 |
| 1477 std::vector<HWND> child_windows; | |
| 1478 EnumChildWindows(hWnd, AddChildWindowToVector, | |
| 1479 reinterpret_cast<LPARAM>(&child_windows)); | |
| 1480 | |
| 1481 if (child_windows.size()) { | |
| 1482 HWND child = child_windows[0]; | |
| 1483 | |
| 1484 RECT host_rect, child_rect; | |
| 1485 GetClientRect(hWnd, &host_rect); | |
| 1486 if (GetClientRect(child, &child_rect)) { | |
| 1487 if (child_rect.right < host_rect.right || | |
| 1488 child_rect.bottom != host_rect.bottom) { | |
| 1489 FillRect(paint.hdc, &host_rect, | |
| 1490 static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH))); | |
| 1491 } | |
| 1492 } | |
| 1493 } | |
| 1494 EndPaint(hWnd, &paint); | 1478 EndPaint(hWnd, &paint); |
| 1495 } | 1479 } |
| 1496 | 1480 |
| 1497 // WndProc for the compositor host window. We use this instead of Default so | 1481 // WndProc for the compositor host window. We use this instead of Default so |
| 1498 // we can drop WM_PAINT and WM_ERASEBKGD messages on the floor. | 1482 // we can drop WM_PAINT and WM_ERASEBKGD messages on the floor. |
| 1499 static LRESULT CALLBACK CompositorHostWindowProc(HWND hWnd, UINT message, | 1483 static LRESULT CALLBACK CompositorHostWindowProc(HWND hWnd, UINT message, |
| 1500 WPARAM wParam, LPARAM lParam) { | 1484 WPARAM wParam, LPARAM lParam) { |
| 1501 switch (message) { | 1485 switch (message) { |
| 1502 case WM_ERASEBKGND: | 1486 case WM_ERASEBKGND: |
| 1503 return 0; | 1487 return 0; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1555 } | 1539 } |
| 1556 | 1540 |
| 1557 void RenderWidgetHostViewWin::ShowCompositorHostWindow(bool show) { | 1541 void RenderWidgetHostViewWin::ShowCompositorHostWindow(bool show) { |
| 1558 // When we first create the compositor, we will get a show request from | 1542 // When we first create the compositor, we will get a show request from |
| 1559 // the renderer before we have gotten the create request from the GPU. In this | 1543 // the renderer before we have gotten the create request from the GPU. In this |
| 1560 // case, simply ignore the show request. | 1544 // case, simply ignore the show request. |
| 1561 if (compositor_host_window_ == NULL) | 1545 if (compositor_host_window_ == NULL) |
| 1562 return; | 1546 return; |
| 1563 | 1547 |
| 1564 if (show) { | 1548 if (show) { |
| 1565 UINT flags = SWP_NOSENDCHANGING | SWP_NOCOPYBITS | SWP_NOZORDER | | 1549 ::ShowWindow(compositor_host_window_, SW_SHOW); |
| 1566 SWP_NOACTIVATE | SWP_DEFERERASE | SWP_SHOWWINDOW; | |
| 1567 gfx::Rect rect = GetViewBounds(); | |
| 1568 ::SetWindowPos(compositor_host_window_, NULL, 0, 0, | |
| 1569 rect.width(), rect.height(), | |
| 1570 flags); | |
| 1571 | 1550 |
| 1572 // Get all the child windows of this view, including the compositor window. | 1551 // Get all the child windows of this view, including the compositor window. |
| 1573 std::vector<HWND> all_child_windows; | 1552 std::vector<HWND> all_child_windows; |
| 1574 ::EnumChildWindows(m_hWnd, AddChildWindowToVector, | 1553 ::EnumChildWindows(m_hWnd, AddChildWindowToVector, |
| 1575 reinterpret_cast<LPARAM>(&all_child_windows)); | 1554 reinterpret_cast<LPARAM>(&all_child_windows)); |
| 1576 | 1555 |
| 1577 // Build a list of just the plugin window handles | 1556 // Build a list of just the plugin window handles |
| 1578 std::vector<HWND> plugin_windows; | 1557 std::vector<HWND> plugin_windows; |
| 1579 bool compositor_host_window_found = false; | 1558 bool compositor_host_window_found = false; |
| 1580 for (size_t i = 0; i < all_child_windows.size(); ++i) { | 1559 for (size_t i = 0; i < all_child_windows.size(); ++i) { |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1799 } | 1778 } |
| 1800 | 1779 |
| 1801 // static | 1780 // static |
| 1802 RenderWidgetHostView* | 1781 RenderWidgetHostView* |
| 1803 RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView( | 1782 RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView( |
| 1804 gfx::NativeView native_view) { | 1783 gfx::NativeView native_view) { |
| 1805 return ::IsWindow(native_view) ? | 1784 return ::IsWindow(native_view) ? |
| 1806 reinterpret_cast<RenderWidgetHostView*>( | 1785 reinterpret_cast<RenderWidgetHostView*>( |
| 1807 ViewProp::GetValue(native_view, kRenderWidgetHostViewKey)) : NULL; | 1786 ViewProp::GetValue(native_view, kRenderWidgetHostViewKey)) : NULL; |
| 1808 } | 1787 } |
| OLD | NEW |