summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/browser.cc6
-rw-r--r--chrome/browser/browser_focus_uitest.cc24
-rw-r--r--chrome/browser/browser_init.cc7
-rw-r--r--chrome/browser/browser_process_impl.cc7
-rw-r--r--chrome/browser/dom_ui/dom_ui_contents.cc3
-rw-r--r--chrome/browser/dom_ui/dom_ui_contents.h6
-rw-r--r--chrome/browser/sessions/session_restore.cc7
-rw-r--r--chrome/browser/tab_contents/tab_contents.cc88
-rw-r--r--chrome/browser/tab_contents/tab_contents.h20
-rw-r--r--chrome/browser/tab_contents/web_contents_view.h11
-rw-r--r--chrome/browser/tab_contents/web_contents_view_gtk.cc12
-rw-r--r--chrome/browser/tab_contents/web_contents_view_gtk.h3
-rw-r--r--chrome/browser/tab_contents/web_contents_view_mac.h3
-rw-r--r--chrome/browser/tab_contents/web_contents_view_mac.mm12
-rw-r--r--chrome/browser/tab_contents/web_contents_view_win.cc78
-rw-r--r--chrome/browser/tab_contents/web_contents_view_win.h6
-rw-r--r--chrome/browser/views/frame/browser_view.cc14
-rw-r--r--chrome/views/view_storage.cc19
-rw-r--r--chrome/views/view_storage.h9
19 files changed, 186 insertions, 149 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index dea7ae1..cbbe84d 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -31,6 +31,7 @@
#include "chrome/browser/tab_contents/site_instance.h"
#include "chrome/browser/tab_contents/tab_contents_type.h"
#include "chrome/browser/tab_contents/web_contents.h"
+#include "chrome/browser/tab_contents/web_contents_view.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/l10n_util.h"
@@ -318,7 +319,7 @@ void Browser::OpenApplicationWindow(Profile* profile, const GURL& url) {
browser->window()->Show();
// TODO(jcampan): http://crbug.com/8123 we should not need to set the initial
// focus explicitly.
- browser->GetSelectedTabContents()->SetInitialFocus();
+ browser->GetSelectedTabContents()->AsWebContents()->view()->SetInitialFocus();
}
///////////////////////////////////////////////////////////////////////////////
@@ -657,8 +658,7 @@ void Browser::NewTab() {
// The call to AddBlankTab above did not set the focus to the tab as its
// window was not active, so we have to do it explicitly.
// See http://crbug.com/6380.
- TabContents* tab = b->GetSelectedTabContents();
- tab->RestoreFocus();
+ b->GetSelectedTabContents()->AsWebContents()->view()->RestoreFocus();
}
}
diff --git a/chrome/browser/browser_focus_uitest.cc b/chrome/browser/browser_focus_uitest.cc
index d920a012..81edcc2 100644
--- a/chrome/browser/browser_focus_uitest.cc
+++ b/chrome/browser/browser_focus_uitest.cc
@@ -442,3 +442,27 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FindFocusTest) {
ASSERT_TRUE(focused_view != NULL);
EXPECT_EQ(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD, focused_view->GetID());
}
+
+// Makes sure the focus is in the right location when opening the different
+// types of tabs.
+IN_PROC_BROWSER_TEST_F(BrowserFocusTest, TabInitialFocus) {
+ HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle());
+ BrowserView* browser_view = BrowserView::GetBrowserViewForHWND(hwnd);
+ ASSERT_TRUE(browser_view);
+ views::FocusManager* focus_manager =
+ views::FocusManager::GetFocusManager(hwnd);
+ ASSERT_TRUE(focus_manager);
+
+ // Open the history tab, focus should be on the tab contents.
+ browser()->ShowHistoryTab();
+ EXPECT_EQ(browser_view->GetContentsView(), focus_manager->GetFocusedView());
+
+ // Open the new tab, focus should be on the location bar.
+ browser()->NewTab();
+ EXPECT_EQ(browser_view->GetLocationBarView(),
+ focus_manager->GetFocusedView());
+
+ // Open the download tab, focus should be on the tab contents.
+ browser()->ShowDownloadsTab();
+ EXPECT_EQ(browser_view->GetContentsView(), focus_manager->GetFocusedView());
+}
diff --git a/chrome/browser/browser_init.cc b/chrome/browser/browser_init.cc
index 328507cb..0e8ac37 100644
--- a/chrome/browser/browser_init.cc
+++ b/chrome/browser/browser_init.cc
@@ -25,6 +25,8 @@
#include "chrome/browser/sessions/session_restore.h"
#include "chrome/browser/tab_contents/infobar_delegate.h"
#include "chrome/browser/tab_contents/navigation_controller.h"
+#include "chrome/browser/tab_contents/web_contents.h"
+#include "chrome/browser/tab_contents/web_contents_view.h"
#include "chrome/browser/net/url_fixer_upper.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
@@ -341,7 +343,10 @@ Browser* BrowserInit::LaunchWithProfile::OpenURLsInBrowser(
browser->window()->Show();
// TODO(jcampan): http://crbug.com/8123 we should not need to set the initial
// focus explicitly.
- browser->GetSelectedTabContents()->SetInitialFocus();
+ if (browser->GetSelectedTabContents()->AsWebContents()) {
+ browser->GetSelectedTabContents()->AsWebContents()->view()->
+ SetInitialFocus();
+ }
return browser;
}
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index 2563d2d4..4730c93 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -196,13 +196,6 @@ BrowserProcessImpl::~BrowserProcessImpl() {
print_job_manager_->OnQuit();
print_job_manager_.reset();
- // TODO(port): remove this completely from BrowserProcessImpl, it has no
- // business being here.
-#if defined(OS_WIN)
- // The ViewStorage needs to go before the NotificationService.
- views::ViewStorage::DeleteSharedInstance();
-#endif
-
// Now OK to destroy NotificationService.
main_notification_service_.reset();
diff --git a/chrome/browser/dom_ui/dom_ui_contents.cc b/chrome/browser/dom_ui/dom_ui_contents.cc
index 9d80db3..f27d441 100644
--- a/chrome/browser/dom_ui/dom_ui_contents.cc
+++ b/chrome/browser/dom_ui/dom_ui_contents.cc
@@ -13,6 +13,7 @@
#include "chrome/browser/extensions/extensions_ui.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/tab_contents/navigation_entry.h"
+#include "chrome/browser/tab_contents/web_contents_view.h"
#include "chrome/common/l10n_util.h"
#include "chrome/common/resource_bundle.h"
#include "chrome/common/url_constants.h"
@@ -194,7 +195,7 @@ void DOMUIContents::SetInitialFocus() {
if (InitCurrentUI(false))
current_ui_->SetInitialFocus();
else
- TabContents::SetInitialFocus();
+ current_ui_->get_contents()->view()->SetInitialFocus();
}
const string16& DOMUIContents::GetTitle() const {
diff --git a/chrome/browser/dom_ui/dom_ui_contents.h b/chrome/browser/dom_ui/dom_ui_contents.h
index 3c8e985..f1796f2 100644
--- a/chrome/browser/dom_ui/dom_ui_contents.h
+++ b/chrome/browser/dom_ui/dom_ui_contents.h
@@ -105,8 +105,6 @@ class DOMUIContents : public WebContents {
virtual bool ShouldDisplayFavIcon();
// The bookmark bar is always visible on the new tab.
virtual bool IsBookmarkBarAlwaysVisible();
- // When NTP gets the initial focus, focus the URL bar.
- virtual void SetInitialFocus();
// Whether we want to display the page's URL.
virtual bool ShouldDisplayURL();
// Get the title for this page.
@@ -114,6 +112,7 @@ class DOMUIContents : public WebContents {
// We may wish to control what happens when a URL is opened.
virtual void RequestOpenURL(const GURL& url, const GURL& referrer,
WindowOpenDisposition disposition);
+ virtual DOMUIContents* AsDOMUIContents() { return this; }
virtual void RenderViewCreated(RenderViewHost* render_view_host);
@@ -124,6 +123,9 @@ class DOMUIContents : public WebContents {
const ViewHostMsg_FrameNavigate_Params& params) { }
virtual bool NavigateToPendingEntry(bool reload);
+ // Gives the DOMUI an opportunity to chose where the focus should go.
+ void SetInitialFocus();
+
// Return the scheme used. We currently use chrome-ui:
static const std::string GetScheme();
diff --git a/chrome/browser/sessions/session_restore.cc b/chrome/browser/sessions/session_restore.cc
index 51c5403..9563204 100644
--- a/chrome/browser/sessions/session_restore.cc
+++ b/chrome/browser/sessions/session_restore.cc
@@ -14,6 +14,8 @@
#include "chrome/browser/sessions/session_service.h"
#include "chrome/browser/sessions/session_types.h"
#include "chrome/browser/tab_contents/navigation_controller.h"
+#include "chrome/browser/tab_contents/web_contents.h"
+#include "chrome/browser/tab_contents/web_contents_view.h"
#include "chrome/common/notification_registrar.h"
#include "chrome/common/notification_service.h"
@@ -363,7 +365,10 @@ class SessionRestoreImpl : public NotificationObserver {
browser->window()->Show();
// TODO(jcampan): http://crbug.com/8123 we should not need to set the
// initial focus explicitly.
- browser->GetSelectedTabContents()->SetInitialFocus();
+ if (browser->GetSelectedTabContents()->AsWebContents()) {
+ browser->GetSelectedTabContents()->AsWebContents()->view()->
+ SetInitialFocus();
+ }
}
void AppendURLsToBrowser(Browser* browser, const std::vector<GURL>& urls) {
diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc
index 4da0609..0e8f6e4 100644
--- a/chrome/browser/tab_contents/tab_contents.cc
+++ b/chrome/browser/tab_contents/tab_contents.cc
@@ -22,10 +22,6 @@
#include "chrome/browser/views/download_started_animation.h"
#include "chrome/browser/views/blocked_popup_container.h"
#include "chrome/views/native_scroll_bar.h"
-#include "chrome/views/root_view.h"
-#include "chrome/views/view.h"
-#include "chrome/views/view_storage.h"
-#include "chrome/views/widget.h"
#endif
#if defined(OS_WIN)
@@ -54,22 +50,9 @@ TabContents::TabContents(TabContentsType type)
capturing_contents_(false),
blocked_popups_(NULL),
is_being_destroyed_(false) {
-#if defined(OS_WIN)
- last_focused_view_storage_id_ =
- views::ViewStorage::GetSharedInstance()->CreateStorageID();
-#endif
}
TabContents::~TabContents() {
-#if defined(OS_WIN)
- // Makes sure to remove any stored view we may still have in the ViewStorage.
- //
- // It is possible the view went away before us, so we only do this if the
- // view is registered.
- views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance();
- if (view_storage->RetrieveView(last_focused_view_storage_id_) != NULL)
- view_storage->RemoveView(last_focused_view_storage_id_);
-#endif
}
// static
@@ -366,77 +349,6 @@ void TabContents::Focus() {
#endif
}
-void TabContents::StoreFocus() {
-#if defined(OS_WIN)
- views::ViewStorage* view_storage =
- views::ViewStorage::GetSharedInstance();
-
- if (view_storage->RetrieveView(last_focused_view_storage_id_) != NULL)
- view_storage->RemoveView(last_focused_view_storage_id_);
-
- views::FocusManager* focus_manager =
- views::FocusManager::GetFocusManager(GetNativeView());
- if (focus_manager) {
- // |focus_manager| can be NULL if the tab has been detached but still
- // exists.
- views::View* focused_view = focus_manager->GetFocusedView();
- if (focused_view)
- view_storage->StoreView(last_focused_view_storage_id_, focused_view);
-
- // If the focus was on the page, explicitly clear the focus so that we
- // don't end up with the focused HWND not part of the window hierarchy.
- // TODO(brettw) this should move to the view somehow.
- HWND container_hwnd = GetNativeView();
- if (container_hwnd) {
- views::View* focused_view = focus_manager->GetFocusedView();
- if (focused_view) {
- HWND hwnd = focused_view->GetRootView()->GetWidget()->GetHWND();
- if (container_hwnd == hwnd || ::IsChild(container_hwnd, hwnd))
- focus_manager->ClearFocus();
- }
- }
- }
-#endif
-}
-
-void TabContents::RestoreFocus() {
-#if defined(OS_WIN)
- views::ViewStorage* view_storage =
- views::ViewStorage::GetSharedInstance();
- views::View* last_focused_view =
- view_storage->RetrieveView(last_focused_view_storage_id_);
-
- if (!last_focused_view) {
- SetInitialFocus();
- } else {
- views::FocusManager* focus_manager =
- views::FocusManager::GetFocusManager(GetNativeView());
-
- // If you hit this DCHECK, please report it to Jay (jcampan).
- DCHECK(focus_manager != NULL) << "No focus manager when restoring focus.";
-
- if (last_focused_view->IsFocusable() && focus_manager &&
- focus_manager->ContainsView(last_focused_view)) {
- last_focused_view->RequestFocus();
- } else {
- // The focused view may not belong to the same window hierarchy (e.g.
- // if the location bar was focused and the tab is dragged out), or it may
- // no longer be focusable (e.g. if the location bar was focused and then
- // we switched to fullscreen mode). In that case we default to the
- // default focus.
- SetInitialFocus();
- }
- view_storage->RemoveView(last_focused_view_storage_id_);
- }
-#endif
-}
-
-void TabContents::SetInitialFocus() {
-#if defined(OS_WIN)
- ::SetFocus(GetNativeView());
-#endif
-}
-
void TabContents::AddInfoBar(InfoBarDelegate* delegate) {
// Look through the existing InfoBarDelegates we have for a match. If we've
// already got one that matches, then we don't add the new one.
diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h
index 7d0e562..d28e068 100644
--- a/chrome/browser/tab_contents/tab_contents.h
+++ b/chrome/browser/tab_contents/tab_contents.h
@@ -37,6 +37,7 @@ class WindowDelegate;
}
class BlockedPopupContainer;
+class DOMUIContents;
class DOMUIHost;
class DownloadItem;
class DownloadShelf;
@@ -141,6 +142,9 @@ class TabContents : public PageNavigator,
// Returns this object as a DOMUIHost if it is one, and NULL otherwise.
virtual DOMUIHost* AsDOMUIHost() { return NULL; }
+ // Returns this object as a DOMUIContents if it is one, and NULL otherwise.
+ virtual DOMUIContents* AsDOMUIContents() { return NULL; }
+
TabContentsDelegate* delegate() const { return delegate_; }
void set_delegate(TabContentsDelegate* d) { delegate_ = d; }
@@ -373,13 +377,6 @@ class TabContents : public PageNavigator,
// Make the tab the focused window.
virtual void Focus();
- // Stores the currently focused view.
- virtual void StoreFocus();
-
- // Restores focus to the last focus view. If StoreFocus has not yet been
- // invoked, SetInitialFocus is invoked.
- virtual void RestoreFocus();
-
// Invoked the first time this tab is getting the focus through TAB traversal.
// By default this does nothing, but is overridden to set the focus for the
// first element in the page.
@@ -450,12 +447,6 @@ class TabContents : public PageNavigator,
// Called when a ConstrainedWindow we own is moved or resized.
void DidMoveOrResize(ConstrainedWindow* window);
- // Sets focus to the tab contents window, but doesn't actually set focus to
- // a particular element in it (see also SetInitialFocus(bool) which does
- // that in different circumstances).
- // FIXME(brettw) having two SetInitialFocus that do different things is silly.
- virtual void SetInitialFocus();
-
protected:
// NotificationObserver implementation:
virtual void Observe(NotificationType type,
@@ -548,9 +539,6 @@ class TabContents : public PageNavigator,
// each SiteInstance.
int32 max_page_id_;
- // The id used in the ViewStorage to store the last focused view.
- int last_focused_view_storage_id_;
-
// See capturing_contents() above.
bool capturing_contents_;
diff --git a/chrome/browser/tab_contents/web_contents_view.h b/chrome/browser/tab_contents/web_contents_view.h
index f9d7075..52fceba 100644
--- a/chrome/browser/tab_contents/web_contents_view.h
+++ b/chrome/browser/tab_contents/web_contents_view.h
@@ -115,6 +115,17 @@ class WebContentsView : public RenderViewHostDelegate::View {
// page.
virtual void ForwardMessageToDevToolsClient(const IPC::Message& message) = 0;
+ // Sets focus to the appropriate element when the tab contents is shown the
+ // first time.
+ virtual void SetInitialFocus() = 0;
+
+ // Stores the currently focused view.
+ virtual void StoreFocus() = 0;
+
+ // Restores focus to the last focus view. If StoreFocus has not yet been
+ // invoked, SetInitialFocus is invoked.
+ virtual void RestoreFocus() = 0;
+
protected:
WebContentsView() {} // Abstract interface.
diff --git a/chrome/browser/tab_contents/web_contents_view_gtk.cc b/chrome/browser/tab_contents/web_contents_view_gtk.cc
index a8a8522..6c90ae1 100644
--- a/chrome/browser/tab_contents/web_contents_view_gtk.cc
+++ b/chrome/browser/tab_contents/web_contents_view_gtk.cc
@@ -141,6 +141,18 @@ bool WebContentsViewGtk::GetFindBarWindowInfo(gfx::Point* position,
return false;
}
+void WebContentsViewGtk::SetInitialFocus() {
+ // TODO(port)
+}
+
+void WebContentsViewGtk::StoreFocus() {
+ // TODO(port)
+}
+
+void WebContentsViewGtk::RestoreFocus() {
+ // TODO(port)
+}
+
void WebContentsViewGtk::UpdateDragCursor(bool is_drop_target) {
NOTIMPLEMENTED();
}
diff --git a/chrome/browser/tab_contents/web_contents_view_gtk.h b/chrome/browser/tab_contents/web_contents_view_gtk.h
index 2edd353..ec71c49 100644
--- a/chrome/browser/tab_contents/web_contents_view_gtk.h
+++ b/chrome/browser/tab_contents/web_contents_view_gtk.h
@@ -41,6 +41,9 @@ class WebContentsViewGtk : public WebContentsView {
virtual void ReparentFindWindow(Browser* new_browser) const;
virtual bool GetFindBarWindowInfo(gfx::Point* position,
bool* fully_visible) const;
+ virtual void SetInitialFocus();
+ virtual void StoreFocus();
+ virtual void RestoreFocus();
// Backend implementation of RenderViewHostDelegate::View.
virtual WebContents* CreateNewWindowInternal(
diff --git a/chrome/browser/tab_contents/web_contents_view_mac.h b/chrome/browser/tab_contents/web_contents_view_mac.h
index 9f562c0..59eb422 100644
--- a/chrome/browser/tab_contents/web_contents_view_mac.h
+++ b/chrome/browser/tab_contents/web_contents_view_mac.h
@@ -56,6 +56,9 @@ class WebContentsViewMac : public WebContentsView,
virtual void HideFindBar(bool end_session);
virtual bool GetFindBarWindowInfo(gfx::Point* position,
bool* fully_visible) const;
+ virtual void SetInitialFocus();
+ virtual void StoreFocus();
+ virtual void RestoreFocus();
// Backend implementation of RenderViewHostDelegate::View.
virtual WebContents* CreateNewWindowInternal(
diff --git a/chrome/browser/tab_contents/web_contents_view_mac.mm b/chrome/browser/tab_contents/web_contents_view_mac.mm
index deb452c..b607697 100644
--- a/chrome/browser/tab_contents/web_contents_view_mac.mm
+++ b/chrome/browser/tab_contents/web_contents_view_mac.mm
@@ -152,6 +152,18 @@ bool WebContentsViewMac::GetFindBarWindowInfo(gfx::Point* position,
return true;
}
+void WebContentsViewMac::SetInitialFocus() {
+ // TODO(port)
+}
+
+void WebContentsViewMac::StoreFocus() {
+ // TODO(port)
+}
+
+void WebContentsViewMac::RestoreFocus() {
+ // TODO(port)
+}
+
void WebContentsViewMac::UpdateDragCursor(bool is_drop_target) {
NOTIMPLEMENTED();
}
diff --git a/chrome/browser/tab_contents/web_contents_view_win.cc b/chrome/browser/tab_contents/web_contents_view_win.cc
index 48b7466..51a9ffb 100644
--- a/chrome/browser/tab_contents/web_contents_view_win.cc
+++ b/chrome/browser/tab_contents/web_contents_view_win.cc
@@ -10,6 +10,7 @@
#include "chrome/browser/browser.h" // TODO(beng): this dependency is awful.
#include "chrome/browser/browser_process.h"
#include "chrome/browser/debugger/dev_tools_window.h"
+#include "chrome/browser/dom_ui/dom_ui_host.h"
#include "chrome/browser/download/download_request_manager.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/render_view_host.h"
@@ -24,6 +25,8 @@
#include "chrome/common/gfx/chrome_canvas.h"
#include "chrome/common/os_exchange_data.h"
#include "chrome/common/url_constants.h"
+#include "chrome/views/root_view.h"
+#include "chrome/views/view_storage.h"
#include "net/base/net_util.h"
#include "webkit/glue/plugins/webplugin_delegate_impl.h"
#include "webkit/glue/webdropdata.h"
@@ -51,9 +54,18 @@ WebContentsView* WebContentsView::Create(WebContents* web_contents) {
WebContentsViewWin::WebContentsViewWin(WebContents* web_contents)
: web_contents_(web_contents),
ignore_next_char_event_(false) {
+ last_focused_view_storage_id_ =
+ views::ViewStorage::GetSharedInstance()->CreateStorageID();
}
WebContentsViewWin::~WebContentsViewWin() {
+ // Makes sure to remove any stored view we may still have in the ViewStorage.
+ //
+ // It is possible the view went away before us, so we only do this if the
+ // view is registered.
+ views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance();
+ if (view_storage->RetrieveView(last_focused_view_storage_id_) != NULL)
+ view_storage->RemoveView(last_focused_view_storage_id_);
}
WebContents* WebContentsViewWin::GetWebContents() {
@@ -232,6 +244,72 @@ void WebContentsViewWin::ForwardMessageToDevToolsClient(
dev_tools_window_->SendDevToolsClientMessage(message);
}
+void WebContentsViewWin::SetInitialFocus() {
+ if (web_contents_->AsDOMUIContents())
+ web_contents_->AsDOMUIContents()->SetInitialFocus();
+ else
+ ::SetFocus(GetNativeView());
+}
+
+void WebContentsViewWin::StoreFocus() {
+ views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance();
+
+ if (view_storage->RetrieveView(last_focused_view_storage_id_) != NULL)
+ view_storage->RemoveView(last_focused_view_storage_id_);
+
+ views::FocusManager* focus_manager =
+ views::FocusManager::GetFocusManager(GetNativeView());
+ if (focus_manager) {
+ // |focus_manager| can be NULL if the tab has been detached but still
+ // exists.
+ views::View* focused_view = focus_manager->GetFocusedView();
+ if (focused_view)
+ view_storage->StoreView(last_focused_view_storage_id_, focused_view);
+
+ // If the focus was on the page, explicitly clear the focus so that we
+ // don't end up with the focused HWND not part of the window hierarchy.
+ // TODO(brettw) this should move to the view somehow.
+ HWND container_hwnd = GetNativeView();
+ if (container_hwnd) {
+ views::View* focused_view = focus_manager->GetFocusedView();
+ if (focused_view) {
+ HWND hwnd = focused_view->GetRootView()->GetWidget()->GetHWND();
+ if (container_hwnd == hwnd || ::IsChild(container_hwnd, hwnd))
+ focus_manager->ClearFocus();
+ }
+ }
+ }
+}
+
+void WebContentsViewWin::RestoreFocus() {
+ views::ViewStorage* view_storage = views::ViewStorage::GetSharedInstance();
+ views::View* last_focused_view =
+ view_storage->RetrieveView(last_focused_view_storage_id_);
+
+ if (!last_focused_view) {
+ SetInitialFocus();
+ } else {
+ views::FocusManager* focus_manager =
+ views::FocusManager::GetFocusManager(GetNativeView());
+
+ // If you hit this DCHECK, please report it to Jay (jcampan).
+ DCHECK(focus_manager != NULL) << "No focus manager when restoring focus.";
+
+ if (last_focused_view->IsFocusable() && focus_manager &&
+ focus_manager->ContainsView(last_focused_view)) {
+ last_focused_view->RequestFocus();
+ } else {
+ // The focused view may not belong to the same window hierarchy (e.g.
+ // if the location bar was focused and the tab is dragged out), or it may
+ // no longer be focusable (e.g. if the location bar was focused and then
+ // we switched to fullscreen mode). In that case we default to the
+ // default focus.
+ SetInitialFocus();
+ }
+ view_storage->RemoveView(last_focused_view_storage_id_);
+ }
+}
+
void WebContentsViewWin::UpdateDragCursor(bool is_drop_target) {
drop_target_->set_is_drop_target(is_drop_target);
}
diff --git a/chrome/browser/tab_contents/web_contents_view_win.h b/chrome/browser/tab_contents/web_contents_view_win.h
index 15fd3f5..cd26bb7 100644
--- a/chrome/browser/tab_contents/web_contents_view_win.h
+++ b/chrome/browser/tab_contents/web_contents_view_win.h
@@ -43,6 +43,9 @@ class WebContentsViewWin : public WebContentsView,
virtual void SizeContents(const gfx::Size& size);
virtual void OpenDeveloperTools();
virtual void ForwardMessageToDevToolsClient(const IPC::Message& message);
+ virtual void SetInitialFocus();
+ virtual void StoreFocus();
+ virtual void RestoreFocus();
// Backend implementation of RenderViewHostDelegate::View.
virtual WebContents* CreateNewWindowInternal(
@@ -113,6 +116,9 @@ class WebContentsViewWin : public WebContentsView,
// Whether to ignore the next CHAR keyboard event.
bool ignore_next_char_event_;
+ // The id used in the ViewStorage to store the last focused view.
+ int last_focused_view_storage_id_;
+
DISALLOW_COPY_AND_ASSIGN(WebContentsViewWin);
};
diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc
index 5836e55..e8c2a54 100644
--- a/chrome/browser/views/frame/browser_view.cc
+++ b/chrome/browser/views/frame/browser_view.cc
@@ -500,8 +500,8 @@ void BrowserView::Show() {
// If we do find there are cases where we need to restore the focus on show,
// that should be added and this should be removed.
TabContents* selected_tab_contents = GetSelectedTabContents();
- if (selected_tab_contents)
- selected_tab_contents->RestoreFocus();
+ if (selected_tab_contents && selected_tab_contents->AsWebContents())
+ selected_tab_contents->AsWebContents()->view()->RestoreFocus();
frame_->Show();
}
@@ -923,8 +923,9 @@ void BrowserView::TabSelectedAt(TabContents* old_contents,
// We do not store the focus when closing the tab to work-around bug 4633.
// Some reports seem to show that the focus manager and/or focused view can
// be garbage at that point, it is not clear why.
- if (old_contents && !old_contents->is_being_destroyed())
- old_contents->StoreFocus();
+ if (old_contents && !old_contents->is_being_destroyed() &&
+ old_contents->AsWebContents())
+ old_contents->AsWebContents()->view()->StoreFocus();
// Update various elements that are interested in knowing the current
// TabContents.
@@ -936,8 +937,9 @@ void BrowserView::TabSelectedAt(TabContents* old_contents,
// etc not result in sad tab.
new_contents->DidBecomeSelected();
if (BrowserList::GetLastActive() == browser_ &&
- !browser_->tabstrip_model()->closing_all()) {
- new_contents->RestoreFocus();
+ !browser_->tabstrip_model()->closing_all() &&
+ new_contents->AsWebContents()) {
+ new_contents->AsWebContents()->view()->RestoreFocus();
}
// Update all the UI bits.
diff --git a/chrome/views/view_storage.cc b/chrome/views/view_storage.cc
index bc5849c..42396b8 100644
--- a/chrome/views/view_storage.cc
+++ b/chrome/views/view_storage.cc
@@ -11,8 +11,6 @@
namespace views {
-ViewStorage* ViewStorage::shared_instance_ = NULL;
-
// This struct contains the information to locate a specific view.
// Locating a view is not always straight-forward as a view can be a floating
// view, or the child of a floating view. Floating views are frequently deleted
@@ -36,19 +34,7 @@ struct ViewLocationInfo {
// static
ViewStorage* ViewStorage::GetSharedInstance() {
- if (shared_instance_)
- return shared_instance_;
-
- shared_instance_ = new ViewStorage();
- return shared_instance_;
-}
-
-// static
-void ViewStorage::DeleteSharedInstance() {
- if (!shared_instance_)
- return;
- delete shared_instance_;
- shared_instance_ = NULL;
+ return Singleton<ViewStorage>::get();
}
ViewStorage::ViewStorage() : view_storage_next_id_(0) {
@@ -57,9 +43,6 @@ ViewStorage::ViewStorage() : view_storage_next_id_(0) {
}
ViewStorage::~ViewStorage() {
- NotificationService::current()->RemoveObserver(
- this, NotificationType::VIEW_REMOVED, NotificationService::AllSources());
-
STLDeleteContainerPairSecondPointers(id_to_view_location_.begin(),
id_to_view_location_.end());
diff --git a/chrome/views/view_storage.h b/chrome/views/view_storage.h
index a965158..8b17474 100644
--- a/chrome/views/view_storage.h
+++ b/chrome/views/view_storage.h
@@ -5,6 +5,7 @@
#ifndef CHROME_VIEWS_VIEW_STORAGE_H_
#define CHROME_VIEWS_VIEW_STORAGE_H_
+#include "base/singleton.h"
#include "chrome/common/notification_observer.h"
#include "chrome/views/view.h"
@@ -31,9 +32,6 @@ class ViewStorage : public NotificationObserver {
// It is guaranted to be non NULL.
static ViewStorage* GetSharedInstance();
- // Deletes the global instance of the ViewStorage.
- static void DeleteSharedInstance();
-
// Returns a unique storage id that can be used to store/retrieve views.
int CreateStorageID();
@@ -47,6 +45,8 @@ class ViewStorage : public NotificationObserver {
void RemoveView(int storage_id);
private:
+ friend struct DefaultSingletonTraits<ViewStorage>;
+
ViewStorage();
~ViewStorage();
@@ -69,9 +69,6 @@ class ViewStorage : public NotificationObserver {
// Association View to id, used to speed up view notification removal.
std::map<View*, std::vector<int>*> view_to_ids_;
- // The singleton instance.
- static ViewStorage* shared_instance_;
-
DISALLOW_COPY_AND_ASSIGN(ViewStorage);
};