summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/browser_focus_uitest.cc47
-rw-r--r--chrome/browser/debugger/debugger_view.cc8
-rw-r--r--chrome/browser/debugger/debugger_view.h4
-rw-r--r--chrome/browser/external_tab_container.cc8
-rw-r--r--chrome/browser/external_tab_container.h4
-rw-r--r--chrome/browser/views/browser_views.vcproj32
-rw-r--r--chrome/browser/views/frame/browser_view.cc16
-rw-r--r--chrome/browser/views/frame/browser_view.h10
-rw-r--r--chrome/browser/views/tab_contents/native_tab_contents_container.h42
-rw-r--r--chrome/browser/views/tab_contents/native_tab_contents_container_gtk.cc198
-rw-r--r--chrome/browser/views/tab_contents/native_tab_contents_container_gtk.h40
-rw-r--r--chrome/browser/views/tab_contents/native_tab_contents_container_win.cc182
-rw-r--r--chrome/browser/views/tab_contents/native_tab_contents_container_win.h44
-rw-r--r--chrome/browser/views/tab_contents/tab_contents_container.cc112
-rw-r--r--chrome/browser/views/tab_contents/tab_contents_container.h79
-rw-r--r--chrome/browser/views/tab_contents_container_view.cc223
-rw-r--r--chrome/browser/views/tab_contents_container_view.h79
-rw-r--r--chrome/chrome.gyp9
18 files changed, 786 insertions, 351 deletions
diff --git a/chrome/browser/browser_focus_uitest.cc b/chrome/browser/browser_focus_uitest.cc
index 01603ac..17946e0 100644
--- a/chrome/browser/browser_focus_uitest.cc
+++ b/chrome/browser/browser_focus_uitest.cc
@@ -11,6 +11,7 @@
#include "chrome/browser/view_ids.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/browser/views/location_bar_view.h"
+#include "chrome/browser/views/tab_contents/tab_contents_container.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
@@ -110,14 +111,16 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, DISABLED_BrowsersRememberFocus) {
views::FocusManager::GetFocusManager(hwnd);
ASSERT_TRUE(focus_manager);
- EXPECT_EQ(browser_view->GetContentsView(), focus_manager->GetFocusedView());
+ EXPECT_EQ(browser_view->contents_container()->GetFocusView(),
+ focus_manager->GetFocusedView());
// Now hide the window, show it again, the focus should not have changed.
// TODO(jcampan): retrieve the WidgetWin and show/hide on it instead of
// using Windows API.
::ShowWindow(hwnd, SW_HIDE);
::ShowWindow(hwnd, SW_SHOW);
- EXPECT_EQ(browser_view->GetContentsView(), focus_manager->GetFocusedView());
+ EXPECT_EQ(browser_view->contents_container()->GetFocusView(),
+ focus_manager->GetFocusedView());
// Click on the location bar.
LocationBarView* location_bar = browser_view->GetLocationBarView();
@@ -147,7 +150,8 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, DISABLED_BrowsersRememberFocus) {
views::FocusManager* focus_manager2 =
views::FocusManager::GetFocusManager(hwnd2);
ASSERT_TRUE(focus_manager2);
- EXPECT_EQ(browser_view2->GetContentsView(), focus_manager2->GetFocusedView());
+ EXPECT_EQ(browser_view2->contents_container()->GetFocusView(),
+ focus_manager2->GetFocusedView());
// Switch to the 1st browser window, focus should still be on the location
// bar and the second browser should have nothing focused.
@@ -158,7 +162,8 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, DISABLED_BrowsersRememberFocus) {
// Switch back to the second browser, focus should still be on the page.
browser2->window()->Activate();
EXPECT_EQ(NULL, focus_manager->GetFocusedView());
- EXPECT_EQ(browser_view2->GetContentsView(), focus_manager2->GetFocusedView());
+ EXPECT_EQ(browser_view->contents_container()->GetFocusView(),
+ focus_manager2->GetFocusedView());
// Close the 2nd browser to avoid a DCHECK().
browser_view2->Close();
@@ -200,7 +205,7 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, TabsRememberFocus) {
// Activate the location bar or the page.
views::View* view_to_focus = kFocusPage[i][j] ?
- browser_view->GetContentsView() :
+ browser_view->contents_container()->GetFocusView() :
browser_view->GetLocationBarView();
ui_controls::MoveMouseToCenterAndPress(view_to_focus,
@@ -218,7 +223,7 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, TabsRememberFocus) {
// Activate the location bar or the page.
views::View* view = kFocusPage[i][j] ?
- browser_view->GetContentsView() :
+ browser_view->contents_container()->GetFocusView() :
browser_view->GetLocationBarView();
EXPECT_EQ(view, focus_manager->GetFocusedView());
}
@@ -391,7 +396,8 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversalOnInterstitial) {
views::FocusManager::GetFocusManager(hwnd);
// Focus should be on the page.
- EXPECT_EQ(browser_view->GetContentsView(), focus_manager->GetFocusedView());
+ EXPECT_EQ(browser_view->contents_container()->GetFocusView(),
+ focus_manager->GetFocusedView());
// Let's show an interstitial.
TestInterstitialPage* interstitial_page =
@@ -485,7 +491,8 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, InterstitialFocus) {
views::FocusManager::GetFocusManager(hwnd);
// Page should have focus.
- EXPECT_EQ(browser_view->GetContentsView(), focus_manager->GetFocusedView());
+ EXPECT_EQ(browser_view->contents_container()->GetFocusView(),
+ focus_manager->GetFocusedView());
EXPECT_TRUE(browser()->GetSelectedTabContents()->render_view_host()->view()->
HasFocus());
@@ -501,14 +508,16 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, InterstitialFocus) {
ui_test_utils::RunMessageLoop();
// The interstitial should have focus now.
- EXPECT_EQ(browser_view->GetContentsView(), focus_manager->GetFocusedView());
+ EXPECT_EQ(browser_view->contents_container()->GetFocusView(),
+ focus_manager->GetFocusedView());
EXPECT_TRUE(interstitial_page->HasFocus());
// Hide the interstitial.
interstitial_page->DontProceed();
// Focus should be back on the original page.
- EXPECT_EQ(browser_view->GetContentsView(), focus_manager->GetFocusedView());
+ EXPECT_EQ(browser_view->contents_container()->GetFocusView(),
+ focus_manager->GetFocusedView());
EXPECT_TRUE(browser()->GetSelectedTabContents()->render_view_host()->view()->
HasFocus());
}
@@ -565,12 +574,14 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FindFocusTest) {
EXPECT_EQ(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD, focused_view->GetID());
// Set focus to the page.
- ui_controls::MoveMouseToCenterAndPress(browser_view->GetContentsView(),
- ui_controls::LEFT,
- ui_controls::DOWN | ui_controls::UP,
- new MessageLoop::QuitTask());
+ ui_controls::MoveMouseToCenterAndPress(
+ browser_view->contents_container()->GetFocusView(),
+ ui_controls::LEFT,
+ ui_controls::DOWN | ui_controls::UP,
+ new MessageLoop::QuitTask());
ui_test_utils::RunMessageLoop();
- EXPECT_EQ(browser_view->GetContentsView(), focus_manager->GetFocusedView());
+ EXPECT_EQ(browser_view->contents_container()->GetFocusView(),
+ focus_manager->GetFocusedView());
// Now press Ctrl+F again and focus should move to the Find box.
ui_controls::SendKeyPressNotifyWhenDone(VK_F, true, false, false,
@@ -599,7 +610,8 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, TabInitialFocus) {
// Open the history tab, focus should be on the tab contents.
browser()->ShowHistoryTab();
- EXPECT_EQ(browser_view->GetContentsView(), focus_manager->GetFocusedView());
+ EXPECT_EQ(browser_view->contents_container()->GetFocusView(),
+ focus_manager->GetFocusedView());
// Open the new tab, focus should be on the location bar.
browser()->NewTab();
@@ -608,5 +620,6 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, TabInitialFocus) {
// Open the download tab, focus should be on the tab contents.
browser()->ShowDownloadsTab();
- EXPECT_EQ(browser_view->GetContentsView(), focus_manager->GetFocusedView());
+ EXPECT_EQ(browser_view->contents_container()->GetFocusView(),
+ focus_manager->GetFocusedView());
}
diff --git a/chrome/browser/debugger/debugger_view.cc b/chrome/browser/debugger/debugger_view.cc
index 7625f83..81ce36e 100644
--- a/chrome/browser/debugger/debugger_view.cc
+++ b/chrome/browser/debugger/debugger_view.cc
@@ -19,7 +19,7 @@
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/view_ids.h"
-#include "chrome/browser/views/tab_contents_container_view.h"
+#include "chrome/browser/views/tab_contents/tab_contents_container.h"
#include "chrome/common/url_constants.h"
#include "grit/debugger_resources.h"
#include "views/grid_layout.h"
@@ -31,7 +31,7 @@
DebuggerView::DebuggerView(DebuggerWindow* window)
: window_(window), output_ready_(false) {
- web_container_ = new TabContentsContainerView();
+ web_container_ = new TabContentsContainer;
AddChildView(web_container_);
AddAccelerator(views::Accelerator(VK_ESCAPE, false, false, false));
}
@@ -101,7 +101,7 @@ void DebuggerView::OnInit() {
tab_contents_ = new TabContents(profile, NULL, MSG_ROUTING_NONE, NULL);
tab_contents_->set_delegate(this);
- web_container_->SetTabContents(tab_contents_);
+ web_container_->ChangeTabContents(tab_contents_);
tab_contents_->render_view_host()->AllowDOMUIBindings();
GURL contents(std::string(chrome::kChromeUIScheme) +
@@ -115,7 +115,7 @@ void DebuggerView::OnShow() {
}
void DebuggerView::OnClose() {
- web_container_->SetTabContents(NULL);
+ web_container_->ChangeTabContents(NULL);
delete tab_contents_;
}
diff --git a/chrome/browser/debugger/debugger_view.h b/chrome/browser/debugger/debugger_view.h
index b4aa0b5..a83ce58 100644
--- a/chrome/browser/debugger/debugger_view.h
+++ b/chrome/browser/debugger/debugger_view.h
@@ -18,7 +18,7 @@
class DebuggerView;
class DebuggerWindow;
class TabContents;
-class TabContentsContainerView;
+class TabContentsContainer;
class Value;
class DebuggerView : public views::View,
@@ -90,7 +90,7 @@ class DebuggerView : public views::View,
DebuggerWindow* window_;
gfx::Font font_;
TabContents* tab_contents_;
- TabContentsContainerView* web_container_;
+ TabContentsContainer* web_container_;
std::vector<std::wstring> pending_output_;
std::vector<std::string> pending_events_;
bool output_ready_;
diff --git a/chrome/browser/external_tab_container.cc b/chrome/browser/external_tab_container.cc
index d250868..a32ed53 100644
--- a/chrome/browser/external_tab_container.cc
+++ b/chrome/browser/external_tab_container.cc
@@ -14,7 +14,7 @@
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/provisional_load_details.h"
#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/views/tab_contents_container_view.h"
+#include "chrome/browser/views/tab_contents/tab_contents_container.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/notification_service.h"
#include "chrome/test/automation/automation_messages.h"
@@ -73,12 +73,12 @@ bool ExternalTabContainer::Init(Profile* profile, HWND parent,
tab_contents_->set_delegate(this);
tab_contents_->render_view_host()->AllowExternalHostBindings();
- // Create a TabContentsContainerView to handle focus cycling using Tab and
+ // Create a TabContentsContainer to handle focus cycling using Tab and
// Shift-Tab.
- tab_contents_container_ = new TabContentsContainerView();
+ tab_contents_container_ = new TabContentsContainer;
root_view_.AddChildView(tab_contents_container_);
// Note that SetTabContents must be called after AddChildView is called
- tab_contents_container_->SetTabContents(tab_contents_);
+ tab_contents_container_->ChangeTabContents(tab_contents_);
NavigationController* controller = &tab_contents_->controller();
registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED,
diff --git a/chrome/browser/external_tab_container.h b/chrome/browser/external_tab_container.h
index f3a186d..ee111e7 100644
--- a/chrome/browser/external_tab_container.h
+++ b/chrome/browser/external_tab_container.h
@@ -23,7 +23,7 @@
class AutomationProvider;
class TabContents;
class Profile;
-class TabContentsContainerView;
+class TabContentsContainer;
// This class serves as the container window for an external tab.
// An external tab is a Chrome tab that is meant to displayed in an
// external process. This class provides the FocusManger needed by the
@@ -162,7 +162,7 @@ class ExternalTabContainer : public TabContentsDelegate,
HACCEL external_accel_table_;
unsigned int external_accel_entry_count_;
// A view to handle focus cycling
- TabContentsContainerView* tab_contents_container_;
+ TabContentsContainer* tab_contents_container_;
private:
int tab_handle_;
diff --git a/chrome/browser/views/browser_views.vcproj b/chrome/browser/views/browser_views.vcproj
index f36a0072..4912e2f 100644
--- a/chrome/browser/views/browser_views.vcproj
+++ b/chrome/browser/views/browser_views.vcproj
@@ -411,6 +411,30 @@
>
</File>
</Filter>
+ <Filter
+ Name="TabContents"
+ >
+ <File
+ RelativePath=".\tab_contents\native_tab_contents_container.h"
+ >
+ </File>
+ <File
+ RelativePath=".\tab_contents\native_tab_contents_container_win.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\tab_contents\native_tab_contents_container_win.h"
+ >
+ </File>
+ <File
+ RelativePath=".\tab_contents\tab_contents_container.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\tab_contents\tab_contents_container.h"
+ >
+ </File>
+ </Filter>
<File
RelativePath=".\about_chrome_view.cc"
>
@@ -824,14 +848,6 @@
>
</File>
<File
- RelativePath=".\tab_contents_container_view.cc"
- >
- </File>
- <File
- RelativePath=".\tab_contents_container_view.h"
- >
- </File>
- <File
RelativePath=".\tab_icon_view.cc"
>
</File>
diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc
index 31e1fd9..d9fe819 100644
--- a/chrome/browser/views/frame/browser_view.cc
+++ b/chrome/browser/views/frame/browser_view.cc
@@ -31,7 +31,7 @@
#include "chrome/browser/views/fullscreen_exit_bubble.h"
#include "chrome/browser/views/infobars/infobar_container.h"
#include "chrome/browser/views/status_bubble_views.h"
-#include "chrome/browser/views/tab_contents_container_view.h"
+#include "chrome/browser/views/tab_contents/tab_contents_container.h"
#include "chrome/browser/views/tabs/tab_strip.h"
#include "chrome/browser/views/toolbar_star_toggle.h"
#include "chrome/browser/views/toolbar_view.h"
@@ -362,7 +362,7 @@ gfx::Rect BrowserView::GetFindBarBoundingBox() const {
// This function returns the area the Find Bar can be laid out within. This
// basically implies the "user-perceived content area" of the browser window
// excluding the vertical scrollbar. This is not quite so straightforward as
- // positioning based on the TabContentsContainerView since the BookmarkBarView
+ // positioning based on the TabContentsContainer since the BookmarkBarView
// may be visible but not persistent (in the New Tab case) and we position
// the Find Bar over the top of it in that case since the BookmarkBarView is
// not _visually_ connected to the Toolbar.
@@ -594,9 +594,9 @@ StatusBubble* BrowserView::GetStatusBubble() {
void BrowserView::SelectedTabToolbarSizeChanged(bool is_animating) {
if (is_animating) {
- contents_container_->set_fast_resize(true);
+ contents_container_->SetFastResize(true);
UpdateUIForContents(browser_->GetSelectedTabContents());
- contents_container_->set_fast_resize(false);
+ contents_container_->SetFastResize(false);
} else {
UpdateUIForContents(browser_->GetSelectedTabContents());
contents_container_->Layout();
@@ -892,7 +892,7 @@ void BrowserView::TabDetachedAt(TabContents* contents, int index) {
// freed. This is because the focus manager performs some operations
// on the selected TabContents when it is removed.
infobar_container_->ChangeTabContents(NULL);
- contents_container_->SetTabContents(NULL);
+ contents_container_->ChangeTabContents(NULL);
}
}
@@ -911,8 +911,8 @@ void BrowserView::TabSelectedAt(TabContents* old_contents,
// Update various elements that are interested in knowing the current
// TabContents.
infobar_container_->ChangeTabContents(new_contents);
- contents_container_->SetTabContents(new_contents);
- // TODO(beng): This should be called automatically by SetTabContents, but I
+ contents_container_->ChangeTabContents(new_contents);
+ // TODO(beng): This should be called automatically by ChangeTabContents, but I
// am striving for parity now rather than cleanliness. This is
// required to make features like Duplicate Tab, Undo Close Tab,
// etc not result in sad tab.
@@ -1278,7 +1278,7 @@ void BrowserView::Init() {
infobar_container_ = new InfoBarContainer(this);
AddChildView(infobar_container_);
- contents_container_ = new TabContentsContainerView;
+ contents_container_ = new TabContentsContainer;
set_contents_view(contents_container_);
AddChildView(contents_container_);
diff --git a/chrome/browser/views/frame/browser_view.h b/chrome/browser/views/frame/browser_view.h
index 64294fe..f230ecf 100644
--- a/chrome/browser/views/frame/browser_view.h
+++ b/chrome/browser/views/frame/browser_view.h
@@ -33,7 +33,7 @@ class FullscreenExitBubble;
class HtmlDialogUIDelegate;
class InfoBarContainer;
class StatusBubbleViews;
-class TabContentsContainerView;
+class TabContentsContainer;
class TabStrip;
namespace views {
@@ -179,6 +179,12 @@ class BrowserView : public BrowserWindow,
void AttachBrowserBubble(BrowserBubble *bubble);
void DetachBrowserBubble(BrowserBubble *bubble);
+#ifdef UNIT_TEST
+ TabContentsContainer* contents_container() const {
+ return contents_container_;
+ }
+#endif
+
// Overridden from BrowserWindow:
virtual void Show();
virtual void SetBounds(const gfx::Rect& bounds);
@@ -377,7 +383,7 @@ class BrowserView : public BrowserWindow,
int find_bar_y_;
// The view that contains the selected TabContents.
- TabContentsContainerView* contents_container_;
+ TabContentsContainer* contents_container_;
// The Status information bubble that appears at the bottom of the window.
scoped_ptr<StatusBubbleViews> status_bubble_;
diff --git a/chrome/browser/views/tab_contents/native_tab_contents_container.h b/chrome/browser/views/tab_contents/native_tab_contents_container.h
new file mode 100644
index 0000000..4d17002
--- /dev/null
+++ b/chrome/browser/views/tab_contents/native_tab_contents_container.h
@@ -0,0 +1,42 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_VIEWS_TAB_CONTENTS_NATIVE_TAB_CONTENTS_CONTAINER_H_
+#define CHROME_BROWSER_VIEWS_TAB_CONTENTS_NATIVE_TAB_CONTENTS_CONTAINER_H_
+
+class RenderViewHost;
+class TabContents;
+class TabContentsContainer;
+namespace views {
+class View;
+}
+
+// An interface that the TabContentsContainer uses to talk to a platform-
+// specific view that hosts the native handle of the TabContents' view.
+class NativeTabContentsContainer {
+ public:
+ // Creates an appropriate native container for the current platform.
+ static NativeTabContentsContainer* CreateNativeContainer(
+ TabContentsContainer* container);
+
+ // Attaches the new TabContents to the native container.
+ virtual void AttachContents(TabContents* contents) = 0;
+
+ // Detaches the old TabContents from the native container.
+ virtual void DetachContents(TabContents* contents) = 0;
+
+ // Tells the container to update less frequently during resizing operations
+ // so performance is better.
+ virtual void SetFastResize(bool fast_resize) = 0;
+
+ // Tells the container that the RenderViewHost for the attached TabContents
+ // has changed and it should update focus.
+ virtual void RenderViewHostChanged(RenderViewHost* old_host,
+ RenderViewHost* new_host) = 0;
+
+ // Retrieves the views::View that hosts the TabContents.
+ virtual views::View* GetView() = 0;
+};
+
+#endif // CHROME_BROWSER_VIEWS_TAB_CONTENTS_NATIVE_TAB_CONTENTS_CONTAINER_H_
diff --git a/chrome/browser/views/tab_contents/native_tab_contents_container_gtk.cc b/chrome/browser/views/tab_contents/native_tab_contents_container_gtk.cc
new file mode 100644
index 0000000..37bfae4
--- /dev/null
+++ b/chrome/browser/views/tab_contents/native_tab_contents_container_gtk.cc
@@ -0,0 +1,198 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/views/tab_contents/native_tab_contents_container_gtk.h"
+
+#include "chrome/browser/renderer_host/render_widget_host_view.h"
+#include "chrome/browser/tab_contents/interstitial_page.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/views/tab_contents/tab_contents_container.h"
+#include "views/focus/focus_manager.h"
+#include "views/widget/root_view.h"
+#include "views/widget/widget.h"
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeTabContentsContainerGtk, public:
+
+NativeTabContentsContainerGtk::NativeTabContentsContainerGtk(
+ TabContentsContainer* container)
+ : container_(container) {
+}
+
+NativeTabContentsContainerGtk::~NativeTabContentsContainerGtk() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeTabContentsContainerGtk, NativeTabContentsContainer overrides:
+
+void NativeTabContentsContainerGtk::AttachContents(TabContents* contents) {
+ // We need to register the tab contents window with the BrowserContainer so
+ // that the BrowserContainer is the focused view when the focus is on the
+ // TabContents window (for the TabContents case).
+ SetAssociatedFocusView(this);
+
+ Attach(contents->GetNativeView());
+
+ // TODO(port): figure out focus interception
+#if defined(OS_WIN)
+ HWND contents_hwnd = contents->GetContentNativeView();
+ if (contents_hwnd)
+ views::FocusManager::InstallFocusSubclass(contents_hwnd, this);
+#endif
+}
+
+void NativeTabContentsContainerGtk::DetachContents(TabContents* contents) {
+ // TODO(port): figure out focus interception
+#if defined(OS_WIN)
+ // TODO(brettw) should this move to HWNDView::Detach which is called below?
+ // It needs cleanup regardless.
+ HWND container_hwnd = contents->GetNativeView();
+
+ // Hide the contents before adjusting its parent to avoid a full desktop
+ // flicker.
+ ShowWindow(container_hwnd, SW_HIDE);
+
+ // Reset the parent to NULL to ensure hidden tabs don't receive messages.
+ ::SetParent(container_hwnd, NULL);
+
+ // Unregister the tab contents window from the FocusManager.
+ views::FocusManager::UninstallFocusSubclass(container_hwnd);
+ HWND hwnd = contents->GetContentNativeView();
+ if (hwnd) {
+ // We may not have an HWND anymore, if the renderer crashed and we are
+ // displaying the sad tab for example.
+ views::FocusManager::UninstallFocusSubclass(hwnd);
+ }
+#endif
+
+ // Now detach the TabContents.
+ Detach();
+}
+
+void NativeTabContentsContainerGtk::SetFastResize(bool fast_resize) {
+ set_fast_resize(fast_resize);
+}
+
+void NativeTabContentsContainerGtk::RenderViewHostChanged(
+ RenderViewHost* old_host,
+ RenderViewHost* new_host) {
+ // TODO(port): figure out focus interception
+#if defined(OS_WIN)
+ if (old_host && old_host->view()) {
+ views::FocusManager::UninstallFocusSubclass(
+ old_host->view()->GetPluginNativeView());
+ }
+
+ if (new_host && new_host->view()) {
+ views::FocusManager::InstallFocusSubclass(
+ new_host->view()->GetPluginNativeView(), this);
+ }
+
+ // If we are focused, we need to pass the focus to the new RenderViewHost.
+ views::FocusManager* focus_manager = views::FocusManager::GetFocusManager(
+ GetRootView()->GetWidget()->GetNativeView());
+ if (focus_manager->GetFocusedView() == this)
+ Focus();
+#endif
+}
+
+views::View* NativeTabContentsContainerGtk::GetView() {
+ return this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeTabContentsContainerGtk, views::View overrides:
+
+bool NativeTabContentsContainerGtk::SkipDefaultKeyEventProcessing(
+ const views::KeyEvent& e) {
+ // Don't look-up accelerators or tab-traverse if we are showing a non-crashed
+ // TabContents.
+ // We'll first give the page a chance to process the key events. If it does
+ // not process them, they'll be returned to us and we'll treat them as
+ // accelerators then.
+ return container_->tab_contents() &&
+ !container_->tab_contents()->is_crashed();
+}
+
+views::FocusTraversable* NativeTabContentsContainerGtk::GetFocusTraversable() {
+ return NULL;
+}
+
+bool NativeTabContentsContainerGtk::IsFocusable() const {
+ // We need to be focusable when our contents is not a view hierarchy, as
+ // clicking on the contents needs to focus us.
+ return container_->tab_contents() != NULL;
+}
+
+void NativeTabContentsContainerGtk::Focus() {
+ if (container_->tab_contents()) {
+ // Set the native focus on the actual content of the tab, that is the
+ // interstitial if one is showing.
+ if (container_->tab_contents()->interstitial_page()) {
+ container_->tab_contents()->interstitial_page()->Focus();
+ return;
+ }
+ // TODO(port): set focus to inner content widget.
+#if defined(OS_WIN)
+ SetFocus(container_->tab_contents()->GetContentNativeView());
+#endif
+ }
+}
+
+void NativeTabContentsContainerGtk::RequestFocus() {
+ // This is a hack to circumvent the fact that a view does not explicitly get
+ // a call to set the focus if it already has the focus. This causes a problem
+ // with tabs such as the TabContents that instruct the RenderView that it got
+ // focus when they actually get the focus. When switching from one TabContents
+ // tab that has focus to another TabContents tab that had focus, since the
+ // TabContentsContainerView already has focus, Focus() would not be called and
+ // the RenderView would not get notified it got focused.
+ // By clearing the focused view before-hand, we ensure Focus() will be called.
+ GetRootView()->FocusView(NULL);
+ View::RequestFocus();
+}
+
+void NativeTabContentsContainerGtk::AboutToRequestFocusFromTabTraversal(
+ bool reverse) {
+ if (!container_->tab_contents())
+ return;
+ // Give an opportunity to the tab to reset its focus.
+ if (container_->tab_contents()->interstitial_page()) {
+ container_->tab_contents()->interstitial_page()->SetInitialFocus(reverse);
+ return;
+ }
+ container_->tab_contents()->SetInitialFocus(reverse);
+}
+
+bool NativeTabContentsContainerGtk::GetAccessibleRole(
+ AccessibilityTypes::Role* role) {
+ // TODO(port): figure out a11y
+#if defined(OS_WIN)
+ DCHECK(role);
+
+ *role = AccessibilityTypes::ROLE_GROUPING;
+#endif
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeTabContentsContainerGtk, views::FocusTraversable overrides:
+
+views::FocusTraversable*
+ NativeTabContentsContainerGtk::GetFocusTraversableParent() {
+ return GetRootView();
+}
+
+views::View* NativeTabContentsContainerGtk::GetFocusTraversableParentView() {
+ return this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeTabContentsContainer, public:
+
+// static
+NativeTabContentsContainer* NativeTabContentsContainer::CreateNativeContainer(
+ TabContentsContainer* container) {
+ return new NativeTabContentsContainerGtk(container);
+}
diff --git a/chrome/browser/views/tab_contents/native_tab_contents_container_gtk.h b/chrome/browser/views/tab_contents/native_tab_contents_container_gtk.h
new file mode 100644
index 0000000..e4e245d
--- /dev/null
+++ b/chrome/browser/views/tab_contents/native_tab_contents_container_gtk.h
@@ -0,0 +1,40 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_VIEWS_TAB_CONTENTS_NATIVE_TAB_CONTENTS_CONTAINER_GTK_H_
+#define CHROME_BROWSER_VIEWS_TAB_CONTENTS_NATIVE_TAB_CONTENTS_CONTAINER_GTK_H_
+
+#include "chrome/browser/views/tab_contents/native_tab_contents_container.h"
+#include "views/controls/native_view_host_gtk.h"
+
+class NativeTabContentsContainerGtk : public NativeTabContentsContainer,
+ public views::NativeViewHostGtk {
+ public:
+ explicit NativeTabContentsContainerGtk(TabContentsContainer* container);
+ virtual ~NativeTabContentsContainerGtk();
+
+ // Overridden from NativeTabContentsContainer:
+ virtual void AttachContents(TabContents* contents);
+ virtual void DetachContents(TabContents* contents);
+ virtual void SetFastResize(bool fast_resize);
+ virtual void RenderViewHostChanged(RenderViewHost* old_host,
+ RenderViewHost* new_host);
+ virtual views::View* GetView();
+
+ // Overridden from views::View:
+ virtual bool SkipDefaultKeyEventProcessing(const views::KeyEvent& e);
+ virtual views::FocusTraversable* GetFocusTraversable();
+ virtual bool IsFocusable() const;
+ virtual void Focus();
+ virtual void RequestFocus();
+ virtual void AboutToRequestFocusFromTabTraversal(bool reverse);
+ virtual bool GetAccessibleRole(AccessibilityTypes::Role* role);
+
+ private:
+ TabContentsContainer* container_;
+
+ DISALLOW_COPY_AND_ASSIGN(NativeTabContentsContainerGtk);
+};
+
+#endif // CHROME_BROWSER_VIEWS_TAB_CONTENTS_NATIVE_TAB_CONTENTS_CONTAINER_GTK_H_
diff --git a/chrome/browser/views/tab_contents/native_tab_contents_container_win.cc b/chrome/browser/views/tab_contents/native_tab_contents_container_win.cc
new file mode 100644
index 0000000..c715d7d
--- /dev/null
+++ b/chrome/browser/views/tab_contents/native_tab_contents_container_win.cc
@@ -0,0 +1,182 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/views/tab_contents/native_tab_contents_container_win.h"
+
+#include "chrome/browser/renderer_host/render_widget_host_view.h"
+#include "chrome/browser/tab_contents/interstitial_page.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/views/tab_contents/tab_contents_container.h"
+#include "views/focus/focus_manager.h"
+#include "views/widget/root_view.h"
+#include "views/widget/widget.h"
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeTabContentsContainerWin, public:
+
+NativeTabContentsContainerWin::NativeTabContentsContainerWin(
+ TabContentsContainer* container)
+ : container_(container) {
+}
+
+NativeTabContentsContainerWin::~NativeTabContentsContainerWin() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeTabContentsContainerWin, NativeTabContentsContainer overrides:
+
+void NativeTabContentsContainerWin::AttachContents(TabContents* contents) {
+ // We need to register the tab contents window with the BrowserContainer so
+ // that the BrowserContainer is the focused view when the focus is on the
+ // TabContents window (for the TabContents case).
+ SetAssociatedFocusView(this);
+
+ Attach(contents->GetNativeView());
+ HWND contents_hwnd = contents->GetContentNativeView();
+ if (contents_hwnd)
+ views::FocusManager::InstallFocusSubclass(contents_hwnd, this);
+}
+
+void NativeTabContentsContainerWin::DetachContents(TabContents* contents) {
+ // TODO(brettw) should this move to HWNDView::Detach which is called below?
+ // It needs cleanup regardless.
+ HWND container_hwnd = contents->GetNativeView();
+
+ // Hide the contents before adjusting its parent to avoid a full desktop
+ // flicker.
+ ShowWindow(container_hwnd, SW_HIDE);
+
+ // Reset the parent to NULL to ensure hidden tabs don't receive messages.
+ ::SetParent(container_hwnd, NULL);
+
+ // Unregister the tab contents window from the FocusManager.
+ views::FocusManager::UninstallFocusSubclass(container_hwnd);
+ HWND hwnd = contents->GetContentNativeView();
+ if (hwnd) {
+ // We may not have an HWND anymore, if the renderer crashed and we are
+ // displaying the sad tab for example.
+ views::FocusManager::UninstallFocusSubclass(hwnd);
+ }
+
+ // Now detach the TabContents.
+ Detach();
+}
+
+void NativeTabContentsContainerWin::SetFastResize(bool fast_resize) {
+ set_fast_resize(fast_resize);
+}
+
+void NativeTabContentsContainerWin::RenderViewHostChanged(
+ RenderViewHost* old_host,
+ RenderViewHost* new_host) {
+ if (old_host && old_host->view()) {
+ views::FocusManager::UninstallFocusSubclass(
+ old_host->view()->GetPluginNativeView());
+ }
+
+ if (new_host && new_host->view()) {
+ views::FocusManager::InstallFocusSubclass(
+ new_host->view()->GetPluginNativeView(), this);
+ }
+
+ // If we are focused, we need to pass the focus to the new RenderViewHost.
+ views::FocusManager* focus_manager = views::FocusManager::GetFocusManager(
+ GetRootView()->GetWidget()->GetNativeView());
+ if (focus_manager->GetFocusedView() == this)
+ Focus();
+}
+
+views::View* NativeTabContentsContainerWin::GetView() {
+ return this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeTabContentsContainerWin, views::View overrides:
+
+bool NativeTabContentsContainerWin::SkipDefaultKeyEventProcessing(
+ const views::KeyEvent& e) {
+ // Don't look-up accelerators or tab-traverse if we are showing a non-crashed
+ // TabContents.
+ // We'll first give the page a chance to process the key events. If it does
+ // not process them, they'll be returned to us and we'll treat them as
+ // accelerators then.
+ return container_->tab_contents() &&
+ !container_->tab_contents()->is_crashed();
+}
+
+views::FocusTraversable* NativeTabContentsContainerWin::GetFocusTraversable() {
+ return NULL;
+}
+
+bool NativeTabContentsContainerWin::IsFocusable() const {
+ // We need to be focusable when our contents is not a view hierarchy, as
+ // clicking on the contents needs to focus us.
+ return container_->tab_contents() != NULL;
+}
+
+void NativeTabContentsContainerWin::Focus() {
+ if (container_->tab_contents()) {
+ // Set the native focus on the actual content of the tab, that is the
+ // interstitial if one is showing.
+ if (container_->tab_contents()->interstitial_page()) {
+ container_->tab_contents()->interstitial_page()->Focus();
+ return;
+ }
+ SetFocus(container_->tab_contents()->GetContentNativeView());
+ }
+}
+
+void NativeTabContentsContainerWin::RequestFocus() {
+ // This is a hack to circumvent the fact that a view does not explicitly get
+ // a call to set the focus if it already has the focus. This causes a problem
+ // with tabs such as the TabContents that instruct the RenderView that it got
+ // focus when they actually get the focus. When switching from one TabContents
+ // tab that has focus to another TabContents tab that had focus, since the
+ // TabContentsContainerView already has focus, Focus() would not be called and
+ // the RenderView would not get notified it got focused.
+ // By clearing the focused view before-hand, we ensure Focus() will be called.
+ GetRootView()->FocusView(NULL);
+ View::RequestFocus();
+}
+
+void NativeTabContentsContainerWin::AboutToRequestFocusFromTabTraversal(
+ bool reverse) {
+ if (!container_->tab_contents())
+ return;
+ // Give an opportunity to the tab to reset its focus.
+ if (container_->tab_contents()->interstitial_page()) {
+ container_->tab_contents()->interstitial_page()->SetInitialFocus(reverse);
+ return;
+ }
+ container_->tab_contents()->SetInitialFocus(reverse);
+}
+
+bool NativeTabContentsContainerWin::GetAccessibleRole(
+ AccessibilityTypes::Role* role) {
+ DCHECK(role);
+
+ *role = AccessibilityTypes::ROLE_GROUPING;
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeTabContentsContainerWin, views::FocusTraversable overrides:
+
+views::FocusTraversable*
+ NativeTabContentsContainerWin::GetFocusTraversableParent() {
+ return GetRootView();
+}
+
+views::View* NativeTabContentsContainerWin::GetFocusTraversableParentView() {
+ return this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeTabContentsContainer, public:
+
+// static
+NativeTabContentsContainer* NativeTabContentsContainer::CreateNativeContainer(
+ TabContentsContainer* container) {
+ return new NativeTabContentsContainerWin(container);
+}
diff --git a/chrome/browser/views/tab_contents/native_tab_contents_container_win.h b/chrome/browser/views/tab_contents/native_tab_contents_container_win.h
new file mode 100644
index 0000000..92ed769
--- /dev/null
+++ b/chrome/browser/views/tab_contents/native_tab_contents_container_win.h
@@ -0,0 +1,44 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_VIEWS_TAB_CONTENTS_NATIVE_TAB_CONTENTS_CONTAINER_WIN_H_
+#define CHROME_BROWSER_VIEWS_TAB_CONTENTS_NATIVE_TAB_CONTENTS_CONTAINER_WIN_H_
+
+#include "chrome/browser/views/tab_contents/native_tab_contents_container.h"
+#include "views/controls/hwnd_view.h"
+
+class NativeTabContentsContainerWin : public NativeTabContentsContainer,
+ public views::HWNDView {
+ public:
+ explicit NativeTabContentsContainerWin(TabContentsContainer* container);
+ virtual ~NativeTabContentsContainerWin();
+
+ // Overridden from NativeTabContentsContainer:
+ virtual void AttachContents(TabContents* contents);
+ virtual void DetachContents(TabContents* contents);
+ virtual void SetFastResize(bool fast_resize);
+ virtual void RenderViewHostChanged(RenderViewHost* old_host,
+ RenderViewHost* new_host);
+ virtual views::View* GetView();
+
+ // Overridden from views::View:
+ virtual bool SkipDefaultKeyEventProcessing(const views::KeyEvent& e);
+ virtual views::FocusTraversable* GetFocusTraversable();
+ virtual bool IsFocusable() const;
+ virtual void Focus();
+ virtual void RequestFocus();
+ virtual void AboutToRequestFocusFromTabTraversal(bool reverse);
+ virtual bool GetAccessibleRole(AccessibilityTypes::Role* role);
+
+ // Overridden from HWNDView:
+ virtual views::FocusTraversable* GetFocusTraversableParent();
+ virtual views::View* GetFocusTraversableParentView();
+
+ private:
+ TabContentsContainer* container_;
+
+ DISALLOW_COPY_AND_ASSIGN(NativeTabContentsContainerWin);
+};
+
+#endif // CHROME_BROWSER_VIEWS_TAB_CONTENTS_NATIVE_TAB_CONTENTS_CONTAINER_WIN_H_
diff --git a/chrome/browser/views/tab_contents/tab_contents_container.cc b/chrome/browser/views/tab_contents/tab_contents_container.cc
new file mode 100644
index 0000000..8ffe870
--- /dev/null
+++ b/chrome/browser/views/tab_contents/tab_contents_container.cc
@@ -0,0 +1,112 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/views/tab_contents/tab_contents_container.h"
+
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/view_ids.h"
+#include "chrome/browser/views/tab_contents/native_tab_contents_container.h"
+#include "chrome/common/notification_service.h"
+
+////////////////////////////////////////////////////////////////////////////////
+// TabContentsContainer, public:
+
+TabContentsContainer::TabContentsContainer()
+ : native_container_(NULL),
+ tab_contents_(NULL) {
+ SetID(VIEW_ID_TAB_CONTAINER);
+}
+
+TabContentsContainer::~TabContentsContainer() {
+ if (tab_contents_)
+ RemoveObservers();
+}
+
+void TabContentsContainer::ChangeTabContents(TabContents* contents) {
+ if (tab_contents_) {
+ native_container_->DetachContents(tab_contents_);
+ tab_contents_->WasHidden();
+ RemoveObservers();
+ }
+ tab_contents_ = contents;
+ // When detaching the last tab of the browser ChangeTabContents is invoked
+ // with NULL. Don't attempt to do anything in that case.
+ if (tab_contents_) {
+ native_container_->AttachContents(tab_contents_);
+ AddObservers();
+ }
+}
+
+void TabContentsContainer::SetFastResize(bool fast_resize) {
+ native_container_->SetFastResize(fast_resize);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// TabContentsContainer, NotificationObserver implementation:
+
+void TabContentsContainer::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (type == NotificationType::RENDER_VIEW_HOST_CHANGED) {
+ RenderViewHostSwitchedDetails* switched_details =
+ Details<RenderViewHostSwitchedDetails>(details).ptr();
+ RenderViewHostChanged(switched_details->old_host,
+ switched_details->new_host);
+ } else if (type == NotificationType::TAB_CONTENTS_DESTROYED) {
+ TabContentsDestroyed(Source<TabContents>(source).ptr());
+ } else {
+ NOTREACHED();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// TabContentsContainer, View overrides:
+
+void TabContentsContainer::Layout() {
+ if (native_container_) {
+ native_container_->GetView()->SetBounds(0, 0, width(), height());
+ native_container_->GetView()->Layout();
+ }
+}
+
+void TabContentsContainer::ViewHierarchyChanged(bool is_add,
+ views::View* parent,
+ views::View* child) {
+ if (is_add && child == this) {
+ native_container_ = NativeTabContentsContainer::CreateNativeContainer(this);
+ AddChildView(native_container_->GetView());
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// TabContentsContainer, private:
+
+void TabContentsContainer::AddObservers() {
+ // TabContents can change their RenderViewHost and hence the HWND that is
+ // shown and getting focused. We need to keep track of that so we install
+ // the focus subclass on the shown HWND so we intercept focus change events.
+ registrar_.Add(this,
+ NotificationType::RENDER_VIEW_HOST_CHANGED,
+ Source<NavigationController>(&tab_contents_->controller()));
+
+ registrar_.Add(this,
+ NotificationType::TAB_CONTENTS_DESTROYED,
+ Source<TabContents>(tab_contents_));
+}
+
+void TabContentsContainer::RemoveObservers() {
+ registrar_.RemoveAll();
+}
+
+void TabContentsContainer::RenderViewHostChanged(RenderViewHost* old_host,
+ RenderViewHost* new_host) {
+ native_container_->RenderViewHostChanged(old_host, new_host);
+}
+
+void TabContentsContainer::TabContentsDestroyed(TabContents* contents) {
+ // Sometimes, a TabContents is destroyed before we know about it. This allows
+ // us to clean up our state in case this happens.
+ DCHECK(contents == tab_contents_);
+ ChangeTabContents(NULL);
+}
diff --git a/chrome/browser/views/tab_contents/tab_contents_container.h b/chrome/browser/views/tab_contents/tab_contents_container.h
new file mode 100644
index 0000000..aba2565
--- /dev/null
+++ b/chrome/browser/views/tab_contents/tab_contents_container.h
@@ -0,0 +1,79 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_VIEWS_TAB_CONTENTS_TAB_CONTENTS_CONTAINER_H_
+#define CHROME_BROWSER_VIEWS_TAB_CONTENTS_TAB_CONTENTS_CONTAINER_H_
+
+#ifdef UNIT_TEST
+#include "chrome/browser/views/tab_contents/native_tab_contents_container.h"
+#endif
+#include "chrome/common/notification_registrar.h"
+#include "views/view.h"
+
+class NativeTabContentsContainer;
+class RenderViewHost;
+class TabContents;
+
+class TabContentsContainer : public views::View,
+ public NotificationObserver {
+ public:
+ TabContentsContainer();
+ virtual ~TabContentsContainer();
+
+ // Changes the TabContents associated with this view.
+ void ChangeTabContents(TabContents* contents);
+
+ // Accessor for |tab_contents_|.
+ TabContents* tab_contents() const { return tab_contents_; }
+
+#ifdef UNIT_TEST
+ View* GetFocusView() { return native_container_->GetView(); }
+#endif
+
+ // Tells the container to update less frequently during resizing operations
+ // so performance is better.
+ void SetFastResize(bool fast_resize);
+
+ // Overridden from NotificationObserver:
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ // Overridden from views::View:
+ virtual void Layout();
+ protected:
+
+ // Overridden from views::View:
+ virtual void ViewHierarchyChanged(bool is_add, views::View* parent,
+ views::View* child);
+
+ private:
+ // Add or remove observers for events that we care about.
+ void AddObservers();
+ void RemoveObservers();
+
+ // Called when the RenderViewHost of the hosted TabContents has changed, e.g.
+ // to show an interstitial page.
+ void RenderViewHostChanged(RenderViewHost* old_host,
+ RenderViewHost* new_host);
+
+ // Called when a TabContents is destroyed. This gives us a chance to clean
+ // up our internal state if the TabContents is somehow destroyed before we
+ // get notified.
+ void TabContentsDestroyed(TabContents* contents);
+
+ // An instance of a NativeTabContentsContainer object that holds the native
+ // view handle associated with the attached TabContents.
+ NativeTabContentsContainer* native_container_;
+
+ // The attached TabContents.
+ TabContents* tab_contents_;
+
+ // Handles registering for our notifications.
+ NotificationRegistrar registrar_;
+
+ DISALLOW_COPY_AND_ASSIGN(TabContentsContainer);
+};
+
+#endif // CHROME_BROWSER_VIEWS_TAB_CONTENTS_TAB_CONTENTS_CONTAINER_H_
diff --git a/chrome/browser/views/tab_contents_container_view.cc b/chrome/browser/views/tab_contents_container_view.cc
deleted file mode 100644
index def7279..0000000
--- a/chrome/browser/views/tab_contents_container_view.cc
+++ /dev/null
@@ -1,223 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/views/tab_contents_container_view.h"
-
-#include <algorithm>
-
-#include "base/logging.h"
-#include "chrome/browser/renderer_host/render_view_host.h"
-#include "chrome/browser/renderer_host/render_widget_host_view.h"
-#include "chrome/browser/tab_contents/interstitial_page.h"
-#include "chrome/browser/tab_contents/render_view_host_manager.h"
-#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/view_ids.h"
-#include "chrome/common/notification_service.h"
-#include "views/widget/root_view.h"
-#include "views/widget/widget.h"
-
-using views::FocusTraversable;
-using views::FocusManager;
-using views::View;
-
-TabContentsContainerView::TabContentsContainerView() : tab_contents_(NULL) {
- SetID(VIEW_ID_TAB_CONTAINER);
-}
-
-TabContentsContainerView::~TabContentsContainerView() {
- if (tab_contents_)
- RemoveObservers();
-}
-
-void TabContentsContainerView::SetTabContents(TabContents* tab_contents) {
- if (tab_contents_) {
- // TODO(brettw) should this move to HWNDView::Detach which is called below?
- // It needs cleanup regardless.
- HWND container_hwnd = tab_contents_->GetNativeView();
-
- // Hide the contents before adjusting its parent to avoid a full desktop
- // flicker.
- ::ShowWindow(container_hwnd, SW_HIDE);
-
- // Reset the parent to NULL to ensure hidden tabs don't receive messages.
- ::SetParent(container_hwnd, NULL);
-
- tab_contents_->WasHidden();
-
- // Unregister the tab contents window from the FocusManager.
- views::FocusManager::UninstallFocusSubclass(container_hwnd);
- HWND hwnd = tab_contents_->GetContentNativeView();
- if (hwnd) {
- // We may not have an HWND anymore, if the renderer crashed and we are
- // displaying the sad tab for example.
- FocusManager::UninstallFocusSubclass(hwnd);
- }
-
- // Now detach the TabContents.
- Detach();
-
- RemoveObservers();
- }
-
- tab_contents_ = tab_contents;
-
- if (!tab_contents_) {
- // When detaching the last tab of the browser SetTabContents is invoked
- // with NULL. Don't attempt to do anything in that case.
- return;
- }
-
- // We need to register the tab contents window with the BrowserContainer so
- // that the BrowserContainer is the focused view when the focus is on the
- // TabContents window (for the TabContents case).
- SetAssociatedFocusView(this);
-
- Attach(tab_contents->GetNativeView());
- HWND contents_hwnd = tab_contents_->GetContentNativeView();
- if (contents_hwnd)
- FocusManager::InstallFocusSubclass(contents_hwnd, this);
-
- AddObservers();
-}
-
-views::FocusTraversable* TabContentsContainerView::GetFocusTraversable() {
- return NULL;
-}
-
-bool TabContentsContainerView::IsFocusable() const {
- // We need to be focusable when our contents is not a view hierarchy, as
- // clicking on the contents needs to focus us.
- if (tab_contents_)
- return true;
-
- // If we do contain views, then we should just act as a regular container by
- // not being focusable.
- return false;
-}
-
-void TabContentsContainerView::AboutToRequestFocusFromTabTraversal(
- bool reverse) {
- if (!tab_contents_)
- return;
- // Give an opportunity to the tab to reset its focus.
- InterstitialPage* interstitial = tab_contents_->interstitial_page();
- if (interstitial) {
- interstitial->SetInitialFocus(reverse);
- return;
- }
- tab_contents_->SetInitialFocus(reverse);
-}
-
-views::FocusTraversable* TabContentsContainerView::GetFocusTraversableParent() {
- return GetRootView();
-}
-
-views::View* TabContentsContainerView::GetFocusTraversableParentView() {
- return this;
-}
-
-void TabContentsContainerView::Focus() {
- if (tab_contents_) {
- // Set the native focus on the actual content of the tab, that is the
- // interstitial if one is showing.
- InterstitialPage* interstitial = tab_contents_->interstitial_page();
- if (interstitial) {
- interstitial->Focus();
- return;
- }
- ::SetFocus(tab_contents_->GetContentNativeView());
- }
-}
-
-void TabContentsContainerView::RequestFocus() {
- // This is a hack to circumvent the fact that a view does not explicitly get
- // a call to set the focus if it already has the focus. This causes a problem
- // with tabs such as the TabContents that instruct the RenderView that it got
- // focus when they actually get the focus. When switching from one TabContents
- // tab that has focus to another TabContents tab that had focus, since the
- // TabContentsContainerView already has focus, Focus() would not be called and
- // the RenderView would not get notified it got focused.
- // By clearing the focused view before-hand, we ensure Focus() will be called.
- GetRootView()->FocusView(NULL);
- View::RequestFocus();
-}
-
-bool TabContentsContainerView::GetAccessibleRole(
- AccessibilityTypes::Role* role) {
- DCHECK(role);
-
- *role = AccessibilityTypes::ROLE_GROUPING;
- return true;
-}
-
-bool TabContentsContainerView::SkipDefaultKeyEventProcessing(
- const views::KeyEvent& e) {
- // Don't look-up accelerators or tab-traverse if we are showing a non-crashed
- // TabContents.
- // We'll first give the page a chance to process the key events. If it does
- // not process them, they'll be returned to us and we'll treat them as
- // accelerators then.
- if (tab_contents_ && !tab_contents_->is_crashed())
- return true;
- return false;
-}
-
-void TabContentsContainerView::Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- if (type == NotificationType::RENDER_VIEW_HOST_CHANGED) {
- RenderViewHostSwitchedDetails* switched_details =
- Details<RenderViewHostSwitchedDetails>(details).ptr();
- RenderViewHostChanged(switched_details->old_host,
- switched_details->new_host);
- } else if (type == NotificationType::TAB_CONTENTS_DESTROYED) {
- TabContentsDestroyed(Source<TabContents>(source).ptr());
- } else {
- NOTREACHED();
- }
-}
-
-void TabContentsContainerView::AddObservers() {
- // TabContents can change their RenderViewHost and hence the HWND that is
- // shown and getting focused. We need to keep track of that so we install
- // the focus subclass on the shown HWND so we intercept focus change events.
- registrar_.Add(this,
- NotificationType::RENDER_VIEW_HOST_CHANGED,
- Source<NavigationController>(&tab_contents_->controller()));
-
- registrar_.Add(this,
- NotificationType::TAB_CONTENTS_DESTROYED,
- Source<TabContents>(tab_contents_));
-}
-
-void TabContentsContainerView::RemoveObservers() {
- registrar_.RemoveAll();
-}
-
-void TabContentsContainerView::RenderViewHostChanged(RenderViewHost* old_host,
- RenderViewHost* new_host) {
- if (old_host && old_host->view()) {
- FocusManager::UninstallFocusSubclass(
- old_host->view()->GetPluginNativeView());
- }
-
- if (new_host && new_host->view()) {
- FocusManager::InstallFocusSubclass(
- new_host->view()->GetPluginNativeView(), this);
- }
-
- // If we are focused, we need to pass the focus to the new RenderViewHost.
- FocusManager* focus_manager = FocusManager::GetFocusManager(
- GetRootView()->GetWidget()->GetNativeView());
- if (focus_manager->GetFocusedView() == this)
- Focus();
-}
-
-void TabContentsContainerView::TabContentsDestroyed(TabContents* contents) {
- // Sometimes, a TabContents is destroyed before we know about it. This allows
- // us to clean up our state in case this happens.
- DCHECK(contents == tab_contents_);
- SetTabContents(NULL);
-}
diff --git a/chrome/browser/views/tab_contents_container_view.h b/chrome/browser/views/tab_contents_container_view.h
deleted file mode 100644
index a742c49..0000000
--- a/chrome/browser/views/tab_contents_container_view.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_VIEWS_TAB_CONTENTS_CONTAINER_VIEW_H_
-#define CHROME_BROWSER_VIEWS_TAB_CONTENTS_CONTAINER_VIEW_H_
-
-namespace ChromeView {
-class KeyEvent;
-class View;
-}
-class RenderViewHost;
-class TabContents;
-
-#include "chrome/common/notification_registrar.h"
-#include "views/controls/hwnd_view.h"
-#include "views/event.h"
-#include "views/focus/focus_manager.h"
-
-// This View contains the TabContents.
-// It takes care of linking the TabContents to the browser RootView so that the
-// focus can traverse from one to the other when pressing Tab/Shift-Tab.
-class TabContentsContainerView : public views::HWNDView,
- public NotificationObserver {
- public:
- TabContentsContainerView();
- virtual ~TabContentsContainerView();
-
- // Make the specified tab visible.
- void SetTabContents(TabContents* tab_contents);
- TabContents* GetTabContents() const { return tab_contents_; }
-
- // Overridden from View.
- virtual views::FocusTraversable* GetFocusTraversable();
- virtual bool IsFocusable() const;
- virtual void Focus();
- virtual void RequestFocus();
- virtual void AboutToRequestFocusFromTabTraversal(bool reverse);
- virtual bool GetAccessibleRole(AccessibilityTypes::Role* role);
-
- // Overridden from HWNDView.
- virtual views::FocusTraversable* GetFocusTraversableParent();
- virtual views::View* GetFocusTraversableParentView();
-
- // NotificationObserver implementation.
- virtual void Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details);
-
- protected:
- // Web content should be given first crack at accelerators. This function
- // returns true if not the sad tab.
- virtual bool SkipDefaultKeyEventProcessing(const views::KeyEvent& e);
-
- private:
- // Add or remove observers for events that we care about.
- void AddObservers();
- void RemoveObservers();
-
- // Called when the RenderViewHost of the hosted TabContents has changed, e.g.
- // to show an interstitial page.
- void RenderViewHostChanged(RenderViewHost* old_host,
- RenderViewHost* new_host);
-
- // Called when a TabContents is destroyed. This gives us a chance to clean
- // up our internal state if the TabContents is somehow destroyed before we
- // get notified.
- void TabContentsDestroyed(TabContents* contents);
-
- // Handles registering for our notifications.
- NotificationRegistrar registrar_;
-
- // The current TabContents shown.
- TabContents* tab_contents_;
-
- DISALLOW_COPY_AND_ASSIGN(TabContentsContainerView);
-};
-
-#endif // CHROME_BROWSER_VIEWS_TAB_CONTENTS_CONTAINER_VIEW_H_
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 6cecfdd..9556dff 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -1482,10 +1482,13 @@
'browser/views/star_toggle.h',
'browser/views/status_bubble_views.cc',
'browser/views/status_bubble_views.h',
- 'browser/views/tab_contents_container_view.cc',
- 'browser/views/tab_contents_container_view.h',
'browser/views/tab_icon_view.cc',
'browser/views/tab_icon_view.h',
+ 'browser/views/tab_contents/tab_contents_container.cc',
+ 'browser/views/tab_contents/tab_contents_container.h',
+ 'browser/views/tab_contents/native_tab_contents_container.h',
+ 'browser/views/tab_contents/native_tab_contents_container_win.cc',
+ 'browser/views/tab_contents/native_tab_contents_container_win.h',
'browser/views/tabs/dragged_tab_controller.cc',
'browser/views/tabs/dragged_tab_controller.h',
'browser/views/tabs/dragged_tab_view.cc',
@@ -1679,6 +1682,8 @@
['include', '^browser/views/info_bubble.h'],
['include', '^browser/views/location_bar_view.cc'],
['include', '^browser/views/location_bar_view.h'],
+ ['include', '^browser/views/tab_contents/native_tab_contents_container_gtk.cc'],
+ ['include', '^browser/views/tab_contents/native_tab_contents_container_gtk.h'],
['include', '^browser/views/tabs/dragged_tab_view.cc'],
['include', '^browser/views/tabs/dragged_tab_view.h'],
['include', '^browser/views/tabs/tab.cc'],