Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: ui/views/win/hwnd_message_handler.cc

Issue 2852763002: Added a system caret used for accessibility on Windows. (Closed)
Patch Set: Added a fake caret for accessibility. Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/message_loop/message_loop.h" 19 #include "base/message_loop/message_loop.h"
20 #include "base/single_thread_task_runner.h" 20 #include "base/single_thread_task_runner.h"
21 #include "base/threading/thread_task_runner_handle.h" 21 #include "base/threading/thread_task_runner_handle.h"
22 #include "base/time/time.h" 22 #include "base/time/time.h"
23 #include "base/trace_event/trace_event.h" 23 #include "base/trace_event/trace_event.h"
24 #include "base/win/scoped_comptr.h"
24 #include "base/win/scoped_gdi_object.h" 25 #include "base/win/scoped_gdi_object.h"
25 #include "base/win/windows_version.h" 26 #include "base/win/windows_version.h"
27 #include "ui/accessibility/platform/ax_fake_caret_win.h"
28 #include "ui/accessibility/platform/ax_platform_node_win.h"
29 #include "ui/base/ime/input_method.h"
30 #include "ui/base/ime/text_input_client.h"
31 #include "ui/base/ime/text_input_type.h"
26 #include "ui/base/view_prop.h" 32 #include "ui/base/view_prop.h"
27 #include "ui/base/win/internal_constants.h" 33 #include "ui/base/win/internal_constants.h"
28 #include "ui/base/win/lock_state.h" 34 #include "ui/base/win/lock_state.h"
29 #include "ui/base/win/mouse_wheel_util.h" 35 #include "ui/base/win/mouse_wheel_util.h"
30 #include "ui/base/win/shell.h" 36 #include "ui/base/win/shell.h"
31 #include "ui/base/win/touch_input.h" 37 #include "ui/base/win/touch_input.h"
32 #include "ui/display/win/dpi.h" 38 #include "ui/display/win/dpi.h"
33 #include "ui/display/win/screen_win.h" 39 #include "ui/display/win/screen_win.h"
34 #include "ui/events/event.h" 40 #include "ui/events/event.h"
35 #include "ui/events/event_constants.h" 41 #include "ui/events/event_constants.h"
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 GetProcAddress(GetModuleHandle(L"user32.dll"), 384 GetProcAddress(GetModuleHandle(L"user32.dll"),
379 "EnableChildWindowDpiMessage")); 385 "EnableChildWindowDpiMessage"));
380 }(); 386 }();
381 if (enable_child_window_dpi_message_func) 387 if (enable_child_window_dpi_message_func)
382 enable_child_window_dpi_message_func(hwnd(), TRUE); 388 enable_child_window_dpi_message_func(hwnd(), TRUE);
383 } 389 }
384 390
385 prop_window_target_.reset(new ui::ViewProp(hwnd(), 391 prop_window_target_.reset(new ui::ViewProp(hwnd(),
386 ui::WindowEventTarget::kWin32InputEventTarget, 392 ui::WindowEventTarget::kWin32InputEventTarget,
387 static_cast<ui::WindowEventTarget*>(this))); 393 static_cast<ui::WindowEventTarget*>(this)));
394 delegate_->AddInputMethodObserver(this);
388 395
389 // Direct Manipulation is enabled on Windows 10+. The CreateInstance function 396 // Direct Manipulation is enabled on Windows 10+. The CreateInstance function
390 // returns NULL if Direct Manipulation is not available. 397 // returns NULL if Direct Manipulation is not available.
391 direct_manipulation_helper_ = 398 direct_manipulation_helper_ =
392 gfx::win::DirectManipulationHelper::CreateInstance(); 399 gfx::win::DirectManipulationHelper::CreateInstance();
393 if (direct_manipulation_helper_) 400 if (direct_manipulation_helper_)
394 direct_manipulation_helper_->Initialize(hwnd()); 401 direct_manipulation_helper_->Initialize(hwnd());
395 402
396 // Disable pen flicks (http://crbug.com/506977) 403 // Disable pen flicks (http://crbug.com/506977)
397 base::win::DisableFlicks(hwnd()); 404 base::win::DisableFlicks(hwnd());
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after
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);
sky 2017/06/19 15:00:14 Why do you need to remove the observer here? More
940 DestroyFakeCaret();
sky 2017/06/19 15:00:14 Similarly why does the fake care need to be destro
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
956 if (!ax_fake_caret_)
957 ax_fake_caret_ = std::make_unique<ui::AXFakeCaretWin>(hwnd());
958
959 const gfx::Rect dip_caret_bounds(client->GetCaretBounds());
960 gfx::Rect caret_bounds =
961 display::win::ScreenWin::DIPToScreenRect(hwnd(), dip_caret_bounds);
962 // Collapse any selection.
963 caret_bounds.set_width(1);
964 ax_fake_caret_->MoveCaretTo(caret_bounds);
965 }
966
967 void HWNDMessageHandler::OnTextInputTypeChanged(
968 const ui::TextInputClient* client) {
969 if (!client || client->GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) {
970 DestroyFakeCaret();
971 return;
972 }
973
974 OnCaretBoundsChanged(client);
975 }
976
977 void HWNDMessageHandler::OnInputMethodDestroyed(
978 const ui::InputMethod* input_method) {
979 DestroyFakeCaret();
980 }
981
942 LRESULT HWNDMessageHandler::HandleMouseMessage(unsigned int message, 982 LRESULT HWNDMessageHandler::HandleMouseMessage(unsigned int message,
943 WPARAM w_param, 983 WPARAM w_param,
944 LPARAM l_param, 984 LPARAM l_param,
945 bool* handled) { 985 bool* handled) {
946 // Don't track forwarded mouse messages. We expect the caller to track the 986 // Don't track forwarded mouse messages. We expect the caller to track the
947 // mouse. 987 // mouse.
948 base::WeakPtr<HWNDMessageHandler> ref(weak_factory_.GetWeakPtr()); 988 base::WeakPtr<HWNDMessageHandler> ref(weak_factory_.GetWeakPtr());
949 LRESULT ret = HandleMouseEventInternal(message, w_param, l_param, false); 989 LRESULT ret = HandleMouseEventInternal(message, w_param, l_param, false);
950 *handled = IsMsgHandled(); 990 *handled = IsMsgHandled();
951 return ret; 991 return ret;
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after
1516 1556
1517 // Only the lower 32 bits of l_param are valid when checking the object id 1557 // Only the lower 32 bits of l_param are valid when checking the object id
1518 // because it sometimes gets sign-extended incorrectly (but not always). 1558 // because it sometimes gets sign-extended incorrectly (but not always).
1519 DWORD obj_id = static_cast<DWORD>(static_cast<DWORD_PTR>(l_param)); 1559 DWORD obj_id = static_cast<DWORD>(static_cast<DWORD_PTR>(l_param));
1520 1560
1521 // Accessibility readers will send an OBJID_CLIENT message 1561 // Accessibility readers will send an OBJID_CLIENT message
1522 if (static_cast<DWORD>(OBJID_CLIENT) == obj_id) { 1562 if (static_cast<DWORD>(OBJID_CLIENT) == obj_id) {
1523 // Retrieve MSAA dispatch object for the root view. 1563 // Retrieve MSAA dispatch object for the root view.
1524 base::win::ScopedComPtr<IAccessible> root( 1564 base::win::ScopedComPtr<IAccessible> root(
1525 delegate_->GetNativeViewAccessible()); 1565 delegate_->GetNativeViewAccessible());
1526
1527 // Create a reference that MSAA will marshall to the client.
1528 reference_result = LresultFromObject(IID_IAccessible, w_param, 1566 reference_result = LresultFromObject(IID_IAccessible, w_param,
1529 static_cast<IAccessible*>(root.Detach())); 1567 static_cast<IAccessible*>(root.Detach()));
1568 } else if (::GetFocus() == hwnd() && ax_fake_caret_ &&
1569 static_cast<DWORD>(OBJID_CARET) == obj_id) {
1570 base::win::ScopedComPtr<IAccessible> fake_caret_accessible =
1571 ax_fake_caret_->GetCaret();
1572 reference_result = LresultFromObject(IID_IAccessible, w_param,
1573 fake_caret_accessible.Detach());
1530 } 1574 }
1531 1575
1532 return reference_result; 1576 return reference_result;
1533 } 1577 }
1534 1578
1535 LRESULT HWNDMessageHandler::OnImeMessages(UINT message, 1579 LRESULT HWNDMessageHandler::OnImeMessages(UINT message,
1536 WPARAM w_param, 1580 WPARAM w_param,
1537 LPARAM l_param) { 1581 LPARAM l_param) {
1538 LRESULT result = 0; 1582 LRESULT result = 0;
1539 base::WeakPtr<HWNDMessageHandler> ref(weak_factory_.GetWeakPtr()); 1583 base::WeakPtr<HWNDMessageHandler> ref(weak_factory_.GetWeakPtr());
(...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after
2243 // Ignore size/move/maximize in fullscreen mode. 2287 // Ignore size/move/maximize in fullscreen mode.
2244 if (IsFullscreen() && (((notification_code & sc_mask) == SC_SIZE) || 2288 if (IsFullscreen() && (((notification_code & sc_mask) == SC_SIZE) ||
2245 ((notification_code & sc_mask) == SC_MOVE) || 2289 ((notification_code & sc_mask) == SC_MOVE) ||
2246 ((notification_code & sc_mask) == SC_MAXIMIZE))) 2290 ((notification_code & sc_mask) == SC_MAXIMIZE)))
2247 return; 2291 return;
2248 if (delegate_->GetFrameMode() == FrameMode::CUSTOM_DRAWN) { 2292 if (delegate_->GetFrameMode() == FrameMode::CUSTOM_DRAWN) {
2249 if ((notification_code & sc_mask) == SC_MINIMIZE || 2293 if ((notification_code & sc_mask) == SC_MINIMIZE ||
2250 (notification_code & sc_mask) == SC_MAXIMIZE || 2294 (notification_code & sc_mask) == SC_MAXIMIZE ||
2251 (notification_code & sc_mask) == SC_RESTORE) { 2295 (notification_code & sc_mask) == SC_RESTORE) {
2252 delegate_->ResetWindowControls(); 2296 delegate_->ResetWindowControls();
2297 DestroyFakeCaret();
2253 } else if ((notification_code & sc_mask) == SC_MOVE || 2298 } else if ((notification_code & sc_mask) == SC_MOVE ||
2254 (notification_code & sc_mask) == SC_SIZE) { 2299 (notification_code & sc_mask) == SC_SIZE) {
2255 if (!IsVisible()) { 2300 if (!IsVisible()) {
2256 // Circumvent ScopedRedrawLocks and force visibility before entering a 2301 // Circumvent ScopedRedrawLocks and force visibility before entering a
2257 // resize or move modal loop to get continuous sizing/moving feedback. 2302 // resize or move modal loop to get continuous sizing/moving feedback.
2258 SetWindowLong(hwnd(), GWL_STYLE, 2303 SetWindowLong(hwnd(), GWL_STYLE,
2259 GetWindowLong(hwnd(), GWL_STYLE) | WS_VISIBLE); 2304 GetWindowLong(hwnd(), GWL_STYLE) | WS_VISIBLE);
2260 } 2305 }
2306 DestroyFakeCaret();
2261 } 2307 }
2262 } 2308 }
2263 2309
2264 // Handle SC_KEYMENU, which means that the user has pressed the ALT 2310 // Handle SC_KEYMENU, which means that the user has pressed the ALT
2265 // key and released it, so we should focus the menu bar. 2311 // key and released it, so we should focus the menu bar.
2266 if ((notification_code & sc_mask) == SC_KEYMENU && point.x() == 0) { 2312 if ((notification_code & sc_mask) == SC_KEYMENU && point.x() == 0) {
2267 int modifiers = ui::EF_NONE; 2313 int modifiers = ui::EF_NONE;
2268 if (ui::win::IsShiftPressed()) 2314 if (ui::win::IsShiftPressed())
2269 modifiers |= ui::EF_SHIFT_DOWN; 2315 modifiers |= ui::EF_SHIFT_DOWN;
2270 if (ui::win::IsCtrlPressed()) 2316 if (ui::win::IsCtrlPressed())
(...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after
2912 // not treat this like a fullscreen window. 2958 // not treat this like a fullscreen window.
2913 MONITORINFO monitor_info = {sizeof(monitor_info)}; 2959 MONITORINFO monitor_info = {sizeof(monitor_info)};
2914 GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY), 2960 GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY),
2915 &monitor_info); 2961 &monitor_info);
2916 gfx::Rect shrunk_rect(monitor_info.rcMonitor); 2962 gfx::Rect shrunk_rect(monitor_info.rcMonitor);
2917 shrunk_rect.set_height(shrunk_rect.height() - 1); 2963 shrunk_rect.set_height(shrunk_rect.height() - 1);
2918 background_fullscreen_hack_ = true; 2964 background_fullscreen_hack_ = true;
2919 SetBoundsInternal(shrunk_rect, false); 2965 SetBoundsInternal(shrunk_rect, false);
2920 } 2966 }
2921 2967
2968 void HWNDMessageHandler::DestroyFakeCaret() {
2969 ax_fake_caret_ = nullptr;
2970 }
2971
2922 } // namespace views 2972 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698