 Chromium Code Reviews
 Chromium Code Reviews Issue 2852763002:
  Added a system caret used for accessibility on Windows.  (Closed)
    
  
    Issue 2852763002:
  Added a system caret used for accessibility on Windows.  (Closed) 
  | OLD | NEW | 
|---|---|
| 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 "ui/views/win/hwnd_message_handler.h" | 5 #include "ui/views/win/hwnd_message_handler.h" | 
| 6 | 6 | 
| 7 #include <dwmapi.h> | 7 #include <dwmapi.h> | 
| 8 #include <oleacc.h> | 8 #include <oleacc.h> | 
| 9 #include <shellapi.h> | 9 #include <shellapi.h> | 
| 10 #include <tchar.h> | 10 #include <tchar.h> | 
| 11 | 11 | 
| 12 #include <utility> | 12 #include <utility> | 
| 13 | 13 | 
| 14 #include "base/bind.h" | 14 #include "base/bind.h" | 
| 15 #include "base/bind_helpers.h" | 15 #include "base/bind_helpers.h" | 
| 16 #include "base/debug/alias.h" | 16 #include "base/debug/alias.h" | 
| 17 #include "base/location.h" | 17 #include "base/location.h" | 
| 18 #include "base/macros.h" | 18 #include "base/macros.h" | 
| 19 #include "base/single_thread_task_runner.h" | 19 #include "base/single_thread_task_runner.h" | 
| 20 #include "base/threading/thread_task_runner_handle.h" | 20 #include "base/threading/thread_task_runner_handle.h" | 
| 21 #include "base/time/time.h" | 21 #include "base/time/time.h" | 
| 22 #include "base/trace_event/trace_event.h" | 22 #include "base/trace_event/trace_event.h" | 
| 23 #include "base/win/scoped_comptr.h" | |
| 23 #include "base/win/scoped_gdi_object.h" | 24 #include "base/win/scoped_gdi_object.h" | 
| 24 #include "base/win/windows_version.h" | 25 #include "base/win/windows_version.h" | 
| 26 #include "ui/accessibility/platform/ax_fake_caret_win.h" | |
| 27 #include "ui/accessibility/platform/ax_platform_node_win.h" | |
| 28 #include "ui/base/ime/input_method.h" | |
| 29 #include "ui/base/ime/text_input_client.h" | |
| 30 #include "ui/base/ime/text_input_type.h" | |
| 25 #include "ui/base/view_prop.h" | 31 #include "ui/base/view_prop.h" | 
| 26 #include "ui/base/win/internal_constants.h" | 32 #include "ui/base/win/internal_constants.h" | 
| 27 #include "ui/base/win/lock_state.h" | 33 #include "ui/base/win/lock_state.h" | 
| 28 #include "ui/base/win/mouse_wheel_util.h" | 34 #include "ui/base/win/mouse_wheel_util.h" | 
| 29 #include "ui/base/win/shell.h" | 35 #include "ui/base/win/shell.h" | 
| 30 #include "ui/base/win/touch_input.h" | 36 #include "ui/base/win/touch_input.h" | 
| 31 #include "ui/display/win/dpi.h" | 37 #include "ui/display/win/dpi.h" | 
| 32 #include "ui/display/win/screen_win.h" | 38 #include "ui/display/win/screen_win.h" | 
| 33 #include "ui/events/event.h" | 39 #include "ui/events/event.h" | 
| 34 #include "ui/events/event_constants.h" | 40 #include "ui/events/event_constants.h" | 
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 377 GetProcAddress(GetModuleHandle(L"user32.dll"), | 383 GetProcAddress(GetModuleHandle(L"user32.dll"), | 
| 378 "EnableChildWindowDpiMessage")); | 384 "EnableChildWindowDpiMessage")); | 
| 379 }(); | 385 }(); | 
| 380 if (enable_child_window_dpi_message_func) | 386 if (enable_child_window_dpi_message_func) | 
| 381 enable_child_window_dpi_message_func(hwnd(), TRUE); | 387 enable_child_window_dpi_message_func(hwnd(), TRUE); | 
| 382 } | 388 } | 
| 383 | 389 | 
| 384 prop_window_target_.reset(new ui::ViewProp(hwnd(), | 390 prop_window_target_.reset(new ui::ViewProp(hwnd(), | 
| 385 ui::WindowEventTarget::kWin32InputEventTarget, | 391 ui::WindowEventTarget::kWin32InputEventTarget, | 
| 386 static_cast<ui::WindowEventTarget*>(this))); | 392 static_cast<ui::WindowEventTarget*>(this))); | 
| 393 delegate_->AddInputMethodObserver(*this); | |
| 387 | 394 | 
| 388 // Direct Manipulation is enabled on Windows 10+. The CreateInstance function | 395 // Direct Manipulation is enabled on Windows 10+. The CreateInstance function | 
| 389 // returns NULL if Direct Manipulation is not available. | 396 // returns NULL if Direct Manipulation is not available. | 
| 390 direct_manipulation_helper_ = | 397 direct_manipulation_helper_ = | 
| 391 gfx::win::DirectManipulationHelper::CreateInstance(); | 398 gfx::win::DirectManipulationHelper::CreateInstance(); | 
| 392 if (direct_manipulation_helper_) | 399 if (direct_manipulation_helper_) | 
| 393 direct_manipulation_helper_->Initialize(hwnd()); | 400 direct_manipulation_helper_->Initialize(hwnd()); | 
| 394 | 401 | 
| 395 // Disable pen flicks (http://crbug.com/506977) | 402 // Disable pen flicks (http://crbug.com/506977) | 
| 396 base::win::DisableFlicks(hwnd()); | 403 base::win::DisableFlicks(hwnd()); | 
| (...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 922 // DefWindowProc() may have destroyed the window and/or us in a nested | 929 // DefWindowProc() may have destroyed the window and/or us in a nested | 
| 923 // message loop. | 930 // message loop. | 
| 924 if (!ref || !::IsWindow(window)) | 931 if (!ref || !::IsWindow(window)) | 
| 925 return result; | 932 return result; | 
| 926 } | 933 } | 
| 927 | 934 | 
| 928 if (delegate_) { | 935 if (delegate_) { | 
| 929 delegate_->PostHandleMSG(message, w_param, l_param); | 936 delegate_->PostHandleMSG(message, w_param, l_param); | 
| 930 if (message == WM_NCDESTROY) { | 937 if (message == WM_NCDESTROY) { | 
| 931 RestoreEnabledIfNecessary(); | 938 RestoreEnabledIfNecessary(); | 
| 939 delegate_->RemoveInputMethodObserver(*this); | |
| 940 ax_fake_caret_ = nullptr; | |
| 932 delegate_->HandleDestroyed(); | 941 delegate_->HandleDestroyed(); | 
| 933 } | 942 } | 
| 934 } | 943 } | 
| 935 | 944 | 
| 936 if (message == WM_ACTIVATE && IsTopLevelWindow(window)) | 945 if (message == WM_ACTIVATE && IsTopLevelWindow(window)) | 
| 937 PostProcessActivateMessage(LOWORD(w_param), !!HIWORD(w_param), | 946 PostProcessActivateMessage(LOWORD(w_param), !!HIWORD(w_param), | 
| 938 reinterpret_cast<HWND>(l_param)); | 947 reinterpret_cast<HWND>(l_param)); | 
| 939 return result; | 948 return result; | 
| 940 } | 949 } | 
| 941 | 950 | 
| 951 void HWNDMessageHandler::OnCaretBoundsChanged( | |
| 952 const ui::TextInputClient* client) { | |
| 953 if (!client || client->GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) | |
| 954 return; | |
| 955 DCHECK(ax_fake_caret_); | |
| 956 const gfx::Rect dip_caret_bounds(client->GetCaretBounds()); | |
| 957 gfx::Rect caret_bounds = | |
| 958 display::win::ScreenWin::DIPToScreenRect(hwnd(), dip_caret_bounds); | |
| 959 // Collapse any selection. | |
| 960 caret_bounds.set_width(1); | |
| 961 ax_fake_caret_->MoveCaretTo(caret_bounds); | |
| 962 } | |
| 963 | |
| 964 void HWNDMessageHandler::OnTextInputStateChanged( | |
| 965 const ui::TextInputClient* client) { | |
| 966 if (!client || client->GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) | |
| 967 ax_fake_caret_ = nullptr; | |
| 968 ax_fake_caret_ = std::make_unique<ui::AXFakeCaretWin>(hwnd()); | |
| 969 } | |
| 970 | |
| 971 void HWNDMessageHandler::OnInputMethodDestroyed( | |
| 972 const ui::InputMethod* input_method) { | |
| 973 ax_fake_caret_ = nullptr; | |
| 974 } | |
| 975 | |
| 942 LRESULT HWNDMessageHandler::HandleMouseMessage(unsigned int message, | 976 LRESULT HWNDMessageHandler::HandleMouseMessage(unsigned int message, | 
| 943 WPARAM w_param, | 977 WPARAM w_param, | 
| 944 LPARAM l_param, | 978 LPARAM l_param, | 
| 945 bool* handled) { | 979 bool* handled) { | 
| 946 // Don't track forwarded mouse messages. We expect the caller to track the | 980 // Don't track forwarded mouse messages. We expect the caller to track the | 
| 947 // mouse. | 981 // mouse. | 
| 948 base::WeakPtr<HWNDMessageHandler> ref(weak_factory_.GetWeakPtr()); | 982 base::WeakPtr<HWNDMessageHandler> ref(weak_factory_.GetWeakPtr()); | 
| 949 LRESULT ret = HandleMouseEventInternal(message, w_param, l_param, false); | 983 LRESULT ret = HandleMouseEventInternal(message, w_param, l_param, false); | 
| 950 *handled = IsMsgHandled(); | 984 *handled = IsMsgHandled(); | 
| 951 return ret; | 985 return ret; | 
| (...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1514 | 1548 | 
| 1515 // Only the lower 32 bits of l_param are valid when checking the object id | 1549 // Only the lower 32 bits of l_param are valid when checking the object id | 
| 1516 // because it sometimes gets sign-extended incorrectly (but not always). | 1550 // because it sometimes gets sign-extended incorrectly (but not always). | 
| 1517 DWORD obj_id = static_cast<DWORD>(static_cast<DWORD_PTR>(l_param)); | 1551 DWORD obj_id = static_cast<DWORD>(static_cast<DWORD_PTR>(l_param)); | 
| 1518 | 1552 | 
| 1519 // Accessibility readers will send an OBJID_CLIENT message | 1553 // Accessibility readers will send an OBJID_CLIENT message | 
| 1520 if (static_cast<DWORD>(OBJID_CLIENT) == obj_id) { | 1554 if (static_cast<DWORD>(OBJID_CLIENT) == obj_id) { | 
| 1521 // Retrieve MSAA dispatch object for the root view. | 1555 // Retrieve MSAA dispatch object for the root view. | 
| 1522 base::win::ScopedComPtr<IAccessible> root( | 1556 base::win::ScopedComPtr<IAccessible> root( | 
| 1523 delegate_->GetNativeViewAccessible()); | 1557 delegate_->GetNativeViewAccessible()); | 
| 1524 | |
| 1525 // Create a reference that MSAA will marshall to the client. | |
| 1526 reference_result = LresultFromObject(IID_IAccessible, w_param, | 1558 reference_result = LresultFromObject(IID_IAccessible, w_param, | 
| 1527 static_cast<IAccessible*>(root.Detach())); | 1559 static_cast<IAccessible*>(root.Detach())); | 
| 1560 } else if (IsActive() && ax_fake_caret_ && | |
| 
dmazzoni
2017/05/02 06:55:23
IsActive won't work. Only top-level windows can be
 | |
| 1561 static_cast<DWORD>(OBJID_CARET) == obj_id) { | |
| 1562 base::win::ScopedComPtr<IAccessible> fake_caret_accessible = | |
| 1563 ax_fake_caret_->GetCaret(); | |
| 1564 reference_result = LresultFromObject(IID_IAccessible, w_param, | |
| 1565 fake_caret_accessible.Detach()); | |
| 1528 } | 1566 } | 
| 1529 | 1567 | 
| 1530 return reference_result; | 1568 return reference_result; | 
| 1531 } | 1569 } | 
| 1532 | 1570 | 
| 1533 LRESULT HWNDMessageHandler::OnImeMessages(UINT message, | 1571 LRESULT HWNDMessageHandler::OnImeMessages(UINT message, | 
| 1534 WPARAM w_param, | 1572 WPARAM w_param, | 
| 1535 LPARAM l_param) { | 1573 LPARAM l_param) { | 
| 1536 LRESULT result = 0; | 1574 LRESULT result = 0; | 
| 1537 base::WeakPtr<HWNDMessageHandler> ref(weak_factory_.GetWeakPtr()); | 1575 base::WeakPtr<HWNDMessageHandler> ref(weak_factory_.GetWeakPtr()); | 
| (...skipping 1364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2902 MONITORINFO monitor_info = {sizeof(monitor_info)}; | 2940 MONITORINFO monitor_info = {sizeof(monitor_info)}; | 
| 2903 GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY), | 2941 GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY), | 
| 2904 &monitor_info); | 2942 &monitor_info); | 
| 2905 gfx::Rect shrunk_rect(monitor_info.rcMonitor); | 2943 gfx::Rect shrunk_rect(monitor_info.rcMonitor); | 
| 2906 shrunk_rect.set_height(shrunk_rect.height() - 1); | 2944 shrunk_rect.set_height(shrunk_rect.height() - 1); | 
| 2907 background_fullscreen_hack_ = true; | 2945 background_fullscreen_hack_ = true; | 
| 2908 SetBoundsInternal(shrunk_rect, false); | 2946 SetBoundsInternal(shrunk_rect, false); | 
| 2909 } | 2947 } | 
| 2910 | 2948 | 
| 2911 } // namespace views | 2949 } // namespace views | 
| OLD | NEW |