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_gtk.h" 6 7#include "chrome/browser/ui/view_ids.h" 8#include "chrome/browser/ui/views/tab_contents/tab_contents_container.h" 9#include "content/browser/renderer_host/render_widget_host_view.h" 10#include "content/browser/tab_contents/interstitial_page.h" 11#include "content/browser/tab_contents/tab_contents.h" 12#include "ui/base/accessibility/accessible_view_state.h" 13#include "views/focus/focus_manager.h" 14 15//////////////////////////////////////////////////////////////////////////////// 16// NativeTabContentsContainerGtk, public: 17 18NativeTabContentsContainerGtk::NativeTabContentsContainerGtk( 19 TabContentsContainer* container) 20 : container_(container), 21 focus_callback_id_(0) { 22 SetID(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW); 23} 24 25NativeTabContentsContainerGtk::~NativeTabContentsContainerGtk() { 26} 27 28//////////////////////////////////////////////////////////////////////////////// 29// NativeTabContentsContainerGtk, NativeTabContentsContainer overrides: 30 31void NativeTabContentsContainerGtk::AttachContents(TabContents* contents) { 32 Attach(contents->GetNativeView()); 33} 34 35void NativeTabContentsContainerGtk::DetachContents(TabContents* contents) { 36 gtk_widget_hide(contents->GetNativeView()); 37 38 // Now detach the TabContents. 39 Detach(); 40} 41 42void NativeTabContentsContainerGtk::SetFastResize(bool fast_resize) { 43 set_fast_resize(fast_resize); 44} 45 46void NativeTabContentsContainerGtk::RenderViewHostChanged( 47 RenderViewHost* old_host, 48 RenderViewHost* new_host) { 49 // If we are focused, we need to pass the focus to the new RenderViewHost. 50 views::FocusManager* focus_manager = GetFocusManager(); 51 if (focus_manager->GetFocusedView() == this) 52 OnFocus(); 53} 54 55views::View* NativeTabContentsContainerGtk::GetView() { 56 return this; 57} 58 59void NativeTabContentsContainerGtk::TabContentsFocused( 60 TabContents* tab_contents) { 61#if !defined(TOUCH_UI) 62 // Called when the tab contents native view gets focused (typically through a 63 // user click). We make ourself the focused view, so the focus is restored 64 // properly when the browser window is deactivated/reactivated. 65 views::FocusManager* focus_manager = GetFocusManager(); 66 if (!focus_manager) { 67 NOTREACHED(); 68 return; 69 } 70 focus_manager->SetFocusedView(this); 71#else 72 // no native views in TOUCH_UI, so don't steal the focus 73#endif 74} 75 76//////////////////////////////////////////////////////////////////////////////// 77// NativeTabContentsContainerGtk, views::View overrides: 78 79bool NativeTabContentsContainerGtk::SkipDefaultKeyEventProcessing( 80 const views::KeyEvent& e) { 81 // Don't look-up accelerators or tab-traverse if we are showing a non-crashed 82 // TabContents. 83 // We'll first give the page a chance to process the key events. If it does 84 // not process them, they'll be returned to us and we'll treat them as 85 // accelerators then. 86 return container_->tab_contents() && 87 !container_->tab_contents()->is_crashed(); 88} 89 90views::FocusTraversable* NativeTabContentsContainerGtk::GetFocusTraversable() { 91 return NULL; 92} 93 94bool NativeTabContentsContainerGtk::IsFocusable() const { 95 // We need to be focusable when our contents is not a view hierarchy, as 96 // clicking on the contents needs to focus us. 97 return container_->tab_contents() != NULL; 98} 99 100void NativeTabContentsContainerGtk::OnFocus() { 101 if (container_->tab_contents()) 102 container_->tab_contents()->Focus(); 103} 104 105void NativeTabContentsContainerGtk::RequestFocus() { 106 // This is a hack to circumvent the fact that a view does not explicitly get 107 // a call to set the focus if it already has the focus. This causes a problem 108 // with tabs such as the TabContents that instruct the RenderView that it got 109 // focus when they actually get the focus. When switching from one TabContents 110 // tab that has focus to another TabContents tab that had focus, since the 111 // TabContentsContainerView already has focus, OnFocus() would not be called 112 // and the RenderView would not get notified it got focused. 113 // By clearing the focused view before-hand, we ensure OnFocus() will be 114 // called. 115 views::FocusManager* focus_manager = GetFocusManager(); 116 if (focus_manager) 117 focus_manager->SetFocusedView(NULL); 118 View::RequestFocus(); 119} 120 121void NativeTabContentsContainerGtk::AboutToRequestFocusFromTabTraversal( 122 bool reverse) { 123 if (!container_->tab_contents()) 124 return; 125 // Give an opportunity to the tab to reset its focus. 126 if (container_->tab_contents()->interstitial_page()) { 127 container_->tab_contents()->interstitial_page()->FocusThroughTabTraversal( 128 reverse); 129 return; 130 } 131 container_->tab_contents()->FocusThroughTabTraversal(reverse); 132} 133 134void NativeTabContentsContainerGtk::GetAccessibleState( 135 ui::AccessibleViewState* state) { 136 state->role = ui::AccessibilityTypes::ROLE_GROUPING; 137} 138 139//////////////////////////////////////////////////////////////////////////////// 140// NativeTabContentsContainer, public: 141 142// static 143NativeTabContentsContainer* NativeTabContentsContainer::CreateNativeContainer( 144 TabContentsContainer* container) { 145 return new NativeTabContentsContainerGtk(container); 146} 147