Commit 9b142396 authored by erikchen's avatar erikchen Committed by Commit bot

Mac: Clicking an omnibox decoration should not highlight the omnibox.

Prior to this CL, the AutocompleteTextField becomes first responder if the user
left-clicks a decoration. This is a bug that this CL fixes. This also fixes a
bug where ZeroSuggest did not disappear when the user drags the origin chip.

BUG=356887

Review URL: https://codereview.chromium.org/1011943002

Cr-Commit-Position: refs/heads/master@{#329781}
parent a04c0468
...@@ -392,6 +392,17 @@ const CGFloat kAnimationDuration = 0.2; ...@@ -392,6 +392,17 @@ const CGFloat kAnimationDuration = 0.2;
DCHECK_EQ([self currentEditor], [[self window] firstResponder]); DCHECK_EQ([self currentEditor], [[self window] firstResponder]);
return NO; return NO;
} }
// If the event is a left-mouse click, and it lands on a decoration, then the
// event should not cause the text field to become first responder.
NSEvent* event = [NSApp currentEvent];
if ([event type] == NSLeftMouseDown) {
LocationBarDecoration* decoration =
[[self cell] decorationForEvent:event inRect:[self bounds] ofView:self];
if (decoration && decoration->AcceptsMousePress())
return NO;
}
return [super acceptsFirstResponder]; return [super acceptsFirstResponder];
} }
......
...@@ -39,22 +39,6 @@ class MockDecoration : public LocationBarDecoration { ...@@ -39,22 +39,6 @@ class MockDecoration : public LocationBarDecoration {
MOCK_METHOD0(GetMenu, NSMenu*()); MOCK_METHOD0(GetMenu, NSMenu*());
}; };
class MockButtonDecoration : public ButtonDecoration {
public:
// Note: It does not matter which images are used here - but ButtonDecoration
// needs _some_ images to work properly.
MockButtonDecoration()
: ButtonDecoration(IMAGE_GRID(IDR_OMNIBOX_EV_BUBBLE),
IDR_OMNIBOX_EV_BUBBLE_CENTER,
IMAGE_GRID(IDR_OMNIBOX_EV_BUBBLE),
IDR_OMNIBOX_EV_BUBBLE_CENTER,
IMAGE_GRID(IDR_OMNIBOX_EV_BUBBLE),
IDR_OMNIBOX_EV_BUBBLE_CENTER,
3) {}
void Hide() { SetVisible(false); }
MOCK_METHOD2(OnMousePressed, bool(NSRect frame, NSPoint location));
};
// Mock up an incrementing event number. // Mock up an incrementing event number.
NSUInteger eventNumber = 0; NSUInteger eventNumber = 0;
...@@ -170,6 +154,31 @@ class AutocompleteTextFieldObserverTest : public AutocompleteTextFieldTest { ...@@ -170,6 +154,31 @@ class AutocompleteTextFieldObserverTest : public AutocompleteTextFieldTest {
AutocompleteTextFieldTest::TearDown(); AutocompleteTextFieldTest::TearDown();
} }
// Returns the center point of the decoration.
NSPoint ClickLocationForDecoration(LocationBarDecoration* decoration) {
AutocompleteTextFieldCell* cell = [field_ cell];
NSRect decoration_rect =
[cell frameForDecoration:decoration inFrame:[field_ bounds]];
EXPECT_FALSE(NSIsEmptyRect(decoration_rect));
return NSMakePoint(NSMidX(decoration_rect), NSMidY(decoration_rect));
}
void SendMouseClickToDecoration(LocationBarDecoration* decoration) {
NSPoint point = ClickLocationForDecoration(decoration);
NSEvent* downEvent = Event(field_, point, NSLeftMouseDown);
NSEvent* upEvent = Event(field_, point, NSLeftMouseUp);
// Can't just use -sendEvent:, since that doesn't populate -currentEvent.
[NSApp postEvent:downEvent atStart:YES];
[NSApp postEvent:upEvent atStart:NO];
NSEvent* next_event = [NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:nil
inMode:NSDefaultRunLoopMode
dequeue:YES];
[NSApp sendEvent:next_event];
}
StrictMock<MockAutocompleteTextFieldObserver> field_observer_; StrictMock<MockAutocompleteTextFieldObserver> field_observer_;
}; };
...@@ -789,61 +798,56 @@ TEST_F(AutocompleteTextFieldTest, HideFocusState) { ...@@ -789,61 +798,56 @@ TEST_F(AutocompleteTextFieldTest, HideFocusState) {
EXPECT_TRUE([FieldEditor() shouldDrawInsertionPoint]); EXPECT_TRUE([FieldEditor() shouldDrawInsertionPoint]);
} }
// Verify that OnSetFocus for button decorations is only sent after the // Verify that clicking a decoration that accepts mouse clicks does not focus
// decoration is picked as the target for the subsequent -mouseDown:. Otherwise // the Omnibox.
// hiding a ButtonDecoration in OnSetFocus will prevent a call to TEST_F(AutocompleteTextFieldObserverTest,
// OnMousePressed, since it is already hidden at the time of mouseDown. ClickingDecorationDoesNotFocusOmnibox) {
TEST_F(AutocompleteTextFieldObserverTest, ButtonDecorationFocus) {
// Add the mock button.
MockButtonDecoration mock_button;
mock_button.SetVisible(true);
AutocompleteTextFieldCell* cell = [field_ cell]; AutocompleteTextFieldCell* cell = [field_ cell];
[cell addLeftDecoration:&mock_button];
// Ensure button is hidden when OnSetFocus() is called. // Set up a non-interactive decoration.
EXPECT_CALL(field_observer_, OnSetFocus(false)).WillOnce( MockDecoration noninteractive_decoration;
testing::InvokeWithoutArgs(&mock_button, &MockButtonDecoration::Hide)); noninteractive_decoration.SetVisible(true);
EXPECT_CALL(noninteractive_decoration, AcceptsMousePress())
// Ignore incidental calls. .WillRepeatedly(testing::Return(false));
[cell addLeftDecoration:&noninteractive_decoration];
// Set up an interactive decoration.
MockDecoration interactive_decoration;
EXPECT_CALL(interactive_decoration, AcceptsMousePress())
.WillRepeatedly(testing::Return(true));
interactive_decoration.SetVisible(true);
[cell addLeftDecoration:&interactive_decoration];
EXPECT_CALL(interactive_decoration, OnMousePressed(_, _))
.WillRepeatedly(testing::Return(true));
// Ignore incidental calls. The exact frequency of these calls doesn't matter
// as they are auxiliary.
EXPECT_CALL(field_observer_, SelectionRangeForProposedRange(_)) EXPECT_CALL(field_observer_, SelectionRangeForProposedRange(_))
.WillRepeatedly(testing::Return(NSMakeRange(0, 0))); .WillRepeatedly(testing::Return(NSMakeRange(0, 0)));
EXPECT_CALL(field_observer_, OnMouseDown(_)); EXPECT_CALL(field_observer_, OnMouseDown(_)).Times(testing::AnyNumber());
EXPECT_CALL(field_observer_, OnSetFocus(false)).Times(testing::AnyNumber());
// Still expect an OnMousePressed on the button. EXPECT_CALL(field_observer_, OnKillFocus()).Times(testing::AnyNumber());
EXPECT_CALL(mock_button, OnMousePressed(_, _)) EXPECT_CALL(field_observer_, OnDidEndEditing()).Times(testing::AnyNumber());
.WillOnce(testing::Return(true));
// Get click point for button decoration.
NSRect button_rect =
[cell frameForDecoration:&mock_button inFrame:[field_ bounds]];
EXPECT_FALSE(NSIsEmptyRect(button_rect));
NSPoint click_location =
NSMakePoint(NSMidX(button_rect), NSMidY(button_rect));
// Ensure the field is currently not first responder. // Ensure the field is currently not first responder.
[test_window() makePretendKeyWindowAndSetFirstResponder:nil]; [test_window() makePretendKeyWindowAndSetFirstResponder:nil];
EXPECT_NSNE([[field_ window] firstResponder], field_); NSResponder* firstResponder = [[field_ window] firstResponder];
EXPECT_FALSE(
// Execute button click event sequence. [base::mac::ObjCCast<NSView>(firstResponder) isDescendantOf:field_]);
NSEvent* downEvent = Event(field_, click_location, NSLeftMouseDown);
NSEvent* upEvent = Event(field_, click_location, NSLeftMouseUp); // Clicking an interactive decoration doesn't change the first responder.
SendMouseClickToDecoration(&interactive_decoration);
// Can't just use -sendEvent:, since that doesn't populate -currentEvent. EXPECT_NSEQ(firstResponder, [[field_ window] firstResponder]);
[NSApp postEvent:downEvent atStart:YES];
[NSApp postEvent:upEvent atStart:NO]; // Clicking a non-interactive decoration focuses the Omnibox.
NSEvent* next_event = [NSApp nextEventMatchingMask:NSAnyEventMask SendMouseClickToDecoration(&noninteractive_decoration);
untilDate:nil firstResponder = [[field_ window] firstResponder];
inMode:NSDefaultRunLoopMode EXPECT_TRUE(
dequeue:YES]; [base::mac::ObjCCast<NSView>(firstResponder) isDescendantOf:field_]);
[NSApp sendEvent:next_event];
// Clicking an interactive decoration doesn't change the first responder.
// Expectations check that both OnSetFocus and OnMouseDown were called. SendMouseClickToDecoration(&interactive_decoration);
// Additionally, ensure button is hidden and field is firstResponder. EXPECT_NSEQ(firstResponder, [[field_ window] firstResponder]);
EXPECT_FALSE(mock_button.IsVisible());
EXPECT_TRUE(NSIsEmptyRect([cell frameForDecoration:&mock_left_decoration_
inFrame:[field_ bounds]]));
EXPECT_TRUE([base::mac::ObjCCastStrict<NSView>(
[[field_ window] firstResponder]) isDescendantOf:field_]);
} }
TEST_F(AutocompleteTextFieldObserverTest, SendsEditingMessages) { TEST_F(AutocompleteTextFieldObserverTest, SendsEditingMessages) {
......
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