OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "app/l10n_util.h" | 7 #include "app/l10n_util.h" |
8 #include "app/l10n_util_win.h" | 8 #include "app/l10n_util_win.h" |
9 #include "app/resource_bundle.h" | 9 #include "app/resource_bundle.h" |
10 #include "app/view_prop.h" | 10 #include "app/view_prop.h" |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget( | 274 RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget( |
275 RenderWidgetHost* widget) { | 275 RenderWidgetHost* widget) { |
276 return new RenderWidgetHostViewWin(widget); | 276 return new RenderWidgetHostViewWin(widget); |
277 } | 277 } |
278 | 278 |
279 /////////////////////////////////////////////////////////////////////////////// | 279 /////////////////////////////////////////////////////////////////////////////// |
280 // RenderWidgetHostViewWin, public: | 280 // RenderWidgetHostViewWin, public: |
281 | 281 |
282 RenderWidgetHostViewWin::RenderWidgetHostViewWin(RenderWidgetHost* widget) | 282 RenderWidgetHostViewWin::RenderWidgetHostViewWin(RenderWidgetHost* widget) |
283 : render_widget_host_(widget), | 283 : render_widget_host_(widget), |
| 284 compositor_host_window_(NULL), |
284 track_mouse_leave_(false), | 285 track_mouse_leave_(false), |
285 ime_notification_(false), | 286 ime_notification_(false), |
286 capture_enter_key_(false), | 287 capture_enter_key_(false), |
287 is_hidden_(false), | 288 is_hidden_(false), |
288 about_to_validate_and_paint_(false), | 289 about_to_validate_and_paint_(false), |
289 close_on_deactivate_(false), | 290 close_on_deactivate_(false), |
290 being_destroyed_(false), | 291 being_destroyed_(false), |
291 tooltip_hwnd_(NULL), | 292 tooltip_hwnd_(NULL), |
292 tooltip_showing_(false), | 293 tooltip_showing_(false), |
293 shutdown_factory_(this), | 294 shutdown_factory_(this), |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 | 376 |
376 void RenderWidgetHostViewWin::SetSize(const gfx::Size& size) { | 377 void RenderWidgetHostViewWin::SetSize(const gfx::Size& size) { |
377 if (is_hidden_) | 378 if (is_hidden_) |
378 return; | 379 return; |
379 | 380 |
380 // No SWP_NOREDRAW as autofill popups can resize and the underneath window | 381 // No SWP_NOREDRAW as autofill popups can resize and the underneath window |
381 // should redraw in that case. | 382 // should redraw in that case. |
382 UINT swp_flags = SWP_NOSENDCHANGING | SWP_NOOWNERZORDER | SWP_NOCOPYBITS | | 383 UINT swp_flags = SWP_NOSENDCHANGING | SWP_NOOWNERZORDER | SWP_NOCOPYBITS | |
383 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_DEFERERASE; | 384 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_DEFERERASE; |
384 SetWindowPos(NULL, 0, 0, size.width(), size.height(), swp_flags); | 385 SetWindowPos(NULL, 0, 0, size.width(), size.height(), swp_flags); |
| 386 if (compositor_host_window_) { |
| 387 ::SetWindowPos(compositor_host_window_, |
| 388 NULL, |
| 389 0, 0, |
| 390 size.width(), size.height(), |
| 391 SWP_NOSENDCHANGING | SWP_NOCOPYBITS | SWP_NOZORDER | SWP_NOACTIVATE); |
| 392 } |
385 render_widget_host_->WasResized(); | 393 render_widget_host_->WasResized(); |
386 EnsureTooltip(); | 394 EnsureTooltip(); |
387 } | 395 } |
388 | 396 |
389 gfx::NativeView RenderWidgetHostViewWin::GetNativeView() { | 397 gfx::NativeView RenderWidgetHostViewWin::GetNativeView() { |
390 return m_hWnd; | 398 return m_hWnd; |
391 } | 399 } |
392 | 400 |
393 void RenderWidgetHostViewWin::MovePluginWindows( | 401 void RenderWidgetHostViewWin::MovePluginWindows( |
394 const std::vector<WebPluginGeometry>& plugin_window_moves) { | 402 const std::vector<WebPluginGeometry>& plugin_window_moves) { |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
702 Redraw(); | 710 Redraw(); |
703 } | 711 } |
704 | 712 |
705 void RenderWidgetHostViewWin::RenderViewGone() { | 713 void RenderWidgetHostViewWin::RenderViewGone() { |
706 // TODO(darin): keep this around, and draw sad-tab into it. | 714 // TODO(darin): keep this around, and draw sad-tab into it. |
707 UpdateCursorIfOverSelf(); | 715 UpdateCursorIfOverSelf(); |
708 being_destroyed_ = true; | 716 being_destroyed_ = true; |
709 DestroyWindow(); | 717 DestroyWindow(); |
710 } | 718 } |
711 | 719 |
| 720 static BOOL CALLBACK AddChildWindowToVector(HWND hwnd, LPARAM lparam) { |
| 721 std::vector<HWND>* vector = reinterpret_cast<std::vector<HWND>*>(lparam); |
| 722 vector->push_back(hwnd); |
| 723 return TRUE; |
| 724 } |
| 725 |
| 726 void RenderWidgetHostViewWin::WillWmDestroy() { |
| 727 if (!compositor_host_window_) |
| 728 return; |
| 729 |
| 730 std::vector<HWND> all_child_windows; |
| 731 ::EnumChildWindows(compositor_host_window_, AddChildWindowToVector, |
| 732 reinterpret_cast<LPARAM>(&all_child_windows)); |
| 733 if (all_child_windows.size()) { |
| 734 DCHECK(all_child_windows.size() == 1); |
| 735 ::ShowWindow(all_child_windows[0], SW_HIDE); |
| 736 ::SetParent(all_child_windows[0], NULL); |
| 737 } |
| 738 } |
| 739 |
712 void RenderWidgetHostViewWin::WillDestroyRenderWidget(RenderWidgetHost* rwh) { | 740 void RenderWidgetHostViewWin::WillDestroyRenderWidget(RenderWidgetHost* rwh) { |
713 if (rwh == render_widget_host_) | 741 if (rwh == render_widget_host_) |
714 render_widget_host_ = NULL; | 742 render_widget_host_ = NULL; |
715 } | 743 } |
716 | 744 |
717 void RenderWidgetHostViewWin::Destroy() { | 745 void RenderWidgetHostViewWin::Destroy() { |
718 // We've been told to destroy. | 746 // We've been told to destroy. |
719 // By clearing close_on_deactivate_, we prevent further deactivations | 747 // By clearing close_on_deactivate_, we prevent further deactivations |
720 // (caused by windows messages resulting from the DestroyWindow) from | 748 // (caused by windows messages resulting from the DestroyWindow) from |
721 // triggering further destructions. The deletion of this is handled by | 749 // triggering further destructions. The deletion of this is handled by |
722 // OnFinalMessage(); | 750 // OnFinalMessage(); |
723 close_on_deactivate_ = false; | 751 close_on_deactivate_ = false; |
724 being_destroyed_ = true; | 752 being_destroyed_ = true; |
| 753 WillWmDestroy(); |
725 DestroyWindow(); | 754 DestroyWindow(); |
726 } | 755 } |
727 | 756 |
728 void RenderWidgetHostViewWin::SetTooltipText(const std::wstring& tooltip_text) { | 757 void RenderWidgetHostViewWin::SetTooltipText(const std::wstring& tooltip_text) { |
729 // Clamp the tooltip length to kMaxTooltipLength so that we don't | 758 // Clamp the tooltip length to kMaxTooltipLength so that we don't |
730 // accidentally DOS the user with a mega tooltip (since Windows doesn't seem | 759 // accidentally DOS the user with a mega tooltip (since Windows doesn't seem |
731 // to do this itself). | 760 // to do this itself). |
732 const std::wstring& new_tooltip_text = | 761 const std::wstring& new_tooltip_text = |
733 l10n_util::TruncateString(tooltip_text, kMaxTooltipLength); | 762 l10n_util::TruncateString(tooltip_text, kMaxTooltipLength); |
734 | 763 |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
842 ResetTooltip(); | 871 ResetTooltip(); |
843 TrackMouseLeave(false); | 872 TrackMouseLeave(false); |
844 } | 873 } |
845 | 874 |
846 void RenderWidgetHostViewWin::OnPaint(HDC unused_dc) { | 875 void RenderWidgetHostViewWin::OnPaint(HDC unused_dc) { |
847 DCHECK(render_widget_host_->process()->HasConnection()); | 876 DCHECK(render_widget_host_->process()->HasConnection()); |
848 | 877 |
849 // If the GPU process is rendering directly into the View, | 878 // If the GPU process is rendering directly into the View, |
850 // call the compositor directly. | 879 // call the compositor directly. |
851 RenderWidgetHost* render_widget_host = GetRenderWidgetHost(); | 880 RenderWidgetHost* render_widget_host = GetRenderWidgetHost(); |
852 if (render_widget_host->is_gpu_rendering_active()) { | 881 if (render_widget_host->is_accelerated_compositing_active()) { |
853 // We initialize paint_dc here so that BeginPaint()/EndPaint() | 882 // We initialize paint_dc here so that BeginPaint()/EndPaint() |
854 // get called to validate the region. | 883 // get called to validate the region. |
855 CPaintDC paint_dc(m_hWnd); | 884 CPaintDC paint_dc(m_hWnd); |
856 render_widget_host_->ScheduleComposite(); | 885 render_widget_host_->ScheduleComposite(); |
857 return; | 886 return; |
858 } | 887 } |
859 | 888 |
860 about_to_validate_and_paint_ = true; | 889 about_to_validate_and_paint_ = true; |
861 BackingStoreWin* backing_store = static_cast<BackingStoreWin*>( | 890 BackingStoreWin* backing_store = static_cast<BackingStoreWin*>( |
862 render_widget_host_->GetBackingStore(true)); | 891 render_widget_host_->GetBackingStore(true)); |
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1450 if (!render_widget_host_ || | 1479 if (!render_widget_host_ || |
1451 render_process_host != render_widget_host_->process()) | 1480 render_process_host != render_widget_host_->process()) |
1452 return; | 1481 return; |
1453 | 1482 |
1454 // If it was our RenderProcessHost that posted the notification, | 1483 // If it was our RenderProcessHost that posted the notification, |
1455 // clear the BrowserAccessibilityManager, because the renderer is | 1484 // clear the BrowserAccessibilityManager, because the renderer is |
1456 // dead and any accessibility information we have is now stale. | 1485 // dead and any accessibility information we have is now stale. |
1457 browser_accessibility_manager_.reset(NULL); | 1486 browser_accessibility_manager_.reset(NULL); |
1458 } | 1487 } |
1459 | 1488 |
| 1489 // Looks through the children windows of the CompositorHostWindow. If the |
| 1490 // compositor child window is found, its size is checked against the host |
| 1491 // window's size. If the child is smaller in either dimensions, we fill |
| 1492 // the host window with white to avoid unseemly cracks. |
| 1493 static void PaintCompositorHostWindow(HWND hWnd) { |
| 1494 PAINTSTRUCT paint; |
| 1495 BeginPaint(hWnd, &paint); |
| 1496 |
| 1497 std::vector<HWND> child_windows; |
| 1498 EnumChildWindows(hWnd, AddChildWindowToVector, |
| 1499 reinterpret_cast<LPARAM>(&child_windows)); |
| 1500 |
| 1501 if (child_windows.size()) { |
| 1502 HWND child = child_windows[0]; |
| 1503 |
| 1504 RECT host_rect, child_rect; |
| 1505 GetClientRect(hWnd, &host_rect); |
| 1506 if (GetClientRect(child, &child_rect)) { |
| 1507 if (child_rect.right < host_rect.right || |
| 1508 child_rect.bottom != host_rect.bottom) { |
| 1509 FillRect(paint.hdc, &host_rect, |
| 1510 static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH))); |
| 1511 } |
| 1512 } |
| 1513 } |
| 1514 EndPaint(hWnd, &paint); |
| 1515 } |
| 1516 |
| 1517 // WndProc for the compositor host window. We use this instead of Default so |
| 1518 // we can drop WM_PAINT and WM_ERASEBKGD messages on the floor. |
| 1519 static LRESULT CALLBACK CompositorHostWindowProc(HWND hWnd, UINT message, |
| 1520 WPARAM wParam, LPARAM lParam) { |
| 1521 switch (message) { |
| 1522 case WM_ERASEBKGND: |
| 1523 return 0; |
| 1524 case WM_DESTROY: |
| 1525 return 0; |
| 1526 case WM_PAINT: |
| 1527 PaintCompositorHostWindow(hWnd); |
| 1528 return 0; |
| 1529 default: |
| 1530 return DefWindowProc(hWnd, message, wParam, lParam); |
| 1531 } |
| 1532 } |
| 1533 |
| 1534 // Creates a HWND within the RenderWidgetHostView that will serve as a host |
| 1535 // for a HWND that the GPU process will create. The host window is used |
| 1536 // to Z-position the GPU's window relative to other plugin windows. |
| 1537 gfx::PluginWindowHandle RenderWidgetHostViewWin::CreateCompositorHostWindow() { |
| 1538 DCHECK(!compositor_host_window_); |
| 1539 static ATOM window_class = 0; |
| 1540 if (!window_class) { |
| 1541 WNDCLASSEX wcex; |
| 1542 wcex.cbSize = sizeof(WNDCLASSEX); |
| 1543 wcex.style = 0; |
| 1544 wcex.lpfnWndProc = CompositorHostWindowProc; |
| 1545 wcex.cbClsExtra = 0; |
| 1546 wcex.cbWndExtra = 0; |
| 1547 wcex.hInstance = GetModuleHandle(NULL); |
| 1548 wcex.hIcon = 0; |
| 1549 wcex.hCursor = 0; |
| 1550 wcex.hbrBackground = NULL; |
| 1551 wcex.lpszMenuName = 0; |
| 1552 wcex.lpszClassName = L"CompositorHostWindowClass"; |
| 1553 wcex.hIconSm = 0; |
| 1554 window_class = RegisterClassEx(&wcex); |
| 1555 DCHECK(window_class); |
| 1556 } |
| 1557 |
| 1558 compositor_host_window_ = CreateWindowEx( |
| 1559 WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR, |
| 1560 MAKEINTATOM(window_class), 0, |
| 1561 WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_DISABLED, |
| 1562 0, 0, 0, 0, m_hWnd, 0, GetModuleHandle(NULL), 0); |
| 1563 DCHECK(compositor_host_window_); |
| 1564 |
| 1565 // We need to not just "WM_SHOW" the new indow, but reparent it |
| 1566 // below any existing plugin existing windows. |
| 1567 ShowCompositorHostWindow(true); |
| 1568 |
| 1569 return static_cast<gfx::PluginWindowHandle>(compositor_host_window_); |
| 1570 } |
| 1571 |
| 1572 void RenderWidgetHostViewWin::ShowCompositorHostWindow(bool show) { |
| 1573 // When we first create the compositor, we will get a show request from |
| 1574 // the renderer before we have gotten the create request from the GPU. In this |
| 1575 // case, simply ignore the show request. |
| 1576 if (compositor_host_window_ == NULL) |
| 1577 return; |
| 1578 |
| 1579 if (show) { |
| 1580 UINT flags = SWP_NOSENDCHANGING | SWP_NOCOPYBITS | SWP_NOZORDER | |
| 1581 SWP_NOACTIVATE | SWP_DEFERERASE | SWP_SHOWWINDOW; |
| 1582 gfx::Rect rect = GetViewBounds(); |
| 1583 ::SetWindowPos(compositor_host_window_, NULL, 0, 0, |
| 1584 rect.width(), rect.height(), |
| 1585 flags); |
| 1586 |
| 1587 // Get all the child windows of this view, including the compositor window. |
| 1588 std::vector<HWND> all_child_windows; |
| 1589 ::EnumChildWindows(m_hWnd, AddChildWindowToVector, |
| 1590 reinterpret_cast<LPARAM>(&all_child_windows)); |
| 1591 |
| 1592 // Build a list of just the plugin window handles |
| 1593 std::vector<HWND> plugin_windows; |
| 1594 bool compositor_host_window_found = false; |
| 1595 for (size_t i = 0; i < all_child_windows.size(); ++i) { |
| 1596 if (all_child_windows[i] != compositor_host_window_) |
| 1597 plugin_windows.push_back(all_child_windows[i]); |
| 1598 else |
| 1599 compositor_host_window_found = true; |
| 1600 } |
| 1601 DCHECK(compositor_host_window_found); |
| 1602 |
| 1603 // Set all the plugin windows to be "after" the compositor window. |
| 1604 // When the compositor window is created, gets placed above plugins. |
| 1605 for (size_t i = 0; i < plugin_windows.size(); ++i) { |
| 1606 HWND next; |
| 1607 if (i + 1 < plugin_windows.size()) |
| 1608 next = plugin_windows[i+1]; |
| 1609 else |
| 1610 next = compositor_host_window_; |
| 1611 ::SetWindowPos(plugin_windows[i], next, 0, 0, 0, 0, |
| 1612 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); |
| 1613 } |
| 1614 } else { |
| 1615 ::ShowWindow(compositor_host_window_, SW_HIDE); |
| 1616 } |
| 1617 } |
| 1618 |
1460 void RenderWidgetHostViewWin::SetAccessibilityFocus(int acc_obj_id) { | 1619 void RenderWidgetHostViewWin::SetAccessibilityFocus(int acc_obj_id) { |
1461 if (!browser_accessibility_manager_.get() || | 1620 if (!browser_accessibility_manager_.get() || |
1462 !render_widget_host_ || | 1621 !render_widget_host_ || |
1463 !render_widget_host_->process() || | 1622 !render_widget_host_->process() || |
1464 !render_widget_host_->process()->HasConnection()) { | 1623 !render_widget_host_->process()->HasConnection()) { |
1465 return; | 1624 return; |
1466 } | 1625 } |
1467 | 1626 |
1468 render_widget_host_->SetAccessibilityFocus(acc_obj_id); | 1627 render_widget_host_->SetAccessibilityFocus(acc_obj_id); |
1469 } | 1628 } |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1635 } | 1794 } |
1636 | 1795 |
1637 // static | 1796 // static |
1638 RenderWidgetHostView* | 1797 RenderWidgetHostView* |
1639 RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView( | 1798 RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView( |
1640 gfx::NativeView native_view) { | 1799 gfx::NativeView native_view) { |
1641 return ::IsWindow(native_view) ? | 1800 return ::IsWindow(native_view) ? |
1642 reinterpret_cast<RenderWidgetHostView*>( | 1801 reinterpret_cast<RenderWidgetHostView*>( |
1643 ViewProp::GetValue(native_view, kRenderWidgetHostViewKey)) : NULL; | 1802 ViewProp::GetValue(native_view, kRenderWidgetHostViewKey)) : NULL; |
1644 } | 1803 } |
OLD | NEW |