Home | History | Annotate | Download | only in tab_contents
      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 
     18 NativeTabContentsContainerGtk::NativeTabContentsContainerGtk(
     19     TabContentsContainer* container)
     20     : container_(container),
     21       focus_callback_id_(0) {
     22   SetID(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
     23 }
     24 
     25 NativeTabContentsContainerGtk::~NativeTabContentsContainerGtk() {
     26 }
     27 
     28 ////////////////////////////////////////////////////////////////////////////////
     29 // NativeTabContentsContainerGtk, NativeTabContentsContainer overrides:
     30 
     31 void NativeTabContentsContainerGtk::AttachContents(TabContents* contents) {
     32   Attach(contents->GetNativeView());
     33 }
     34 
     35 void NativeTabContentsContainerGtk::DetachContents(TabContents* contents) {
     36   gtk_widget_hide(contents->GetNativeView());
     37 
     38   // Now detach the TabContents.
     39   Detach();
     40 }
     41 
     42 void NativeTabContentsContainerGtk::SetFastResize(bool fast_resize) {
     43   set_fast_resize(fast_resize);
     44 }
     45 
     46 void 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 
     55 views::View* NativeTabContentsContainerGtk::GetView() {
     56   return this;
     57 }
     58 
     59 void 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 
     79 bool 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 
     90 views::FocusTraversable* NativeTabContentsContainerGtk::GetFocusTraversable() {
     91   return NULL;
     92 }
     93 
     94 bool 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 
    100 void NativeTabContentsContainerGtk::OnFocus() {
    101   if (container_->tab_contents())
    102     container_->tab_contents()->Focus();
    103 }
    104 
    105 void 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 
    121 void 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 
    134 void NativeTabContentsContainerGtk::GetAccessibleState(
    135     ui::AccessibleViewState* state) {
    136   state->role = ui::AccessibilityTypes::ROLE_GROUPING;
    137 }
    138 
    139 ////////////////////////////////////////////////////////////////////////////////
    140 // NativeTabContentsContainer, public:
    141 
    142 // static
    143 NativeTabContentsContainer* NativeTabContentsContainer::CreateNativeContainer(
    144     TabContentsContainer* container) {
    145   return new NativeTabContentsContainerGtk(container);
    146 }
    147