Commit f958e39a authored by shuchen's avatar shuchen Committed by Commit bot

Using input language instead of the application locale to determine the...

Using input language instead of the application locale to determine the Omnibox's text input type on Windows.

This cl contains a small refactoring of:
1) Changes GetInputLocale() to IsInputLocaleCJK(), so that the function would less likely to be abused.
2) Makes InputMethodBase to have empty implementations for OnInputLocaleChanged/IsInputLocaleCJK.

BUG=344834

Review-Url: https://codereview.chromium.org/2298123003
Cr-Commit-Position: refs/heads/master@{#417189}
parent 4506eb54
......@@ -101,30 +101,6 @@ OmniboxState::OmniboxState(const OmniboxEditModel::State& model_state,
OmniboxState::~OmniboxState() {
}
// Helpers --------------------------------------------------------------------
// We'd like to set the text input type to TEXT_INPUT_TYPE_URL, because this
// triggers URL-specific layout in software keyboards, e.g. adding top-level "/"
// and ".com" keys for English. However, this also causes IMEs to default to
// Latin character mode, which makes entering search queries difficult for IME
// users. Therefore, we try to guess whether an IME will be used based on the
// application language, and set the input type accordingly.
ui::TextInputType DetermineTextInputType() {
#if defined(OS_WIN)
DCHECK(g_browser_process);
const std::string& locale = g_browser_process->GetApplicationLocale();
const std::string& language = locale.substr(0, 2);
// Assume CJK + Thai users are using an IME.
if (language == "ja" ||
language == "ko" ||
language == "th" ||
language == "zh")
return ui::TEXT_INPUT_TYPE_SEARCH;
#endif
return ui::TEXT_INPUT_TYPE_URL;
}
} // namespace
......@@ -171,7 +147,7 @@ OmniboxViewViews::~OmniboxViewViews() {
void OmniboxViewViews::Init() {
set_controller(this);
SetTextInputType(DetermineTextInputType());
SetTextInputType(ui::TEXT_INPUT_TYPE_URL);
if (popup_window_mode_)
SetReadOnly(true);
......@@ -372,6 +348,26 @@ void OmniboxViewViews::ExecuteCommand(int command_id, int event_flags) {
}
}
ui::TextInputType OmniboxViewViews::GetTextInputType() const {
ui::TextInputType input_type = views::Textfield::GetTextInputType();
// We'd like to set the text input type to TEXT_INPUT_TYPE_URL, because this
// triggers URL-specific layout in software keyboards, e.g. adding top-level
// "/" and ".com" keys for English. However, this also causes IMEs to default
// to Latin character mode, which makes entering search queries difficult for
// IME users. Therefore, we try to guess whether an IME will be used based on
// the input language, and set the input type accordingly.
#if defined(OS_WIN)
if (input_type != ui::TEXT_INPUT_TYPE_NONE && location_bar_view_) {
ui::InputMethod* input_method =
location_bar_view_->GetWidget()->GetInputMethod();
if (input_method && input_method->IsInputLocaleCJK())
return ui::TEXT_INPUT_TYPE_SEARCH;
}
#endif
return input_type;
}
void OmniboxViewViews::SetTextAndSelectedRange(const base::string16& text,
const gfx::Range& range) {
SetText(text);
......
......@@ -103,6 +103,7 @@ class OmniboxViewViews
void OnPaint(gfx::Canvas* canvas) override;
void OnNativeThemeChanged(const ui::NativeTheme* theme) override;
void ExecuteCommand(int command_id, int event_flags) override;
ui::TextInputType GetTextInputType() const override;
private:
FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, CloseOmniboxPopupOnTextDrag);
......
......@@ -52,8 +52,8 @@ void DummyInputMethod::CancelComposition(const TextInputClient* client) {
void DummyInputMethod::OnInputLocaleChanged() {
}
std::string DummyInputMethod::GetInputLocale() {
return std::string();
bool DummyInputMethod::IsInputLocaleCJK() const {
return false;
}
TextInputType DummyInputMethod::GetTextInputType() const {
......
......@@ -31,7 +31,7 @@ class DummyInputMethod : public InputMethod {
void OnCaretBoundsChanged(const TextInputClient* client) override;
void CancelComposition(const TextInputClient* client) override;
void OnInputLocaleChanged() override;
std::string GetInputLocale() override;
bool IsInputLocaleCJK() const override;
TextInputType GetTextInputType() const override;
TextInputMode GetTextInputMode() const override;
int GetTextInputFlags() const override;
......
......@@ -125,9 +125,9 @@ class InputMethod {
// TODO(ime): Consider to take a parameter of TextInputClient.
virtual void OnInputLocaleChanged() = 0;
// Returns the locale of current keyboard layout or input method, as a BCP-47
// tag, or an empty string if the input method cannot provide it.
virtual std::string GetInputLocale() = 0;
// Returns whether the system input locale is in CJK languages.
// This is only used in Windows platforms.
virtual bool IsInputLocaleCJK() const = 0;
// TODO(yoichio): Following 3 methods(GetTextInputType, GetTextInputMode and
// CanComposeInline) calls client's same method and returns its value. It is
......
......@@ -49,12 +49,6 @@ void InputMethodAndroid::CancelComposition(
const ui::TextInputClient* client) {
}
void InputMethodAndroid::OnInputLocaleChanged() {}
std::string InputMethodAndroid::GetInputLocale() {
return "";
}
bool InputMethodAndroid::IsCandidatePopupOpen() const {
return false;
}
......
......@@ -23,8 +23,6 @@ class UI_BASE_IME_EXPORT InputMethodAndroid : public InputMethodBase {
void DispatchKeyEvent(ui::KeyEvent* event) override;
void OnCaretBoundsChanged(const TextInputClient* client) override;
void CancelComposition(const TextInputClient* client) override;
void OnInputLocaleChanged() override;
std::string GetInputLocale() override;
bool IsCandidatePopupOpen() const override;
DISALLOW_COPY_AND_ASSIGN(InputMethodAndroid);
......
......@@ -320,13 +320,6 @@ void InputMethodAuraLinux::ResetContext() {
composition_changed_ = false;
}
void InputMethodAuraLinux::OnInputLocaleChanged() {
}
std::string InputMethodAuraLinux::GetInputLocale() {
return "";
}
bool InputMethodAuraLinux::IsCandidatePopupOpen() const {
// There seems no way to detect candidate windows or any popups.
return false;
......
......@@ -33,8 +33,6 @@ class UI_BASE_IME_EXPORT InputMethodAuraLinux
void OnTextInputTypeChanged(const TextInputClient* client) override;
void OnCaretBoundsChanged(const TextInputClient* client) override;
void CancelComposition(const TextInputClient* client) override;
void OnInputLocaleChanged() override;
std::string GetInputLocale() override;
bool IsCandidatePopupOpen() const override;
// Overriden from ui::LinuxInputMethodContextDelegate
......
......@@ -65,6 +65,13 @@ void InputMethodBase::OnTextInputTypeChanged(const TextInputClient* client) {
NotifyTextInputStateChanged(client);
}
void InputMethodBase::OnInputLocaleChanged() {
}
bool InputMethodBase::IsInputLocaleCJK() const {
return false;
}
TextInputType InputMethodBase::GetTextInputType() const {
TextInputClient* client = GetTextInputClient();
return client ? client->GetTextInputType() : TEXT_INPUT_TYPE_NONE;
......
......@@ -47,6 +47,8 @@ class UI_BASE_IME_EXPORT InputMethodBase
// If a derived class overrides this method, it should call parent's
// implementation.
void OnTextInputTypeChanged(const TextInputClient* client) override;
void OnInputLocaleChanged() override;
bool IsInputLocaleCJK() const override;
TextInputType GetTextInputType() const override;
TextInputMode GetTextInputMode() const override;
......
......@@ -149,7 +149,7 @@ class MockInputMethodBase : public InputMethodBase {
void OnCaretBoundsChanged(const TextInputClient* client) override {}
void CancelComposition(const TextInputClient* client) override {}
void OnInputLocaleChanged() override {}
std::string GetInputLocale() override { return ""; }
bool IsInputLocaleCJK() const override { return false; }
bool IsCandidatePopupOpen() const override { return false; }
// Overriden from InputMethodBase.
void OnWillChangeFocusedClient(TextInputClient* focused_before,
......
......@@ -231,15 +231,6 @@ void InputMethodChromeOS::CancelComposition(const TextInputClient* client) {
ResetContext();
}
void InputMethodChromeOS::OnInputLocaleChanged() {
// Not supported.
}
std::string InputMethodChromeOS::GetInputLocale() {
// Not supported.
return "";
}
bool InputMethodChromeOS::IsCandidatePopupOpen() const {
// TODO(yukishiino): Implement this method.
return false;
......
......@@ -34,8 +34,6 @@ class UI_BASE_IME_EXPORT InputMethodChromeOS : public InputMethodBase {
void OnTextInputTypeChanged(const TextInputClient* client) override;
void OnCaretBoundsChanged(const TextInputClient* client) override;
void CancelComposition(const TextInputClient* client) override;
void OnInputLocaleChanged() override;
std::string GetInputLocale() override;
bool IsCandidatePopupOpen() const override;
protected:
......
......@@ -344,11 +344,6 @@ class InputMethodChromeOSTest : public internal::InputMethodDelegate,
// Tests public APIs in ui::InputMethod first.
TEST_F(InputMethodChromeOSTest, GetInputLocale) {
// ui::InputMethodChromeOS does not support the API.
EXPECT_EQ("", ime_->GetInputLocale());
}
TEST_F(InputMethodChromeOSTest, GetInputTextType) {
EXPECT_EQ(TEXT_INPUT_TYPE_NONE, ime_->GetTextInputType());
input_type_ = TEXT_INPUT_TYPE_PASSWORD;
......
......@@ -25,8 +25,6 @@ class UI_BASE_IME_EXPORT InputMethodMac : public InputMethodBase {
void DispatchKeyEvent(ui::KeyEvent* event) override;
void OnCaretBoundsChanged(const TextInputClient* client) override;
void CancelComposition(const TextInputClient* client) override;
void OnInputLocaleChanged() override;
std::string GetInputLocale() override;
bool IsCandidatePopupOpen() const override;
private:
......
......@@ -29,13 +29,6 @@ void InputMethodMac::OnCaretBoundsChanged(const TextInputClient* client) {
void InputMethodMac::CancelComposition(const TextInputClient* client) {
}
void InputMethodMac::OnInputLocaleChanged() {
}
std::string InputMethodMac::GetInputLocale() {
return "";
}
bool InputMethodMac::IsCandidatePopupOpen() const {
// There seems to be no way to tell if a candidate window is open.
return false;
......
......@@ -49,12 +49,6 @@ void InputMethodMinimal::OnCaretBoundsChanged(const TextInputClient* client) {}
void InputMethodMinimal::CancelComposition(const TextInputClient* client) {}
void InputMethodMinimal::OnInputLocaleChanged() {}
std::string InputMethodMinimal::GetInputLocale() {
return std::string();
}
bool InputMethodMinimal::IsCandidatePopupOpen() const {
return false;
}
......
......@@ -23,8 +23,6 @@ class UI_BASE_IME_EXPORT InputMethodMinimal : public InputMethodBase {
void DispatchKeyEvent(ui::KeyEvent* event) override;
void OnCaretBoundsChanged(const TextInputClient* client) override;
void CancelComposition(const TextInputClient* client) override;
void OnInputLocaleChanged() override;
std::string GetInputLocale() override;
bool IsCandidatePopupOpen() const override;
private:
......
......@@ -267,12 +267,18 @@ void InputMethodWin::CancelComposition(const TextInputClient* client) {
}
void InputMethodWin::OnInputLocaleChanged() {
// Note: OnInputLocaleChanged() is for crbug.com/168971.
// Note: OnInputLocaleChanged() is for capturing the input language which can
// be used to determine the appropriate TextInputType for Omnibox.
// See crbug.com/344834.
// Currently OnInputLocaleChanged() on Windows relies on WM_INPUTLANGCHANGED,
// which is known to be incompatible with TSF.
// TODO(shuchen): Use ITfLanguageProfileNotifySink instead.
OnInputMethodChanged();
imm32_manager_.SetInputLanguage();
}
std::string InputMethodWin::GetInputLocale() {
return imm32_manager_.GetInputLanguageName();
bool InputMethodWin::IsInputLocaleCJK() const {
return imm32_manager_.IsInputLanguageCJK();
}
bool InputMethodWin::IsCandidatePopupOpen() const {
......
......@@ -31,7 +31,7 @@ class UI_BASE_IME_EXPORT InputMethodWin : public InputMethodBase {
void OnCaretBoundsChanged(const TextInputClient* client) override;
void CancelComposition(const TextInputClient* client) override;
void OnInputLocaleChanged() override;
std::string GetInputLocale() override;
bool IsInputLocaleCJK() const override;
bool IsCandidatePopupOpen() const override;
protected:
......
......@@ -80,8 +80,8 @@ void MockInputMethod::CancelComposition(const TextInputClient* client) {
void MockInputMethod::OnInputLocaleChanged() {
}
std::string MockInputMethod::GetInputLocale() {
return "";
bool MockInputMethod::IsInputLocaleCJK() const {
return false;
}
TextInputType MockInputMethod::GetTextInputType() const {
......
......@@ -43,7 +43,7 @@ class UI_BASE_IME_EXPORT MockInputMethod
void OnCaretBoundsChanged(const TextInputClient* client) override;
void CancelComposition(const TextInputClient* client) override;
void OnInputLocaleChanged() override;
std::string GetInputLocale() override;
bool IsInputLocaleCJK() const override;
TextInputType GetTextInputType() const override;
TextInputMode GetTextInputMode() const override;
int GetTextInputFlags() const override;
......
......@@ -124,13 +124,19 @@ IMM32Manager::~IMM32Manager() {
}
void IMM32Manager::SetInputLanguage() {
// Retrieve the current keyboard layout from Windows and determine whether
// or not the current input context has IMEs.
// Also save its input language for language-specific operations required
// while composing a text.
HKL keyboard_layout = ::GetKeyboardLayout(0);
input_language_id_ =
static_cast<LANGID>(reinterpret_cast<uintptr_t>(keyboard_layout));
// Retrieve the current input language from the system's keyboard layout.
// Using GetKeyboardLayoutName instead of GetKeyboardLayout, because
// the language from GetKeyboardLayout is the language under where the
// keyboard layout is installed. And the language from GetKeyboardLayoutName
// indicates the language of the keyboard layout itself.
// See crbug.com/344834.
WCHAR keyboard_layout[KL_NAMELENGTH];
if (::GetKeyboardLayoutNameW(keyboard_layout)) {
input_language_id_ =
static_cast<LANGID>(_wtoi(&keyboard_layout[KL_NAMELENGTH >> 1]));
} else {
input_language_id_ = 0x0409; // Fallback to en-US.
}
}
void IMM32Manager::CreateImeWindow(HWND window_handle) {
......@@ -457,31 +463,10 @@ void IMM32Manager::SetUseCompositionWindow(bool use_composition_window) {
use_composition_window_ = use_composition_window;
}
std::string IMM32Manager::GetInputLanguageName() const {
const LCID locale_id = MAKELCID(input_language_id_, SORT_DEFAULT);
// max size for LOCALE_SISO639LANGNAME and LOCALE_SISO3166CTRYNAME is 9.
wchar_t buffer[9];
// Get language id.
int length = ::GetLocaleInfo(locale_id, LOCALE_SISO639LANGNAME, &buffer[0],
arraysize(buffer));
if (length <= 1)
return std::string();
std::string language;
base::WideToUTF8(buffer, length - 1, &language);
if (SUBLANGID(input_language_id_) == SUBLANG_NEUTRAL)
return language;
// Get region id.
length = ::GetLocaleInfo(locale_id, LOCALE_SISO3166CTRYNAME, &buffer[0],
arraysize(buffer));
if (length <= 1)
return language;
std::string region;
base::WideToUTF8(buffer, length - 1, &region);
return language.append(1, '-').append(region);
bool IMM32Manager::IsInputLanguageCJK() const {
LANGID lang = PRIMARYLANGID(input_language_id_);
return lang == LANG_CHINESE || lang == LANG_JAPANESE ||
lang == LANG_KOREAN;
}
void IMM32Manager::SetTextInputMode(HWND window_handle,
......
......@@ -229,8 +229,8 @@ class UI_BASE_IME_EXPORT IMM32Manager {
// Returns the current input language id.
LANGID input_language_id() const { return input_language_id_; }
// Returns BCP-47 tag name of the current input language.
std::string GetInputLanguageName() const;
// Returns whether the system's input language is CJK.
bool IsInputLanguageCJK() const;
// Sets conversion status corresponding to |input_mode|.
virtual void SetTextInputMode(HWND window_handle, TextInputMode input_mode);
......
......@@ -83,8 +83,6 @@ class MockInputMethod : public ui::InputMethodBase {
void OnTextInputTypeChanged(const ui::TextInputClient* client) override;
void OnCaretBoundsChanged(const ui::TextInputClient* client) override {}
void CancelComposition(const ui::TextInputClient* client) override;
void OnInputLocaleChanged() override {}
std::string GetInputLocale() override;
bool IsCandidatePopupOpen() const override;
void ShowImeIfNeeded() override {}
......@@ -211,10 +209,6 @@ void MockInputMethod::CancelComposition(const ui::TextInputClient* client) {
}
}
std::string MockInputMethod::GetInputLocale() {
return "en-US";
}
bool MockInputMethod::IsCandidatePopupOpen() const {
return false;
}
......
......@@ -102,12 +102,6 @@ void InputMethodMus::OnInputLocaleChanged() {
// whether we want to support this or not.
}
std::string InputMethodMus::GetInputLocale() {
// TODO(moshayedi): crbug.com/637418. Not supported in ChromeOS. Investigate
// whether we want to support this or not.
return std::string();
}
bool InputMethodMus::IsCandidatePopupOpen() const {
// TODO(moshayedi): crbug.com/637416. Implement this properly when we have a
// mean for displaying candidate list popup.
......
......@@ -39,7 +39,6 @@ class VIEWS_MUS_EXPORT InputMethodMus : public ui::InputMethodBase {
void OnCaretBoundsChanged(const ui::TextInputClient* client) override;
void CancelComposition(const ui::TextInputClient* client) override;
void OnInputLocaleChanged() override;
std::string GetInputLocale() override;
bool IsCandidatePopupOpen() const override;
private:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment