summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorshess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-17 04:07:50 +0000
committershess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-17 04:07:50 +0000
commitda80205aeedefe6a562113bf86b13c5714dcdc82 (patch)
tree19b8a32cc1dca9ac4a235c373118a3945b0bd1ac
parentaaf124502e4c86acf98b88998fca3afcdb88a234 (diff)
downloadchromium_src-da80205aeedefe6a562113bf86b13c5714dcdc82.zip
chromium_src-da80205aeedefe6a562113bf86b13c5714dcdc82.tar.gz
chromium_src-da80205aeedefe6a562113bf86b13c5714dcdc82.tar.bz2
[Mac] Allow omnibox decorations to decline mouse events.
Certain decorations like the keyword-search bubble let mouse events fall through to the field, as indicated by an i-beam cursor. This change causes decorations next to the text area to be aggregated into the text-area's cursor rect. BUG=41612 TEST=Keyword-search bubble shows I-beam cursor. TEST=Location icon and star and page actions show arrow. Review URL: http://codereview.chromium.org/2825048 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@52807 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/cocoa/location_bar/autocomplete_text_field.mm13
-rw-r--r--chrome/browser/cocoa/location_bar/autocomplete_text_field_cell.h5
-rw-r--r--chrome/browser/cocoa/location_bar/autocomplete_text_field_cell.mm47
-rw-r--r--chrome/browser/cocoa/location_bar/autocomplete_text_field_cell_unittest.mm3
-rw-r--r--chrome/browser/cocoa/location_bar/autocomplete_text_field_unittest.mm1
-rw-r--r--chrome/browser/cocoa/location_bar/content_setting_decoration.h1
-rw-r--r--chrome/browser/cocoa/location_bar/ev_bubble_decoration.h1
-rw-r--r--chrome/browser/cocoa/location_bar/location_bar_decoration.h7
-rw-r--r--chrome/browser/cocoa/location_bar/location_icon_decoration.h1
-rw-r--r--chrome/browser/cocoa/location_bar/page_action_decoration.h1
-rw-r--r--chrome/browser/cocoa/location_bar/star_decoration.h1
11 files changed, 65 insertions, 16 deletions
diff --git a/chrome/browser/cocoa/location_bar/autocomplete_text_field.mm b/chrome/browser/cocoa/location_bar/autocomplete_text_field.mm
index 041cff8..6464510 100644
--- a/chrome/browser/cocoa/location_bar/autocomplete_text_field.mm
+++ b/chrome/browser/cocoa/location_bar/autocomplete_text_field.mm
@@ -204,19 +204,6 @@
[undoManager_ removeAllActions];
}
-// Show the I-beam cursor unless the mouse is over an image within the field
-// (Page Actions or the security icon) in which case show the arrow cursor.
-// TODO(rohitrao): Should default to the arrow cursor. http://crbug.com/41612
-- (void)resetCursorRects {
- NSRect fieldBounds = [self bounds];
- [self addCursorRect:fieldBounds cursor:[NSCursor IBeamCursor]];
-
- // TODO(shess): This needs to traverse the LocationBarDecorations
- // and put up a cursor for them, too. Except for the keyword-search
- // stuff? Sigh.
- // http://crbug.com/48867
-}
-
// TODO(shess): -resetFieldEditorFrameIfNeeded is the place where
// changes to the cell layout should be flushed. LocationBarViewMac
// and ToolbarController are calling this routine directly, and I
diff --git a/chrome/browser/cocoa/location_bar/autocomplete_text_field_cell.h b/chrome/browser/cocoa/location_bar/autocomplete_text_field_cell.h
index cbb3e63..d1150e2 100644
--- a/chrome/browser/cocoa/location_bar/autocomplete_text_field_cell.h
+++ b/chrome/browser/cocoa/location_bar/autocomplete_text_field_cell.h
@@ -82,6 +82,11 @@ class LocationBarDecoration;
inRect:(NSRect)cellFrame
ofView:(AutocompleteTextField*)controlView;
+// Overridden from StyledTextFieldCell to include decorations adjacent
+// to the text area which don't handle mouse clicks themselves.
+// Keyword-search bubble, for instance.
+- (NSRect)textCursorFrameForFrame:(NSRect)cellFrame;
+
@end
// Internal methods here exposed for unit testing.
diff --git a/chrome/browser/cocoa/location_bar/autocomplete_text_field_cell.mm b/chrome/browser/cocoa/location_bar/autocomplete_text_field_cell.mm
index 3d62be6..4e46456 100644
--- a/chrome/browser/cocoa/location_bar/autocomplete_text_field_cell.mm
+++ b/chrome/browser/cocoa/location_bar/autocomplete_text_field_cell.mm
@@ -167,7 +167,9 @@ void CalculatePositionsHelper(
// |decorations| will contain the resulting visible decorations, and
// |decoration_frames| will contain their frames in the same
// coordinates as |frame|. Decorations will be ordered left to right.
-void CalculatePositionsInFrame(
+// As a convenience returns the index of the first right-hand
+// decoration.
+size_t CalculatePositionsInFrame(
NSRect frame,
const std::vector<LocationBarDecoration*>& left_decorations,
const std::vector<LocationBarDecoration*>& right_decorations,
@@ -199,6 +201,7 @@ void CalculatePositionsInFrame(
decoration_frames->end());
*remaining_frame = frame;
+ return left_count;
}
} // namespace
@@ -386,6 +389,46 @@ void CalculatePositionsInFrame(
return textFrame;
}
+- (NSRect)textCursorFrameForFrame:(NSRect)cellFrame {
+ std::vector<LocationBarDecoration*> decorations;
+ std::vector<NSRect> decorationFrames;
+ NSRect textFrame;
+ size_t left_count =
+ CalculatePositionsInFrame(cellFrame, leftDecorations_, rightDecorations_,
+ &decorations, &decorationFrames, &textFrame);
+
+ // Determine the left-most extent for the i-beam cursor.
+ CGFloat minX = NSMinX(textFrame);
+ for (size_t index = left_count; index--; ) {
+ if (decorations[index]->AcceptsMousePress())
+ break;
+
+ // If at leftmost decoration, expand to edge of cell.
+ if (!index) {
+ minX = NSMinX(cellFrame);
+ } else {
+ minX = NSMinX(decorationFrames[index]) - kDecorationHorizontalPad;
+ }
+ }
+
+ // Determine the right-most extent for the i-beam cursor.
+ CGFloat maxX = NSMaxX(textFrame);
+ for (size_t index = left_count; index < decorations.size(); ++index) {
+ if (decorations[index]->AcceptsMousePress())
+ break;
+
+ // If at rightmost decoration, expand to edge of cell.
+ if (index == decorations.size() - 1) {
+ maxX = NSMaxX(cellFrame);
+ } else {
+ maxX = NSMaxX(decorationFrames[index]) + kDecorationHorizontalPad;
+ }
+ }
+
+ // I-beam cursor covers left-most to right-most.
+ return NSMakeRect(minX, NSMinY(textFrame), maxX - minX, NSHeight(textFrame));
+}
+
- (void)drawHintWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
DCHECK(hintString_);
@@ -466,7 +509,7 @@ void CalculatePositionsInFrame(
ofView:(AutocompleteTextField*)controlView {
LocationBarDecoration* decoration =
[self decorationForEvent:theEvent inRect:cellFrame ofView:controlView];
- if (!decoration)
+ if (!decoration || !decoration->AcceptsMousePress())
return NO;
NSRect decorationRect =
diff --git a/chrome/browser/cocoa/location_bar/autocomplete_text_field_cell_unittest.mm b/chrome/browser/cocoa/location_bar/autocomplete_text_field_cell_unittest.mm
index d3a4bfd..6dfa50b 100644
--- a/chrome/browser/cocoa/location_bar/autocomplete_text_field_cell_unittest.mm
+++ b/chrome/browser/cocoa/location_bar/autocomplete_text_field_cell_unittest.mm
@@ -178,6 +178,7 @@ TEST_F(AutocompleteTextFieldCellTest, TextFrame) {
// The cursor frame should stay the same throughout.
const NSRect cursorFrame([cell textCursorFrameForFrame:bounds]);
+ EXPECT_TRUE(NSEqualRects(cursorFrame, bounds));
// At default settings, everything goes to the text area.
textFrame = [cell textFrameForFrame:bounds];
@@ -185,7 +186,7 @@ TEST_F(AutocompleteTextFieldCellTest, TextFrame) {
EXPECT_TRUE(NSContainsRect(bounds, textFrame));
EXPECT_EQ(NSMinX(bounds), NSMinX(textFrame));
EXPECT_EQ(NSMaxX(bounds), NSMaxX(textFrame));
- EXPECT_TRUE(NSEqualRects(cursorFrame, textFrame));
+ EXPECT_TRUE(NSContainsRect(cursorFrame, textFrame));
// Small search hint leaves text frame to left.
[cell setSearchHintString:@"Search hint" availableWidth:kWidth];
diff --git a/chrome/browser/cocoa/location_bar/autocomplete_text_field_unittest.mm b/chrome/browser/cocoa/location_bar/autocomplete_text_field_unittest.mm
index 64ffbd8..8e27682 100644
--- a/chrome/browser/cocoa/location_bar/autocomplete_text_field_unittest.mm
+++ b/chrome/browser/cocoa/location_bar/autocomplete_text_field_unittest.mm
@@ -32,6 +32,7 @@ class MockDecoration : public LocationBarDecoration {
void SetVisible(bool visible) { visible_ = visible; }
virtual void DrawInFrame(NSRect frame, NSView* control_view) { ; }
+ virtual bool AcceptsMousePress() { return true; }
MOCK_METHOD1(OnMousePressed, bool(NSRect frame));
MOCK_METHOD0(GetMenu, NSMenu*());
diff --git a/chrome/browser/cocoa/location_bar/content_setting_decoration.h b/chrome/browser/cocoa/location_bar/content_setting_decoration.h
index 9ff6eda..bba2140 100644
--- a/chrome/browser/cocoa/location_bar/content_setting_decoration.h
+++ b/chrome/browser/cocoa/location_bar/content_setting_decoration.h
@@ -28,6 +28,7 @@ class ContentSettingDecoration : public ImageDecoration {
void UpdateFromTabContents(const TabContents* tab_contents);
// Overridden from |LocationBarDecoration|
+ virtual bool AcceptsMousePress() { return true; }
virtual bool OnMousePressed(NSRect frame);
virtual NSString* GetToolTip();
diff --git a/chrome/browser/cocoa/location_bar/ev_bubble_decoration.h b/chrome/browser/cocoa/location_bar/ev_bubble_decoration.h
index ea1697a..0cdd960 100644
--- a/chrome/browser/cocoa/location_bar/ev_bubble_decoration.h
+++ b/chrome/browser/cocoa/location_bar/ev_bubble_decoration.h
@@ -29,6 +29,7 @@ class EVBubbleDecoration : public BubbleDecoration {
virtual NSPasteboard* GetDragPasteboard();
virtual NSImage* GetDragImage();
virtual bool OnMousePressed(NSRect frame);
+ virtual bool AcceptsMousePress() { return true; }
private:
LocationIconDecoration* location_icon_; // weak, owned by location bar.
diff --git a/chrome/browser/cocoa/location_bar/location_bar_decoration.h b/chrome/browser/cocoa/location_bar/location_bar_decoration.h
index 9500e42..51571cc 100644
--- a/chrome/browser/cocoa/location_bar/location_bar_decoration.h
+++ b/chrome/browser/cocoa/location_bar/location_bar_decoration.h
@@ -46,6 +46,13 @@ class LocationBarDecoration {
// Returns the tooltip for this decoration, return |nil| for no tooltip.
virtual NSString* GetToolTip() { return nil; }
+ // Decorations which do not accept mouse events are treated like the
+ // field's background for purposes of selecting text. When such
+ // decorations are adjacent to the text area, they will show the
+ // I-beam cursor. Decorations which do accept mouse events will get
+ // an arrow cursor when the mouse is over them.
+ virtual bool AcceptsMousePress() { return false; }
+
// Determine if the item can act as a drag source.
virtual bool IsDraggable() { return false; }
diff --git a/chrome/browser/cocoa/location_bar/location_icon_decoration.h b/chrome/browser/cocoa/location_bar/location_icon_decoration.h
index 18952d2..9d705a8 100644
--- a/chrome/browser/cocoa/location_bar/location_icon_decoration.h
+++ b/chrome/browser/cocoa/location_bar/location_icon_decoration.h
@@ -26,6 +26,7 @@ class LocationIconDecoration : public ImageDecoration {
// Show the page info panel on click.
virtual bool OnMousePressed(NSRect frame);
+ virtual bool AcceptsMousePress() { return true; }
private:
// The location bar view that owns us.
diff --git a/chrome/browser/cocoa/location_bar/page_action_decoration.h b/chrome/browser/cocoa/location_bar/page_action_decoration.h
index 17a7e33..7bbf443 100644
--- a/chrome/browser/cocoa/location_bar/page_action_decoration.h
+++ b/chrome/browser/cocoa/location_bar/page_action_decoration.h
@@ -50,6 +50,7 @@ class PageActionDecoration : public ImageDecoration,
NSPoint GetBubblePointInFrame(NSRect frame);
// Overridden from |LocationBarDecoration|
+ virtual bool AcceptsMousePress() { return true; }
virtual bool OnMousePressed(NSRect frame);
virtual NSString* GetToolTip();
virtual NSMenu* GetMenu();
diff --git a/chrome/browser/cocoa/location_bar/star_decoration.h b/chrome/browser/cocoa/location_bar/star_decoration.h
index e39f9a8..6fbe91d 100644
--- a/chrome/browser/cocoa/location_bar/star_decoration.h
+++ b/chrome/browser/cocoa/location_bar/star_decoration.h
@@ -26,6 +26,7 @@ class StarDecoration : public ImageDecoration {
NSPoint GetBubblePointInFrame(NSRect frame);
// Implement |LocationBarDecoration|.
+ virtual bool AcceptsMousePress() { return true; }
virtual bool OnMousePressed(NSRect frame);
virtual NSString* GetToolTip();