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_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