diff options
author | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-25 18:07:24 +0000 |
---|---|---|
committer | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-25 18:07:24 +0000 |
commit | cdacb88cb3d3b11f21caae229816a68cab3170b2 (patch) | |
tree | 48dd9264836574f3152bc2f65d0bf10c353cac42 /chrome/browser/cocoa/autocomplete_text_field.mm | |
parent | ec9773681c979a58f966d6cb0fc8ad16746e3adf (diff) | |
download | chromium_src-cdacb88cb3d3b11f21caae229816a68cab3170b2.zip chromium_src-cdacb88cb3d3b11f21caae229816a68cab3170b2.tar.gz chromium_src-cdacb88cb3d3b11f21caae229816a68cab3170b2.tar.bz2 |
[Mac] Manually reposition Omnibox field editor rather than using focus machinery.
Previously this code abused the Cocoa focus machinery to move the
field editor around when needed, which required the code to mess
around with delegation to make sure the changes didn't leak out to the
core autocomplete code. Unfortunately, it also messes with other
features, like undo. This change does the positioning manually, which
should let everything just work.
TEST=Tab-to-search and keyword hints shouldn't cause the field to break.
Review URL: http://codereview.chromium.org/219031
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27217 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/cocoa/autocomplete_text_field.mm')
-rw-r--r-- | chrome/browser/cocoa/autocomplete_text_field.mm | 51 |
1 files changed, 23 insertions, 28 deletions
diff --git a/chrome/browser/cocoa/autocomplete_text_field.mm b/chrome/browser/cocoa/autocomplete_text_field.mm index f48d508..25db457 100644 --- a/chrome/browser/cocoa/autocomplete_text_field.mm +++ b/chrome/browser/cocoa/autocomplete_text_field.mm @@ -29,38 +29,33 @@ return static_cast<AutocompleteTextFieldCell*>([self cell]); } -// TODO(shess): An alternate implementation of this would be to pick -// out the field's subview (which may be a clip view around the field -// editor) and manually resize it to the textFrame returned from the -// cell's -splitFrame:*. That doesn't mess with the editing state of -// the field editor system, but does make other assumptions about how -// field editors are placed. +// Cocoa text fields are edited by placing an NSTextView as subview, +// positioned by the cell's -editWithFrame:inView:... method. Using +// the standard -makeFirstResponder: machinery to reposition the field +// editor results in reseting the field editor's editing state, which +// AutocompleteEditViewMac monitors. This causes problems because +// editing can require the field editor to be repositioned, which +// could disrupt editing. This code repositions the subview directly, +// which causes no editing-state changes. - (void)resetFieldEditorFrameIfNeeded { AutocompleteTextFieldCell* cell = [self cell]; if ([cell fieldEditorNeedsReset]) { - NSTextView* editor = (id)[self currentEditor]; + // No change to bounds necessary if not editing. + NSText* editor = [self currentEditor]; if (editor) { - // Clear the delegate so that it doesn't see - // -control:textShouldEndEditing: (closes autocomplete popup). - id delegate = [self delegate]; - [self setDelegate:nil]; - - // -makeFirstResponder: will select-all, restore selection. - NSRange sel = [editor selectedRange]; - [[self window] makeFirstResponder:self]; - [editor setSelectedRange:sel]; - - [self setDelegate:delegate]; - - // Now provoke call to delegate's -controlTextDidBeginEditing:. - // This is necessary to make sure that we'll send the - // appropriate -control:textShouldEndEditing: call when we lose - // focus. - // TODO(shess): Would be better to only restore this state if - // -controlTextDidBeginEditing: had already been sent. - // Unfortunately, that's hard to detect. Could either check - // popup IsOpen() or model has_focus()? - [editor shouldChangeTextInRange:sel replacementString:@""]; + // When editing, we should have exactly one subview, which is a + // clipview containing the editor (for purposes of scrolling). + NSArray* subviews = [self subviews]; + DCHECK_EQ([subviews count], 1U); + DCHECK([editor isDescendantOf:self]); + if ([subviews count] > 0) { + const NSRect frame([cell drawingRectForBounds:[self bounds]]); + [[subviews objectAtIndex:0] setFrame:frame]; + + // Make sure the selection remains visible. + // TODO(shess) Could this be janky? + [editor scrollRangeToVisible:[editor selectedRange]]; + } } [cell setFieldEditorNeedsReset:NO]; } |