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

Side by Side Diff: chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm

Issue 1855423003: Interpret '?' and Ctrl-K or Ctrl-E as putting omnibox in keyword search mode for Default Search Pro… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add includes for mac tests Created 4 years, 6 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.h" 5 #include "chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.h"
6 6
7 #include <Carbon/Carbon.h> // kVK_Return 7 #include <Carbon/Carbon.h> // kVK_Return
8 8
9 #include "base/mac/foundation_util.h" 9 #include "base/mac/foundation_util.h"
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 Profile* profile, 207 Profile* profile,
208 CommandUpdater* command_updater, 208 CommandUpdater* command_updater,
209 AutocompleteTextField* field) 209 AutocompleteTextField* field)
210 : OmniboxView( 210 : OmniboxView(
211 controller, 211 controller,
212 base::WrapUnique(new ChromeOmniboxClient(controller, profile))), 212 base::WrapUnique(new ChromeOmniboxClient(controller, profile))),
213 profile_(profile), 213 profile_(profile),
214 popup_view_(new OmniboxPopupViewMac(this, model(), field)), 214 popup_view_(new OmniboxPopupViewMac(this, model(), field)),
215 field_(field), 215 field_(field),
216 saved_temporary_selection_(NSMakeRange(0, 0)), 216 saved_temporary_selection_(NSMakeRange(0, 0)),
217 selection_before_change_(NSMakeRange(0, 0)),
218 marked_range_before_change_(NSMakeRange(0, 0)), 217 marked_range_before_change_(NSMakeRange(0, 0)),
219 delete_was_pressed_(false), 218 delete_was_pressed_(false),
220 delete_at_end_pressed_(false), 219 delete_at_end_pressed_(false),
221 in_coalesced_update_block_(false), 220 in_coalesced_update_block_(false),
222 do_coalesced_text_update_(false), 221 do_coalesced_text_update_(false),
223 do_coalesced_range_update_(false) { 222 do_coalesced_range_update_(false) {
224 [field_ setObserver:this]; 223 [field_ setObserver:this];
225 224
226 // Needed so that editing doesn't lose the styling. 225 // Needed so that editing doesn't lose the styling.
227 [field_ setAllowsEditingTextAttributes:YES]; 226 [field_ setAllowsEditingTextAttributes:YES];
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 DCHECK_LE(caret_pos, text.size()); 380 DCHECK_LE(caret_pos, text.size());
382 SetTextAndSelectedRange(text, NSMakeRange(caret_pos, 0)); 381 SetTextAndSelectedRange(text, NSMakeRange(caret_pos, 0));
383 382
384 if (update_popup) 383 if (update_popup)
385 UpdatePopup(); 384 UpdatePopup();
386 385
387 if (notify_text_changed) 386 if (notify_text_changed)
388 TextChanged(); 387 TextChanged();
389 } 388 }
390 389
391 void OmniboxViewMac::SetForcedQuery() { 390 void OmniboxViewMac::EnterKeywordModeForDefaultSearchProvider() {
392 // We need to do this first, else |SetSelectedRange()| won't work. 391 // We need to do this first, else |SetSelectedRange()| won't work.
393 FocusLocation(true); 392 FocusLocation(true);
394 393
395 const base::string16 current_text(GetText()); 394 // Transition the user into keyword mode using their default search provider.
396 const size_t start = current_text.find_first_not_of(base::kWhitespaceUTF16); 395 // Select their query if they typed one.
397 if (start == base::string16::npos || (current_text[start] != '?')) { 396 model()->EnterKeywordModeForDefaultSearchProvider(
398 SetUserText(base::ASCIIToUTF16("?")); 397 KeywordModeEntryMethod::KEYBOARD_SHORTCUT);
399 } else { 398 SelectAll(false);
400 NSRange range = NSMakeRange(start + 1, current_text.size() - start - 1);
401 [[field_ currentEditor] setSelectedRange:range];
402 }
403 } 399 }
404 400
405 bool OmniboxViewMac::IsSelectAll() const { 401 bool OmniboxViewMac::IsSelectAll() const {
406 if (![field_ currentEditor]) 402 if (![field_ currentEditor])
407 return true; 403 return true;
408 const NSRange all_range = NSMakeRange(0, GetTextLength()); 404 const NSRange all_range = NSMakeRange(0, GetTextLength());
409 return NSEqualRanges(all_range, GetSelectedRange()); 405 return NSEqualRanges(all_range, GetSelectedRange());
410 } 406 }
411 407
412 bool OmniboxViewMac::DeleteAtEndPressed() { 408 bool OmniboxViewMac::DeleteAtEndPressed() {
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 } 672 }
677 673
678 bool OmniboxViewMac::IsFirstResponder() const { 674 bool OmniboxViewMac::IsFirstResponder() const {
679 return [field_ currentEditor] != nil ? true : false; 675 return [field_ currentEditor] != nil ? true : false;
680 } 676 }
681 677
682 void OmniboxViewMac::OnBeforePossibleChange() { 678 void OmniboxViewMac::OnBeforePossibleChange() {
683 // We should only arrive here when the field is focused. 679 // We should only arrive here when the field is focused.
684 DCHECK(IsFirstResponder()); 680 DCHECK(IsFirstResponder());
685 681
686 selection_before_change_ = GetSelectedRange(); 682 GetState(&state_before_change_);
687 text_before_change_ = GetText();
688 marked_range_before_change_ = GetMarkedRange(); 683 marked_range_before_change_ = GetMarkedRange();
689 } 684 }
690 685
691 bool OmniboxViewMac::OnAfterPossibleChange(bool allow_keyword_ui_change) { 686 bool OmniboxViewMac::OnAfterPossibleChange(bool allow_keyword_ui_change) {
692 // We should only arrive here when the field is focused. 687 // We should only arrive here when the field is focused.
693 DCHECK(IsFirstResponder()); 688 DCHECK(IsFirstResponder());
694 689
695 const NSRange new_selection(GetSelectedRange()); 690 State new_state;
696 const base::string16 new_text(GetText()); 691 GetState(&new_state);
697 const size_t length = new_text.length(); 692 OmniboxView::StateChanges state_changes =
693 GetStateChanges(state_before_change_, new_state);
698 694
699 const bool selection_differs = 695 const bool at_end_of_edit = (new_state.text.length() == new_state.sel_end);
700 (new_selection.length || selection_before_change_.length) &&
701 !NSEqualRanges(new_selection, selection_before_change_);
702 const bool at_end_of_edit = (length == new_selection.location);
703 const bool text_differs = (new_text != text_before_change_) ||
704 !NSEqualRanges(marked_range_before_change_, GetMarkedRange());
705
706 // When the user has deleted text, we don't allow inline
707 // autocomplete. This is assumed if the text has gotten shorter AND
708 // the selection has shifted towards the front of the text. During
709 // normal typing the text will almost always be shorter (as the new
710 // input replaces the autocomplete suggestion), but in that case the
711 // selection point will have moved towards the end of the text.
712 // TODO(shess): In our implementation, we can catch -deleteBackward:
713 // and other methods to provide positive knowledge that a delete
714 // occurred, rather than intuiting it from context. Consider whether
715 // that would be a stronger approach.
716 const bool just_deleted_text =
717 (length < text_before_change_.length() &&
718 new_selection.location <= selection_before_change_.location);
719 696
720 delete_at_end_pressed_ = false; 697 delete_at_end_pressed_ = false;
721 698
722 const bool something_changed = model()->OnAfterPossibleChange( 699 const bool something_changed = model()->OnAfterPossibleChange(
723 text_before_change_, new_text, new_selection.location, 700 state_changes, allow_keyword_ui_change && !IsImeComposing());
724 NSMaxRange(new_selection), selection_differs, text_differs,
725 just_deleted_text, allow_keyword_ui_change && !IsImeComposing());
726 701
727 if (delete_was_pressed_ && at_end_of_edit) 702 if (delete_was_pressed_ && at_end_of_edit)
728 delete_at_end_pressed_ = true; 703 delete_at_end_pressed_ = true;
729 704
730 // Restyle in case the user changed something. 705 // Restyle in case the user changed something.
731 // TODO(shess): I believe there are multiple-redraw cases, here. 706 // TODO(shess): I believe there are multiple-redraw cases, here.
732 // Linux watches for something_changed && text_differs, but that 707 // Linux watches for something_changed && text_differs, but that
733 // fails for us in case you copy the URL and paste the identical URL 708 // fails for us in case you copy the URL and paste the identical URL
734 // back (we'll lose the styling). 709 // back (we'll lose the styling).
735 TextChanged(); 710 TextChanged();
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
863 return true; 838 return true;
864 } 839 }
865 840
866 if (cmd == @selector(cancelOperation:)) { 841 if (cmd == @selector(cancelOperation:)) {
867 return model()->OnEscapeKeyPressed(); 842 return model()->OnEscapeKeyPressed();
868 } 843 }
869 844
870 if ((cmd == @selector(insertTab:) || 845 if ((cmd == @selector(insertTab:) ||
871 cmd == @selector(insertTabIgnoringFieldEditor:)) && 846 cmd == @selector(insertTabIgnoringFieldEditor:)) &&
872 model()->is_keyword_hint()) { 847 model()->is_keyword_hint()) {
873 return model()->AcceptKeyword(ENTERED_KEYWORD_MODE_VIA_TAB); 848 return model()->AcceptKeyword(KeywordModeEntryMethod::TAB);
874 } 849 }
875 850
876 // |-noop:| is sent when the user presses Cmd+Return. Override the no-op 851 // |-noop:| is sent when the user presses Cmd+Return. Override the no-op
877 // behavior with the proper WindowOpenDisposition. 852 // behavior with the proper WindowOpenDisposition.
878 NSEvent* event = [NSApp currentEvent]; 853 NSEvent* event = [NSApp currentEvent];
879 if (cmd == @selector(insertNewline:) || 854 if (cmd == @selector(insertNewline:) ||
880 (cmd == @selector(noop:) && 855 (cmd == @selector(noop:) &&
881 ([event type] == NSKeyDown || [event type] == NSKeyUp) && 856 ([event type] == NSKeyDown || [event type] == NSKeyUp) &&
882 [event keyCode] == kVK_Return)) { 857 [event keyCode] == kVK_Return)) {
883 WindowOpenDisposition disposition = 858 WindowOpenDisposition disposition =
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 // from the Chrome-specific code. 991 // from the Chrome-specific code.
1017 NSTextView* editor = static_cast<NSTextView*>([field_ currentEditor]); 992 NSTextView* editor = static_cast<NSTextView*>([field_ currentEditor]);
1018 const NSRange selectedRange = GetSelectedRange(); 993 const NSRange selectedRange = GetSelectedRange();
1019 if ([editor shouldChangeTextInRange:selectedRange replacementString:s]) { 994 if ([editor shouldChangeTextInRange:selectedRange replacementString:s]) {
1020 // Record this paste, so we can do different behavior. 995 // Record this paste, so we can do different behavior.
1021 model()->OnPaste(); 996 model()->OnPaste();
1022 997
1023 // Force a Paste operation to trigger the text_changed code in 998 // Force a Paste operation to trigger the text_changed code in
1024 // OnAfterPossibleChange(), even if identical contents are pasted 999 // OnAfterPossibleChange(), even if identical contents are pasted
1025 // into the text box. 1000 // into the text box.
1026 text_before_change_.clear(); 1001 state_before_change_.text.clear();
1027 1002
1028 [editor replaceCharactersInRange:selectedRange withString:s]; 1003 [editor replaceCharactersInRange:selectedRange withString:s];
1029 [editor didChangeText]; 1004 [editor didChangeText];
1030 } 1005 }
1031 } 1006 }
1032 1007
1033 // TODO(dominich): Move to OmniboxView base class? Currently this is defined on 1008 // TODO(dominich): Move to OmniboxView base class? Currently this is defined on
1034 // the AutocompleteTextFieldObserver but the logic is shared between all 1009 // the AutocompleteTextFieldObserver but the logic is shared between all
1035 // platforms. Some refactor might be necessary to simplify this. Or at least 1010 // platforms. Some refactor might be necessary to simplify this. Or at least
1036 // this method could call the OmniboxView version. 1011 // this method could call the OmniboxView version.
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1169 display_text); 1144 display_text);
1170 NSDictionary* notification_info = @{ 1145 NSDictionary* notification_info = @{
1171 NSAccessibilityAnnouncementKey : announcement, 1146 NSAccessibilityAnnouncementKey : announcement,
1172 NSAccessibilityPriorityKey : @(NSAccessibilityPriorityHigh) 1147 NSAccessibilityPriorityKey : @(NSAccessibilityPriorityHigh)
1173 }; 1148 };
1174 NSAccessibilityPostNotificationWithUserInfo( 1149 NSAccessibilityPostNotificationWithUserInfo(
1175 [field_ window], 1150 [field_ window],
1176 NSAccessibilityAnnouncementRequestedNotification, 1151 NSAccessibilityAnnouncementRequestedNotification,
1177 notification_info); 1152 notification_info);
1178 } 1153 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.h ('k') | chrome/browser/ui/cocoa/omnibox/omnibox_view_mac_browsertest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698