Chromium Code Reviews| 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..6e4a297ec6ad99a2aa6690f9e099ed04aa18f632 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); |
|
sky
2017/06/19 15:00:14
Why do you need to remove the observer here? More
|
| + DestroyFakeCaret(); |
|
sky
2017/06/19 15:00:14
Similarly why does the fake care need to be destro
|
| 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) |
| + return; |
| + |
| + if (!ax_fake_caret_) |
| + ax_fake_caret_ = std::make_unique<ui::AXFakeCaretWin>(hwnd()); |
| + |
| + 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) { |
| + DestroyFakeCaret(); |
| + return; |
| + } |
| + |
| + OnCaretBoundsChanged(client); |
| +} |
| + |
| +void HWNDMessageHandler::OnInputMethodDestroyed( |
| + const ui::InputMethod* input_method) { |
| + DestroyFakeCaret(); |
| +} |
| + |
| 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; |
| @@ -2250,6 +2294,7 @@ void HWNDMessageHandler::OnSysCommand(UINT notification_code, |
| (notification_code & sc_mask) == SC_MAXIMIZE || |
| (notification_code & sc_mask) == SC_RESTORE) { |
| delegate_->ResetWindowControls(); |
| + DestroyFakeCaret(); |
| } else if ((notification_code & sc_mask) == SC_MOVE || |
| (notification_code & sc_mask) == SC_SIZE) { |
| if (!IsVisible()) { |
| @@ -2258,6 +2303,7 @@ void HWNDMessageHandler::OnSysCommand(UINT notification_code, |
| SetWindowLong(hwnd(), GWL_STYLE, |
| GetWindowLong(hwnd(), GWL_STYLE) | WS_VISIBLE); |
| } |
| + DestroyFakeCaret(); |
| } |
| } |
| @@ -2919,4 +2965,8 @@ void HWNDMessageHandler::OnBackgroundFullscreen() { |
| SetBoundsInternal(shrunk_rect, false); |
| } |
| +void HWNDMessageHandler::DestroyFakeCaret() { |
| + ax_fake_caret_ = nullptr; |
| +} |
| + |
| } // namespace views |