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

Side by Side Diff: chrome/browser/ui/views/omnibox/omnibox_view_win.cc

Issue 8391010: Improve omnibox accessibility on Windows. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 1 month 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "chrome/browser/ui/views/omnibox/omnibox_view_win.h" 5 #include "chrome/browser/ui/views/omnibox/omnibox_view_win.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <locale> 8 #include <locale>
9 #include <string> 9 #include <string>
10 10
11 #include <richedit.h> 11 #include <richedit.h>
12 #include <textserv.h> 12 #include <textserv.h>
13 13
14 #include "base/auto_reset.h" 14 #include "base/auto_reset.h"
15 #include "base/basictypes.h" 15 #include "base/basictypes.h"
16 #include "base/i18n/rtl.h" 16 #include "base/i18n/rtl.h"
17 #include "base/lazy_instance.h" 17 #include "base/lazy_instance.h"
18 #include "base/memory/ref_counted.h" 18 #include "base/memory/ref_counted.h"
19 #include "base/string_util.h" 19 #include "base/string_util.h"
20 #include "base/utf_string_conversions.h" 20 #include "base/utf_string_conversions.h"
21 #include "base/win/iat_patch_function.h" 21 #include "base/win/iat_patch_function.h"
22 #include "chrome/app/chrome_command_ids.h" 22 #include "chrome/app/chrome_command_ids.h"
23 #include "chrome/browser/autocomplete/autocomplete_accessibility.h"
24 #include "chrome/browser/autocomplete/autocomplete_match.h" 23 #include "chrome/browser/autocomplete/autocomplete_match.h"
25 #include "chrome/browser/autocomplete/autocomplete_popup_model.h" 24 #include "chrome/browser/autocomplete/autocomplete_popup_model.h"
26 #include "chrome/browser/autocomplete/keyword_provider.h" 25 #include "chrome/browser/autocomplete/keyword_provider.h"
27 #include "chrome/browser/browser_process.h" 26 #include "chrome/browser/browser_process.h"
28 #include "chrome/browser/command_updater.h" 27 #include "chrome/browser/command_updater.h"
29 #include "chrome/browser/net/url_fixer_upper.h" 28 #include "chrome/browser/net/url_fixer_upper.h"
30 #include "chrome/browser/profiles/profile.h" 29 #include "chrome/browser/profiles/profile.h"
31 #include "chrome/browser/ui/browser.h" 30 #include "chrome/browser/ui/browser.h"
32 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" 31 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
33 #include "chrome/common/chrome_notification_types.h" 32 #include "chrome/common/chrome_notification_types.h"
34 #include "content/browser/tab_contents/tab_contents.h" 33 #include "content/browser/tab_contents/tab_contents.h"
35 #include "content/browser/user_metrics.h" 34 #include "content/browser/user_metrics.h"
36 #include "googleurl/src/url_util.h" 35 #include "googleurl/src/url_util.h"
37 #include "grit/generated_resources.h" 36 #include "grit/generated_resources.h"
38 #include "net/base/escape.h" 37 #include "net/base/escape.h"
39 #include "skia/ext/skia_utils_win.h" 38 #include "skia/ext/skia_utils_win.h"
39 #include "ui/base/accessibility/accessible_view_state.h"
40 #include "ui/base/clipboard/clipboard.h" 40 #include "ui/base/clipboard/clipboard.h"
41 #include "ui/base/clipboard/scoped_clipboard_writer.h" 41 #include "ui/base/clipboard/scoped_clipboard_writer.h"
42 #include "ui/base/dragdrop/drag_drop_types.h" 42 #include "ui/base/dragdrop/drag_drop_types.h"
43 #include "ui/base/dragdrop/drag_source.h" 43 #include "ui/base/dragdrop/drag_source.h"
44 #include "ui/base/dragdrop/drop_target.h" 44 #include "ui/base/dragdrop/drop_target.h"
45 #include "ui/base/dragdrop/os_exchange_data.h" 45 #include "ui/base/dragdrop/os_exchange_data.h"
46 #include "ui/base/dragdrop/os_exchange_data_provider_win.h" 46 #include "ui/base/dragdrop/os_exchange_data_provider_win.h"
47 #include "ui/base/events.h" 47 #include "ui/base/events.h"
48 #include "ui/base/keycodes/keyboard_codes.h" 48 #include "ui/base/keycodes/keyboard_codes.h"
49 #include "ui/base/l10n/l10n_util.h" 49 #include "ui/base/l10n/l10n_util.h"
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 if (text_object_model_) 299 if (text_object_model_)
300 text_object_model_->Undo(tomSuspend, NULL); 300 text_object_model_->Undo(tomSuspend, NULL);
301 } 301 }
302 302
303 OmniboxViewWin::ScopedSuspendUndo::~ScopedSuspendUndo() { 303 OmniboxViewWin::ScopedSuspendUndo::~ScopedSuspendUndo() {
304 // Resume Undo processing. 304 // Resume Undo processing.
305 if (text_object_model_) 305 if (text_object_model_)
306 text_object_model_->Undo(tomResume, NULL); 306 text_object_model_->Undo(tomResume, NULL);
307 } 307 }
308 308
309 // A subclass of NativeViewHost that provides accessibility info for the
310 // underlying Omnibox view.
311 class OmniboxViewWrapper : public views::NativeViewHost {
312 public:
313 explicit OmniboxViewWrapper(OmniboxViewWin* omnibox_view_win)
314 : omnibox_view_win_(omnibox_view_win) { }
315
316 gfx::NativeViewAccessible GetNativeViewAccessible() {
317 // This forces it to use NativeViewAccessibilityWin rather than
318 // any accessibility provided natively by the HWND.
319 return View::GetNativeViewAccessible();
320 }
321
322 // views::View
323 virtual void GetAccessibleState(ui::AccessibleViewState* state) {
324 state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_LOCATION);
325 state->role = ui::AccessibilityTypes::ROLE_TEXT;
326 state->value = omnibox_view_win_->GetText();
327 state->state = ui::AccessibilityTypes::STATE_EDITABLE;
328 size_t sel_start;
329 size_t sel_end;
330 omnibox_view_win_->GetSelectionBounds(&sel_start, &sel_end);
331 state->selection_start = sel_start;
332 state->selection_end = sel_end;
sky 2011/10/25 20:08:45 Is this ok if sel_start > sel_end?
dmazzoni 2011/10/26 16:46:13 Yes, I tested creating a selection using shift+rig
333 }
334
335 private:
336 OmniboxViewWin* omnibox_view_win_;
337 };
sky 2011/10/25 20:08:45 DISALLOW_COPY_AND_ASSIGN
dmazzoni 2011/10/26 16:46:13 Done.
338
309 /////////////////////////////////////////////////////////////////////////////// 339 ///////////////////////////////////////////////////////////////////////////////
310 // OmniboxViewWin 340 // OmniboxViewWin
311 341
312 namespace { 342 namespace {
313 343
314 // These are used to hook the CRichEditCtrl's calls to BeginPaint() and 344 // These are used to hook the CRichEditCtrl's calls to BeginPaint() and
315 // EndPaint() and provide a memory DC instead. See OnPaint(). 345 // EndPaint() and provide a memory DC instead. See OnPaint().
316 HWND edit_hwnd = NULL; 346 HWND edit_hwnd = NULL;
317 PAINTSTRUCT paint_struct; 347 PAINTSTRUCT paint_struct;
318 348
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 CHARRANGE selection; 690 CHARRANGE selection;
661 GetSel(selection); 691 GetSel(selection);
662 return IsSelectAllForRange(selection); 692 return IsSelectAllForRange(selection);
663 } 693 }
664 694
665 bool OmniboxViewWin::DeleteAtEndPressed() { 695 bool OmniboxViewWin::DeleteAtEndPressed() {
666 return delete_at_end_pressed_; 696 return delete_at_end_pressed_;
667 } 697 }
668 698
669 void OmniboxViewWin::GetSelectionBounds(string16::size_type* start, 699 void OmniboxViewWin::GetSelectionBounds(string16::size_type* start,
670 string16::size_type* end) { 700 string16::size_type* end) const {
671 CHARRANGE selection; 701 CHARRANGE selection;
672 GetSel(selection); 702 GetSel(selection);
673 *start = static_cast<size_t>(selection.cpMin); 703 *start = static_cast<size_t>(selection.cpMin);
674 *end = static_cast<size_t>(selection.cpMax); 704 *end = static_cast<size_t>(selection.cpMax);
675 } 705 }
676 706
677 void OmniboxViewWin::SelectAll(bool reversed) { 707 void OmniboxViewWin::SelectAll(bool reversed) {
678 if (reversed) 708 if (reversed)
679 SetSelection(GetTextLength(), 0); 709 SetSelection(GetTextLength(), 0);
680 else 710 else
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 } 747 }
718 748
719 void OmniboxViewWin::ClosePopup() { 749 void OmniboxViewWin::ClosePopup() {
720 model_->StopAutocomplete(); 750 model_->StopAutocomplete();
721 } 751 }
722 752
723 void OmniboxViewWin::SetFocus() { 753 void OmniboxViewWin::SetFocus() {
724 ::SetFocus(m_hWnd); 754 ::SetFocus(m_hWnd);
725 } 755 }
726 756
727 IAccessible* OmniboxViewWin::GetIAccessible() {
728 if (!autocomplete_accessibility_) {
729 CComObject<AutocompleteAccessibility>* accessibility = NULL;
730 if (!SUCCEEDED(CComObject<AutocompleteAccessibility>::CreateInstance(
731 &accessibility)) || !accessibility)
732 return NULL;
733
734 // Wrap the created object in a smart pointer so it won't leak.
735 base::win::ScopedComPtr<IAccessible> accessibility_comptr(accessibility);
736 if (!SUCCEEDED(accessibility->Initialize(this)))
737 return NULL;
738
739 // Copy to the class smart pointer, and notify that an instance of
740 // IAccessible was allocated for m_hWnd.
741 autocomplete_accessibility_ = accessibility_comptr;
742 NotifyWinEvent(EVENT_OBJECT_CREATE, m_hWnd, OBJID_CLIENT, CHILDID_SELF);
743 }
744 // Detach to leave ref counting to the caller.
745 return autocomplete_accessibility_.Detach();
746 }
747
748 void OmniboxViewWin::SetDropHighlightPosition(int position) { 757 void OmniboxViewWin::SetDropHighlightPosition(int position) {
749 if (drop_highlight_position_ != position) { 758 if (drop_highlight_position_ != position) {
750 RepaintDropHighlight(drop_highlight_position_); 759 RepaintDropHighlight(drop_highlight_position_);
751 drop_highlight_position_ = position; 760 drop_highlight_position_ = position;
752 RepaintDropHighlight(drop_highlight_position_); 761 RepaintDropHighlight(drop_highlight_position_);
753 } 762 }
754 } 763 }
755 764
756 void OmniboxViewWin::MoveSelectedText(int new_position) { 765 void OmniboxViewWin::MoveSelectedText(int new_position) {
757 const string16 selected_text(GetSelectedText()); 766 const string16 selected_text(GetSelectedText());
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
878 887
879 if (selection_differs) 888 if (selection_differs)
880 controller_->OnSelectionBoundsChanged(); 889 controller_->OnSelectionBoundsChanged();
881 890
882 if (something_changed && text_differs) 891 if (something_changed && text_differs)
883 TextChanged(); 892 TextChanged();
884 893
885 if (text_differs) { 894 if (text_differs) {
886 // Note that a TEXT_CHANGED event implies that the cursor/selection 895 // Note that a TEXT_CHANGED event implies that the cursor/selection
887 // probably changed too, so we don't need to send both. 896 // probably changed too, so we don't need to send both.
888 parent_view_->GetWidget()->NotifyAccessibilityEvent( 897 native_view_host_->GetWidget()->NotifyAccessibilityEvent(
889 parent_view_, ui::AccessibilityTypes::EVENT_TEXT_CHANGED, true); 898 native_view_host_, ui::AccessibilityTypes::EVENT_TEXT_CHANGED, true);
890 } else if (selection_differs) { 899 } else if (selection_differs) {
891 // Notify assistive technology that the cursor or selection changed. 900 // Notify assistive technology that the cursor or selection changed.
892 parent_view_->GetWidget()->NotifyAccessibilityEvent( 901 native_view_host_->GetWidget()->NotifyAccessibilityEvent(
893 parent_view_, ui::AccessibilityTypes::EVENT_SELECTION_CHANGED, true); 902 native_view_host_,
903 ui::AccessibilityTypes::EVENT_SELECTION_CHANGED,
904 true);
894 } else if (delete_at_end_pressed_) { 905 } else if (delete_at_end_pressed_) {
895 model_->OnChanged(); 906 model_->OnChanged();
896 } 907 }
897 908
898 return something_changed; 909 return something_changed;
899 } 910 }
900 911
901 gfx::NativeView OmniboxViewWin::GetNativeView() const { 912 gfx::NativeView OmniboxViewWin::GetNativeView() const {
902 return m_hWnd; 913 return m_hWnd;
903 } 914 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
940 bool ime_composing = false; 951 bool ime_composing = false;
941 HIMC context = ImmGetContext(m_hWnd); 952 HIMC context = ImmGetContext(m_hWnd);
942 if (context) { 953 if (context) {
943 ime_composing = !!ImmGetCompositionString(context, GCS_COMPSTR, NULL, 0); 954 ime_composing = !!ImmGetCompositionString(context, GCS_COMPSTR, NULL, 0);
944 ImmReleaseContext(m_hWnd, context); 955 ImmReleaseContext(m_hWnd, context);
945 } 956 }
946 return ime_composing; 957 return ime_composing;
947 } 958 }
948 959
949 views::View* OmniboxViewWin::AddToView(views::View* parent) { 960 views::View* OmniboxViewWin::AddToView(views::View* parent) {
950 views::NativeViewHost* host = new views::NativeViewHost; 961 native_view_host_ = new OmniboxViewWrapper(this);
951 parent->AddChildView(host); 962 parent->AddChildView(native_view_host_);
952 host->set_focus_view(parent); 963 native_view_host_->set_focus_view(parent);
David Tseng 2011/10/25 21:55:25 On Windows, is the focused view the parent? (Locat
dmazzoni 2011/10/26 16:46:13 I think this doesn't affect native focus, it just
David Tseng 2011/10/27 20:42:16 Ok; I did see two native IAccessible's with focuse
953 host->Attach(GetNativeView()); 964 native_view_host_->Attach(GetNativeView());
954 return host; 965 return native_view_host_;
955 } 966 }
956 967
957 int OmniboxViewWin::OnPerformDrop(const views::DropTargetEvent& event) { 968 int OmniboxViewWin::OnPerformDrop(const views::DropTargetEvent& event) {
958 return OnPerformDropImpl(event, false); 969 return OnPerformDropImpl(event, false);
959 } 970 }
960 971
961 int OmniboxViewWin::OnPerformDropImpl(const views::DropTargetEvent& event, 972 int OmniboxViewWin::OnPerformDropImpl(const views::DropTargetEvent& event,
962 bool in_drag) { 973 bool in_drag) {
963 const ui::OSExchangeData& data = event.data(); 974 const ui::OSExchangeData& data = event.data();
964 975
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
1323 } 1334 }
1324 1335
1325 void OmniboxViewWin::OnCut() { 1336 void OmniboxViewWin::OnCut() {
1326 OnCopy(); 1337 OnCopy();
1327 1338
1328 // This replace selection will have no effect (even on the undo stack) if the 1339 // This replace selection will have no effect (even on the undo stack) if the
1329 // current selection is empty. 1340 // current selection is empty.
1330 ReplaceSel(L"", true); 1341 ReplaceSel(L"", true);
1331 } 1342 }
1332 1343
1333 LRESULT OmniboxViewWin::OnGetObject(UINT uMsg, 1344 LRESULT OmniboxViewWin::OnGetObject(UINT message,
1334 WPARAM wparam, 1345 WPARAM wparam,
1335 LPARAM lparam) { 1346 LPARAM lparam) {
1336 // Accessibility readers will send an OBJID_CLIENT message. 1347 // This is a request for the native accessibility object.
1337 if (lparam == OBJID_CLIENT) { 1348 if (lparam == OBJID_CLIENT) {
1338 // Re-attach for internal re-usage of accessibility pointer. 1349 return LresultFromObject(IID_IAccessible, wparam,
1339 autocomplete_accessibility_.Attach(GetIAccessible()); 1350 native_view_host_->GetNativeViewAccessible());
1340
1341 if (autocomplete_accessibility_) {
1342 return LresultFromObject(IID_IAccessible, wparam,
1343 autocomplete_accessibility_);
1344 }
1345 } 1351 }
1346 return 0; 1352 return 0;
1347 } 1353 }
1348 1354
1349 LRESULT OmniboxViewWin::OnImeComposition(UINT message, 1355 LRESULT OmniboxViewWin::OnImeComposition(UINT message,
1350 WPARAM wparam, 1356 WPARAM wparam,
1351 LPARAM lparam) { 1357 LPARAM lparam) {
1352 if (ignore_ime_messages_) { 1358 if (ignore_ime_messages_) {
1353 // This message was sent while we're in the middle of meddling with the 1359 // This message was sent while we're in the middle of meddling with the
1354 // underlying edit control. If we handle it below, OnAfterPossibleChange() 1360 // underlying edit control. If we handle it below, OnAfterPossibleChange()
(...skipping 1257 matching lines...) Expand 10 before | Expand all | Expand 10 after
2612 // PosFromChar(i) might return 0 when i is greater than 1. 2618 // PosFromChar(i) might return 0 when i is greater than 1.
2613 return font_.GetStringWidth(text) + GetHorizontalMargin(); 2619 return font_.GetStringWidth(text) + GetHorizontalMargin();
2614 } 2620 }
2615 2621
2616 bool OmniboxViewWin::IsCaretAtEnd() const { 2622 bool OmniboxViewWin::IsCaretAtEnd() const {
2617 long length = GetTextLength(); 2623 long length = GetTextLength();
2618 CHARRANGE sel; 2624 CHARRANGE sel;
2619 GetSelection(sel); 2625 GetSelection(sel);
2620 return sel.cpMin == sel.cpMax && sel.cpMin == length; 2626 return sel.cpMin == sel.cpMax && sel.cpMin == length;
2621 } 2627 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698