Commit 63a13975 authored by Tommy Li's avatar Tommy Li Committed by Commit Bot

[omnibox] For about:blank homepage, select-all the initial focus

Currently, when the user has chosen about:blank as their homepage, and
Chromium starts up, the location bar is focused, but the URL
"about:blank" is NOT selected.

This leads to the cursor being at index 0, and the user starts typing
BEFORE the existing "about:blank" URL, so typing "foo" leads to:
"fooabout:blank".

This is surprising behavior, and this CL fixes that, as well as adds a
test.

We originally tried to fix this in 2019, but this effort had to be
reverted because we caused a bug on the NTP:
https://chromium-review.googlesource.com/c/chromium/src/+/1559115

This CL preserves the fixed NTP behavior (validated by a test), and
also fixes the about:blank behavior, also validated by a new test.

Bug: 45260
Change-Id: I8ca57ea10215c297aabc22e51138af7ea21ef677
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2464202Reviewed-by: default avatarPeter Kasting <pkasting@chromium.org>
Commit-Queue: Peter Kasting <pkasting@chromium.org>
Cr-Commit-Position: refs/heads/master@{#816272}
parent ab1c69b1
...@@ -1318,11 +1318,9 @@ void Browser::SetFocusToLocationBar() { ...@@ -1318,11 +1318,9 @@ void Browser::SetFocusToLocationBar() {
// Two differences between this and FocusLocationBar(): // Two differences between this and FocusLocationBar():
// (1) This doesn't get recorded in user metrics, since it's called // (1) This doesn't get recorded in user metrics, since it's called
// internally. // internally.
// (2) This is called with |select_all| == false, because this is a renderer // (2) This is called with |is_user_initiated| == false, because this is a
// initiated focus (this method is a WebContentsDelegate override). // renderer initiated focus (this method is a WebContentsDelegate
// We don't select-all for renderer initiated focuses, as the user may // override).
// currently be typing something while the tab finishes loading. We don't
// want to clobber user input by selecting all while the user is typing.
window_->SetFocusToLocationBar(false); window_->SetFocusToLocationBar(false);
} }
......
...@@ -48,8 +48,6 @@ class LocationBar { ...@@ -48,8 +48,6 @@ class LocationBar {
// Renderer-initiated focuses (like browser startup or NTP finished loading), // Renderer-initiated focuses (like browser startup or NTP finished loading),
// should have |is_user_initiated| set to false, so we can avoid disrupting // should have |is_user_initiated| set to false, so we can avoid disrupting
// user actions and avoid requesting on-focus suggestions. // user actions and avoid requesting on-focus suggestions.
//
// TODO(tommycli): See if there's a more descriptive name for this method.
virtual void FocusLocation(bool is_user_initiated) = 0; virtual void FocusLocation(bool is_user_initiated) = 0;
// Puts the user into keyword mode with their default search provider. // Puts the user into keyword mode with their default search provider.
......
...@@ -737,6 +737,22 @@ IN_PROC_BROWSER_TEST_F(OmniboxViewTest, ...@@ -737,6 +737,22 @@ IN_PROC_BROWSER_TEST_F(OmniboxViewTest,
EXPECT_EQ(old_selected_line, popup_model->selected_line()); EXPECT_EQ(old_selected_line, popup_model->selected_line());
} }
// Verifies that https://crbug.com/45260 doesn't regress.
IN_PROC_BROWSER_TEST_F(OmniboxViewTest,
RendererInitiatedFocusSelectsAllWhenStartingBlurred) {
ASSERT_NO_FATAL_FAILURE(NavigateExpectUrl(GURL("about:blank")));
OmniboxView* omnibox_view = nullptr;
ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view));
ASSERT_FALSE(omnibox_view->IsSelectAll());
// Simulate a renderer-initated focus event. Expect that everything is
// selected now.
browser()->SetFocusToLocationBar();
EXPECT_TRUE(omnibox_view->IsSelectAll());
}
// Verifies that https://crbug.com/924935 doesn't regress.
IN_PROC_BROWSER_TEST_F(OmniboxViewTest, IN_PROC_BROWSER_TEST_F(OmniboxViewTest,
RendererInitiatedFocusPreservesUserText) { RendererInitiatedFocusPreservesUserText) {
OmniboxView* omnibox_view = nullptr; OmniboxView* omnibox_view = nullptr;
......
...@@ -1412,7 +1412,7 @@ LocationBar* BrowserView::GetLocationBar() const { ...@@ -1412,7 +1412,7 @@ LocationBar* BrowserView::GetLocationBar() const {
return GetLocationBarView(); return GetLocationBarView();
} }
void BrowserView::SetFocusToLocationBar(bool select_all) { void BrowserView::SetFocusToLocationBar(bool is_user_initiated) {
// On Windows, changing focus to the location bar causes the browser window to // On Windows, changing focus to the location bar causes the browser window to
// become active. This can steal focus if the user has another window open // become active. This can steal focus if the user has another window open
// already. On Chrome OS, changing focus makes a view believe it has a focus // already. On Chrome OS, changing focus makes a view believe it has a focus
...@@ -1424,7 +1424,7 @@ void BrowserView::SetFocusToLocationBar(bool select_all) { ...@@ -1424,7 +1424,7 @@ void BrowserView::SetFocusToLocationBar(bool select_all) {
#endif #endif
LocationBarView* location_bar = GetLocationBarView(); LocationBarView* location_bar = GetLocationBarView();
location_bar->FocusLocation(select_all); location_bar->FocusLocation(is_user_initiated);
if (!location_bar->omnibox_view()->HasFocus()) { if (!location_bar->omnibox_view()->HasFocus()) {
// If none of location bar got focus, then clear focus. // If none of location bar got focus, then clear focus.
views::FocusManager* focus_manager = GetFocusManager(); views::FocusManager* focus_manager = GetFocusManager();
......
...@@ -388,7 +388,7 @@ class BrowserView : public BrowserWindow, ...@@ -388,7 +388,7 @@ class BrowserView : public BrowserWindow,
autofill::AutofillBubbleHandler* GetAutofillBubbleHandler() override; autofill::AutofillBubbleHandler* GetAutofillBubbleHandler() override;
void ExecutePageActionIconForTesting(PageActionIconType type) override; void ExecutePageActionIconForTesting(PageActionIconType type) override;
LocationBar* GetLocationBar() const override; LocationBar* GetLocationBar() const override;
void SetFocusToLocationBar(bool select_all) override; void SetFocusToLocationBar(bool is_user_initiated) override;
void UpdateReloadStopState(bool is_loading, bool force) override; void UpdateReloadStopState(bool is_loading, bool force) override;
void UpdateToolbar(content::WebContents* contents) override; void UpdateToolbar(content::WebContents* contents) override;
void UpdateCustomTabBarVisibility(bool visible, bool animate) override; void UpdateCustomTabBarVisibility(bool visible, bool animate) override;
......
...@@ -385,7 +385,20 @@ void LocationBarView::FocusLocation(bool is_user_initiated) { ...@@ -385,7 +385,20 @@ void LocationBarView::FocusLocation(bool is_user_initiated) {
if (omnibox_already_focused) if (omnibox_already_focused)
omnibox_view()->model()->ClearKeyword(); omnibox_view()->model()->ClearKeyword();
if (is_user_initiated) // If the user initiated the focus, then we always select-all, even if the
// omnibox is already focused. This can happen if the user pressed Ctrl+L
// while already typing in the omnibox.
//
// For renderer initiated focuses (like NTP or about:blank page load finish):
// - If the omnibox was not already focused, select-all. This handles the
// about:blank homepage case, where the location bar has initial focus.
// It annoys users if the URL is not pre-selected. https://crbug.com/45260.
// - If the omnibox is already focused, DO NOT select-all. This can happen
// if the user starts typing before the NTP finishes loading. If the NTP
// finishes loading and then does a renderer-initiated focus, performing
// a select-all here would surprisingly overwrite the user's first few
// typed characters. https://crbug.com/924935.
if (is_user_initiated || !omnibox_already_focused)
omnibox_view_->SelectAll(true); omnibox_view_->SelectAll(true);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment