Skip to content

Commit

Permalink
MacViews: Select word under cursor on right click.
Browse files Browse the repository at this point in the history
This CL modifies SelectionController::OnMousePressed to ensure right clicking
outside the current selection, selects the word under the cursor on Mac. A new
constant PlatformStyle::kSelectWordOnRightClick is introduced to facilitate
this.

BUG=657556
TEST= On Mac, enable chrome://flags/#secondary-ui-md. Open Bookmark Bubble.
Enter some text in the name textfield. Ensure the word under the cursor is
selected on a right click outside the current selection.

Review-Url: https://codereview.chromium.org/2580293003
Cr-Commit-Position: refs/heads/master@{#440373}
  • Loading branch information
karandeepb authored and Commit bot committed Dec 22, 2016
1 parent 34ff2f4 commit e9f75ea
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 18 deletions.
54 changes: 40 additions & 14 deletions ui/views/controls/textfield/textfield_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -654,31 +654,36 @@ class TextfieldTest : public ViewsTestBase, public TextfieldController {
EXPECT_TRUE(menu->IsEnabledAt(7 /* SELECT ALL */));
}

void PressLeftMouseButton(int extra_flags) {
ui::MouseEvent click(ui::ET_MOUSE_PRESSED, mouse_position_, mouse_position_,
ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
ui::EF_LEFT_MOUSE_BUTTON | extra_flags);
textfield_->OnMousePressed(click);
}

void PressLeftMouseButton() {
PressLeftMouseButton(0);
void PressMouseButton(ui::EventFlags mouse_button_flags, int extra_flags) {
ui::MouseEvent press(ui::ET_MOUSE_PRESSED, mouse_position_, mouse_position_,
ui::EventTimeForNow(), mouse_button_flags,
mouse_button_flags | extra_flags);
textfield_->OnMousePressed(press);
}

void ReleaseLeftMouseButton() {
void ReleaseMouseButton(ui::EventFlags mouse_button_flags) {
ui::MouseEvent release(ui::ET_MOUSE_RELEASED, mouse_position_,
mouse_position_, ui::EventTimeForNow(),
ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
mouse_button_flags, mouse_button_flags);
textfield_->OnMouseReleased(release);
}

void ClickLeftMouseButton(int extra_flags) {
void PressLeftMouseButton(int extra_flags = 0) {
PressMouseButton(ui::EF_LEFT_MOUSE_BUTTON, extra_flags);
}

void ReleaseLeftMouseButton() {
ReleaseMouseButton(ui::EF_LEFT_MOUSE_BUTTON);
}

void ClickLeftMouseButton(int extra_flags = 0) {
PressLeftMouseButton(extra_flags);
ReleaseLeftMouseButton();
}

void ClickLeftMouseButton() {
ClickLeftMouseButton(0);
void ClickRightMouseButton() {
PressMouseButton(ui::EF_RIGHT_MOUSE_BUTTON, 0);
ReleaseMouseButton(ui::EF_RIGHT_MOUSE_BUTTON);
}

void DragMouseTo(const gfx::Point& where) {
Expand Down Expand Up @@ -1453,6 +1458,27 @@ TEST_F(TextfieldTest, DoubleAndTripleClickTest) {
EXPECT_STR_EQ("hello", textfield_->GetSelectedText());
}

// Tests text selection behavior on a right click.
TEST_F(TextfieldTest, SelectWordOnRightClick) {
InitTextfield();
textfield_->SetText(ASCIIToUTF16("hello world"));

// Verify right clicking within the selection does not alter the selection.
textfield_->SelectRange(gfx::Range(1, 5));
EXPECT_STR_EQ("ello", textfield_->GetSelectedText());
MoveMouseTo(gfx::Point(GetCursorPositionX(3), 0));
ClickRightMouseButton();
EXPECT_STR_EQ("ello", textfield_->GetSelectedText());

// Verify right clicking outside the selection, selects the word under the
// cursor on platforms where this is expected.
MoveMouseTo(gfx::Point(GetCursorPositionX(8), 0));
const char* expected_right_click =
PlatformStyle::kSelectWordOnRightClick ? "world" : "ello";
ClickRightMouseButton();
EXPECT_STR_EQ(expected_right_click, textfield_->GetSelectedText());
}

TEST_F(TextfieldTest, DragToSelect) {
InitTextfield();
textfield_->SetText(ASCIIToUTF16("hello world"));
Expand Down
23 changes: 19 additions & 4 deletions ui/views/selection_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,7 @@ bool SelectionController::OnMousePressed(const ui::MouseEvent& event,
break;
case 1:
// Select the word at the click location on a double click.
delegate_->OnBeforePointerAction();
render_text->MoveCursorTo(event.location(), false);
render_text->SelectWord();
delegate_->OnAfterPointerAction(false, true);
SelectWord(event.location());
double_click_word_ = render_text->selection();
break;
case 2:
Expand All @@ -73,6 +70,15 @@ bool SelectionController::OnMousePressed(const ui::MouseEvent& event,
}
}

// TODO(crbug.com/676296): Right clicking an unfocused text view should select
// all its text on Mac.
const bool select_word_on_right_click =
event.IsOnlyRightMouseButton() &&
PlatformStyle::kSelectWordOnRightClick &&
!render_text->IsPointInSelection(event.location());
if (select_word_on_right_click)
SelectWord(event.location());

if (handles_selection_clipboard_ && event.IsOnlyMiddleMouseButton()) {
if (render_text->IsPointInSelection(event.location())) {
delegate_->OnBeforePointerAction();
Expand Down Expand Up @@ -171,6 +177,15 @@ void SelectionController::TrackMouseClicks(const ui::MouseEvent& event) {
}
}

void SelectionController::SelectWord(const gfx::Point& point) {
gfx::RenderText* render_text = GetRenderText();
DCHECK(render_text);
delegate_->OnBeforePointerAction();
render_text->MoveCursorTo(point, false);
render_text->SelectWord();
delegate_->OnAfterPointerAction(false, true);
}

gfx::RenderText* SelectionController::GetRenderText() {
return delegate_->GetRenderTextForSelectionController();
}
Expand Down
3 changes: 3 additions & 0 deletions ui/views/selection_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ class VIEWS_EXPORT SelectionController {
// Tracks the mouse clicks for single/double/triple clicks.
void TrackMouseClicks(const ui::MouseEvent& event);

// Selects the word at the given |point|.
void SelectWord(const gfx::Point& point);

// Returns the associated render text instance via the |delegate_|.
gfx::RenderText* GetRenderText();

Expand Down
1 change: 1 addition & 0 deletions ui/views/style/platform_style.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const int PlatformStyle::kMinLabelButtonHeight = 33;
const bool PlatformStyle::kDefaultLabelButtonHasBoldFont = true;
const bool PlatformStyle::kDialogDefaultButtonCanBeCancel = true;
const bool PlatformStyle::kTextDragVerticallyDragsToEnd = false;
const bool PlatformStyle::kSelectWordOnRightClick = false;
const CustomButton::NotifyAction PlatformStyle::kMenuNotifyActivationAction =
CustomButton::NOTIFY_ON_RELEASE;
const bool PlatformStyle::kTreeViewHasFocusRing = false;
Expand Down
3 changes: 3 additions & 0 deletions ui/views/style/platform_style.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ class VIEWS_EXPORT PlatformStyle {
// the left or right end of the text from the cursor, respectively.
static const bool kTextDragVerticallyDragsToEnd;

// Whether right clicking on text, selects the word under cursor.
static const bool kSelectWordOnRightClick;

// The menu button's action to show the menu.
static const CustomButton::NotifyAction kMenuNotifyActivationAction;

Expand Down
1 change: 1 addition & 0 deletions ui/views/style/platform_style_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
const bool PlatformStyle::kDefaultLabelButtonHasBoldFont = false;
const bool PlatformStyle::kDialogDefaultButtonCanBeCancel = false;
const bool PlatformStyle::kTextDragVerticallyDragsToEnd = true;
const bool PlatformStyle::kSelectWordOnRightClick = true;
const bool PlatformStyle::kTreeViewHasFocusRing = true;
const bool PlatformStyle::kTreeViewSelectionPaintsEntireRow = true;
const bool PlatformStyle::kUseRipples = false;
Expand Down

0 comments on commit e9f75ea

Please sign in to comment.