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