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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/ui/views/tab_contents/native_tab_contents_container_win.h" 6 7 #include "chrome/browser/ui/view_ids.h" 8 #include "chrome/browser/ui/views/tab_contents/tab_contents_container.h" 9 #include "chrome/browser/ui/views/tab_contents/tab_contents_view_views.h" 10 #include "content/browser/renderer_host/render_widget_host_view.h" 11 #include "content/browser/tab_contents/interstitial_page.h" 12 #include "content/browser/tab_contents/tab_contents.h" 13 #include "ui/base/accessibility/accessible_view_state.h" 14 #include "views/focus/focus_manager.h" 15 16 //////////////////////////////////////////////////////////////////////////////// 17 // NativeTabContentsContainerWin, public: 18 19 NativeTabContentsContainerWin::NativeTabContentsContainerWin( 20 TabContentsContainer* container) 21 : container_(container) { 22 SetID(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW); 23 } 24 25 NativeTabContentsContainerWin::~NativeTabContentsContainerWin() { 26 } 27 28 //////////////////////////////////////////////////////////////////////////////// 29 // NativeTabContentsContainerWin, NativeTabContentsContainer overrides: 30 31 void NativeTabContentsContainerWin::AttachContents(TabContents* contents) { 32 // We need to register the tab contents window with the BrowserContainer so 33 // that the BrowserContainer is the focused view when the focus is on the 34 // TabContents window (for the TabContents case). 35 set_focus_view(this); 36 37 Attach(contents->GetNativeView()); 38 } 39 40 void NativeTabContentsContainerWin::DetachContents(TabContents* contents) { 41 // Detach the TabContents. Do this before we unparent the 42 // TabContentsViewViews so that the window hierarchy is intact for any 43 // cleanup during Detach(). 44 Detach(); 45 46 // TODO(brettw) should this move to NativeViewHost::Detach? It 47 // needs cleanup regardless. 48 HWND container_hwnd = contents->GetNativeView(); 49 if (container_hwnd) { 50 // Hide the contents before adjusting its parent to avoid a full desktop 51 // flicker. 52 ShowWindow(container_hwnd, SW_HIDE); 53 54 // Reset the parent to NULL to ensure hidden tabs don't receive messages. 55 static_cast<TabContentsViewViews*>(contents->view())->Unparent(); 56 } 57 } 58 59 void NativeTabContentsContainerWin::SetFastResize(bool fast_resize) { 60 set_fast_resize(fast_resize); 61 } 62 63 void NativeTabContentsContainerWin::RenderViewHostChanged( 64 RenderViewHost* old_host, 65 RenderViewHost* new_host) { 66 // If we are focused, we need to pass the focus to the new RenderViewHost. 67 if (GetFocusManager()->GetFocusedView() == this) 68 OnFocus(); 69 } 70 71 views::View* NativeTabContentsContainerWin::GetView() { 72 return this; 73 } 74 75 void NativeTabContentsContainerWin::TabContentsFocused( 76 TabContents* tab_contents) { 77 views::FocusManager* focus_manager = GetFocusManager(); 78 if (!focus_manager) { 79 NOTREACHED(); 80 return; 81 } 82 focus_manager->SetFocusedView(this); 83 } 84 85 //////////////////////////////////////////////////////////////////////////////// 86 // NativeTabContentsContainerWin, views::View overrides: 87 88 bool NativeTabContentsContainerWin::SkipDefaultKeyEventProcessing( 89 const views::KeyEvent& e) { 90 // Don't look-up accelerators or tab-traversal if we are showing a non-crashed 91 // TabContents. 92 // We'll first give the page a chance to process the key events. If it does 93 // not process them, they'll be returned to us and we'll treat them as 94 // accelerators then. 95 return container_->tab_contents() && 96 !container_->tab_contents()->is_crashed(); 97 } 98 99 bool NativeTabContentsContainerWin::IsFocusable() const { 100 // We need to be focusable when our contents is not a view hierarchy, as 101 // clicking on the contents needs to focus us. 102 return container_->tab_contents() != NULL; 103 } 104 105 void NativeTabContentsContainerWin::OnFocus() { 106 if (container_->tab_contents()) 107 container_->tab_contents()->Focus(); 108 } 109 110 void NativeTabContentsContainerWin::RequestFocus() { 111 // This is a hack to circumvent the fact that a the OnFocus() method is not 112 // invoked when RequestFocus() is called on an already focused view. 113 // The TabContentsContainer is the view focused when the TabContents has 114 // focus. When switching between from one tab that has focus to another tab 115 // that should also have focus, RequestFocus() is invoked one the 116 // TabContentsContainer. In order to make sure OnFocus() is invoked we need 117 // to clear the focus before hands. 118 { 119 // Disable notifications. Clear focus will assign the focus to the main 120 // browser window. Because this change of focus was not user requested, 121 // don't send it to listeners. 122 views::AutoNativeNotificationDisabler local_notification_disabler; 123 GetFocusManager()->ClearFocus(); 124 } 125 View::RequestFocus(); 126 } 127 128 void NativeTabContentsContainerWin::AboutToRequestFocusFromTabTraversal( 129 bool reverse) { 130 container_->tab_contents()->FocusThroughTabTraversal(reverse); 131 } 132 133 void NativeTabContentsContainerWin::GetAccessibleState( 134 ui::AccessibleViewState* state) { 135 state->role = ui::AccessibilityTypes::ROLE_GROUPING; 136 } 137 138 //////////////////////////////////////////////////////////////////////////////// 139 // NativeTabContentsContainer, public: 140 141 // static 142 NativeTabContentsContainer* NativeTabContentsContainer::CreateNativeContainer( 143 TabContentsContainer* container) { 144 return new NativeTabContentsContainerWin(container); 145 } 146