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

Unified 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 side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698