Commit fe7e213c authored by Siye Liu's avatar Siye Liu Committed by Commit Bot

Notify input method about input type change in omnibox during CJK IME

On Windows platform, omnibox has a special handling that if the input
method is Chinese, Japanese or Korean, then the input type of is changed
to TEXT_INPUT_TYPE_SEARCH. We should notify input mothod that the input
type has been changed.

Bug: 1108845
Change-Id: I0266d9617277696ccb8bfa42ad76f9cbc3d802f3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2314686
Commit-Queue: Siye Liu <siliu@microsoft.com>
Reviewed-by: default avatarMichael Wasserman <msw@chromium.org>
Reviewed-by: default avatarYohei Yukawa <yukawa@chromium.org>
Cr-Commit-Position: refs/heads/master@{#791443}
parent c1f75b24
...@@ -657,23 +657,23 @@ void OmniboxViewViews::ExecuteCommand(int command_id, int event_flags) { ...@@ -657,23 +657,23 @@ void OmniboxViewViews::ExecuteCommand(int command_id, int event_flags) {
} }
} }
ui::TextInputType OmniboxViewViews::GetTextInputType() const { void OmniboxViewViews::OnInputMethodChanged() {
ui::TextInputType input_type = views::Textfield::GetTextInputType(); #if defined(OS_WIN)
// We'd like to set the text input type to TEXT_INPUT_TYPE_URL, because this // 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 // triggers URL-specific layout in software keyboards, e.g. adding top-level
// "/" and ".com" keys for English. However, this also causes IMEs to default // "/" and ".com" keys for English. However, this also causes IMEs to default
// to Latin character mode, which makes entering search queries difficult for // 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 // IME users. Therefore, we try to guess whether an IME will be used based on
// the input language, and set the input type accordingly. // the input language, and set the input type accordingly.
#if defined(OS_WIN) if (location_bar_view_) {
if (input_type != ui::TEXT_INPUT_TYPE_NONE && location_bar_view_) {
ui::InputMethod* input_method = ui::InputMethod* input_method =
location_bar_view_->GetWidget()->GetInputMethod(); location_bar_view_->GetWidget()->GetInputMethod();
if (input_method && input_method->IsInputLocaleCJK()) if (input_method && input_method->IsInputLocaleCJK())
return ui::TEXT_INPUT_TYPE_SEARCH; SetTextInputType(ui::TEXT_INPUT_TYPE_SEARCH);
else
SetTextInputType(ui::TEXT_INPUT_TYPE_URL);
} }
#endif #endif
return input_type;
} }
void OmniboxViewViews::AddedToWidget() { void OmniboxViewViews::AddedToWidget() {
......
...@@ -148,7 +148,7 @@ class OmniboxViewViews : public OmniboxView, ...@@ -148,7 +148,7 @@ class OmniboxViewViews : public OmniboxView,
void OnMouseReleased(const ui::MouseEvent& event) override; void OnMouseReleased(const ui::MouseEvent& event) override;
void OnPaint(gfx::Canvas* canvas) override; void OnPaint(gfx::Canvas* canvas) override;
void ExecuteCommand(int command_id, int event_flags) override; void ExecuteCommand(int command_id, int event_flags) override;
ui::TextInputType GetTextInputType() const override; void OnInputMethodChanged() override;
void AddedToWidget() override; void AddedToWidget() override;
void RemovedFromWidget() override; void RemovedFromWidget() override;
base::string16 GetLabelForCommandId(int command_id) const override; base::string16 GetLabelForCommandId(int command_id) const override;
......
...@@ -38,7 +38,9 @@ ...@@ -38,7 +38,9 @@
#include "ui/accessibility/ax_node_data.h" #include "ui/accessibility/ax_node_data.h"
#include "ui/base/clipboard/clipboard.h" #include "ui/base/clipboard/clipboard.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h" #include "ui/base/clipboard/scoped_clipboard_writer.h"
#include "ui/base/ime/init/input_method_factory.h"
#include "ui/base/ime/input_method.h" #include "ui/base/ime/input_method.h"
#include "ui/base/ime/mock_input_method.h"
#include "ui/base/ime/text_edit_commands.h" #include "ui/base/ime/text_edit_commands.h"
#include "ui/base/ime/text_input_client.h" #include "ui/base/ime/text_input_client.h"
#include "ui/base/test/ui_controls.h" #include "ui/base/test/ui_controls.h"
...@@ -810,4 +812,55 @@ IN_PROC_BROWSER_TEST_F(OmniboxViewViewsUIATest, AccessibleOmnibox) { ...@@ -810,4 +812,55 @@ IN_PROC_BROWSER_TEST_F(OmniboxViewViewsUIATest, AccessibleOmnibox) {
close_waiter.Wait(); close_waiter.Wait();
EXPECT_FALSE(omnibox_view->model()->popup_model()->IsOpen()); EXPECT_FALSE(omnibox_view->model()->popup_model()->IsOpen());
} }
namespace {
// MockInputMethod ------------------------------------------------------------
class OmniBoxMockInputMethod : public ui::MockInputMethod {
public:
OmniBoxMockInputMethod() : ui::MockInputMethod(nullptr) {}
bool IsInputLocaleCJK() const override { return input_locale_cjk; }
void SetInputLocaleCJK(bool is_cjk) { input_locale_cjk = is_cjk; }
private:
bool input_locale_cjk = false;
};
} // namespace
class OmniboxViewViewsIMETest : public OmniboxViewViewsTest {
public:
OmniboxViewViewsIMETest() {}
void SetUp() override {
input_method_ = new OmniBoxMockInputMethod();
// transfers ownership.
ui::SetUpInputMethodForTesting(input_method_);
InProcessBrowserTest::SetUp();
}
protected:
void SetUpCommandLine(base::CommandLine* command_line) override {
OmniboxViewViewsTest::SetUpCommandLine(command_line);
command_line->AppendSwitch(switches::kEnableExperimentalUIAutomation);
}
OmniBoxMockInputMethod* input_method_ = nullptr;
};
IN_PROC_BROWSER_TEST_F(OmniboxViewViewsIMETest, TextInputTypeChangedTest) {
chrome::FocusLocationBar(browser());
OmniboxView* view = nullptr;
ASSERT_NO_FATAL_FAILURE(GetOmniboxViewForBrowser(browser(), &view));
OmniboxViewViews* omnibox_view_views = static_cast<OmniboxViewViews*>(view);
ui::InputMethod* input_method =
omnibox_view_views->GetWidget()->GetInputMethod();
EXPECT_EQ(input_method, input_method_);
EXPECT_EQ(ui::TEXT_INPUT_TYPE_URL, omnibox_view_views->GetTextInputType());
input_method_->SetInputLocaleCJK(/*is_cjk*/ true);
omnibox_view_views->OnInputMethodChanged();
EXPECT_EQ(ui::TEXT_INPUT_TYPE_SEARCH, omnibox_view_views->GetTextInputType());
input_method_->SetInputLocaleCJK(/*is_cjk*/ false);
omnibox_view_views->OnInputMethodChanged();
EXPECT_EQ(ui::TEXT_INPUT_TYPE_URL, omnibox_view_views->GetTextInputType());
}
#endif // OS_WIN #endif // OS_WIN
...@@ -111,6 +111,10 @@ class TSFBridgeImpl : public TSFBridge { ...@@ -111,6 +111,10 @@ class TSFBridgeImpl : public TSFBridge {
// An ITfThreadMgr object to be used in focus and document management. // An ITfThreadMgr object to be used in focus and document management.
Microsoft::WRL::ComPtr<ITfThreadMgr> thread_manager_; Microsoft::WRL::ComPtr<ITfThreadMgr> thread_manager_;
// An ITfInputProcessorProfiles object to be used to get current language
// locale profile.
Microsoft::WRL::ComPtr<ITfInputProcessorProfiles> input_processor_profiles_;
// A map from TextInputType to an editable document for TSF. We use multiple // A map from TextInputType to an editable document for TSF. We use multiple
// TSF documents that have different InputScopes and TSF attributes based on // TSF documents that have different InputScopes and TSF attributes based on
// the TextInputType associated with the target document. For a TextInputType // the TextInputType associated with the target document. For a TextInputType
...@@ -134,6 +138,9 @@ class TSFBridgeImpl : public TSFBridge { ...@@ -134,6 +138,9 @@ class TSFBridgeImpl : public TSFBridge {
// Handle to ITfKeyTraceEventSink. // Handle to ITfKeyTraceEventSink.
DWORD key_trace_sink_cookie_ = 0; DWORD key_trace_sink_cookie_ = 0;
// Handle to ITfLanguageProfileNotifySink
DWORD language_profile_cookie_ = 0;
DISALLOW_COPY_AND_ASSIGN(TSFBridgeImpl); DISALLOW_COPY_AND_ASSIGN(TSFBridgeImpl);
}; };
...@@ -149,6 +156,11 @@ TSFBridgeImpl::~TSFBridgeImpl() { ...@@ -149,6 +156,11 @@ TSFBridgeImpl::~TSFBridgeImpl() {
if (SUCCEEDED(thread_manager_->QueryInterface(IID_PPV_ARGS(&source)))) { if (SUCCEEDED(thread_manager_->QueryInterface(IID_PPV_ARGS(&source)))) {
source->UnadviseSink(key_trace_sink_cookie_); source->UnadviseSink(key_trace_sink_cookie_);
} }
Microsoft::WRL::ComPtr<ITfSource> language_source;
if (SUCCEEDED(input_processor_profiles_->QueryInterface(
IID_PPV_ARGS(&language_source)))) {
language_source->UnadviseSink(language_profile_cookie_);
}
} }
for (TSFDocumentMap::iterator it = tsf_document_map_.begin(); for (TSFDocumentMap::iterator it = tsf_document_map_.begin();
...@@ -173,6 +185,13 @@ bool TSFBridgeImpl::Initialize() { ...@@ -173,6 +185,13 @@ bool TSFBridgeImpl::Initialize() {
return false; return false;
} }
if (FAILED(::CoCreateInstance(CLSID_TF_InputProcessorProfiles, nullptr,
CLSCTX_ALL,
IID_PPV_ARGS(&input_processor_profiles_)))) {
DVLOG(1) << "Failed to create InputProcessorProfiles instance.";
return false;
}
if (FAILED(::CoCreateInstance(CLSID_TF_ThreadMgr, nullptr, CLSCTX_ALL, if (FAILED(::CoCreateInstance(CLSID_TF_ThreadMgr, nullptr, CLSCTX_ALL,
IID_PPV_ARGS(&thread_manager_)))) { IID_PPV_ARGS(&thread_manager_)))) {
DVLOG(1) << "Failed to create ThreadManager instance."; DVLOG(1) << "Failed to create ThreadManager instance.";
...@@ -421,6 +440,21 @@ bool TSFBridgeImpl::CreateDocumentManager(TSFTextStore* text_store, ...@@ -421,6 +440,21 @@ bool TSFBridgeImpl::CreateDocumentManager(TSFTextStore* text_store,
return false; return false;
} }
Microsoft::WRL::ComPtr<ITfSource> language_source;
if (FAILED(input_processor_profiles_->QueryInterface(
IID_PPV_ARGS(&language_source)))) {
DVLOG(1) << "Failed to get source_ITfInputProcessorProfiles.";
return false;
}
if (FAILED(
language_source->AdviseSink(IID_ITfLanguageProfileNotifySink,
static_cast<ITfTextEditSink*>(text_store),
&language_profile_cookie_))) {
DVLOG(1) << "AdviseSink for language profile notify sink failed.";
return false;
}
if (*source_cookie == TF_INVALID_COOKIE) { if (*source_cookie == TF_INVALID_COOKIE) {
DVLOG(1) << "The result of cookie is invalid."; DVLOG(1) << "The result of cookie is invalid.";
return false; return false;
......
...@@ -81,6 +81,8 @@ HRESULT TSFTextStore::QueryInterface(REFIID iid, void** result) { ...@@ -81,6 +81,8 @@ HRESULT TSFTextStore::QueryInterface(REFIID iid, void** result) {
*result = static_cast<ITextStoreACP*>(this); *result = static_cast<ITextStoreACP*>(this);
} else if (iid == IID_ITfContextOwnerCompositionSink) { } else if (iid == IID_ITfContextOwnerCompositionSink) {
*result = static_cast<ITfContextOwnerCompositionSink*>(this); *result = static_cast<ITfContextOwnerCompositionSink*>(this);
} else if (iid == IID_ITfLanguageProfileNotifySink) {
*result = static_cast<ITfLanguageProfileNotifySink*>(this);
} else if (iid == IID_ITfTextEditSink) { } else if (iid == IID_ITfTextEditSink) {
*result = static_cast<ITfTextEditSink*>(this); *result = static_cast<ITfTextEditSink*>(this);
} else if (iid == IID_ITfKeyTraceEventSink) { } else if (iid == IID_ITfKeyTraceEventSink) {
...@@ -841,6 +843,15 @@ HRESULT TSFTextStore::OnEndComposition(ITfCompositionView* composition_view) { ...@@ -841,6 +843,15 @@ HRESULT TSFTextStore::OnEndComposition(ITfCompositionView* composition_view) {
return S_OK; return S_OK;
} }
HRESULT TSFTextStore::OnLanguageChange(LANGID langid, BOOL* pfAccept) {
return S_OK;
}
HRESULT TSFTextStore::OnLanguageChanged() {
if (text_input_client_)
text_input_client_->OnInputMethodChanged();
return S_OK;
}
HRESULT TSFTextStore::OnKeyTraceDown(WPARAM wParam, LPARAM lParam) { HRESULT TSFTextStore::OnKeyTraceDown(WPARAM wParam, LPARAM lParam) {
// fire the event right away if we're in composition // fire the event right away if we're in composition
if (has_composition_range_) { if (has_composition_range_) {
......
...@@ -102,6 +102,7 @@ class TextInputClient; ...@@ -102,6 +102,7 @@ class TextInputClient;
class COMPONENT_EXPORT(UI_BASE_IME_WIN) TSFTextStore class COMPONENT_EXPORT(UI_BASE_IME_WIN) TSFTextStore
: public ITextStoreACP, : public ITextStoreACP,
public ITfContextOwnerCompositionSink, public ITfContextOwnerCompositionSink,
public ITfLanguageProfileNotifySink,
public ITfKeyTraceEventSink, public ITfKeyTraceEventSink,
public ITfTextEditSink { public ITfTextEditSink {
public: public:
...@@ -216,6 +217,10 @@ class COMPONENT_EXPORT(UI_BASE_IME_WIN) TSFTextStore ...@@ -216,6 +217,10 @@ class COMPONENT_EXPORT(UI_BASE_IME_WIN) TSFTextStore
IFACEMETHODIMP OnEndComposition( IFACEMETHODIMP OnEndComposition(
ITfCompositionView* composition_view) override; ITfCompositionView* composition_view) override;
// ITfLanguageProfileNotifySink:
IFACEMETHODIMP OnLanguageChange(LANGID langid, BOOL* pfAccept) override;
IFACEMETHODIMP OnLanguageChanged() override;
// ITfTextEditSink: // ITfTextEditSink:
IFACEMETHODIMP OnEndEdit(ITfContext* context, IFACEMETHODIMP OnEndEdit(ITfContext* context,
TfEditCookie read_only_edit_cookie, TfEditCookie read_only_edit_cookie,
......
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