diff options
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/browser.cc | 8 | ||||
-rw-r--r-- | chrome/browser/browser.h | 1 | ||||
-rw-r--r-- | chrome/browser/browser_focus_uitest.cc | 106 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_view_host.cc | 4 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_view_host.h | 1 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_view_host_delegate.h | 3 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_widget_host.cc | 4 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_widget_host.h | 2 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents.cc | 7 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents.h | 1 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents_view_gtk.cc | 6 |
11 files changed, 102 insertions, 41 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index 88cf354..a8e5469 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -1999,6 +1999,14 @@ void Browser::TabContentsFocused(TabContents* tab_content) { window_->TabContentsFocused(tab_content); } +bool Browser::TakeFocus(bool reverse) { + NotificationService::current()->Notify( + NotificationType::FOCUS_RETURNED_TO_BROWSER, + Source<Browser>(this), + NotificationService::NoDetails()); + return false; +} + bool Browser::IsApplication() const { return (type_ & TYPE_APP) != 0; } diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h index 5635c23..f5c1bd6 100644 --- a/chrome/browser/browser.h +++ b/chrome/browser/browser.h @@ -515,6 +515,7 @@ class Browser : public TabStripModelDelegate, virtual void ContentsMouseEvent(TabContents* source, bool motion); virtual void ContentsZoomChange(bool zoom_in); virtual void TabContentsFocused(TabContents* tab_content); + virtual bool TakeFocus(bool reverse); virtual bool IsApplication() const; virtual void ConvertContentsToApplication(TabContents* source); virtual bool ShouldDisplayURLField(); diff --git a/chrome/browser/browser_focus_uitest.cc b/chrome/browser/browser_focus_uitest.cc index d2cab01..89abf91 100644 --- a/chrome/browser/browser_focus_uitest.cc +++ b/chrome/browser/browser_focus_uitest.cc @@ -147,7 +147,8 @@ class TestInterstitialPage : public InterstitialPage { public: TestInterstitialPage(TabContents* tab, bool new_navigation, const GURL& url) : InterstitialPage(tab, new_navigation, url), - waiting_for_dom_response_(false) { + waiting_for_dom_response_(false), + waiting_for_focus_change_(false) { FilePath file_path; bool r = PathService::Get(chrome::DIR_TEST_DATA, &file_path); EXPECT_TRUE(r); @@ -192,10 +193,25 @@ class TestInterstitialPage : public InterstitialPage { return render_view_host()->view()->HasFocus(); } + void WaitForFocusChange() { + waiting_for_focus_change_ = true; + ui_test_utils::RunMessageLoop(); + } + + protected: + virtual void FocusedNodeChanged() { + if (!waiting_for_focus_change_) + return; + + waiting_for_focus_change_= false; + MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); + } + private: std::string html_contents_; bool waiting_for_dom_response_; + bool waiting_for_focus_change_; std::string dom_response_; }; @@ -396,6 +412,10 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, LocationBarLockFocus) { } // Focus traversal on a regular page. +// Note that this test relies on a notification from the renderer that the +// focus has changed in the page. The notification in the renderer may change +// at which point this test would fail (see comment in +// RenderWidget::didFocus()). IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) { HTTPTestServer* server = StartHTTPServer(); @@ -420,7 +440,7 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) { CheckViewHasFocus(VIEW_ID_LOCATION_BAR); // Now let's press tab to move the focus. - for (int j = 0; j < 7; ++j) { + for (size_t j = 0; j < arraysize(kExpElementIDs); ++j) { // Let's make sure the focus is on the expected element in the page. std::string actual; ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString( @@ -430,21 +450,22 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) { &actual)); ASSERT_STREQ(kExpElementIDs[j], actual.c_str()); - ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_TAB, false, - false, false, - new MessageLoop::QuitTask()); - ui_test_utils::RunMessageLoop(); - // Ideally, we wouldn't sleep here and instead would use the event - // processed ack notification from the renderer. I am reluctant to create - // a new notification/callback for that purpose just for this test. - PlatformThread::Sleep(kActionDelayMs); + ASSERT_TRUE(ui_controls::SendKeyPress(window, base::VKEY_TAB, + false, false, false)); + + if (j < arraysize(kExpElementIDs) - 1) { + ui_test_utils::WaitForFocusChange(browser()->GetSelectedTabContents()-> + render_view_host()); + } else { + // On the last tab key press, the focus returns to the browser. + ui_test_utils::WaitForFocusInBrowser(browser()); + } } // At this point the renderer has sent us a message asking to advance the // focus (as the end of the focus loop was reached in the renderer). // We need to run the message loop to process it. - MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); - ui_test_utils::RunMessageLoop(); + MessageLoop::current()->RunAllPending(); } // Now let's try reverse focus traversal. @@ -453,12 +474,17 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) { CheckViewHasFocus(VIEW_ID_LOCATION_BAR); // Now let's press shift-tab to move the focus in reverse. - for (int j = 0; j < 7; ++j) { - ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_TAB, false, - true, false, - new MessageLoop::QuitTask()); - ui_test_utils::RunMessageLoop(); - PlatformThread::Sleep(kActionDelayMs); + for (size_t j = 0; j < 7; ++j) { + ASSERT_TRUE(ui_controls::SendKeyPress(window, base::VKEY_TAB, + false, true, false)); + + if (j < arraysize(kExpElementIDs) - 1) { + ui_test_utils::WaitForFocusChange(browser()->GetSelectedTabContents()-> + render_view_host()); + } else { + // On the last tab key press, the focus returns to the browser. + ui_test_utils::WaitForFocusInBrowser(browser()); + } // Let's make sure the focus is on the expected element in the page. std::string actual; @@ -473,8 +499,7 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) { // At this point the renderer has sent us a message asking to advance the // focus (as the end of the focus loop was reached in the renderer). // We need to run the message loop to process it. - MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); - ui_test_utils::RunMessageLoop(); + MessageLoop::current()->RunAllPending(); } } @@ -517,26 +542,26 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, MAYBE_FocusTraversalOnInterstitial) { CheckViewHasFocus(VIEW_ID_LOCATION_BAR); // Now let's press tab to move the focus. - for (int j = 0; j < 7; ++j) { + for (size_t j = 0; j < 7; ++j) { // Let's make sure the focus is on the expected element in the page. std::string actual = interstitial_page->GetFocusedElement(); ASSERT_STREQ(kExpElementIDs[j], actual.c_str()); - ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_TAB, false, - false, false, - new MessageLoop::QuitTask()); - ui_test_utils::RunMessageLoop(); - // Ideally, we wouldn't sleep here and instead would use the event - // processed ack notification from the renderer. I am reluctant to create - // a new notification/callback for that purpose just for this test. - PlatformThread::Sleep(kActionDelayMs); + ASSERT_TRUE(ui_controls::SendKeyPress(window, base::VKEY_TAB, + false, false, false)); + + if (j < arraysize(kExpElementIDs) - 1) { + interstitial_page->WaitForFocusChange(); + } else { + // On the last tab key press, the focus returns to the browser. + ui_test_utils::WaitForFocusInBrowser(browser()); + } } // At this point the renderer has sent us a message asking to advance the // focus (as the end of the focus loop was reached in the renderer). // We need to run the message loop to process it. - MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); - ui_test_utils::RunMessageLoop(); + MessageLoop::current()->RunAllPending(); } // Now let's try reverse focus traversal. @@ -545,12 +570,16 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, MAYBE_FocusTraversalOnInterstitial) { CheckViewHasFocus(VIEW_ID_LOCATION_BAR); // Now let's press shift-tab to move the focus in reverse. - for (int j = 0; j < 7; ++j) { - ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_TAB, false, - true, false, - new MessageLoop::QuitTask()); - ui_test_utils::RunMessageLoop(); - PlatformThread::Sleep(kActionDelayMs); + for (size_t j = 0; j < 7; ++j) { + ASSERT_TRUE(ui_controls::SendKeyPress(window, base::VKEY_TAB, + false, true, false)); + + if (j < arraysize(kExpElementIDs) - 1) { + interstitial_page->WaitForFocusChange(); + } else { + // On the last tab key press, the focus returns to the browser. + ui_test_utils::WaitForFocusInBrowser(browser()); + } // Let's make sure the focus is on the expected element in the page. std::string actual = interstitial_page->GetFocusedElement(); @@ -560,8 +589,7 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, MAYBE_FocusTraversalOnInterstitial) { // At this point the renderer has sent us a message asking to advance the // focus (as the end of the focus loop was reached in the renderer). // We need to run the message loop to process it. - MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); - ui_test_utils::RunMessageLoop(); + MessageLoop::current()->RunAllPending(); } } diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index 932bf89..63cc15e 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -1572,6 +1572,10 @@ void RenderViewHost::NotifyRendererResponsive() { delegate_->RendererResponsive(this); } +void RenderViewHost::OnMsgFocusedNodeChanged() { + delegate_->FocusedNodeChanged(); +} + gfx::Rect RenderViewHost::GetRootWindowResizerRect() const { return delegate_->GetRootWindowResizerRect(); } diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index 52a0c10..b7f2d86 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -452,6 +452,7 @@ class RenderViewHost : public RenderWidgetHost, virtual void OnUserGesture(); virtual void NotifyRendererUnresponsive(); virtual void NotifyRendererResponsive(); + virtual void OnMsgFocusedNodeChanged(); // IPC message handlers. void OnMsgShowView(int route_id, diff --git a/chrome/browser/renderer_host/render_view_host_delegate.h b/chrome/browser/renderer_host/render_view_host_delegate.h index c1e301c..74dc44e 100644 --- a/chrome/browser/renderer_host/render_view_host_delegate.h +++ b/chrome/browser/renderer_host/render_view_host_delegate.h @@ -544,6 +544,9 @@ class RenderViewHostDelegate { // The RenderView has inserted one css file into page. virtual void DidInsertCSS() {} + + // A different node in the page got focused. + virtual void FocusedNodeChanged() {} }; #endif // CHROME_BROWSER_RENDERER_HOST_RENDER_VIEW_HOST_DELEGATE_H_ diff --git a/chrome/browser/renderer_host/render_widget_host.cc b/chrome/browser/renderer_host/render_widget_host.cc index 05b90c98..2bdf11c 100644 --- a/chrome/browser/renderer_host/render_widget_host.cc +++ b/chrome/browser/renderer_host/render_widget_host.cc @@ -132,6 +132,7 @@ void RenderWidgetHost::OnMessageReceived(const IPC::Message &msg) { IPC_MESSAGE_HANDLER(ViewHostMsg_HandleInputEvent_ACK, OnMsgInputEventAck) IPC_MESSAGE_HANDLER(ViewHostMsg_Focus, OnMsgFocus) IPC_MESSAGE_HANDLER(ViewHostMsg_Blur, OnMsgBlur) + IPC_MESSAGE_HANDLER(ViewHostMsg_FocusedNodeChanged, OnMsgFocusedNodeChanged) IPC_MESSAGE_HANDLER(ViewHostMsg_SetCursor, OnMsgSetCursor) IPC_MESSAGE_HANDLER(ViewHostMsg_ImeUpdateStatus, OnMsgImeUpdateStatus) #if defined(OS_LINUX) @@ -778,6 +779,9 @@ void RenderWidgetHost::OnMsgBlur() { } } +void RenderWidgetHost::OnMsgFocusedNodeChanged() { +} + void RenderWidgetHost::OnMsgSetCursor(const WebCursor& cursor) { if (!view_) { return; diff --git a/chrome/browser/renderer_host/render_widget_host.h b/chrome/browser/renderer_host/render_widget_host.h index b76d4c7..a80d1fd 100644 --- a/chrome/browser/renderer_host/render_widget_host.h +++ b/chrome/browser/renderer_host/render_widget_host.h @@ -406,6 +406,8 @@ class RenderWidgetHost : public IPC::Channel::Listener, void OnMsgInputEventAck(const IPC::Message& message); void OnMsgFocus(); void OnMsgBlur(); + virtual void OnMsgFocusedNodeChanged(); + void OnMsgSetCursor(const WebCursor& cursor); // Using int instead of ViewHostMsg_ImeControl for control's type to avoid // having to bring in render_messages.h in a header file. diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index c7c1c37..1568790 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -2410,6 +2410,13 @@ void TabContents::DidInsertCSS() { // This RVHDelegate function is used for extensions and not us. } +void TabContents::FocusedNodeChanged() { + NotificationService::current()->Notify( + NotificationType::FOCUS_CHANGED_IN_PAGE, + Source<RenderViewHost>(render_view_host()), + NotificationService::NoDetails()); +} + void TabContents::FileSelected(const FilePath& path, int index, void* params) { render_view_host()->FileSelected(path); diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h index 61404f3..cd8ec58 100644 --- a/chrome/browser/tab_contents/tab_contents.h +++ b/chrome/browser/tab_contents/tab_contents.h @@ -897,6 +897,7 @@ class TabContents : public PageNavigator, virtual void LoadStateChanged(const GURL& url, net::LoadState load_state); virtual bool IsExternalTabContainer() const; virtual void DidInsertCSS(); + virtual void FocusedNodeChanged(); // SelectFileDialog::Listener ------------------------------------------------ diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.cc b/chrome/browser/tab_contents/tab_contents_view_gtk.cc index 6326ae1..32ac7cf 100644 --- a/chrome/browser/tab_contents/tab_contents_view_gtk.cc +++ b/chrome/browser/tab_contents/tab_contents_view_gtk.cc @@ -549,8 +549,10 @@ void TabContentsViewGtk::GotFocus() { // This is called when we the renderer asks us to take focus back (i.e., it has // iterated past the last focusable element on the page). void TabContentsViewGtk::TakeFocus(bool reverse) { - gtk_widget_child_focus(GTK_WIDGET(GetTopLevelNativeWindow()), - reverse ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD); + if (!tab_contents()->delegate()->TakeFocus(reverse)) { + gtk_widget_child_focus(GTK_WIDGET(GetTopLevelNativeWindow()), + reverse ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD); + } } void TabContentsViewGtk::HandleKeyboardEvent( |