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

Side by Side Diff: ui/accessibility/platform/ax_platform_node_win.cc

Issue 2806093002: Forward AXPlatformNodeWin calls to the right child. (Closed)
Patch Set: Convert get_accChild Created 3 years, 8 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
« no previous file with comments | « ui/accessibility/platform/ax_platform_node_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 <atlbase.h> 5 #include <atlbase.h>
6 #include <atlcom.h> 6 #include <atlcom.h>
7 #include <limits.h> 7 #include <limits.h>
8 #include <oleacc.h> 8 #include <oleacc.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 10
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 // Always increment ref when returning a reference to a COM object. 248 // Always increment ref when returning a reference to a COM object.
249 child->pdispVal->AddRef(); 249 child->pdispVal->AddRef();
250 } 250 }
251 return result; 251 return result;
252 } 252 }
253 253
254 HRESULT AXPlatformNodeWin::accDoDefaultAction(VARIANT var_id) { 254 HRESULT AXPlatformNodeWin::accDoDefaultAction(VARIANT var_id) {
255 COM_OBJECT_VALIDATE_VAR_ID(var_id); 255 COM_OBJECT_VALIDATE_VAR_ID(var_id);
256 AXActionData data; 256 AXActionData data;
257 data.action = ui::AX_ACTION_DO_DEFAULT; 257 data.action = ui::AX_ACTION_DO_DEFAULT;
258 if (delegate_->AccessibilityPerformAction(data)) 258
259 auto* target = GetTargetFromChildID(var_id);
dmazzoni 2017/04/10 07:20:19 What do you think about putting GetTargetFromChild
260 if (!target)
261 return E_INVALIDARG;
262
263 if (target->delegate_->AccessibilityPerformAction(data))
259 return S_OK; 264 return S_OK;
260 return E_FAIL; 265 return E_FAIL;
261 } 266 }
262 267
263 STDMETHODIMP AXPlatformNodeWin::accLocation( 268 STDMETHODIMP AXPlatformNodeWin::accLocation(
264 LONG* x_left, LONG* y_top, LONG* width, LONG* height, VARIANT var_id) { 269 LONG* x_left, LONG* y_top, LONG* width, LONG* height, VARIANT var_id) {
265 COM_OBJECT_VALIDATE_VAR_ID_4_ARGS(var_id, x_left, y_top, width, height); 270 COM_OBJECT_VALIDATE_VAR_ID_4_ARGS(var_id, x_left, y_top, width, height);
266 gfx::Rect bounds = delegate_->GetScreenBoundsRect(); 271
272 auto* target = GetTargetFromChildID(var_id);
273 if (!target)
274 return E_INVALIDARG;
275
276 gfx::Rect bounds = target->delegate_->GetScreenBoundsRect();
267 *x_left = bounds.x(); 277 *x_left = bounds.x();
268 *y_top = bounds.y(); 278 *y_top = bounds.y();
269 *width = bounds.width(); 279 *width = bounds.width();
270 *height = bounds.height(); 280 *height = bounds.height();
271 281
272 if (bounds.IsEmpty()) 282 if (bounds.IsEmpty())
273 return S_FALSE; 283 return S_FALSE;
274 284
275 return S_OK; 285 return S_OK;
276 } 286 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 end->pdispVal = result; 335 end->pdispVal = result;
326 // Always increment ref when returning a reference to a COM object. 336 // Always increment ref when returning a reference to a COM object.
327 end->pdispVal->AddRef(); 337 end->pdispVal->AddRef();
328 338
329 return S_OK; 339 return S_OK;
330 } 340 }
331 341
332 STDMETHODIMP AXPlatformNodeWin::get_accChild(VARIANT var_child, 342 STDMETHODIMP AXPlatformNodeWin::get_accChild(VARIANT var_child,
333 IDispatch** disp_child) { 343 IDispatch** disp_child) {
334 COM_OBJECT_VALIDATE_1_ARG(disp_child); 344 COM_OBJECT_VALIDATE_1_ARG(disp_child);
335 LONG child_id = V_I4(&var_child); 345 auto* target = GetTargetFromChildID(var_child);
336 if (child_id == CHILDID_SELF) { 346 if (!target) {
337 *disp_child = this; 347 *disp_child = nullptr;
338 (*disp_child)->AddRef(); 348 return E_INVALIDARG;
339 return S_OK;
340 } 349 }
341 350
342 if (child_id >= 1 && child_id <= delegate_->GetChildCount()) { 351 *disp_child = target;
343 // Positive child ids are a 1-based child index, used by clients 352 (*disp_child)->AddRef();
344 // that want to enumerate all immediate children. 353 return S_OK;
345 *disp_child = delegate_->ChildAtIndex(child_id - 1);
346 if (!(*disp_child))
347 return E_INVALIDARG;
348 (*disp_child)->AddRef();
349 return S_OK;
350 }
351
352 if (child_id >= 0)
353 return E_INVALIDARG;
354
355 // Negative child ids can be used to map to any descendant.
356 AXPlatformNodeWin* child = static_cast<AXPlatformNodeWin*>(
357 GetFromUniqueId(-child_id));
358 if (child && !IsDescendant(child))
359 child = nullptr;
360
361 if (child) {
362 *disp_child = child;
363 (*disp_child)->AddRef();
364 return S_OK;
365 }
366
367 *disp_child = nullptr;
368 return E_INVALIDARG;
369 } 354 }
370 355
371 STDMETHODIMP AXPlatformNodeWin::get_accChildCount(LONG* child_count) { 356 STDMETHODIMP AXPlatformNodeWin::get_accChildCount(LONG* child_count) {
372 COM_OBJECT_VALIDATE_1_ARG(child_count); 357 COM_OBJECT_VALIDATE_1_ARG(child_count);
373 *child_count = delegate_->GetChildCount(); 358 *child_count = delegate_->GetChildCount();
374 return S_OK; 359 return S_OK;
375 } 360 }
376 361
377 STDMETHODIMP AXPlatformNodeWin::get_accDefaultAction( 362 STDMETHODIMP AXPlatformNodeWin::get_accDefaultAction(
378 VARIANT var_id, BSTR* def_action) { 363 VARIANT var_id, BSTR* def_action) {
379 COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, def_action); 364 COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, def_action);
365
366 auto* target = GetTargetFromChildID(var_id);
367 if (!target)
368 return E_INVALIDARG;
369
380 int action; 370 int action;
381 if (!GetIntAttribute(AX_ATTR_ACTION, &action)) { 371 if (!target->GetIntAttribute(AX_ATTR_ACTION, &action)) {
382 *def_action = nullptr; 372 *def_action = nullptr;
383 return S_FALSE; 373 return S_FALSE;
384 } 374 }
385 375
386 base::string16 action_verb = 376 base::string16 action_verb =
387 ActionToString(static_cast<AXSupportedAction>(action)); 377 ActionToString(static_cast<AXSupportedAction>(action));
388 if (action_verb.empty()) { 378 if (action_verb.empty()) {
389 *def_action = nullptr; 379 *def_action = nullptr;
390 return S_FALSE; 380 return S_FALSE;
391 } 381 }
392 382
393 *def_action = SysAllocString(action_verb.c_str()); 383 *def_action = SysAllocString(action_verb.c_str());
394 DCHECK(def_action); 384 DCHECK(def_action);
395 return S_OK; 385 return S_OK;
396 } 386 }
397 387
398 STDMETHODIMP AXPlatformNodeWin::get_accDescription( 388 STDMETHODIMP AXPlatformNodeWin::get_accDescription(
399 VARIANT var_id, BSTR* desc) { 389 VARIANT var_id, BSTR* desc) {
400 COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, desc); 390 COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, desc);
401 return GetStringAttributeAsBstr(ui::AX_ATTR_DESCRIPTION, desc); 391
392 auto* target = GetTargetFromChildID(var_id);
393 if (!target)
394 return E_INVALIDARG;
395
396 return target->GetStringAttributeAsBstr(ui::AX_ATTR_DESCRIPTION, desc);
402 } 397 }
403 398
404 STDMETHODIMP AXPlatformNodeWin::get_accFocus(VARIANT* focus_child) { 399 STDMETHODIMP AXPlatformNodeWin::get_accFocus(VARIANT* focus_child) {
405 COM_OBJECT_VALIDATE_1_ARG(focus_child); 400 COM_OBJECT_VALIDATE_1_ARG(focus_child);
406 gfx::NativeViewAccessible focus_accessible = delegate_->GetFocus(); 401 gfx::NativeViewAccessible focus_accessible = delegate_->GetFocus();
407 if (focus_accessible == this) { 402 if (focus_accessible == this) {
408 focus_child->vt = VT_I4; 403 focus_child->vt = VT_I4;
409 focus_child->lVal = CHILDID_SELF; 404 focus_child->lVal = CHILDID_SELF;
410 } else if (focus_accessible) { 405 } else if (focus_accessible) {
411 focus_child->vt = VT_DISPATCH; 406 focus_child->vt = VT_DISPATCH;
412 focus_child->pdispVal = focus_accessible; 407 focus_child->pdispVal = focus_accessible;
413 focus_child->pdispVal->AddRef(); 408 focus_child->pdispVal->AddRef();
414 return S_OK; 409 return S_OK;
415 } else { 410 } else {
416 focus_child->vt = VT_EMPTY; 411 focus_child->vt = VT_EMPTY;
417 } 412 }
418 413
419 return S_OK; 414 return S_OK;
420 } 415 }
421 416
422 STDMETHODIMP AXPlatformNodeWin::get_accKeyboardShortcut( 417 STDMETHODIMP AXPlatformNodeWin::get_accKeyboardShortcut(
423 VARIANT var_id, BSTR* acc_key) { 418 VARIANT var_id, BSTR* acc_key) {
424 COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, acc_key); 419 COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, acc_key);
425 return GetStringAttributeAsBstr(ui::AX_ATTR_SHORTCUT, acc_key); 420
421 auto* target = GetTargetFromChildID(var_id);
422 if (!target)
423 return E_INVALIDARG;
424
425 return target->GetStringAttributeAsBstr(ui::AX_ATTR_SHORTCUT, acc_key);
426 } 426 }
427 427
428 STDMETHODIMP AXPlatformNodeWin::get_accName( 428 STDMETHODIMP AXPlatformNodeWin::get_accName(
429 VARIANT var_id, BSTR* name) { 429 VARIANT var_id, BSTR* name) {
430 COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, name); 430 COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, name);
431 return GetStringAttributeAsBstr(ui::AX_ATTR_NAME, name); 431 auto* target = GetTargetFromChildID(var_id);
432 if (!target)
433 return E_INVALIDARG;
434
435 return target->GetStringAttributeAsBstr(ui::AX_ATTR_NAME, name);
432 } 436 }
433 437
434 STDMETHODIMP AXPlatformNodeWin::get_accParent( 438 STDMETHODIMP AXPlatformNodeWin::get_accParent(
435 IDispatch** disp_parent) { 439 IDispatch** disp_parent) {
436 COM_OBJECT_VALIDATE_1_ARG(disp_parent); 440 COM_OBJECT_VALIDATE_1_ARG(disp_parent);
437 *disp_parent = GetParent(); 441 *disp_parent = GetParent();
438 if (*disp_parent) { 442 if (*disp_parent) {
439 (*disp_parent)->AddRef(); 443 (*disp_parent)->AddRef();
440 return S_OK; 444 return S_OK;
441 } 445 }
442 446
443 return S_FALSE; 447 return S_FALSE;
444 } 448 }
445 449
446 STDMETHODIMP AXPlatformNodeWin::get_accRole( 450 STDMETHODIMP AXPlatformNodeWin::get_accRole(
447 VARIANT var_id, VARIANT* role) { 451 VARIANT var_id, VARIANT* role) {
448 COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, role); 452 COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, role);
453 auto* target = GetTargetFromChildID(var_id);
454 if (!target)
455 return E_INVALIDARG;
456
449 role->vt = VT_I4; 457 role->vt = VT_I4;
450 role->lVal = MSAARole(); 458 role->lVal = target->MSAARole();
451 return S_OK; 459 return S_OK;
452 } 460 }
453 461
454 STDMETHODIMP AXPlatformNodeWin::get_accState( 462 STDMETHODIMP AXPlatformNodeWin::get_accState(
455 VARIANT var_id, VARIANT* state) { 463 VARIANT var_id, VARIANT* state) {
456 COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, state); 464 COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, state);
465 auto* target = GetTargetFromChildID(var_id);
466 if (!target)
467 return E_INVALIDARG;
468
457 state->vt = VT_I4; 469 state->vt = VT_I4;
458 state->lVal = MSAAState(); 470 state->lVal = target->MSAAState();
459 return S_OK; 471 return S_OK;
460 } 472 }
461 473
462 STDMETHODIMP AXPlatformNodeWin::get_accHelp( 474 STDMETHODIMP AXPlatformNodeWin::get_accHelp(
463 VARIANT var_id, BSTR* help) { 475 VARIANT var_id, BSTR* help) {
464 COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, help); 476 COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, help);
465 return S_FALSE; 477 return S_FALSE;
466 } 478 }
467 479
468 STDMETHODIMP AXPlatformNodeWin::get_accValue(VARIANT var_id, BSTR* value) { 480 STDMETHODIMP AXPlatformNodeWin::get_accValue(VARIANT var_id, BSTR* value) {
469 COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, value); 481 COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, value);
470 return GetStringAttributeAsBstr(ui::AX_ATTR_VALUE, value); 482
483 auto* target = GetTargetFromChildID(var_id);
484 if (!target)
485 return E_INVALIDARG;
486 return target->GetStringAttributeAsBstr(ui::AX_ATTR_VALUE, value);
471 } 487 }
472 488
473 STDMETHODIMP AXPlatformNodeWin::put_accValue(VARIANT var_id, 489 STDMETHODIMP AXPlatformNodeWin::put_accValue(VARIANT var_id,
474 BSTR new_value) { 490 BSTR new_value) {
475 AXActionData data; 491 AXActionData data;
476 data.action = ui::AX_ACTION_SET_VALUE; 492 data.action = ui::AX_ACTION_SET_VALUE;
477 data.value = new_value; 493 data.value = new_value;
478 COM_OBJECT_VALIDATE_VAR_ID(var_id); 494 COM_OBJECT_VALIDATE_VAR_ID(var_id);
479 if (delegate_->AccessibilityPerformAction(data)) 495
496 auto* target = GetTargetFromChildID(var_id);
497 if (!target)
498 return E_INVALIDARG;
499
500 if (target->delegate_->AccessibilityPerformAction(data))
480 return S_OK; 501 return S_OK;
481 return E_FAIL; 502 return E_FAIL;
482 } 503 }
483 504
484 // IAccessible functions not supported. 505 // IAccessible functions not supported.
485 506
486 STDMETHODIMP AXPlatformNodeWin::get_accSelection(VARIANT* selected) { 507 STDMETHODIMP AXPlatformNodeWin::get_accSelection(VARIANT* selected) {
487 COM_OBJECT_VALIDATE_1_ARG(selected); 508 COM_OBJECT_VALIDATE_1_ARG(selected);
488 if (selected) 509 if (selected)
489 selected->vt = VT_EMPTY; 510 selected->vt = VT_EMPTY;
(...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after
1193 LONG start_offset, 1214 LONG start_offset,
1194 ui::TextBoundaryDirection direction) { 1215 ui::TextBoundaryDirection direction) {
1195 HandleSpecialTextOffset(&start_offset); 1216 HandleSpecialTextOffset(&start_offset);
1196 ui::TextBoundaryType boundary = IA2TextBoundaryToTextBoundary(ia2_boundary); 1217 ui::TextBoundaryType boundary = IA2TextBoundaryToTextBoundary(ia2_boundary);
1197 std::vector<int32_t> line_breaks; 1218 std::vector<int32_t> line_breaks;
1198 return static_cast<LONG>(ui::FindAccessibleTextBoundary( 1219 return static_cast<LONG>(ui::FindAccessibleTextBoundary(
1199 text, line_breaks, boundary, start_offset, direction, 1220 text, line_breaks, boundary, start_offset, direction,
1200 AX_TEXT_AFFINITY_DOWNSTREAM)); 1221 AX_TEXT_AFFINITY_DOWNSTREAM));
1201 } 1222 }
1202 1223
1224 AXPlatformNodeWin* AXPlatformNodeWin::GetTargetFromChildID(
1225 const VARIANT& var_id) {
1226 LONG child_id = V_I4(&var_id);
1227 if (child_id == CHILDID_SELF) {
1228 return this;
1229 }
1230
1231 if (child_id >= 1 && child_id <= delegate_->GetChildCount()) {
1232 // Positive child ids are a 1-based child index, used by clients
1233 // that want to enumerate all immediate children.
1234 return static_cast<AXPlatformNodeWin*>(
dmazzoni 2017/04/10 07:20:19 Note that a child may not necessarily be an AXPlat
1235 delegate_->ChildAtIndex(child_id - 1));
1236 }
1237
1238 if (child_id >= 0)
1239 return nullptr;
1240
1241 // Negative child ids can be used to map to any descendant.
1242 auto* child = static_cast<AXPlatformNodeWin*>(GetFromUniqueId(-child_id));
1243 if (child && !IsDescendant(child))
1244 child = nullptr;
1245
1246 return child;
1247 }
1248
1203 } // namespace ui 1249 } // namespace ui
OLDNEW
« no previous file with comments | « ui/accessibility/platform/ax_platform_node_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698