diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-22 23:00:38 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-22 23:00:38 +0000 |
commit | 610d36a0b785f0dfdb6cfce635806ddd5252cb39 (patch) | |
tree | e07ea7e6e636a5d806d891e315458abe1103984a /chrome | |
parent | ca607835220dbfa2842c7667e63fcb243960951d (diff) | |
download | chromium_src-610d36a0b785f0dfdb6cfce635806ddd5252cb39.zip chromium_src-610d36a0b785f0dfdb6cfce635806ddd5252cb39.tar.gz chromium_src-610d36a0b785f0dfdb6cfce635806ddd5252cb39.tar.bz2 |
Refactors TabContentsContainerView into TabContentsContainer and associated platform-specific inner classes.
BUG=none
TEST=make sure web page focus cycling in and out of the content area still works.
Review URL: http://codereview.chromium.org/113784
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16810 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
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'], |