Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4069)

Unified Diff: chrome/browser/autocomplete/autocomplete_edit_view_mac.mm

Issue 113746: Overhaul omnibox focus detection on Mac. (Closed)
Patch Set: Address Pink's suggestion, add some color commentary. Created 11 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/autocomplete/autocomplete_edit_view_mac.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/autocomplete/autocomplete_edit_view_mac.mm
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm b/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm
index c86fa29cc7aeacf7e614be016a01df795a9e3d8f..3b66683d2c3b93514fecd1159bc6b88ccf0ba844 100644
--- a/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm
+++ b/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm
@@ -10,6 +10,31 @@
#include "chrome/browser/autocomplete/autocomplete_popup_view_mac.h"
#include "chrome/browser/tab_contents/tab_contents.h"
+// Focus-handling between |field_| and |model_| is a bit subtle.
+// Other platforms detect change of focus, which is inconvenient
+// without subclassing NSTextField (even with a subclass, the use of a
+// field editor may complicate things).
+//
+// |model_| doesn't actually do anything when it gains focus, it just
+// initializes. Visible activity happens only after the user edits.
+// NSTextField delegate receives messages around starting and ending
+// edits, so that sufcices to catch focus changes. Since all calls
+// into |model_| start from AutocompleteEditViewMac, in the worst case
+// we can add code to sync up the sense of focus as needed.
+//
+// I've added DCHECK(IsFirstResponder()) in the places which I believe
+// should only be reachable when |field_| is being edited. If these
+// fire, it probably means someone unexpected is calling into
+// |model_|.
+//
+// Other platforms don't appear to have the sense of "key window" that
+// Mac does (I believe their fields lose focus when the window loses
+// focus). Rather than modifying focus outside the control's edit
+// scope, when the window resigns key the autocomplete popup is
+// closed. |model_| still believes it has focus, and the popup will
+// be regenerated on the user's next edit. That seems to match how
+// things work on other platforms.
+
namespace {
// TODO(shess): This is ugly, find a better way. Using it right now
@@ -98,7 +123,6 @@ NSRange ComponentToNSRange(const url_parse::Component& component) {
}
- initWithEditView:(AutocompleteEditViewMac*)view;
- (void)windowDidResignKey:(NSNotification*)notification;
-- (void)windowDidBecomeKey:(NSNotification*)notification;
@end
AutocompleteEditViewMac::AutocompleteEditViewMac(
@@ -132,10 +156,6 @@ AutocompleteEditViewMac::AutocompleteEditViewMac(
selector:@selector(windowDidResignKey:)
name:NSWindowDidResignKeyNotification
object:[field_ window]];
- [nc addObserver:edit_helper_
- selector:@selector(windowDidBecomeKey:)
- name:NSWindowDidBecomeKeyNotification
- object:[field_ window]];
}
AutocompleteEditViewMac::~AutocompleteEditViewMac() {
@@ -399,12 +419,22 @@ void AutocompleteEditViewMac::OnRevertTemporaryText() {
SetSelectedRange(saved_temporary_selection_);
}
+bool AutocompleteEditViewMac::IsFirstResponder() const {
+ return [field_ currentEditor] != nil ? true : false;
+}
+
void AutocompleteEditViewMac::OnBeforePossibleChange() {
+ // We should only arrive here when the field is focussed.
+ DCHECK(IsFirstResponder());
+
selection_before_change_ = GetSelectedRange();
text_before_change_ = GetText();
}
bool AutocompleteEditViewMac::OnAfterPossibleChange() {
+ // We should only arrive here when the field is focussed.
+ DCHECK(IsFirstResponder());
+
const NSRange new_selection(GetSelectedRange());
const std::wstring new_text(GetText());
const size_t length = new_text.length();
@@ -450,27 +480,50 @@ bool AutocompleteEditViewMac::OnAfterPossibleChange() {
}
void AutocompleteEditViewMac::OnUpOrDownKeyPressed(bool up, bool by_page) {
+ // We should only arrive here when the field is focussed.
+ DCHECK(IsFirstResponder());
+
const int count = by_page ? model_->result().size() : 1;
model_->OnUpOrDownKeyPressed(up ? -count : count);
}
+
void AutocompleteEditViewMac::OnEscapeKeyPressed() {
+ // We should only arrive here when the field is focussed.
+ DCHECK(IsFirstResponder());
+
model_->OnEscapeKeyPressed();
}
-void AutocompleteEditViewMac::OnSetFocus(bool f) {
- // Only forward if we actually do have the focus.
- if ([field_ currentEditor]) {
- model_->OnSetFocus(f);
- }
+
+void AutocompleteEditViewMac::OnWillBeginEditing() {
+ // We should only arrive here when the field is focussed.
+ DCHECK([field_ currentEditor]);
+
+ // TODO(shess): Having the control key depressed changes the desired
+ // TLD for autocomplete, which changes the results. Not sure if we
+ // can detect that without subclassing NSTextField.
+ const bool controlDown = false;
+ model_->OnSetFocus(controlDown);
+
+ // Capture the current state.
+ OnBeforePossibleChange();
}
-void AutocompleteEditViewMac::OnKillFocus() {
- // TODO(shess): This would seem to be a job for |model_|.
+
+void AutocompleteEditViewMac::OnDidEndEditing() {
ClosePopup();
// Tell the model to reset itself.
model_->OnKillFocus();
}
+
+void AutocompleteEditViewMac::OnDidResignKey() {
+ ClosePopup();
+}
+
void AutocompleteEditViewMac::AcceptInput(
WindowOpenDisposition disposition, bool for_drop) {
+ // We should only arrive here when the field is focussed.
+ DCHECK([field_ currentEditor]);
+
model_->AcceptInput(disposition, for_drop);
}
@@ -534,10 +587,7 @@ void AutocompleteEditViewMac::FocusLocation() {
}
- (void)controlTextDidBeginEditing:(NSNotification*)aNotification {
- edit_view_->OnSetFocus(false);
-
- // Capture the current state.
- edit_view_->OnBeforePossibleChange();
+ edit_view_->OnWillBeginEditing();
}
- (void)controlTextDidChange:(NSNotification*)aNotification {
@@ -549,7 +599,7 @@ void AutocompleteEditViewMac::FocusLocation() {
}
- (BOOL)control:(NSControl*)control textShouldEndEditing:(NSText*)fieldEditor {
- edit_view_->OnKillFocus();
+ edit_view_->OnDidEndEditing();
return YES;
@@ -559,12 +609,7 @@ void AutocompleteEditViewMac::FocusLocation() {
// Signal that we've lost focus when the window resigns key.
- (void)windowDidResignKey:(NSNotification*)notification {
- edit_view_->OnKillFocus();
-}
-
-// Signal that we may have regained focus.
-- (void)windowDidBecomeKey:(NSNotification*)notification {
- edit_view_->OnSetFocus(false);
+ edit_view_->OnDidResignKey();
}
@end
« no previous file with comments | « chrome/browser/autocomplete/autocomplete_edit_view_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698