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

Side by Side Diff: chrome/browser/ui/views/omnibox/omnibox_view_win.cc

Issue 11141019: Re-enable CJK omnibox suggest on Metro UI (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years, 2 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/views/omnibox/omnibox_view_win.h" 5 #include "chrome/browser/ui/views/omnibox/omnibox_view_win.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <locale> 8 #include <locale>
9 #include <string> 9 #include <string>
10 10
11 #include <richedit.h> 11 #include <richedit.h>
12 #include <textserv.h> 12 #include <textserv.h>
13 13
14 #include "base/auto_reset.h" 14 #include "base/auto_reset.h"
15 #include "base/basictypes.h" 15 #include "base/basictypes.h"
16 #include "base/bind.h"
16 #include "base/i18n/rtl.h" 17 #include "base/i18n/rtl.h"
17 #include "base/lazy_instance.h" 18 #include "base/lazy_instance.h"
18 #include "base/memory/ref_counted.h" 19 #include "base/memory/ref_counted.h"
19 #include "base/string_util.h" 20 #include "base/string_util.h"
20 #include "base/utf_string_conversions.h" 21 #include "base/utf_string_conversions.h"
21 #include "base/win/iat_patch_function.h" 22 #include "base/win/iat_patch_function.h"
22 #include "base/win/metro.h" 23 #include "base/win/metro.h"
23 #include "base/win/scoped_hdc.h" 24 #include "base/win/scoped_hdc.h"
24 #include "base/win/scoped_select_object.h" 25 #include "base/win/scoped_select_object.h"
25 #include "base/win/windows_version.h" 26 #include "base/win/windows_version.h"
(...skipping 20 matching lines...) Expand all
46 #include "ui/base/accessibility/accessible_view_state.h" 47 #include "ui/base/accessibility/accessible_view_state.h"
47 #include "ui/base/clipboard/clipboard.h" 48 #include "ui/base/clipboard/clipboard.h"
48 #include "ui/base/clipboard/scoped_clipboard_writer.h" 49 #include "ui/base/clipboard/scoped_clipboard_writer.h"
49 #include "ui/base/dragdrop/drag_drop_types.h" 50 #include "ui/base/dragdrop/drag_drop_types.h"
50 #include "ui/base/dragdrop/drag_source.h" 51 #include "ui/base/dragdrop/drag_source.h"
51 #include "ui/base/dragdrop/drop_target.h" 52 #include "ui/base/dragdrop/drop_target.h"
52 #include "ui/base/dragdrop/os_exchange_data.h" 53 #include "ui/base/dragdrop/os_exchange_data.h"
53 #include "ui/base/dragdrop/os_exchange_data_provider_win.h" 54 #include "ui/base/dragdrop/os_exchange_data_provider_win.h"
54 #include "ui/base/events/event.h" 55 #include "ui/base/events/event.h"
55 #include "ui/base/events/event_constants.h" 56 #include "ui/base/events/event_constants.h"
57 #include "ui/base/ime/win/tsf_bridge.h"
58 #include "ui/base/ime/win/tsf_event_router.h"
56 #include "ui/base/keycodes/keyboard_codes.h" 59 #include "ui/base/keycodes/keyboard_codes.h"
57 #include "ui/base/l10n/l10n_util.h" 60 #include "ui/base/l10n/l10n_util.h"
58 #include "ui/base/l10n/l10n_util_win.h" 61 #include "ui/base/l10n/l10n_util_win.h"
59 #include "ui/base/win/mouse_wheel_util.h" 62 #include "ui/base/win/mouse_wheel_util.h"
60 #include "ui/gfx/canvas.h" 63 #include "ui/gfx/canvas.h"
61 #include "ui/gfx/image/image.h" 64 #include "ui/gfx/image/image.h"
62 #include "ui/views/button_drag_utils.h" 65 #include "ui/views/button_drag_utils.h"
63 #include "ui/views/controls/menu/menu_item_view.h" 66 #include "ui/views/controls/menu/menu_item_view.h"
64 #include "ui/views/controls/menu/menu_model_adapter.h" 67 #include "ui/views/controls/menu/menu_model_adapter.h"
65 #include "ui/views/controls/menu/menu_runner.h" 68 #include "ui/views/controls/menu/menu_runner.h"
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 font_(parent_view->font()), 473 font_(parent_view->font()),
471 possible_drag_(false), 474 possible_drag_(false),
472 in_drag_(false), 475 in_drag_(false),
473 initiated_drag_(false), 476 initiated_drag_(false),
474 drop_highlight_position_(-1), 477 drop_highlight_position_(-1),
475 ime_candidate_window_open_(false), 478 ime_candidate_window_open_(false),
476 background_color_(skia::SkColorToCOLORREF(LocationBarView::GetColor( 479 background_color_(skia::SkColorToCOLORREF(LocationBarView::GetColor(
477 chrome::search::IsInstantExtendedAPIEnabled(parent_view_->profile()), 480 chrome::search::IsInstantExtendedAPIEnabled(parent_view_->profile()),
478 ToolbarModel::NONE, LocationBarView::BACKGROUND))), 481 ToolbarModel::NONE, LocationBarView::BACKGROUND))),
479 security_level_(ToolbarModel::NONE), 482 security_level_(ToolbarModel::NONE),
480 text_object_model_(NULL) { 483 text_object_model_(NULL),
484 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
481 if (!loaded_library_module_) 485 if (!loaded_library_module_)
482 loaded_library_module_ = LoadLibrary(kRichEditDLLName); 486 loaded_library_module_ = LoadLibrary(kRichEditDLLName);
483 487
484 saved_selection_for_focus_change_.cpMin = -1; 488 saved_selection_for_focus_change_.cpMin = -1;
485 489
486 g_paint_patcher.Pointer()->RefPatch(); 490 g_paint_patcher.Pointer()->RefPatch();
487 491
488 Create(location_bar->GetWidget()->GetNativeView(), 0, 0, 0, 492 Create(location_bar->GetWidget()->GetNativeView(), 0, 0, 0,
489 l10n_util::GetExtendedStyles()); 493 l10n_util::GetExtendedStyles());
490 SetReadOnly(popup_window_mode_); 494 SetReadOnly(popup_window_mode_);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 // Non-read-only edit controls have a drop target. Revoke it so that we can 535 // Non-read-only edit controls have a drop target. Revoke it so that we can
532 // install our own. Revoking automatically deletes the existing one. 536 // install our own. Revoking automatically deletes the existing one.
533 HRESULT hr = RevokeDragDrop(m_hWnd); 537 HRESULT hr = RevokeDragDrop(m_hWnd);
534 DCHECK_EQ(S_OK, hr); 538 DCHECK_EQ(S_OK, hr);
535 539
536 // Register our drop target. The scoped_refptr here will delete the drop 540 // Register our drop target. The scoped_refptr here will delete the drop
537 // target if it fails to register itself correctly on |m_hWnd|. Otherwise, 541 // target if it fails to register itself correctly on |m_hWnd|. Otherwise,
538 // the edit control will invoke RevokeDragDrop when it's being destroyed, so 542 // the edit control will invoke RevokeDragDrop when it's being destroyed, so
539 // we don't have to do so. 543 // we don't have to do so.
540 scoped_refptr<EditDropTarget> drop_target(new EditDropTarget(this)); 544 scoped_refptr<EditDropTarget> drop_target(new EditDropTarget(this));
545
546 if (base::win::IsTsfAwareRequired()) {
547 // Register TsfEventRouter to catch TSF related event.
548 tsf_event_router_ = ui::TsfEventRouter::Create();
549 tsf_event_router_->SetTextUpdatedCallback(
550 base::Bind(&OmniboxViewWin::OnTextUpdatedByTsf,
551 weak_ptr_factory_.GetWeakPtr()));
552 tsf_event_router_->SetCandidateWindowStatusChangedCallback(
553 base::Bind(&OmniboxViewWin::OnCandidateWindowCountChangedByTsf,
554 weak_ptr_factory_.GetWeakPtr()));
555 }
541 } 556 }
542 } 557 }
543 558
544 OmniboxViewWin::~OmniboxViewWin() { 559 OmniboxViewWin::~OmniboxViewWin() {
545 // Explicitly release the text object model now that we're done with it, and 560 // Explicitly release the text object model now that we're done with it, and
546 // before we free the library. If the library gets unloaded before this 561 // before we free the library. If the library gets unloaded before this
547 // released, it becomes garbage. Note that since text_object_model_ is lazy 562 // released, it becomes garbage. Note that since text_object_model_ is lazy
548 // initialized, it may still be null. 563 // initialized, it may still be null.
549 if (text_object_model_) 564 if (text_object_model_)
550 text_object_model_->Release(); 565 text_object_model_->Release();
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 native_view_host_, 921 native_view_host_,
907 ui::AccessibilityTypes::EVENT_SELECTION_CHANGED, 922 ui::AccessibilityTypes::EVENT_SELECTION_CHANGED,
908 true); 923 true);
909 } else if (delete_at_end_pressed_) { 924 } else if (delete_at_end_pressed_) {
910 model()->OnChanged(); 925 model()->OnChanged();
911 } 926 }
912 927
913 return something_changed; 928 return something_changed;
914 } 929 }
915 930
931 void OmniboxViewWin::OnTextUpdatedByTsf() {
932 if (ignore_ime_messages_)
933 return;
934 OnAfterPossibleChangeInternal(true);
935 // Call OnBeforePossibleChange function here to get correct diff in next IME
936 // update. The Text Services Framework does not provide any notification
937 // before entering edit session, therefore we don't have good place to call
938 // OnbeforePossibleChange.
falken 2012/10/18 02:15:54 nit: "OnBeforePossibleChange"
Seigo Nonaka 2012/10/18 10:02:23 Done.
939 OnBeforePossibleChange();
940 }
941
942 void OmniboxViewWin::OnCandidateWindowCountChangedByTsf(size_t window_count) {
943 ime_candidate_window_open_ = (window_count != 0);
944 if (ime_candidate_window_open_) {
945 CloseOmniboxPopup();
946 } else {
947 // UpdatePopup assumes user input is in progress, so only call it if
948 // that's the case. Otherwise, autocomplete may run on an empty user
949 // text. For example, Baidu Japanese IME sends IMN_CLOSECANDIDATE when
falken 2012/10/18 02:15:54 In TSF you don't get IMN_CLOSECANDIDATE messages,
Seigo Nonaka 2012/10/18 10:02:23 Done.
950 // composition mode is entered, but the user may not have input anything
951 // yet.
952 if (model()->user_input_in_progress())
953 UpdatePopup();
954 }
955 }
956
916 gfx::NativeView OmniboxViewWin::GetNativeView() const { 957 gfx::NativeView OmniboxViewWin::GetNativeView() const {
917 return m_hWnd; 958 return m_hWnd;
918 } 959 }
919 960
920 // static 961 // static
921 gfx::NativeView OmniboxViewWin::GetRelativeWindowForNativeView( 962 gfx::NativeView OmniboxViewWin::GetRelativeWindowForNativeView(
922 gfx::NativeView edit_native_view) { 963 gfx::NativeView edit_native_view) {
923 // When an IME is attached to the rich-edit control, retrieve its window 964 // When an IME is attached to the rich-edit control, retrieve its window
924 // handle, and the popup window of OmniboxPopupView will be shown under the 965 // handle, and the popup window of OmniboxPopupView will be shown under the
925 // IME windows. 966 // IME windows.
(...skipping 15 matching lines...) Expand all
941 982
942 int OmniboxViewWin::TextWidth() const { 983 int OmniboxViewWin::TextWidth() const {
943 return WidthNeededToDisplay(GetText()); 984 return WidthNeededToDisplay(GetText());
944 } 985 }
945 986
946 string16 OmniboxViewWin::GetInstantSuggestion() const { 987 string16 OmniboxViewWin::GetInstantSuggestion() const {
947 return parent_view_->GetInstantSuggestion(); 988 return parent_view_->GetInstantSuggestion();
948 } 989 }
949 990
950 bool OmniboxViewWin::IsImeComposing() const { 991 bool OmniboxViewWin::IsImeComposing() const {
951 bool ime_composing = false; 992 if (base::win::IsTsfAwareRequired()) {
952 HIMC context = ImmGetContext(m_hWnd); 993 return tsf_event_router_->IsImeComposing();
953 if (context) { 994 } else {
954 ime_composing = !!ImmGetCompositionString(context, GCS_COMPSTR, NULL, 0); 995 bool ime_composing = false;
955 ImmReleaseContext(m_hWnd, context); 996 HIMC context = ImmGetContext(m_hWnd);
997 if (context) {
998 ime_composing = !!ImmGetCompositionString(context, GCS_COMPSTR, NULL, 0);
999 ImmReleaseContext(m_hWnd, context);
1000 }
1001 return ime_composing;
956 } 1002 }
957 return ime_composing;
958 } 1003 }
959 1004
960 int OmniboxViewWin::GetMaxEditWidth(int entry_width) const { 1005 int OmniboxViewWin::GetMaxEditWidth(int entry_width) const {
961 RECT formatting_rect; 1006 RECT formatting_rect;
962 GetRect(&formatting_rect); 1007 GetRect(&formatting_rect);
963 RECT edit_bounds; 1008 RECT edit_bounds;
964 GetClientRect(&edit_bounds); 1009 GetClientRect(&edit_bounds);
965 return entry_width - formatting_rect.left - 1010 return entry_width - formatting_rect.left -
966 (edit_bounds.right - formatting_rect.right); 1011 (edit_bounds.right - formatting_rect.right);
967 } 1012 }
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after
1575 // an in-progress IME composition will be completed at the new caret position, 1620 // an in-progress IME composition will be completed at the new caret position,
1576 // resulting in the string jumping unexpectedly to the front of the edit. 1621 // resulting in the string jumping unexpectedly to the front of the edit.
1577 // 1622 //
1578 // Crazy hack: If we just do PlaceCaretAt(0), and the beginning of the text is 1623 // Crazy hack: If we just do PlaceCaretAt(0), and the beginning of the text is
1579 // currently scrolled out of view, we can wind up with a blinking cursor in 1624 // currently scrolled out of view, we can wind up with a blinking cursor in
1580 // the toolbar at the current X coordinate of the beginning of the text. By 1625 // the toolbar at the current X coordinate of the beginning of the text. By
1581 // first doing a reverse-select-all to scroll the beginning of the text into 1626 // first doing a reverse-select-all to scroll the beginning of the text into
1582 // view, we work around this CRichEditCtrl bug. 1627 // view, we work around this CRichEditCtrl bug.
1583 SelectAll(true); 1628 SelectAll(true);
1584 PlaceCaretAt(0); 1629 PlaceCaretAt(0);
1630
1631 if (base::win::IsTsfAwareRequired())
1632 tsf_event_router_->SetManager(NULL);
1585 } 1633 }
1586 1634
1587 void OmniboxViewWin::OnLButtonDblClk(UINT keys, const CPoint& point) { 1635 void OmniboxViewWin::OnLButtonDblClk(UINT keys, const CPoint& point) {
1588 // Save the double click info for later triple-click detection. 1636 // Save the double click info for later triple-click detection.
1589 tracking_double_click_ = true; 1637 tracking_double_click_ = true;
1590 double_click_point_ = point; 1638 double_click_point_ = point;
1591 double_click_time_ = GetCurrentMessage()->time; 1639 double_click_time_ = GetCurrentMessage()->time;
1592 possible_drag_ = false; 1640 possible_drag_ = false;
1593 1641
1594 // Modifying the selection counts as accepting any inline autocompletion, so 1642 // Modifying the selection counts as accepting any inline autocompletion, so
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
1902 } 1950 }
1903 1951
1904 model()->OnSetFocus(GetKeyState(VK_CONTROL) < 0); 1952 model()->OnSetFocus(GetKeyState(VK_CONTROL) < 0);
1905 1953
1906 // Restore saved selection if available. 1954 // Restore saved selection if available.
1907 if (saved_selection_for_focus_change_.cpMin != -1) { 1955 if (saved_selection_for_focus_change_.cpMin != -1) {
1908 SetSelectionRange(saved_selection_for_focus_change_); 1956 SetSelectionRange(saved_selection_for_focus_change_);
1909 saved_selection_for_focus_change_.cpMin = -1; 1957 saved_selection_for_focus_change_.cpMin = -1;
1910 } 1958 }
1911 1959
1912 SetMsgHandled(false); 1960 if (!base::win::IsTsfAwareRequired()) {
1961 SetMsgHandled(false);
1962 } else {
1963 DefWindowProc();
1964 // Document manager created by RichEdit can be obtained only after
1965 // WM_SETFOCUS event is handled.
1966 tsf_event_router_->SetManager(
1967 ui::TsfBridge::GetInstance()->GetThreadManager());
1968 SetMsgHandled(true);
1969 }
1913 } 1970 }
1914 1971
1915 LRESULT OmniboxViewWin::OnSetText(const wchar_t* text) { 1972 LRESULT OmniboxViewWin::OnSetText(const wchar_t* text) {
1916 // Ignore all IME messages while we process this WM_SETTEXT message. 1973 // Ignore all IME messages while we process this WM_SETTEXT message.
1917 // When SetWindowText() is called while an IME is composing text, the IME 1974 // When SetWindowText() is called while an IME is composing text, the IME
1918 // calls SendMessage() to send a WM_IME_COMPOSITION message. When we receive 1975 // calls SendMessage() to send a WM_IME_COMPOSITION message. When we receive
1919 // this WM_IME_COMPOSITION message, we update the omnibox and may call 1976 // this WM_IME_COMPOSITION message, we update the omnibox and may call
1920 // SetWindowText() again. To stop this recursive message-handler call, we 1977 // SetWindowText() again. To stop this recursive message-handler call, we
1921 // stop updating the omnibox while we process a WM_SETTEXT message. 1978 // stop updating the omnibox while we process a WM_SETTEXT message.
1922 // We wouldn't need to do this update anyway, because either we're in the 1979 // We wouldn't need to do this update anyway, because either we're in the
(...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after
2702 return (rect.left - client_rect.left) + (client_rect.right - rect.right); 2759 return (rect.left - client_rect.left) + (client_rect.right - rect.right);
2703 } 2760 }
2704 2761
2705 int OmniboxViewWin::WidthNeededToDisplay(const string16& text) const { 2762 int OmniboxViewWin::WidthNeededToDisplay(const string16& text) const {
2706 // Use font_.GetStringWidth() instead of 2763 // Use font_.GetStringWidth() instead of
2707 // PosFromChar(location_entry_->GetTextLength()) because PosFromChar() is 2764 // PosFromChar(location_entry_->GetTextLength()) because PosFromChar() is
2708 // apparently buggy. In both LTR UI and RTL UI with left-to-right layout, 2765 // apparently buggy. In both LTR UI and RTL UI with left-to-right layout,
2709 // PosFromChar(i) might return 0 when i is greater than 1. 2766 // PosFromChar(i) might return 0 when i is greater than 1.
2710 return font_.GetStringWidth(text) + GetHorizontalMargin(); 2767 return font_.GetStringWidth(text) + GetHorizontalMargin();
2711 } 2768 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698