Index: ui/views/win/hwnd_message_handler.cc |
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc |
index 4f9ad05241a7b18d9d93f493d1c6567bb57c47e5..5bcf08d967cac3c41119bb98e256062c1aec227a 100644 |
--- a/ui/views/win/hwnd_message_handler.cc |
+++ b/ui/views/win/hwnd_message_handler.cc |
@@ -21,8 +21,14 @@ |
#include "base/threading/thread_task_runner_handle.h" |
#include "base/time/time.h" |
#include "base/trace_event/trace_event.h" |
+#include "base/win/scoped_comptr.h" |
#include "base/win/scoped_gdi_object.h" |
#include "base/win/windows_version.h" |
+#include "ui/accessibility/platform/ax_fake_caret_win.h" |
+#include "ui/accessibility/platform/ax_platform_node_win.h" |
+#include "ui/base/ime/input_method.h" |
+#include "ui/base/ime/text_input_client.h" |
+#include "ui/base/ime/text_input_type.h" |
#include "ui/base/view_prop.h" |
#include "ui/base/win/internal_constants.h" |
#include "ui/base/win/lock_state.h" |
@@ -385,6 +391,7 @@ void HWNDMessageHandler::Init(HWND parent, const gfx::Rect& bounds) { |
prop_window_target_.reset(new ui::ViewProp(hwnd(), |
ui::WindowEventTarget::kWin32InputEventTarget, |
static_cast<ui::WindowEventTarget*>(this))); |
+ delegate_->AddInputMethodObserver(this); |
// Direct Manipulation is enabled on Windows 10+. The CreateInstance function |
// returns NULL if Direct Manipulation is not available. |
@@ -929,6 +936,8 @@ LRESULT HWNDMessageHandler::OnWndProc(UINT message, |
delegate_->PostHandleMSG(message, w_param, l_param); |
if (message == WM_NCDESTROY) { |
RestoreEnabledIfNecessary(); |
+ delegate_->RemoveInputMethodObserver(this); |
+ ax_fake_caret_ = nullptr; |
delegate_->HandleDestroyed(); |
} |
} |
@@ -939,6 +948,37 @@ LRESULT HWNDMessageHandler::OnWndProc(UINT message, |
return result; |
} |
+void HWNDMessageHandler::OnCaretBoundsChanged( |
+ const ui::TextInputClient* client) { |
+ if (!client || client->GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE || |
+ !ax_fake_caret_) { |
+ return; |
+ } |
+ |
+ const gfx::Rect dip_caret_bounds(client->GetCaretBounds()); |
+ gfx::Rect caret_bounds = |
+ display::win::ScreenWin::DIPToScreenRect(hwnd(), dip_caret_bounds); |
+ // Collapse any selection. |
+ caret_bounds.set_width(1); |
+ ax_fake_caret_->MoveCaretTo(caret_bounds); |
+} |
+ |
+void HWNDMessageHandler::OnTextInputTypeChanged( |
+ const ui::TextInputClient* client) { |
+ if (!client || client->GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) { |
+ ax_fake_caret_ = nullptr; |
+ LOG(ERROR) << "Destroying caret"; |
+ return; |
+ } |
+ LOG(ERROR) << "Creating new caret"; |
+ ax_fake_caret_ = std::make_unique<ui::AXFakeCaretWin>(hwnd()); |
+} |
+ |
+void HWNDMessageHandler::OnInputMethodDestroyed( |
+ const ui::InputMethod* input_method) { |
+ ax_fake_caret_ = nullptr; |
+} |
+ |
LRESULT HWNDMessageHandler::HandleMouseMessage(unsigned int message, |
WPARAM w_param, |
LPARAM l_param, |
@@ -1523,10 +1563,14 @@ LRESULT HWNDMessageHandler::OnGetObject(UINT message, |
// Retrieve MSAA dispatch object for the root view. |
base::win::ScopedComPtr<IAccessible> root( |
delegate_->GetNativeViewAccessible()); |
- |
- // Create a reference that MSAA will marshall to the client. |
reference_result = LresultFromObject(IID_IAccessible, w_param, |
static_cast<IAccessible*>(root.Detach())); |
+ } else if (::GetFocus() == hwnd() && ax_fake_caret_ && |
+ static_cast<DWORD>(OBJID_CARET) == obj_id) { |
+ base::win::ScopedComPtr<IAccessible> fake_caret_accessible = |
+ ax_fake_caret_->GetCaret(); |
+ reference_result = LresultFromObject(IID_IAccessible, w_param, |
+ fake_caret_accessible.Detach()); |
} |
return reference_result; |