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

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

Issue 2943243002: Forward BrowserAccessibility get_accState to AXPlatformNode. (Closed)
Patch Set: Mask out focus changes when determining if we should broadcast EVENT_OBJECT_STATECHANGE Created 3 years, 5 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 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 1488 matching lines...) Expand 10 before | Expand all | Expand 10 after
1499 case ui::AX_ROLE_SWITCH: 1499 case ui::AX_ROLE_SWITCH:
1500 return "switch"; 1500 return "switch";
1501 1501
1502 default: 1502 default:
1503 return ""; 1503 return "";
1504 } 1504 }
1505 1505
1506 return ""; 1506 return "";
1507 } 1507 }
1508 1508
1509 bool AXPlatformNodeWin::ShouldNodeHaveReadonlyState(
1510 const AXNodeData& data) const {
1511 if (data.GetBoolAttribute(ui::AX_ATTR_ARIA_READONLY))
1512 return true;
1513
1514 if (!data.HasState(ui::AX_STATE_READ_ONLY))
1515 return false;
1516
1517 switch (data.role) {
1518 case ui::AX_ROLE_ARTICLE:
1519 case ui::AX_ROLE_BUSY_INDICATOR:
1520 case ui::AX_ROLE_DEFINITION:
1521 case ui::AX_ROLE_DESCRIPTION_LIST:
1522 case ui::AX_ROLE_DESCRIPTION_LIST_TERM:
1523 case ui::AX_ROLE_DOCUMENT:
1524 case ui::AX_ROLE_IFRAME:
1525 case ui::AX_ROLE_IMAGE:
1526 case ui::AX_ROLE_IMAGE_MAP:
1527 case ui::AX_ROLE_IMAGE_MAP_LINK:
1528 case ui::AX_ROLE_LIST:
1529 case ui::AX_ROLE_LIST_ITEM:
1530 case ui::AX_ROLE_PROGRESS_INDICATOR:
1531 case ui::AX_ROLE_ROOT_WEB_AREA:
1532 case ui::AX_ROLE_RULER:
1533 case ui::AX_ROLE_SCROLL_AREA:
1534 case ui::AX_ROLE_TERM:
1535 case ui::AX_ROLE_TIMER:
1536 case ui::AX_ROLE_TOOLBAR:
1537 case ui::AX_ROLE_TOOLTIP:
1538 case ui::AX_ROLE_WEB_AREA:
1539 return true;
1540
1541 case ui::AX_ROLE_GRID:
1542 // TODO(aleventhal) this changed between ARIA 1.0 and 1.1,
1543 // need to determine whether grids/treegrids should really be readonly
1544 // or editable by default
1545 // msaa_state |= STATE_SYSTEM_READONLY;
1546 break;
1547
1548 case ui::AX_ROLE_TEXT_FIELD:
1549 case ui::AX_ROLE_SEARCH_BOX:
1550 if (data.HasState(ui::AX_STATE_READ_ONLY))
1551 return true;
1552
1553 default:
1554 break;
1555 }
1556 return false;
1557 }
1558
1559 bool AXPlatformNodeWin::ShouldNodeHaveFocusableState(
1560 const AXNodeData& data) const {
1561 switch (data.role) {
1562 case ui::AX_ROLE_DOCUMENT:
1563 case ui::AX_ROLE_ROOT_WEB_AREA:
1564 case ui::AX_ROLE_WEB_AREA:
1565 return true;
1566
1567 case ui::AX_ROLE_IFRAME:
1568 return false;
1569
1570 case ui::AX_ROLE_LIST_BOX_OPTION:
1571 case ui::AX_ROLE_MENU_LIST_OPTION:
1572 if (data.HasState(ui::AX_STATE_SELECTABLE))
1573 return true;
1574
1575 default:
1576 break;
1577 }
1578
1579 return data.HasState(ui::AX_STATE_FOCUSABLE);
1580 }
1581
1509 int AXPlatformNodeWin::MSAAState() { 1582 int AXPlatformNodeWin::MSAAState() {
1510 const AXNodeData& data = GetData(); 1583 const AXNodeData& data = GetData();
1511 const uint32_t state = data.state; 1584 int msaa_state = 0;
1512 1585
1513 int msaa_state = 0; 1586 // Map the AXState to MSAA state. Note that some of the states are not
1514 if (state & (1 << ui::AX_STATE_COLLAPSED)) 1587 // currently handled.
1588
1589 if (data.HasState(ui::AX_STATE_BUSY))
1590 msaa_state |= STATE_SYSTEM_BUSY;
1591
1592 if (data.HasState(ui::AX_STATE_COLLAPSED))
1515 msaa_state |= STATE_SYSTEM_COLLAPSED; 1593 msaa_state |= STATE_SYSTEM_COLLAPSED;
1516 if (state & (1 << ui::AX_STATE_DEFAULT)) 1594
1595 if (data.HasState(ui::AX_STATE_DEFAULT))
1517 msaa_state |= STATE_SYSTEM_DEFAULT; 1596 msaa_state |= STATE_SYSTEM_DEFAULT;
1518 if (state & (1 << ui::AX_STATE_EXPANDED)) 1597
1598 if (data.HasState(ui::AX_STATE_DISABLED))
1599 msaa_state |= STATE_SYSTEM_UNAVAILABLE;
1600
1601 // TODO(dougt) unhandled ux::AX_STATE_EDITABLE
1602
1603 if (data.HasState(ui::AX_STATE_EXPANDED))
1519 msaa_state |= STATE_SYSTEM_EXPANDED; 1604 msaa_state |= STATE_SYSTEM_EXPANDED;
1520 if (state & (1 << ui::AX_STATE_FOCUSABLE)) 1605
1606 if (ShouldNodeHaveFocusableState(data))
1521 msaa_state |= STATE_SYSTEM_FOCUSABLE; 1607 msaa_state |= STATE_SYSTEM_FOCUSABLE;
1522 if (state & (1 << ui::AX_STATE_HASPOPUP)) 1608
1609 if (data.HasState(ui::AX_STATE_HASPOPUP))
1523 msaa_state |= STATE_SYSTEM_HASPOPUP; 1610 msaa_state |= STATE_SYSTEM_HASPOPUP;
1524 if (state & (1 << ui::AX_STATE_HOVERED)) 1611
1525 msaa_state |= STATE_SYSTEM_HOTTRACKED; 1612 // TODO(dougt) unhandled ux::AX_STATE_HORIZONTAL
1526 if (state & (1 << ui::AX_STATE_INVISIBLE) || 1613
1614 if (data.HasState(ui::AX_STATE_HOVERED)) {
1615 // Expose whether or not the mouse is over an element, but suppress
1616 // this for tests because it can make the test results flaky depending
1617 // on the position of the mouse.
1618 if (delegate_->ShouldIgnoreHoveredStateForTesting())
1619 msaa_state |= STATE_SYSTEM_HOTTRACKED;
1620 }
1621
1622 // TODO(dougt) Why do we set any state on AX_ROLE_IGNORED?
1623 if (data.HasState(ui::AX_STATE_INVISIBLE) ||
1527 GetData().role == ui::AX_ROLE_IGNORED) { 1624 GetData().role == ui::AX_ROLE_IGNORED) {
1528 msaa_state |= STATE_SYSTEM_INVISIBLE; 1625 msaa_state |= STATE_SYSTEM_INVISIBLE;
1529 } 1626 }
1530 if (state & (1 << ui::AX_STATE_LINKED)) 1627 if (data.HasState(ui::AX_STATE_LINKED))
1531 msaa_state |= STATE_SYSTEM_LINKED; 1628 msaa_state |= STATE_SYSTEM_LINKED;
1532 if (state & (1 << ui::AX_STATE_OFFSCREEN)) 1629
1630 // TODO(dougt) unhandled ux::AX_STATE_MULTILINE
1631
1632 if (data.HasState(ui::AX_STATE_MULTISELECTABLE)) {
1633 msaa_state |= STATE_SYSTEM_EXTSELECTABLE;
1634 msaa_state |= STATE_SYSTEM_MULTISELECTABLE;
1635 }
1636
1637 if (data.HasState(ui::AX_STATE_OFFSCREEN))
1533 msaa_state |= STATE_SYSTEM_OFFSCREEN; 1638 msaa_state |= STATE_SYSTEM_OFFSCREEN;
1534 if (state & (1 << ui::AX_STATE_PROTECTED)) 1639
1640 if (data.HasState(ui::AX_STATE_PROTECTED))
1535 msaa_state |= STATE_SYSTEM_PROTECTED; 1641 msaa_state |= STATE_SYSTEM_PROTECTED;
1536 if (state & (1 << ui::AX_STATE_READ_ONLY)) 1642
1643 // READONLY state is complex on windows. We set STATE_SYSTEM_READONLY
1644 // on *some* roles even if the node data isn't marked as AX_STATE_READ_ONLY.
1645 if (ShouldNodeHaveReadonlyState(data))
1537 msaa_state |= STATE_SYSTEM_READONLY; 1646 msaa_state |= STATE_SYSTEM_READONLY;
1538 if (state & (1 << ui::AX_STATE_SELECTABLE)) 1647
1648 // TODO(dougt) unhandled ux::AX_STATE_REQUIRED
1649 // TODO(dougt) unhandled ux::AX_STATE_RICHLY_EDITABLE
1650
1651 if (data.HasState(ui::AX_STATE_SELECTABLE))
1539 msaa_state |= STATE_SYSTEM_SELECTABLE; 1652 msaa_state |= STATE_SYSTEM_SELECTABLE;
1540 if (state & (1 << ui::AX_STATE_SELECTED)) 1653
1654 if (data.HasState(ui::AX_STATE_SELECTED))
1541 msaa_state |= STATE_SYSTEM_SELECTED; 1655 msaa_state |= STATE_SYSTEM_SELECTED;
1542 if (state & (1 << ui::AX_STATE_DISABLED))
1543 msaa_state |= STATE_SYSTEM_UNAVAILABLE;
1544 1656
1657 // TODO(dougt) unhandled VERTICAL
1658
1659 if (data.HasState(ui::AX_STATE_VISITED))
1660 msaa_state |= STATE_SYSTEM_TRAVERSED;
1661
1662 //
1545 // Checked state 1663 // Checked state
1664 //
1546 const auto checked_state = static_cast<ui::AXCheckedState>( 1665 const auto checked_state = static_cast<ui::AXCheckedState>(
1547 GetIntAttribute(ui::AX_ATTR_CHECKED_STATE)); 1666 GetIntAttribute(ui::AX_ATTR_CHECKED_STATE));
1548 switch (checked_state) { 1667 switch (checked_state) {
1549 case ui::AX_CHECKED_STATE_TRUE: 1668 case ui::AX_CHECKED_STATE_TRUE:
1550 msaa_state |= data.role == ui::AX_ROLE_TOGGLE_BUTTON 1669 msaa_state |= data.role == ui::AX_ROLE_TOGGLE_BUTTON
1551 ? STATE_SYSTEM_PRESSED 1670 ? STATE_SYSTEM_PRESSED
1552 : STATE_SYSTEM_CHECKED; 1671 : STATE_SYSTEM_CHECKED;
1553 break; 1672 break;
1554 case ui::AX_CHECKED_STATE_MIXED: 1673 case ui::AX_CHECKED_STATE_MIXED:
1555 msaa_state |= STATE_SYSTEM_MIXED; 1674 msaa_state |= STATE_SYSTEM_MIXED;
1556 break; 1675 break;
1557 default: 1676 default:
1558 break; 1677 break;
1559 } 1678 }
1560 1679
1680 //
1681 // Handle STATE_SYSTEM_FOCUSED
1682 //
1561 gfx::NativeViewAccessible focus = delegate_->GetFocus(); 1683 gfx::NativeViewAccessible focus = delegate_->GetFocus();
1562 if (focus == GetNativeViewAccessible()) 1684 if (focus == GetNativeViewAccessible())
1563 msaa_state |= STATE_SYSTEM_FOCUSED; 1685 msaa_state |= STATE_SYSTEM_FOCUSED;
1564 1686
1565 // On Windows, the "focus" bit should be set on certain containers, like 1687 // On Windows, the "focus" bit should be set on certain containers, like
1566 // menu bars, when visible. 1688 // menu bars, when visible.
1567 // 1689 //
1568 // TODO(dmazzoni): this should probably check if focus is actually inside 1690 // TODO(dmazzoni): this should probably check if focus is actually inside
1569 // the menu bar, but we don't currently track focus inside menu pop-ups, 1691 // the menu bar, but we don't currently track focus inside menu pop-ups,
1570 // and Chrome only has one menu visible at a time so this works for now. 1692 // and Chrome only has one menu visible at a time so this works for now.
1571 if (data.role == ui::AX_ROLE_MENU_BAR && 1693 if (data.role == ui::AX_ROLE_MENU_BAR &&
1572 !(state & (1 << ui::AX_STATE_INVISIBLE))) { 1694 !(data.HasState(ui::AX_STATE_INVISIBLE))) {
1573 msaa_state |= STATE_SYSTEM_FOCUSED; 1695 msaa_state |= STATE_SYSTEM_FOCUSED;
1574 } 1696 }
1575 1697
1698 // Handle STATE_SYSTEM_LINKED
1699 if (GetData().role == ui::AX_ROLE_IMAGE_MAP_LINK ||
1700 GetData().role == ui::AX_ROLE_LINK) {
1701 msaa_state |= STATE_SYSTEM_LINKED;
1702 }
1703
1576 return msaa_state; 1704 return msaa_state;
1577 } 1705 }
1578 1706
1579 int AXPlatformNodeWin::MSAAEvent(ui::AXEvent event) { 1707 int AXPlatformNodeWin::MSAAEvent(ui::AXEvent event) {
1580 switch (event) { 1708 switch (event) {
1581 case ui::AX_EVENT_ALERT: 1709 case ui::AX_EVENT_ALERT:
1582 return EVENT_SYSTEM_ALERT; 1710 return EVENT_SYSTEM_ALERT;
1583 case ui::AX_EVENT_FOCUS: 1711 case ui::AX_EVENT_FOCUS:
1584 return EVENT_OBJECT_FOCUS; 1712 return EVENT_OBJECT_FOCUS;
1585 case ui::AX_EVENT_MENU_START: 1713 case ui::AX_EVENT_MENU_START:
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1699 1827
1700 AXPlatformNodeBase* base = 1828 AXPlatformNodeBase* base =
1701 FromNativeViewAccessible(node->GetNativeViewAccessible()); 1829 FromNativeViewAccessible(node->GetNativeViewAccessible());
1702 if (base && !IsDescendant(base)) 1830 if (base && !IsDescendant(base))
1703 base = nullptr; 1831 base = nullptr;
1704 1832
1705 return static_cast<AXPlatformNodeWin*>(base); 1833 return static_cast<AXPlatformNodeWin*>(base);
1706 } 1834 }
1707 1835
1708 } // namespace ui 1836 } // namespace ui
OLDNEW
« no previous file with comments | « ui/accessibility/platform/ax_platform_node_win.h ('k') | ui/accessibility/platform/test_ax_node_wrapper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698